ShinobiMind

basketball player and hacker will keep be childish.

CSAW CTF Reversing 100

Challenge

tablEZ
Bobby was talking about tables a bunch, so I made some table stuff. I think this is what he was talking about...

Solution

Given file is 64-bit ELF file. It seems crack me style binary.

$ file tablez  
tablez: 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]=72adea86090fb7deeb319e95681fd2c669dcc503, not stripped    
$ ./tablez  
Please enter the flag:  
aaaaaaaaaaaaaaaaaaa  
WRONG  
$ltrace ./tablez  
puts("Please enter the flag:"Please enter the flag:
)                                = 23  
fgets(aaaaaaaaaaaaaaa  
"aaaaaaaaaaaaaaa\n", 128, 0x7f41cc9528c0)               = 0x7ffed0b824e0  
strlen("aaaaaaaaaaaaaaa\n")                                   = 16  
strlen("aaaaaaaaaaaaaaa")                                     = 15  
puts("WRONG"WRONG  
)                                                 = 6  
+++ exited (status 1) +++

Disassembling with hopper, we can see the main function has 3 important steps.

  1. convert 8 bit data according to trans_tbl.
  2. compare input data length and 0x25
  3. compare converted data and fixed strings

[f:id:grapeBiscuit:20170929085901j:plain]

we should know trans_tbl and fixed strings.

gdb-peda$ x/512b 0x555555755280
0x555555755280 <trans_tbl>: 0x01    0xbb    0x02    0x9b    0x03    0xc4    0x04    0x6c
0x555555755288 <trans_tbl+8>:   0x05    0x4a    0x06    0x2e    0x07    0x22    0x08    0x45
0x555555755290 <trans_tbl+16>:  0x09    0x33    0x0a    0xb8    0x0b    0xd5    0x0c    0x06
0x555555755298 <trans_tbl+24>:  0x0d    0x0a    0x0e    0xbc    0x0f    0xfa    0x10    0x79
0x5555557552a0 <trans_tbl+32>:  0x11    0x24    0x12    0xe1    0x13    0xb2    0x14    0xbf
0x5555557552a8 <trans_tbl+40>:  0x15    0x2c    0x16    0xad    0x17    0x86    0x18    0x60

gdb-peda$ x/38b $rbp-0xc0
0x7fffffffe080: 0x27    0xb3    0x73    0x9d    0xf5    0x11    0xe7    0xb1
0x7fffffffe088: 0xb3    0xbe    0x99    0xb3    0xf9    0xf9    0xf4    0x30
0x7fffffffe090: 0x1b    0x71    0x99    0x73    0x23    0x65    0x99    0xb1
0x7fffffffe098: 0x65    0x11    0x11    0xbe    0x23    0x99    0x27    0xf9
0x7fffffffe0a0: 0x23    0x99    0x05    0x65    0xce    0x00

Work

So, we'll find strings mach 3 conditions above. I wrote script.

#! /usr/bin/env/python

flag = ""

magicWord = [0x27,0xb3,0x73,0x9d,0xf5,0x11,0xe7,0xb1,
0xb3,0xbe,0x99,0xb3,0xf9,0xf9,0xf4,0x30,
0x1b,0x71,0x99,0x73,0x23,0x65,0x99,0xb1,
0x65,0x11,0x11,0xbe,0x23,0x99,0x27,0xf9,
0x23,0x99,0x05,0x65,0xce]

