RCE技巧
- Linux命令长度限制突破方法
- 8个字符限制绕过
- 过滤英文字母和数字
- php版本7
- php版本5
Linux命令长度限制突破方法
8个字符限制绕过
<?php
<?php
$param = $_REQUEST['param'];
if (strlen($param) < 8) {
echo shell_exec($param);
}
shell_exec — 通过 shell 执行命令并将完整的输出以字符串的方式返回,通过shell环境执行命令
这里长度做了限制,只能执行比较短的命令,但是还是需要写shell才能执行,那想一想Linux那些命令存在且最短,那就有个重定向>,比如w>a,w就是一些登录的信息,将w的输出重定向到a
这样也ok,只是a里面没有内容
想一想sh 0,sh就是bash,执行0嘛,如果0是一个文件,是不是就可以执行0里面的命令了,就比如shell脚本有个a.sh,bash a.sh就执行了。直接去创建文件下写命令太长了那不实际被限制长度了,那就用这样的方法将这些文件名通过一些排列组合拼接好,写到一个其他文件去,就是多个文件排列组合成一句话木马,再将这些木马写到一个文件里面去,再用sh执行那就ok了
那就比如可以通过时间的顺序,那最新写的就排到最前面了
但是注意php一句话基本有特殊字符的,所以要用base64的方式写入
在页面执行,这里为了展示清楚
直接执行就好了
过滤英文字母和数字
php版本7
<?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__);
}
这里采用的是无字母数字的构造技巧
PHP7前是不允许用($a)();
这样的方法来执行动态函数的,但PHP7中增加了对此的支持。所以,我们可以通过('phpinfo')();
~取反操作,组成原理不是有原码,反码,补码,取反就是反码操作
那先urlencode();编码操作,因为要放在url地址栏里面
用$code接受,取反再取反就是phpinfo()了,但是这里是php7的版本,但是在php5的版本不行
这样就可以绕过了
php版本5
那在5.6的版本呢
那不管有没有接受post参数我都可以向程序post一个文件,然后生成一个临时文件,但是post了临时文件,php不接收,快速将文件的删除掉了,那咋做,那我们测试下临时文件是咋样的
可以开开上传文件的配置
看临时文件生成了
但是临时文件没内容是因为咱php没写内容
那该写啥,改写的是系统命令
再看一眼发现临时文件果然被删了,那我们考虑下,上传成功后再临时文件没删除时执行命令
emmmm但是咋匹配呢,临时文件不让用英文和数字,那总不能ls -la /* /去匹配吧,这么多,而且还有字母,ls -la /???/??? 用和?这样匹配都ok,但是也多啊,而且临时文件是没有x的执行权限的额,但是在linux中就算没有执行权限,但是可以用点加上空格就可以实现
/bin/bash a.txt 虽然能执行但是有英文
post提交是提交到我们的代码里面,post的请求和get请求是同时触发的
那我们再看看临时文件的不同之处,就是最后一位是大写字母,linux文件里面最后一位大写还是蛮少的,但是这个提交几率一半一半多试几次就好了,那咋匹配大写,那看看网上的ascii表
那linux的啥方法,linux的通配符称为glob通配符,那就查查它的规范,原来它是shell中的路径通配符,那咋匹配一个范围,那我匹配大写字母也就是 @到 [ ,那创建个文件试一试
linux的通配符官方文档看看: https://man7.org/linux/man-pages/man7/glob.7.html
它说匹配的是一个范围,那说明思路没错
诶嘿,找到了
ok开干,上传文件改,要post文件,临时文件才会生成,又到了burpsuit的时刻
eval传参开始是有php开始标签的,先闭合再写php代码,?><?= `. /???/????????[@[]`%3b?> HTTP/1.1
=相当于php7的语法,开启一个短链接,可以不写<?php
一直执行匹配,一个执行. eval不能执行linux命令,只能执行php代码,但是
再linux可以执行命令
但是get传参要遵循urlcode编码,不要有空格,@,-,?
?code=?><?= `.+/%3f%3f%3f/%3f%3f%3f%3f%3f%3f%3f%3f[%40-[]`%3b?>HTTP/1.1