无痕渗透“INSERT INTO”型SQL注入

2023-11-14

原文链接:http://www.mathyvanhoef.com/2011/10/exploiting-insert-into-sql-injections.html

在某个寂静的深夜,你徘徊在一个网站中,其中包含一个可提交form,需要你输入一个昵称。你输入了一个单引号作为你的昵称,网站返回了一条异常信息:“You have an error in your SQL syntax”。机智的你很快明白,这里很可能存在一个“INSERT INTO”型的SQL注入。现在,你可以简单的使用sqlmap然后让它干一些不可描述的事情。但是,这样会带来一个严重的问题:一个自动化的工具会发送很多请求,而其中很大一部分的INSERT操作会成功。这样一来,对方的数据库中就会出现很多奇怪的数据。我们必须要避免这种情况。

首先,我们先在本地创建一个类似的环境来进行演示。测试代码如下:

<?php  
 $con = mysql_connect("localhost", "root", "toor") or die(mysql_error($con));  
 mysql_select_db("testdb", $con) or die(mysql_error($con));  
 $var = $_POST['post'];  
 mysql_query("INSERT INTO data VALUES ('one', '$var')") or die(mysql_error($con));  
 mysql_close($con) or die(mysql_error($con));  
 echo "The values have been added!\n";  
 ?>  

通常情况下,一个经验丰富的程序员是不会写出这么简单的代码来的。不过,这仅仅是一个简单的示例,可以用来演示渗透就足够了。我们来用sqlmap渗透一下这个环境。

./sqlmap.py -u "http://localhost/test.php" --data "post=ValidValue" -v 3

部分的输出可以在pastebin看到。它发现了一个Error-based型的SQL注入。关于这个漏洞我们会在文章的结尾再进行讨论。现在,我们先忽略这个注入,并且可以发现sqlmap在数据库中插入了很多奇怪的数据。

奇怪的数据

避免输入奇怪的数据

我们必须找到一个语法正确,但是语义错误的sql语句。并且,这个语义错误必须在执行的时候才能够被检测到。我立刻想到了标量子查询(scalar subqueries)。这种类型的子查询,只能够返回一行,否则就会返回异常。在MySQL的手册中提到:

In its simplest form, a scalar subquery is a subquery that returns a single value. A scalar subquery is a simple operand, and you can use it almost anywhere a single column value or literal is legal, and you can expect it to have those characteristics that all operands have: a data type, a length, an indication that it can be NULL, and so on.

下面是一个示例

SELECT (SELECT name FROM users WHERE email = 'bobby@tables.com')

如果子查询的结果为空,那么会被转化为NULL。如果email是一个主键的话,那么最多一个name会被返回。如果email不是主键的话,那么name的个数可能不只一个,这需要根据数据库的具体内容来决定。这就说明了,必须首先执行这个子查询,才能够确认
这个子查询是否是个合法的标量子查询。另外一个标量子查询的示例如下:

SELECT 'Your name is: ' || (SELECT name FROM users WHERE email = 'bobby@tables.com')

在这里,||是字符串拼接操作。下面的查询必然会返回异常 “#1242 - Subquery returns more than 1 row”

SELECT (SELECT nameIt FROM ((SELECT 'value1' AS nameIt) UNION (SELECT 'value2' AS nameIt)) TEST)

好了,现在我们获得了一个必然会返回异常的查询语句。通过这个异常,就可以阻止原始的INSERT INTO语句被成功执行,同时,我们自己的SQL语句又能够成功执行。下面,我会来演示将这句话改造成SQL盲注。首先,我们需要利用条件语句创造不同的执行效果。要做到这一点,有两种策略。第一种策略是,找到另外一个语义错误的查询,然后根据条件语句产生不同的异常。第二中策略是利用时间的差异:如果条件为真,那么查询立刻结束;否则执行一个较长的时间。基于时间的攻击更容易构造出来。可以看到下面的SQL语句,我们把上一条语句中的namelt替换为了一个更加复杂的表达式:

