题目信息
- 赛事:Bugku CTF
- 题目:
本地管理员 - 考点:X-Forwarded-For 绕过 IP 限制 + 信息泄露
解题过程
1. 信息收集
-
访问题目链接,显示登录表单,无有效提示信息
-
尝试任意账号登录(如
admin/123456),返回错误:IP禁止访问,请联系本地管理员登陆,IP已被记录. -
查看页面源码(F12),发现注释中的 Base64 编码:
html<!-- dGVzdDEyMw== --> -
解码后获得潜在密码:
test123
2. 漏洞利用
- IP 绕过 :
- 使用 Burp Suite 拦截登录请求
- 在请求头中添加
X-Forwarded-For: 127.0.0.1(伪造本地访问) - 重放请求后,IP 限制提示消失,返回新错误:
身份信息错误
- 凭证爆破 :
- 尝试常见管理员账号(
admin、administrator) - 结合源码泄露的密码
test123进行组合测试 - 成功登录的组合:
admin+test123
- 尝试常见管理员账号(
3. Flag 提取
-
登录后页面返回 Flag:
flag{xxx}
原理总结
一、漏洞原理分析
1. X-Forwarded-For 绕过机制
- 设计缺陷 :
服务器仅通过X-Forwarded-For头获取客户端 IP,未校验该头真实性 - 本地特权逻辑 :
访问控制策略为if (client_ip == "127.0.0.1") { grant_access(); } - 伪造原理 :
添加X-Forwarded-For: 127.0.0.1使服务器误判请求来源为本地
2. 信息泄露风险
- Base64 编码的密码
dGVzdDEyMw==直接暴露在 HTML 注释中 - 攻击者可通过简单解码获取凭证(
test123)
3. 认证逻辑缺陷
- IP 验证与身份认证分离:
访问登录页
触发IP限制
源码泄露密码 test123
Burp抓包
添加X-Forwarded-For:127.0.0.1
绕过IP限制
尝试admin/test123
获取flag
- 二者无强关联,导致绕过 IP 限制后可直接尝试凭证
二、防御方案
1. 安全 IP 验证实现
python
# Python Flask 示例:校验代理链可信度
TRUSTED_PROXIES = ["10.0.0.1", "192.168.1.100"] # 可信代理白名单
def get_client_ip():
remote_ip = request.remote_addr
xff = request.headers.get("X-Forwarded-For", "")
if xff and remote_ip in TRUSTED_PROXIES:
# 从右向左取第一个非可信代理 IP
for ip in reversed(xff.split(",")]):
ip = ip.strip()
if ip not in TRUSTED_PROXIES:
return ip
return remote_ip # 无代理或不可信代理时直连 IP
2. 敏感信息保护
- 禁止在 HTML/JS 中硬编码凭证(即使编码)
- 使用后端配置文件管理密钥,避免前端泄露
3. 认证逻辑加固
-
双重验证 :
pythonif get_client_ip() == "127.0.0.1" and validate_credentials(user, pwd): grant_access() -
动态二次认证 :
管理员登录需短信/邮箱验证码(即使 IP 可信)
三、同类题目通用解法
| 步骤 | 操作 |
|---|---|
| 信息收集 | 1. 检查页面源码注释/JS 文件 2. 触发错误消息(如 IP 限制)获取线索 |
| 绕过限制 | 1. 尝试 X-Forwarded-For: 127.0.0.1 2. 补充 X-Real-IP: 127.0.0.1 等头 |
| 凭证获取 | 1. 爆破常见账号(admin/root) 2. 结合泄露信息(Base64/明文)尝试密码 |
| Flag 提取 | 登录后检查 Cookie/响应正文/网络请求(常见于 /flag 接口) |
关键技巧:
Burp 自动化 :通过
Match and Replace自动添加伪造头编码识别 :Base64 特征(结尾
=号)、Hex 编码等优先解码IP 绕过组合技 :
httpX-Forwarded-For: 127.0.0.1, 192.168.1.100 X-Real-IP: 127.0.0.1 Client-IP: 127.0.0.1