You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mysql-connector-python中堆叠查询里Sleep()无法执行的问题

问题:MySQL堆叠查询中sleep()无法执行的解决方法

我在Django开发安全类CTF应用,要实现基于时间的盲SQL注入练习。因为Django的Model.raw()不支持堆叠查询,所以用了mysql-connector-python,通过cursor.execute(query, multi=True)执行堆叠查询,但发现堆叠里的sleep(X)不生效——比如执行select sleep(2); select 1;时响应时间只有0.005秒左右,单独执行select sleep(2);则正常耗时约2秒。试过do sleep(X)也不行,但这套堆叠查询在MySQL控制台和Workbench里能正常运行。我的实际需求是通过时间盲注从临时表逐字符读取文件(比如/etc/passwd),求解决办法。


相关代码与执行结果

堆叠查询场景代码

视图代码:

query = f"select sleep(2); select 1;"

mydb = mysql.connector.connect(
    host="localhost",
    user="****",
    password="****",
    database="****"
)

cursor = mydb.cursor()
cursor.execute(query, multi=True)

return HttpResponse(f"query: {cursor}")

测试脚本:

url = f"http://127.0.0.1:8080/books/book/?q=1"

start = time.perf_counter()
response = requests.get(f'{url}')
end = time.perf_counter()

print(response.text)
print(f'response time: {end-start}')

执行结果:

query: MySQLCursor: select sleep(2); select 1;
response time: 0.005476321006426588

单查询场景代码

视图代码:

query = f"select sleep(2);"

mydb = mysql.connector.connect(
    host="localhost",
    user="****",
    password="****",
    database="****"
)

cursor = mydb.cursor()
cursor.execute(query)

return HttpResponse(f"query: {cursor}")

测试脚本:

url = f"http://127.0.0.1:8080/books/book/?q=1"

start = time.perf_counter()
response = requests.get(f'{url}')
end = time.perf_counter()

print(response.text)
print(f'response time: {end-start}')

执行结果:

query: MySQLCursor: select sleep(2);
response time: 2.010241993004456

解决方案

1. 遍历所有查询结果

当使用multi=True执行堆叠查询时,mysql-connector-python默认只会初始化第一个查询,不会自动触发后续查询的实际执行。必须手动迭代cursor来执行所有语句,包括sleep()所在的查询:

query = f"select sleep(2); select 1;"

mydb = mysql.connector.connect(
    host="localhost",
    user="****",
    password="****",
    database="****"
)

cursor = mydb.cursor()
# 执行堆叠查询
results = cursor.execute(query, multi=True)
# 遍历所有结果集,触发每个查询的执行
for result in results:
    # 若为查询语句,可获取结果;无需结果时直接pass即可
    if result.with_rows:
        result.fetchall()

return HttpResponse(f"query: {cursor}")

这样sleep(2)会被实际执行,响应时间会符合预期。

2. 合并查询逻辑(替代堆叠)

如果不需要真正的堆叠,可将sleep逻辑合并到单个查询中,比如用条件判断触发sleep,无需开启multi=True:

# 示例:条件满足时触发sleep,适配时间盲注场景
query = f"select case when (substring((select load_file('/etc/passwd')),1,1)='r') then sleep(2) else 0 end;"
cursor.execute(query)

这种方式更贴合时间盲注的需求,避免堆叠查询的执行问题。

3. 检查连接配置

确保mysql-connector-python的连接参数无异常,可显式设置autocommit(虽对sleep执行影响不大,但能避免潜在的事务阻塞):

mydb = mysql.connector.connect(
    host="localhost",
    user="****",
    password="****",
    database="****",
    autocommit=True
)

内容的提问来源于stack exchange,提问作者NotACodER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:22:50