SQL 注入漏洞研究
SQL 注入漏洞研究
SQL 注入漏洞研究
一、SQL注入的原理
1.1 定义
1.2 漏洞代码示例
1.3利用SQL注入可以做什么(危害)
二、SQL注入的分类
2.1 按传递参数类型划分
2.2 以回显的方式划分
三、SQL注入的方法
3.1 逐字猜解法
3.2 联合查询法
3.3 盲注
3.3.1 MySQL盲注关键函数
3.3.2 基于时间的盲注
3.3.3 基于布尔型的盲注
3.4报错注入
3.4.1 duplicate entry '1' for key 'group_key'报错注入
3.4.1.1 理解floor(rand(0)*2)函数
3.4.1.2 理解group by [column_name]函数
3.4.1.3 报错的原因分析
3.4.1.4 基于此种类型报错信息常用注入语句
3.5 宽字节注入(sqli-labs less-32)
3.5.1 基本知识
3.5.2 绕过转义字符,进行注入
3.6 命令注入
3.6.1
SQL基本知识补充
一、SQL结构化查询语言
二、数据库的常用注释符
三、MySQL数据库基础
3.1 MySQL内置的information_schema数据库结构
3.1.1 schemata:存取数据库命的表
3.1.2 tables:存数据库以及数据库中的表名
3.1.3 columns:存取数据库、表、以及表中的字段
3.2 MySQL注入常用函数和语句
3.2.1 查询服务器主机信息
3.2.2 查询数据库版本信息
3.2.3 查询数据库用户信息
3.2.4 枚举数据库内容
3.2.5 联合查询语句
3.3 concat,concatws,groupconcat函数
3.3.1 concat()和concat_ws()
3.3.2 group_concat()
一、SQL注入的原理
1.1 定义
当应用程序将用户输入的内容拼接到SQL语句中,一起提交给数据库的时候,就会产生SQL注入威胁。
1.2 漏洞代码示例
1.3利用SQL注入可以做什么(危害)
-通过sleep,benchmark等函数时数据库阻塞不能正常工作
(4)文件系统操作:列目录,读取、写入文件(一句话木马)等等。
二、SQL注入的分类
2.1 按传递参数类型划分
-例如:id=1 ,数字型注入不需要考虑单引号或者双引号闭合
-例如:name='bob',字符型注入需要考虑单引号的闭合和注释问题。
2.2 以回显的方式划分
-回显正常:通过执行构造的SQL注入语句之后,页面与原页面存在差异,但是没有报错信息。
-回显报错:通过执行构造的SQL注入语句之后,页面报错并且将报错信息显示在页面上。
-基于时间的盲注:构造SQL语句之后根据页面的响应时间来判断。
三、SQL注入的方法
3.1 逐字猜解法
3.2 联合查询法
3.3 盲注
盲注:即在SQL注入过程中,SQL语句执行选择后,选择的数据不能回显到前端,需要使用一些特殊的方式进行判断或者尝试,这个过程称为"盲注"。
3.3.1 MySQL盲注关键函数
(1)count([column_name]) 返回指定列的值的数目(NULL不计入)
(2)limit(m,n) m代表从m+1条记录开始检索,n代表取出n条数据。(m可以设为0)
(4)mid(),substr(),substring(),left()
说明:这四个都是字符串截取函数,其中前三个的用法是一致的。这里以mid()为例进行介绍。
mid(string,start,length) 每个参数的含义如下:
-length(可选)要返回的字符数。如果省略,则返回剩余的全部文本。
3.3.2 基于时间的盲注
3.3.3 基于布尔型的盲注
3.4报错注入
3.4.1 duplicate entry '1' for key 'group_key'报错注入
select count(*),floor(rand(0)*2)x from information_schema.character_sets group by x;
说明:利用上边语句可以导致数据库进行报错,通过concat函数连接注入语句与floor(rand(0)*2)函数,从而实现将注入结果与报错信息回显到前端页面。
3.4.1.1 理解floor(rand(0)*2)函数
-rand(0) 用于产生0(包含)-1(不包含)的随机数,如果没有参数,那么产生的随机数是随机的并且不可重复的。如果带了参数,例如:rand(2),相当于制定了随机数产生的种子,产生的随机数可重复。
3.4.1.2 理解group by [column_name]函数
3.4.1.3 报错的原因分析
通过floor报错的方法来爆数据的本质是group by语句的报错。group by语句报错的原因是floor(random(0)*2)的不确定性,即可能为0也可能为1。
实际测试中发现,出现报错,至少要求数据记录为3行,记录数超过3行一定会报错,2行时是不报错的。
3.4.1.4 基于此种类型报错信息常用注入语句
select count(*),floor(rand(0)*2)x from information_schema.schemata group by x;
3.5 宽字节注入(sqli-labs less-32)
3.5.1 基本知识
许多字符的集合,这些字符组成一套符号系统,可以组合起来形象的表达各种含义
编码:对字符赋予一个数值(encoding) 来确定这个字符在该字符集中的位置。
Unicode字符集等(通用多八位编码字符集,支持各种不同语言的书面文本的交换、处理及显示)
ASCII、GB2312、ANSI、UTF-8、UNICODE
GBK:这是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,及不论中英文字符都使用双字节来表示,为了区分中文,将其最高位都设定成1。
编码建议:程序都使用Unicode编码,网站都是用UTF-8编码。
3.5.2 绕过转义字符,进行注入
MySQL特性:MySQL 在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ASCII码要大于128,GBK的汉字的范围)。
实际上,只要编码值大于128,均可以实现吃掉\。例如%81,%82, %83等等。
原理: %e5 \ ' (即%e5%5c%27)>%e5%5c%5c%5c%27 >錦 \ \ ',这样反斜杠就被转义了。
3.6 命令注入
3.6.1
SQL基本知识补充
一、SQL结构化查询语言
二、数据库的常用注释符
数据库 | 注释符 | 描述 |
SQL Server、Oracle | -- | 用于单行注释 |
SQL Server、Oracle | /**/ | 用于多行注释 |
MySQL | -- | 用于单行注释,要求后边必须跟一个空格符 |
MySQL | # | 用于单行注释 |
MySQL | /**/ | 用于多行注释 |
三、MySQL数据库基础
3.1 MySQL内置的information_schema数据库结构
3.1.1 schemata:存取数据库命的表
mysql> select schema_name from information_schema.schemata;
3.1.2 tables:存数据库以及数据库中的表名
mysql> select table_name from information_schema.tables where table_schema = 'dvwa';
3.1.3 columns:存取数据库、表、以及表中的字段
3.2 MySQL注入常用函数和语句
3.2.1 查询服务器主机信息
3.2.2 查询数据库版本信息
3.2.3 查询数据库用户信息
(2)current_user() 当前登陆用户和登录用户主机名
(3)system_user() 数据库系统用户账户名称和登陆主机名
(4)session_user() 当前会话用户名和登陆主机名
3.2.4 枚举数据库内容
3.2.5 联合查询语句
(1)order by n //判断当前查询结果的列数,配合union使用
(2)order by n+1 //让n一直增加,直到出现错误的页面
(3)union //联合查询 例如:union select
注意:使用union select 联合查询的时候,前后查询语句的回显列数要一致!
3.3 concat,concatws,groupconcat函数
说明:利用这三个函数,可以将注入的结果更好的回显到前端页面。
3.3.1 concat()和concat_ws()
(1)concat(str1,str2,...) 没有分隔符,串联多列结果
(2)concat_ws([分隔符号],str1,str2,...) 含有分隔符,串列多列结果