前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sprintf格式化字符串

sprintf格式化字符串

作者头像
字节脉搏实验室
发布2020-05-13 14:33:09
1.7K0
发布2020-05-13 14:33:09
举报
文章被收录于专栏:字节脉搏实验室

0x01 定义和用法:

sprintf() 函数把格式化的字符串写入变量中。

arg1arg2++ 参数将被插入到主字符串中的百分号(%)符号处。该函数是逐步执行的。在第一个 % 符号处,插入 arg1,在第二个 % 符号处,插入 arg2,依此类推。

注释:如果 % 符号多于 arg 参数,则您必须使用占位符,如果不多于也可使用。占位符位于 % 符号之后,由数字和 “\$” 组成

语法:sprintf(format,arg1,arg2,arg++)

详情参看:

https://www.w3school.com.cn/php/func_string_sprintf.asp

这里我将我觉得更为重要的部分列出

这个Demo就使用了占位符,输出结果:the number is 123 可以理解为1\$会被置为空,所以就以%d的形式输出。

再看这个Demo,输出结果:the number is d 可以理解为%1$\会被置为空

0x02 sprintf注入原理

可以看到, php源码中只对15种类型做了匹配, 其他字符类型都直接break了,php未做任何处理,直接跳过,所以导致了这个问题:

没做字符类型检测的最大危害就是它可以吃掉一个转义符\, 如果%后面出现一个\,那么php会把\当作一个格式化字符的类型而吃掉\, 最后%\(或%1$\)被替换为空.

因此sprintf注入,或者说php格式化字符串注入的原理为:

要明白%后的一个字符(除了%,%上面表格已经给出了)都会被当作字符型类型而被吃掉,也就是被当作一个类型进行匹配后面的变量,比如%c匹配asciii码,%d匹配整数,如果不在定义的也会匹配,匹配空,比如%\,这样我们的目的只有一个,使得单引号逃逸,也就是能够起到闭合的作用。

举两个例子:

不使用占位符

所以输出结果是:select * from user where username = '' and 1=1#';

使用占位符

所以输出结果是:SELECT * FROM t WHERE a='admin' AND b='' and 1=1#'

通过以上两个例子可以看到是通过吃掉'\'来使得单引号逃逸出来

0x03 CTF应用

以[DASCTF2020]babytricks为例首先是一个登录框,在hint中找到select * from user where user='$user' and passwd='%s'

其中原题部分关键代码如下,同时因为有print_r的存在,所以出现了非预期解

输出结果:select * from user where user='nd passwd='^0#' limit 0,1 可以看到没加\后没有构成占位符置空,反而向后吞噬三位吃掉了' a

异或规则:相同为0,不同为1,而'nd passwd’会被PHP当作0来与后面的数值进行异或,从而实现了类似万能密码的构造,打印输出了内容

0x04 总结

sprintf的格式化字符串漏洞,首先通过传入%,看是否有sprintf函数的报错来进行判断。再根据格式化的位置利用占位符进行注入。本篇文章中要注意区分%1$\和%1\$的不同。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 字节脉搏实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 定义和用法:
  • 0x02 sprintf注入原理
  • 0x03 CTF应用
  • 0x04 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档