第一章:SQL注入基础——你必须要搞懂的核心概念

大家好,我是老周。做渗透测试这些年,SQL注入一直是我最常碰到的漏洞类型。说实话,它虽然经典,但很多新手一上来就急着用工具,反而忽略了最基础的东西。今天咱们就把这块地基打牢。

1.1 什么是SQL注入?

SQL注入,说白了就是攻击者把恶意的SQL代码塞进输入框,骗过数据库去执行。我见过太多人把它想复杂了——其实原理很简单:你的程序没有对用户输入做严格过滤,导致数据库把输入当成了代码来执行。

核心定义:SQL注入是一种将恶意SQL语句插入到应用程序输入参数中,并在后端数据库服务器上执行的安全漏洞。

举个例子,一个登录页面让你输入用户名和密码。后台的SQL可能是这样的:

SELECT * FROM users WHERE username = '用户输入' AND password = '用户输入'

如果我在用户名里输入 admin' OR '1'='1,那SQL就变成了:

SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '随便输'

你看,OR '1'='1' 永远为真,整个查询就绕过了密码验证。我在项目中遇到过好几次,有些开发人员觉得「谁会这么输入啊」,结果就被打了脸。

1.2 SQL注入的危害有多大?

很多人觉得SQL注入就是「拖个库」而已。嗯,这只是冰山一角。我整理了一下实际危害:

  • 数据泄露:用户密码、身份证、银行卡号全被拿走。2017年Equifax数据泄露,影响1.4亿人,就是SQL注入干的。
  • 数据篡改:攻击者可以改你的订单金额、改你的账户余额。
  • 权限提升:从普通用户变成管理员,想干嘛干嘛。
  • 服务器沦陷:某些数据库支持执行系统命令,比如MySQL的 INTO OUTFILE 可以写webshell。

⚠️ 我曾经见过一个案例:某电商平台因为一个搜索框的SQL注入,导致整个服务器被拿下,黑客在服务器上挖了三个月矿才被发现。所以别小看任何一个输入点。

1.3 SQL注入的分类——GET/POST/Cookie注入

按数据提交方式,SQL注入主要分三类。我习惯用「数据从哪里来」来区分:

注入类型 数据来源 常见场景 检测方法
GET注入 URL参数 商品详情页?id=1 直接在浏览器地址栏改参数
POST注入 请求体 登录表单、搜索框 用Burp Suite抓包改数据
Cookie注入 HTTP请求头 记住登录状态、购物车 修改Cookie值再发包

你想想看,为什么要把Cookie单独列出来?因为很多开发人员只过滤了GET和POST参数,却忘了Cookie也能被篡改。我早期做渗透时就吃过这个亏——一个站怎么测都没漏洞,后来发现注入点在Cookie里。

1.4 SQL注入原理——数据库是怎么被「骗」的

原理其实就一句话:用户输入被拼接到SQL语句中,改变了原语句的语义。

正常的流程是这样的:

  1. 用户输入数据(比如商品ID)
  2. 程序把数据拼接到SQL模板里
  3. 数据库执行拼接后的完整SQL
  4. 返回结果给用户

问题出在第2步。如果用户输入的不是普通数据,而是SQL代码片段,那拼接后的SQL就「变味」了。

💡 我的理解方式:把SQL语句想象成一句话,用户输入是填空的词。如果填的是「苹果」,句子是「我吃了一个苹果」。但如果填的是「苹果;删除所有数据」,句子就变成了「我吃了一个苹果;删除所有数据」——数据库会执行两个语句。

1.5 常见数据库的差异——MySQL vs MSSQL vs Oracle

做SQL注入,不同数据库的「脾气」不一样。我整理了一张对比表,建议你收藏:

特性 MySQL MSSQL (SQL Server) Oracle
注释符 -- # -- --
字符串连接 CONCAT()|| + ||CONCAT()
查询版本 @@versionVERSION() @@VERSION SELECT banner FROM v$version
获取表名 information_schema.tables sysobjects all_tables
报错注入 extractvalue()updatexml() convert()cast() ctxsys.drithsx.sn()
堆叠查询 支持(需PHP等支持多语句) 默认支持 不支持(默认)

这里有几个坑,我踩过:

  • MySQL的注释符# 是MySQL独有的,MSSQL和Oracle不认识。所以用SQLMap时,如果目标数据库是MySQL,它会自动用 # 注释,但换到MSSQL就会报错。
  • Oracle的dual表:Oracle查询必须带 FROM,所以测试时要用 SELECT 1 FROM dual。我第一次测Oracle时,直接写 SELECT 1,结果报错半天没反应过来。
  • MSSQL的堆叠查询:默认支持多条语句用分号隔开,比如 SELECT * FROM users; DROP TABLE orders。MySQL需要看驱动是否支持,PHP的mysql扩展就不支持多语句。

实战建议:拿到一个注入点,第一步不是急着跑数据,而是先判断数据库类型。我一般用三个方法:看报错信息、看注释符是否生效、看 version() 函数的返回。SQLMap虽然能自动识别,但手动确认更靠谱。

1.6 本章知识体系图

下面这张图是我自己画的,把本章的核心知识点串起来了。你可以把它当成一张「地图」,以后遇到SQL注入问题,先看这张图定位:

SQL注入基础 · 知识体系 SQL注入 定义:恶意SQL代码拼接到查询语句中执行 危害:数据泄露 · 篡改 · 权限提升 · 服务器沦陷 分类 GET注入(URL参数) POST注入(请求体) Cookie注入(请求头) 原理:用户输入改变SQL语句语义 常见数据库差异 MySQL(#注释、information_schema) MSSQL(+连接、sysobjects) Oracle(dual表、all_tables)

💡 怎么用这张图?每次做SQL注入测试前,先看一遍这张图。从「定义」出发,确认自己理解原理;再看「分类」,判断当前测试点属于哪一类;最后看「数据库差异」,选对payload。我自己的习惯是把它打印出来贴在工位上。

1.7 本章小结

这一章我们聊了SQL注入的四个核心问题:它是什么、有什么危害、分哪几类、不同数据库有什么区别。说实话,这些基础概念决定了你后面能不能用好SQLMap。我见过太多人一上来就 sqlmap -u url,结果连报错信息都看不懂——就是因为没搞懂数据库差异。

下一章我们会开始动手,用SQLMap做第一次注入测试。但在此之前,我建议你把本章的数据库差异表背下来,尤其是注释符和系统表的区别。嗯,这是基本功,绕不过去的。


公众号:蓝海资料掘金营,微信 deep3321