RiceTeaCatPanda CTF 2020 Write-up
はじめに
2020/01/20 ~ 2019/01/25に開催されたRiceTeaCatPanda CTFにチーム(NekochanNano!)で参加しました.
成績
チームとしては29問解いて34位でした (1323チーム中).
今回は自分が解いた6問のWrite-upを書きます.
Reverse Engineering
What's the Password: Revisited [300pts]
There's a password somewhere...
> file whats-the-password-revisited whats-the-password-revisited: ELF 64-bit LSB shared object x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=36f742e6516c60be312a3b60eb7e4f3fbf703161, stripped
アプローチ:Ghidraでデコンパイル
配布ファイルを実行するとパスワードの入力を求められます.
> ./whats-the-password-revisited Whats the password? satto1237 Hey, that's not right!
配布ファイルをGhidra
でデコンパイルして,内部処理を確認すると
入力文字列に対して排他的論理和をとった値とDAT_00301020
を比較していることが分かるので後はデコーダを書けば終わりです.
undefined8 FUN_001007c0(void) { // [snip] byte local_3b [20]; // [snip] __fgets_chk(local_3b,0x16,0x1c); // [snip] lVar1 = 0; do { if ((int)(char)(&DAT_00301020)[(long)(int)lVar1 * 0x50] != ((int)(char)(local_3b[lVar1] ^ 0x32) + 1U ^ 0x32)) { puts("Hey, that\'s not right!"); /* WARNING: Subroutine does not return */ exit(0); } lVar1 = lVar1 + 1; } while (lVar1 != 0x14); // [snip] }
# DAT_00301020 DAT = [0x3a, 0x31, 0x52, 0x30, 0x34, 0x36, 0x52, 0x30, 0x33, 0x5c, 0x3a, 0x51, 0x73, 0x30, 0x35, 0x45, 0x5c, 0x31, 0x5a, 0x34] passwd = '' for x in DAT: passwd += chr(((x ^ 0x32) - 1) ^ 0x32) print(passwd)
> python solve.py 50m371m32_5Pr34D_0U7
> ./whats-the-password-revisited Whats the password? 50m371m32_5Pr34D_0U7 Nice job! Here's your flag: rtcp{fL492_r_50m371m32_5Pr34D_0U7}
rtcp{fL492_r_50m371m32_5Pr34D_0U7}
screams [1500pts]
You know what, you fix this lol
https://github.com/JEF1056/riceteacatpanda/tree/master/screams%20(1500)
aaaaaaaaaaaaaaaaaa.wav
> file aaaaaaaaaaaaaaaaaa.wav aaaaaaaaaaaaaaaaaa.wav: RIFF (little-endian) data, WAVE audio, stereo 44100 Hz
ur-worst-nightmare.py
import cv2 as a import soundfile as b import random as c import numpy as d from tqdm import tqdm as e import os as f import binascii as z g, h = a.imread("pls-no.jpg"), b.SoundFile("oh-gawd-plsno.wav", 'r') i, j = g.shape[0], 0 k=d.zeros((i*i,2), dtype=d.float64) l, m = e(total=i*i), h.read() l.set_description(" nuKiNG") h.close() u=True t = b'9\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' v = b'@\xe4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' for n in range(0,i): for o in range(0,i): if u == True: p, q, r = g[n][o][0], g[n][o][1], g[n][o][2]; p, q, r = str(p), str(q), str(r) # me me me while len(p) < 3: p="0"+p while len(q) < 3: q="0"+q while len(r) < 3: r="0"+r#eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee result = p+q+r for w in range(0, j+1): x=z.b2a_uu(t); y=z.b2a_uu(v) t = z.a2b_uu("0.00") # ww v = z.a2b_uu("-0.00") s=c.randint(0,1) if s == 0: k[j]=(m[j][0]*2,float(x.decode()[:-2].strip(" ")+result)) if s == 1: k[j]=(m[j][0]*2,float(y.decode()[:-2].strip(" ")+result)) j+=1 #b l.update(1) #wow 0 then b.write('out.wav', k, 44100, 'FLOAT')
アプローチ:頑張ってエンコーダを読む
aaaaaaaaaaaaaaaaaa.wav
とur-worst-nightmare.py
が配布されます.
ur-worst-nightmare.py
はエンコーダで,恐らくaaaaaaaaaaaaaaaaaa.wav
はフラグ画像が埋め込まれた音声ファイルだと考えられます(guessingしたくないのでファイル名を)out.wav
に」してくれ
ur-worst-nightmare.py
の処理を簡単にまとめると以下のようになります.
- フラグ画像の読み込み
- 音声ファイルの読み込み
- フラグ画像のBGRの各ピクセル値を取得
- 各ピクセル値を3桁で0パディング
0.00
または-0.00
と0パディングしたピクセル値を連結して小数化- 小数化したピクセル値を
wav
に埋め込み
これらを踏まえてソルバを書くこと以下のようになります.
from PIL import Image import soundfile img = Image.new('RGB', (500,500)) wav = soundfile.SoundFile("aaaaaaaaaaaaaaaaaa.wav", 'r') wav_data = wav.read() wav.close() count = 0 for y in range(500): for x in range(500): b = int(abs(wav_data[count][1] * 100000)) g = int(abs(wav_data[count][1] * 100000 * 1000)) % 1000 r = int(abs(wav_data[count][1] * 100000 * 1000 * 1000)) % 1000 count += 1 img.putpixel((x,y),(r,g,b)) # img.show() img.save('./flag.jpg')
rtcp{uh_oh_sisters_342}
General Skills
Treeeeeeee [200pts]
It appears that my cat has gotten itself stuck in a tree... It's really tall and I can't seem to reach it. Maybe you can throw a snake at the tree to find it?
Oh, you want to know what my cat looks like? I put a picture in the hints.
treemycatisin.7z
> file treemycatisin.7z treemycatisin.7z: 7-zip archive data, version 0.4
アプローチ:ハッシュ値
treemycatisin.7z
を解凍すると27847のディレクトリと1337のファイルを含んだbigtree
フォルダを得ることができます.
bigtree
内のファイルを眺めるとどうやら2種類のjpg
ファイルが大量に存在することが分かります.
1つ1つ調べるのは手間がかかるのでハッシュ値を利用してサクッと目的のファイルを検索します.
> mkdir jpg > find ./bigtree -type f | grep "\.jpg$" | xargs -J% cp -p % ./jpg > md5 ./jpg/*.jpg | awk '{print $4}' | sort | uniq -c 655 2d7b81239b77deb7fbda026d9521939b 681 49390dd9695e7ab7c49fbea6697bc1a9 1 aeb3e033f8bdbf2ec44fda714da72f77 > md5 ./jpg/*.jpg | grep aeb3e033f8bdbf2ec44fda714da72f77 MD5 (./jpg/ENP92.jpg) = aeb3e033f8bdbf2ec44fda714da72f77 > open ./jpg/ENP92.jpg
RTCP{MEOW_SHARP_PIDGION_RICE_TREE}
Cryptography
HOOOOOOOOOOMEEEEEE RUNNNNNNNNNNNNN!!!!! [50pts]
AND JAKE IS ROUNDING THE BASES
HE PASSES BASE 32!!!
HE ROUNDS BASE 64!!!!!!!
WE'RE WITNESSING A MIRACLE!!!!!!!!!!!!!Just one more base to go ;D
Ecbf1HZ_kd8jR5K?[";(7;aJp?[4>J?Slk3<+n'pF]W^,F>._lB/=r
アプローチ:base85
base85でデコードするとflag
になります.
rtcp{uH_JAk3_w3REn't_y0u_4t_Th3_uWust0r4g3}
View Hintを使わないと問題が見れないのってどうなの
Don't Give The GIANt a COOKie [100pts]
It was just a typical day in the bakery for Delphine. She was preparing her famous chocolate cake, when all of a sudden a GIANt burst through the doors of her establishment and demanded a cookie. Being the strong-willed girl she was, Delphine refused and promptly threw her rolling pin at the GIANt. Doing what any sensible being would do when faced with projectiles, the GIANt let out a shriek and ran out of the shop. Delphine smiled to herself, it was another day well done. But oh? What's this? It seems the GIANt dropped this behind while he was screaming and scrambling out of the shop.
69acad26c0b7fa29d2df023b4744bf07
アプローチ:md5のクラック
以下のオンラインツールを利用してmd5をクラックします.
rtcp{chocolate mmm}
15 [100pts]
Lhzdwt eceowwl: Dhtnwt Pcln Eaao Qwoohvw
Okw qsyo okcln bah'i fslo cl baht Dhtnwt Pcln dhtnwt cy yazwalw'y eaao ehlnhy. Dho sy co ohtly aho, okso zcnko dw fkso bah nwo. S 4vksllwt hmqasiwi s mkaoa slalbzahyqb oa okw ycow ykafvsycln kcy ewwo cl s mqsyocv dcl ae qwoohvw, fcok okw yosowzwlo: "Okcy cy okw qwoohvw bah wso so Dhtnwt Pcln." Sizcoowiqb, kw ksi ykawy al. Dho okso'y wgwl fatyw.
Okw mayo fwlo qcgw so 11:38 MZ al Xhqb 16, sli s zwtw ofwlob zclhowy qsowt, okw Dhtnwt Pcln cl rhwyocal fsy sqwtowi oa okw tanhw wzmqabww. So qwsyo, C kamw kw'y tanhw. Kaf ici co ksmmwl? Fwqq, okw DP wzmqabww ksil'o twzagwi okw WJCE isos etaz okw hmqasiwi mkaoa, fkcvk yhnnwyowi okw vhqmtco fsy yazwfkwtw cl Zsbecwqi Kwcnkoy, Akca. Okcy fsy so 11:47. Oktww zclhowy qsowt so 11:50, okw Dhtnwt Pcln dtslvk siitwyy fsy mayowi fcok fcykwy ae ksmmb hlwzmqabzwlo. Ecgw zclhowy qsowt, okw lwfy yosocal fsy valosvowi db slaokwt 4vksllwt. Sli oktww zclhowy qsowt, so 11:58, s qclp fsy mayowi: DP'y "Owqq hy sdaho hy" alqclw eathz. Okw eaao mkaoa, aokwtfcyw plafl sy wjkcdco S, fsy soosvkwi. Vqwgwqsli Yvwlw Zsnsuclw valosvowi okw DP cl rhwyocal okw lwjo isb. Fkwl rhwyocalwi, okw dtwspesyo ykceo zslsnwt ysci "Ak, C plaf fka okso cy. Kw'y nwoocln ectwi." Zbyowtb yaqgwi, db 4vksl. Laf fw vsl sqq na dsvp oa wsocln aht esyo eaai cl mwsvw.
tovm{v4T3Ehq_f1oK_3J1e_i4O4}
アプローチ:quipqiup
換字式暗号っぽいのでquipqiupに投げます.
rtcp{c4R3Ful_w1tH_3X1f_d4T4}
まとめ
- guessingが多すぎてしんどかった
- 途中で飽きてしまった(チームメンバのみなさん申し訳ないです)