1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IERAE CTF2024 Writeup (入門問題のみ)

Posted at

CTF 初心者でとりあえず何かしらのコンテストに出てみようと思い IERAE CTF2024 に参加しました!
結果としては入門問題をいくつか解いただけで終わりましたが, トレーニングも兼ねて解けた問題の Writeup を書いてみます (Qiita での投稿も初なので何かお作法等変なことがあれば教えてほしいです!)

筆者の CTF に関するレベル (参考)

  • OverTheWire の bandit, natas, Leviathan をある程度解いた (わからなかったところは主に Web 上の writeup を見て何とかクリアした感じ)
  • CTFlearn で easy の問題を大体解いた (こちらもわからないところは早めに見切りをつけて writeup を探して勉強したので, すべて自力ではない)

Writeup

Welcome

  • 確認問題のため省略

OMG

  • ブラウザから指定された url を開くと 33 回クリックしてとの指示が出ている $\to$ 愚直に考えると 33 回クリックするとフラグが表示されそう?
  • ソースコードを確認すると 33 回クリックされた場合にある文字列が base64 デコードされたものが表示されるようになっていた $\to$ おそらくコード内にあるその文字列がフラグを base64 エンコードされたもの
  • 上記の予想通り base64 デコードしてみるとフラグゲット!

derangement

  • 配布された python コードを読むと, magicword に指定された 15 文字のランダム文字列を当てることができればフラグがゲットできるらしい
  • 最大 300 回までクエリを投げることが可能で, 各クエリでは必ず magicword と同じ位置に同じ文字が来ないよう並べ替えられた文字列を取得する
  • 各位置において当てはまる可能性のある文字は 15 文字までなので, 300 回のクエリで magicword を絞ることは可能
  • 以下の exploit を作成し実行したらフラグを獲得できた
from pwn import *

sh = remote("104.199.135.28", 55555)

welcome_txt = sh.recvuntil(b">").decode()
print(welcome_txt)

# send 1 for hint
print("send 1")
sh.send(b"1\n")
hint_txts = sh.recvuntil(b">").decode().split("\n")
hint_txt = ""
for txt in hint_txts:
    if "hint:" in txt:
        hint_txt = txt.split()[1].replace("\n","")

print(list(hint_txt))

possible_chars = "".join(list(set(list(hint_txt))))
possibles = [possible_chars] * len(hint_txt)
print(possibles)

for i in range(100):
    print("send 1")
    sh.send(b"1\n")
    hint_txts = sh.recvuntil(b">").decode().split("\n")
    hint_txt = ""
    for txt in hint_txts:
        if "hint:" in txt:
            hint_txt = txt.split()[1].replace("\n","")
    hint_strs = hint_txt
    print(hint_strs)

    for i in range(len(hint_strs)):
        if hint_strs[i] in possibles[i]:
            possibles[i] = possibles[i].replace(hint_strs[i],"")

passwd = "".join(possibles)
print(passwd)

sh.send(b"2\n")
prompt_txt = sh.recvuntil(b">").decode()
print(prompt_txt)
sh.send(passwd.encode())
sh.interactive()

実際に 300 回ループを回す必要はなく, 100 回程度のループでもうまくパスワードを推測できた.

Assignment

  • 配布された実行ファイルについて gdb で逆アセンブルをかけたところ, main 関数でフラグをバラバラな順番で読み込んでいることが確認できた.
  • 手作業で元の順番通りに並べ替えてフラグを取得 (他にもっと楽な方法がありそう)

感想

  • 全くできなかったらどうしようと不安だったけれど, とりあえず参加してみたら普通に楽しかったです (競プロを始めたときに近い感じ)
  • CTFTime で毎週何かしらの CTF の開催情報が載っているので, 今後も定期的に参加してみようと思いました
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?