javascript
Spring4Shell的漏洞原理分析
Spring框架最新的PoC
這兩天出來(lái)的一個(gè)RCE漏洞,但是有以下的條件限制才行:
必須是jdk9及以上
必須是部署在tomcat的應(yīng)用
是springmvc的或者webflux的應(yīng)用
具體的可以查看spring官方:
https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement
我看到這個(gè)漏洞的時(shí)候,就去查了以下怎么利用的,github一搜很多py腳本。
但是我沒(méi)找到漏洞利用的原理,所以我就自己做了個(gè)demo,然后debugger了一下,原來(lái)是這樣~
漏洞利用的原理
我們都知道,我們?cè)趕pringmvc的時(shí)候經(jīng)常會(huì)這么寫代碼來(lái)接收前端傳來(lái)的參數(shù)
@RequestMapping(value?=?"/register",?method?=?RequestMethod.GET) public?String?register(@RequestParam?Map<String,?String>?requestparams,?Model?model)?throws?Exception?{String?email?=?requestparams.get("email");String?username?=?requestparams.get("username");model.addAttribute("data",?"email:"?+?email?+?"?username:"?+?username);return?"index"; }如果我們這么訪問(wèn):
http://localhost:8080/vulnerable_war/register?email=11&username=b
那么返回的結(jié)果就是這樣:
image那么如果我們把接收的類型從Map轉(zhuǎn)成一個(gè)POJO的話,就像這樣:
@RequestMapping(value?=?"/register2",?method?=?RequestMethod.GET) public?String?register2(HelloWorld?obj,?Model?model)?throws?Exception?{model.addAttribute("data",?obj.toString());return?"index"; }訪問(wèn)一下:
image這說(shuō)明了,springmvc框架幫我們做了一個(gè)很重要的事情:
通過(guò)我們請(qǐng)求的數(shù)據(jù),轉(zhuǎn)成了POJO對(duì)象。
恰巧就是這個(gè)非常好用的封裝導(dǎo)致了這個(gè)POC
解析POC第一步:到底構(gòu)造了一個(gè)什么數(shù)據(jù)會(huì)引發(fā)呢?
跑的環(huán)境是:
jdk11
tomcat8.5.58
spring-webmvc5.3.15
將上面的數(shù)據(jù)用下面post的方式調(diào)用下面的接口
image@RequestMapping(value?=?"/rapid7") public?void?vulnerable(HelloWorld?model)?{}注意header里面的值是需要的,目的是為了迎合tomcat日志的pattern(下面會(huì)講到)
%i 這個(gè)語(yǔ)法是從請(qǐng)求的header里面拿xxx
就會(huì)在tomcat的Root目錄下生成一個(gè)jsp文件
image內(nèi)容如下:
image計(jì)息POC第二步:jsp文件是怎么生成的?
方法接收的class:HelloWorld,我這么傳,spring框架是怎么來(lái)處理的呢?
image根據(jù)HelloWorld的實(shí)例
結(jié)合傳過(guò)來(lái)屬性路徑:class.module.classLoader.resources.context.parent.pipeline.first.pattern
然后一步步的運(yùn)用反射來(lái)去拿屬性對(duì)應(yīng)的值,這個(gè)例子的話就是
調(diào)用HelloWorld的getClass() 拿到Class對(duì)象
通過(guò)class對(duì)象調(diào)用getModule()
通過(guò)Module調(diào)用getClassLoader()
通過(guò)ClassLoader拿resources
context是Tomcat的StandardContext
parent拿到的是StandardEngine
pipeline拿到的是StandardPipeline
first拿到的是AccessLogValve
可以在下圖所示設(shè)置斷點(diǎn):就可以看到上面說(shuō)的每一步了
主角上場(chǎng):
AccessLogValve是tomcat記錄日志的,
pattern是日志格式
suffix是日志文件的后綴
prefix是日志文件的前綴
fileDateFormat是日期文件的時(shí)間格式
謎底揭曉
根據(jù)以上分析,我們知道,傳過(guò)去的data由對(duì)象的class作為引子,然后springmvc會(huì)一步步反射拿屬性的方式最終是給AccessLogValve對(duì)象的幾個(gè)屬性的賦值操作
經(jīng)過(guò)對(duì)tomcat的處理請(qǐng)求的日志管道(AccessLogValve)的改寫,導(dǎo)致當(dāng)前請(qǐng)求會(huì)被觸發(fā)記錄日志,日志會(huì)按照我們想要的方式生成了一個(gè)jsp文件。
image為啥是jdk9及以上版本呢,因?yàn)閙odule的概念是從jdk9開(kāi)始的~
為啥是得部署到tomcat里的應(yīng)用呢,因?yàn)橹挥羞@樣才會(huì)利用它的日志功能~
spring是咋修復(fù)的
image我是正東,學(xué)的越多不知道也越多。一個(gè)漏洞引發(fā)的思考~收獲挺大!
總結(jié)
以上是生活随笔為你收集整理的Spring4Shell的漏洞原理分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何获取当前C#程序所有线程的调用栈信息
- 下一篇: JS实现上下左右四方向无间隙滚动