trans_tbl = [0x01,0xbb,0x02,0x9b,0x03,0xc4,0x04,0x6c,
0x05,0x4a,0x06,0x2e,0x07,0x22,0x08,0x45,
0x09,0x33,0x0a,0xb8,0x0b,0xd5,0x0c,0x06,
0x0d,0x0a,0x0e,0xbc,0x0f,0xfa,0x10,0x79,
0x11,0x24,0x12,0xe1,0x13,0xb2,0x14,0xbf,
0x15,0x2c,0x16,0xad,0x17,0x86,0x18,0x60,
0x19,0xa4,0x1a,0xb6,0x1b,0xd8,0x1c,0x59,
0x1d,0x87,0x1e,0x41,0x1f,0x94,0x20,0x77,
0x21,0xf0,0x22,0x4f,0x23,0xcb,0x24,0x61,
0x25,0x25,0x26,0xc0,0x27,0x97,0x28,0x2a,
0x29,0x5c,0x2a,0x08,0x2b,0xc9,0x2c,0x9f,
0x2d,0x43,0x2e,0x4e,0x2f,0xcf,0x30,0xf9,
0x31,0x3e,0x32,0x6f,0x33,0x65,0x34,0xe7,
0x35,0xc5,0x36,0x39,0x37,0xb7,0x38,0xef,
0x39,0xd0,0x3a,0xc8,0x3b,0x2f,0x3c,0xaa,
0x3d,0xc7,0x3e,0x47,0x3f,0x3c,0x40,0x81,
0x41,0x32,0x42,0x49,0x43,0xd3,0x44,0xa6,
0x45,0x96,0x46,0x2b,0x47,0x58,0x48,0x40,
0x49,0xf1,0x4a,0x9c,0x4b,0xee,0x4c,0x1a,
0x4d,0x5b,0x4e,0xc6,0x4f,0xd6,0x50,0x80,
0x51,0x2d,0x52,0x6d,0x53,0x9a,0x54,0x3d,
0x55,0xa7,0x56,0x93,0x57,0x84,0x58,0xe0,
0x59,0x12,0x5a,0x3b,0x5b,0xb9,0x5c,0x09,
0x5d,0x69,0x5e,0xba,0x5f,0x99,0x60,0x48,
0x61,0x73,0x62,0xb1,0x63,0x7c,0x64,0x82,
0x65,0xbe,0x66,0x27,0x67,0x9d,0x68,0xfb,
0x69,0x67,0x6a,0x7e,0x6b,0xf4,0x6c,0xb3,
0x6d,0x05,0x6e,0xc2,0x6f,0x5f,0x70,0x1b,
0x71,0x54,0x72,0x23,0x73,0x71,0x74,0x11,
0x75,0x30,0x76,0xd2,0x77,0xa5,0x78,0x68,
0x79,0x9e,0x7a,0x3f,0x7b,0xf5,0x7c,0x7a,
0x7d,0xce,0x7e,0x0b,0x7f,0x0c,0x80,0x85,
0x81,0xde,0x82,0x63,0x83,0x5e,0x84,0x8e,
0x85,0xbd,0x86,0xfe,0x87,0x6a,0x88,0xda,
0x89,0x26,0x8a,0x88,0x8b,0xe8,0x8c,0xac,
0x8d,0x03,0x8e,0x62,0x8f,0xa8,0x90,0xf6,
0x91,0xf7,0x92,0x75,0x93,0x6b,0x94,0xc3,
0x95,0x46,0x96,0x51,0x97,0xe6,0x98,0x8f,
0x99,0x28,0x9a,0x76,0x9b,0x5a,0x9c,0x91,
0x9d,0xec,0x9e,0x1f,0x9f,0x44,0xa0,0x52,
0xa1,0x01,0xa2,0xfc,0xa3,0x8b,0xa4,0x3a,
0xa5,0xa1,0xa6,0xa3,0xa7,0x16,0xa8,0x10,
0xa9,0x14,0xaa,0x50,0xab,0xca,0xac,0x95,
0xad,0x92,0xae,0x4b,0xaf,0x35,0xb0,0x0e,
0xb1,0xb5,0xb2,0x20,0xb3,0x1d,0xb4,0x5d,
0xb5,0xc1,0xb6,0xe2,0xb7,0x6e,0xb8,0x0f,
0xb9,0xed,0xba,0x90,0xbb,0xd4,0xbc,0xd9,
0xbd,0x42,0xbe,0xdd,0xbf,0x98,0xc0,0x57,
0xc1,0x37,0xc2,0x19,0xc3,0x78,0xc4,0x56,
0xc5,0xaf,0xc6,0x74,0xc7,0xd1,0xc8,0x04,
0xc9,0x29,0xca,0x55,0xcb,0xe5,0xcc,0x4c,
0xcd,0xa0,0xce,0xf2,0xcf,0x89,0xd0,0xdb,
0xd1,0xe4,0xd2,0x38,0xd3,0x83,0xd4,0xea,
0xd5,0x17,0xd6,0x07,0xd7,0xdc,0xd8,0x8c,
0xd9,0x8a,0xda,0xb4,0xdb,0x7b,0xdc,0xe9,
0xdd,0xff,0xde,0xeb,0xdf,0x15,0xe0,0x0d,
0xe1,0x02,0xe2,0xa2,0xe3,0xf3,0xe4,0x34,
0xe5,0xcc,0xe6,0x18,0xe7,0xf8,0xe8,0x13,
0xe9,0x8d,0xea,0x7f,0xeb,0xae,0xec,0x21,
0xed,0xe3,0xee,0xcd,0xef,0x4d,0xf0,0x70,
0xf1,0x53,0xf2,0xfd,0xf3,0xab,0xf4,0x72,
0xf5,0x64,0xf6,0x1c,0xf7,0x66,0xf8,0xa9,
0xf9,0xb0,0xfa,0x1e,0xfb,0xd7,0xfc,0xdf,
0xfd,0x36,0xfe,0x7d,0xff,0x31]

