基礎知識
今天和昨天的漏洞都跟SpEL有關。SpEL是Spring的表達式語言,支持在運行時查詢和操作對象圖,可以與基於XML和基於注解的Spring配置還有bean定義一起使用。由於它能夠在運行時動態分配值,可節省大量Java代碼。
用bean做實驗:
調用結果:
漏洞原理
在REST API的Patch方法中(實現RFC6902),path的值被傳入setValue
,導致執行了SpEL表達式,觸發遠程命令執行漏洞。
復現環境
在ubuntu 16.04虛擬機中用vulhub靶場提供的docker容器來復現
jdk版本1.7
影響版本
pivotal Spring Data REST < 2.5.12 2.6.7 3.0 RC3
pivotal Spring Boot < 2.0.0M4
pivotal Spring Data < Kay-RC3
復現過程
1. 進入vulhub目錄:spring/CVE-2017-8046,啟動docker容器
2.發送如下請求,利用SpEL表達式執行惡意代碼:
3.查看結果,惡意代碼執行成功
這里的SpEL用的就是基礎知識里面提到的第二種使用方式,使用了java.lang.Runtime類的getRuntime().exec方法,可是這里為啥要轉成byte[],不直接傳字符串?
試了下直接調SpelExpression是可以直接傳字符串的:
再發一次之前的PATCH請求,直接傳字符串T(java.lang.Runtime).getRuntime().exec(new java.lang.String('touch /tmp/success')),沒有成功,好吧,可能是源程序里面的參數類型是byte[]吧。。
看了一下Spring目錄后面的幾個目錄,都是SpEL命令執行造成的,原理差不多,就不一一復現了。
本文僅用於技術學習和交流,嚴禁用於非法用途,否則產生的一切后果自行承擔。