SQL注入五步法:从入门到精通

张开发
2026/4/20 23:52:50 15 分钟阅读

分享文章

SQL注入五步法:从入门到精通
前言本文介绍了sql注入解题步骤总结链接了sqli-labs的相关内容怎么部署 sqli-LabsSQL 注入练习靶场及less1、2讲解-CSDN博客sql注入简介SQL注入SQL Injection简称SQLi是Web安全领域最著名、最危险的漏洞之一。简单来说它就像是黑客利用你网站的输入框直接对后台数据库下达了“非法指令”。为了让你更全面地了解它我为你整理了以下核心要点1. 什么是 SQL 注入想象一下你去餐厅点菜菜单上写着“今日特价鱼”。正常情况你告诉服务员“我要鱼”服务员去厨房下单。SQL注入你告诉服务员“我要鱼把厨房炸了”。如果服务员应用程序傻傻地把这句话原封不动传给厨房数据库厨房可能真的会执行“炸厨房”的操作。技术定义攻击者在Web表单、URL参数等输入区域插入恶意的SQL命令欺骗数据库服务器执行非授权的查询或操作。2. 核心原理为什么会被注入根本原因在于“数据与代码未分离”。开发人员为了方便直接将用户的输入拼接到SQL语句中而没有进行过滤或验证。正常代码逻辑SELECT * FROM users WHERE username admin AND password 123456被注入后的逻辑假设密码框输入了 OR 11SELECT * FROM users WHERE username admin AND password OR 11由于11永远为真黑客无需知道密码即可登录。3. 它有什么危害SQL注入的危害极大通常被称为“拖库”或“删库跑路”的元凶危害类型具体后果数据泄露窃取用户名、密码、身份证号、信用卡信息等敏感数据。数据篡改修改账户余额、权限甚至植入后门账号。数据删除清空数据库表导致业务瘫痪删库。服务器控制在特定配置下通过数据库执行系统命令完全控制服务器。4. 常见的注入类型根据攻击手法和回显情况主要分为以下几类联合查询注入利用UNION操作符把黑客的查询结果和正常结果拼在一起显示。这是最常见、最基础的类型如你之前练习的 Less-1。报错注入故意让数据库报错通过错误信息把数据“吐”出来。盲注页面不显示数据也不报错黑客通过页面内容的“真/假”变化布尔盲注或页面响应的时间长短时间盲注来一点点猜解数据。堆叠注入一次执行多条SQL语句如; DROP TABLE users危害极大。5. 如何防御防御SQL注入的核心原则是永远不要信任用户的输入。使用预编译语句这是最有效的防御手段。它会让数据库把SQL指令和数据分开处理数据只会被当作纯文本不会被当作命令执行。输入验证严格检查用户输入的类型如ID必须是数字、长度和格式。最小权限原则连接数据库的账号不要给root或sa权限只给必要的读写权限。6. 真实案例SQL注入历史悠久造成了无数重大安全事故2017年 Equifax 数据泄露导致1.47亿用户的个人信息包括社保号泄露损失超7亿美元。2014年 索尼影业被黑黑客利用SQL注入窃取了未发布的电影、员工薪资和内部邮件。总结来说SQL注入是Web安全的必修课。大致解题步骤 标准化解题“五步法”你可以根据这个流程来解题第一步探测找注入点操作加单引号加双引号加and 11/and 12。目的判断是数字型还是字符型是否需要闭合符号。判断是报错显示能看到错误信息还是盲注页面没变化。第二步猜列数Order By操作order by 3--order by 4--...目的确定查询结果有几列。如果不一致页面会报错。Payloadid1 order by 3--第三步找显示位Union Select操作让前面的查询结果为空用-1或99999然后拼接union select。目的看页面上显示的是第几个数字比如页面显示了 2 和 3那你后面查数据库就要把函数放在第 2 或 3 的位置。Payloadid-1 union select 1,2,3--第四步爆库爆表Information_Schema操作利用显示位查询系统表。Payload爆表名-1 union select 1, group_concat(table_name), 3 from information_schema.tables where table_schemadatabase()--(注意你之前的步骤里写的是schema建议直接写database()这样不用自己猜库名)第五步爆字段爆数据操作知道了表名去查列名知道了列名去查数据。Payload爆列名-1 union select 1, group_concat(column_name), 3 from information_schema.columns where table_nameusers--Payload爆数据-1 union select 1, username, password from users--新手学习sql注入中会想到的问题对的对的我就是新手如何分辨 SQL 注入的难易程度并不需要你从最简单的一个个试到难的通常“一下就能看出来”或者通过简单的“报错测试”就能确定方向。所谓的“难”与“容易”主要取决于注入点的数据类型和闭合方式。看 URL 参数形式最直观的判断容易数字型如果 URL 是id1这种纯数字形式通常是最简单的数字型注入。你不需要猜测闭合符号单引号还是双引号直接构造 SQL 逻辑即可。中等字符型如果 URL 是id1或usernameadmin你需要先判断是用单引号、双引号还是括号()来闭合。困难搜索型/特殊型如果参数看起来像搜索词或者包含复杂的编码可能需要尝试%、_或者特定的闭合方式。使用“报错法”快速探测核心技巧拿到一个注入点不要瞎猜直接加一个单引号或者输入and 12看反应报错Error Based页面上直接出现了 SQL 语法错误提示如You have an error in your SQL syntax。这是最容易的因为数据库直接告诉你它的语法结构是什么甚至有时候会直接告诉你数据库版本。无报错但内容消失Union Based页面空白或提示“找不到内容”但没有 SQL 错误代码。这说明注入成功但被后台屏蔽了错误显示你需要用UNION联合查询。页面完全一样Blind/Boolean Based无论怎么改页面看起来都一样只有细微差别比如文字少了一行。这比较难需要通过“真假”逻辑布尔盲注或“时间延迟”时间盲注来猜解。总结看到id数字且加了单引号报错通常是字符型看到id数字加了单引号报错但加and 11正常通常是数字型。Payload是什么通俗点说Payload 就是“特制的武器”或“特殊的钥匙”。在 SQL 注入里它指的就是那一串包含恶意代码的字符串。举个最简单的例子假设网站的登录框代码逻辑是这样的SELECT * FROM users WHERE username 这里是你输入的内容;普通输入正常钥匙你输入admin。数据库执行SELECT * FROM users WHERE username admin;这是正常的只查 adminPayload特制武器你输入admin #。这串字符admin #就是Payload。数据库执行SELECT * FROM users WHERE username admin #;#后面的内容被注释掉了密码验证失效你直接登录了总结Payload 用来欺骗数据库、让它乖乖听话的那串代码。简单的题我可不可以直接记payload完全可以。在 SQL 注入里Payload 其实就是固定的“公式”尤其是像 Less-1 和 Less-2 这种基础关卡直接背下来能帮你省下大量的推导时间。对于你正在做的Less-2数字型注入你只需要记住下面这组“万能公式”即可。Less-2 专属“背诵版”流程1. 判断注入点操作在 URL 后面加and 11或and 12。Payloadid1 and 11页面正常id1 and 12页面异常/无数据结论没有单引号干扰直接拼接数字确认为数字型。2. 爆列数Payloadid-1 order by 3--id-1 order by 4--技巧把id改成-1是为了让前面的查询失效让页面只显示你后面UNION的数据。3. 爆数据Payloadid-1 union select 1,2,3--后续看页面哪个位置显示数字就把那个数字换成函数。4. 核心函数查库名/版本union select 1, database(), version()--查表名union select 1,2, group_concat(table_name) from information_schema.tables where table_schemadatabase()--查列名union select 1,2, group_concat(column_name) from information_schema.columns where table_nameusers--查数据union select 1,2, group_concat(username, :, password) from users--为什么 Less-2 比 Less-1 简单你可以对比一下Less-1字符型你需要记id-1 union select 1,2,3 --注意那个单引号和后面的--注释符。Less-2数字型你只需要记id-1 union select 1,2,3。区别在于不需要闭合符号不用管是单引号还是双引号。注释符可加可不加因为是数字型id1 union select...后面如果没有多余的符号其实不需要--来注释直接跑通也没问题当然加上更严谨。总结背下来是第一步理解是第二步。对于 Less-2你只需要记住id后面直接跟 SQL 语句不需要加引号。只要掌握了这一点剩下的步骤和 Less-1 完全一样。那难一点的是怎么样的思路面对更复杂的题目关键在于从“记忆者”转变为“思考者”建立起一套系统化的解题思路。这套思路可以概括为四个核心阶段信息收集、类型判断、策略制定、对抗与利用。 阶段一信息收集与类型判断这是所有后续操作的基础目标是摸清“敌情”。寻找注入点常规位置首先测试所有用户可控的输入点包括 URL 参数如?id1、POST 表单如登录框、搜索框以及 HTTP 请求头如Cookie,User-Agent。触发异常在这些输入点尝试输入特殊字符最常用的是单引号和双引号。如果页面返回数据库错误如SQL syntax error或页面布局发生异常这通常意味着存在注入点。判断注入类型这是决定后续攻击策略的关键一步。你需要通过构造不同的测试语句观察页面的响应来判断。字符型 vs. 数字型数字型输入id1 and 11页面正常输入id1 and 12页面异常如内容消失或报错。字符型输入id1 and 11页面正常输入id1 and 12页面异常。这揭示了后端 SQL 语句是否用引号包裹了输入。联合查询 vs. 盲注 vs. 报错注入联合查询 (Union-Based)页面能正常显示查询结果。这是最理想的情况可以直接通过UNION SELECT将你的查询结果“拼接”到页面上显示出来。盲注 (Blind SQLi)页面不显示任何数据库内容也无法触发错误。你只能通过页面返回的“真/假”状态布尔盲注或响应时间的快慢时间盲注来逐位推断数据。报错注入 (Error-Based)页面不显示查询结果但会返回详细的数据库错误信息。你可以利用特定的函数如 MySQL 的extractvalue()或updatexml()将查询的数据“藏”在错误信息中回显出来。 阶段二策略制定与信息提取一旦判断出注入类型就可以制定相应的攻击策略开始提取数据。确定查询字段数对于联合查询你需要先知道原 SQL 语句查询了多少列。通过ORDER BY语句如id1 ORDER BY 3--不断递增数字直到页面报错从而确定列数。探测数据库结构无论哪种类型目标都是获取数据库的结构信息。你需要利用数据库的“元数据”表在 MySQL 中是information_schema来查询获取当前数据库名SELECT database()获取所有表名SELECT table_name FROM information_schema.tables WHERE table_schemadatabase()获取指定表的列名SELECT column_name FROM information_schema.columns WHERE table_name目标表名提取敏感数据在获取了表名和列名后就可以构造最终的查询语句来获取flag、密码等敏感数据了。联合查询直接使用UNION SELECT将目标数据查询出来。盲注/报错注入需要配合substr()、ascii()等函数逐位猜解数据。这个过程非常繁琐通常会编写 Python 脚本来自动化完成。⚔️ 阶段三对抗与利用重点高难度的题目往往会设置各种障碍考验你的对抗能力。WAF/关键字过滤绕过当发现UNION、SELECT、空格等关键字被过滤时需要运用绕过技巧大小写混合UnIoN SeLeCt双写绕过UNIUNIONON SELESELECTCT内联注释/*!50000UNION*/ /*!50000SELECT*/编码替换使用CHAR(117,110,105,111,110)或十六进制0x756e696f6e来代替字符串union。空格绕过使用/**/、%09(Tab)、%0a(换行) 等替代空格。二次注入 (Second-Order SQLi)这是一种更隐蔽的攻击。攻击载荷首先被存入数据库此时被转义不会触发然后在后续的另一个功能中程序误以为库中数据是安全的而直接使用从而触发注入。这需要你理解整个应用的交互流程。自动化工具辅助对于复杂的盲注手动操作效率极低。熟练掌握 SQLMap 等工具并理解其参数如--techniqueB用于布尔盲注-T指定表名是解决难题的必备技能。总而言之解决难题的思路不是去匹配一个已知的 Payload而是像侦探一样通过观察和分析目标应用的每一个细微反馈不断提出假设、验证假设最终拼凑出完整的攻击路径。适合学习的靶场--sqli-labs能带你深入探索以下三个核心领域帮助你构建更全面的 Web 安全知识体系 多样化的注入场景与技术sqli-labs的设计哲学是“分型分类”它系统地覆盖了从基础到高阶的多种注入类型和特殊场景让你理解不同环境下的利用方式。按数据回显分类联合查询注入 (UNION-Based):页面会直接回显数据库查询结果是学习数据提取的基础。报错注入 (Error-Based):页面不直接显示数据但会返回数据库错误信息通过构造特定语句让错误信息“携带”出数据。盲注 (Blind SQLi):页面既无数据回显也无报错信息只能通过页面内容的真假布尔盲注或响应时间的快慢时间盲注来逐位推断数据。按注入点位置分类GET/POST 注入:最常见的注入方式漏洞点位于 URL 参数或表单提交的数据中。HTTP 头部注入:漏洞点隐藏在Cookie、User-Agent、Referer等 HTTP 请求头字段中揭示了“一切输入皆不可信”的防御思想。按数据类型和编码分类字符型与数字型:区分参数是否被引号包裹这决定了闭合方式的不同。宽字节注入:利用数据库字符集如 GBK与应用程序编码如 UTF-8的差异绕过单引号转义是一种高级的绕过技巧。特殊注入类型二次注入 (Second-Order SQLi):攻击分为两步首先将恶意数据存入数据库此时被转义不触发然后在后续的查询中程序误以为库中数据是安全的而直接使用从而触发注入。更新/插入语句注入:不仅限于SELECT查询还包括UPDATE、INSERT等场景例如在修改密码功能中注入可以直接篡改其他用户的密码。️ 进阶利用与防御对抗sqli-labs不仅是学习攻击的平台更是理解攻防对抗的绝佳环境。WAF 绕过专项训练:靶场专门设置了需要绕过 Web 应用防火墙WAF的关卡。你需要学习并实践各种绕过技巧例如使用内联注释/*!50000SELECT*/替代关键字。使用CHAR()函数或十六进制编码来替换被过滤的字符串。利用空格替换符如/**/、%09绕过对空格的检测。文件读写操作:在满足特定条件如数据库用户拥有FILE权限且secure_file_priv配置允许时可以利用 SQL 注入读取服务器上的敏感文件如/etc/passwd或写入 Webshell如INTO OUTFILE从而获取服务器控制权。 自动化与工具链实践sqli-labs是一个理想的练习场用于学习和实践自动化渗透测试工具。SQLMap 等工具的使用:你可以使用 SQLMap 等自动化工具对靶场进行扫描和利用直观地理解工具的工作原理、参数含义以及它能自动完成的复杂操作。编写自定义脚本:对于盲注等需要大量请求的场景手动操作效率极低。通过编写 Python 等语言的脚本可以实现数据的自动化提取这不仅能提升效率还能让你深入理解注入逻辑的底层实现。

更多文章