for j in range(len(magicWord)):
    for i in range(0xff):
        if trans_tbl[ i+ i +1] == magicWord[j]:
            flag += chr(trans_tbl[i+i])
            break
print flag

Sweets

$ python solve.py 
flag{t4ble_l00kups_ar3_b3tter_f0r_m3}

CSAW CTF Forensics 150

Challenge

Missed Registration
It's registration day! These forms just seem longer and longer... pcap file is here

Solutions

Almost of all packets are HTTP POST packets. They looks like sending data normally, but some packet include x parameter. Their Contents-length on HTTP header and real data length are different. It is suspicious.
Then, I pick up all x parameter data. Then we can find that the head of data is "0x42 0x4d". The magic number "0x42 0x4d" means that this file is BMP file.
So, we'll write solving script.

#!/usr/bin/env python

from scapy.all import *
import binascii

packets = rdpcap('cap.pcap')
f = open('flag.bin','wb')

for packet in packets:
    params = ""
    if Raw in packet:
        params = packet[Raw].load
        if params.find("&x=") > 0:
            xLocation = params.rfind("&x=")
            word = params[xLocation+3:]
            f.write(binascii.unhexlify(word))
f.close()

sweets

FLAG{3Am_LaunDR3Y_FLaG_L34kz!}

ASIS CTF Final 2017 Reversing ABC

今回は問題を解くことができませんでした。備忘録として残します。

Challenge

Description: Start Reverse

Solution

64bitのELFファイルが与えられます。ひとまず実行してみます。

