某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

    • 服务器端主题
    • SQL注入

      • SQL注入
        • 什么是SQL注入?
        • SQL注入攻击成功时的影响是什么?
        • SQL注入示例
        • 检索隐藏数据
        • 颠覆应用程序逻辑
        • 从其他数据库表中检索数据
        • 检查数据库
        • SQL盲注漏洞
        • 如何检测 SQL 注入漏洞
        • 在不同的查询部分中注入SQL
        • 不同上下文中的 SQL 注入
        • 二阶SQL注入
        • 数据库特定因素
        • 如何防范SQL注入
      • SQL注入-UNION攻击
      • SQL注入-检查数据库信息
      • SQL注入-盲注
      • SQL注入备忘单
      • 实验室参考答案
    • 身份验证

    • 目录遍历

    • OS命令注入

    • 业务逻辑漏洞

    • 信息泄露

    • 访问控制

    • 文件上传漏洞

    • 条件竞争

    • 服务端请求伪造(SSRF)

    • XML外部实体(XXE)注入

    • NoSQL注入

    • API测试

  • 客户端主题(翻译)

  • 高级主题(翻译)

  • 扩展阅读(翻译)

  • 个人学习笔记

  • 实验室做题记录

  • BurpSuite及官方实验室
  • 服务器端主题(翻译)
  • SQL注入
clincat
2023-03-12
目录

SQL注入

翻译

原文:https://portswigger.net/web-security/sql-injection

- name: 翻译
  desc: 原文:https://portswigger.net/web-security/sql-injection
  bgColor: '#F0DFB1'
  textColor: 'green'
1
2
3
4

SQL注入是一个古老的黄金漏洞,导致了许多引人注目的数据泄露。

尽管学习起来相对简单,但它可以潜在地用于一些高度严重的漏洞。这使得它成为初学者理想的第一个主题,甚至对于更有经验的用户也是必要的知识。

访问官方链接 https://portswigger.net/web-security/sql-injection (opens new window) 以学习SQL注入

# 0SQL注入

在本节中,我们将解释什么是SQL注入(SQLi,SQL injection),描述一些常见的示例,解释如何发现和利用各种SQL注入漏洞,并总结如何防范SQL注入。

实验室

如果你已经熟悉SQLi漏洞背后的基本概念,并且只想在一些实际的、易受攻击的目标上练习和利用它们,那么你可以从下面的链接访问本主题中的所有实验室。

View all SQL injection labs >> (opens new window)

# 1什么是SQL注入?

SQL注入(SQLi)是一种Web安全漏洞,允许攻击者干扰应用程序 并对其数据库进行查询。

它通常允许攻击者查看他们无法检索的数据。这可能包括属于其他用户的数据,或者应用程序本身能够访问的任何其他数据。在许多情况下,攻击者可以修改或删除这些数据,从而导致应用程序的内容或行为发生持久更改。

在某些情况下,攻击者可以升级SQL注入攻击 以破坏底层服务器或其他后端基础设施,或执行拒绝服务攻击。

提示

官方在此处提供了一个YouTuBe的视频链接:https://www.youtube.com/embed/wX6tszfgYp4?origin=https://portswigger.net&rel=0 (opens new window)

# 2SQL注入攻击成功时的影响是什么?

成功的SQL注入攻击可能导致对敏感数据的未授权访问,例如密码、信用卡详细信息或用户个人信息。近年来,许多备受瞩目的数据泄露都是SQL注入攻击的结果,导致声誉受损和监管部门罚款。

在某些情况下,攻击者可以获得进入组织系统的持久后门,导致长期的威胁,可以在很长一段时间内不被注意到。

# 3SQL注入示例

有各种各样的SQL注入漏洞、攻击和技术,它们出现在不同的情况下。一些常见的SQL注入示例包括:

  • 检索隐藏数据 (opens new window),你可以在其中修改SQL查询以返回其他结果。

  • 颠覆应用程序逻辑 (opens new window),你可以更改查询来干扰应用程序逻辑。

  • UNION攻击 (opens new window),可以从不同的数据库表中检索数据。

  • 检查数据库 (opens new window),从中可以提取关于数据库版本和结构的信息。

  • SQL盲注 (opens new window),你控制的查询结果不会在应用程序的响应中返回。

