前言
我们下面进行下一个漏洞——RCE的学习。RCE是常见漏洞之一,是Web安全必学漏洞。
我们用一张图简述本文的内容:
什么是RCE?
漏洞介绍
RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
RCE主要指远程代码执行和远程命令执行,CTFHub中将文件包含漏洞也看作RCE漏洞。
漏洞分类
一、远程命令执行
二、远程代码执行
三、文件包含漏洞
实际上,RCE主要是remote code execute(远程代码执行)和remote command execute(远程命令执行)的缩写,但有时把文件包含漏洞也归为其中。
命令执行和代码执行的联系及区别
这两者的区别主要在于命令执行是调用操作系统命令进行执行,而代码执行是调用服务器网站的代码进行执行。
但代码执行在利用过程中往往会通过调用网站代码去执行系统命令,两者是相互联系的,故统一归类于RCE。
远程命令执行
介绍
一、定义及原理
远程命令执行,顾名思义就是可以远程执行系统命令。
该漏洞的出现是由于应用系统从设计上需要给用户提供指定的远程命令操作的接口,例如在防火墙的WEB界面中会存在一个故障排除功能,里面就会存在类似Ping操作的界面,若设计者未针对这类功能进行严格的控制检测,则可能导致攻击者提交恶意命令,从而控制后台,控制服务器。
简单来说,根据设计需求,有时会允许用户执行系统命令,要是不对用户的行为进行限制,用户就可以随意执行系统命令,造成危害,这就是远程命令执行。
二、成因
- 代码层过滤不严
- 系统的漏洞造成命令注入
- 调用的第三方组件存在代码执行漏洞常见的命令执行函数
- PHP:exec、shell_exec、system、passthru、popen、proc_open等
- ASP.NET:System.Diagnostics.Start.Process、System.Diagnostics.Start.ProcessStartInfo等
- Java:java.lang.runtime.Runtime.getRuntime、java.lang.runtime.Runtime.exec等
三、漏洞检测
漏洞常常出现在网络设备、安全设备、自动化运维平台上面。
往往在有需求的地方,出现RCE的概率较大,这里的有需求指的是有用户执行系统命令的需求。
白盒:可以对代码进行审计。
黑盒:可以使用一些漏扫工具、公开的漏洞、手工看功能点及参数值,其中参数值主要需要看是否和相关的漏洞函数有关,若有就可以进行测试,但是可能存在加密的情况,那么还需要进行解密。
常用命令执行函数
我们这里对常见的PHP命令执行函数进行讲解。
system():能将字符串作为OS命令执行,且返回命令执行结果;
exec():能将字符串作为OS命令执行,但是只返回执行结果的最后一行(约等于无回显);
shell_exec():能将字符串作为OS命令执行
passthru():能将字符串作为OS命令执行,只调用命令不返回任何结果,但把命令的运行结果原样输出到标准输出设备上;
popen():打开进程文件指针
proc_open():与popen()类似
pcntl_exec():在当前进程空间执行指定程序;
反引号``:反引号``内的字符串会被解析为OS命令;
常见命令
一、Windows
dir:列出目录中的文件和子目录。
例如,dir C:\\Users可以列出C盘下Users目录中的所有文件和子目录。
cd:改变当前目录。
例如,cd C:\\Windows可以将当前目录更改为C盘下的Windows目录。
copy:复制文件到指定位置。
例如,copy C:\\file.txt D:\\可以将C盘下的file.txt复制到D盘。
move:移动文件或重命名文件/目录。
例如,move C:\\file.txt D:\\可以将C盘下的file.txt移动到D盘。
del:删除一个或多个文件。
例如,del C:\\file.txt可以删除C盘下的file.txt文件。
md/mkdir:创建新目录。
例如,md C:\\NewFolder可以在C盘下创建一个名为NewFolder的新目录。
rd/rmdir:删除目录。
例如,rd C:\\OldFolder可以删除C盘下的OldFolder目录。
attrib:显示或更改文件属性。
例如,attrib +r C:\\file.txt可以将C盘下的file.txt文件设置为只读属性。
还有ren(重命名文件或目录)、type(显示文件内容)、format(格式化磁盘)。
ping #测试连通性
tracert #追踪路由
telnet #远程连接
ipconfig #查看ip
arp -a #查看路由表
calc #打开计算器
regedit #打开注册表
netstat -ano #查看服务器端口信息
更多请看:Windows系统常用操作命令大全_windows常用命令-CSDN博客
二、Linux
1、文件和目录操作
- cd:切换目录。例如,cd /home 进入 /home 目录。
- pwd:显示当前工作目录。
- ls:列出目录内容。例如,ls -l 显示详细列表。
- mkdir:创建目录。例如,mkdir dir1 创建名为 dir1 的目录。
- rmdir:删除空目录。
- rm:删除文件或目录。例如,rm -rf dir1 递归删除 dir1 及其内容。
- cp:复制文件或目录。例如,cp file1 file2 将 file1 复制为 file2。
- mv:移动或重命名文件或目录。例如,mv old_name new_name 重命名文件。
- du:统计文件和目录的磁盘使用情况。
2、查看文件内容
- cat:连接文件并打印到标准输出。例如,cat file1 查看 file1 的内容。
- tac:反向显示文件内容。
- more:分页显示文件内容。
- less:类似 more,但允许向前和向后滚动。
- head:显示文件的前几行。例如,head -n 10 file1 显示 file1 的前10行。
- tail:显示文件的最后几行或实时跟踪文件更新。例如,tail -f /var/log/syslog 实时查看日志文件。
3、系统管理和网络
- shutdown:关闭系统。例如,shutdown -h now 立即关机。
- reboot:重启系统。
- date:显示或设置系统日期和时间。
- ping:测试网络连通性。例如,ping google.com 测试与 Google 的网络连接。
4、用户和权限管理
- useradd:添加新用户。
- userdel:删除用户。
- groupadd:添加新组。
- groupdel:删除组。
- chown:更改文件或目录的属主和属组。例如,chown user:group file1 将 file1 的属主更改为 user,属组更改为 group。
- chmod:更改文件或目录的权限。例如,chmod 755 file1 设置 file1 的权限为755。
5、压缩与解压缩
- tar:归档文件。例如,tar -czvf archive.tar.gz dir1 将 dir1 压缩为 archive.tar.gz。
- gzip:压缩文件。例如,gzip file1 将 file1 压缩为 file1.gz。
- gunzip:解压缩 .gz 文件。
- zip:压缩文件或目录为 .zip 格式。
- unzip:解压缩 .zip 文件。
6、其他常用命令
- find:在文件系统中查找文件或目录。例如,find / -name file1 从根目录开始查找名为 file1 的文件。
- grep:在文件中搜索文本。例如,grep "hello" file1 在 file1 中搜索包含 "hello" 的行。
- ps:显示当前运行的进程。例如,ps aux 显示所有进程。
- kill:终止进程。例如,kill -9 PID 强制终止进程 PID。
更多请看:Linux常见指令(超全超详细)_linux指令-CSDN博客
常见命令连接符
一、Windows
|:直接执行后面的语句:
||:如果前面的语句执行出错,则执行后面的语句,否则仅执行前面的语句
&:前后的语句均可执行,但是前面的语句如果执行结果为假(即执行失败),则仅输出后面语句的结果
&&:如果前面的语句为假,则直接报错,也不执行后面的语句。
> 和 >>:输出重定向命令
> 清除文件中原有的内容后再写入
>> 追加内容到文件末尾,而不会清除原有的内容。主要将本来显示在屏幕上的内容输出到指定文件中;指定文件如果不存在,则自动生成该文件
<:从文件中获得输入信息,而不是从屏幕上,一般用于 date time label 等需要等待输入的命令
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %*:命令行传递给批处理的参数
%0 批处理文件本身
%1 第一个参数
%9 第九个参数
%* 从第一个参数开始的所有参数
具体请看:windows终端cmd命令和连接符等_cmd 连接符-CSDN博客
二、Linux
;:按顺序执行语句
|:只执行后面语句
||:如果前面的语句执行失败,则执行后面的语句。如果前面的语句执行成功,则不执行后面的语句。
&:如果前面的语句为假(执行失败),则执行后面的语句,否则两条语句均会执行
&&:如果前面的语句出错,则停止,否则两条语句均会执行
更多请见:linux命令分隔符有哪些 - 酷盾
远程代码执行
介绍
一、定义及原理
远程代码执行,顾名思义就是用户可以远程执行代码。
这个漏洞和命令执行漏洞相近,根据设计的需求,需将用户输入的部分代码进行执行,又或者服务器对危险函数过滤不严导致用户输入的一些字符串可以被转换成代码来执行。这些时候往往容易导致远程代码执行。
二、成因
- 用户能够控制函数输入
- 存在可执行代码的危险函数常见代码执行函数
- PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)
- Javascript: eval
- Vbscript:Execute、Eval
- Python: exec
三、漏洞检测
整体的检测方式和命令执行都是一样的,只是输入的方式不同。
常见代码执行函数
我们这里对常见的PHP代码执行函数进行详解
eval函数
该函数会将字符串当作函数进行执行,但是需要传入一个完整的语句,同时必须以;分号结尾,也是最常见的函数。
assert函数
该函数是判断是否为字符串,如果是则当初代码进行执行,但是在php7.0.29之后的版本不支持动态调用。
${}执行代码
该执行代码会将中间的php代码进行解析。
array_map函数
该函数是为数组的每个元素应用回调函数。
文件包含
介绍
一、定义及原理
和SQL注入等攻击方式一样,文件包含漏洞也是一种注入型漏洞,其本质就是用户将一段能够控制的脚本或者代码输入文件里,并让服务端执行该文件。
什么叫包含呢?以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程叫做包含。
有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件,从而导致文件包含漏洞。
二、分类
文件包含漏洞主要包含两个方面,即本地文件包含漏洞(Local File Inclusion)和远程文件包含漏洞(Remote File Inclusion)。其中本地文件包含漏洞(LFI)有时也叫做目录遍历漏洞、任意文件访问漏洞。
三、本地文件包含漏洞和远程文件包含漏洞的区别
顾名思义,能够打开并包含本地文件的漏洞,我们称为本地文件包含漏洞(LFI);可以加载远程文件的,这种漏洞被称为远程文件包含(RFI)。
区别就在与包含文件的位置不同,需要注意的是,include/require函数加载远程文件时,allow_url_include、allow_url_fopen要求状态为ON,可以phpinfo进行查看。
LFI漏洞利用
一、配合文件上传使用
有时候我们找不到文件上传漏洞,无法上传webshell,可以先上传一个图片格式的webshell到服务器,再利用本地文件包含漏洞进行解析。
这种利用方式我们在学习文件上传时做upload-labs已经用过,详见作者的文章
二、包含Apache日志文件
有时候网站存在文件包含漏洞,但是却没有文件上传点。这个时候我们还可以通过利用Apache的日志文件来生成一句话木马。
三、包含SESSION文件
可以先根据尝试包含到SESSION文件,在根据文件内容寻找可控变量,在构造payload插入到文件中,最后包含即可。
四、包含临时文件
php中上传文件,会创建临时文件。在linux下使用/tmp目录,而在windows下使用C:\windows\temp目录。在临时文件被删除前,可以利用时间竞争的方式包含该临时文件。
由于包含需要知道包含的文件名。一种方法是进行暴力猜解,linux下使用的是随机函数有缺陷,而windows下只有65535种不同的文件名,所以这个方法是可行的。
另一种方法是配合phpinfo页面的php variables,可以直接获取到上传文件的存储路径和临时文件名,直接包含即可。
RFI漏洞利用
如果PHP的配置选项allow_url_include、allow_url_fopen状态为ON的话,则include/require函数是可以加载远程文件的,这种漏洞被称为远程文件包含(RFI)。
RFI简单的利用可以看CTFHub技能树RCE中“远程包含“一题,简单来说就是在自己这里写一句话木马,然后让服务器端包含自己的一句话木马,从而可以控制服务器。
常见的文件包含函数
PHP伪协议
PHP内置了很多URL风格的封装协议,除了常规的include/require函数,我们也常常用这些PHP伪协议去实现文件包含漏洞。
一、php://协议
php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input。
php://filter用于读取源码。
php://input用于执行php代码。
1、php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。
利用条件:
allow_url_fopen :off/on
allow_url_include:on
2、php://filter 读取源代码,有时候需要base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。
利用条件:
allow_url_fopen :off/on
allow_url_include:off/on
php://filter具有四个参数:
举例,
php://filter/resource=/flag
php://filter/read=convert.base64-encode/resource=/flag
二、file://协议
file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响
三、ZIP://协议
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
zip://中只能传入绝对路径。
要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23(即下述POC中#要用%23替换)
只需要是zip的压缩包即可,后缀名可以任意更改。
相同的类型还有zlib://和bzip2://
利用条件:
allow_url_fopen :off/on
allow_url_include:off/on
四、data://协议
data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。
利用data:// 伪协议可以直接达到执行php代码的效果,例如执行phpinfo()函数:
利用条件:
allow_url_fopen :on
allow_url_include:on
我们总结一下上面的伪协议:
在PHP手册中还可以看到更多伪协议,
混淆和绕过
过滤cat
cat替换命令:more、less、tac、head、tail、vi、vim、nl、od、sort、uniq。
more:按页显示,用于文件内容较多且不能滚动屏幕时查看文件
less:与more类似
tac:与cat相反,按行反向输出
head:查看文件首几行
tail:查看文件末几行
nl:在cat查看文件的基础上显示行号
od:以二进制方式读文件,od -A d -c /flag转人可读字符
xxd:以二进制方式读文件,同时有可读字符显示
sort:排序文件
uniq:报告或删除文件的重复行
file -f:报错文件内容
grep:过滤查找字符串,grep flag /flag
过滤空格
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS、{cat,flag}等
$IFS在linux下表示分隔符,但是如果单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用,但是为什么要用$9呢,因为$9只是当前系统shell进程的第九个参数的持有者,它始终为空字符串。
过滤目录分隔符
用&&连接命令
127.0.0.1;cd flag_is_here&&cat flag.php
采用多管道命令绕过
127.0.0.1||cd flag_is_here;cat flag.php
过滤运算符
URL编码绕过:%0a、%0d、%0D%0A
其他绕过
一、反斜杠\绕过
//如cat、ls被过滤,使用\绕过c\at /flagl\s /
二、引号绕过
//如cat、ls被过滤ca""t /flagl's' /
三、拼接法
a=fl;b=ag;cat$IFS$a$b
四、编码绕过
1、Base64
2、8进制
3、16进制
五、正则匹配绕过
//如flag被过滤
cat /f???
cat /fl*
cat /f[a-z]{3}
六、取反绕过
//取反传参<?php$a = "system";$b = "cat /flag";$c = urlencode(~$a);$d = urlencode(~$b);//输出得到取反传参内容echo "?cmd=(~".$c.")(~".$d.");"?>
参考文献
RCE代码及命令执行(详解)_rce命令执行-CSDN博客
干货 | 命令执行漏洞和代码执行漏洞详解 - 网络安全自修室 - 博客园
RCE漏洞详解及绕过总结(全面)-CSDN博客
命令执行(RCE)面对各种过滤,骚姿势绕过总结-CSDN博客
文件包含漏洞全面详解-CSDN博客
文件包含漏洞详解(超级详细)-CSDN博客