$ ./abc 
give me flag... :D
$ ./abc 12345
Sorry, try harder :(

引数に期待される文字列を入力する問題のようです。

$ ltrace ./abc 12345
...
...
...
strcmp("fb644351560d8296fe6da332236b1f8d"...,"69fc8b9b1cdfe47e6b51a6804fc1dbdd"...) = 48  
puts("Sorry, try harder :("Sorry, try harder :(    )   = 21  

入力した文字列に対して、なんらかの文字列変換を行った後、固定値"69fc8b9b1cdfe47e6b51a6804fc1dbdd"と文字列比較をしています。入力文字列が9文字の場合と、10文字の場合で比較する文字列が変わらないことから、入力文字列は9文字かもしれません。

デコンパイルをしてみます。0x400876の引数入力チェック後の0x4008baの関数が怪しそうです。mallocで3回に分けてメモリ領域を確保しており、それぞれを、0x4024dfの関数に食わせてます。var_168に4byte、var_158に4byte、var_160に4byte入れておりますが、var_158は4byte目から6byteなので、入力値は12文字であることが分かります。
何故、(var_190 + 0x8)が入力引数の先頭アドレスなのか分かりません…分かる方は教えて頂けると幸いです。

おそらく、0x4024dfが何らかの文字列変換をさせる関数なんじゃないかと思います。中に入っていくと、かなり複雑なことをしていそうです。。。0x400cc6を見るといくつかの固定文字列(例 0x5a827999)とAND演算をしていました。0x5a827999をググってみると、SHA-1の記事が多数引っ掛かります。0x4024dfはSHA-1ハッシュ関数だと推定します。(推定ばっかりだなぁ org…)

0x4008baの最後のif文を見ると、次の条件でflagを手に入れる事が出来ることが分かります。
- 入力引数3-8文字のSHA-1ハッシュ値が"69fc8b9b1cdfe47e6b51a6804fc1dbdd" - 入力引数1-4文字が入力引数9-12文字未満であること。 - 入力引数1-4文字のハッシュ値の先頭4文字が、自身と同じであること。 - 入力引数9-12文字のハッシュ値の先頭4文字が、自身と同じであること。

1-4文字と入力引数9-12を求めるスクリプトを書きました。無駄のあるスクリプトですが、数分で2パターンが見つかりました。

#!/usr/bin/env python

import random
import hashlib

while True:
    arg = ''
    for num in range(4):
        arg += random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')

    hash = hashlib.sha1(arg).hexdigest()

    if hash[:4] == arg:
        print "arg is " + arg
        print "sha1 hash is " + hash
        break

#arg is 57d9
#arg is b53a

入力引数は57d9****b53aであることが分かりました。


ここまでは、CTF開催時間で出来ました。


残りの4byteを調べます。 hashcatを使うと早いようです。不明文字は4文字ですが、推定のところが間違っているかもしれないですし、6文字で調べてみます。

hashcat64 -m 100 -a 3 69fc8b9b1cdfe47e6b51a6804fc1dbddba1ea1d9 ?a?a?a?a?a?a  

結果まで9時間かかりました。

69fc8b9b1cdfe47e6b51a6804fc1dbddba1ea1d9:$HEX[393a2d2a2962]

asciiコード表と照らし合わせると、6文字は"9:-)b"であることが分かります。
つまり、入力引数は"57d9:-
)b53a"です。

Sweets

“57d9:-*)b53a"を入力引数にして実行させてみます。

$ ./abc 57d9:-*)b53a  
bash: syntax error near unexpected token `)'
$ ./abc 57d9:-*\)b53a
gj, you got the flag: ASIS{477408a4d4ad68aa7abdfd2be0e4717154497c42}

flagを入手できました。

brush

表面をなめただけの気がします。アセンブラともっと仲良くなりたいorg

HackIT CTF 2017 Forensic 100

Challenge

This file was captured from one of the computers at the Internet cafe. We think that the hacker was using this computer at that time. Try to get his secret documents. ( flag format is flag{…} )

Solution

あたえられるのはpcapファイルです。中を開くとUSBのパケットが並びます。interrupt転送やらハブのディスクリプタが流れた後、怪しげなディスクリプタが流れていました。アップルのキーボードに関するパケットのようです。 f:id:grapeBiscuit:20170829114902j:plain

その後のパケットもinterrupt転送で8byteのパケットを転送しているので、これはUSB keyboardのパケットだと推定。これを読み解けばflagを取れそうです。
keyboardのデータに関しては、usb.orgがこちらで資料を公開しています。53ページからがキーボードのレイアウトで、これをもとに8byteのデータをを文字に変換するスクリプトを書きます。
f:id:grapeBiscuit:20170906095110j:plain
7月に発売されたセキュリティコンテストのためのCTF問題集にとても参考となるスクリプトが紹介されていたので、それをベースに書きました。

セキュリティコンテストのためのCTF問題集

セキュリティコンテストのためのCTF問題集

#! /usr/bin/env python
#! -*- cording: utf-8 -*-

from scapy.all import *

keymap = {  0x04: ('a','A'), 0x05: ('b','B'),0x06: ('c','C'),
            0x07: ('d','D'), 0x08: ('e','E'),0x09: ('f','F'),
            0x0a: ('g','G'), 0x0b: ('h','H'),0x0c: ('i','I'),
            0x0d: ('j','J'), 0x0e: ('k','K'),0x0f: ('l','L'),
            0x10: ('m','M'), 0x11: ('n','N'),0x12: ('o','O'),
            0x13: ('p','P'), 0x14: ('q','Q'),0x15: ('r','R'),
            0x16: ('s','S'), 0x17: ('t','T'),0x18: ('u','U'),
            0x19: ('v','V'), 0x1a: ('w','W'),0x1b: ('x','X'),
            0x1c: ('y','Y'), 0x1d: ('z','Z'),0x1e: ('1','!'),
            0x1f: ('2','@'), 0x20: ('3','#'),0x21: ('4','$'),
            0x22: ('5','%'), 0x23: ('6','^'),0x24: ('7','&'),
            0x25: ('8','*'), 0x26: ('9','('),0x27: ('0',')'),
            0x28: (' [Enter] ',' [Enter] '), 0x29: ('\x1b','\x1b'),
            0x2a: (' [del] ',' [del] '), 0x2b: ('\x09','\x09'),
            0x2c: ('\x20','\x20'), 0x2d: ('-','_'),
            0x2e: ('=','+'), 0x2f: ('[','{'),0x30: (']','}'),
            0x31: ('\\','|'), 0x33: (';',':'),0x34: ('\'','\"'),
            0x35: ('`','~'), 0x36: (',','<'),0x37: ('.','>'),
            0x38: ('/','?'),
            0x51:(' [downArrow] ',' [downArrow] '), 0x52: (' [upArrow] ',' [upArrow] '),0x32: ('\\','|')
            }

