はるすえすしーのぶろぐ

ブログのないようがないよう

NITIC_CTF_2 writeup

NITIC CTF(36h, 9/5 12時~9/6 24時)に1人で参加して1701ポイントで62位でした~。
今までcpawCTFとかpicoCTFはやったことあったけど、リアルタイムでのコンテストは初めてだった。

f:id:halss:20210907231224p:plain

f:id:halss:20210907231245p:plain

f:id:halss:20210907231309p:plain

初めてのwriteupです。

▶目次

Web

web_meta (100pt)

ブラウザから覗いても何もないけど、拡張ツール開いてみるとflag is ...って書いてある。

▶Flag

nitic_ctf{You_can_see_dev_too1!}

long flag (200pt)

Flagがありそうだけど表示されてないっぽいので拡張ツール開いてpタグの中を見る。 <span>n</span><span>i</span>...とたくさん書いてあるので全部コピーして置換ツールとかで消去する。

▶Flag

nitic_ctf{Jy!Hxj$RdB$uA,b$uM.bN7AidL6qe4gkrB9dMU-jY8KU828ByP9E#YDi9byaF4sQ-p/835r26MT!QwWWM|c!ia(ynt48hBs&-,|3}

Pwn

pwn monster 1 (100pt)

netcatを使ってnc 35.200.120.35 9001にアクセスするとポ〇モンバトル的なのが始まる。 自分のモンスターのHP/ATKは100/10なのに相手のHP/ATKは9999/9999とめっちゃ不利、普通に負ける。 名前入力の際に長い文字列をぶち込んでやればスタックを破壊してHP/ATKを最強にできるので、勝つ。 (monster 2のATKをマイナスにすると敵を回復させすぎて死ぬって解説面白い、解けなかったんだけども…)

▶Flag

nitic_ctf{We1c0me_t0_pwn_w0r1d!}

Misc

Excel (100pt)

配布されたエクセルファイル開いて、Ctrl+Fで「nitic」で検索するとU869にフラグがある。

▶Flag

nitic_ctf{plz_find_me}

image_conv (200pt)

nitic_ctf{ }とだけ書かれたpngファイルが配布される。
最初$ file after_flag.pngとかしてたけど唐突にペイントツールとかで塗りつぶしたらフラグ出てきた。

▶Flag

nitic_ctf{high_contrast}

Rev

protected (200pt)

$ file challすると実行ファイルらしいので実行してみるとパスワード聞かれる。合ってるとFlagがもらえるっぽい。$ strings challするとsUp3r_s3Cr37_P4s5w0Rdという怪しい文字列が出てくるのでパスワードとして入力するとフラグが得られる。
やらかし大臣なのでnitic_ctf{sUp3r_s3Cr37_P4s5w0Rd}をして1WA…

▶Flag

nitic_ctf{hardcode_secret}

Crypto

Caesar Cipher (100pt)

暗号文fdhvdurot13.comで適当に試していくとフラグを見つけられる。タイトル通り。

▶Flag

nitic_ctf{caesar}

ord_xor (300pt)

Pythonファイルとテキストファイルが配布される。テキストファイルの中身はnhtjcZcsfroydRx`rl。 XORは2回繰り返すと元に戻るので、os.environ[“FLAG”]をテキストファイルの中身に入れ替えるだけでフラグが得られる。

import os
flag = ""
with open("./flag","r") as f:
    flag=f.read()

def xor(c: str, n: int) -> str:
    temp = ord(c)
    for _ in range(n):
        temp ^= n
    return chr(temp)

dec_flag = ""
for i in range(len(flag)):
    dec_flag += xor(flag[i], i)
print(dec_flag)

▶Flag

nitic_ctf{ord_xor}

もしかしてnanigasi_sanはFlagを作るのが下手なんですか?

tanitu_kanji (300pt)

Pythonファイルとテキストファイルが配布される。テキストファイルの中身はl0d0pipdave0dia244im6fsp8xPythonファイルは10文字の暗号化形式formatとFLAGを環境変数から取り出し、formatのi番目が”1”ならalphabets→after1、それ以外ならalphabets→after2に変換しているらしい。 復号化はformatを210通りをbit全探索でやってみてafter1→alphabetsとafter2→alphabetsを試す。

import os
alphabets = "abcdefghijklmnopqrstuvwxyz0123456789{}_"
after1 = "fl38ztrx6q027k9e5su}dwp{o_bynhm14aicjgv"
after2 = "rho5b3k17pi_eytm2f94ujxsdvgcwl{}a086znq"

with open("./flag","r") as f:
    flag = f.read()

def reconv(s: str, table: str) -> str:
    res = ""
    for c in s:
        i = table.index(c)
        res += alphabets[i]
    return res

for bit in range(1<<10):
    dec_flag = flag
    format = ""
    for j in range(10):
        if (bit & (1<<j)):
            format += "1"
        else:
            format += "0"

    for f in format:
        if f == "1":
            dec_flag = reconv(dec_flag, after1)
        else:
            dec_flag = reconv(dec_flag, after2)

    if dec_flag[0:9]=="nitic_ctf":
        print(dec_flag)

▶Flag

nitic_ctf{bit_full_search}

解けなかったやつ

300pt : password(+fixed), pwn monster 2~3, braincheck, report or repeat, summeRSA
500pt : Is it Shell?, baby_IO_jail

ちょっと難しいレベルの問題から上の知識が一切なかったので撃沈。

summeRSA (300pt)

RSA暗号で暗号化された文cと公開鍵e,Nが与えられる。平文mがthe magic words are squeamish ossifrage. nitic_ctf{〇〇}でありFlagの中身は7文字であることがわかっている。 7文字全通り試してe乗してmod Nをとった結果がcと一致したらOK!みたいな脳筋コード書いたけどとけなかった。 Coppersmith’s Attackは検索したけど実装できなくて死

using Primes
function main()
    N = 139144195401291376287432009135228874425906733339426085480096768612837545660658559348449396096584313866982260011758274989304926271873352624836198271884781766711699496632003696533876991489994309382490275105164083576984076280280260628564972594554145121126951093422224357162795787221356643193605502890359266274703
    e = 7
    c = 137521057527189103425088525975824332594464447341686435497842858970204288096642253643188900933280120164271302965028579612429478072395471160529450860859037613781224232824152167212723936798704535757693154000462881802337540760439603751547377768669766050202387684717051899243124941875016108930932782472616565122310

    ans = "the magic words are squeamish ossifrage. nitic_ctf{"
    abc = "!\"#\$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    len = length(abc)
    for i in 1:len,j in 1:len,k in 1:len,l in 1:len,n in 1:len,m in 1:len,o in 1:len
        res = join([ans,abc[i],abc[j],abc[k],abc[l],abc[n],abc[m],abc[o],"}"])
        m_res = parse(BigInt, bytes2hex(Vector{UInt8}(res)), base=16)
        if m_res^e % N == c
            println(hex2bytes(string(m_res, base=16)))
            return
        end
    end
end

main()

感想・反省?

(そもそもwriteupって感想書いていいものなのかよくわからないけど…)
nanigasi_sanをはじめ茨城高専の運営の皆さんお疲れさまでした。自分としては、CTFに親しみを持たせつつ学ばないといけない事柄を示してくれるコンテストで有難かったです。
反省は、Ghidraの使い方忘れて逆コンパイルはできないわ、RSA暗号の解き方がわかっても実装できないわ、nanigasi_sanの300点しか解けないわで慌てすぎてTwitterしかすることがなくなってました。反省します。