本文是学习SQL注入的笔记和部分总结,详细的写了我认为重要的一些东西

目录

SQL注入漏洞基础

我们为什么要了解SQL注入漏洞

SQL注入原理

注入过程

注入方法

数字型注入

字符型注入

MySQL数据库的使用

MySQL的常用语句

元数据库

常用函数

注入手法

联合查询

案例:利用联合查询获取用户名和密码

报错注入

布尔盲注

延时注入


SQL注入漏洞基础

我们为什么要了解SQL注入漏洞

SQL注入漏洞(SQL Injection)是很高危的漏洞之一,通过OWASP top 10可以看到,注射漏洞仍排在榜首的位置,这就说明了它的危害性之高

SQL注入原理

攻击者利用SQL语句或字符串将非法数据插入到服务器端数据库中,以获取管理用户的权限,将数据库管理用户的权限进一步提高至操作系统管理用户权限,控制服务器操作系统,获取重要信息及机密文件

注入过程

  1. 发现注入点
  2. 收集数据库信息
  3. 获取用户名密码
  4. 寻找后台管理入口
  5. 查看数据库中的内容

注入方法

数字型注入

输入参数一般为整形,如ID、页码等

假设URL为:HTTP://www.example/test.php?id=1

可以猜测,SQL语句有可能为 select * from table_test where id = 1

①如果在URL后加一个单引号 ,HTTP://www.example/test.php?id=1'

    此时,SQL语句变为 select * from table_test where id = 1',多了一个单引号,语句自然会出错,页面就会回显异常

②在URL后加 and 1 = 1,HTTP://www.example/test.php?id=1 and 1 = 1

    此时,SQL语句变为 select * from table_test where id = 1 and 1 = 1,因为and前后都为真,语句不会出错,页面回显正常

    将 and 1 = 1改为and 1 = 2,HTTP://www.example/test.php?id=1 and 1 = 2

    此时,SQL语句变为 select * from table_test where id = 1 and 1 = 2,因为and前为真,后为假,语句执行正常,页面却会出现错误

此类数字型注入多出现在ASP、PHP等弱类型语言中

字符型注入

输入参数一般为字符串,与数字型不同,字符串类型多需要单引号来闭合

可以猜测,字符型SQL语句可能为 select * from table_test where username =  'admin'

①如果注入时输入 admin and 1 = 1,此时SQL语句如下

    select * from table_test where username = 'admin and 1 = 1'

    所以我们可以在admin后加一个单引号并在最后加上注释符-- ,让它与之前的单引号进行闭合并注释掉多余的单引号

    输入 admin' and 1 = 1 --       

    select * from table_test where username = 'admin' and 1 = 1 -- '

当然按照数据提交方式来分的话,还可以分为GET注入、POST注入、COOKIE注入等等,与上述两种注入方法相比,也就是展现形式不同,就是将猫又叫了个咪

MySQL数据库的使用

常用的三种数据库的注入,即SQL Server、MySQL、Oracle的注入,虽然是三种不同的数据库,但注入思路都是相同的,仅仅是不同的数据库语句有些许不同,所以,以MySQL为例进行说明

MySQL的常用语句

数据库创建;数据库查看;

使用数据库;创建一个新表(id和name为表的字段名);查看数据库中的所有表;

给表中插入数据;查表

更改表的内容

删除表中的内容

删除表;删除数据库

元数据库

查询用户数据库名称

select SCHEMA_NAME from INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1

意思是:从INFORMATION_SCHEMA.SCHEMATA表中查询出第一个数据库名称

查询当前数据库表

select TABLE_NAME from INFORMATION_SCEMA.TABLES where TABLE_SCHEMA = (select DATABASE()) limit 0,1

意思是:从INFORMATION_SCEMA.TABLES表中查询当前数据库表,并且只显示第一条数据

查询指定表的所有字段

select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'cms' LIMIT 0,1

意思是:从INFORMATION_SCHEMA.COLUMNS表中查询TABLE_NAME是cms的字段名,并且只显示第一条数据

常用函数

以下两种需要有相应权限

load_file()函数读文件操作

into outfile()写文件

concat()函数    连接字符串    语法:concat(str1,'分隔符', str2,'分隔符', str3...)  也可不指定分隔符

concat_ws()函数    连接字符串,可一次性指定分隔符    语法:concat_ws('分隔符', str1, str2, ...)

group_concat()函数    分组聚合  

length()    返回字符串长度

hex()    将字符串转化成16进制

ascii    返回ASCII码值

注入手法

联合查询

数据库中的内容可以回显到页面

使用union select语句,生成两张虚拟表,将结果纵向拼接

语句:···?id=1 union select 1,2,3···

使用条件:

  • 两张虚拟表具有相同的列数
  • 虚拟表对应的列数据类型相同(数字可以代表任何数据类型)

案例:利用联合查询获取用户名和密码

所使用是搭建的供练习的环境,请勿在现实中使用本文所讲的方法不要试图挑战法律的底线

因为拼接的表必须列数相同,所以需要知道表有多少列

利用order by,order by 20页面报错,说明没有20列

接下来可尝试10列,如果报错,则没有10列;若未报错,则接下来可尝试15列,直到找到正确的列数

最后成功测试出有15列,则在union select后写15个数字,查看页面回显

可将3和11换成SQL语句,查询敏感信息

换成version()和database(),页面回显了版本信息和数据库

利用元数据库和group_concat获取表名

将16进制转化成字符串

找到有利用价值的表,获取该表的字段名

用concat_ws函数将字符串拼接

得到用户名和密码

密码通过md5解密

在线md5解密网站

报错注入

使用错误显示信息,可以通过一些异常将字符串消息提取出来

此处记住一些经典语句即可,有兴趣可以查看下列连接

https://www.freebuf/column/158705.html

布尔盲注

数据库名称长度

在URL后添加布尔值,查看页面回显是否正常来推断想要的信息

例如URL为:HTTP://www.example/test.php?id=1

可在后添加 HTTP://www.example/test.php?id=1 and length(database()) < 20 --+

如果数据库长度<20,页面会正常回显,否则,会出现异常,由此可判断出数据库名称的长度

数据库名

在后添加 HTTP://www.example/test.php?id=1 and ascii(substr(database(),2,1)) > 100 --+

意为,数据库名称,从第2个字符开始取,取1个,判断这个字符的ASCII码值是否大于100(可取>、<、=)

经过数次判断,最终可得到数据库名称

延时注入

例如URL为:HTTP://www.example/test.php?id=1

数据库名称长度

可在后面添加 HTTP://www.example/test.php?id=1 and if(length(database()) < 20,sleep(5),1) --+

意为,如果数据库名称长度小于20,返回页面时产生5秒延迟

数据库名

可在后添加 HTTP://www.example/test.php?id=1 and if(ascii(substr(database(),2,1)) > 100,sleep(5),1) --+

意为,数据库名称,从第2个字符开始取,取1个,判断这个字符的ASCII码值是否大于100(可取>、<、=)

经过数次判断,最终可得到数据库名称

联合查询、报错注入、布尔盲注、延时注入的成本依次提高,所以,在手注时,前面的有用时能用前面的就用前面的

 

 

 

 

 

 

 

更多推荐

2020年了,还要学习SQL注入吗?