picoCTF 2018 - Writeup
- はじめに
- 解法
- Reversing Warmup 1 - Points: 50 - (Solves: 6228)
- Reversing Warmup 2 - Points: 50 - (Solves: 7489)
- assembly-0 - Points: 150 - (Solves: 1748)
- be-quick-or-be-dead-1 - Points: 200 - (Solves: 1057)
- quackme - Points: 200 - (Solves: 557)
- assembly-2 - Points: 250 - (Solves: 841)
- be-quick-or-be-dead-2 - Points: 275 - (Solves: 401)
- quackme up - Points: 350 - (Solves: 371)
- Radix's Terminal - Points: 400 - (Solves: 625)
- assembly-3 - Points: 400 - (Solves: 432)
- keygen-me-1 - Points: 400 - (Solves: 337)
- assembly-4 - Points: 550 - (Solves: 291)
- おわりに
はじめに
picoCTF 2018に参加しました。8000点分ぐらいは入れた気がする。
解法
Reversing Warmup 1 - Points: 50 - (Solves: 6228)
与えられたELFファイルにFLAGがハードコードされている
FLAG : picoCTF{welc0m3_t0_r3VeRs1nG}
Reversing Warmup 2 - Points: 50 - (Solves: 7489)
問題文にある文字列"dGg0dF93NHNfczFtcEwz"をBase64デコードする
FLAG : picoCTF{th4t_w4s_s1mpL3}
assembly-0 - Points: 150 - (Solves: 1748)
.intel_syntax noprefix .bits 32 .global asm0 asm0: push ebp mov ebp,esp mov eax,DWORD PTR [ebp+0x8] mov ebx,DWORD PTR [ebp+0xc] mov eax,ebx mov esp,ebp pop ebp ret
上のアセンブリについて, asm0(0xc9,0xb0) の時の戻り値を答える
2つの引数がasm0に渡されて, DWORD PTR [ebp+0x8] = 0xc9, DWORD PTR [ebp+0xc] = 0xb0 となる
上記の2値はmov命令でコピーされて, eax = 0xc9, ebx = 0xb0 となる
ebxの値がeaxに上書きされる
eaxはそのまま変更されずにreturnするので, 戻り値は0xb0
FLAG : 0xb0
be-quick-or-be-dead-1 - Points: 200 - (Solves: 1057)
ELFファイル(64bit)が与えられる
普通に実行すると"You need a faster machine. Bye bye."と表示されて終了する
hamasho30@hamasho30-virtual-machine:~$ file be-quick-or-be-dead-1 be-quick-or-be-dead-1: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=320c38e014db3ec8882eda82d062ebe7a28943d7, not stripped hamasho30@hamasho30-virtual-machine:~$ ./be-quick-or-be-dead-1 Be Quick Or Be Dead 1 ===================== Calculating key... You need a faster machine. Bye bye.
計算処理を行なっている関数等にBreakPointを設定して動かす(Alermは無視)
gdb-peda$ Calculating key... Program received signal SIGALRM, Alarm clock. Done calculating key gdb-peda$ Printing flag: picoCTF{why_bother_doing_unnecessary_computation_fedbb737}
FLAG : picoCTF{why_bother_doing_unnecessary_computation_fedbb737}
quackme - Points: 200 - (Solves: 557)
ELFファイル(32bit)が与えられる
実行すると標準入力からの入力を受け付ける
hamasho30@hamasho30-virtual-machine:~$ file ./main ./main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=09dbd61b7f2aa72b7c04e2ab78a4cc9c437c4ac9, not stripped hamasho30@hamasho30-virtual-machine:~$ ./main You have now entered the Duck Web, and you're in for a honkin' good time. Can you figure out my trick? AAAAA That's all folks.
IDAで開いて処理を確認すると, read_input()で取得した値とsekrutBufferの値をXORした結果が"You have now entered the Duck Web, and you're in for a honk"と一致するかチェックしている
手元でXORしてみるとFLAGが得られる
FLAG : picoCTF{qu4ckm3_7ed36e4b}
assembly-2 - Points: 250 - (Solves: 841)
ループ処理を抜けた時のeaxの値を求められればOK
そのために, 0x0e + 0x41 * i が0x9886以上になる時のiを求め, その値に0x21を加算する
.intel_syntax noprefix .bits 32 .global asm2 asm2: push ebp mov ebp,esp sub esp,0x10 mov eax,DWORD PTR [ebp+0xc] # 0x21 mov DWORD PTR [ebp-0x4],eax # ebp-0x4 = 0x21 mov eax,DWORD PTR [ebp+0x8] # 0x0e mov DWORD PTR [ebp-0x8],eax # ebp-0x8 = 0x0e jmp part_b part_a: add DWORD PTR [ebp-0x4],0x1 add DWORD PTR [ebp+0x8],0x41 part_b: cmp DWORD PTR [ebp+0x8],0x9886 jle part_a mov eax,DWORD PTR [ebp-0x4] mov esp,ebp pop ebp ret
FLAG : 0x27a
be-quick-or-be-dead-2 - Points: 275 - (Solves: 401)
時間内に解けなかった
このELFファイルはFLAGの生成に使うフィボナッチ数を再帰処理で求めているので計算に凄く時間がかかっている
計算処理を手元で行なって必要なフィボナッチ数を用意して, デバッガでレジスタの値を書き換えるとかで良いかと思ったが, 上手く行かなかったので諦めた
quackme up - Points: 350 - (Solves: 371)
ELFファイルが与えられる
実行すると入力を受け付けるので色々試したところ, 入力された文字を1文字ずつ暗号化しているように見える
同じ文字は入力位置や全体の入力文字数にかかわらず, 同じ文字に暗号化されていると思われる
変換テーブルが作れれば良さそう?(記号も使えそうなのでそれも考慮する)
hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: A Here's your ciphertext: 02 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks. hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: AAA Here's your ciphertext: 02 02 02 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks. hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: B Here's your ciphertext: 32 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks. hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: BBB Here's your ciphertext: 32 32 32 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks. hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: AB Here's your ciphertext: 02 32 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks. hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: -^\@[;:]./\, Here's your ciphertext: C4 F3 D3 12 A3 A5 B5 C3 F4 E4 D3 D4 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks.
どういうロジックで暗号化を行っているか確認しようと思ったが, その前に暗号化された入力と一緒に出力されている値が気になった
Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1
試しに"picoCTF{"と入力してみると"Here's your ciphertext: 11 80 20 E0 22 53 72 A1" となり, "Now quack it! : " の先頭と一致した
hamasho30@hamasho30-virtual-machine:~$ ./quackmeup We're moving along swimmingly. Is this one too fowl for you? Enter text to encrypt: picoCTF{ Here's your ciphertext: 11 80 20 E0 22 53 72 A1 Now quack it! : 11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 That's all folks.
暗号化のロジックは読まずとも, 変換テーブルを作ってあげると解けそうなのでやってみた
FLAG : picoCTF{qu4ckm3_8c02c0af}
やっていることは ROL4 -> XOR 0x16 -> ROR8 だと思う
Radix's Terminal - Points: 400 - (Solves: 625)
与えられたELFファイルにハードコードされた文字列"cGljb0NURntiQXNFXzY0X2VOQ29EaU5nX2lTX0VBc1lfMTk1MTA2ODN9"をBase64デコードする
FLAG : picoCTF{bAsE_64_eNCoDiNg_iS_EAsY_19510683}
assembly-3 - Points: 400 - (Solves: 432)
問題文より, asm3(0xb3fb1998,0xfe1a474d,0xd5373fd4)の時の値を求める
.intel_syntax noprefix .bits 32 .global asm3 asm3: push ebp mov ebp,esp mov eax,0x62 xor al,al mov ah,BYTE PTR [ebp+0xa] sal ax,0x10 sub al,BYTE PTR [ebp+0xd] add ah,BYTE PTR [ebp+0xe] xor ax,WORD PTR [ebp+0x10] mov esp, ebp pop ebp ret
3つの引数がスタックに積まれている状態をこんな感じと考える
0x08 0x09 0x0a 0x0b 98 19 [fb] b3 0x0c 0x0d 0x0e 0x0f 4d [47] [1a] fe 0x10 0x11 0x12 0x13 [d4 3f] 37 d5
リトルエンディアンであることと, 最後のXORだけ取得している値のサイズがWORDであることに注意する
asm3: push ebp mov ebp,esp mov eax,0x62 # 0x00000062 xor al,al # 0x00000000 mov ah,BYTE PTR [ebp+0xa] # <- 0xfb sal ax,0x10 sub al,BYTE PTR [ebp+0xd] # <- 0x47 add ah,BYTE PTR [ebp+0xe] # <- 0x1a xor ax,WORD PTR [ebp+0x10] # <- 0x3fd4 mov esp, ebp pop ebp ret
FLAG : 0x256d
keygen-me-1 - Points: 400 - (Solves: 337)
16桁のプロダクトキーを求められる
最終的に, 1~15桁目までの文字列を処理した結果と16文字目を処理した結果を比較している
15桁目までを固定して, 16桁目を調整すればActivateできる値を求められる(Activateすることができる値は色々あると思う)
XXXXXXXX@pico-2018-shell-1:~$ cd /problems/keygen-me-1_3_a2370158b7b72b3863212502340f2c32 XXXXXXXX@pico-2018-shell-1:/problems/keygen-me-1_3_a2370158b7b72b3863212502340f2c32$ ll total 68 drwxr-xr-x 2 root root 4096 Sep 28 07:48 ./ drwxr-x--x 576 root root 53248 Sep 30 03:45 ../ -rwxr-sr-x 1 hacksports keygen-me-1_3 7836 Sep 28 07:48 activate* -r--r----- 1 hacksports keygen-me-1_3 41 Sep 28 07:48 flag.txt XXXXXXXX@pico-2018-shell-1:/problems/keygen-me-1_3_a2370158b7b72b3863212502340f2c32$ ./activate 111111111111111O Product Activated Successfully: picoCTF{k3yg3n5_4r3_s0_s1mp13_749501403} XXXXXXXX@pico-2018-shell-1:/problems/keygen-me-1_3_a2370158b7b72b3863212502340f2c32$
FLAG : picoCTF{k3yg3n5_4r3_s0_s1mp13_749501403}
assembly-4 - Points: 550 - (Solves: 291)
nasmファイルが渡される
ソースコードを見ると凄く長いコードであることが分かる(問題文にも WARNING: It is VERY long... とある)
ヒントに"Hmm.. There must be an easier way than reversing the whole thing right?"とあり, これまでの違うやり方を勧めている感じがする(なので, 動的に解析したい)
hamasho30@hamasho30-virtual-machine:~$ nasm -g -f elf32 -o a.out comp.nasm hamasho30@hamasho30-virtual-machine:~$ gcc -o comp a.out hamasho30@hamasho30-virtual-machine:~$ file comp comp: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=eb84afb9d9ad0ce20eabfbeaac3848f1e0cd0c0c, not stripped hamasho30@hamasho30-virtual-machine:~$ ./comp picoCTF{1_h0p3_y0u_c0mP1l3d_tH15_24186504403hamasho30@hamasho30-virtual-machine:~$
生成した実行ファイルを動かすと picoCTF{1_h0p3_y0u_c0mP1l3d_tH15_24186504403 と出力されたが, 末尾が"}"じゃないので壊れてそう
picoCTF{1_h0p3_y0u_c0mP1l3d_tH15_24186504403} だと通らないので picoCTF{1_h0p3_y0u_c0mP1l3d_tH15_2418650440} にしたら通った
FLAG : picoCTF{1_h0p3_y0u_c0mP1l3d_tH15_2418650440}
おわりに
Reversing全完したかったが数問残ってしまった。そのうちやります。