前言
php是一门神奇的语言,不同函数的配合不当就有可能造成漏洞。这里记录一下由于sprintf
和addslashes
函数配合使用,可能造成的注入漏洞。
分析
思考下面的代码1
2
3
4
$user = addslashes($_GET['user']);
$sql = sprintf("select * from users where type='%s' and user='$user'",'admin');
...//对sql语句进行查询
代码中使用addslashes
函数对传入参数进行转义,然后用sprintf
函数进行sql语句的构造。
现在假设服务器的其他配置和代码安全,并且对该sql语句不做其他转义或过滤。那么如何绕过呢?这里由于sprintf函数在使用中将$user
变量直接加入到格式化控制字符串中,那么如果$user
变量中含有%
的话sprintf函数将解析该位置的参数,如果没有提供对应参数函数就会报错。c语言中sprintf函数会将%d
,%c
等解析成相应类型,PHP中也一样,那么如果传入下面的字符串会发生什么?1
%1$' or 1#
这里加上%1
表示使用sprintf的第二个参数来对应解析。这时由于字符串通过addslashes
的转义在单引号前面会插入一个\,当传入sprintf时%
就会‘吞掉’后面的\,从而‘’’逃逸出来,完成注入。
解决办法
严格控制sprintf的格式化控制字符串,不使用PHP的双引号解析变量的方式。
总结
这是在做ctf中学到的,由于不知道这种方式可以使‘’’逃逸出来,还是参考了搜索引擎上的文章。漏洞总是出现在函数的使用上,熟悉函数的使用和特性对漏洞的分析和挖掘是有帮助的。另外,在漏洞挖掘中要时刻注意数据的流向,说不定当中一个环节就放过了恶意数据。