SQL注入漏洞原理

漏洞产生的根本原因

核心问题:用户输入与数据库交互

php 复制代码
// 安全代码(数据写死)
$sql = "SELECT * FROM table1 WHERE id < 4";

上述代码没有漏洞,因为查询条件是固定的。

php 复制代码
// 存在漏洞的代码(用户可控)
$id = $_GET['id'];
$sql = "SELECT * FROM table1 WHERE id < $id";

当用户可以控制查询参数时,就可能产生SQL注入漏洞。

漏洞触发条件

用户输入场景

  • GET参数:?id=4
  • POST表单提交
  • Cookie值
  • HTTP头部信息

危险操作

php 复制代码
// 带引号的参数
$sql = "SELECT * FROM table1 WHERE username='$username'";

如果用户输入包含单引号:

复制代码
?username=admin' OR '1'='1

实际执行的SQL变成:

sql 复制代码
SELECT * FROM table1 WHERE username='admin' OR '1'='1'

破坏引号闭合

复制代码
?id=4'
?id=4\

这些输入会破坏SQL语句结构,导致:

  • 数据库报错
  • 泄露数据库结构信息
  • 执行恶意SQL语句

生产环境与实验环境差异

PHPStudy实验环境

  • 默认关闭错误显示
  • 便于学习和测试
  • 不会暴露敏感信息

靶场环境

  • 故意开启错误显示
  • 方便学习漏洞利用
  • 模拟不安全的配置

生产环境

  • 应该关闭错误显示
  • 记录日志但不向用户展示
  • 使用通用错误页面

SQL注入实战案例

靶场地址:sqliabs.njhack.xyz

测试目标: 获取数据库中的所有用户信息

基础测试

复制代码
http://sqliabs.njhack.xyz/?id=2
http://sqliabs.njhack.xyz/index.php?id=2

攻击思路

  1. 判断注入点存在性
  2. 确定字段数量
  3. 获取数据库信息
  4. 提取表名和字段名
  5. 导出敏感数据

代码层面的漏洞分析

后端处理逻辑

php 复制代码
<?php
$id = $_GET['id'];
$sql = "SELECT username, password FROM table1 WHERE id = $id";
$result = $conn->query($sql);
?>

正常请求

复制代码
?id=1
执行:SELECT username, password FROM table1 WHERE id = 1

恶意请求

复制代码
?id=1 OR 1=1
执行:SELECT username, password FROM table1 WHERE id = 1 OR 1=1
结果:返回所有记录

估算目标数据库语法

数据库语法差异: 不同数据库有不同的SQL方言:

  • MySQL:使用反引号、LIMIT语法
  • SQL Server:使用方括号、TOP语法
  • Oracle:使用ROWNUM
  • PostgreSQL:使用双引号

判断数据库类型: 通过错误信息、特定函数、语法差异来判断。

相关推荐
ptc学习者7 小时前
黑格尔时代后崩解的辩证法
数据库
代码游侠7 小时前
应用——智能配电箱监控系统
linux·服务器·数据库·笔记·算法·sqlite
!chen8 小时前
EF Core自定义映射PostgreSQL原生函数
数据库·postgresql
霖霖总总8 小时前
[小技巧14]MySQL 8.0 系统变量设置全解析:SET GLOBAL、SET PERSIST 与 SET PERSIST_ONLY 的区别与应用
数据库·mysql
马克学长8 小时前
SSM校园食堂订餐系统531p9(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·ssm 校园食堂订餐系统
alonewolf_998 小时前
深入剖析MySQL索引底层:B+树、联合索引与跳跃扫描原理全解
数据库·b树·mysql
oMcLin8 小时前
如何在 AlmaLinux 9 上配置并优化 Redis 集群,支持高并发的实时数据缓存与快速查询?
数据库·redis·缓存
洛阳纸贵8 小时前
Redis
数据库·redis·缓存
l1t9 小时前
DeepSeek辅助编写的利用位掩码填充唯一候选数方法求解数独SQL
数据库·sql·算法·postgresql