SECCON Beginners CTF 2022 Write-up

技術

2022-06-04 14:00 – 2022-06-05 14:00 (JST)に開催されたSECCON Beginners CTF 2022のWrite-upです。

前回に引き続き友人であるmaa氏との2人チームで出場し、1067pt獲得して全1121チーム中67位でした。

Welcome (welcome)

開始直後にDiscordでアナウンスされるフラグのコピペRTA。

ctf4b{W3LC0M3_70_53CC0N_B361NN3R5_C7F_2022}

Quiz (reversing)

stringsしたら出てきた

$ strings quiz | grep ctf4b
ctf4b{w0w_d1d_y0u_ca7ch_7h3_fl4g_1n_0n3_sh07?}

CoughingFox (crypto)

# problem.py
from random import shuffle

flag = b"ctf4b{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}"

cipher = []

for i in range(len(flag)):
    f = flag[i]
    c = (f + i)**2 + i
    cipher.append(c)

shuffle(cipher)
print("cipher =", cipher)

リスト型に格納されたフラグの各要素について、( f[i] + i )^2 + i という計算が行われシャッフルされたものが出力されるので、そのまま逆の処理を書いてflagを復元しました。

# solver.py
import math

cipher = [12147, 20481, 7073, 10408, 26615, 19066, 19363, 10852, 11705, 17445, 3028, 10640, 10623, 13243, 5789, 17436, 12348, 10818, 15891, 2818, 13690, 11671, 6410, 16649, 15905, 22240, 7096, 9801, 6090, 9624, 16660, 18531, 22533, 24381, 14909, 17705, 16389, 21346, 19626, 29977, 23452, 14895, 17452, 17733, 22235, 24687, 15649, 21941, 11472]


for i in range(len(cipher)):
    for c in cipher:
        s = math.sqrt(c-i)-i
        if s%1==0:
            print (int(s).to_bytes(2, byteorder = "big").decode(), end="")
ctf4b{Hey,Fox?YouCanNotTearThatHouseDown,CanYou?}

phisher (misc)

ホモグラフ攻撃をOCRで再現している問題。

送信した文字列が指定のフォントで画像に変換され、その画像をOCRした結果がwww.example.comと一致しかつwww.example.comに含まれる文字が使われていなければflagが手に入る。

Homoglyph Attack Generatorなるものがあったのでこれを使ってメンバーと協力しながら1文字ずつ通る文字を探していった。

試行錯誤の様子
ctf4b{n16h7_ph15h1n6_15_600d}

H2 (misc)

main.goのソースコードと大量のパケットが記録されたpcapデータが渡される。

// main.go
package main

import (
  "net/http"
  "log"
  "fmt"
  "golang.org/x/net/http2"
  "golang.org/x/net/http2/h2c"
)

const SECRET_PATH = "<secret>"

func main() {
  handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == SECRET_PATH {
      w.Header().Set("x-flag", "<secret>")
    }
    w.WriteHeader(200)
    fmt.Fprintf(w, "Can you find the flag?\n")
  })

  h2s := &http2.Server{}
  h1s := &http.Server{
    Addr:    ":8080",
    Handler: h2c.NewHandler(handler, h2s),
  }

  log.Fatal(h1s.ListenAndServe())
}

パスが正しいときだけx-flagというヘッダーが渡されるようなので、pcapデータをWireSharkで開き下記フィルタで絞ると当該通信が見つかった。

http2.header.name == x-flag
ctf4b{http2_uses_HPACK_and_huffm4n_c0ding}

textex (web)

TeXを書くとPDFに変換して出力してくれるサービス。”flag”という文字が含まれていると弾かれてしまうので分割しマクロで置換することで回避し、/inputでflagファイルの中身を出力。

\documentclass{article}
\begin{document}
\def\fl{../../fl}
\def\ag{ag}
\input{\fl\ag}
\end{document}

これでローカル(配布Docker)上では動作したのだが、同じコードをサーバー側に投げるとエラーで弾かれてしまい困っていた。(他の参加者が同様の内容でDiscord上で質問しているのも複数回見かけた。)

flagの形式がctf4b{XXX}であるため、\inputでflagを埋め込んだ際に{}が特殊文字として認識されてしまっているということに途中で気づき、{}を置換する方法を探していたが、結局数式モードで出力し、消えた{}を復元・下付き文字を_に変換などの微調整を行うことで強引に解決

\documentclass{article}
\begin{document}
\def\fl{/var/www/fl}
\def\ag{ag}
$\input{\fl\ag}$
\end{document}
出力されるPDF
ctf4b{15_73x_pr0n0unc3d_ch0u?}

追記:
終了後に公開された作問者writeupによると、\verbatiminput等を使うのが想定解らしい。

タイトルとURLをコピーしました