[【通过】] s2-045 分析

[复制链接]
Rabbittb 发表于 2017-3-13 15:56:51 | 显示全部楼层 |阅读模式

正式成员|主题 |帖子 |积分 161

本帖最后由 Rabbittb 于 2017-3-14 14:40 编辑

[size=18.0706px]s2-045 分析

1
.漏洞分析
   以下分析基于版本struct 2.3.20版本

struct 使用java ee中的Filter去拦截请求,并实现自己的功能。也就是说,用户所发出的请求,首先会在org.apache.struts2.dispatcher.ng.filter中的StrutsPrepareAndExecuteFilter类去执行。首先执行类中的doFilter方法。这个方法是自动调用的,在这里可以struct拦截用户的请求,并实现自己的业务代码。于是会执行prepare.wrapRequest这个调用。如下图

1

1

我们跟入这个函数

2

2


会执行dispatcher.wrapRequest这个函数。于是继续跟入

3

3


在这里,将会判断一下是否包含multipart/form-data这个头。注意,在这里,并没去区分是什么http方法,也就是说,get方法强行包含一个带有恶意代码的content-type头,也会执行到这里的。
在这里,首先判断一下是否为null和是否包含multipart/form-data。如果不包含,也就是get方法和post表单提交,则执行else里面的内容。如果包含,也就是说可能有文件上传,则执行if里面的内容。
在if中,首先获取到默认的解析器

4

4


可以查看一下multipartHandlerName的默认值

5

5


也就是获取默认配置中的值,而在struct的默认配置(org.apache.struct2的default.properties)中,这个值恰好为jakarta,默认配置为

6

6


回到dispatcher.wrapReques中,获取到默认的解析器后,将会把MultiPartRequestWrapper这个类实例化,执行MultiPartRequestWrapper的构造函数。跟入MultiPartRequestWrapper的构造函数

7

7


在这里,将会执行muiti.pase函数,因为这里的multipartrequest为JakartaMultiPartRequest类,于是将会执行JakartaMultiPartRequest.parse方法,跟入之

8

8


这里是重点,在这里将会执行java的捕获异常,如果捕获到异常的花,将会执行builderrorMessage方法,也就是产生漏洞的地方。继续跟入,将会执行processUpload函数

9

9


在这里,将会调用parseRequest对请求进行解析,跟入

10

10


在这里,将会调用upload.parseRequest函数,跟入

11

11


现在已经进入org.apache.commons.fileupload的FileUploadBase类,注意在这里,没有对FileItemStreamImpl进行捕获异常,于是跟入FileItemStreamImpl的构造函数中

12

12


在这里,将会得到content-type头,并且检查一下是否以multipart开头。所以,exp中并不会以multipart开头。于是在这里将会抛出异常,并将content-type信息放入异常中。
这里并没有任何代码捕获异常,于是向函数调用方继续抛出,到org.apache.commons.fileupload的FileUploadBase类的parseRequest方法,但是parseRequest方法中,恰好没有对这段代码捕获异常,于是继续向上抛出异常。在JakartaMultiPartRequest.parseRequest方法中,也没有捕获异常,于是到JakartaMultiPartRequest.processUpload方法中。在这里,也没有捕获异常,于是返回到JakartaMultiPartRequest.pase函数中。这里对代码捕获异常,于是在这里,将会执行catch里面的语句,也就会在这里调用builderrorMessage函数,参数为异常的信息,也就是包含恶意content-type头的那一段字符串。跟入这个函数

13

13


在这里将会执行LocalizedTextUtil.findText。谷歌一下这个函数的信息

14

14


发现这里可能会执行ognl语句,跟入这个函数

15

15


将会执行getDefaultMessage,参数为包含payload的content-type头,跟入

16

16


在这里,将会执行TextParseUtil.translateVariables,谷歌一下这个函数

17

17


到这里,将会把包含payload的content-type头作为ognl语句去执行。再继续跟,就是表达式处理的过程了。于是,漏洞就产生了


注:本文于本月9日投稿后,发表于先知论坛



投稿文章s2-045 分析.pdf

1.37 MB, 下载次数: 728

评分

参与人数 1酒票 +5 收起 理由
管理05 + 5 欢迎加入90!

查看全部评分

webshell 发表于 2017-3-14 13:56:51 | 显示全部楼层

正式成员|主题 |帖子 |积分 137

能顺便说下exp如何编写么。就是编写exp的思路。目前只知道exp,却不知道原理是怎样实现的,主要还是不懂ognl 语言,请赐教!
姗姗来迟 发表于 2017-3-14 18:43:01 | 显示全部楼层

正式成员|主题 |帖子 |积分 148

RE: s2-045 分析

webshell 发表于 2017-3-14 13:56
能顺便说下exp如何编写么。就是编写exp的思路。目前只知道exp,却不知道原理是怎样实现的,主要还是不懂ognl 语言,请赐教!

exp都是参照poc写出来的,读懂poc随便什么语言都可以写,PHP或者python 都行
快速回复 返回顶部 返回列表