RCE漏洞原理及利用
引路题QAQ:NSSCTF-[SWPUCTF 2021 新生赛]babyrce,窝的博客里题解部分也有详解嘿嘿()
一、RCE漏洞概述
web的应用开发中常常为了灵活性与简洁性,让应用调用代码执行函数或系统命令执行函数处理,如果对用户输入过滤不严,容易产生远程代码执行漏洞或命令执行漏洞。
RCE漏洞分为两类:
远程命令执行漏洞(Remote Command Execution)和远程代码执行漏洞(Remote Code Execution)
它们的成因分别为:
应用程序需要调用外部操作系统命令来完成特定功能(例如,网络诊断工具中的 ping 或 traceroute,文件处理,系统管理任务)。如果应用程序将用户可控的输入(如 IP 地址、文件名、搜索词等)直接或不安全地嵌入到将要执行的命令字符串中,攻击者就可以注入额外的命令。
应用程序使用了能将字符串作为代码执行的函数(如 PHP 中的 eval()、assert(),Python 中的 exec()),并且将用户可控的输入传递给了这些函数。或者,存在反序列化漏洞、模板注入、不安全的文件包含等,允许用户输入影响代码执行流。
二、常见的RCE漏洞函数
1.系统命令执行函数
1).system() ;这个相信大家都不陌生(抬头不见低头见),能将字符串作为命令执行并返回结果;
2).exec() ; 也能将字符串作为命令执行,但是只能返回结果的最后一行(至今不知道有什么用emmmmmm);
3).shell_exec() ; 能执行命令但不返回结果;
4).passthru(); 能将字符串作为命令执行,只调用命令不返回任何结果,但把命令的运行结果原样输出到标准输出设备上(这里指的是命令的执行状态,0代表成功,非0代表失败)
二编warnings:system不需要提供output函数,他是直接把结果返回出来,同样return_var是执行的状态码;
而exec函数需要提供$output函数才能,且返回的数据是array类型;
shell_exec则与exec类似。
1 | system() # 语法 : system(string $command, int &$result_code = null) |
三、具体利用
1.文件包含
对于文件包含所常用的命令拼接方式:
1)使用(;)分隔
eg.
1 | c1;c2;c3 |
无论c1是否成立,该语句都会按顺序依次执行所有命令。
2)使用逻辑与 (&&) 和逻辑或 (||)
1 | c1&&c2 //只有当左边的命令成功执行(返回状态码为 0)时,才会执行右边的命令。 |
3)命令替换
$( ... ):
1 | c1 $(c2) |
命令替换会将命令的输出替换到当前命令中。
2.绕过技巧
过滤cat
用类似命令代替:
1 | tac:反向查看。 |
eg.[FSCTF 2023]Hello,you
这题就是经典的cat过滤,我们在注入fla*通配符时回显flag.php;我们尝试cat被拦截后使用 ; more fla*,成功得到flag。
过滤flag
- 通配符绕过:
?:代表单个字符。*:模糊匹配,代表任意字符串。 如:cat fla*或者cat fla?- 或者用反斜线绕过
如:cat fla\g
- 单引号或者双引号绕过 如cat f’‘lag或者cat f’‘l’‘a’'g
3.无字母RCE
eg.[HUBUCTF 2022 新生赛]HowToGetShell
1 | <?php |
首先我们明确思路,我们的核心目的就是不使用字母、数字,去构造诸如 assert、system 函数的字符串,然后利用动态执行的方法进行调用。
我们就能想到异或,构造payload如下:
1 | mess=$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');$___=$$__;$_($___[_]); |
除了异或外,我还在网上看到了一些其他的思路:
方法二 取反
该方法利用的是UTF-8编码的某个汉字,并将其中某个字符取出来。
可以看到,当我们对一个中文取反的话会返回大小写字母以及特殊字符,那么我们配合索引进行取值即可,帅字在 UTF-8 编码中占用了3个字节,具体的UTF编码为: \xe5\xb8\x85, php 将字符串视为字节数组,所以在PHP中可以将其看做是包含三个字节的数组。
使用 帅[1] 的结果是 \xb8 经过取反之后得到字母 G。
具体取反过程如下:
-
先将十六进制
b8转为二进制。 -
再将
b8的二进制进行按位取反,0变成1,1变成0。 -
最后再将得到的二进制转为十进制与
ASCII表中进行比对,最终找到字母G。获取字符的脚本:
1 | <?php |
脚本来源:(▽)
4.无参RCE
可能用的到的函数
1 | localeconv() – 函数返回一个包含本地数字及货币格式信息的数组 第一个是. |
eg.[HNCTF 2022 WEEK2]Canyource
Leave a comment