网站已被SQL注入攻击

时间:2011-01-05 04:57:30

标签: mysql sql-injection

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

查询:

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

查询运行后显示整数结果,如“74545883”。

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

7 个答案:

答案 0 :(得分:19)

看起来像overflow attack。他们UNION - 使用您现有的查询。用url编码的结果替换所有%20和(空格):

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

分解:

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

    从这次攻击判断,我怀疑你没有在mysql_real_escape_string()中包含输入,这允许攻击跳出你的查询并执行他们自己的。

    有关详细信息,请参阅owasp.org

答案 1 :(得分:5)

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

现在,首先用联合部分中的空格替换%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)包围

答案 2 :(得分:3)

查询使用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注入。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

这是使用Havij注射的例子 0x7e和0x27对应于〜,'wich将用于构建HTML显示 如 ID = 999999.9 +工会+ +所有选择+ 0x31303235343830303536,(选择+的concat(0x7e格式,0×27,UNHEX(十六进制(铸造(sample_tbl.name +为+炭))),0x27,0x7e)+从+ test。 sample_tbl +订单+由+ ID +极限+ 0,1)+ - 此查询将从表test的表sample_tbl中呈现~'Alfred'〜这是列名的字段值

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

答案 5 :(得分:0)

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

当您尝试以字符串形式动态创建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始终为真,从而可能让攻击者访问该表中的每一行。

现在您已了解它,查看代码并使用Prepared Statements替换每个动态创建的查询。 OWASP网站也有很多防御性编码资源:

www.owasp.org

答案 6 :(得分:-1)

是的,他有你的数据库名称的十六进制形式,你说是' 74545883'。 通过Unhexing它,他将拥有真正的数据库名称。