Sine安全-网络安全背后的巨人,提供服务器安全_服务器维护_网站安全解决方案

PHP网站代码的安全检测之sprintf函数安全

         

          关于php网站的安全检测,前不久看到WP博客爆出SQL注入漏洞,在此漏洞上我们进行网站

安全分析,wordpress是基于PHP代码开发的一套博客系统,我们在对其网站代码的安全检测中发

现,其中的sprintf单引号引发的安全问题,在此对这类函数做一些网站安全测试和漏洞利用详情。

 
sprintf函数 & vsprintf函数
 
 
sprintf函数是以一种规定的格式对不同的数据进行拼接,并将拼接结果返回,它并不像C语言里的

printf函数一样直接输出,而是需要另外的输出函数,如echo将返回的结果输出出来。
 
 
sprintf函数的用法可以在w3school的介绍中查看。至于vsprintf函数除了传参的时候使用了数组,

其余的与sprintf函数一样。Sine安全公司是一家专注于:服务器安全、网站安全、网站安全检测、

网站漏洞修复,渗透测试,安全服务于一体的网络安全服务提供商。

 
 
自动类型转换

 
首先我们要注意的就是,sprintf函数的自动类型转换功能。
 
当按照某一格式输出时,遇到第一个非本格式的字符就会自动截断后面的字符。

网站安全测试代码:
 
<?php
  $str = '788 1and 1=1';
  echo sprintf('output is %d',$str);
 ?>
 
PHP代码输出结果为如下图:
 

 
可以看到,当检测到第一个不属于%d类型的空格时,就会自动地去进行截断。所以从程序员的

角度来讲,很容易忘记对%d输入的数据进行强制的类型转换,因为即使不手动转换,程序也能

正常运行。
所以这一承载着危险payload的变量值就很可能被保留了下来,进入了下一步操作,

就像WP的SQL漏洞是一样的。
 
 
吞噬单引号
 
 
sprintf的第一个参数format的语法为(PS:使用了[]对每个元素进行分隔) 必须,百分号%可选,

美元符号$和单引号'可选,长度百分号为识别符,被认为是特定匹配模式的开始;后面的数字是

从模式参数后面的第n个参数输入数据;美元符号和后面的单引号是开启padding模式

(字符填充)的标识,紧跟在$'后面的是用来填充的字符,
长度则为规定的输入数据长度,如果

数据足够的话无效,如果数据不够的话就使用$'后面的填充字符进行填充;最后的为数据类型 s

表示字符串,d表示整数.
Sine安全公司是一家专注于:服务器安全、网站安全、网站安全检测、

网站
漏洞修复,渗透测试,安全服务于一体的网络安全服务提供商。
 
 
 
网站安全测试代码:
 
<?php
$str = '788 1and 1=1';
echo sprintf('output is %d hello',$str).'<br>';
echo sprintf('output is %s hello',$str).'<br>';
echo sprintf('output is %20s hello',$str).'<br>';
echo sprintf('output is %1\'#20s\' hello',$str).'<br>';
echo sprintf('output is %1$\'#20s\' hello',$str).'<br>';
echo sprintf('output is %1$\' aand 1=1',$str).'<br>';
?>
 
不加$的话只会吞掉单引号,但却无法正常带入参数$'两个都存在的话,被理解为开启padding模

式(补齐模式),所以这个单引号就被吞掉了,导致了单引号的逃逸。最后一种模式会吞掉单引

号后面的两个字符,同样导致单引号溢出。
 
 
 
未知类型吞噬斜杠
 
 
%d为整数,%s为字符串,但%y是没有规定的格式。但如果在sprintf中使用%y的话,并不会报错

而是输出空,所以可以利用这个特性吞掉反转义符。
 
<?php
$str = '788 1and 1=1';
echo sprintf('output is %y hello',$str).'<br>';
$sql1 = "select * from user where username = '%1$\' and 1=1#' and password='%s';";
$sql2 = "select * from user where username = '\' and 1=1#' and password='%s';";
$args = "admin";
echo sprintf( $sql1, $args).'<br>' ;
echo sprintf( $sql2, $args) ;
?>
 
结果如下图:
 
 


 
除此之外还有宽字节吞掉单引号,substr吞掉单引号,在dedecms不断成熟,db类使用逐渐规范

的今天,了解一些吞噬单引号的技巧对于网站安全检测工作来说是非常重要的。
 
分享: