2020 TSG CTF - Slick Logger Writeup
Time-based Blind Regex Injectionでフラグを奪取
この記事は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"のような特定のパラメータ形式で使用され、アンクォート(引用符解除)されます。
そのため、"""を入力すると空文字扱いとなり、MySQLのlike '%'のように(全件)検索できるようになります。
(@Payload at GONに感謝)
これにより、
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にはUSLACKBOTというuseridが存在しません。
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の精度が低下します。
検索ワードを適度に分割してフラグを取得しましょう!
また、精度が少し低いため、同じペイロードを数回送信し、最も遅延が発生したワードの統計を取るようにします! 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エクスプロイトコードを確認してください。
https://github.com/JaewookYou/ctf-writeups/blob/master/2020TSGCTF/slick-logger/ex.py
コメント