格式化字符串(部分)

一.什么是格式化字符串

格式化字符串就是使用Format函数将指定字符串转换为想要输出的格式

1.格式化字符串函数

①常见的有格式化字符串函数有
  • 输入

    • scanf
  • 输出

函数基本介绍
printf输出到stdout
printf输出到 stdout
fprintf输出到指定 FILE 流
vprintf根据参数列表格式化输出到 stdout
vfprintf根据参数列表格式化输出到指定 FILE 流
sprintf输出到字符串
snprintf输出指定字节数到字符串
vsprintf根据参数列表格式化输出到字符串
vsnprintf根据参数列表格式化输出指定字节到字符串
setproctitle设置 argv
syslog输出日志
err, verr, warn, vwarn 等。。。

2.格式化字符串

①常见的格式化字符串
字符串类型表示
d4-byte整数
u4-byte无符号整数
x4-byte十六进制数
s4-byte ptr字符串
c 1-byte单个字符
hh1-byte限定输出格式为8位
h2byte限定输出格式为16位
I4byte限定输出格式为32位
II8-byte限定输出格式为64位
②常见格式化字符串格式(摘自CTF Wiki)

%[parameter][flags][field width][.precision][length]type

  • parameter
    • n$,获取格式化字符串中的指定参数
  • flags(可为0个或多个)
  • field width
    • 输出的最小宽度
  • precision
    • 输出的最大长度
  • length,输出的长度
    • hh,输出一个字节
    • h,输出一个双字节
  • type
    • d/i,有符号整数
    • u,无符号整数
    • x/X,16 进制 unsigned int 。x 使用小写字母;X 使用大写字母。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
    • o,8 进制 unsigned int 。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
    • s,如果没有用 l 标志,输出 null 结尾字符串直到精度规定的上限;如果没有指定精度,则输出所有字节。如果用了 l 标志,则对应函数参数指向 wchar_t 型的数组,输出时把每个宽字符转化为多字节字符,相当于调用 wcrtomb 函数。
    • c,如果没有用 l 标志,把 int 参数转为 unsigned char 型输出;如果用了 l 标志,把 wint_t 参数转为包含两个元素的 wchart_t 数组,其中第一个元素包含要输出的字符,第二个元素为 null 宽字符。
    • p, void * 型,输出对应变量的值。printf("%p",a) 用地址的格式打印变量 a 的值,printf("%p", &a) 打印变量 a 所在的地址。
    • n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
    • %, '%'字面值,不接受任何 flags, width。

二.格式化字符串漏洞

1.原理

错误的使用,直接将使用者的输入作为了fmt使用
例如,以printf为例:
我们正常使用printf时,是这样的:printf("%s", str,n)
但是由于一些人马虎或者偷懒,可能会写成printf(str),这种情况下,程序虽然会报错,但是依旧是编译成功的。但是,此时str会被当做是一个format参数。众所周知,format参数中的字符串是可以被输出的,但是如果这串字符串中有基本的格式化字符串参数(如%s, %n, %x, %p等),那么这些内容就会被当做基本的格式化字符串参数来处理,这样就出现了可利用的漏洞。
2.常用格式化字符串参数

参数基本介绍
%c输出字符
%d输出十进制整数
%x输出16进制数据
%p输出16进制数据(与%x基本相同,只是附加前缀0x)
%s输出字符串(偏移处指针指向的字符串)
%n将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置
  • 注:%n是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符串参数可用于读取信息或配合%n写数据。

三.格式化字符串漏洞利用

由于存在格式化字符串漏洞,所以,格式化字符串可以被攻击者的输入任意控制,但是printf本身是检查后面有几个参数。所以,我们可以利用%x来造成栈上信息泄露,利用$来控制信息泄露的位置,从而达到对任意地址数据的控制。

1.对任意内存地址处数据的读取

2.对任意内存地址处数据的写入

3.格式化字符串的综合利用

①got劫持
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值