关于BMZCTF hitcon_2017_ssrfme的解法

在BMZCTF中,有一道题是hitcon_2017_ssrfme,在尝试做了该题后,又翻看了现有的write-up,发现现有的write-up语焉不详,对于不原理和微操讲解不细,因此写了这篇文章,主要是在前人的基础上对此题进行进一步描述,主要针对刚接触此领域的小白用户,希望能够对他们理解这道题提供帮助。
首先,打开本题,可以看到下列代码:

 <?php 
    $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]); 
    @mkdir($sandbox); 
    @chdir($sandbox); 

    $data = shell_exec("GET " . escapeshellarg($_GET["url"])); 
    $info = pathinfo($_GET["filename"]); 
    $dir  = str_replace(".", "", basename($info["dirname"])); 
    @mkdir($dir); 
    @chdir($dir); 
    @file_put_contents(basename($info["basename"]), $data); 
    highlight_file(__FILE__); ?>

简要分析上述代码,基本功能是这样的:
首先,为每一个用户建立沙箱,路径是在本地路径的基础上/sandbox/【字符串“orange”和ip地址】的md5码。
然后进入该沙箱进行工作。
然后执行get命令,(在这里,get是perl的一个命令,可以对远程的文件进行拉取)get命令的参数(用户通过url变量的方式进行get传入)可以被控制,但是后台使用了escapeshellarg对用户输入进行过滤。(不能使用传统的||链接符的方式进行命令执行)
然后根据用户get方式传入的filename变量,将上述命令执行的结果,放入到filename中,并且,对filename进行了限制,不允许通过…/的方式改变传入文件的位置。如果filename有地址,则会把当前目录改变到filename绝对路径下。
最后,把data中的内容(执行get 命令的结果)传入到filename中。

这道题突破点都在第五行,即执行的GET命令上,必须对perl中GET命令缺陷有了解,才能找到对应的思路。
这道题有两种解法,第一种需要一个公网服务器,在服务器上创建一个本地payload,然后控制url参数访问本地的payload,之后就能够反弹得到shell了;下面我主要来讲解一下第二种,即利用GET中的open函数漏洞。
open函数在GET命令被调用时执行,也就是第五行执行GET命令时,perl语言会调用open命令,漏洞就存在于open命令对于文件的处理上,关于这个漏洞,外国人有文章,是这样写的:
Perl saw that your “file” ended with a “pipe” (vertical
bar) character. So it interpreted the “file” as a command to be executed, and interpreted the command’s output as the “file”'s contents. The command is “who” (which prints information on currently logged-in users). If you execute that command, you will see that the output is exactly what the Perl program gave you.
翻译过来意思是:
perl函数看到要打开的文件名中如果以管道符(键盘上那个竖杠)结尾,就会中断原有打开文件操作,并且把这个文件名当作一个命令来执行,并且将命令的执行结果作为这个文件的内容写入。这个命令的执行权限是当前的登录者。如果你执行这个命令,你会看到perl程序运行的结果。

因此,我们可以构造这样的payload:
首先:
url=【任意】&filename=cat /flag|
如下所示:
第一步:构造payload文件
之所以要进行这一步,是因为构造一个文件名为cat /flag|的文件,open函数只有在找到指定文件文件名的情况下才会把该特殊形式的文件当作命令在执行。
完成这一步,访问cat /flag|文件,会发现该文件存在(具体内容是什么不重要),如下所示:
在这里插入图片描述
其次,
url=file:cat /flag|&filename=/123.txt
如下所示:
第二步
之所以要进行这一步,是因为url要作为open的一个参数,打开上述构造好的文件,前面已经讲过,当文件名以管道符结尾时,该文件名所指的命令会被中断执行,及cat /flag会被执行,并且根据这道题的特性,该命令执行的结果会被写入到filename所指定的文件中,因此,访问filename所指定的文件,就可以看到结果了。如下所示:
结果

最后,为了照顾小白,在这里讲解一下sandbox和flag位置的问题,大神们可以直接略过:
sandbox的问题很好解决,直接百度搜索【IP地址】,就可以查看自己所连入的第一个公网IP,其次用orange和IP地址组合后,生成md5码即可,这里就不再详述了。
至于为什么知道flag位置是/flag,其实这是BMZCTF的“惯例”,如果要对此较真,也可以在一开始执行ls /命令,进而找到/flag的位置。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永远是少年啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值