def read_usbdata_from_pcap():
    pcap = rdpcap("task.pcap")
    usb_data = []
    for pkt in pcap:
        buf = pkt['Raw'].load
        if buf[22] == '\x01':
            if len(buf[27:]) == 8:
                usb_data.append(buf[27:])
    return usb_data


def analyze_usb_data(usb_data):
    flag = ""
    for d in usb_data:
        if d[2] == '\x00' or not('\00' in d[3:8]):
            #No Event
            continue
        if d[0] == '\x02' or d[0] == '\x20':
            #press shift
            #binary -> int
            c = keymap[ord(d[2])][1]
            flag += c
        else:
            #binary -> int
            c = keymap[ord(d[2])][0]
            flag += c
    print flag

def main():
    data = read_usbdata_from_pcap()
    analyze_usb_data(data)

if __name__ == '__main__':
    main()

すると、次のキーが押されていた事がわかります。


w [Enter] k [Enter] f [Enter] b [Enter] 3' [upArrow] [ [upArrow] l [upArrow] # [upArrow] {w$ [downArrow] >b [downArrow] ag [downArrow] [e [downArrow] ci.[ [upArrow] [f [upArrow] {k [upArrow] n$ [upArrow] ju} [downArrow] : [downArrow] 3 [downArrow] u [downArrow] %= [upArrow] | [upArrow] y [upArrow] 6 [upArrow] ,‘ [downArrow] p [downArrow] b [downArrow] 7 [downArrow] %& [upArrow] d [upArrow] 0 [upArrow] j [upArrow] pt [downArrow] i [downArrow] a [downArrow] [ [downArrow] k( [upArrow] = [upArrow] r [upArrow] m [upArrow] ]= [downArrow] 0 [downArrow] d [downArrow] > [downArrow] lc [upArrow] * [upArrow] _ [upArrow] { [upArrow] j% [downArrow] u [downArrow] s [downArrow] ( [downArrow] *2 [upArrow] 0 [upArrow] n [upArrow] ’ [upArrow] ;9 [downArrow] h [downArrow] 4 [downArrow] ] [downArrow] y4 [upArrow] ‘ [upArrow] k [upArrow] ; [upArrow] +p [downArrow] f [downArrow] e [downArrow] $ [downArrow] !} [upArrow] 1 [upArrow] _ [upArrow] k [upArrow] s& [downArrow] s [downArrow] 2 [downArrow] c [downArrow] %q [upArrow] $ [upArrow] . [upArrow] ! [upArrow] #, [downArrow] s [downArrow] 0 [downArrow] c [downArrow] z3 [upArrow] e [upArrow] } [upArrow] - [upArrow] i


