主流脚本语言都支持对XPath的处理,本次实例分析以PHP来学习XPath注入的原理;
blog.xml:
index.php:
$xml = simplexml_load_file('blog.xml');
$name = $_GET['name'];
$pwd = md5($_GET['pwd']);
$query = "/root/users/user[username/text()='".$name."' and password/text()='".$pwd."']";
echo $query;
$result = $xml->xpath($query);
if($result) {
echo '
}
代码很简单,实现了一个简单的登陆验证功能.其实和SQL注入相似,没有对用户输入的数据做过滤,导致攻击者可以直接注入”XPath表达式”,只要知道用户名就能绕过密码验证,
如果用户名没法得知,可以用两个”or”来绕过验证逻辑
这边有个存放分数的xml文件:
score.xml:
查询分数的php是:
score.php:
if (file_exists('score.xml')){
$xml = simplexml_load_file('score.xml'); //»ñÈ¡xmlÎļþÀïÃæµÄÊý¾Ý
if (isset($_GET['user'])){
$user = $_GET['user'];
//¹¹ÔìÓï¾ä
$en_scr = "//peo[@name='{$user}']/subject[contains(foo, 'english')]/score";
$ch_scr = "//peo[@name='{$user}']/subject[contains(foo, 'chinese')]/score";
$en_qu = $xml -> xpath($en_scr);
$ch_qu = $xml -> xpath($ch_scr);
foreach ($en_qu as $key => $value) {
echo $user.':
english is '.$value;
}
foreach ($ch_qu as $key => $value) {
echo '
'.'chinese is '.$value;
}
}else{
echo 'only have three user: vk, tom, helen.';
}
}
?>
这里,php用simplexml_load_file()这个函数来访问那个存分数的xml文件,然后用xpath语法去查询数据。
查询vk用户分数
依次其他两个用户也可以查询。
定位到源码,看xml查询语言的实现
图中框这个就相当于Sql中的语句,这就是xpath路径选取xml节点的语句
直接解释查询语句
/peo 匹配到所有peo节点
这节点不止一个,到底要哪个呢?
[@name='{$user}'] 接收到用户名字,来查询相应的节点(就是刚才的helen,vk)
/subject 刚才peo节点下的subject节点
这时候问题又来了,subject节点不止一个,哪个呢?
[contains(foo, 'english')] contains函数,第一个参数给出节点名,第二个写字符串
意思就是,匹配出他的foo子节点中,信息含有english的那个
/score 已经找到相应的subject了,然后就是找分数了。Score就是存放分数的节点
这样就能实现从xml文件中查询相应数据了!
以上两个案例仅供学习参考。
本地搭建PHP环境进行模拟测试,建议安装PHPstudy,只需将要复现的xml文件和php文件上传至web目录,通过浏览器访问即,手工测试便于深入理解xml查询,数据存储方式,深一步理解漏洞形成原理。