SELECT (SELECT CASE WHEN <condition> THEN SLEEP(3) ELSE 'anyValue' END FROM ((SELECT 'value1' AS nameIt) UNION (SELECT 'value2' AS nameIt)) TEST)

如果<condition>为真,那么服务器会首先等待3秒钟,然后返回一个异常(子查询返回了不止一个结果)。否则,<condition>为假,那么服务器会立即返回这个异常。接下里要做的,就是通过服务器响应的时间,来判断<condition>的真假了。基于这一点,我可以用一些自动化的工具或者脚本来完成一个基于时间的SQL盲注。

这幅图片中有4个忍者

让我们回过头来看一下php代码。在post的参数中,我们应该写入什么来发起攻击呢?你可以自己尝试找到答案。这是你必须自己掌握的技巧,特别是在给出源码的情况下。

发送一下字段可以完成这个攻击:

' || (SELECT CASE WHEN <condition> THEN SLEEP(3) ELSE 'anyValue' END FROM ((SELECT 'value1' AS nameIt) UNION (SELECT 'value2' AS nameIt)) TEST) || '

服务器在接受到这个参数后,实际会执行:

INSERT INTO data VALUES ('one', '' || (SELECT CASE WHEN <condition> THEN SLEEP(3) ELSE 'anyValue' END FROM ((SELECT 'value1' AS nameIt) UNION (SELECT 'value2' AS nameIt)) TEST) || '')

语法上是完全正确的!

更快的进行渗透

上面所说的方法十分有效,但是这是基于时间的攻击,可能会需要相当长的一段时间才能够成功渗透。实际上,我们还有一种策略可以选择,那就是根据条件产生不同的异常。首先,我们需要找到另外一种可以产生的异常。听起来很简单,但是实际做的时候才会发现,要产生一个异常很简单,但是要让这个异常在执行的时候产生,并且可以根据条件语句去控制,是一个很难的事情。在经历了一个多小时的探索后,我尝试了各种奇怪的SQL语句,也反覆阅读了MYSQL的文档,终于找到了一个可用的东西。下面就是我找到的SQL语句:

SELECT 'canBeAnyValue' REGEXP (SELECT CASE WHEN <condition> THEN '.*' ELSE '*' END)

其中,语句‘value’ REGEXP ‘regexp’是一个条件判断,当value的值符合正则表达式regexp则返回真,否则返回假。注意,.*是一个合法的正则表达式,而*不是。所以,当<condition>为真的时候,正则表达式合法,整个条件语句可以执行。否则的话,非法的正则表达式会被MySQL检测出来,并返回异常“#1139 - Got error ‘repetition-operator operand invalid’ from regexp”。棒极了!现在,我们可以创造一个基于条件的SQL盲注语句:当条件为真,那么标量子查询异常会被返回;当条件为假,正则表达式非法的异常会被返回。

但这中间还有一个障碍:我们必须小心的使用REGEXP异常。打个比方,假如你将基于时间的SQL盲注语句改成了下面这样:

SELECT (SELECT CASE WHEN <condition> THEN 'anyValue' REGEXP '*' ELSE 'AnyValue' END FROM ((SELECT 'value1' AS nameIt) UNION (SELECT 'value2' AS nameIt)) TEST)

你这么写的理由在于: 如果<condition>为假,那么它会返回‘thisCanBeAnyValue两次,并且返回一个异常,提示标量子查询返回了不止一个结果。如果<condition>为真,那么它会尝试用'*'去对”anyValue’进行正则匹配,然后返回一个正则表达式非法的异常。但是事实并不是如此!在这个语句下,你永远会得到一个正则表达式非法的异常。为什么?因为MySql知道,‘anyValue’ REGEXP ‘*’是一个不变的常量,不会因为任何东西而改变。因此,它会对这个查询进行优化,然后提前处理这个值。所以,尽管<condition>为假,MySql仍然会在优化阶段,对正则表达式进行匹配。这个正则表达式始终是非法的,因此该异常会一直被返回。要绕过这一点,就必须将'*''.*'分别放在SELECT CASE WHEN .. END控制流的两条线上,才能够避免被优化。

下面就是在我们的示例代码中国年,最终可以使用的参数:

