Skip to content

Commit

Permalink
add syntaxflow xss case
Browse files Browse the repository at this point in the history
  • Loading branch information
v1ll4n committed Jul 22, 2024
1 parent fb40ed8 commit b0dfa56
Show file tree
Hide file tree
Showing 26 changed files with 212 additions and 3 deletions.
4 changes: 4 additions & 0 deletions java-realworld/java-debug.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
noDeepCross5 as $entry;
$entry(*?{!have: this && opcode: param} as $params)

$params --> as $sink;
12 changes: 12 additions & 0 deletions java-realworld/java-directly-xss.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
desc(
title: 'checking [XSS Directly from Springboot Controller Params]',
type: vuln
)

*Mapping.__ref__(*?{opcode: param && !have: this} as $params);
check $params;
$params <getFunc> as $sink;
check $sink;
$sink?{any: '.ok', '.body', 'ResponseEntity'} as $output;
check $output;
alert $output;
13 changes: 13 additions & 0 deletions java-realworld/java-filter-detect.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
desc(
title: 'checking [XSS Filter from Springboot Controller Params]',
type: audit
)

*Mapping.__ref__(*?{opcode: param && !have: this} as $params);
check $params;

$params -{until: `* <getFunc> ?{ any: /(?i).*xss.*/, /(?i).*filter.*/, /(?i).*escape.*/, /(?i).*encodexss.*/, /(?i).*xss.*?encode.*/, filterXSS } as $filter`}-> *;
check $filter;

$filter() -{hook: `*?{any: '.ok', '.body', 'ResponseEntity' && !opcode: param} as $sink` }-> *;
check $sink
12 changes: 12 additions & 0 deletions java-realworld/java-weak-filter-xss.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
desc(
title: 'checking [XSS Weak Handler from Springboot Controller Params]',
type: vuln
)

*Mapping.__ref__(*?{opcode: param && !have: this} as $params);
check $params;
$params -{hook: `*<getFunc>?{!any: /(?i)((xss)|(filter)|(escape))/} as $filter`}-> <getFunc> as $sink;
check $sink;
$sink?{any: '.ok', '.body', 'ResponseEntity'} as $output;
check $output;
alert $output;
17 changes: 16 additions & 1 deletion java-realworld/sample/bin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.36.0.3</version> <!-- 请检查最新版本 -->
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
Expand All @@ -39,7 +51,10 @@
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Java Freemaker

使用 Springboot Freemaker Starter 启动后,在 Controller Method 中,返回一个 String 则为 freemaker template 的模版名称(文件名)。

找到文件名比较关键。

一般作为一个 Controller 来说,他的方法是一个纯 Literal String,例如为 $ret,则需要在数据库中搜索 f`${ret}\.\w+` 类似的文件存在,一般来说这个文件中的 ${...} 是可以供 SSTI 的点。

一般的模版注入的审计都类似这种情况,Java 中出现裸 TPL 的渲染和调用的机会不多,框架会包裹一系列的用法。
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
spring.application.name=demo

# SQLite ?????
spring.datasource.url=jdbc:sqlite:database.db
spring.datasource.driver-class-name=org.sqlite.JDBC
spring.jpa.database-platform=org.hibernate.dialect.SQLiteDialect

# sqlmap mapper
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.demo.model

# freemaker
spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.suffix=.ftl

# auto update
spring.jpa.hibernate.ddl-auto=update

spring.sql.init.mode=always
8 changes: 8 additions & 0 deletions java-realworld/sample/bin/src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
INSERT INTO users (name, age)
VALUES ('Alice', 25);

INSERT INTO users (name, age)
VALUES ('Bob', 30);

INSERT INTO users (name, age)
VALUES ('Charlie', 35);
15 changes: 15 additions & 0 deletions java-realworld/sample/bin/src/main/resources/mapper/UserMapper.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">

