BugkuCTF-PWN题pwn6-printf超详细讲解(未提供Libc版本)

前言

此题是我根据某大佬wp(从Libc官网下载的Libc)解出的,我在他的exp脚本基础上进行修改通过LibcSearcher搜索可利用的Libc,因为这道题在Bugku未提供Libc版本

有些部分很难理解,如果有大佬知道的,还请不吝赐教

还是先把解题流程写下来吧

解题流程

查看文件类型:
在这里插入图片描述
查看保护机制:
在这里插入图片描述
IDA64位打开:
伪码:
在这里插入图片描述
查看子程序:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
case 2:
在这里插入图片描述
在这里插入图片描述
对encode2进行分析,发现printf(buf1),应该是要用格式化字符串漏洞,因为buf1并不是这个函数的局部变量,可能还是个格式化字符串不在栈上的格式化字符串漏洞,具体的encode操作是对一个字节进行移位,想利用的话还要先构造一个逆算法。

case 3:
在这里插入图片描述
在这里插入图片描述
对encode3进行分析,buf是0x110大小,但是read是0x100,直接栈溢出是没戏了,这里还有个strcpy函数,可以把encode1里的src复制给buf,后来发现实现不了,放弃了,还是老老实实地通过格式化字符串漏洞写GOT表吧,encode算法也是移位操作,写个逆算法就行。

case 1:
在这里插入图片描述
在这里插入图片描述
对encode1进行分析,该函数的功能时先输入一个key,之后对这个key进行逐位加1异或的操作(具体看伪码,用文字也有点难描述)
之后用前面key生成的一个结果对真正要encode的字符串再进行一个异或操作,最终输出结果。其他没发现啥问题。

解题思路

通过上面的分析,大体思路是通过格式化字符串漏洞写GOT表,把strcpy换成system。具体要解决以下几个问题:
1、程序正常执行的话是一轮游,选择任何一个encode算法,执行完就退出了。需要能重复执行该程序,不能执行一次就退出。
2、如何获取libc基址、程序基址、栈地址。
3、写各个encode的逆算法。

针对第1个问题,发现判断是否退出的关键变量qword_201700在src的后面,而且encode1的read是0x150,覆盖qword_201700使用0x148就够用了,0^x=x,这里的key选用\x00,首次尝试使用’a’*0x148直接过了(其实0x141~-0x148都可以)。

针对第2个问题,使用格式化字符串漏洞,配合gdb调试可以泄露libc基址、程序基址、栈地址。

针对第3个问题,encode2和encode3都是移位操作,不涉及复杂的数学知识,也好实现。

具体调试

针对泄露地址的问题,在printf处下断点,红框的__libc_start_main可以用来泄露libc基址,使用fmtarg,这个插件需要安装到gdb里。(那位大佬说具体的偏移也可以看最左侧的值,这里是0x32,0x32+5=55,这里不明白为什么要加5,有大佬知道的,还请不吝赐教)
在这里插入图片描述
rbp下面的存储是返回地址,和IDA里的信息可以对应上,可以计算出程序基址。使用fmtarg。(偏移的算法也可以是0x2e+5=51,不明白为什么加5,有大佬知道的,还请不吝赐教)
在这里插入图片描述
泄露地址后开始使用格式化字符串不在栈上的利用。首先找三个指针p1->p2->p3。具体见下图的红框。p1(%14$p)、p2(%50 $p)、p3(%54 $p)(这里最疑惑,为什么要找这三个指针,有大佬知道的,还请不吝赐教)
在这里插入图片描述
具体的利用是分两步走的:
第一步首先通过p1写p2的低位字节(改变指向p3的偏移),再利用p2把p3所在的内存改成strcpyGOT表地址。
第二步通过p2写p3(此时已经是strcpyGOT表)的低位字节,再通过strcpyGOT把最终指向地址改为system的libc地址。

首先看第一步的之间过程
在这里插入图片描述
在这里插入图片描述
最终的p3值被改为了strcpyGOT地址
在这里插入图片描述
第二步的之间过程与第一步类似,不一张张贴图了
exp:

#coding=utf-8
from pwn import *
import sys
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值