-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #81 from yaklang/TBOsec/add-2023-09-21-patch
Add YakLab doc(ssrf、cmdi、Shiro、Fastjosn)
- Loading branch information
Showing
49 changed files
with
1,486 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# 01.Shlex 解析的命令注入 | ||
|
||
Shlex 是一个用于解析命令行参数的库,它能够帮助开发者将命令行参数分割成一个字符串切片,以便于在 Go 语言中执行外部命令。在下面的示例中,我们演示了如何使用 Shlex 安全地执行 ping 命令,以避免命令注入漏洞。 | ||
|
||
### 示例代码: | ||
|
||
```Go | ||
{ | ||
DefaultQuery: "ip=127.0.0.1", | ||
Path: "/ping/shlex", | ||
Title: "Shlex 解析的命令注入", | ||
Handler: func(writer http.ResponseWriter, request *http.Request) { | ||
ip := request.URL.Query().Get("ip") | ||
if ip == "" { | ||
writer.Write([]byte(`no ip set`)) | ||
return | ||
} | ||
var raw = fmt.Sprintf("ping %v", ip) | ||
list, err := shlex.Split(raw) | ||
if err != nil { | ||
writer.Write([]byte(`shlex parse failed: ` + err.Error())) | ||
return | ||
} | ||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
defer cancel() | ||
outputs, err1 := exec.CommandContext(ctx, list[0], list[1:]...).CombinedOutput() | ||
// 尝试将 GBK 转换为 UTF-8 | ||
utf8Outputs, err2 := utils.GbkToUtf8(outputs) | ||
if err2 != nil { | ||
writer.Write(outputs) | ||
} else { | ||
writer.Write(utf8Outputs) | ||
} | ||
if err1 != nil { | ||
writer.Write([]byte("exec : " + err1.Error())) | ||
return | ||
} | ||
}, | ||
RiskDetected: false, | ||
} | ||
``` | ||
|
||
### 代码分析: | ||
|
||
- 这个示例演示了如何使用 Shlex 解析用户提供的 IP 地址,并使用 `ping` 命令来测试该地址的可达性。 | ||
- `shlex.Split` 函数用于安全地解析命令字符串,避免了常见的命令注入漏洞。如果解析失败,将返回错误信息。 | ||
- 使用 `exec.CommandContext` 函数来创建一个可以执行外部命令的命令对象,然后使用 `CombinedOutput` 方法执行该命令,并将结果捕获到 `outputs` 中。 | ||
- 最后,通过检查错误变量 `err1` 和 `err2` 来处理执行命令的结果和错误信息,并将结果返回给客户端。 | ||
|
||
:::tip | ||
|
||
这个示例中采取了一系列安全措施,包括使用 Shlex 进行安全的命令解析,使用上下文控制命令执行的超时,以及尝试将输出从 GBK 转换为 UTF-8 编码。这些措施大大减少了命令注入的风险。 | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
|
||
# 02.Bash 解析的命令注入 | ||
|
||
Bash 解析的命令注入是一种常见的安全漏洞,它出现在使用 Bash 解析器执行用户提供的命令时。应用程序没有对用户输入进行充分的验证和过滤,导致用户提供的数据被直接拼接到执行的命令中,从而使攻击者能够插入恶意代码,并执行任意命令。 | ||
|
||
### 示例代码: | ||
|
||
该代码接受一个名为 "ip" 的 GET 参数,并将其作为参数拼接到命令字符串中。然后,使用 Bash 解析器执行这个命令,并返回执行结果。 | ||
|
||
```Go | ||
Handler: func(writer http.ResponseWriter, request *http.Request) { | ||
ip := request.URL.Query().Get("ip") | ||
if ip == "" { | ||
writer.Write([]byte(`no ip set`)) | ||
return | ||
} | ||
var raw = fmt.Sprintf("ping %v", ip) | ||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) | ||
defer cancel() | ||
outputs, err1 := exec.CommandContext(ctx, `bash`, "-c", raw).CombinedOutput() | ||
// 尝试将 GBK 转换为 UTF-8 | ||
utf8Outputs, err2 := utils.GbkToUtf8(outputs) | ||
if err2 != nil { | ||
writer.Write(outputs) | ||
} else { | ||
writer.Write(utf8Outputs) | ||
} | ||
if err1 != nil { | ||
writer.Write([]byte("exec : " + err1.Error())) | ||
return | ||
}}, | ||
``` | ||
|
||
### 攻击示例: | ||
|
||
```HTML | ||
ip=127.0.0.1|ls / | ||
``` | ||
|
||
上述 Payload 在 "ip" 参数后面添加了一个管道符,然后执行了一个简单的 "ls /" 命令,列出了根目录下的文件和目录 | ||
|
||
为了防御 Bash 解析的命令注入漏洞,开发者应当始终谨慎处理用户输入,特别是当用户提供的数据用于构造命令或者执行系统操作时。 | ||
|
||
### 防御措施: | ||
|
||
- 使用安全的参数化查询或预编译模式来执行命令,而不是简单的字符串拼接。 | ||
- 对用户输入进行严格的验证和过滤,仅接受预期格式的数据。 | ||
- 避免直接执行用户输入的命令,而是将输入用作参数,并在执行之前进行安全转义和验证。 | ||
- 最小化系统中所使用的特权账户的权限,并仅允许其执行必要的操作。 | ||
- 定期更新系统软件和组件,以修复已知的漏洞。 | ||
|
||
### 靶场演示: 视频 | ||
|
||
<video | ||
src="/img/yaklab/exec/02unsafe-bash.mp4" | ||
loop={true} | ||
playsInline={true} | ||
controls={true} | ||
autoPlay={true} | ||
style={{ width: 890 }} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"label": "命令注入测试案例", | ||
"position": 6 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# 01.GET 传参案例案例 | ||
|
||
fastjson 的一个安全问题是不受信任的用户可以构造恶意 JSON 数据,导致远程代码执行漏洞。本漏洞案例演示了一个 fastjson GET 请求传参的示例,其中存在潜在的 fastjson 远程代码执行漏洞。 | ||
|
||
### 示例代码: | ||
|
||
```Go | ||
{ | ||
Title: "GET 传参案例案例", | ||
Path: "/json-in-query", | ||
DefaultQuery: `auth={"user":"admin","password":"password"}`, | ||
Handler: func(writer http.ResponseWriter, request *http.Request) { | ||
if request.Method == http.MethodGet { | ||
action := request.URL.Query().Get("action") | ||
if action == "" { | ||
// 返回登录页面或脚本 | ||
// 省略部分代码 | ||
return | ||
} | ||
auth := request.URL.Query().Get("auth") | ||
if auth == "" { | ||
writer.Write([]byte("auth 参数不能为空")) | ||
return | ||
} | ||
response := mockController(generateFastjsonParser("1.2.43"), request, auth) | ||
writer.Write([]byte(response)) | ||
} else { | ||
writer.WriteHeader(http.StatusMethodNotAllowed) | ||
} | ||
}, | ||
} | ||
``` | ||
|
||
### 攻击示例: | ||
|
||
```Plain | ||
http://127.0.0.1:8787/fastjson/json-in-query?auth={"@type":"java.net.Inet4Address","val":"dnslog"}&action=login | ||
``` | ||
|
||
在以上 URL 中,攻击者传递了一个 auth 参数,其中包含了恶意构造的 JSON 数据。这个恶意 JSON 数据可能触发 fastjson 解析器漏洞。 | ||
|
||
### 防御措施: | ||
|
||
- 更新 fastjson 库: 确保使用的 fastjson 库是最新版本,因为早期版本可能存在已知的漏洞。 | ||
- 白名单: 对 JSON 数据中的字段和内容进行白名单验证,只接受预期的字段和数据。 | ||
- 谨慎使用 fastjson: 在不受信任的环境中,避免使用 fastjson 解析不受信任的 JSON 数据。 | ||
|
||
### 靶场演示: 视频 | ||
|
||
<video | ||
src="/img/yaklab/fastjson/01unsafe-json-inquery.mp4" | ||
loop={true} | ||
playsInline={true} | ||
controls={true} | ||
autoPlay={true} | ||
style={{ width: 890 }} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
|
||
# 02.POST Form 传参案例案例 | ||
|
||
Fastjson 在处理 JSON 数据时存在一些潜在的安全风险,尤其是在接收用户输入并将其反序列化为 Java 对象时。这个漏洞案例演示了如何通过在 POST 表单参数中注入恶意 JSON 数据来触发 Fastjson 反序列化漏洞。 | ||
|
||
### 示例代码: | ||
|
||
```Go | ||
{ | ||
Title: "POST Form传参漏洞案例", | ||
Path: "/json-in-form", | ||
Handler: func(writer http.ResponseWriter, request *http.Request) { | ||
if request.Method == http.MethodPost { | ||
body := request.FormValue("auth") | ||
response := mockController(generateFastjsonParser("1.2.43"), request, body) | ||
writer.Write([]byte(response)) | ||
} else { | ||
writer.Write([]byte(utils2.Format(string(fastjson_loginPage), map[string]string{ | ||
"script": | ||
// 省略部分代码, | ||
}))) | ||
return | ||
} | ||
}, | ||
} | ||
``` | ||
|
||
### 攻击示例: | ||
|
||
攻击者发送 POST 请求到`/json-in-form`,在表单参数`auth`中注入恶意 JSON 数据 | ||
|
||
```Plain | ||
{"@type":"java.net.Inet4Address","val":"dnslog"} | ||
``` | ||
|
||
服务器使用 Fastjson 反序列化恶意 JSON 数据。 | ||
|
||
恶意 JSON 数据中的内容被反序列化成 Java 对象,并且攻击者可能获得对服务器的控制或者执行恶意操作。 | ||
|
||
### 防御措施: | ||
|
||
- 更新 Fastjson 库:确保你的应用程序使用的 Fastjson 库版本不受已知漏洞的影响,始终保持最新的安全更新。 | ||
- 输入验证:在接受用户输入并将其用于反序列化之前,进行严格的输入验证和过滤,仅接受符合预期结构的数据。 | ||
- 阻止不必要的反序列化:只在必要的情况下执行反序列化操作,避免将未经验证的数据传递给 Fastjson。 | ||
- 安全配置:Fastjson 提供了一些配置选项,可以帮助减少安全风险,例如关闭自动类型识别。 | ||
|
||
### 靶场演示: 视频 | ||
|
||
<video | ||
src="/img/yaklab/fastjson/02unsafe-json-inform.mp4" | ||
loop={true} | ||
playsInline={true} | ||
controls={true} | ||
autoPlay={true} | ||
style={{ width: 890 }} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
--- | ||
sidebar_position: 3 | ||
--- | ||
|
||
# 03.POST Body 传参案例 | ||
|
||
该案例演示了一种潜在的安全漏洞,当后端处理 POST 请求的请求体(Request Body)时,没有对其中的数据进行足够的验证和处理,可能导致安全问题。特别是在使用 Fastjson 或其他 JSON 解析器的情况下,攻击者可以构造恶意 JSON 请求体来触发 Java 反序列化漏洞。 | ||
|
||
### 示例代码: | ||
|
||
```Go | ||
{ | ||
Title: "POST Body传参案例案例", | ||
Path: "/json-in-body", | ||
Handler: func(writer http.ResponseWriter, request *http.Request) { | ||
if request.Method == http.MethodPost { | ||
body, err := io.ReadAll(request.Body) | ||
if err != nil { | ||
writer.WriteHeader(http.StatusBadRequest) | ||
writer.Write([]byte("Invalid request")) | ||
return | ||
} | ||
defer request.Body.Close() | ||
response := mockController(generateFastjsonParser("1.2.43"), request, string(body)) | ||
writer.Write([]byte(response)) | ||
} else { | ||
writer.Write([]byte(utils2.Format(string(fastjson_loginPage), map[string]string{ | ||
"script": `function load(){ | ||
name=$("#username").val(); | ||
password=$("#password").val(); | ||
auth = {"user":name,"password":password}; | ||
$.ajax({ | ||
type:"post", | ||
url:"/fastjson/json-in-body", | ||
data:JSON.stringify(auth), | ||
dataType: "json", | ||
success: function (data ,textStatus, jqXHR) | ||
{ | ||
$("#response").text(JSON.stringify(data)); | ||
console.log(data); | ||
}, | ||
error:function (XMLHttpRequest, textStatus, errorThrown) { | ||
alert("请求出错"); | ||
}, | ||
}) | ||
}`, | ||
}))) | ||
return | ||
} | ||
}, | ||
} | ||
``` | ||
|
||
### 攻击示例: | ||
|
||
攻击者可以构造 POST 请求,将恶意 JSON 数据作为请求体发送给目标服务器。例如,post payload ` {"@type":"``java.net``.Inet4Address","val":"dnslog"} ` 将触发 Fastjson 反序列化漏洞。 | ||
|
||
### 防御措施: | ||
|
||
- 验证请求体:后端应该对接收到的请求体进行验证和解析,确保其格式正确,数据类型合法。 | ||
- 使用安全的 JSON 解析库:考虑使用安全的 JSON 解析库,这些库通常会提供防御反序列化攻击的功能。 | ||
- 限制反序列化能力:在可能的情况下,禁用或限制应用程序的反序列化能力,只反序列化信任的数据。 | ||
|
||
:::caution | ||
|
||
请注意,漏洞的防御措施可能因编程语言和框架而异,因此确保您的应用程序采取了适当的防御措施,以确保安全性。 | ||
|
||
::: | ||
|
||
### 靶场演示: 视频 | ||
|
||
<video | ||
src="/img/yaklab/fastjson/03unsafe-json-inbody.mp4" | ||
loop={true} | ||
playsInline={true} | ||
controls={true} | ||
autoPlay={true} | ||
style={{ width: 890 }} | ||
/> |
Oops, something went wrong.