【问题标题】:How to do damage with SQL by adding to the end of a statement?如何通过添加到语句的末尾来破坏 SQL?
【发布时间】:2014-07-04 11:10:54
【问题描述】:

也许我在 SQL 方面没有足够的创造力或知识......但看起来没有办法在 SELECT 中执行 DROP TABLE 或 DELETE FROM 而无法启动新语句。

基本上,我们的代码库有一些巨大的、“不够强大”的 SQL 生成组件,它从不使用预准备语句,而我们现在有一个与这个遗留组件交互的 API。

现在我们可以通过追加到查询的末尾来修改查询,但是无法插入任何分号。因此,我们可以这样做:

/query?[...]&location_ids=loc1')%20or%20L1.ID%20in%20('loc2

这会导致这个

SELECT...WHERE L1.PARENT_ID='1' and L1.ID IN ('loc1') or L1.ID in ('loc2');...

这只是一个例子。

基本上,我们可以在任何/大多数生成的 SQL 查询的末尾附加几乎任何内容,而不是添加分号。

关于这可能会如何造成一些损害的任何想法?您可以在删除或删除表的 SQL 查询末尾添加一些内容吗?或者创建一个非常荒谬的查询,它占用了所有 CPU 并且永远不会完成?

【问题讨论】:

  • 关于 SQL 注入的话题很多,您不妨阅读一些以前的搜索结果by clicking here 或手动搜索。
  • 您声明查询字符串添加的结果将导致 "SELECT...WHERE L1.PARENT_ID='00000000-0000-0000-0000-000000000001' 和 L1.ID IN ('loc1 ') 或 L1.ID in ('loc2');"但如果你注意到末尾有一个分号。分号是怎么来的?
  • SQL 组件将其添加到末尾。
  • 所以如果我构造这样的查询字符串 /query?[...]&location_ids=loc1');我在查询字符串中输入的分号会发生什么变化?
  • 服务器抛出异常。 com.company.nbi.exceptions.ApplicationException: 0x1F615:EXCEPTION OCCURRED RUNNING SQL QUERY: org.postgresql.util.PSQLException: ERROR: unterminated quoted string at or near "')"

标签: sql postgresql security sql-injection


【解决方案1】:

你是这么说的:

/query?[...]&location_ids=loc1')%20or%20L1.ID%20in%20('loc2

将导致:

SELECT...WHERE L1.PARENT_ID='1' and L1.ID IN ('loc1') or L1.ID in ('loc2');

所以它看起来像这样:

/query?[...]&location_ids=');DROP%20TABLE users;--

将导致:

SELECT...WHERE L1.PARENT_ID='1' and L1.ID IN ('');DROP TABLE users;--');

这是一个 SELECT、一个 DROP 和一个注释。

【讨论】:

  • SQL 是半净化的,分号被删除。我无法在语句中插入分号;我更好奇你可以添加什么(比如使用 JOIN 或 UNION)来做一些有趣的事情。但仍会尝试以某种方式在其中添加分号(阅读上面发布的链接@Zarthus。)
【解决方案2】:

如果无法注入另一个语句,则您仅限于现有语句及其功能。

就像在这种情况下,如果您仅限于 SELECT 并且您知道注入发生的位置,请查看 PostgreSQL’s SELECT syntax 以了解您的选择。由于您要注入WHERE clause,因此您只能在WHERE 子句之后注入其他条件或其他允许的子句。

如果SELECT 的结果返回给用户,您可能需要添加自己的SELECTUNION operation。但是,PostgreSQL 要求对应列的数据类型兼容:

表示UNION 的直接操作数的两个SELECT 语句必须产生相同数量的列,并且对应的列必须是兼容的数据类型。

所以你首先需要知道原始SELECT的列数和数据类型。

可以使用ORDER BY clause 检测列数,方法是指定列号,如ORDER BY 3,这将按第三列的值对结果进行排序。如果指定的列不存在,则查询失败。

现在,在确定列数后,您可以为UNION SELECT 的每一列注入具有适当列数的UNION SELECTnull

 loc1') UNION SELECT null,null,null,null,null --

现在,您可以通过为每一列一一使用不同的值来确定每一列的类型。如果列的类型不兼容,您可能会出现提示预期数据类型的错误,例如:

错误:整数的输入语法无效
错误:无法匹配 UNION 类型的文本和整数

在您确定了足够多的列类型后(如果向用户显示一列可能就足够了),您可以更改您的SELECT 以选择您想要的任何内容。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 2015-10-19
  • 1970-01-01
相关资源
最近更新 更多