浅谈CTF中代码审计PHP死亡退出
前言:遇到一个代码审计的题目,略有思考。记录一下~
源码就是这样的
<?php
show_source(__FILE__);
$content = '<?php exit; ?>';
$content .= $_POST['data'];
file_put_contents($_POST['filename'], $content);
.=
就是拼接。前面的$content
已经给了<?php exit; ?>
,所以说不管后面是什么,都会先执行退出。导致后面的语句不执行。这也叫PHP死亡退出。
P神的讲解
实战中会比较多的在缓存和配置文件里。
绕过其实也很简单,POST方式提交了参数,这个是可控的,所以尝试PHP伪协议来进行写入一句话,并且使用base64-decode去除死亡退出。
- 利用
php://filter
流的base64_decode
函数特性去除死亡exit - base64编码中只包含64个可打印字符,在解码的时候,遇到这64个之外的字符,就会略过
<?php exit; ?>
这条代码base64解码时,会解码为phpexit
- base64解码是四个byte一组,所以再增加一个字符,凑够两组,后面的就会正常解码
在本地进行实验
payload
filename=php://filter/write=convert.base64-decode/resource=shell.php&data=aPD9waHAgcGhwaW5mbygpOyA/Pg
查看网站目录成功写入
内容是
可以看到已经绕过了exit。直接执行我写入的PHP语句了。
自己的理解:原本不管写入什么都是拼接在<?php exit;?>
后面的,像这样
执行一下是什么都没有。
因为先执行了exit
退出了。
还有今天下午的慕测平台的软件测试大赛,比较菜就做出来两个,一个是git泄露,一个是文件上传。第一题跟这个类似。
源码是
<?php
show_source(__FILE__);
$filename = $_REQUEST['file'];
$data = '<?php exit();?> ' . $filename;
file_put_contents($filename,$data);
这个题,可能是运维师傅给的权限太高了,直接将写权限给出来了,就有人搅屎,把index.php给删了。然后网站就访问不了了。
解题过程中这个没想明白的是$_REQUEST
虽然是集合get和post的请求方式,但是这个两个都是request,就有点难以理解。我进行复现时是这样的。
就会有报错,内容是,file_put_contents()
需要两个参数,而此请求只提供了一个。
所以无法成功执行。
还有就是如果使用base64-decode
file=php://filter/write=convert.base64-decode/resource=shell.php&file=aPD9waHAgZmlsZV9nZXRfY29udGVudHMoImZsYWcucGhwIikgPz4=
是可以成功写入,但是写入的是这样的。而且文件名也是base64编码。无法利用。
目前思路卡在这里。不知道有没有wp,或者回头问问其他师傅们。
看到的师傅们如果了解还请指点一下,感谢!