2024/06/15(~24h)に行われたSECCONのbeginner向けCTF大会にチームで出場しました。(Team Name: FCS-Zundamons, User Name: HydrangeA)(順位: 366/962)
CTFを3回ほど経験した上でチームで出場させてもらいました。チームメンバーの後輩たちにCTFこんな感じだよ~と教えつつ主にreversingの問題に取り組みました。しかし、実際に解けた問題は1問だけであまり成長できてないことを実感しました。(悲しい)
なのでwriteupとしては1問、他の問題で解けなかったものに関してはここまで勉強できたという記録を残す意味で書かせていただきました。
何かの参考になれば幸いです。
見たことがない形式のファイルだけど、中身を見れば何かわかるかも…?
cha-ll-enge.tar.gz 0356d82e580af031d889a46a750dd3a6b96a74ce
reversingの問題の傾向として、ファイルが添付されてその中身を解読してフラグを取る問題が定番というイメージがあったので、この問題もそうだろうと感じました。なのでさっそくダウンロード、中身を見てみます。
ファイルの中身
cha.ll.enge
.ll.enge?となったのでfileコマンドを打ってみる。
file cha.ll.enge
cha.ll.enge: ASCII text, with very long lines (478)
ただのテキストファイルのようなので、catコマンドでファイルを見てみると…
見たことのないコードのようなものが出てきました。これを解読して欲しいということか…?気合で読むものなのだろうか…
一旦自力で読むことは置いといて、8行目の@main()の行を検索すれば何の言語で書かれたものか分かるのではないか、と予想して検索しました。すると、LLVMというキーワードが出てきました。
LLVMはコンパイラの実行を最適化するための言語…という認識があっているか分かりませんが、知らず知らずの内にお世話になっていそうな言語だと感じました。
それはともかく、これを自力で1から学習して読むか、LLVMを逆変換してCプログラムに直すツールがあるかどうか探すか、AI(Chat-GPT)に変換してもらうか、の3択を考えました。
結論から言うと、Chat-GPTに変換してもらい、C言語プログラムを読むことで解答しました。
以下が返答結果のCプログラムです。
これを見ると、key[50]というものがあり、これはLLVMコードでも確認できましたが、ユーザの標準入力に対して処理を行う秘密鍵であることが明確になりました。そして正しい標準入力(FLAG)に対してkeyの中身をxorし、xor_resultがすべて0になることでフラグの正誤を判定しているようです。
xor_resultの結果に入る値は
であり、result = 0の時にflagと対応する文字となるため、
となることが分かります。
後は上記の法則を満たすCプログラムに変換し、実行します。するとフラグが出現します。
ctf4b{7ick_7ack_11vm_int3rmed14te_repr3sen7a7i0n}
ここからはunsolveな問題の、考えたことの殴り書きです。
Intel記法のアセンブリ言語を書いて、flag.txtファイルの中身を取得してみよう!
https://assemble.beginners.seccon.games
assemble.tar.gz d68dd70d722c38f90c8c4a8e8c36be6a94e3fab4
ページ先を見ると、Intel記法のアセンブリ言語で、mov・push・syscallのみでフラグを取得せよ、といった内容がありました。
アセンブリ言語については事前にある程度学んできましたが、実際に1から書くことはなかったのでいい経験になったような気がします。
ステップ3の標準出力のところまでは達成しましたが、最後にflag.txtの中身を出力するに至りませんでした。未だに最後が分からないので、その点は他のwriteupを参考にさせていただくとします。
少なくとも今回学べた内容としては、
・syscallする際の引数にあたるレジスタはrdi, rsi, rdx…であること
・rbp, rspがスタックに関するアドレスを持っていること
です。レジスタ毎の特徴を理解し、実際に書きながら体験できたことが大きいです。
adminのみflagを取得できる認可サービスを作りました!
https://wooorker.beginners.seccon.games
脆弱性報告bot(URL)
wooorker.tar.gz 2911ea65e5bb56cca44780edeae2ccf8c0956a52
ざっくりと説明すると、adminとしてログインできた時のみ正しいトークンを受け取り、そのトークン情報があればフラグを回収できる、という問題だと思います。
adminのパスワードを取得するすべが無いように見えたため、パスワードを予想することは諦めました。代わりにトークンを作る箇所で怪しい部分があったので、トークンを偽造すれば攻撃に成功すると考えました。
adminとは別にadmin権限を持たないguestアカウントがあり、そちらでログインすればトークン(フラグは取れない)が取得できます。
そのトークンを復号する(jwtによる署名文を復号できるサイトがあった)と、暗号化前の平文(json)が取得できたため、その中身を書き換えることで偽造できそうでした。
パラメータを書き換えつつ、トークン作成時の秘密パラメータjwtSecretはよく見ると1秒で1ずつ増えているように見えたので、これが今回の脆弱性の部分につながっていると予想し、jwtSecretを先読みして書き換えることで攻撃できると考えましたが、結果としてはうまくいかず失敗しました。これ以上の方法が思いつきません…。良いところまでいった気もするんですがねぇ…。
それ以上に脆弱性報告botの使い方が良くわからんかった。他のwriteupできちんと学習します。
beginner向けとはいえ、やはり骨のある問題が多い。CTFというコンテストの難しさを改めて実感しました。いっぱい解いて、手札を増やすに限りますね。地道に精進していきましょう。
最後まで読んでいただきありがとうございます。