sprintf字符串格式化漏洞
1 | var_dump(sprintf("1%'#10s9",'monkey')); |
问题出在单引号上
Sprintf()函数中**%**1$’[需要填充的字符]10s:
在需要填充的字符前面都要加上一个单引号,’10’代表的字符串总长度为10。
执行
1 | <?php |
结果为
1 | select * from t where a='' |
在php的格式化字符串中,%后的一个字符(除了’%’)会被当作字符类型,而被吃掉,单引号’,斜杠\也不例外
所以,如果提前将%'and 1 = 1 #'
拼接到sql语句里,如果存在sqli过滤,单引号会被转移成
1 | \'select* from user where username = '%\' and 1=1#'; |
然后sql语句如果继续进入格式化字符串,\会被%吃掉,则 ‘ 成功逃逸
测试1:
1 | <?php |
结果:
1 | select * from user where username = '' and 1=1#'; |
测试2:
1 | <?php |
结果:
1 | select * from user where username = '' and 1=1#' andpassword='admin'; |
国外的研究人员AnthonyFerrara给出了另一种利用方式
1 | <?php |
%c起到了类似chr()的效果,将数字39转化为单引号’,从而导致了sql注入。
结果:
1 | SELECT * FROM foo WHERE bar IN ('') OR 1 = 1 /*') AND baz = 39 |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment
ValineGitalk