Yakit实战:快速挖掘前后端分离网站的API接口漏洞
# 前言
大致步骤就是:
- app.js中提取所有js路径列表
- 获取 js内容
- yakit脚本或者热加载功能一键提取api列表
- fuzz api
- fuzz api参数
- getshell
# 详情
- 根据js特征手动提取js路径列表(自动化待实现)
- 设置热加载代码
// 使用标签 {{yak(handle|param)}} 可触发热加载调用
handle = func(param) {
// 在这里可以直接返回一个字符串
return codec.EncodeBase64("base64-prefix" + param) + sprintf("_origin(%v)", param)
}
// 使用标签 {{yak(handle1|...)}} 可触发热加载调用
handle1 = func(param) {
// 这个特殊的 Hook 也支持返回数组
return ["12312312", "abc", "def"]
}
// beforeRequest 允许发送数据包前再做一次处理,定义为 func(origin []byte) []byte
beforeRequest = func(req) {
/*
// 我们可以提供一些基础用法,比如说单纯就是替换一个时间戳~
req = str.ReplaceAll(req, "TIMESTAMP_INT64", sprint(time.Now().Unix()))
*/
return []byte(req)
}
// afterRequest 允许对每一个请求的响应做处理,定义为 func(origin []byte) []byte
afterRequest = func(rsp) {
return []byte(rsp)
}
var linkCompilerStr2 = `(?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,})|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{1,}\.(?:[a-zA-Z]{1,4}|action)(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{3,}(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:\w)(?:[\?|#][^"|']{0,}|)))(?:"|')`
// mirrorHTTPFlow 允许对每一个请求的响应做处理,定义为 func(req []byte, rsp []byte, params map[string]any) map[string]any
// 返回值回作为下一个请求的参数,或者提取的数据,如果你需要解密响应内容,在这里操作是最合适的
mirrorHTTPFlow = func(req, rsp, params) {
params["api_list"] = str.Join(re.FindAll(string(poc.GetHTTPPacketBody(rsp)),linkCompilerStr2),"\n")
return params
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
- fuzz 提取api
其实这个功能还有待优化,不如脚本来的方便
println(`Hello Yak World!`)
filename = "/Users/x/yakit-projects/temp/tmp937318693.txt"
data = file.ReadLines(filename)
url = "http://xxxx"
var linkCompilerStr = `(?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,})|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{1,}\.(?:[a-zA-Z]{1,4}|action)(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{3,}(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:\w)(?:[\?|#][^"|']{0,}|)))(?:"|')`
var apiList = []
for path in data {
target = url + path
println("正在请求:", target)
resp, req, err = poc.Get(target)
die(err)
res = re.FindAll(string(resp.GetBody()), linkCompilerStr)
for i in res {
apiList.Append(i)
}
}
apiList = str.RemoveRepeat(apiList)
print(len(apiList))
f = file.OpenFile("/tmp/test.txt", file.O_CREATE | file.O_RDWR|file.O_APPEND, 0o777)~
defer f.Close()
for api in apiList {
if str.Contains(api, ".js") || str.Contains(api, ".png") || str.Contains(api, ".jpg") || str.Contains(api, ".gif") || str.Contains( api, "./") || str.Contains(api, ".vue") {
continue
} else if str.StartsWith(api, "/" /*type: string*/) {
f.WriteLine(f`${api}`)
}
}
println("done")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
- api fuzz
..... ..... .....
- param fuzz
..... ..... .....