Shi0shishi0

汐鹿生

picoCTF 2018 - Writeup

はじめに

picoCTF 2018に参加しました.

あまり時間取れなかった. 8000点分ぐらいは入れた気がする.

ReversingだけでもWriteupを書いておこうというお気持ち.

解法

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全完したかったが数問残ってしまった. そのうちやる.