用友的一处jndi及sql注入审计
首先查看其中一个模块的映射配置

经分析,这里所有的映射均可利用,以SoapRequestAction类为例

首先查看SoapRequestAction的流程,在execuse方法中获取了两个参数,ws、soap

然后将两个参数传进sendRequest方法,在sendRequest方法中,会根据传进的ws参数去查找对应的soap接口服务

传进来的soap参数则作为soap接口参数来进行请求

从上面流程得知这是一个soap服务
参数表现为:
1 | |
接下来查找可以利用的webservice接口
在IMsgCenterWebService.wsdl接口文档中,存在很多个字符串参数dataSource,根据字面意思,假设他存在一个数据源连接功能

需要跟进相应方法查看参数是否真的是数据源连接功能,能不能用作jdbc反序列化
根据接口文档名称,得到接口类nc.itf.msgcenter.IMsgCenterWebService,我们以uploadAttachment方法为例跟进

图中接口对应的实现类为
MsgCenterWebServiceImpl.class
在该实现类的uploadAttachment方法中又调用IMsgCenterService接口的实现

查看IMsgCenterService接口

对应的实现类
MsgCenterServiceImpl.class
在uploadAttachment方法中,会将我们前面注意到的dataSource等参数传进resetInvacationInfoByMsgID方法做处理

跟进resetInvacationInfoByMsgID方法,参数传进来后,首先是做了一个初始化。具体为:将参数dataSource设置为UserDataSource的值,以供后面的流程调用

另一个传进的参数pk_sourcemsg则是传进retrieveByPK方法做查询

继续跟进流程
BaseDAO.class
在retrieveByPK方法中,封装了一个manager对象,这里的dataSource是上面说到设置的UserDataSource值,即传进的参数dataSource

跟进createPersistenceManager方法

PersistenceManager.getInstance返回的是他的子类JdbcPersistenceManager

所以跟进JdbcPersistenceManager
JdbcPersistenceManager.class
在JdbcPersistenceManager对象中做了一次初始化,此时的dataSource就是传进的参数dataSource

接着进入到init方法,在init方法中,又使用JdbcSession对象来处理dataSource

查看JdbcSession.class
在构造函数JdbcSession里对dataSource进行连接

具体看getConnection方法:

往下就是触发流程了
DataSourceCenter.class
变量name是传进的参数dataSource,在DataSourceCenter.getConnection方法中将参数传递到Context.lookup,到这里就可以确定这是一个jndi注入了,与JDBC反序列化无瓜


验证:
根据IMsgCenterWebService.wsdl接口文档构造soap参数
1 | |

最后:
在审计时一度以为这是一个jdbc反序列化,给人错觉的地方太多了,好在最后验证时成功了,且报错的内容与过程看到的一致
最后的最后:
这个接口里还有个紧急注入,不修就倒闭:MsgCenterServiceImpl
参数拼接:

这个方法由这里调用

根据代码可以看到这里参数必须是json格式,只需要pk_sourcemsg参数为空就可以进入else流程,造成注入
这个方法最终由这里调用

1 | |
声明:
本文章用于学习交流,严禁用于非法操作,出现后果一切自行承担,阅读此文章表示你已同意本声明。
Disclaimer:
This article is for study and communication. It is strictly forbidden to use it for illegal operations. All consequences shall be borne by yourself. Reading this article means that you have agreed to this statement.