# 4检索隐藏数据

假设有一个购物应用程序,它以不同的类别来显示产品。

当用户点击gift类别时,他们的浏览器会请求URL:

https://insecure-website.com/products?category=Gifts
1

这将导致应用程序执行 SQL 查询,并从数据库中检索相关产品的详细信息:

SELECT * FROM products WHERE category = 'Gifts' AND released = 1
1

这个 SQL 查询要求数据库返回:

  • 所有数据(*)
  • 从 products 表中
  • category 字段等于 Gifts
  • 并且 released 字段等于1

限制条件released = 1用于隐藏未发布的产品。对于未发布的产品,假设released = 0。

该应用程序不会针对 SQL 注入攻击实现任何防御措施,因此攻击者可以构建如下攻击:

https://insecure-website.com/products?category=Gifts'--
1

这将导致SQL查询:

SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1
1

这里的关键是双破折号--是 SQL 中的注释指示符,这意味着查询的其余部分被解释为注释。

这有效地删除了查询的其余部分,因此它不再包含条件AND release = 1。这意味着将显示所有产品,包括未发布的产品。

更进一步,攻击者可以使应用程序显示任何类别中的所有产品,包括他们不知道的类别:

https://insecure-website.com/products?category=Gifts'+OR+1=1--
1

这将导致 SQL 查询:

SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
1

修改后的查询将返回类别为Gifts或1等于1的所有项目。由于1=1始终为真,查询将返回所有项。

警告

在向 SQL 查询中注入OR 1=1条件时要小心。

尽管这在注入的初始上下文中可能是无害的,但应用程序在多个不同的查询中 使用来自单个请求的数据是很常见的。

例如,如果条件达到UPDATE或DELETE语句,则可能导致数据意外丢失。

实验室-学徒

WHERE子句中的SQL注入漏洞,允许检索隐藏数据 >>

- name: 实验室-学徒
  desc: WHERE子句中的SQL注入漏洞,允许检索隐藏数据 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/sql-injection/lab-retrieve-hidden-data
  bgColor: '#001350'
  textColor: '#39d50c'
1
2
3
4
5
6

# 5颠覆应用程序逻辑

假设有一个登录类应用程序,它允许用户使用 用户名和密码 进行登录。

如果用户提交用户名wiener和密码bluecheese,应用程序通过执行以下 SQL 查询来检查凭据:

SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'
1

如果该查询返回了用户的详细信息,则登录成功。否则将被拒绝。

在这里,攻击者可以使用 SQL 注释序列--,从查询的WHERE子句中删除密码检查,并作为任何用户登录,而无需密码。例如,提交用户名administrator'--和一个空密码,结果如下:

SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
1

该查询返回用户名为administrator的用户,攻击者以该用户身份成功登录。

实验室-学徒

允许绕过登录的SQL注入漏洞 >>

- name: 实验室-学徒
  desc: 允许绕过登录的SQL注入漏洞 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/sql-injection/lab-login-bypass
  bgColor: '#001350'
  textColor: '#39d50c'
1
2
3
4
5
6

# 6从其他数据库表中检索数据

在应用程序响应中返回 SQL 查询结果的情况下,攻击者可以利用 SQL 注入漏洞,从数据库中的其他表中检索数据。

这是使用UNION关键字完成的,它允许你执行额外的SELECT查询并将结果附加到原始查询。

例如,如果应用程序执行以下查询,其中包含用户输入 “Gifts” :

SELECT name, description FROM products WHERE category = 'Gifts'
1

然后攻击者可以提交输入:

' UNION SELECT username, password FROM users--
1

这将导致应用程序返回所有用户名和密码 以及产品的名称和描述。

阅读更多

SQL注入UNION攻击 >> (opens new window)

