格式化字符串漏洞

这不是一篇完整的关于 “格式化字符串漏洞“ 的文章
我在学习中遇到问题所搜索到的一些零碎知识 在这做一下总结,  参考中的每一个链接都很好的 讲解了 “格式化字符串漏洞”

基本的格式化字符串参数:
参考:http://bobao.360.cn/learning/detail/3654.html

%c:输出字符,配上%n可用于向指定地址写数据。
%d:输出十进制整数,配上%n可用于向指定地址写数据。
%x:输出16进制数据,如%i$x表示要泄漏偏移i处4字节长的16进制数据,%i$lx表示要泄漏偏移i处8字节长的16进制数据,32bit和64bit环境下一样。
%p:输出16进制数据,与%x基本一样,只是附加了前缀0x,在32bit下输出4字节,在64bit下输出8字节,可通过输出字节的长度来判断目标环境是32bit还是64bit。
%s:输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s表示输出偏移i处地址所指向的字符串,在32bit和64bit环境下一样,可用于读取GOT表等信息。
%n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100x10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),  而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过%$hn或%$hhn来适时调整。
%n : 是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符串参数可用于读取信息或配合%n写数据。

利用格式化字符串漏洞改写任意内存数据:
参考 :http://www.jianshu.com/p/f2acfeb66b6c

向内存中写入4个字节的方法是将其划分成两块(两个高位字节和两个低位字节),然后使用#$和%hn将它们放入到正确的位置。

例如,我们要将 0xbffffffa 写入内存 0x0804a028 ——示例代码的 canary(金丝雀)的地址,首先把值拆分:
两个高位字节(HOB): 0xbfff
两个低位字节(LOB): 0xffff

然后通过魔术计算公式构造一个格式化字符串:
"\x2a\xa0\x04\x08\x28\xa0\x04\x08 %.49143x%4\$hn%.16379x%5\$hn"


#  ./fmttest `printf "\x2a\xa0\x04\x08\x28\xa0\x04\x08"`%.49143x%4\$hn%.16379x%5\$hn
(这里省略一大堆输出)
Canary at 0x0804a028 = 0xbffffffa

示例成功的将canary的内容改为0xbffffffa 。

构建示例所用的公式请对照下图(魔术公式表):

 

GDB调试 和 程序运行时 内存地址不一样:

参考:http://bobao.360.cn/learning/detail/695.html

这里有一点需要特别注意: gdb调试环境里面的栈地址跟直接运行程序是不一样的,也就是说我们在直接运行程序时修改这个地址是没用的,所以我们需要结合格式化字符串漏洞读内存的功能,先泄露一个地址出来,然后我们根据泄露出来的地址计算出ebp-0x10的地址。

我们继续在gdb调试,执行get()函数后随便输入AAAAAAA,执行到printf()的时候观察栈区:



我们如果只输入%x的话就可以读出esp+4地址上的数据,也就是0xbfffefe4,而我们需要修改的地址为0xbffff048,这两个地址的偏移为0x6

下面我们就可以直接运行程序,并输入%x,然后获取ESP+4地址内的值:
1 [email protected]:~/Desktop/format$ ./test
2 %x
3 bffff024

那我们需要修改的地址就是:0xbffff024+0x64=0xbffff088

最后就是要在地址0xbffff088处写入2000: \x88\xf0\xff\xbf%10x%10x%10x%1966x%n

 
[email protected]:~/Desktop/format$ python -c "print ‘\x88\xf0\xff\xbf%10x%10x%10x%.1966x%n‘" > 11
[email protected]:~/Desktop/format$ cat 11 | ./test 
????  bffff024     0     0000000(省略了很多很多0)0000000000000000000000000003good!!

参考:

http://bobao.360.cn/learning/detail/3654.html

http://www.jianshu.com/p/f2acfeb66b6c

http://bobao.360.cn/learning/detail/695.html

时间: 2024-10-11 03:57:07

格式化字符串漏洞的相关文章

YS VTM模块存在格式化字符串漏洞,可导致VTM进程异常退出【高危】

YS VTM模块存在格式化字符串漏洞,可导致VTM进程异常退出[高危] 问题描述:          YS VTM模块开放对外监听端口(8554和8664),此次使用sulley fuzzing框架对监听在8664端口的私有二进制协议进行测试,以检测可能发生的各种问题.在该协议中,客户端会向8664端口发送一个二进制+文本格式的报文,对该报文格式的各个字段进行fuzzing,发现当向服务端的VTM进程传入格式化字符串时会崩溃并退出. 测试步骤: 1.  分别在客户机和服务器安装sulley fu

