SchoolCTF writeup
日本時間2015/11/04 15:00~21:30に行われたSchoolCTFの解けた(または協力した)問題のwriteupです。
(admin 200) Cipollino, little onion
Do you like containers as we do?
添付ファイル:image_1cfb4379b82626f0b5d28129ddb5918f8c010aa8.jpg
画像で「このファイルはrarファイルだよ!」と教えてくれてます。とりあえずバイナリエディタで開いてみます。
pngファイルじゃねーか!
と、いうわけでこの中にrarファイルがあるとみて、pngの終端であるIENDという文字列を探します。
ありました。IENDから4バイトほど先に3ar!という文字列が見えます。rarファイル、来ましたね。というわけでバイト列0x52,0x61,0x72,0x21より前を全て削除します。
このようになったら、適当なファイル名.rarにして解凍ソフトで解凍します。すると…。
巨大QRコードが現れました。これを読み込むことのできるソフトを探すとQR Code Editorというソフトが見つかったので導入してみると…。
C++が出てきました。
#include <iostream> #include <cstdio> using namespace std; unsigned int key=2343454423; unsigned char gen_key(){ key=key*4356776434567+65765; return (unsigned char) ((unsigned int)(key/65536)%32768); } int main(){ unsigned int mas[]={18, 8, 43, 102, 31, 185, 187, 48, 34, 195, 107, 9, 7, 228, 188, 131, 72, 89, 232, 220, 25, 64, 176, 18, 220, 61, 149, 41, 208, 216, 41, 105, 76, 139, 154, 48, 157, 174, 50, 235, 138, 200, 206, 108, 106, 203, 231, 169, 158, 102, 5, 86, 8, 57, 80, 19, 216, 188, 139, 210, 36, 252, 6, 81, 73, 91, 53, 63, 10, 30, 27, 211, 216, 100, 84, 150, 76, 179, 154, 144, 124, 34, 189, 221, 21, 84, 159, 40, 30, 1, 191, 161, 48, 115, 178, 120, 172, 28, 45, 221, 86, 113, 108, 131, 22, 198, 86, 148, 38, 125, 94, 127, 230, 234, 19, 204, 90, 40, 153, 169, 15, 213, 174, 139, 26, 117, 172, 160, 93, 127, 1, 33, 151, 92, 46, 141, 219, 39, 86, 249, 156, 170, 174, 32, 249, 98, 135, 42, 187, 70, 192, 32, 168, 83, 95, 253, 63, 0, 244, 136, 85, 115, 51, 56, 183, 85, 253, 195, 135, 52, 164, 204, 162, 36, 255, 27, 141, 11, 184, 133, 27, 209, 16, 119, 144, 23, 79, 60, 48, 33, 136, 51, 23, 242, 211, 60, 72, 153, 123, 254, 34, 228, 127, 225, 237, 34, 0, 132, 197, 71, 110, 234, 69, 106, 237, 99, 51, 202, 114, 194, 33, 53, 249, 204, 197, 12, 185, 28, 36, 204, 245, 63, 103, 126, 99, 16, 126, 79, 221, 106, 1, 17, 224, 170, 22, 213, 219, 21, 116, 146, 90, 238, 62, 144, 176, 0, 100, 211, 85, 132, 155, 198, 138, 51, 79, 136, 153, 43, 232, 15, 210, 43, 249, 22, 248, 76, 136, 40, 221, 222, 218, 94, 13, 44, 210, 35, 140, 113, 209, 148, 210, 110, 51, 183, 195, 80, 88, 247, 2, 161, 212, 230, 161, 53, 85, 180, 38, 113, 78, 115, 31, 220, 101}; unsigned char gen_mas[313]; int j; for(j=0;j<313;j++){ gen_mas[j]=mas[j]^gen_key(); } for(j=0;j<313;j++){ printf("0x%x, ", gen_mas[j]); } cout << endl; }
実行すると、こうなります。
0x42, 0x36, 0x34, 0x27, 0x59, 0x53, 0x41, 0x39, 0x49, 0x43, 0x63, 0x33, 0x4d, 0x43, 0x41, 0x33, 0x4e, 0x69, 0x41, 0x32, 0x4e, 0x53, 0x41, 0x33, 0x4d, 0x53, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x33, 0x4d, 0x53, 0x41, 0x30, 0x4f, 0x43, 0x41, 0x32, 0x4f, 0x43, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x32, 0x4f, 0x43, 0x41, 0x32, 0x4e, 0x53, 0x41, 0x33, 0x4e, 0x79, 0x41, 0x33, 0x4f, 0x43, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x32, 0x4e, 0x69, 0x41, 0x34, 0x4d, 0x69, 0x41, 0x30, 0x4f, 0x43, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x34, 0x4e, 0x53, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x34, 0x4d, 0x69, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x34, 0x4d, 0x79, 0x41, 0x30, 0x4f, 0x43, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x32, 0x4e, 0x79, 0x41, 0x30, 0x4f, 0x43, 0x41, 0x30, 0x4f, 0x43, 0x41, 0x33, 0x4e, 0x69, 0x41, 0x35, 0x4e, 0x53, 0x41, 0x32, 0x4f, 0x43, 0x41, 0x32, 0x4f, 0x53, 0x41, 0x32, 0x4e, 0x79, 0x41, 0x34, 0x4d, 0x69, 0x41, 0x34, 0x4f, 0x53, 0x41, 0x34, 0x4d, 0x43, 0x41, 0x34, 0x4e, 0x43, 0x41, 0x33, 0x4f, 0x53, 0x41, 0x34, 0x4d, 0x69, 0x63, 0x4b, 0x43, 0x6d, 0x31, 0x68, 0x63, 0x7a, 0x31, 0x62, 0x58, 0x51, 0x6f, 0x4b, 0x62, 0x57, 0x46, 0x7a, 0x50, 0x57, 0x45, 0x75, 0x63, 0x33, 0x42, 0x73, 0x61, 0x58, 0x51, 0x6f, 0x4a, 0x79, 0x41, 0x6e, 0x4b, 0x51, 0x6f, 0x4b, 0x5a, 0x6d, 0x39, 0x79, 0x49, 0x47, 0x6b, 0x67, 0x61, 0x57, 0x34, 0x67, 0x63, 0x6d, 0x46, 0x75, 0x5a, 0x32, 0x55, 0x6f, 0x62, 0x47, 0x56, 0x75, 0x4b, 0x47, 0x31, 0x68, 0x63, 0x79, 0x6b, 0x70, 0x4f, 0x67, 0x6f, 0x4a, 0x59, 0x6a, 0x31, 0x70, 0x62, 0x6e, 0x51, 0x6f, 0x62, 0x57, 0x46, 0x7a, 0x57, 0x32, 0x6c, 0x64, 0x4b, 0x51, 0x6f, 0x4a, 0x59, 0x7a, 0x31, 0x6f, 0x5a, 0x58, 0x67, 0x6f, 0x59, 0x69, 0x6b, 0x4b, 0x43, 0x58, 0x42, 0x79, 0x61, 0x57, 0x35, 0x30, 0x4b, 0x47, 0x4d, 0x73, 0x49, 0x47, 0x56, 0x75, 0x5a, 0x44, 0x30, 0x6e, 0x49, 0x43, 0x63, 0x70, 0x43, 0x67, 0x70, 0x77, 0x63, 0x6d, 0x6c, 0x75, 0x64, 0x43, 0x67, 0x6e, 0x4a, 0x79, 0x6b, 0x3d, 0x27,
大量の16進数の出力があるので、これを文字列に変えます。
#include <iostream> #include <cstdio> using namespace std; unsigned int key = 2343454423; unsigned char gen_key(){ key = key * 4356776434567 + 65765; return (unsigned char)((unsigned int)(key / 65536) % 32768); } int main(){ unsigned int mas[] = { 18, 8, 43, 102, 31, 185, 187, 48, 34, 195, 107, 9, 7, 228, 188, 131, 72, 89, 232, 220, 25, 64, 176, 18, 220, 61, 149, 41, 208, 216, 41, 105, 76, 139, 154, 48, 157, 174, 50, 235, 138, 200, 206, 108, 106, 203, 231, 169, 158, 102, 5, 86, 8, 57, 80, 19, 216, 188, 139, 210, 36, 252, 6, 81, 73, 91, 53, 63, 10, 30, 27, 211, 216, 100, 84, 150, 76, 179, 154, 144, 124, 34, 189, 221, 21, 84, 159, 40, 30, 1, 191, 161, 48, 115, 178, 120, 172, 28, 45, 221, 86, 113, 108, 131, 22, 198, 86, 148, 38, 125, 94, 127, 230, 234, 19, 204, 90, 40, 153, 169, 15, 213, 174, 139, 26, 117, 172, 160, 93, 127, 1, 33, 151, 92, 46, 141, 219, 39, 86, 249, 156, 170, 174, 32, 249, 98, 135, 42, 187, 70, 192, 32, 168, 83, 95, 253, 63, 0, 244, 136, 85, 115, 51, 56, 183, 85, 253, 195, 135, 52, 164, 204, 162, 36, 255, 27, 141, 11, 184, 133, 27, 209, 16, 119, 144, 23, 79, 60, 48, 33, 136, 51, 23, 242, 211, 60, 72, 153, 123, 254, 34, 228, 127, 225, 237, 34, 0, 132, 197, 71, 110, 234, 69, 106, 237, 99, 51, 202, 114, 194, 33, 53, 249, 204, 197, 12, 185, 28, 36, 204, 245, 63, 103, 126, 99, 16, 126, 79, 221, 106, 1, 17, 224, 170, 22, 213, 219, 21, 116, 146, 90, 238, 62, 144, 176, 0, 100, 211, 85, 132, 155, 198, 138, 51, 79, 136, 153, 43, 232, 15, 210, 43, 249, 22, 248, 76, 136, 40, 221, 222, 218, 94, 13, 44, 210, 35, 140, 113, 209, 148, 210, 110, 51, 183, 195, 80, 88, 247, 2, 161, 212, 230, 161, 53, 85, 180, 38, 113, 78, 115, 31, 220, 101 }; unsigned char gen_mas[313]; int j; for (j = 0; j<313; j++){ gen_mas[j] = mas[j] ^ gen_key(); } for (j = 0; j<313; j++){ printf("0x%x, ", gen_mas[j]); } cout << endl; printf("\n%s", gen_mas); //これを付け加えただけ }
実行すると、先ほどの16進数の下に
B64'YSA9ICc3MCA3NiA2NSA3MSA5NSA3MSA0OCA2OCA5NSA2OCA2NSA3NyA3OCA5NSA2NiA4MiA0OCA5NSA4NSA5NSA4MiA5NSA4MyA0OCA5NSA2NyA0OCA0OCA3NiA5NSA2OCA2OSA2NyA4MiA4OSA4MCA4NCA3OSA4MicKCm1hcz1bXQoKbWFzPWEuc3BsaXQoJyAnKQoKZm9yIGkgaW4gcmFuZ2UobGVuKG1hcykpOgoJYj1pbnQobWFzW2ldKQoJYz1oZXgoYikKCXByaW50KGMsIGVuZD0nICcpCgpwcmludCgnJyk='フフフフフフフフフフフ
このような文字列が現れます。B64と書いてあるので、base64でしょうか。シングルクォートで囲まれた文字列をデコードします。
$ echo "YSA9ICc3MCA3NiA2NSA3MSA5NSA3MSA0OCA2OCA5NSA2OCA2NSA3NyA3OCA5NSA2NiA4MiA0OCA5NSA4NSA5NSA4MiA5NSA4MyA0OCA5NSA2NyA0OCA0OCA3NiA5NSA2OCA2OSA2NyA4MiA4OSA4MCA4NCA3OSA4MicKCm1hcz1bXQoKbWFzPWEuc3BsaXQoJyAnKQoKZm9yIGkgaW4gcmFuZ2UobGVuKG1hcykpOgoJYj1pbnQobWFzW2ldKQoJYz1oZXgoYikKCXByaW50KGMsIGVuZD0nICcpCgpwcmludCgnJyk=" | base64 -d a = '70 76 65 71 95 71 48 68 95 68 65 77 78 95 66 82 48 95 85 95 82 95 83 48 95 67 48 48 76 95 68 69 67 82 89 80 84 79 82' mas=[] mas=a.split(' ') for i in range(len(mas)): b=int(mas[i]) c=hex(b) print(c, end=' ') print('')
今度はpython3です。実行してみます。
0x46 0x4c 0x41 0x47 0x5f 0x47 0x30 0x44 0x5f 0x44 0x41 0x4d 0x4e 0x5f 0x42 0x52 0x30 0x5f 0x55 0x5f 0x52 0x5f 0x53 0x30 0x5f 0x43 0x30 0x30 0x4c 0x5f 0x44 0x45 0x43 0x52 0x59 0x50 0x54 0x4f 0x52
先ほどと同じように16進数が出てきました。
ここでソースを読んでみると、ただ10進数を16進数に直しているだけなのでこれを文字列に直します。(上手いやり方が見つからなかったのでバイナリエディタでやってしまった・・・)
すると
FLAG_G0D_DAMN_BR0_U_R_S0_C00L_DECRYPTOR
フラグが現れました。
(crypto 100) Lazy cryptanalyst
Looks like I'm too lazy to complete it. >_< Can you help me a little?
bsxz xz om rxuvi. bsiri qri oqym gbsirz vxji xb, whb bsxz gyi xz oxyi. om rxuvi xz om wizb urxiye. xb xz om vxui. x ohzb oqzbir xb qz x ohzb oqzbir om vxui. fxbsghb oi, om rxuvi xz hzivizz. fxbsghb om rxuvi, x qo hzivizz. x ohzb uxri om rxuvi brhi. x ohzb zsggb zbrqxlsbir bsqy om iyiom, fsg xz brmxyl bg jxvv oi. x ohzb zsggb sxo wiugri si zsggbz oi. x fxvv. wiugri lge x zfiqr bsxz kriie: om rxuvi qye omzivu qri eiuiyeirz gu om kghybrm, fi qri bsi oqzbirz gu ghr iyiom, fi qri bsi zqpxgrz gu om vxui. zg wi xb, hybxv bsiri xz yg iyiom, whb ciqki. uvql xz q eqm fxbsghb wvgge xz vxji q eqm fxbsghb zhyzsxyi. qoiy.
これは単一換字暗号だと勘がささやいている!ってみたまんまですね。
ヒントとして、すでにb = t,s = hであると教えられています。
エドガー・アラン・ボーの『黄金虫』という本では
e,t,a,o,i,n,s,h,r,d,l,u,c,m,f,w,g,y,p,b,v,k,x,j,q,zという順番でその英字の出現回数が多くなります。
まずは出現回数を調べてみます。
def main(): str1 = "bsxz xz om rxuvi. bsiri qri oqym gbsirz vxji xb, whb bsxz gyi xz oxyi. om rxuvi xz om wizb urxiye. xb xz om vxui. x ohzb oqzbir xb qz x ohzb oqzbir om vxui. fxbsghb oi, om rxuvi xz hzivizz. fxbsghb om rxuvi, x qo hzivizz. x ohzb uxri om rxuvi brhi. x ohzb zsggb zbrqxlsbir bsqy om iyiom, fsg xz brmxyl bg jxvv oi. x ohzb zsggb sxo wiugri si zsggbz oi. x fxvv. wiugri lge x zfiqr bsxz kriie: om rxuvi qye omzivu qri eiuiyeirz gu om kghybrm, fi qri bsi oqzbirz gu ghr iyiom, fi qri bsi zqpxgrz gu om vxui. zg wi xb, hybxv bsiri xz yg iyiom, whb ciqki. uvql xz q eqm fxbsghb wvgge xz vxji q eqm fxbsghb zhyzsxyi. qoiy." a = b = c = d = e = f = g = h = i = j =k = l = m = n = o = p = q = r = s = t = u = v = w = x = y = z = 0 for si in str1: if si == "a": a += 1 elif si == "b": b +=1 elif si == "c": c +=1 elif si == "d": d +=1 elif si == "e": e +=1 elif si == "f": f +=1 elif si == "g": g +=1 elif si == "h": h +=1 elif si == "i": i +=1 elif si == "j": j +=1 elif si == "k": k +=1 elif si == "l": l +=1 elif si == "m": m +=1 elif si == "n": n +=1 elif si == "o": o +=1 elif si == "p": p +=1 elif si == "q": q +=1 elif si == "r": r +=1 elif si == "s": s +=1 elif si == "t": t +=1 elif si == "u": u +=1 elif si == "v": v +=1 elif si == "w": w +=1 elif si == "x": x +=1 elif si == "y": y +=1 elif si == "z": z +=1 print("a = "+ str(a)) print("b = "+ str(b)) print("c = "+ str(c)) print("d = "+ str(d)) print("e = "+ str(e)) print("f = "+ str(f)) print("g = "+ str(g)) print("h = "+ str(h)) print("i = "+ str(i)) print("j = "+ str(j)) print("k = "+ str(k)) print("l = "+ str(l)) print("m = "+ str(m)) print("n = "+ str(n)) print("o = "+ str(o)) print("p = "+ str(p)) print("q = "+ str(q)) print("r = "+ str(r)) print("s = "+ str(s)) print("t = "+ str(t)) print("u = "+ str(u)) print("v = "+ str(v)) print("w = "+ str(w)) print("x = "+ str(x)) print("y = "+ str(y)) print("z = "+ str(z)) if __name__ == '__main__': main()
汚いコードで申し訳ない。結果、
a = 0 b = 42 c = 1 d = 0 e = 9 f = 9 g = 27 h = 18 i = 64 j = 3 k = 3 l = 4 m = 21 n = 0 o = 32 p = 1 q = 22 r = 30 s = 21 t = 0 u = 19 v = 21 w = 7 x = 50 y = 17 z = 43
こんな頻度で文字が現れていることがわかります。あとは少しずつ、当てはめていくだけです。(英語ができないので2時間ぐらい時間吸われました)
import string substitution = str.maketrans( \ "abcdefghijklmnopqrstuvwxyz", \ "atcddwouekcgynmvarhtflbins") #ここを変えながら試行錯誤 str1 = "bsxz xz om rxuvi. bsiri qri oqym gbsirz vxji xb, whb bsxz gyi xz oxyi. om rxuvi xz om wizb urxiye. xb xz om vxui. x ohzb oqzbir xb qz x ohzb oqzbir om vxui. fxbsghb oi, om rxuvi xz hzivizz. fxbsghb om rxuvi, x qo hzivizz. x ohzb uxri om rxuvi brhi. x ohzb zsggb zbrqxlsbir bsqy om iyiom, fsg xz brmxyl bg jxvv oi. x ohzb zsggb sxo wiugri si zsggbz oi. x fxvv. wiugri lge x zfiqr bsxz kriie: om rxuvi qye omzivu qri eiuiyeirz gu om kghybrm, fi qri bsi oqzbirz gu ghr iyiom, fi qri bsi zqpxgrz gu om vxui. zg wi xb, hybxv bsiri xz yg iyiom, whb ciqki. uvql xz q eqm fxbsghb wvgge xz vxji q eqm fxbsghb zhyzsxyi. qoiy." print(str.translate(str1, substitution))
途中詰まったら、途中まで出来上がった文章をググり、完成させました。(でもflagがわからなかったのでuvarimelonさんに解読してもらいました、感謝)
完成文はこんな感じに。
this is my rifle. there are many others like it, but this one is mine. my rifle is my best friend. it is my life. i must master it as i must master my life. without me, my rifle is useless. without my rifle, i am useless. i must fire my rifle true. i must shoot straighter than my enemy, who is trying to kill me. i must shoot him before he shoots me. i will. before god i swear this creed: my rifle and myself are defenders of my country, we are the masters of our enemy, we are the saviors of my life. so be it, until there is no enemy, but ceace. flag is a day without blood is like a day without sunshine. amen.
最後の方にflag is a day without blood is like a day without sunshine
とあり、これがフラグになります。
(joy 100) Highly professional
A big computer security company needs a highly qualified recon expert.
Think you're the one? If so you just have to find out a name of the company owner. The name is your interview pass.
Flag format: firstname_lastname, e.g. john_snow
この画像からCEOをreconしろという問題。画像を見てみると、allsafe?なんだかよくわからない。普通に検索してもわけがわからなかったので、こういう時はグーグル先生の画像検索を使いました。
出てきたページを片端から調べていくと、Mr.Robotという言葉が目立ちました。Mr.Robotを検索すると、海外ドラマみたいです。ハッカーの話みたいで、面白そう!
で、そのMr.Robotの英語版Wikipediaを見ると、CEOの名前が載っていました。
(reverse 100) Simple Check
Enter the right key.
Task.x86 Task.x86-64 Task_x86.exe
私は実行ファイルを見ると、まずはIDAで開いてみたくなるのでIDAで開きました。気になったところはこんなところ。
testでZFに0がセットされ、強制的にジャンプさせられていることがわかります。ここに処理を移してみたら…?
というわけでデバッガに突っ込んでみます。
$chmod 755 Task.x86-64 $gdb Task.x86-64 GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from Task.x86-64...(no debugging symbols found)...done. (gdb) disas main Dump of assembler code for function main: 0x00000000004007bc <+0>: push %rbp 0x00000000004007bd <+1>: mov %rsp,%rbp 0x00000000004007c0 <+4>: push %rbx 0x00000000004007c1 <+5>: sub $0x58,%rsp 0x00000000004007c5 <+9>: mov %edi,-0x54(%rbp) 0x00000000004007c8 <+12>: mov %rsi,-0x60(%rbp) 0x00000000004007cc <+16>: mov %fs:0x28,%rax 0x00000000004007d5 <+25>: mov %rax,-0x18(%rbp) 0x00000000004007d9 <+29>: xor %eax,%eax 0x00000000004007db <+31>: mov %rsp,%rax 0x00000000004007de <+34>: mov %rax,%rbx 0x00000000004007e1 <+37>: movb $0x54,-0x44(%rbp) 0x00000000004007e5 <+41>: movb $0xc8,-0x43(%rbp) 0x00000000004007e9 <+45>: movb $0x7e,-0x42(%rbp) 0x00000000004007ed <+49>: movb $0xe3,-0x41(%rbp) 0x00000000004007f1 <+53>: movb $0x64,-0x40(%rbp) 0x00000000004007f5 <+57>: movb $0xc7,-0x3f(%rbp) 0x00000000004007f9 <+61>: movb $0x16,-0x3e(%rbp) 0x00000000004007fd <+65>: movb $0x9a,-0x3d(%rbp) 0x0000000000400801 <+69>: movb $0xcd,-0x3c(%rbp) 0x0000000000400805 <+73>: movb $0x11,-0x3b(%rbp) 0x0000000000400809 <+77>: movb $0x65,-0x3a(%rbp) 0x000000000040080d <+81>: movb $0x32,-0x39(%rbp) 0x0000000000400811 <+85>: movb $0x2d,-0x38(%rbp) 0x0000000000400815 <+89>: movb $0xe3,-0x37(%rbp) 0x0000000000400819 <+93>: movb $0xd3,-0x36(%rbp) 0x000000000040081d <+97>: movb $0x43,-0x35(%rbp) 0x0000000000400821 <+101>: movb $0x92,-0x34(%rbp) 0x0000000000400825 <+105>: movb $0xa9,-0x33(%rbp) 0x0000000000400829 <+109>: movb $0x9d,-0x32(%rbp) 0x000000000040082d <+113>: movb $0xd2,-0x31(%rbp) 0x0000000000400831 <+117>: movb $0xe6,-0x30(%rbp) 0x0000000000400835 <+121>: movb $0x6d,-0x2f(%rbp) 0x0000000000400839 <+125>: movb $0x2c,-0x2e(%rbp) 0x000000000040083d <+129>: movb $0xd3,-0x2d(%rbp) 0x0000000000400841 <+133>: movb $0xb6,-0x2c(%rbp) 0x0000000000400845 <+137>: movb $0xbd,-0x2b(%rbp) 0x0000000000400849 <+141>: movb $0xfe,-0x2a(%rbp) 0x000000000040084d <+145>: movb $0x6a,-0x29(%rbp) 0x0000000000400851 <+149>: mov $0x14,%eax 0x0000000000400856 <+154>: cltq 0x0000000000400858 <+156>: sub $0x1,%rax 0x000000000040085c <+160>: mov %rax,-0x28(%rbp) 0x0000000000400860 <+164>: mov $0x14,%eax 0x0000000000400865 <+169>: cltq 0x0000000000400867 <+171>: mov %rax,%r8 0x000000000040086a <+174>: mov $0x0,%r9d 0x0000000000400870 <+180>: mov $0x14,%eax 0x0000000000400875 <+185>: cltq 0x0000000000400877 <+187>: mov %rax,%rdx 0x000000000040087a <+190>: mov $0x0,%ecx 0x000000000040087f <+195>: mov $0x14,%eax 0x0000000000400884 <+200>: cltq 0x0000000000400886 <+202>: mov $0x10,%edx 0x000000000040088b <+207>: sub $0x1,%rdx 0x000000000040088f <+211>: add %rdx,%rax 0x0000000000400892 <+214>: mov $0x10,%ecx 0x0000000000400897 <+219>: mov $0x0,%edx 0x000000000040089c <+224>: div %rcx 0x000000000040089f <+227>: imul $0x10,%rax,%rax 0x00000000004008a3 <+231>: sub %rax,%rsp 0x00000000004008a6 <+234>: mov %rsp,%rax 0x00000000004008a9 <+237>: add $0x0,%rax 0x00000000004008ad <+241>: mov %rax,-0x20(%rbp) 0x00000000004008b1 <+245>: mov $0x4009ec,%edi 0x00000000004008b6 <+250>: mov $0x0,%eax 0x00000000004008bb <+255>: callq 0x400570 <printf@plt> 0x00000000004008c0 <+260>: mov -0x20(%rbp),%rax 0x00000000004008c4 <+264>: mov %rax,%rsi 0x00000000004008c7 <+267>: mov $0x4009f2,%edi 0x00000000004008cc <+272>: mov $0x0,%eax 0x00000000004008d1 <+277>: callq 0x4005a0 <__isoc99_scanf@plt> 0x00000000004008d6 <+282>: mov -0x20(%rbp),%rax 0x00000000004008da <+286>: mov %rax,%rdi 0x00000000004008dd <+289>: callq 0x4006a6 <check_key> 0x00000000004008e2 <+294>: test %eax,%eax 0x00000000004008e4 <+296>: je 0x4008f4 <main+312> 0x00000000004008e6 <+298>: lea -0x44(%rbp),%rax 0x00000000004008ea <+302>: mov %rax,%rdi 0x00000000004008ed <+305>: callq 0x400701 <interesting_function> 0x00000000004008f2 <+310>: jmp 0x4008fe <main+322> 0x00000000004008f4 <+312>: mov $0x4009f5,%edi 0x00000000004008f9 <+317>: callq 0x400550 <puts@plt> 0x00000000004008fe <+322>: mov $0x0,%eax 0x0000000000400903 <+327>: mov %rbx,%rsp 0x0000000000400906 <+330>: mov -0x18(%rbp),%rcx 0x000000000040090a <+334>: xor %fs:0x28,%rcx 0x0000000000400913 <+343>: je 0x40091a <main+350> 0x0000000000400915 <+345>: callq 0x400560 <__stack_chk_fail@plt> 0x000000000040091a <+350>: mov -0x8(%rbp),%rbx 0x000000000040091e <+354>: leaveq 0x000000000040091f <+355>: retq End of assembler dump. (gdb)
test命令があるところは+294です。作戦としてはその次のje命令にブレークポイントをセットし、ブレークポイントまで来たら次の命令にジャンプさせる、ということを考えました。
それではやってみます。
(gdb) b *main+296 Breakpoint 1 at 0x4008e4 (gdb) r Starting program: /home/******/Task.x86-64 Key: dkjaskghasdkl Breakpoint 1, 0x00000000004008e4 in main () (gdb) jump *main+298 Continuing at 0x4008e6. flag_is_you_know_cracking!!![Inferior 1 (process 1332) exited normally] (gdb)
簡単にフラグが出ました。
(web 100) Hunger games
Oh, that monkey is really annoying, can you feed it please?
チェックボックスを使って食べ物を選択し、サルにあげるゲームみたいです。食べ物はオレンジ、リンゴ、パイナップル。あれ、バナナは?
とりあえずオレンジをあげてみると・・・
やっぱりバナナが欲しいと。この時点で解法に察しがつきました。途中でプロキシを噛ませて、オレンジを送信してみます。
POSTでdetaにorangeがセットされて送信されるようです。ここをbananaに変えてみたら…?
flag get!!
感想
初めてのオンラインCTFでした。楽しかったです。まだ易しい問題しかできないのが悔しいですが、今後もっと参加していって強くなっていきたいと思います。 けっこうwriteup書くのは大変ですね…。