1. ์์ฝ๋๋
์์ฝ๋(Shellcode)๋ ์คํํ ์ ์๋ ์ด์ ๋ธ๋ฆฌ(๊ธฐ๊ณ์ด) ์ฝ๋ ์กฐ๊ฐ์ ์๋ฏธํ๋ค.
pwnable์์๋ ์์ ํ๋ํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ์์ฝ๋๋ฅผ ์ฌ์ฉ๋๋ค.
๋ง์ฝ ํ๋ก๊ทธ๋จ์ ์คํ ์์น(rip)๋ฅผ ์์ ์ด ์์ฑํ ์์ฝ๋๋ก ์ฎ๊ธธ ์ ์๊ฒ ๋๋ค๋ฉด ์ด์
๋ธ๋ฆฌ์ด๋ ๊ธฐ๊ณ์ด์ ๊ฑฐ์ ์ผ๋์ผ ๋์๋๋ฏ๋ก ์ฌ์ค์ ์ํ๋ ๋ชจ๋ ๋ช
๋ น์ CPU์ ๋ด๋ฆด ์ ์๊ฒ ๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์์ฝ๋๋ ์ด์
๋ธ๋ฆฌ์ด๋ก ๊ตฌ์ฑ๋๋ฏ๋ก ๊ณต๊ฒฉ์ ์ํํ ๋์ ์ํคํ
์ฒ์ ์ด์์ฒด์ ์ ๋ฐ๋ผ, ๊ทธ๋ฆฌ๊ณ ์
ธ์ฝ๋์ ๋ชฉ์ ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์์ฑ๋๋ฏ๋ก, ์ง์ ์์ฑํ ์ค ์์์ผ ํ๋ค.
2. orw ์์ฝ๋ ์์ฑ
“/tmp/flag”๊ฒฝ๋ก์ ํ์ผ์ readํ๋ ์์ฝ๋๋ฅผ ์์ฑํด๋ณด์
์ด์ฒ๋ผ ํ์ผ๊ณผ ๊ด๋ จ๋ ์์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ํ์ํ syscall์ open(), read(), write() ๋ฑ์ด ์๋ค.
char buf[0x30];
int fd = open("/tmp/flag", RD_ONLY, NULL);
read(fd, buf, 0x30);
write(1, buf, 0x30);
64bit์์๋ rax์ syscall number๊ฐ ๋ค์ด๊ฐ๊ณ rdi, rsi, rdx์ ๊ฐ๊ฐ ์ฒซ๋ฒ์งธ, ๋๋ฒ์งธ ์ธ๋ฒ์งธ ์ธ์๊ฐ ๋ค์ด๊ฐ๋ค.
(64๋นํธ ํจ์ ํธ์ถ ๊ท์ฝ ์ฐธ๊ณ )
syscall | rax | rdi | rsi | 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 |
์ฆ, ํ์ผ open (์ด๊ธฐ) -> ํ์ผ ์ฝ๊ธฐ -> ๋ด์ฉ ์ฐ๊ธฐ ์ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
(1) open("/tmp/flag", RD_ONLY, NULL)
open์ ์ฒซ๋ฒ์งธ ์ธ์(rdi)๋ก openํ filename์ ๋ฐ๋๋ค.
์ฆ, ์ฐ๋ฆฌ๋ ์ฝ์ด์ผ๋๋ ํ์ผ์ ์ด๋ฆ์ ์ธ์๋ก ์ฃผ๊ธฐ ์ํด์ “/tmp/flag” ๋ฌธ์์ด์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ํด์ผ ํ๋ค.
๋ฉ๋ชจ๋ฆฌ๋ ๋ฆฌํ์๋์ ๋ฐฉ์์ผ๋ก ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋๋ฏ๋ก 2f 74 6d 70 2f 66 6c 61 67 ๋ฅผ ์ญ์์ผ๋ก ์ ๋ ฅํด์ผ ํ๋ฏ๋ก, ์คํ์ 0x67616c662f706d742f๋ฅผ pushํด์ผ ํ๋ค.
์ด๋, 64๋นํธ์์๋ 8๋ฐ์ดํธ ๋จ์๋ก ์คํ์ ๊ฐ์ ์ ์ฅํ ์ ์๋๋ฐ ํ์ฌ ์ ์ฅํด์ผ ํ๋ ๋ฌธ์์ด์ 9๋ฐ์ดํธ์ด๊ธฐ ๋๋ฌธ์ 0x67์ ๋ฐ๋ก ๋จผ์ push ํด์ค๋ค. ๊ทธ๋ฆฌ๊ณ rdi๊ฐ ์ด๋ฅผ ๊ฐ๋ฆฌํค๋๋ก rsp๋ฅผ rdi๋ก ์ฎ๊ธด๋ค. (์ฒซ๋ฒ์งธ ์ธ์์ด๊ธฐ ๋๋ฌธ)
- push 0x67
- mov rax, 0x616c662f706d742f
- push rax
//์ฌ๊ธฐ์ ์ ๋ฐ๋ก push์ํ๊ณ rax์ ์ ์ฅํ๊ณ pushํ๋์ง ์์งํ ์ ๋ชจ๋ฅด๊ฒ ๋ค..์ด๊ฒ ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ด๋ผ๋๋ฐ ๋จผ๊ฐ ์๋ฟ์ง๊ฐ ์์
open ํจ์์ ๋๋ฒ์งธ ์ธ์๋ก๋ ํ์ผ์ ์ฌ๋ ๋ชจ๋๋ฅผ ์ง์ ํ๋๋ฐ, ์ฐ๋ฆฌ๋ ํ์ผ์ ์์ฑํ๊ฑฐ๋ ์ฐ์ง ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ฝ๊ธฐ ์ ์ฉ ๋ชจ๋(O_RDONLY)๋ก ํ์ผ์ ์ด ๊ฒ์ด๋ฏ๋ก rdi๋ฅผ 0์ผ๋ก ์ค์ ํ ๊ฒ์ด๋ค.
- xor rsi, rsi
- xor์ ๋ ๋นํธ๊ฐ ๋ค๋ฅผ ๋ 1์, ๊ฐ์ ๋ 0์ ๋ฐํ (์๊ธฐ ์์ ๊ณผ xor ์ฐ์ฐ์ด๋ฏ๋ก ๋ฌด์กฐ๊ฑด 0 ๋ฐํ ํ rsi์ ์ ์ฅ)
//์ด๊ฒ๋ ๊ทธ๋ฅ mov rsi, 0 ํ๋ฉด ๋์ง ์๋
-> xor rsi, rsi๋ ๋จ์ํ rsi๋ฅผ 0์ผ๋ก ๋ง๋๋ ๊ฐ์ฅ ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ ์ค ํ๋๋ผ๊ณ ํ๋ค. (๋ ์์ ๋ฐ์ดํธ ์๋ก ์ธ์ฝ๋ฉ๋๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ๋ฉด์์ ๋ ํจ์จ์ ์ด๋ผ๊ณ ํจ)
์ธ๋ฒ์งธ ์ธ์๋ ํ์ผ ์์ฑ ์ ๊ถํ ์ค์ ์ด๋ฏ๋ก ํ์ผ์ ์ฝ์ ๋์๋ ์๋ฏธ๋ฅผ ๊ฐ์ง ์์ผ๋ฏ๋ก, rdx๋ 0์ผ๋ก ์ค์ ํ๋ค.
//๋ง์ฐฌ๊ฐ์ง์ ์ด์ ๋ก xor์ฐ์ฐ ์ฌ์ฉ
- xor rdx, rdx
๋ง์ง๋ง์ผ๋ก rax๋ฅผ open์ syscall ๊ฐ์ธ 2๋ก ์ค์ ํ๋ค.
push 0x67 ;์ ์ฅํด์ผ ํ๋ ๋ฌธ์์ด์ด 9๋ฐ์ดํธ์ด๋ฏ๋ก g(๋ฆฌํ์๋์) ๋จผ์ push
mov rax, 0x616c662f706d742f ; ๋๋จธ์ง 8๋ฐ์ดํธ rax์ ์ ์ฅ
push rax ; rax์ ์ ์ฅํ 8๋ฐ์ดํธ push
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)
(2) read(fd, buf, 0x30)
syscall์ ๋ฐํ ๊ฐ์ rax๋ก ์ ์ฅ๋๋ค. (open()์ ๋ฆฌํด๊ฐ์ fd)
๋ฐ๋ผ์ open("/tmp/flag", RD_ONLY, NULL)์ fd๋ rax์ ์ ์ฅ๋๋ค.
read์ ์ฒซ ๋ฒ์งธ ์ธ์๋ ์ฝ์ ํ์ผ์ fd๊ฐ์ด๋ฏ๋ก rax๊ฐ์ rdi์ ๋ฃ์ด์ค๋ค.
- mov rdi, rax
๋ ๋ฒ์งธ ์ธ์์ธ rsi๋ ํ์ผ์์ ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฒํผ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
0x30 ๋งํผ์ ๋ฐ์ดํฐ๋ฅผ ํ์ผ์์ ์ฝ์ด์ฌ ๊ฒ์ด๋ฏ๋ก, rsi์ rsp-0x30์ ๊ฐ๋ฅดํค๋๋ก ํ๋ค.
- mov rsi, rsp
- sub rsi, 0x30
์ธ ๋ฒ์งธ ์ธ์์ธ rdx๋ ํ์ผ๋ก๋ถํฐ ์ฝ์ด๋ผ ๋ฐ์ดํฐ์ ๊ธธ์ด์ธ 0x30์ผ๋ก ์ค์ ํ๋ค.
- mov rdx, 0x30
read ์์คํ ์ฝ์ ํธ์ถํ๊ธฐ ์ํด์ rax๋ฅผ 0์ผ๋ก ์ค์ ํฉ๋๋ค.
- mov rax, 0x0
- ์ ์๋ ์ xor์ํ๋๊ฑฐ์ ๊ตฌ๊ธ๋งํด๋ด๋ ๋ชจ๋ฅด๊ฒ ์ ใ ํ
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)
(3) write(1, buf, 0x30)
write()๋ ์ฒซ๋ฒ์งธ ์ธ์๋ก ํ์ค ์ถ๋ ฅ(stdout) fd๋ฅผ ๋ฐ์ผ๋ฏ๋ก 1๋ก ์ค์ ํ๋ค.
- mov rdi, 1
- ํ์ผ ๋์คํฌ๋ฆฝํฐ์ ๊ฐ์ด ๋จ์ํ ์ ์ ๊ฐ์ ํํํ๋ ๊ฒฝ์ฐ์๋ 10์ง์ ํ๊ธฐ๊ฐ ๋ ํํ๊ฒ ์ฌ์ฉ๋๋ค๊ณ ํ๋ค,,
rsi์ rdx๋ read์ ๊ฐ์ด ๋์ผํ๋ฏ๋ก, ์ด์ ์ ์ฌ์ฉํ ๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
- buf: ์ถ๋ ฅํ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๋ฒํผ์ ์ฃผ์
- count: ์ถ๋ ฅํ ๋ฐ์ดํธ ์
write ์์คํ ์ฝ์ ํธ์ถํ๊ธฐ ์ํด์ rax๋ฅผ 1๋ก ์ค์ ํ๋ค.
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x30)
๋ฐ๋ผ์ ์ต์ข ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
;Name: orw.S
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)
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)
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x30)
์ด์ ๋ธ๋ฆฌ ์ฝ๋๋ฅผ ์ปดํ์ผํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ ์ ์๋ค.
์ ์ฝ๋๋ ์ด์ ๋ธ๋ฆฌ์ด๋ก ์์ฑ๋ ์งง์ ๊ธฐ๊ณ์ด ์ฝ๋๋ก ํน์ ๊ธฐ๋ฅ์ ์ํํ๋ ์ฝ๋์ด์ง๋ง, ๋ ๋ฆฝ์ ์ผ๋ก ์คํ ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ์ด ์๋๊ธฐ ๋๋ฌธ์ ๋จ์ํ ๊ธฐ๊ณ์ด๋ก ๋ณํ๋์๋๋ผ๋, ์ด์์ฒด์ ๊ฐ ์๊ตฌํ๋ ELFํ์์ด ์๋๋ฏ๋ก ๋ฆฌ๋ ์ค์์ ์คํ๋ ์ ์๋ค. ๋ฐ๋ผ์, ์คํ ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ง ๊ฐ์ถ๊ณ , ๊ตฌ์ฒด์ ์ธ ๊ธฐ๋ฅ์ ์๋ ์ฝ๋์ธ ์ค์ผ๋ ํค ์ฝ๋์ ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์ ์ฝ๋๋ฅผ ์ฝ์ ํ๋ฉด ELF ํ์์ ๊ฐ์ถ๊ฒ ๋์ด ์คํ ๊ฐ๋ฅํ๊ฒ ๋๋ค.
*์ค์ผ๋ ํค ์ฝ๋๋ ํต์ฌ ๋ด์ฉ์ด ๋น์ด์๋, ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ง ๊ฐ์ถ ์ฝ๋๋ฅผ ์๋ฏธํจ.
- ์ค์ผ๋ ํค ์ฝ๋
// 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(); }
์์ ์ค์ผ๋ ํค ์ฝ๋์์ __asm__ ๋ถ๋ถ์ ์ฐ๋ฆฌ๊ฐ ์์ฑํ ์์ฝ๋ ์ฑ์ฐ๋ฉด ๋๋ค.
// 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 ํ์ผ์ ์์ฑํ ๋ค ์ ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด ์ ๋๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋~
3. ๋๋ฒ๊น
๋ค์์ผ๋ก๋ ์ฐ๋ฆฌ๊ฐ ๋ง๋ค ์ ์ฝ๋๋ฅผ ๋๋ฒ๊น ํด๋ณผ ๊ฒ์ด๋ค.
> gdb orw ๋ช ๋ น์ด๋ฅผ ํตํด gdb๋ฅผ ์คํ์์ผ์ค๋ค.
๊ทธ ๋ค์ ์์ด ์คํํ๋ ๋ถ๋ถ์ธ run_sh()์ bp๋ฅผ ๊ฑธ์ด์ค๋ค
> b *run_sh
(1) ์ฒซ๋ฒ์งธ syscall์ด ์์นํ run_sh+29 ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ์ค์ ํ ํ ์คํ
> b *run_sh+29
> c
pwndbg๋ syscall์ ํธ์ถํ ๋, ์๋์ฒ๋ผ ์ธ์๋ฅผ ํด์ํด์ ๋ณด์ฌ์ค๋ค.
๋ฐ๋ผ์,
open(“/tmp/flag”, O_RDONLY(0), NULL(0));๊ฐ ์คํ๋จ์ ํ์ธํ ์ ์๋ค.
syscall์ ์คํํด๋ณด๋ฉด open ์์คํ ์ฝ์ ์ํํ ๊ฒฐ๊ณผ๋ก /tmp/flag์ fd(3)๊ฐ rax์ ์ ์ฅ๋๋ค.
(2) ๋๋ฒ์งธ syscall์ด ์์นํ run_sh+55 ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ์ค์ ํ ํ ์คํ
.read(fd, buf, 0x30)
-> fd(3)์์ ๋ฐ์ดํฐ๋ฅผ 0x7fffffffe2c8์ 0x30๋ฐ์ดํธ๋งํผ ์ ์ฅํ๋ค.
ni ๋ช ๋ น์ด๋ก syscall์ ์คํํด๋ณด๊ณ , RSI ๋ ์ง์คํฐ์ ๊ฐ์ ํ์ธํด๋ณด๋ฉด ํ์ผ์ ๋ด์ฉ์ด 0x7fffffffe2b8์ ์ ์ฅ๋์์์ ์ ์ ์๋ค.
rsi๋ read ํจ์์ ๋ ๋ฒ์งธ ์ธ์๋ก, ํ์ผ์์ ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฒํผ ์ฃผ์๋ฅผ ์ ๋ฌํ๋ค.
์ฐ๋ฆฌ๋ 0x30 ๋งํผ์ ๋ฐ์ดํฐ๋ฅผ ํ์ผ์์ ์ฝ์ด์ฌ ๊ฒ์ด๋ฏ๋ก, rsi์ rsp-0x30์ ๊ฐ๋ฅดํค๋๋ก ํ์๋ค.
์ด๋, rsi ๊ฐ์ rsp์ ์ ์ฅํ ๋ค sub ๋ช ๋ น์ด๋ฅผ ํตํด์ rsi์ 0x30์ ๋บ ๊ฐ์ ์ ์ฅํ๋ ๋ฐฉ์์ผ๋ก ํ์๊ธฐ ๋๋ฌธ์ ์๋
> mov rsi, rsp ์คํ ๊ฒฐ๊ณผ rsi๊ฐ rsp๋ฅผ ๊ฐ๋ฅดํค๊ณ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
> sub rsi, 0x30์ ์คํ ๊ฒฐ๊ณผ, rsi์๋ rsp 0x7fffffffdee8 - 0x30 ์ ๊ฐ์ธ 0x0x7fffffffdeb8 ๋ฅผ ๊ฐ๋ฅดํค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ค์ ๋์์์ ์ด๋ฌํ ๋ ์ง์คํฐ์ ๊ฐ์ x/s ๋ช ๋ น์ด๋ก๋ ํ์ธํ ์ ์๋ค.
x: 16์ง์๋ก ๋ณด์ฌ์ค
s: ํด๋น ์ฃผ์์ ์๋ ๋ฌธ์์ด์ ๋๊น์ง (\n์ ๋ง๋ ๋๊น์ง) ๋ณด์ฌ์ค
(3) ์ธ๋ฒ์งธ syscall์ด ์์นํ run_sh+71 ๋ธ๋ ์ดํฌ ํฌ์ธํธ๋ฅผ ์ค์ ํ ํ ์คํ
write ํจ์๋ ์ฒซ๋ฒ์งธ ์ธ์์ธ rdi๋ง 1๋ก ์ค์ ํ ๋ค, ๋๋จธ์ง ์ธ์(buf, 0x30)๋ read์ ๋์ผํ์๋ค.
๋ฐ๋ผ์ rdi๋ง 1๋ก ์ค์ ๋์ด์๊ณ , ๋๋จธ์ง ๋ ์ง์คํฐ์ ๊ฐ์ ๋์ผํ๋ค.
ni๋ฅผ ํตํด syscall์ ์คํํ๋ฉด 0x7fffffffdeb8 (rsp - 0x30)์ ์ ์ฅ๋ ๊ฐ์ธ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋๋ค.
+) ์คํ ๊ฒฐ๊ณผ ์ถ๋ ฅ์ ์ด์ํ ๊ฐ์ด ํฌํจ๋๋ค๋ฉด, ์ด๊ธฐํ๋์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค.
์ด์ ๋ํ ๊ฐ๋ ์ ์ถํ์ ๋ค์ ๋ค๋ค๋ณผ ๊ฒ์ด๋ค.