自在学
分类课程AI导师价格
分类课程AI导师价格
Web应用安全与渗透测试
2 / 17
渗透测试方法论
自在学

© 2025 - 2026 自在学,保留所有权利。

公网安备湘公网安备43020302000292号 | 湘ICP备2025148919号-1

关于我们隐私政策使用条款

© 2025 自在学,保留所有权利。

公网安备湘公网安备43020302000292号湘ICP备2025148919号-1

编程Web应用渗透测试Web应用技术基础

Web应用技术基础

做渗透测试,你得先懂Web应用是怎么工作的。很多人一上来就想学SQL注入、XSS,但连HTTP请求都看不懂,那肯定学不好。这一部分,让我们从实战的角度,深入理解Web应用的技术基础。这是做渗透测试的“语法基础”,不理解这些,后面的漏洞理解起来会很困难。


HTTP/HTTPS协议

很多人会用Burp Suite抓包,但看不懂包里的内容。他们知道要改参数,但不知道为什么要这样改,也不知道改哪里。

理解HTTP协议,是做渗透测试的基础。就像学编程要先学语法一样,做Web渗透测试,必须先理解HTTP协议。

HTTP请求结构

一个完整的HTTP请求,包含这几个部分:

请求行 请求头 空行 请求体(可选)

让我用一个真实的例子给你看:

POST /api/login.php HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Content-Type: application/x-www-form-urlencoded Content-Length: 38 Cookie: sessionid=abc123 Connection: keep-alive username=admin&password=123456

请求行:POST /api/login.php HTTP/1.1,其中POST是请求方法,/api/login.php是请求路径,HTTP/1.1是协议版本。

请求头:从Host到Connection都是请求头。Host标识目标主机,告诉服务器要访问哪个域名。User-Agent包含客户端信息,告诉服务器你用的什么浏览器。Content-Type指定请求体的类型,这里是application/x-www-form-urlencoded,表示表单数据。Content-Length表示请求体的长度,这里是38字节。Cookie包含会话信息,用于维持登录状态。

空行:请求头和请求体之间必须有一个空行

请求体:username=admin&password=123456,这是实际传输的数据

HTTP响应结构

HTTP响应的结构类似:

状态行 响应头 空行 响应体

真实例子:

HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Mon, 01 Jan 2024 12:00:00 GMT Content-Type: application/json Content-Length: 156 Set-Cookie: sessionid=xyz789; Path=/; HttpOnly Connection: keep-alive {"status":"success","message":"Login successful","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}

状态行:HTTP/1.1 200 OK,其中200是状态码,表示请求成功,OK是状态描述。

响应头:Server头包含服务器信息,这个很重要,做信息收集时会用到,比如这里显示nginx/1.18.0,说明用的是nginx服务器,版本是1.18.0。Set-Cookie用于设置Cookie,注意这里的HttpOnly属性,后面会详细讲。Content-Type指定响应体的类型,这里是application/json,表示返回的是JSON数据。

响应体:实际的响应内容,这里是JSON格式的数据,包含登录成功的状态和token。

图片描述:一个展示HTTP请求和响应结构的示意图,包含请求行、请求头、请求体,以及响应状态行、响应头、响应体等各个部分的详细标注

常见的HTTP方法

做渗透测试,你得知道这些HTTP方法:

方法说明安全提示
GET获取资源,参数在URL里,如/api/user.php?id=1。
可以被缓存,有长度限制,URL过长可能被截断。
参数出现在URL、日志和浏览器历史中,敏感信息勿用GET,否则易泄露。
POST提交数据,参数在请求体,不在URL。
不会被缓存,可大量传输数据,无长度限制。
相对GET更安全,参数不在URL中,但在请求体仍可能被拦截或泄露。
PUT上传或替换资源,常用于上传文件到服务器。常被禁用,因可被攻击者利用上传恶意文件,务必控制权限。
DELETE删除指定资源。操作危险,需严格权限校验,否则可能导致数据被恶意删除。
OPTIONS查询服务器支持的方法,返回所有允许的方法列表。可用于信息收集,发现隐藏API端点,注意不泄露不必要的接口信息。
HEAD只获取响应头,不返回响应体。可用于探测,通常不会被完整日志记录,可用于隐藏探测行为。
PATCH对已存在资源部分内容进行修改。需严格权限验证,否则可能被恶意修改数据。

状态码的含义

状态码是HTTP响应的重要部分,做渗透测试时,状态码能告诉你很多信息。

状态码说明常见场景/安全提示
2xx 成功
200 OK请求成功最常见的成功状态码
201 Created创建成功通常用于POST请求创建资源
204 No Content成功但无内容常用于DELETE等请求
3xx 重定向
301 Moved Permanently永久重定向,资源移动到新位置资源位置发生变化,SEO友好
302 Found临时重定向,资源暂时移动登录跳转、临时变更
304 Not Modified资源未修改,客户端可用缓存与缓存相关,可减少流量
4xx 客户端错误
400 Bad Request请求错误,参数有问题参数格式不对、缺失等
401 Unauthorized未授权,需要认证通常提示未登录、Token无效等
403 Forbidden禁止访问,权限不足已登录但无权限,或访问被禁止
404 Not Found资源未找到路径错误、接口不存在
405 Method Not Allowed请求方法不允许路径存在但方法不对(如GET被禁用,支持POST)
413 Payload Too Large请求体过大上传数据、文件等超服务器限制
429 Too Many Requests请求过于频繁限流机制,防止暴力破解
5xx 服务器错误
500 Internal Server Error服务器内部错误代码异常,常见可由SQL注入等漏洞导致
502 Bad Gateway网关错误,通常是代理服务器问题代理、负载均衡等场景容易遇到
503 Service Unavailable服务不可用服务器过载、维护、临时下线等

状态码能帮你快速定位问题。403说明路径存在,但没权限,可以尝试绕过,比如尝试其他路径或者修改权限。405说明路径存在,但方法不对,可以尝试其他方法,比如GET不行就试试POST。500说明代码执行了,但出错了,可能有注入漏洞,因为参数处理出错。429说明有速率限制,可以尝试绕过,比如换IP或者降低请求频率。

HTTPS vs HTTP

HTTPS就是在HTTP基础上加了TLS加密。很多人觉得用了HTTPS就安全了,其实不是。HTTPS只能保证传输过程的加密,不能保证服务器端的安全、客户端的安全、应用逻辑的安全。即使传输过程加密了,如果服务器端有漏洞,或者应用逻辑有问题,还是会被攻击。

做渗透测试时,经常需要抓HTTPS的包。方法很简单,安装Burp Suite的CA证书到浏览器,或者用mitmproxy等工具。这样就能看到HTTPS的明文内容了。

在测试中发现,很多系统的HTTPS配置存在问题。使用弱加密算法、证书配置错误、支持不安全的协议版本(如SSL 2.0),这些都是常见的问题。这些配置缺陷可能导致中间人攻击,或者被利用已知漏洞。

这些都可以通过工具检测,比如sslscan、testssl.sh,可以快速发现TLS配置问题。


Cookie、Session、Header

Cookie

Cookie是Web应用中最常用的会话管理机制。做渗透测试,你必须深入理解Cookie。

Cookie的结构:

name=value; attribute1=value1; attribute2=value2

常见的Cookie属性:

HttpOnly的作用是防止JavaScript访问Cookie,安全意义是防XSS攻击窃取Cookie。如果Cookie设置了HttpOnly,JavaScript无法通过document.cookie读取,这样即使有XSS漏洞,攻击者也无法窃取Cookie。测试方法是尝试用JavaScript读取Cookie,如果设置了HttpOnly,document.cookie读不到。

Secure的作用是只在HTTPS下传输Cookie,安全意义是防止中间人攻击窃取Cookie。如果Cookie设置了Secure,在HTTP下不会传输,只有在HTTPS下才会传输。测试方法是在HTTP下看Cookie是否传输,如果设置了Secure,HTTP下应该不传输。

SameSite的作用是防止CSRF攻击。值有三种,Strict最严格,跨站请求不发送Cookie,完全防止CSRF。Lax部分允许,GET请求可以跨站,POST请求不行,这是平衡安全和用户体验的折中方案。None允许跨站,但需要Secure,这是最宽松的设置。测试方法是构造CSRF攻击,看Cookie是否发送,如果设置了SameSite=Strict,跨站请求应该不发送Cookie。

Path的作用是指定Cookie的有效路径,安全意义是限制Cookie的作用范围。比如Path设置为/admin,那么这个Cookie只在/admin路径下有效。测试方法是在不同路径下测试Cookie是否有效,比如在/admin下有效,在/user下可能无效。

Domain的作用是指定Cookie的有效域名,安全意义是限制Cookie的作用范围。比如Domain设置为.example.com,那么这个Cookie在所有example.com的子域名下都有效。测试方法是在子域名下测试Cookie是否有效,比如在admin.example.com和user.example.com下是否都能用。

实战案例:Cookie安全问题

Set-Cookie: sessionid=abc123; Path=/

上面的系统问题有几个。没有HttpOnly,可能被XSS窃取,如果网站有XSS漏洞,攻击者可以通过JavaScript读取Cookie。 没有Secure,在HTTP下也传输,如果网站同时支持HTTP和HTTPS,在HTTP下Cookie也会传输,容易被中间人攻击窃取。没有SameSite,可能被CSRF利用,攻击者可以构造跨站请求,利用用户的Cookie进行操作。

攻击者可以通过XSS窃取Cookie,然后用这个Cookie登录了系统。这说明Cookie的安全配置很重要,如果配置不当,即使有XSS漏洞,也可能被利用。

Session

Session是服务器端的会话管理机制。客户端通过Session ID(通常存在Cookie里)来标识会话。

Session的工作流程:

Session的安全问题:

Session ID可预测,问题是如果Session ID是可预测的,比如基于时间戳生成,攻击者可以预测其他用户的Session ID,从而冒充其他用户。测试方法是注册多个账号,分析Session ID的规律,看看是否有可预测的模式。

Session固定攻击,问题是如果系统在登录后不重新生成Session ID,攻击者可以先获取Session ID,然后诱导用户登录,这样攻击者就能用这个Session ID访问用户的账号。测试方法是获取未登录的Session ID,登录后看Session ID是否变化,如果不变,就存在Session固定漏洞。

Session超时问题,问题是Session超时时间太长,或者登出后Session不失效,这样即使用户登出了,Session ID还能用,攻击者如果获取了Session ID,还能继续使用。测试方法是登录后登出,看Session ID是否还能用,如果还能用,就存在问题。

案例:Session固定攻击

一个简单的案例就是攻击者可以在未登录状态下,访问网站,获取Session ID:sessionid=abc123。然后诱导用户(或自己)用这个Session ID登录。 登录后,Session ID还是abc123,没有重新生成。这样攻击者就可以用这个Session ID直接访问用户的账号,因为Session ID没有变化,攻击者获取的Session ID在用户登录后仍然有效,可以冒充用户访问账号。

Header

HTTP Header包含很多信息,做渗透测试时,这些信息很有用。

常见的请求头:

Header 名称作用说明安全意义/风险渗透测试方法
User-Agent标识客户端类型,告知服务器使用的浏览器或工具可被用来识别爬虫或自动化脚本,错误判断可被绕过防护修改 User-Agent,看响应是否不同,判断系统是否依赖该头作安全策略
Referer标识请求来源,表明来源页面支持 CSRF 防护(判断来源是否同源),配置不当易被绕过删除或修改 Referer,看能否绕过 CSRF 防护,若无效说明防护不严格
Origin标识请求最初来源(CORS 相关),主要用于跨域请求作为 CORS 授权依据,CORS 策略配置不当可能被利用修改 Origin,测试服务器是否允许任意跨域来源,判断是否存在 CORS 问题
X-Forwarded-For标识真实客户端 IP(代理转发时使用)服务器信任该头可能被用于 IP 伪造,绕过 IP 限制修改 X-Forwarded-For,观察服务器行为,判断是否信任此头以检测 IP 伪造风险
X-Real-IP同 X-Forwarded-For,也用于标识真实客户端 IP也可能被用来 IP 伪造修改 X-Real-IP,同上,判断系统是否信任此头

常见的响应头:

响应头名称作用说明安全意义/风险渗透测试方法
Server标识服务器类型和版本,如 nginx/1.18.0攻击者可据此查找对应服务器版本的已知漏洞,发起定向攻击分析响应头,收集服务器类型和版本信息,查找对应漏洞数据库
X-Powered-By标识后端技术栈,如 PHP/7.4.3揭露后端框架信息,被攻击者针对已知漏洞利用分析响应头获取后端信息,结合技术栈公开漏洞库进行针对性检测
X-Frame-Options防止页面被iframe嵌入,实现点击劫持防护若未设置或配置不当,页面易被嵌入,从而被实施点击劫持攻击用iframe尝试嵌入目标页面,若可嵌入说明该头未生效,存在点击劫持风险
Content-Security-Policy
(CSP)
限制资源加载和脚本执行,有效防止XSS等攻击若策略不完善,攻击者可绕过CSP实施XSS等攻击分析CSP策略内容,判断是否存在配置漏洞,尝试已知绕过技巧验证效果

案例:通过Header绕过防护

假设一个系统根据User-Agent判断是否是爬虫,如果是爬虫就限制访问。如果系统只检查User-Agent,攻击者可以修改User-Agent为正常的浏览器,成功绕过限制。

另一个场景是系统根据Referer做CSRF防护,验证请求来源。如果系统只是简单检查Referer是否存在,攻击者可以删除Referer头,或者修改Referer为合法域名,可能就能绕过CSRF防护。这说明验证不严格,CSRF防护可能存在问题。


URL编码与参数传递

为什么需要编码?

URL中有些字符有特殊含义,比如?表示查询参数开始,&表示参数分隔符,=表示键值分隔符,#表示锚点,空格也需要编码。如果参数值中包含这些字符,就需要编码,否则会被解析成URL的语法,而不是参数值。

常见的编码方式

1. URL编码(Percent Encoding)

URL编码是最常见的编码方式,格式:%XX(XX是十六进制)

空格 → %20 + → %2B & → %26 = → %3D

在测试时,很多人经常用URL编码绕过WAF。WAF可能检测union select,但编码后union%20select可能检测不到,因为WAF可能只检测原始字符串,不检测编码后的。或者双重编码:union%2520select(%20编码成%2520),如果WAF只解码一次,可能检测不到,但服务器解码两次,就能正常执行。

2. Unicode编码

Unicode编码用于非ASCII字符:

中 → \u4e2d 文 → \u6587

实战应用:

某些系统可能对Unicode字符处理不当,可以用来绕过。比如文件名:test.txt → test\u002etxt(.的Unicode编码),如果系统对Unicode处理不当,可能可以绕过文件扩展名限制。SQL注入中:' → \u0027,如果系统对Unicode处理不当,可能可以绕过SQL注入过滤。

3. HTML实体编码

HTML实体编码用于HTML上下文:

< → &lt; > → &gt; & → &amp; " → &quot; ' → &#39;

实战应用:

在XSS测试中,如果输出在HTML上下文,可能需要用HTML实体编码。比如<script>alert(1)</script> → &lt;script&gt;alert(1)&lt;/script&gt;,这样HTML解析器就不会把它当作标签。但如果系统解码不当,可能可以绕过,比如系统对HTML实体解码了,但过滤不严格,可能可以绕过。

4. Base64编码

Base64不是URL编码,但经常用在参数传递中:

admin → YWRtaW4= password → cGFzc3dvcmQ=

实战应用:

很多系统用Base64编码参数,可能是为了隐藏参数内容,让参数看起来不那么明显。或者避免特殊字符问题,Base64编码后都是ASCII字符,不会有特殊字符。但Base64编码不是加密,可以轻松解码。在测试中,可以解码Base64参数,查看里面的内容,有时候能发现敏感信息或者可以修改的参数。

5. 双重编码/多重编码

有时候,系统会对参数进行多次编码,或者解码多次。这可能导致编码不一致,可以用来绕过:

原始:union select 一次编码:union%20select 二次编码:union%2520select(%编码成%25)

实战应用:

假设一个WAF拦截了union select,直接输入会被拦截。尝试URL编码一次union%20select,仍然被拦截。但编码两次union%2520select成功绕过。原因是WAF只解码一次,检测不到SQL注入,但服务器解码两次,得到原始的union select,成功执行。这说明编码不一致可能导致绕过,WAF和服务器对编码的处理不同,就可能被利用。

参数传递的位置

参数可以传递在多个位置,做渗透测试时,要测试所有位置:

1. URL参数(Query String)

GET /api/user.php?id=1&name=admin

2. POST Body

POST /api/user.php Content-Type: application/x-www-form-urlencoded id=1&name=admin

3. JSON Body

POST /api/user.php Content-Type: application/json {"id":1,"name":"admin"}

4. Cookie

Cookie: user_id=1; user_name=admin

5. Header

X-User-Id: 1 X-User-Name: admin

6. URL路径

GET /api/user/1/profile

实战技巧:

在测试时,应该测试所有可能的位置。常见的比如URL参数、POST Body,这些是最常见的参数传递位置。不常见的比如Header、Cookie、路径,这些位置也可能传递参数。有时候,系统在不同位置对参数的处理不同,可能某个位置有漏洞,另一个位置没有,所以要多测试几个位置,才能发现漏洞。

编码绕过案例

让我给你一个完整的编码绕过案例:

场景:测试一个搜索功能,参数是keyword

步骤1:正常测试

GET /search?keyword=test

响应正常。

步骤2:尝试SQL注入

GET /search?keyword=test' OR 1=1--

响应:被WAF拦截。

步骤3:尝试URL编码

GET /search?keyword=test%27%20OR%201%3D1%2D%2D

响应:还是被拦截。

步骤4:尝试双重编码

GET /search?keyword=test%2527%2520OR%25201%253D1%252D%252D

响应:成功绕过WAF,返回了所有结果。

分析:

WAF只解码一次,所以%27被解码成',被检测到SQL注入。双重编码后,WAF解码一次得到%27,检测不到SQL注入,因为WAF认为这是编码后的字符,不是SQL注入。但服务器解码两次,得到',成功注入。这说明编码不一致可能导致绕过,WAF和服务器对编码的处理不同,就可能绕过。

图片描述:一个展示URL编码绕过WAF的流程图,展示从原始payload到URL编码、双重编码的过程,以及WAF和服务器对编码的不同处理方式


完整的请求分析示例

让我们用一个完整的案例,把这一节课的内容串起来。

目标:分析一个登录功能的HTTP请求和响应

步骤1:抓取请求

用Burp Suite抓取登录请求:

POST /api/login HTTP/1.1 Host: target.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Accept: application/json Content-Type: application/json Origin: https://target.com Referer: https://target.com/login Cookie: csrftoken=abc123def456 Content-Length: 52 {"username":"admin","password":"password123"}

步骤2:分析请求

请求方法是POST(适合传输敏感信息),Content-Type是application/json(JSON格式),Cookie包含CSRF token,请求体是JSON格式的用户名和密码。

步骤3:分析响应

HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Mon, 01 Jan 2024 12:00:00 GMT Content-Type: application/json Content-Length: 245 Set-Cookie: sessionid=xyz789abc123; Path=/; HttpOnly; Secure; SameSite=Strict Set-Cookie: csrftoken=newtoken123; Path=/; Secure; SameSite=Strict X-Powered-By: PHP/7.4.3 Connection: keep-alive {"status":"success","message":"Login successful","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjA5NDU2MDAwfQ.xxx"}

步骤4:安全分析

Server头泄露了服务器类型和版本(nginx/1.18.0),X-Powered-By头泄露了后端语言和版本(PHP/7.4.3),Cookie安全属性有HttpOnly(防XSS)、Secure(只在HTTPS传输)、SameSite=Strict(防CSRF),响应体包含JWT token,可以用来后续认证。

步骤5:测试点

基于这个分析,可以测试的点有几个。SQL注入,在username和password字段尝试注入,看看是否有SQL注入漏洞。JSON注入,尝试在JSON中注入特殊字符,看看系统对JSON的处理是否安全。CSRF,测试CSRF token的验证,看看CSRF防护是否严格。Session管理,测试Session ID的生成和验证,看看Session是否安全。信息泄露,Server和X-Powered-By头泄露了信息,可以用来查找已知漏洞。


总结

HTTP协议是基础,不理解HTTP,做不好渗透测试。HTTP协议是Web应用的基础,所有的Web应用都基于HTTP协议,如果不理解HTTP协议,就无法理解Web应用的工作原理,也就无法做好渗透测试。 请求和响应结构,每个部分都可能有问题。请求行、请求头、请求体,响应状态行、响应头、响应体,每个部分都可能存在安全问题,都需要仔细分析。

Cookie和Session是会话管理的核心,也是安全问题的重灾区。Cookie和Session的安全配置很重要,如果配置不当,可能导致XSS、CSRF等攻击。Session ID的生成和验证也很重要,如果Session ID可预测,或者存在Session固定漏洞,都可能导致安全问题。 Header信息可能泄露信息,也可能用来绕过防护。响应头可能泄露服务器信息、后端技术信息,可以用来查找已知漏洞。请求头可能用来绕过防护,比如修改User-Agent、Referer等。

编码方式很重要,理解各种编码,才能绕过WAF和过滤。URL编码、Unicode编码、HTML实体编码、Base64编码等,理解这些编码方式,才能在测试中绕过WAF和过滤,发现漏洞。

下一节课,我们会学习渗透测试方法论。这是做渗透测试的"总指导",告诉你应该怎么系统性地进行测试。

记住:技术基础不扎实,后面的漏洞理解起来会很困难。如果你对这一节课的内容还有疑问,建议多实践,可以尝试用Burp Suite多抓几个包,多分析几个请求和响应。

实践建议: 安装Burp Suite,配置好代理,访问几个网站,抓取登录、注册等功能的请求,分析请求和响应的每个部分,尝试修改参数,看响应有什么变化,理解各种编码方式,尝试用编码绕过一些简单的过滤。

  • HTTP/HTTPS协议
    • HTTP请求结构
    • HTTP响应结构
    • 常见的HTTP方法
    • 状态码的含义
    • HTTPS vs HTTP
  • Cookie、Session、Header
    • Cookie
    • Session
    • Header
  • URL编码与参数传递
    • 为什么需要编码?
    • 常见的编码方式
    • 参数传递的位置
    • 编码绕过案例
  • 完整的请求分析示例
  • 总结

目录

  • HTTP/HTTPS协议
    • HTTP请求结构
    • HTTP响应结构
    • 常见的HTTP方法
    • 状态码的含义
    • HTTPS vs HTTP
  • Cookie、Session、Header
    • Cookie
    • Session
    • Header
  • URL编码与参数传递
    • 为什么需要编码?
    • 常见的编码方式
    • 参数传递的位置
    • 编码绕过案例
  • 完整的请求分析示例
  • 总结