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:使用双引号

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

相关推荐
KmSH8umpK几秒前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第五篇
数据库·redis·分布式
lilihuigz4 分钟前
企业培训网站搭建指南:5步在WordPress上创建品牌学院
数据库
WL_Aurora12 分钟前
MySQL 5 卸载到 MySQL 8 安装完整指南(不踩坑版)
数据库·mysql
灰阳阳15 分钟前
MySQL的基本架构
数据库·mysql·架构
@小柯555m34 分钟前
MySql(高级操作符--Where in 和Not in)
数据库·sql·mysql
许彰午35 分钟前
CacheSQL(一):手写数据库的工程化重生
java·数据库·缓存
MmeD UCIZ35 分钟前
MySQL单表存多大的数据量比较合适
数据库·mysql
SarL EMEN1 小时前
mysql之联合索引
数据库·mysql
l1t1 小时前
DeepSeek总结的DuckDB anofox-forecast季节调整时间序列预测插件功能
开发语言·数据库
meta INGU1 小时前
mysql数据被误删的恢复方案
数据库·mysql