格式化字符串漏洞

一、原理

格式化字符串漏洞的产生原因一般是由于不规范的printf函数使用造成的。

printf函数是C语言中的格式化输出函数,它对于每一个格式串(%s、%n...),printf函数都会在栈中寻找一个变量,并将其视为一个字符串的地址,然后printf会尝试寻找这些地址所对应的字符串,将其复制到格式化字符串中去输出,如果栈中的值指向的地址无法访问或不存在,那么printf就会输出空值。

函数原型:int printf(const char*format,...);

函数返回值:打印出的字符格式

二、利用

如果printf函数未写明格式化字符串,只写出了对应的参量,那我们就可以任意输出带有特定目的的格式化字符串来泄露或是篡改栈上的值从而获取程序控制流。

几种常见的转换说明符:

  • %s 获取指定变量所对应地址的内容,但是会存在零截断。(%2$s:表示栈上第二个空间内容)
  • %p 把指向的内存的值直接输出,并不会作为一个地址去访问指向的东西,可以避免程序崩溃(找偏移量)
  • %n 它会把读到的值视为一个地址,并把printf已经输出的字符数量写入到这个地址指向的位置。(%6$n表示往第六个参数指向的内存中写内容:写入目标地址的值=已经输出的字符数量)

三、常见题型

1.泄露栈内存

  • 获取某个变量的值(%n$x、%n$s)
  • 获取某个变量对应的地址内存

2.泄露任意地址内存

  • 利用GOT表得到libc函数地址,进而获取libc,进而获取其他libc函数地址(addr%k$s)

3.覆盖内存

...[overwrite addr]....%[overwrite offset]$n

其中… 表示我们的填充内容,overwrite addr 表示我们所要覆盖的地址,overwrite offset 地址表示我们所要覆盖的地址存储的位置为输出函数的格式化字符串的第几个参数

四、攻击

除了可以采用”%x$n”的方式手动构造payload外,还可以利用pwntools中的fmtstr格式化字符串类来解决问题。

函数用法:fmtstr_payload(offset,{原地址(要写入数据的地址):X(字符数量或目的函数)})

函数原型:fmtstr_payload(offset,writes,numbwritten=0,write_size='byte')

  • offset(int):表示格式化字符串偏移量;
  • writes(dic):格式为{addr:value , addr2:value2},用于往addr里写入value的值,表示利用%n写入的数据,采用python字典形式:{seed:1}【将seed的值改成1】或者可以将printf_got改为system()地址直接进行提权:{printf_got:system_addr}。
  • numbwritten(int):已经由printf函数写入的字节数,没有设置0,采用默认值即可;
  • write_size:表示写入方式:hhn(byte,按字节写入)、hn(short,两字节写入)、n(int,四字节写入)
  • 默认值是byte,即按hhn写入。

fmtstr_payload()返回结果就是payload

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值