2021 MyFirstCTF write-up


Information

ID gunjyo
Date 2021/05/22 09:30 - 17:30
Rank 11/282
Score 1362

Prologue

這是我初次參加(好像也只能參加一次) MyFirstCTF,為期 8 小時。
題目會與接續的 AIS3 Pre-exam 些微重疊(因為 AIS3 Pre-exam 的第一天是 MFC~)

我的排名是第 11 名 ,雖然解的題目不多,對當時的我來說是個還滿滿意的成績~
因為是 PR90 以上所以當時有領到獎狀和 AIS3 的帽子 😍
mfc rank

事不遲疑,直接進到 write-up 吧

Misc

Cat Slayer ᶠᵃᵏᵉ | Nekogoroshi

BGM: 亜咲花「I believe what you said」
TERM=xterm-256color ssh -p 5566 h173@quiz.ais3.org
Author: splitline feat. Hojo Satoko

Welcome 題

TERM=xterm-256color ssh -p 5566 h173@quiz.ais3.org
連線後會跳轉到輸入數字密碼的介面,只要按錯一個就會跳 Locked,要重新連線
暴力嘗試即可
密碼 2025830455298

flag AIS3{H1n4m1z4w4_Sh0k0gun}

HINT 附上了影片

[祝賀] 新垣結衣新婚快樂 發錢囉

題目檔案
下載後觀察到是 png , foremost 可以看到裡面有 zip檔案
需要密碼 但 zip cracker 沒辦法找到
猜測是 zip 偽加密,下載 editor 更改後就可以得到 flag 的圖片
左邊為原檔 右邊為更改後

flag

Crypto

Microchip

output: =Js&;*A``odZHi\'>D=Js&#i-DYf>Uy\'yuyfyu<)Gu

把 FLAG 每四個字就翻轉,接著加上 key 後 mod 96,再加上 32 後取字元值,就會得到 output
只要有 key 就可以用 result 逆推回 flag
由於我們知道 flag format = AIS3{printable},因此利用AIS3就可以輕易逆推 key
4 個而已慢慢用手推即可

接著把 result 依據 key 逆推回去即可
script

result = '=Js&;*A`odZHi\'>D=Js&#i-DYf>Uy\'yuyfyu<)Gu'
n = list()
for i in range(0,40,4):
    for j in range(4):
        n.append(ord(result[i+j])-32)
print(n)
#n = [29, 42, 83, 6, 27, 10, 33, 64, 79, 68, 58, 40, 73, 7, 30, 36, 29, 42, 83, 6, 3, 73, 13, 36, 57, 70, 30, 53, 89, 7, 89, 85, 89, 70, 89, 85, 28, 9, 39, 85]

for i in range(0,40,4):
    n[i],n[i+1],n[i+2],n[i+3] = n[i+3],n[i+2],n[i+1],n[i]
print(n)
#n = [6, 83, 42, 29, 64, 33, 10, 27, 40, 58, 68, 79, 36, 30, 7, 73, 6, 83, 42, 29, 36, 13, 73, 3, 53, 30, 70, 57, 85, 89, 7, 89, 85, 89, 70, 89, 85, 39, 9, 28]

key = [69,42,87,10]
for i in range(40):
    print(chr(((n[i] + 96 - key[i%4]) % 96) + 32) , end='')

執行 script 後得到AIS3{w31c0me_t0_AIS3_cryptoO0O0o0Ooo0}22 可以看到 padding 為 22

flag AIS3{w31c0me_t0_AIS3_cryptoO0O0o0Ooo0}

Judgement

from hashlib import sha256
import string
flag = 'AIS3{THIS_IS_A_FAKE_FLAG}'

cand = string.ascii_letters + string.digits + '_{}'
charset = string.printable[:93]
print(cand)
enc = ''
for c in flag:
    assert(c in cand)
    enc  += charset[int(sha256(c.encode()).hexdigest(), 16) % len(charset)]
print(enc)

output:)g;Fk@>2g;2V2J?d5G3_8V2<dR2i5GZ@<?2)g\j_2V&?2;@[F@ek2_3"=k&;2)\F2J9LL4g[W2"[2<)RZ23@<?2elFZ?2=@jZ23@=F2Yi52;lL5Vj2J?2J8\e@eW23e2lF330

很直覺的想法是把所有cand裡面的字元都跑一次+比對,但因為有多個字元會跑出同一個結果,所以我把每個結果的可能性都print出來用人工比對
script

from hashlib import sha256
import string
enc = ')g;Fk@>2g;2V2J?d5G3_8V2<dR2i5GZ@<?2)g\j_2V&?2;@[F@ek2_3"=k&;2)\F2J9LL4g[W2"[2<)RZ23@<?2elFZ?2=@jZ23@=F2Yi52;lL5Vj2J?2J8\e@eW23e2lF330'
for i in enc:
    print(i,end = ' ')
    for j in cand:
        c = charset[int(sha256(j.encode()).hexdigest(), 16) % len(charset)]
        if(i==c):
            print(j,end = ' ')
    print()

第一個字元為題目的enc 後面的是可能的字元

按照一般英文邏輯 + leet 語法去比對,但發現有幾個不太明確的,因此把已經推出來的丟到網路上便發現 flag 其實是來自sans undertale 😂

flag
AIS3{iT_IS_4_Beaut1FUL_day_0utside_8IrD5_4Re_SiNGin9_F1owERS_Ar3_BlOOmIN6_oN_dAys_1iKe_7h3se_
kiDs_1ik3_Y0u_ShOuLD_Be_BUrnin6_1n_h311}

ReSident evil villAge

註:此題用了非正規解

題目是 RSA 簽證,目標是把 signature 送進去以達到 pow(sig, e, n) == bytes_to_long(b'Ethan Winters')
原則上只要把 Ethan Winters 轉成 hex 丟進去讓它跑出 signature 之後,再丟回去讓他 verify 就可以了。
但是從 if msg == b'Ethan Winters' or bytes_to_long(msg) >= n: # msg+k*n not allowed 這行可以看到 check msg == Ethan Winters 會被擋掉。
由於送進去的是字串,於是要讓數字不變但是字串改變,就去嘗試 Bypass,發現前面加上 00 可以繞過,所以傳 00 加上 Ethan Winters 轉成 hex 就可以了
直接上圖。

Epilogue

記得在早上的時候可能是太緊張,好像只解出一兩題(?)左右
一開始就看到有一題 RSA,因為前幾天一直在 CryptoHack 練 RSA 然後又有兩個人很快就解了就果斷看那題,然後就看了爆炸久,大概在一個半小時的時候就很崩潰,因為大家的分數都蹭蹭蹭的上去(賽前一周有專門陪我練的學長,所以有種要考好的壓力(#))
後來吃完午餐冷靜下來之後解題就比較順利了
真的是親身體會比賽緊張會影響發揮這句話~~~
有任何問題歡迎和我討論~~


Author: Gunjyo
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Gunjyo !
  TOC