Mysql 该网站已通过SQL注入遭到黑客攻击

Mysql 该网站已通过SQL注入遭到黑客攻击,mysql,sql-injection,Mysql,Sql Injection,最近我的网站被SQL注入攻击。黑客使用了以下查询 获取我的数据库名。我无法理解他们写的这个问题 查询: =-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536-- 运行查询后,它显示一个整数结果,类似于“74545883” 你

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

查询:

=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
运行查询后,它显示一个整数结果,类似于“
74545883


你能解释一下查询是如何工作的吗?

首先,查询看起来像是HTML编码的。将
%20
s替换为空格,它将变得更具可读性。此外,他们正在将查询的一部分转换为某种东西的十六进制表示形式。也可以尝试对语句的这一部分进行十六进制解码

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

从一些表格中选择*,其中一些列=

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

'x'或1=1

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

从某个表格中选择*,其中某个列='x'或1=1

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

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


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

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

请看
UNHEX
示例

mysql> SELECT UNHEX('4D7953514C');
        -> 'MySQL'
mysql> SELECT 0x4D7953514C;
        -> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
        -> 'string'
mysql> SELECT HEX(UNHEX('1267'));
        -> '1267'
很高兴知道它们是如何进入的,但总而言之,您需要修改代码以避免SQL注入。

这看起来像是一个错误。它们与您现有的查询相结合。将所有
%20
替换为(空格),因为其url编码产生:

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

  • =-999.9
    刚刚结束您当前的查询
  • 0x31303235343830303536
    NULL
    -它们只是与现有查询中的列数匹配。如果有
    SELECT*FROM users
    users
    有4列,则
    UNION
    也必须有4列。结果,他们只是使用`空值'来填充这些列
  • 真正的困惑在于
    CONCAT()
    。它们将126、39、数据库名称组合为十六进制值、39和126
  • --
    是一条mysql注释-它会忽略查询之后的其余部分
  • 从这次攻击判断,我怀疑您没有在
    mysql\u real\u escape\u string()
    中包装输入,这使得被攻击的用户可以跳出您的查询并执行自己的查询


    有关更多信息,请参阅。

    这不是完整的查询,实际上是用户在web应用程序中输入了此字符串

    现在,首先用联合部件中的空格替换%20,您将得到:

    SELECT concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
    
    似乎用户将字符串放在了您期望的某个位置。因此,您可以看到,首先有一个数字(999.9)来完成查询的原始条件。然后,添加一个联合零件。 最后,在联合部分之后,添加注释字符(-),以便绕过查询的其余部分(可能由您的系统添加)

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

    SELECT 
        concat
        (
            0x7e,
            0x27,
            Hex(cast(database() as char)),
            0x27,
            0x7e
        ),
        0x31303235343830303536,
        0x31303235343830303536,
        0x31303235343830303536
    
    现在,结果第一列的子字符串将包含datbase名称的十六进制编码形式。实际上,它应该被单引号(0x27)包围,然后再被~(0x7e)包围


    我想你的日志中一定有其他条目,如果没有的话,他事先知道你有3列。

    这是使用Havij进行注入的一个示例 0x7e和0x27对应于~和',用于框显HTML显示 比如 id=9999999.9+union+all+select+0x31303235343830303536,(select+concat(0x7e,0x27,unhex(十六进制(cast(sample_tbl.name+as+char))),0x27,0x7e)+from+
    测试
    。sample_tbl+Order+by+id+limit+0,1)+-- 此查询将从表test中的表sample_tbl中呈现列名的字段值~'Alfred'~


    “r3dm0v3_hvj_injection”是Havij的签名码unhex 0x7233646D3076335F68766A5F696E6A656374696F6E根据

    是的,他得到了您数据库名称的十六进制形式,您说是“74545883”。
    通过取消勾选,他将获得真实的数据库名称。

    请不要签署您的查询,我们知道您是谁,这是您日志中唯一的条目?请不要签署您的查询-有一刻,我想知道签署mysql查询意味着什么:)问题中的查询哈。。。我会编辑它,因为它的模糊性(0x31303235343830303536)给出了“%hv”。也许是电话卡?这是一个非常大的数字-介于2^78和2^79之间。可能是mysqls max_int-试图溢出?作为旁注,31303235343830303536的ASCII表示形式是“1025480056”--在ASCII中,0x3n是数字n。有点像necro,但我想我还是告诉你0x31303235343830303536是Havij的名片,一个自动SQL注入工具。@astander-他问查询是如何工作的。我将其解释为“他们是如何绕过我的(缺乏)预防的”,而不是“这里的每个功能都做了什么”。我觉得一个人应该能够对“mysql十六进制”执行google查询,但新手可能不习惯于逃避查询和常见的mysql注入尝试,是吗?google“mysql十六进制”会告诉他函数的功能(就像你链接的那样),但google“mysql注入”不会告诉他为什么他的特定查询被黑客攻击……他们在我的网站上尝试了相同的MySQL注入,但他们在没有任何数据库查询的页面上进行了尝试,一切都基于文件:-)
    -999.9 UNION ALL SELECT 
    CONCAT('Hex(cast(database() as char))'),
    0x31303235343830303536,
    0x31303235343830303536,
    0x31303235343830303536