これをひとつづつテキストエディタ上で入力します。
特殊文字"[“や”{“を自動保管してくれる機能に注意しましょう。notepad.exeが一番いいかもしれません。
するとflagが出現します。


w{w$ju},’pt]=j%;9+ps&#,i
k#>bn$:6pijm0u{h’;fks!s-
flag{k3yb0ard_sn4ke_2.0}
b[[e[fu|7d[=>((0]’$1c$ce
3’ci.[%=%&k(lc
2y4!}%qz3


sweets

flag{k3yb0ard_sn4ke_2.0}
USBのプロトコルをかじっていれば解ける問題でした。セキュリティコンテストのためのCTF問題集がとても参考になりました。ビギナーは必携です。

grub rescueと表示されるdual bootパソコンを復旧させる方法

環境

  • Let’s note LX5
  • windows10 x64
  • Debian8 x64

原因

Windows Updateにより新しいパーティションが追加される。

手順

  1. grub rescueが表示されて困る。
    PCを起動すると、いつもはGRUBが表示されるところが下記のように表示されます。

      grub rescue>
    
  2. 状態確認 lsコマンドでパーティションがどのような状態になっているか確認。

      grub rescue> ls
      (hd0) (hd1) (hd1,gpt8) (hd1,gpt7) (hd1,gpt6) (hd1,gpt5) (hd1,gpt4) (hd1,gpt3) (hd1,gpt2) (hd1,gpt1)
    
  3. Linuxの入っているパーティションを探す。 (hd1,gpt6)にLinuxファイルシステムがあることが分かります。

      grub rescue> ls (hd1,gpt7)
      (hd1,gpt7): Filesystem is unknown
    
      grub rescue> ls (hd1,gpt6)
      (hd1,gpt6): Filesystem is ext2
    
  4. 本当にLinuxファイルシステムか確認 grub rescue> ls (hd1,gpt6)/boot/grub/

  5. GRUBのノーマルモジュールをロードし、GRUBメニューを表示させる。

     grub rescue> set prefix=(hd1,gpt6)/boot/grub
     grub rescue> root=(hd1,gpt6)
     grub rescue> insmod normal
     grub rescue> normal
    

    するといつものGRUBの画面が表示されるのでDebianで立ち上げます。

  6. GRUBの修正 ターミナルを開き、下記コマンドを叩きます。

      sudo grub-install /dev/sda/
    

以上で終了です。再起動するといつものGRUBの画面が表示されます。
こちらを参考にさせてもらいました、ありがとうございます。

SECCON CTF 2016 Binary 100

Challenge

Anti-Debugging
Reverse it.
bin (SHA1: 690c72681b1cd2bb9fe01efe0bfb71b44f7838d3)
may some AV will alert,but no problem.

私の環境ではAVに引っかからなかったです。気を利かせてくれたのか、役立たずなのか、、、

Solution

与えられたのは32bitのPEファイルです。まずは、実行してみます。
パスワードなんて知らないですけど、パスワードを入手しなくてはならないようです。

\> .\bin  
Input password >abcde  
password is wrong.

IDA demoを使います。
“Input password >"をprintfした後、strcmpをしているところがあるので、ここら辺が怪しいなぁと思い、ここにbreakpointを指定して実行します。ここのstrcmpではEAXとECXの値を比べているので、それぞれのアドレスの先を見ます。passwordには先ほどと同じ"abcde"を渡しました。
f:id:grapeBiscuit:20170708132837p:plain

EAXとECXの値は次の通りです。
f:id:grapeBiscuit:20170708133020p:plain

それぞれのstackには次のように値が入っていました。
f:id:grapeBiscuit:20170708133256p:plain

ECXのアドレス(0019FED8)には、"0x61 0x62, 0x63, 0x64, 0x65"が並んでおり、これは先ほどpasswordとして渡した “abcde"をasciiコードにしたものです。EAXのアドレス(0019FEC4)には、"0x49, 0x29, …, 0x6E,0x2E"が並んでおり、同様にasciiコード表と見比べると"I have a pen."がpasswordだと分かリます。
passwordで"I have a pen."と入力し、再度プログラムを実行します。IsDebbugerPresent関数を使って弾かれてしまいます。
f:id:grapeBiscuit:20170708172553p:plain

その先のコードを見ると、その他wiresharkvmwareでも弾かれるようです。諸々のプロセスを見た後、怪しい部分を見つけたのでここまでジャンプします。ジャンプしたい先で、(右クリック) -> (Set IP), (Jump to IP)でジャンプできました。
f:id:grapeBiscuit:20170708172852p:plain

ジャンプ後、そのまま実行すると、ポップアップでflagが出てきます。

Answer

SECCON{check_Ascii85}

Sweets

  • 今回はジャンプしても目的は達成されたのだが、ジャンプして飛ばした部分に重要な処理があった場合は、どうなるのだろうか。
  • Anti debugに関してまだリバースエンジニアリングバイブルで勉強中なので、早く読み進めなくては。

Trend Micro CTF 2017 Reversing 100 writeup

Challenge

問題文をメモし忘れてしまいました、、、
暗号化と圧縮したファイルを解凍するとpocketという名前のzipファイルが現れます。binwalkでジャカジャカ展開していきます。

# binwalk pocket  
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             Zip archive data, at least v2.0 to extract, compressed size: 39281, uncompressed size: 39271, name: biscuit  
39371         0x99CB          End of Zip archive

すると、biscuit1とbiscuit2というファイルが展開されます。

# binwalk biscuit1  
 DECIMAL       HEXADECIMAL     DESCRIPTION
 --------------------------------------------------------------------------------
 0             0x0             Microsoft executable, portable (PE)

# binwalk biscuit2 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             Zip archive data, encrypted at least v2.0 to extract, compressed size: 69, uncompressed size: 64, name: biscuit4
107           0x6B            Zip archive data, encrypted at least v2.0 to extract, compressed size: 12778, uncompressed size: 30935, name: biscuit5
12923         0x327B          Zip archive data, encrypted at least v2.0 to extract, compressed size: 13747, uncompressed size: 14378, name: biscuit3
26870         0x68F6          End of Zip archive

biscuit2は暗号化されたzipファイルのようです。その暗号鍵がbiscuit1から得られるのでしょう。biscuit1は32bitのPEファイルなので、まずwindowsから起動してみます。

.\biscuit1.exe  
Please find sweets name starting from m for biscuit2.

はい、予想通り暗号鍵があると教えてくれました。mから始まるスイーツの名前だそうです。PEviewで見ると、"GetCommandLineA"が見つかり、何かコマンドライン引数を引っ張ってるのかなぁと予想しながら(最近、リバースエンジニアリングバイブルで勉強したので)デバッガーに食わせます。 ollydbgを使って処理を追っていくと、"macaron"という文字列が見当たります。これが暗号鍵でした。
biscuit2を解凍すると、buscuit3, buscuit4, buscuit5が展開されます。 biscuit4はテキストファイルで次のように書かれています。

# cat biscuit4 
Please create flag.

hint:

Flag = TMCTF{biscuit3_ biscuit5}

どうやら、buscuit3とbuscuit5から答えを持ってこればFlagが得られそうです。それぞれのファイルは次のようです。biscuit3は展開します。

# binwalk biscuit3 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
382           0x17E           Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
14253         0x37AD          Zip archive data, at least v1.0 to extract, compressed size: 5, uncompressed size: 5, name: biscuit.txt
14356         0x3814          End of Zip archive  

# binwalk biscuit5 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             Microsoft executable, portable (PE)

biscuit3を展開するとbiscuit.txtが出てきて、中にはcreamと書かれています。”cream”がbiscuit3の答えです。

biscuit5の方はbuiscuit2と同様に"GetCommandLineA"に注目しながら、ollydbgで解析していくと途中で"choux"という文字列が現れます。これがbiscuit5の答えです。

Answer

ようやくFlagがgetできました。TMCTF{cream_ choux}
と思いきや、ヒントが間違っていたようです。
TMCTF{choux_cream}