MySQL 网站已被 SQL 注入攻击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4600954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Site has been hacked via SQL Injection
提问by surezram
Recently my site was hacked via SQL injection. The hacker used the following query to get my DB name. I cannot understand this query they wrote.
最近我的网站被 SQL 注入攻击了。黑客使用以下查询来获取我的数据库名称。我无法理解他们写的这个查询。
Query:
询问:
=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
After the query was ran it showed an integer result, something like "74545883
".
查询运行后,它显示一个整数结果,类似于“ 74545883
”。
Can you explain how the query works?
你能解释一下查询是如何工作的吗?
回答by sethvargo
It looks like an overflow attack. They UNION
-ed with your existing query. replacing all your %20
with (space) since its url-encoded yields:
看起来像是溢出攻击。他们 - UNION
ed 与您现有的查询。用%20
(space)替换你的所有内容,因为它的 url 编码产生:
=-999.9 UNION ALL SELECT CONCAT(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536-
break it down:
分解一下:
- the
=-999.9
is just ending your current query 0x31303235343830303536
isNULL
- they are just matching the number of columns in your existing query. If you hadSELECT * FROM users
andusers
had 4 columns, theUNION
must also have 4 columns. As a result, they just used `NULL values to populate those columns.- the real confusion is in the
CONCAT()
. They are combining 126, 39, database name as hex value, 39, and 126 --
is a mysql comment - it ignores the rest of your query after
- 在
=-999.9
刚刚结束的当前查询 0x31303235343830303536
是NULL
- 它们只是匹配现有查询中的列数。如果您有SELECT * FROM users
并且users
有 4 列,则UNION
也必须有 4 列。结果,他们只是使用 NULL 值来填充这些列。- 真正的困惑在于
CONCAT()
. 它们组合了 126、39、数据库名称作为十六进制值、39 和 126 --
是一个 mysql 注释 - 它会在之后忽略您查询的其余部分
Judging from this attack, i suspect that you are not wrapping input in mysql_real_escape_string()
, which allowed to attacked to jump out of your query and execute their own.
从这次攻击来看,我怀疑您没有将输入包装在 中mysql_real_escape_string()
,这允许攻击跳出您的查询并执行自己的查询。
See owasp.orgfor more information.
有关更多信息,请访问 owasp.org。
回答by Sarwar Erfan
This is not the complete query, actually the person entered this string in your web app.
这不是完整的查询,实际上该人在您的 Web 应用程序中输入了此字符串。
Now, first replace %20 with blank space in the union part, you get:
现在,首先用联合部分中的空格替换 %20,你得到:
SELECT concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
Seems like the user put the string in some place where you were expecting an number. So, you see that first there is a number (999.9) to complete the original condition of the query. Then, an UNION part is added. Finally, after the UNION part, the comment characters are added (-- ) so that, the rest of the query (which might be being added by your system) is bypassed.
似乎用户将字符串放在您期望数字的某个位置。因此,您会看到首先有一个数字 (999.9) 来完成查询的原始条件。然后,添加了 UNION 部分。最后,在 UNION 部分之后,添加注释字符 (--),以便绕过查询的其余部分(可能由您的系统添加)。
We can format the code for better understanding:
我们可以格式化代码以便更好地理解:
SELECT
concat
(
0x7e,
0x27,
Hex(cast(database() as char)),
0x27,
0x7e
),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
Now, substring of the first column of the result will contain the hex encoded form of your datbase name. Actually, it should be surrounded by single quotes (0x27), then again surrounded by ~ (0x7e)
现在,结果第一列的子字符串将包含您的数据库名称的十六进制编码形式。实际上,它应该用单引号(0x27)包围,然后再用〜(0x7e)包围
回答by Adriaan Stander
The query returned the Database name using DATABASE() , it then converted this to a hex value using HEx()function.
查询使用DATABASE()返回数据库名称,然后使用HEx()函数将其转换为十六进制值。
Once they had this they could use UNHEXfunction
一旦他们有了这个,他们就可以使用UNHEX函数
Have a look at the UNHEX
examples
看看UNHEX
例子
mysql> SELECT UNHEX('4D7953514C');
-> 'MySQL'
mysql> SELECT 0x4D7953514C;
-> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
-> 'string'
mysql> SELECT HEX(UNHEX('1267'));
-> '1267'
It is good to know how they got in, but all in all, you need to fix up your code to avoid SQL Injection.
很高兴知道它们是如何进入的,但总而言之,您需要修复代码以避免 SQL 注入。
回答by Eric Fortis
-999.9 UNION ALL SELECT
CONCAT('Hex(cast(database() as char))'),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
I think you must have other entries in your log, if not he knew before hand that you have 3 columns.
我认为您的日志中必须有其他条目,否则他事先知道您有 3 列。
回答by Name
This is an exemple of injection using Havij
The 0x7e and 0x27 correspond to ~ and ' wich will be used to frame the HTML display
such as
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+Order+by+id+limit+0,1)+--
This query will render ~'Alfred'~ which is the field value of the column name, from the table sample_tbl in the table test
这是使用 Havij 的注入示例 0x7e 和 0x27 对应于 ~ 和 ' 将用于框架 HTML 显示如 id=999999.9+union+all+select+0x31303235343830303536,(select+concat(0x7e,0x (Hex(cast(sample_tbl.name+as+char))),0x27,0x7e)+from+ test
.sample_tbl+Order+by+id+limit+0,1)+-- 此查询将呈现 ~'Alfred'~是列名的字段值,来自表test中的表sample_tbl
~'r3dm0v3_hvj_injection'~ is the Havij signature code unhex 0x7233646D3076335F68766A5F696E6A656374696F6E according to http://www.string-functions.com/hex-string.aspx
~'r3dm0v3_hvj_injection'~ 是 Havij 签名代码 unhex 0x7233646D3076335F68766A5F696E6A656374696F6E 根据http://www.string-functions.com/hex-string.aspx
回答by bakoyaro
First off, the query looks like it's HTML encoded. Replace the %20
s with spaces and it will become a little more readable. Also they are converting part of the query into a hex representation of something. Try hexadecimal decoding that part of the statement as well.
首先,查询看起来像是 HTML 编码的。%20
用空格替换s,它会变得更具可读性。此外,他们正在将查询的一部分转换为某些内容的十六进制表示。也尝试对语句的那部分进行十六进制解码。
A SQL injection risk is created when you try to create a SQL dynamically as a string, and then send it to the DBMS. Imagine a string like this stored in your system for use in a search bar, etc:
当您尝试将 SQL 作为字符串动态创建,然后将其发送到 DBMS 时,就会产生 SQL 注入风险。想象一个这样的字符串存储在您的系统中以用于搜索栏等:
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN=
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN=
To complete the query and let the attack in, they would need to make their input like this:
为了完成查询并让攻击进入,他们需要像这样输入:
'x' or 1=1
'x' or 1=1
In that instance the query will become:
在这种情况下,查询将变为:
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN='x' or 1=1
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN='x' or 1=1
SOME_COLUMN
could be any variable, it doesn't matter where it fails, the thing that matters is that 1=1
is ALWAYS true, thereby potentially giving the attacker access to every row in that table.
SOME_COLUMN
可以是任何变量,它在哪里失败并不重要,重要的是它1=1
总是正确的,从而有可能让攻击者访问该表中的每一行。
Now that you know about it, go through your code and replace every dynamically created query with a Prepared Statements. The OWASP site has a lot of resources for defensive coding as well:
既然您知道了,请检查您的代码并将每个动态创建的查询替换为准备好的语句。OWASP 站点也有很多用于防御性编码的资源:
回答by Noname
Yes he has got the hex form of your database name which you say is '74545883'. By Unhexing it he would have got the real database name.
是的,他有你的数据库名称的十六进制形式,你说它是“74545883”。通过 Unhexing 它,他将获得真正的数据库名称。