TSG CTF 2020🏁 CTF🌐 已翻译
2020 TSG CTF - Slick Logger 题解
利用 Time-based Blind Regex Injection 获取 Flag
#tsg-ctf#regex-injection#blind#golang
本文由 AI 从韩语机器翻译,部分表达可能与原文有所不同。
阅读原文(韩语)slick-logger web 5 solvers
func searchHandler(w http.ResponseWriter, r *http.Request) {
channelID, ok := r.URL.Query()["channel"]
if !ok || !validateParameter(channelID[0]) {
http.Error(w, "channel parameter is required", 400)
return
}
queries, ok := r.URL.Query()["q"]
if !ok || !validateParameter(queries[0]) {
http.Error(w, "q parameter is required", 400)
return
}
users := []User{}
readJSON("/var/lib/data/users.json", &users)
dir, _ := strconv.Unquote(channelID[0])
query, _ := strconv.Unquote(queries[0])
if strings.HasPrefix(dir, "G") {
http.Error(w, "You cannot view private channels, sorry!", 403)
return
}
re, _ := regexp.Compile("(?i)" + query)
messages := []Message{}
filepath.Walk("/var/lib/data/", func(path string, _ os.FileInfo, _ error) error {
if strings.HasPrefix(path, "/var/lib/data/"+dir) && strings.HasSuffix(path, ".json") {
newMessages := []Message{}
readJSON(path, &newMessages)
for _, message := range newMessages {
if re.MatchString(message.Text) {
// Fill in user info
for _, user := range users {
if user.ID == message.UserID {
messages = append(messages, Message{
Text: re.ReplaceAllString(message.Text, "<em>$0</em>"),
UserID: message.UserID,
UserName: user.Name,
Icon: user.Profile.Image,
Timestamp: message.Timestamp,
})
break
}
}
}
}
}
return nil
})
result, _ := json.Marshal(messages)
w.WriteHeader(http.StatusOK)
header := w.Header()
header.Set("Content-type", "application/json")
fmt.Fprint(w, string(result))
}在搜索功能中,程序接收我们的输入:channel 和 q
但它们使用了特定的参数格式,比如 "value",并对其进行去引号(unquote)处理。
因此,如果我们输入 """,它会变成空值,我们就可以像在 MySQL 数据库中使用 like '%' 一样进行搜索。
(感谢 GON 的 @Payload)
接下来,
filepath.Walk("/var/lib/data/", func(path string, _ os.FileInfo, _ error) error {
if strings.HasPrefix(path, "/var/lib/data/"+dir) && strings.HasSuffix(path, ".json") {
newMessages := []Message{}
readJSON(path, &newMessages)我们可以获取秘密频道的管理员消息,
users := []User{}
readJSON("/var/lib/data/users.json", &users)
...
for _, user := range users {
if user.ID == message.UserID {但由于这个条件的限制,users.json 中不存在 userid 为 USLACKBOT 的用户
for _, message := range newMessages {
>>> if re.MatchString(message.Text) {
// Fill in user info
for _, user := range users {但是我们的搜索词 query 会作为参数传递给 regexp.Compile,而且它是在 userid 匹配之前被使用的。
所以我们可以利用它进行 Blind Regex Injection。 (https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets)
随着搜索词长度的增加,Blind Regex Injection 的准确率会降低。
适当地切分搜索词来获取 Flag!
另外准确率有点低,所以我们多次发送相同的 Payload,通过统计延迟最长的词来判断!XD
[*] 5 : 0.06300497055053711
[*] } : 0.062014102935791016
[*] N : 0.05901360511779785
---------------------
[*] } : 0.06202411651611328
[*] 0 : 0.060013771057128906
[*] W : 0.058012962341308594
---------------------
[*] U : 0.09402132034301758
[*] B : 0.0660254955291748
[*] } : 0.06601500511169434
---------------------
[*] } : 0.06301426887512207
[*] Z : 0.06101393699645996
[*] Y : 0.060013532638549805
---------------------
[*] } : 0.06601476669311523
[*] H : 0.06502485275268555
[*] 6 : 0.05902361869812012
---------------------
[Finished in 13.1s]
## this could be `}` is the currect word查看我的利用脚本(Exploit)
https://github.com/JaewookYou/ctf-writeups/blob/master/2020TSGCTF/slick-logger/ex.py
评论