# 7检查数据库

在初步识别 SQL 注入漏洞后,获取有关数据库本身的一些信息通常很有用。这些信息通常可以为进一步利用铺平道路。

你可以查询数据库的版本详细信息。执行此操作的方式取决于数据库类型,因此你可以使用任何有效的技术推断数据库类型。例如,在 Oracle 上可以执行:

SELECT * FROM v$version
1

你还可以确定存在哪些数据库表,以及它们包含哪些列。例如,在大多数数据库中,可以执行以下查询来列出表:

SELECT * FROM information_schema.tables
1

阅读更多

在SQL注入攻击中检查数据库 >> (opens new window)

SQL注入备忘单 >> (opens new window)

# 8SQL盲注漏洞

许多 SQL 注入实例都是盲注漏洞。这意味着应用程序不会在其响应中返回 SQL 查询的结果或任何数据库错误的详细信息。

盲注漏洞仍然可以被利用,用来访问未经授权的数据,但所涉及的技术通常更复杂且难以执行。

根据漏洞的性质和所涉及的数据库,可以使用以下技术来利用 SQL 盲注漏洞:

  • 你可以更改查询的逻辑,从而根据单个条件的真实性,在应用程序的响应中 触发可检测的差异。这可能包括 在一些布尔逻辑中注入一个新的条件,或者有条件地触发一个错误,比如被零整除。(布尔盲注)
  • 你可以在查询处理过程中 有条件地触发时间延迟,从而允许你根据应用程序响应所需的时间 推断条件的真实性。(时间盲注)
  • 你可以使用 OAST (opens new window) 技术触发带外网络交互。这种技术非常强大,可以在其他技术无法做到的情况下工作。通常,你可以通过带外通道直接窃取数据,例如,将数据放入你控制的域的 DNS 查找中。(DNSLOG盲注)

阅读更多

SQL盲注 >> (opens new window)

# 9如何检测 SQL 注入漏洞

使用 Burp Suite 的Web漏洞扫描器 (opens new window)可以快速可靠地发现大多数SQL注入漏洞。

可以通过 对应用程序中的每个入口点 使用一组系统性的测试,从而手动检测 SQL 注入。这通常涉及:

  • 提交单引号字符'并查找错误或其他异常。
  • 提交一些特定于 SQL 的语法,该语法的计算结果为 入口点的基(原始)值和不同的值,并在应用程序响应中 查找差异。
  • 提交布尔条件,如OR 1=1和OR 1=2,并查找应用程序响应中的差异。
  • 提交 用于在 SQL 查询中 触发时间延迟的有效负载,并查找响应时间的差异。
  • 提交 OAST 有效负载,以便在 SQL 查询中 触发带外网络交互,并监视任何 因此而产生的交互。

# 10在不同的查询部分中注入SQL

大多数 SQL 注入漏洞都出现在SELECT查询的WHERE子句中。经验丰富的测试人员通常都很了解这种类型的 SQL 注入。

但是,SQL 注入漏洞在原则上,可以出现在 查询中的任何位置 和 不同的查询类型中。其他最经常出现 SQL 注入的地方是:

  • 在UPDATE语句中,在更新的值或WHERE子句中。
  • 在INSERT语句中,在插入的值中。
  • 在SELECT语句中,在表名 或 列名内。
  • 在SELECT语句的ORDER BY子句中。

# 11不同上下文中的 SQL 注入

到目前为止,在所有实验室中,你都使用查询字符串来注入恶意的 SQL 有效负载。

但是,请务必注意,你可以使用应用程序 作为 SQL 查询处理的任何可控输入,从而执行 SQL 注入攻击。例如,一些网站采用 JSON 或 XML 格式的输入,并使用它来查询数据库。

这些不同的格式,甚至可以为你提供替代方法,通过混淆攻击 (opens new window)来绕过由于 WAF 和其他防御机制 而被阻止的攻击。

“弱实现” 通常只是在请求中查找常见的 SQL 注入关键字,因此你可以通过对“被禁止的关键字”进行简单地编码或转义,从而绕过这些过滤器。