' || (SELECT 'thisCanBeAnyValue' REGEXP (SELECT CASE WHEN <condition> THEN '.*' ELSE '*' END) FROM ((SELECT 'value1' AS nameIt) UNION (SELECT 'value2' AS nameIt)) TEST) || '

当条件为假时,正则表达式非法的异常会被返回。当条件为真时,标量子查询异常会被返回。所有的这些,都是在避免INSERT语句被成功执行的情况下发生的。这样一来,网站管理员就不会在数据库中看到任何奇怪的数据。最后,这个攻击语句会比之前基于时间的攻击快很多。好样的!

** 更进一步:基于异常的SQL注入

上面所提到的方法是我自己想到的。然而,这个网页返回了错误信息,因此也存在了一个已知的基于异常的SQL注入(通过异常信息获取数据库中的数据)。这也是sqlmap所发现的注入。通过基于异常的SQL注入,渗透速度会进一步加快。这个注入是基于一下语句产生的:

SELECT COUNT(*), CONCAT('We can put any scalar subquery here', FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x

当我们执行这个语句的时候,会得到一个异常信息 “ERROR 1062 (23000): Duplicate entry ‘We can put any scalar subquery here’ for key ‘group_key’”。可以看到,输入的语句在返回的异常信息中出现了。事实上,我们可以在这里放入任何值,包括一个标量子查询。首先,先来研究一下为什么这个异常会产生。在MySql文档中,提到了“You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times”(你不能够在ORDER BY中使用一个包含RAND()列,因为ORDER BY会多次访问这个列的值)。同样的,RAND()在GROUP BY语句中也同样会被多次访问。每一次RAND()被访问,都会产生一个新的值。好了,那么根据文档中所说的,我们实际上不允许这样子来使用RAND()方法。为什么?因为这个方法每次都返回一个新的值,而MySql则要求了一个方法必须每次返回相同的值。这样一来,就会导致我们所看到的异常信息。

你面对的敌人远比你强大!祝你好运!

总而言之,这个异常信息包含了一个用户可控的字符串!也就是说,我们可以让它返回任何数据库中的数据,从而极大的加快了渗透的速度。也许你还是好奇为什么这个查询会失败。要清楚这个问题,必须对DBMS执行查询语句的过程有一个准确的了解。关于这个不在本文章的讨论范围之内。你只需要记住,这个查询语句中的问题是因为RAND()被多次访问了,并且返回了不同的值,而这不是DBMS所接受的。

让我们再次回到示例代码。下面的参数可以达到渗透的目的:

' || (SELECT 'temp' FROM (SELECT COUNT(*), CONCAT((subquery returning the value we want to retrieve), FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) FromTable) || '

完美,我们得到了一个十分快速的SQL注入。根据可访问表的不同,这个例子可能需要进行适当的调整才能工作。另外,我们还可以将之前提到的语义错误的SQL注入引入进来。通过这种方式,我们可以确保数据不会被插入到表中。毕竟,我们是通过一种未定义的方式来产生的异常。也许就有那么一种DBMS,可以将查询中的RAND()进行特殊处理,而不返回异常,谁知道呢?

最后提一句,隐藏痕迹永远只是相对的。在某些情况下,SQL异常会被记录下来,而管理员可以在发生异常的时候得到提醒。在这种情况下,这些攻击的痕迹就完全暴露出来了!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无痕渗透“INSERT INTO”型SQL注入 的相关文章

  • JSON 响应周围的注释块

    我注意到一些 Web 应用程序返回 AJAX 响应 并在注释块中嵌入 JSON 数据 例如 这是一个示例响应 firstName John lastName Smith address streetAddress 21 2nd Street
  • 使用链接进行电子邮件验证是一个坏主意

    在我的注册过程中 用户注册后 他们会收到通过电子邮件发送的验证链接 如果他们单击该链接 那么他们的帐户才会得到验证 但这种验证方法对于机器人来说是不是太容易了 我认为电子邮件可以由机器人创建 但可以肯定的是 如果验证只是单击链接 那么它也可
  • 具有桌面应用程序安全性的 OAuth2

    我有一个 Electron 应用程序 它基本上是一个 Google Drive 客户端 我打算使用 OAuth 2 但是 Google API 要求我在生成 client secret 的地方注册我的应用程序 由于这是一个桌面应用程序 因此
  • openssl_crypt 中初始化向量的使用

    我看了一下this https stackoverflow com questions 1391132 two way encryption in php问题 并想为自己做 当我运行这段代码时 直接取自这个答案 https stackove
  • 如何在 C# 中创建 PKCS12 .p12 文件?

    这可能是一个n00b问题 但我在这方面确实没有任何经验 我需要创建一个包含 X509 证书和私钥的 p12 捆绑包 我当前有两个对象 X509Certificate2 和包含关键信息的 RSAParameters 对象 如何将它们合并到 p
  • 解码 OAEP 填充时出错

    我的问题已经解决了一半 请帮助 我已使用数字签名的公钥成功加密了文本 但在解密时出现错误 解码 OAEP 填充时出错 我的代码如下 region Test Encryption public void a using var rsa new
  • 保护 JSF 应用程序的安全

    我的一位自由职业者朋友邀请我加入他的 JSF 2 0 项目 我正在慢慢加快速度并将各个部分整合在一起 来自 Windows Forms NET 世界 至少可以说 我还有很多东西需要学习 我主要担心的是对于如何保护 JSF 应用程序缺乏明显的
  • 各个平台对 SHA-2 的支持情况如何?

    我读到 SHA 1 即将从 FIPS 180 2 标准中退役 http gcn com articles 2010 03 03 rsa sha competition aspxhttp gcn com articles 2010 03 03
  • 安全转义表名/列名

    我在 php 中使用 PDO 因此无法使用准备好的语句转义表名或列名 以下是我自己实现它的万无一失的方法 tn str replace REQUEST tn column str replace REQUEST column sql SEL
  • AES 在汇编中的实现 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 大家好 我正在尝试构建一个代码来演示
  • 是否有一种加密技术可以将 8 位数字变成 10 或 11 位或更少的数字?

    我见过的许多加密技术都可以轻松加密一个简单的 8 位数字 如 12345678 但结果通常是 8745b34097af8bc9de087e98deb8707aac8797d097f 编造的 但你明白了 有没有办法加密这个 8 位数字 但生成
  • 是否可以在 PHP 中使用 file_get_contents 来破坏 CSRF 令牌验证

    在每个会话的表单上使用令牌的 CSRF 预防方法是一种流行的方法 但是 我不明白这种令牌方式如何保护file get contentsPHP 可以获取跨域文件表单的内容 gt 它可以获取表单上的令牌并使用它 那么这种token方式是如何运作
  • 使用 Javascript eval() 100% 安全吗?

    我正在编写一个生成 Javascript 代码的 PHP 库 Javascript 代码有许多名为component001 component002 etc 页面通过 AJAX 动态加载 我需要通过 URL 变量传递组件的名称 然后由脚本进
  • 受信任的 1.5 小程序可以执行系统命令吗?

    如果是的话 这个能力有什么限制吗 具体来说 我需要以 Mac OSX 为目标 我以前用过这个在 Windows 系统上启动东西 但从未在 Mac 上尝试过 public void launchScript String args Strin
  • php 中的简单授权/登录功能

    我希望第一次实现用户登录到我的网站 我很高兴构建自己的解决方案 或者实现一些开源的东西 但是到目前为止 在我的搜索中没有任何包是明显的选择 同样 我完全意识到 作为一名中级 php 程序员 如果我推出自己的解决方案 并真正敞开大门 我很可能
  • python:API 令牌生成及其危险

    我正在按照 Flask Web Development 一书来实现基于令牌的身份验证 基本上 用户使用 HTTP 基本身份验证对其进行身份验证 并为其生成令牌 s Serializer app config SECRET KEY expir
  • 使用 PBKDF2 和 SHA256 生成 128 位 AES 密钥是否安全?

    我想使用 PBKDF2 和一些加密哈希函数来生成 128 位 AES 密钥 SHA1 也是 128 位 所以我想将其与 PBKDF2 一起使用 但它已损坏 所以我选择使用 SHA256 这是否安全 或者散列大小和生成的密钥大小之间的差异是否
  • 对客户端 JavaScript 计算器使用 eval 安全吗?

    我正在制作一个计算器 作为用户浏览器的静态 HTML 页面 该页面并非旨在将任何信息提交回服务器 除了这个计算器之外 网页上不会出现任何其他内容 在这种情况下使用 eval 安全吗 或者换句话说 在这种情况下使用 eval 是否会导致额外的
  • 任何第三方都可以从我的项目加载嵌入式资源吗?

    请参考我的一篇之前的问题 https stackoverflow com questions 14681364 issues passing data from dll to application 我问的是如何从 DLL 加载已编译的资源
  • Couchdb - 为读者用户提供的蒲团

    我想知道如何阻止读者访问 couchdb 中的 futon utils 只允许管理员访问 我需要这样做 为什么如果读者用户访问蒲团 他可以看到我所有数据库的名称以及有多少文档 我的应用程序应该让读者只有在知道文档 ID 时才能访问文档 引用

随机推荐

  • 首期 OSCHINA 季度软件评选活动正式开启,快来投票吧!

    gt https www oschina net project 2020 q1 project 上周我们发出了 OSCHINA 开源软件趋势榜 即将上线的通知 并收到不少软件推荐 首先要感谢大家的热情参与 若有对此还不了解的朋友 OSCH
  • CSS 滑动门

    先来体会下现实中的滑动门 或者你可以叫做推拉门 滑动门出现的背景 制作网页时 为了美观 常常需要为网页元素设置特殊形状的背景 比如微信导航栏 有凸起和凹下去的感觉 最大的问题是里面的字数不一样多 咋办 为了使各种特殊形状的背景能够自适应元素
  • TypeScript 基础 — Null 和 Undefined

    null 和 undefined 都有各自的类型名称 这些类型本身没有用处 因为我们只能将 null 和 undefined 赋值给定义为 null 或 undefined 类型的变量 let u undefined undefined u
  • Mac os系统下使用python3与Django进行网站搭建-2

    后台管理 站点分为内容发布和公共访问两部分 内容发布的部分是由网站的管理员负责查看 添加 修改 删除数据 开发这些重复的功能是一件繁琐的工作 所以Django能够根据定义的模型类自动地生成管理模块 使用Django的管理模块 需要按照如下步
  • 智能随访系统:提升患者综合服务能力和就医体验,提高医院品牌价值与服务质量

    随着互联网技术的不断发展以及 全民健康 全生命周期管理 概念的深化落实 随访作为医疗过程中的闭环环节 医院传统的人工电话随访方式已不能适应需求 将逐渐被智能化随访系统替代 智能化随访是指结合互联网等主流技术 以专业的随访知识库为基础 提供以
  • uni-app微信小程序开发自定义select下拉多选内容篇

    欢迎点击领取 前端面试题进阶指南 前端登顶之巅 最全面的前端知识点梳理总结 分享一个使用比较久的 技术框架公司的选型 uni app uni ui vue3 vite4 ts 需求分析 微信小程序 uni ui内容 1 创建一个自定义的下拉
  • 基于个人开发的C++MySQL插件使用UE4蓝图连接MySQL数据库

    关于UE4连接数据库 其实很简单 本质上就是使用c 来建立DB操作 再通过封装成蓝图可调用的函数即可 当然一般网络游戏是不需要在蓝图中连接数据库的 因为db操作放在客户端来做是不安全 也是不合理的 试想一下 我如果把你的游戏客户端破解了 是
  • 【推荐算法】FM模型:Factorization Machines

    1 线性回归 在介绍FM之前 我们先简单回顾以下线性回归 回归分析是一种预测性的建模技术 它研究的是因变量 目标 和自变量 预测器 之间的关系 这种技术通常用于预测分析 时间序列模型以及发现变量之间的因果关系 通常使用曲线 直线来拟合数据点
  • Jmeter之json提取器

    目标 步骤 添加 线程组 HTTP 请求 后置处理器 JSON 提取器 配置 引用名称 匹配后的数据要存储的变量名 JSON path json 路径 weatherinfo city 引用 直接引用变量名即可
  • 代码思维怎么训练

    做一个基础页面 表格 表单 导航条 模态框 轮播图 做一个主页 顶部是导航条 导航条的下面是轮播图 右上角是一个注册按钮 点击以后 弹出一个注册的模态框 1 记录思路 2 思路转成注释 越详细越好 3 看着注释写代码 4 如果写不下去 继续
  • 数据库常用SQL语句(二):多表连接查询

    前面主要介绍了单表操作时的相关查询语句 接下来介绍一下多表之间的关系 这里主要是多表数据记录的查询 也就是如何在一个查询语句中显示多张表的数据 这也叫多表数据记录的连接查询 在实现连接查询时 首先是将两个或两个以上的表按照某种关系连接起来
  • nfc(近距离无线通讯技术)

    这个技术由非接触式射频识别 RFID 演变而来 由 飞利浦半导体 现恩智浦半导体 诺基亚和 索尼共同研制开发 其基础是RFID及互连技术 近场通信 Near Field Communication NFC 是一种短距高频的无线电技术 在13
  • 零基础学区块链专栏文章目录

    前往老猿Python博文目录 零基础学区块链专栏 为免费专栏 基于老猿自己零基础学习区块链的知识总结 因此文章一定是循序渐进的介绍区块链相关知识 供类似老猿这种有一定计算机基础但区块链知识为零的同好们参考 但老猿介绍的内容都是概念性的基础知
  • 让你的应用支持新iPad的Retina显示屏

    一 应用图片 标准iOS控件里的图片资源 苹果已经做了相应的升级 我们需要操心的是应用自己的图片资源 就像当初为了支持iPhone 4而制作的 2x高分辨率版本 译者 以下简称高分 图片一样 我们要为iPad应用中的图片制作对应的高分版本
  • java 身边距离怎么查询_附近的人位置距离计算方法

    附近的人的位置用经纬度表示 然后通过两点的经纬度计算距离 根据网上的推荐 最终采用geohash geohash的实现java版 1 importjava util BitSet 2 importjava util HashMap 3 im
  • Pandas删除缺失数据函数--dropna

    在pandas中 dropna函数分别存在于DataFrame Series和Index中 下面我们以DataFrame dropna函数为例进行介绍 Series和Index中的参数意义同DataFrame中大致相同 pandas Dat
  • C# 网络编程之webBrowser乱码问题及解决知识

    在使用PHP MySQL编写网页时 曾近就因为显示中文乱码 口口口 困扰我很长时间 没想到在C 制作浏览器或获取XML页面时也经常会遇到显示中文乱码的问题 可想而知怎样解决编码问题或统一编码问题是非常严重的问题 下面就讲讲我的一些理解及解决
  • 《曾国藩家书》读书手记(修身篇一)

    曾国藩被章太炎评价为 誉之则圣相 谳之则元凶 为什么有这样的评价呢 我们可以看出曾国藩这个人褒贬不一 不过毛和蒋对于曾国藩都是推崇备至 毛说过 吾近于人 独服于曾国藩 看来曾国藩还是有可取之处的 尤其是他的家书 很多人评价甚高 一 修身篇
  • mysql存储引擎层核心服务层_MySQL(逻辑分层,存储引擎,sql优化,索引优化以及底层实现(B+Tree))...

    一 逻辑分层 连接层 连接与线程处理 这一层并不是MySQL独有 一般的基于C S架构的都有类似组件 比如连接处理 授权认证 安全等 服务层 包括缓存查询 解析器 优化器 这一部分是MySQL核心功能 包括解析 优化SQL语句 查询缓存目录
  • 无痕渗透“INSERT INTO”型SQL注入

    原文链接 http www mathyvanhoef com 2011 10 exploiting insert into sql injections html 在某个寂静的深夜 你徘徊在一个网站中 其中包含一个可提交form 需要你输入