<insert id="insertUser" parameterType="com.example.demo.model.UserModel">
INSERT INTO users (name, age)
VALUES (#{name}, #{age})
</insert>

<select id="findAllUsers" resultType="com.example.demo.model.UserModel">
SELECT id, name, age
FROM users
</select>

</mapper>
14 changes: 14 additions & 0 deletions java-realworld/sample/bin/src/main/resources/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CREATE TABLE IF NOT EXISTS users
(
id
INTEGER
PRIMARY
KEY
AUTOINCREMENT,
name
TEXT
NOT
NULL,
age
INTEGER
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome ${name}! If you see this, this is loaded by freemarkerConfig, not Controller Method Return</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome ${name?html}!</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome ${name}!</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome ${defaultName}!</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.example.demo.controller.deepcross;

import com.example.demo.controller.utils.DummyUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DeepCrossController {
@GetMapping({"/xss/safe", "/xss/no-cross"})
@GetMapping({"/xss/direct/1", "/xss/no-cross/1"})
public ResponseEntity<String> noDeepCross(@RequestParam(required = false) String body) {
if (body == null) {
return ResponseEntity.ok("No input, try <a href='/xss/no-cross?body=hello-world'>here</a>");
Expand All @@ -18,6 +18,57 @@ public ResponseEntity<String> noDeepCross(@RequestParam(required = false) String
return resp;
}

@GetMapping({"/xss/direct/2", "/xss/no-cross/2"})
public ResponseEntity<String> noDeepCross1(@RequestParam(required = false) String body) {
if (body == null) {
return ResponseEntity.ok("No input, try <a href='/xss/no-cross?body=hello-world'>here</a>");
}
ResponseEntity<String> resp = ResponseEntity.ok().body(body);
return resp;
}

@GetMapping({"/xss/direct/3", "/xss/no-cross/3"})
public ResponseEntity<String> noDeepCross2(@RequestParam(required = false) String body) {
if (body == null) {
return ResponseEntity.ok("No input, try <a href='/xss/no-cross?body=hello-world'>here</a>");
}
ResponseEntity<String> resp = new ResponseEntity(body, HttpStatus.OK);
return resp;
}

@GetMapping({"/xss/direct/4", "/xss/no-cross/4"})
public ResponseEntity<String> noDeepCross4(@RequestParam(required = false) String body) {
if (body == null) {
return ResponseEntity.ok("No input, try <a href='/xss/no-cross?body=hello-world'>here</a>");
}
ResponseEntity<String> resp = new ResponseEntity(body, HttpStatus.OK);
return resp;
}

@GetMapping({"/xss/direct/5"})
public ResponseEntity<String> noDeepCross5(@RequestParam(required = false) String body) {
if (body == null) {
return ResponseEntity.ok("No input, try <a href='/xss/no-cross?body=hello-world'>here</a>");
}
body = "Pre Handle" + body;
body = body.replaceAll("Hello", "---Hello---");
body += "\n\nSigned by DeepCrossController";
ResponseEntity<String> resp = new ResponseEntity(body, HttpStatus.OK);
return resp;
}

@GetMapping({"/xss/direct/6"})
public ResponseEntity<String> noDeepCross6(@RequestParam(required = false) String body) {
if (body == null) {
return ResponseEntity.ok("No input, try <a href='/xss/no-cross?body=hello-world'>here</a>");
}
body = body.replaceAll("Hello", "---Hello---");
body += "\n\nSigned by DeepCrossController";
body = DummyUtil.filterXSS(body);
ResponseEntity<String> resp = new ResponseEntity(body, HttpStatus.OK);
return resp;
}

@GetMapping({"/xss/unsafe1", "/xss/cross-method"})
public ResponseEntity<String> CrossMethod(@RequestParam String body) {
return DeepCrossController.directWrite(body);
Expand All @@ -37,5 +88,7 @@ public ResponseEntity<String> CrossMethod3(@RequestParam String body) {
public ResponseEntity<String> CrossMethod4(@RequestParam String body) {
return directWrite(DummyUtil.filterXSS(body));
}


}

0 comments on commit b0dfa56

Please sign in to comment.