总字符数: 10.96K
代码: 4.48K, 文本: 4.01K
预计阅读时间: 37 分钟
命令执行
漏洞信息
漏洞原理
应用有时需要调用一些执行系统命令的函数,如PHP
中的system
、exec
、shell_exec
、 passthru
、popen
、proc_popen
等,当用户能控制这些函数中的参数时,就可以将恶意系统命令. 拼接到正常命令中,从而造成命令注入攻击,这就是命令注入漏洞.
利用条件
- 应用调用执行系统命令的函数
- 将用户输入作为系统命令的参数拼接到了命令行中
- 没有对用户输入进行过滤或过滤不严
漏洞分类
命令直接注入执行漏洞
应用程序直接使用了危险的可执行系统命令的函数,比如php的system、exec函数等,并且这些函数的运行参数是用户可控的,若过滤不严格,就会增大命令执行漏洞的概率.命令本地包含执行漏洞.(注:(CGI)系统命令注入执行漏洞示例,就比如Bash漏洞,就属于这类漏洞,用户可以直接更改HTTP头user-agent的值,就可引发命令注入.)
命令包含执行漏洞
命令本地/远程包含漏洞:应用程序直接包含或执行了用户可控的上传脚本文件或远程文件(URL引用文件),就会触发此漏洞.
命令反序列执行漏洞
有些动态脚本语言,如php支持实例对象的序列化传输,然后服务端将实例对象反序列化出来并执行解析后实例的构造函数、析构函数或_wakeup()函数,若这些函数利用了用户可控的参数,则会触发命令/代码注入执行漏洞,原理和之前直接注入一样.
命令动态变量执行漏洞
有些动态脚本语言,如php,支持变量或函数的动态定义,即运行时可通过参数名来动态组装变量、变量值或函数.若代码中包含有类似代码,就会存在动态变量/函数的执行漏洞.
漏洞危害
继承Web
服务程序的权限去执行系统命令或读写文件 反弹shell
控制整个网站甚至控制服务器 进一步内网渗透
- 控制受害主机:攻击者可以通过RCE攻击远程控制受害主机,执行任意操作.
- 窃取敏感信息:攻击者可以利用RCE攻击窃取受害主机上的敏感信息,如密码、银行账户等.
- 破坏数据:攻击者可以利用RCE攻击破坏受害主机上的数据,如删除文件、格式化硬盘等.
- 传播恶意代码:攻击者可以利用RCE攻击在受害主机上安装恶意软件,从而进行更多的攻击.
- 滥用系统权限:攻击者可以利用RCE攻击获取受害主机上的系统权限,从而进行更多的攻击和滥用.
防范措施
防止远程命令执行漏洞是一项关键任务,可以通过以下方法来实现:
(1)输入数据过滤和验证:应用程序应该对所有输入数据进行充分的过滤和验证,包括但不限于用户输 入、文件上传、cookie等.
(2)使用安全的编程语言和框架:使用安全的编程语言和框架可以帮助开发人员避免常见的安全漏洞.
(3)最小化应用程序权限:应用程序应该以最低的权限运行,这可以减少攻击者获取服务器或系统的控制 权的可能性.
(4)定期更新和修补程序:定期更新和修补程序可以帮助消除安全漏洞,包括远程命令执行漏洞. (5)使用Web应用程序防火墙:Web应用程序防火墙可以帮助检测和阻止恶意流量,包括远程命令执行漏洞攻击
(6)限制外部访问:限制外部访问可以帮助保护Web应用程序免受未经授权的访问和攻击.
(7)日志和监控:记录和监控应用程序的所有操作可以帮助发现安全漏洞和恶意行为,以及对应应急响 应.
(8)加密和认证:使用加密和认证机制可以帮助保护应用程序的数据免受未经授权的访问和窃取.
(9)安全开发实践:开发人员应该遵循安全开发实践,包括但不限于安全代码审查、安全测试、安全培训 等.
常见连接符(管道符)
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系统支持的连接符
连接符 | 含义 |
---|---|
; | 执行前面的语句才会执行后面的语句.例如:ping 127.0.0.1;whoami |
| | 直接执行后面的语句.例如:ping 127.0.0.1|whoami |
|| | 如果前面执行的语句出错,才执行后面的语句,所以前面的语句必须为假.例如 ping 127.0.0.1 || whoami |
& | 前面的语句不管是真还是假都执行后面的语句.例如: ping 127.0.0.1 & whoami |
&& | 如果前面的语句为假则直接出错,也不执行后面的语句,只有前面的语句为真才行.例如: ping 127.0.0.1 && whoami |
常见命令执行的函数
php
执行系统命令有 6 个函数:
命令 | 说明 |
---|---|
exec() |
允许执行一个外部程序(如UNIX Shell/Linux Shell 或CMD 命令等) |
system() |
允许执行一个外部程序并回显输出,类似于passthru() |
passthru() |
允许执行一个外部程序并回显输出,类似于exec() |
popen() |
可通过popen() 的参数传递一条命令,并对popen() 所打开的文件进行执行 |
proc_open() |
执行一个命令并打开文件指针用于读取以及写入 |
shell_exec() |
通过Shell 执行命令,并将执行结果作为字符串返回 |
system()
1 | [root@centos7 html]# vim system.php |
执行系统命令,有回显
passthru()
1 |
|
执行系统命令并且显示原始输出
shell_exec()
1 | shell_exec(string $cmd): string) |
通过shell环境执行命令,并且将完整的输出以字符串形式返回(无回显)
exec()
1 |
|
执行一个外部程序, 同时无回显,且输出的时候仅返回命令的最后一行
反引号
1 | echo `ls`; |
只要在反引号里的字符串都会被当作代码执行,注意如果反引号在单、双引号内则不起作用
漏洞复现
低级
我们对命令注入漏洞进行一个初步利用 让我们先执行一段命令,在输入框输入127.0.0.1
,点击submit
提交
可以看到成功回显执行结果,说明ping 127.0.0.1
命令成功.然后尝试构造payload127.0.0.1|whoami
我们再输入框输入127.0.0.1&whoami
,点击submit提交,可以看到不仅ping
命令成功执行,并且后面的whoami
命令也成功执行.
1 | if( isset( $_POST[ 'Submit' ] ) ) { |
中级
1 | // 设置危险字符的数组 |
通过源代码分析可以知道并没有过滤|,所以还是可以通过|来绕过
高级
1 | // 定义危险数组 |
高级就特别有意思了,它类似于CTF故意给你留下了一个bug看你能不能发现,其实我们可以看到|旁边有个空格,所以只要我们的Payload |和两边的命令没有空格就不会被替换
不可能
1 | if( isset( $_POST[ 'Submit' ] ) ) { |
以上也属于一种措施,但是真正的业务中会产生无法ping域名的情况,可能会对正常的业务造成一定的损失
代码执行
漏洞信息
漏洞原理
远程命令执行漏洞的本质是输入数据未经过充分的验证和过滤,攻击者可以通过输入特定的恶意数据来执行任意代码.这通常是由于应用程序或服务器的代码实现中存在漏洞,使得攻击者可以利用该漏洞来执行任意代码.
攻击者可以利用多种技术来执行远程命令执行漏洞攻击,包括但不限于:
操作系统命令注入:攻击者通过输入操作系统命令来执行恶意代码,例如Linux系统中的”shell”命令.
SQL注入:攻击者通过输入SQL语句来执行恶意代码,例如向Web应用程序中的数据库查询语句注入代码.
文件包含:攻击者通过在Web应用程序中包含恶意文件来执行恶意代码,例如通过包含PHP文件来执 行PHP代码.
反序列化漏洞:攻击者通过利用应用程序中的反序列化功能来执行恶意代码.
代码注入:攻击者通过向Web应用程序中注入恶意代码来执行代码.
漏洞危害
或者获取敏感数据,控制服务器,甚至发起更加危险的攻击.
- 数据泄露:攻击者可以利用RCE攻击来窃取服务器上的敏感数据,如用户账号密码、数据库信息等.
- 破坏服务器:攻击者可以利用RCE攻击来破坏服务器的配置,如删除系统文件、更改系统设置等.
- 发起DDoS攻击:攻击者可以利用RCE攻击在目标服务器上安装僵尸程序,并将其作为攻击工具发起 DDoS攻击,使服务器无法正常运行.
漏洞防御
为了防止RCE攻击,应该采取以下措施:
- 及时更新系统和应用程序,修复已知漏洞.
- 使用防火墙和入侵检测系统(IDS)等安全工具,及时检测和防范攻击.
- 对输入的数据进行严格过滤和验证,避免输入参数被解析为可执行代码.
- 限制应用程序的执行权限,将应用程序运行在最小权限的用户下.
- 禁止使用明文密码和弱口令,采用强密码策略.
- 启用日志记录,及时发现和排查异常行为.
代码注入攻击与命令注入攻击不同.因为需求设计,后台有时候需要把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞.不管是使用了代码执行的函数,还是使用了不安全的反序列化等等.
通过代码注入或远程代码执行(RCE),攻击者可以通过注入攻击执行恶意代码、向网站写webshell、控制整个网站甚至服务器.其实际危害性取决于服务器端解释器的限制(例如,PHP,Python等).在某些情况下,攻击者可能能够从代码注入升级为命令注入.
通常,代码注入容易发生在应用程序执行却不经过验证代码的情况下.以下是带有代码注入错误的示例PHP应用程序的源代码.
1 | /** |
根据上面的示例,攻击者可以使用以下结构来执行任意PHP代码.结果是显示出PHP信息页面.
1 | http://example.com/?code=phpinfo(); |
Payload:system('whoami');
命令执行漏洞与代码执行漏洞的区别
命令执行漏洞:直接调用操作系统命令
命令执行漏洞原理:在操作系统中,”&、| 、||”都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令.
代码执行漏洞:靠执行脚本代码调用操作系统命令
应用有时需要调用一些执行系统命令的函数,如PHP中的system
、exec
、assert
、shell_exec
、passthru
、popen
、proc_open
、escapeshellcmd
、pcntl_exec
等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行漏洞,这就是命令执行漏洞.以上函数主要也在webshell中用的多,实际上在正常应用中差别不太大,用得最多的还是前三个.
常用危险函数
PHP
1 | # 函数调用注入和命令执行漏洞 |
java
1 | java.lang.Runtime.getRuntime.exec(command) |
在Java中,虽然没有像PHP的eval
函数一样直接执行字符串的函数,但是反射机制和表达式引擎等功能依然会带来安全隐患.下面简要介绍一下这些概念:
- 反射机制(Reflection): Java的反射机制允许在运行时检查、获取和操作类、接口、字段、方法等类的信息.通过反射,可以动态创建对象、调用方法、获取字段值等,这给了攻击者一定的可操作性.在使用反射时,应该确保对输入进行充分验证和过滤,避免不当操作.
- OGNL(Object-Graph Navigation Language): OGNL是一种表达式语言,用于导航和操作对象图.它常被用于在Struts2等框架中进行数据绑定和表达式求值.攻击者可能通过构造恶意的OGNL表达式来执行任意代码,因此在使用OGNL时需要做好输入验证.
- SpEL(Spring Expression Language): SpEL是Spring框架中的表达式语言,用于在运行时进行查询和操作对象图.和OGNL类似,攻击者可能通过构造恶意的SpEL表达式来执行任意代码.在使用SpEL时应当谨慎处理用户输入.
- MVEL: MVEL是一种类似OGNL和SpEL的表达式语言,也用于在运行时进行动态表达式求值.同样,需要注意防范恶意输入,避免代码执行风险.
python
1 | exec(string) # Python代码的动态执行 |
1 | system() #执行系统指令 |