个人博客地址
http://www.darkerbox.com
欢迎大家学习交流
环境:
https://www.ripstech.com/php-security-calendar-2017/
参考
https://xz.aliyun.com/t/2467
分析
class Login {
public function __construct($user, $pass) {
$this->loginViaXml($user, $pass);
}
public function loginViaXml($user, $pass) {
if (
(!strpos($user, '<') || !strpos($user, '>')) &&
(!strpos($pass, '<') || !strpos($pass, '>'))
) {
$format = '<?xml version="1.0"?>' .
'<user v="%s"/><pass v="%s"/>';
$xml = sprintf($format, $user, $pass);
$xmlElement = new SimpleXMLElement($xml);
// Perform the actual login.
$this->login($xmlElement);
}
}
}
new Login($_POST['username'], $_POST['password']);
漏洞主要出现在strpos
函数。
strpos
主要是用来查找字符在字符串中首次出现的位置。
代码很明显。通过sprintf
格式化字符串函数将参数拼接到xml中,中间的过滤使用的是strpos
函数
作者的本意是通过strpos
匹配到了<
或者>
。就退出判断。
strpos函数是返回字符串首次出现的位置。如果出现了。返回的是数字。如果没有匹配到。返回false。但是作者忽略了<
可能在第一个字符。如果<
在第一个字符。strpos返回的是0。然后取反变为true。绕过了if判断。
所以作者的if判断只能防御<
不在第一个字符的字符串。
user=<"><injected-tag%20property="&pass=<injected-tag>
欢迎大家一起学习交流,共同进步,欢迎加入信息安全小白群