例如,以下基于 XML 的 SQL 注入,使用 XML 转义序列对SELECT中的S字符进行编码:

<stockCheck>
    <productId>
        123
    </productId>
    <storeId>
        999 &#x53;ELECT * FROM information_schema.tables
    </storeId>
</stockCheck>
1
2
3
4
5
6
7
8

实验室-从业者

通过 XML 编码绕过过滤器的 SQL 注入 >>

- name: 实验室-从业者
  desc: 通过 XML 编码绕过过滤器的 SQL 注入 >>
  avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
  link: https://portswigger.net/web-security/sql-injection/lab-sql-injection-with-filter-bypass-via-xml-encoding
  bgColor: '#001350'
  textColor: '#4cc1ff'
1
2
3
4
5
6

# 12二阶SQL注入

当应用程序从 HTTP 请求中获取用户输入,并在处理该请求的过程中,以不安全的方式将输入合并到 SQL 查询中时,就会出现一阶 SQL 注入。

在二阶 SQL 注入(也称为存储 SQL 注入)中,应用程序从 HTTP 请求中获取用户输入,并将其存储起来以备将来使用。这通常是通过数据库来完成的,但是在存储数据的地方不会产生漏洞。稍后,当处理不同的 HTTP 请求时,应用程序检索存储的数据,并以不安全的方式将其合并到 SQL 查询中。

二阶 SQL 注入通常出现在开发人员意识到 SQL 注入漏洞的情况下,因此可以安全地处理输入到数据库中的初始位置。当数据稍后被处理时,它被认为是安全的,因为它之前被安全地放入数据库中。此时,数据以不安全的方式处理,因为开发人员错误地认为它是受信任的。

# 13数据库特定因素

SQL 语言的一些核心特性,在流行的数据库平台上以相同的方式实现,因此许多检测和利用 SQL 注入漏洞的方法,在不同类型的数据库上都是相同的工作方式。

但是,常见数据库之间也存在许多差异。这意味着一些用于检测和利用 SQL 注入的技术,在不同平台上的工作方式不同。例如:

  • 字符串 串联 的语法。
  • 注释。
  • 批处理(堆叠)查询。
  • 特定于平台的 API 。
  • 错误信息。

阅读更多

SQL注入备忘单 >> (opens new window)

# 14如何防范SQL注入

通过在查询中使用参数化查询(预编译语句)而不是字符串连接,可以防范大多数 SQL 注入实例。

以下代码容易受到 SQL 注入的影响,因为用户输入直接连接到查询中:

String query = "SELECT * FROM products WHERE category = '" + input + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
1
2
3

可以很轻松地重写此段代码,以防止用户输入干扰查询结构:

PreparedStatement statement = connection.PrepareStatement("SELECT * FROM products WHERE category = ?");
statement.setString(1, input);
ResultSet resultSet = statement.executeQuery();
1
2
3

参数化查询,可用于不受信任的输入 在查询中显示为数据的任何情况,包括WHERE子句和INSERT或UPDATE语句中的值。但它不能用于处理查询 其他部分的不可信输入,例如表名或列名,或ORDER BY子句。

将不受信任的数据放入查询部分 的应用程序功能 将需要采用不同的方法,例如 将允许的输入值列入白名单,或者使用不同的逻辑来交付所需的行为。

为了使参数化查询能够有效地防范 SQL 注入,查询中使用的字符串 必须始终是硬编码常量,并且不得包含来自任何源的任何变量数据。不要试图逐个判断数据项是否可信,并继续在查询中使用字符串拼接,来表示认为安全的情况。

很容易对数据的可能来源犯错误,或者在其他代码中的更改,违反了关于哪些数据被污染的假设。

阅读更多

使用Burp Suite的Web漏洞扫描程序 查找SQL注入漏洞 >> (opens new window)

编辑 (opens new window)
服务器端主题
SQL注入-UNION攻击

← 服务器端主题 SQL注入-UNION攻击→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式