最近我的网站被SQL注入攻击了。黑客使用了以下查询 获取我的数据库名称。我无法理解他们写的这个查询。
查询:
=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
查询运行后显示整数结果,如“74545883
”。
您能解释一下查询的工作原理吗?
答案 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-
分解:
=-999.9
刚结束当前查询0x31303235343830303536
是NULL
- 它们只是匹配现有查询中的列数。如果您有SELECT * FROM users
且 users
有4列,则UNION
也必须包含4列。因此,他们只使用`NULL值来填充这些列。CONCAT()
。他们将126,39,数据库名称组合为十六进制值,39和126 --
是一条mysql注释 - 在从这次攻击判断,我怀疑你没有在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网站也有很多防御性编码资源:
答案 6 :(得分:-1)
是的,他有你的数据库名称的十六进制形式,你说是' 74545883'。 通过Unhexing它,他将拥有真正的数据库名称。