通用web漏洞应急排查思路(二)
什么是开放重定向
开放重定向这个漏洞,在渗透报告里出现频率很高,但很多人对它的危害估计不足。简单来说,就是网站在做跳转时没有对目标 URL 做任何校验,攻击者只要构造一个”看起来是正规站点”的链接,就能把用户悄悄送到钓鱼页面去。
用户看到的链接是 http://yourcompany.com/redirect?url=http://attacker.com,域名前半截是自己公司的,根本没有戒心,点进去就中招了。
攻击面有哪些?
开放重定向的触发点比想象中要多:
- 最常见的是 URL 参数直接拼接跳转,比如
?next=、?url=、?redirect=这类参数名 - JavaScript 里直接用
window.location跳转,但目标地址来自用户可控的输入 - HTML meta refresh 标签的
content里拼了外部 URL - 服务端 HTTP 响应头
Location里的值没过滤
危害不止是跳转
攻击者用这个漏洞做钓鱼是最直接的场景,但还有一种场景更隐蔽——结合 OAuth 登录流程,把 redirect_uri 改成自己的服务器,直接截获 token。此外,跳转到恶意页面还可能触发浏览器漏洞或强制下载恶意文件,用户毫无感知。
如何在日志里找到它
SOC 分析师在排查时,重点看 GET 请求里的 query 参数是否包含外部 URL 结构。有一个实用的 Nginx 日志正则:
/^.*"GET.*\?.*=(https%3a%2f%2f[a-z0-9-]+%2e[a-z]{2,}).+?.*HTTP\/.*".*$/gm
注意,攻击者经常对 URL 做编码混淆,比如 %3a 是冒号,%2f 是斜杠,直接看 raw 日志会漏掉。碰到在几秒内来自同一个 IP、连续请求同一个参数名的情况,基本可以断定是工具在自动化扫描。
还有一些绕过 WAF 的花样要留意:
- 用
http://[::]:80/这种 IPv6 写法 - 十进制编码 IP:
http://2130706433/其实是http://127.0.0.1 - 十六进制:
http://0x7f000001/
怎么防
开发层面核心就两点:用白名单控制允许跳转的域名,别信任任何用户传进来的 URL。PHP 里可以用 filter_var($url, FILTER_VALIDATE_URL) 做基础校验,但更稳的做法是直接维护一个允许跳转的域名列表,匹配不上就拒绝。
目录遍历:文件路径操控的攻击手法
目录遍历(Directory Traversal)也叫”点点斜杠攻击(dot-dot-slash attack)”,利用的是 Web 应用在拼接文件路径时没有做边界限制,导致攻击者可以跳出 Web 根目录,访问系统上任意文件。
比如一个查看图片的接口长这样:
http://example.com/profiles/picture.php?name=user1.jpg
攻击者只需要把参数改成:
http://example.com/profiles/picture.php?name=../../etc/passwd
如果代码里直接把参数值和路径拼起来,就会读到 /etc/passwd,服务器上的账号信息直接暴露。
和 LFI 有什么区别
新手容易把目录遍历和本地文件包含(LFI)搞混。区别在于攻击的切入点不同:目录遍历是直接操控文件路径参数去读文件;LFI 则是利用 include() 这类函数,把用户输入当作文件名包含进来执行。后者危害更大,因为有代码执行的可能。
触发入口在哪
- URL 里的文件名参数,最直接
- Cookie 里存了文件路径,然后服务端用来读文件
- HTTP 请求头,比如
Referer或自定义头被用于文件操作 - 直接构造文件下载请求
日志特征
检测时最核心的关键词就是 ../,以及它的各种编码变体:
| 形式 | 内容 |
|---|---|
| 原始 | ../ |
| URL 编码 | %2e%2e%2f |
| 双重编码 | %252e%252e%252f |
| 混合编码 | ..%2f、%2e%2e/ |
Nginx 日志里检测编码后的目录遍历可以用:
/^.*"GET.*\?.*=(%2e%2e%2f).+?.*HTTP\/.*".*$/gm
防御要点
代码层面,用 realpath() 取绝对路径之后,再判断这个路径是否还在允许的根目录下面,这是最可靠的方式。同时对文件名做正则校验,只允许字母、数字、下划线、连字符,遇到任何 .、/、\ 直接拒绝。WAF 也要配置对应的规则,因为手动覆盖所有编码变体基本不现实。
暴力破解:最原始也最有效的攻击
暴力破解(Brute Force)听起来很”蛮力”,但在实战里效果出奇的好,原因很简单——很多系统没有任何限制,攻击者可以无限次尝试密码,配上字典或者彩虹表,大量弱口令分分钟就被拿下。
攻击类型比你想的要多
暴力破解不只是”猜登录密码”这一种。针对 Web 应用,常见的还有:
- 目录爆破:用 dirsearch、gobuster 这类工具扫描服务器上隐藏的目录和文件,找到没有权限控制的后台或备份文件
- 密码喷洒(Password Spraying):用一个常见密码(比如
Welcome123)去试一大批账号,避开单账号多次失败触发的锁定机制 - 凭证填充(Credential Stuffing):把从其他地方泄露的账号密码组合,直接来试,成功率在有密码复用习惯的用户里相当高
看日志有什么规律
暴力破解在日志里的特征相对明显。主要看几个维度:
- 同一个 IP 大量 POST 请求到登录接口,状态码密集出现 401 或 403
- 时间间隔极短,正常人登录不会 1 秒发 50 个请求
- User-Agent 固定,自动化工具通常不会每次随机换 UA
- 成功登录前有大量失败记录,然后突然出现一个 200 或 302
检测 Nginx 日志里的暴力破解,可以用这个正则匹配失败的登录尝试:
/^(\S+) \S+ \S+ \[.*?\] "(POST|GET) \/login\.php.*?" (401|403) \d+ ".*?" ".*?"/gm
捕获到的第一个分组就是攻击者 IP,统计它出现的次数,超过阈值直接加黑名单。
事后能做什么
检测到暴力破解后,处置思路:
- 用 Fail2ban 自动根据日志特征封 IP,不需要人工干预
- Nginx 配置里加
deny规则,把问题 IP 段直接丢弃 - 结合 SIEM 查这个 IP 有没有其他攻击行为,判断是不是更大攻击链的一部分
防御不是靠一招
账号锁定策略、CAPTCHA、限速、MFA,这几个缺一不可。WAF 可以做 IP 信誉过滤和行为分析,但不能当作唯一防线——复杂的攻击者完全可以换 IP 池绕过。本质上还是要做多层防御,弱密码、没有 MFA 的账号永远是最脆弱的一环。
XXE:XML 解析器中的漏洞
XXE(XML External Entity)是一个在代码审计和渗透测试里经典到不能再经典的漏洞,但在生产环境里依然反复出现,原因是开发者对 XML 解析器的默认行为了解不够。
先理解 XML 的”外部实体”是什么
XML 允许在文档里定义”实体(Entity)”,外部实体可以引用文件系统上的文件或者远程 URL。本来是为了方便复用内容设计的,但如果解析器在处理用户提交的 XML 时不加限制,攻击者就可以定义一个指向 /etc/passwd 的外部实体,然后让服务端把这个文件内容输出出来。
一个典型的 XXE payload 长这样:
<?xml version="1.0"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <data>&xxe;</data>
解析器一执行,/etc/passwd 的内容就被填进了 <data> 标签里。
可能触发的地方
- 接收 XML 格式 body 的 API 接口(REST 或 SOAP)
- 网站上传 XML 或 Office 文件的功能(Word/Excel 本质上是 ZIP + XML)
- 配置文件导入功能
危害有多大
XXE 的利用方式随着目标环境不同有很大差异:
- 文件读取:最直接,读敏感配置文件、私钥
- SSRF:把外部实体的 URL 指向内网地址,借服务端发起内网请求,可以用来探测内网服务
- 拒绝服务(Billion Laughs):定义层层嵌套的实体引用,指数级消耗内存,把解析器搞崩
- RCE:在特定语言和配置下,XXE 可以链接到远程代码执行
日志里怎么找
XXE 攻击的 payload 里有几个关键词,几乎在所有攻击场景下都会出现:
DOCTYPEENTITYSYSTEMfile://http://(外带数据时会有外部 URL)
在 Nginx 日志里检测包含 DOCTYPE 关键字的请求:
^(\S+) - (\S+) \[(.*?)\] "(\S+) (.*?)\?(?=.*?\b21DOCTYPE\b).*? HTTP\/\d\.\d" (\d+) (\d+) "(.*?)" "(.*?)"
另外,盲 XXE(Blind XXE)不会在响应里直接返回文件内容,而是通过 DNS 查询或 HTTP 请求把数据带出去,在日志里可能只能看到异常的外联请求。这时候要结合 DNS 日志或防火墙出站流量一起分析。
PHP 和 Java 各有坑
PHP 的 DOMDocument 默认允许加载外部实体,必须手动调用 libxml_disable_entity_loader(true) 来禁用。Java 的 DocumentBuilder 同样默认不安全,需要显式配置 setFeature 来关掉外部实体和 DOCTYPE 处理。这种”默认不安全”的设计,是这个漏洞长期存在的根本原因。
总结
这四类攻击——开放重定向、目录遍历、暴力破解、XXE——看起来各不相同,但背后有一个共同的根:对用户输入的信任。无论是跳转 URL、文件路径、登录凭据还是 XML 数据,只要来自外部,就必须当作不可信的数据来处理。
从应急响应的角度看,这些攻击留下的日志特征都是可以规律化的。建立好正则规则、配合 SIEM 做聚合分析,大多数情况下都能在攻击尚未成功时发现异常。真正棘手的是那些低频、慢速、多 IP 轮换的攻击,这时候行为基线分析比单纯的规则匹配更有价值。
赞赏
微信赞赏
支付宝赞赏
发表评论