Linux pwn入门教程——格式化字符串漏洞

本文作者:[email protected] 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进行调用,例如 然而,有时候为了省事也会写成 事实上,这是一种非常危险的写法.由于printf函数族的设计缺陷,当其第一个参数可被控制时,攻击者将有机会对任意内存地址进行读写操作. 0×01 利用格

格式化字符串漏洞-无限循环

程序大致逻辑如下,程序存在system函数,保护只开了NX setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); puts("Welcome to my ctf! What's your name?"); __isoc99_scanf("%64s", &format); printf("Hello "); printf(&format); return 0; 存在格式化字符串漏洞,但

简单的格式化字符串漏洞

找到偏移量后,实现任意地址读需要在偏移量的基础上+1,因为偏移量对应的地址是一个标致,而不是printf函数的参数. 如:%8$s'+p32(flag_addr) 偏移量为7,读取flag_addr中的内容,需要使用%8$s. 实现任意地址写需要将要写入的地址和内容放到偏移量前面. 如:p32(flag_addr)+'%.2333d'+'%7$n' 原文地址:https://www.cnblogs.com/h4y0/p/11558735.html

详谈Format String(格式化字符串)漏洞

格式化字符串漏洞由于目前编译器的默认禁止敏感格式控制符,而且容易通过代码审计中发现,所以此类漏洞极少出现,一直没有笔者本人的引起重视.最近捣鼓pwn题,遇上了不少,决定好好总结了一下. 格式化字符串漏洞最早被Tymm Twillman在1999年发现,当时并未引起重视.在tf8的一份针对wu-ftpd格式化字符串漏洞实现任意代码执行的漏洞的报告之后(详情可参阅 <黑客攻防技术宝典-系统实战篇>),才让人们意识到它的危害,至此而发现了大量的相关漏洞. 格式化字符串漏洞的产生根源主要源于对用 户输

格式化字符串利用小结

格式化字符串利用小结 格式化字符串漏洞基本原理: Printf()函数的一般形式为printf("format",输出表列),其第一个参数就是格式化字符串,用来告诉程序以什么格式进行输出.正常情况下,这样使用: char str[100]; scanf("%s",str); printf("%s",str); 但也有人这么用: char str[100] scanf("%s",str); printf(str) 也许代码编写者

格式化字符串溢出实验

sh视频链接:  课程编写 类别 内容 实验课题名称 格式化字符串溢出实验 实验目的与要求 了解格式化字符串溢出的基本概念 掌握格式化字符串溢出的原理和性质 熟悉格式化字符串溢出攻击的方法 简单掌握格式化字符串溢出的防范方法 实验环境 VPC1(虚拟PC) Windows XP操作系统 软件描述 实验代码 预备知识 格式化字符串的漏洞是由像这样的代码 printf(user_input)引起的,其中 user_input 是用户输入的数据,具有 Set-UID root 权限这类程序在运行的时候

格式化字符串攻击原理及示例

一.类printf函数簇实现原理 类printf函数的最大的特点就是,在函数定义的时候无法知道函数实参的数目和类型. 对于这种情况,可以使用省略号指定参数表. 带有省略号的函数定义中,参数表分为两部分,前半部分是确定个数.确定类型的参数,第二部分就是省略号,代表数目和类型都不确定的参数表,省略号参数表中参数的个数和参数的类型是事先的约定计算出来的,每个实参的地址(指针)是根据确定参数表中最后一个实参的地址算出来的. 这里涉及到函数调用时的栈操作.函数栈的栈底是高地址,栈顶是底地址.在函数调用 时

格式化字符串攻击原理及示例.RP

格式化字符串攻击原理及示例 一.类printf函数簇实现原理 类printf函数的最大的特点就是,在函数定义的时候无法知道函数实参的数目和类型. 对于这种情况,可以使用省略号指定参数表. 带有省略号的函数定义中,参数表分为两部分,前半部分是确定个数.确定类型的参数,第二部分就是省略号,代表数目和类型都不确定的参数表,省略号参数表中参数的个数和参数的类型是事先的约定计算出来的,每个实参的地址(指针)是根据确定参数表中最后一个实参的地址算出来的. 这里涉及到函数调用时的栈操作.函数栈的栈底是高地址,