【由浅入深_打牢基础】一文搞懂XPath 注入漏洞
字数 1289 2025-08-06 20:12:33

XPath注入漏洞详解

0x00 XPath简介

XPath是一种用于在XML或HTML文档中查找信息的语言,类似于SQL在数据库中查询信息的作用。

XPath基本语法

XPath将XML文档视为节点树,包含七种节点类型:

  • 元素节点
  • 属性节点
  • 文本节点
  • 命名空间节点
  • 处理指令节点
  • 注释节点
  • 文档节点(根节点)

常用表达式

  • nodename:选取此节点的所有子节点
  • /:从根节点选取
  • //:选取所有子元素,不考虑其在文档中的位置
  • .:选取当前节点
  • ..:选取当前节点的父节点
  • @:选取属性

常用函数

  • starts-with():匹配属性开始位置的关键字
  • contains():匹配属性值中包含的字符串
  • text():匹配显示文本信息

XPath示例

<?xml version="1.0" encoding="UTF-8" ?>
<students>
  <student number="1">
    <name id="zs">
      <xing></xing>
      <ming></ming>
    </name>
    <age>18</age>
    <sex>male</sex>
  </student>
  <student number="2">
    <name id="ls">李四</name>
    <age>24</age>
    <sex>female</sex>
  </student>
</students>

Python中使用XPath查询示例

from lxml import etree

xml = '''
<students>
  <student number="1">
    <name id="zs">
      <xing>张</xing>
      <ming>三</ming>
    </name>
    <age>18</age>
    <sex>male</sex>
  </student>
  <student number="2">
    <name id="ls">李四</name>
    <age>24</age>
    <sex>female</sex>
  </student>
</students>
'''

tree = etree.XML(xml)

# 选择所有students,选第一个值->students->student->name->xing的文本
out = tree.xpath('//students')[0][0][0][0].text
print(out)  # 输出:张

# 所有name元素,第二个也就是李四那个,选它的文本
out = tree.xpath('//name')[1].text
print(out)  # 输出:李四

# 获取name元素的id属性
out = tree.xpath('//name')[1].xpath('@id')
print(out)  # 输出:['ls']

0x01 XPath注入攻击

XPath注入类似于SQL注入,当应用程序使用用户输入构造XPath查询而没有进行适当过滤时,攻击者可以构造恶意输入来修改查询逻辑。

典型XPath注入示例

假设有以下登录验证代码:

from lxml import etree

xml = '''
<students>
  <student>
    <id>admin</id>
    <password>123456</password>
  </student>
</students>
'''

tree = etree.XML(xml)
username = input('请输入用户名')
password = input('请输入密码')

out = tree.xpath('/students/student[id/text()="'+username+'" and password/text()="'+password+'"]')
print('登录成功,欢迎您'+out[0][0].text)

正常登录

  • 输入:admin123456
  • 构造的XPath:/students/student[id/text()="admin" and password/text()="123456"]

注入攻击

  • 用户名:admin
  • 密码:" or ""="
  • 构造的XPath:/students/student[id/text()="admin" and password/text() = "" or ""=""]
  • 这将返回所有student节点,因为or ""=""条件永远为真

0x02 XPath注入实战示例

2.1 墨者靶场示例

  1. 发现name参数传递XML数据
  2. 假设使用单引号闭合
  3. 构造恒等条件:' or ''='
  4. 成功绕过验证

2.2 bWAPP - XPath(Login Form)

  1. 尝试输入用户名和密码都为admin
  2. 观察URL变化
  3. 构造注入:'or''='
  4. 成功绕过登录

2.3 bWAPP - XPath(Search)

  1. 添加单引号'测试,发现报错,确认存在XPath注入
  2. 尝试构造返回所有值的payload:' | //* or''='' or ''='
  3. 发现报错,说明闭合方式更复杂
  4. 尝试考虑[]闭合:']test[a='a
  5. 仍然报错,考虑可能使用了函数和()
  6. 构造payload:')test[a=('a
  7. 成功获取所有数据

防御措施

  1. 输入验证:严格验证用户输入,只允许预期的字符
  2. 参数化查询:使用参数化XPath查询,避免直接拼接用户输入
  3. 最小权限原则:限制XPath查询的权限
  4. 错误处理:避免显示详细的错误信息
  5. 编码输出:对输出进行适当的编码处理

总结

XPath注入是一种严重的安全漏洞,攻击者可以利用它绕过认证、获取敏感数据或执行未授权的操作。理解XPath语法和注入原理对于开发和测试人员至关重要。通过实施适当的防御措施,可以有效地防止XPath注入攻击。

XPath注入漏洞详解 0x00 XPath简介 XPath是一种用于在XML或HTML文档中查找信息的语言,类似于SQL在数据库中查询信息的作用。 XPath基本语法 XPath将XML文档视为节点树,包含七种节点类型: 元素节点 属性节点 文本节点 命名空间节点 处理指令节点 注释节点 文档节点(根节点) 常用表达式 : nodename :选取此节点的所有子节点 / :从根节点选取 // :选取所有子元素,不考虑其在文档中的位置 . :选取当前节点 .. :选取当前节点的父节点 @ :选取属性 常用函数 : starts-with() :匹配属性开始位置的关键字 contains() :匹配属性值中包含的字符串 text() :匹配显示文本信息 XPath示例 Python中使用XPath查询示例 : 0x01 XPath注入攻击 XPath注入类似于SQL注入,当应用程序使用用户输入构造XPath查询而没有进行适当过滤时,攻击者可以构造恶意输入来修改查询逻辑。 典型XPath注入示例 假设有以下登录验证代码: 正常登录 : 输入: admin 和 123456 构造的XPath: /students/student[id/text()="admin" and password/text()="123456"] 注入攻击 : 用户名: admin 密码: " or ""=" 构造的XPath: /students/student[id/text()="admin" and password/text() = "" or ""=""] 这将返回所有student节点,因为 or ""="" 条件永远为真 0x02 XPath注入实战示例 2.1 墨者靶场示例 发现name参数传递XML数据 假设使用单引号闭合 构造恒等条件: ' or ''=' 成功绕过验证 2.2 bWAPP - XPath(Login Form) 尝试输入用户名和密码都为 admin 观察URL变化 构造注入: 'or''=' 成功绕过登录 2.3 bWAPP - XPath(Search) 添加单引号 ' 测试,发现报错,确认存在XPath注入 尝试构造返回所有值的payload: ' | //* or''='' or ''=' 发现报错,说明闭合方式更复杂 尝试考虑 [] 闭合: ']test[a='a 仍然报错,考虑可能使用了函数和 () 构造payload: ')test[a=('a 成功获取所有数据 防御措施 输入验证 :严格验证用户输入,只允许预期的字符 参数化查询 :使用参数化XPath查询,避免直接拼接用户输入 最小权限原则 :限制XPath查询的权限 错误处理 :避免显示详细的错误信息 编码输出 :对输出进行适当的编码处理 总结 XPath注入是一种严重的安全漏洞,攻击者可以利用它绕过认证、获取敏感数据或执行未授权的操作。理解XPath语法和注入原理对于开发和测试人员至关重要。通过实施适当的防御措施,可以有效地防止XPath注入攻击。