网站已通过 SQL 注入被黑客入侵

Posted

技术标签:

【中文标题】网站已通过 SQL 注入被黑客入侵【英文标题】:Site has been hacked via SQL Injection 【发布时间】:2011-06-03 19:27:53 【问题描述】:

最近我的网站被 SQL 注入攻击了。黑客使用了以下查询 获取我的数据库名称。我无法理解他们写的这个查询。

查询:

=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--

查询运行后,它显示一个整数结果,类似于“74545883”。

您能解释一下查询的工作原理吗?

【问题讨论】:

请不要在您的查询上签名,我们知道您是谁 这是您日志中唯一的条目吗? 请不要签署您的查询 - 有一会儿,我想知道签署 mysql 查询是什么意思:) 有问题的查询...因为它模棱两可,所以我编辑它 【参考方案1】:

首先,查询看起来像是 html 编码的。将%20s 替换为空格,它将变得更具可读性。他们还将部分查询转换为某事物的十六进制表示。尝试对语句的那部分进行十六进制解码。

当您尝试将 SQL 作为字符串动态创建,然后将其发送到 DBMS 时,就会产生 SQL 注入风险。想象一下这样的字符串存储在您的系统中,用于搜索栏等:

SELECT * FROM SOME_TABLE WHERE SOME_COLUMN=

要完成查询并让攻击进入,他们需要这样输入:

'x' or 1=1

在这种情况下,查询将变为:

SELECT * FROM SOME_TABLE WHERE SOME_COLUMN='x' or 1=1

SOME_COLUMN 可以是任何变量,它在哪里失败并不重要,重要的是1=1 始终为真,从而可能让攻击者访问该表中的每一行。

既然您已经了解它,请检查您的代码并将每个动态创建的查询替换为准备好的语句。 OWASP 网站也有很多用于防御性编码的资源:

www.owasp.org

【讨论】:

【参考方案2】:

查询使用DATABASE() 返回数据库名称,然后使用HEx() 函数将其转换为十六进制值。

一旦他们有了这个,他们就可以使用UNHEX函数

查看UNHEX 示例

mysql> SELECT UNHEX('4D7953514C');
        -> 'MySQL'
mysql> SELECT 0x4D7953514C;
        -> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
        -> 'string'
mysql> SELECT HEX(UNHEX('1267'));
        -> '1267'

很高兴知道它们是如何进入的,但总而言之,您需要修复代码以避免 SQL 注入。

【讨论】:

@astander - 他询问查询是如何工作的。我将其解释为“他们是如何绕过我的(缺乏)预防的”,而不是“这里的每个功能都做了什么”。我觉得一个人应该能够执行“mysql HEX”的google查询,但是新手可能不适应转义查询和常见的mysql注入尝试,是吗? 谷歌搜索“mysql HEX”会告诉他该函数的作用(就像你链接的那样),但谷歌搜索“mysql注入”不会告诉他为什么他的特定查询被黑客入侵...... 【参考方案3】:

它看起来像overflow attack。他们UNION-ed 与您现有的查询。用 (space) 替换所有 %20,因为它的 url 编码产生:

=-999.9 UNION ALL SELECT CONCAT(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536-

分解:

    =-999.9 刚刚结束您当前的查询 0x31303235343830303536NULL - 它们只是匹配现有查询中的列数。如果您有 SELECT * FROM users 并且 users 有 4 列,那么 UNION 也必须有 4 列。因此,他们只是使用 `NULL 值来填充这些列。 真正的困惑在于CONCAT()。它们组合了 126、39、数据库名称为十六进制值、39 和 126 -- 是一个 mysql 注释 - 之后它会忽略您的其余查询

从这次攻击来看,我怀疑您没有将输入包装在mysql_real_escape_string() 中,这使得被攻击者可以跳出您的查询并执行自己的查询。

更多信息请参见owasp.org。

【讨论】:

unhex(0x31303235343830303536) 给出了“%H V”。可能是电话卡?这是一个非常大的数字——介于 2^78 和 2^79 之间。 可能是 mysqls max_int - 试图溢出? 附带说明,31303235343830303536 的 ASCII 表示是“1025480056”——在 ASCII 中,0x3n 是数字 n。 有点像死灵,但我想我不妨告诉你,0x31303235343830303536 是自动 SQL 注入工具 Havij 的名片。【参考方案4】:

这不是完整的查询,实际上是这个人在你的网络应用中输入了这个字符串。

现在,首先将联合部分中的 %20 替换为空格,你会得到:

SELECT concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--

似乎用户将字符串放在您期望数字的某个地方。因此,您看到首先有一个数字(999.9)来完成查询的原始条件。然后,添加一个 UNION 部分。 最后,在 UNION 部分之后,添加注释字符 (-- ),以便绕过查询的其余部分(可能正在由您的系统添加)。

我们可以格式化代码以便更好地理解:

SELECT 
    concat
    (
        0x7e,
        0x27,
        Hex(cast(database() as char)),
        0x27,
        0x7e
    ),
    0x31303235343830303536,
    0x31303235343830303536,
    0x31303235343830303536

现在,结果第一列的子字符串将包含您的数据库名称的十六进制编码形式。其实应该用单引号(0x27)括起来,然后再用~(0x7e)括起来

【讨论】:

【参考方案5】:
-999.9 UNION ALL SELECT 
CONCAT('Hex(cast(database() as char))'),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536

我认为你的日志中肯定还有其他条目,如果不是他事先知道你有 3 列。

【讨论】:

【参考方案6】:

这是使用 Havij 进行注入的示例 0x7e 和 0x27 对​​应于 ~ 和 ' ,它们将用于构建 HTML 显示 如 id=999999.9+union+all+select+0x31303235343830303536,(select+concat(0x7e,0x27,unhex(Hex(cast(sample_tbl.name+as+char))),0x27,0x7e)+from+test.sample_tbl+订单+by+id+limit+0,1)+-- 这个查询会从test表中的sample_tbl表中渲染~'Alfred'~是列名的字段值

~'r3dm0v3_hvj_injection'~是根据http://www.string-functions.com/hex-string.aspx的Havij签名码unhex 0x7233646D3076335F68766A5F696E6A656374696F6E

【讨论】:

他们在我的网站上尝试了相同的 MySQL 注入,但他们在页面上尝试了没有任何数据库查询,一切都基于文件:-)【参考方案7】:

是的,他得到了您所说的数据库名称的十六进制形式,即“74545883”。 通过 Unhexing,他将获得真正的数据库名称。

【讨论】:

以上是关于网站已通过 SQL 注入被黑客入侵的主要内容,如果未能解决你的问题,请参考以下文章

电脑被黑客入侵

网站被黑客入侵,js挂马无法清除。

Wordpress 网站不断被黑客入侵

和黑客斗争的 6 天

和黑客斗争的 6 天!

入侵网站的黑客被我抓到了!