news 2026/7/5 23:17:05

SQL注入实战:科学计数法绕过与Sqli-labs靶场通关指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL注入实战:科学计数法绕过与Sqli-labs靶场通关指南

1. 项目概述:为什么Sqli-labs是Web安全入门的必修课

如果你刚接触Web安全,或者想系统性地提升SQL注入实战能力,那么Sqli-labs这个靶场绝对是你绕不开的“新手村”和“训练场”。我第一次接触它的时候,感觉就像拿到了一张藏宝图,里面布满了精心设计的谜题,每一关都对应着一种或多种SQL注入的典型场景。这个靶场之所以经典,是因为它几乎涵盖了SQL注入的所有基础类型:从最简单的字符型、数字型注入,到需要层层绕过的盲注、报错注入,再到需要组合拳的堆叠注入和二次注入。它不只是一个让你“打点”的工具,更是一个让你理解数据库、应用程序和后端代码如何交互的绝佳沙盒。

很多新手会问,网上那么多靶场,为什么偏偏是Sqli-labs?我的体会是,它的设计非常“教学化”。它的代码是开源的,你可以直接看到每一关的后端PHP源码,理解漏洞是如何产生的,以及开发者(或者说,出题人)在哪些地方设置了过滤,又留下了哪些“后门”。这种“上帝视角”对于建立完整的攻击者思维至关重要。你不会只停留在“这个payload能用”的层面,而是会去思考“为什么这个payload能用”以及“开发者为什么会犯这个错”。理解了漏洞的根源,你才能在未来自己开发或审计代码时,有效地避免同类问题。

这次我们要聊的,不仅仅是按部就班地通关,而是聚焦于一个实战中非常有趣且实用的技巧:利用科学计数法绕过过滤。在不少CTF比赛和真实世界的WAF(Web应用防火墙)规则中,单纯的数字或字符串拼接可能会被拦截,但像1e1(表示10)这样的科学计数法表示,却常常成为规则盲区。掌握这个技巧,相当于在你的注入武器库里,又多了一把轻巧而锋利的“手术刀”。

2. 环境搭建与靶场初探:不只是启动一个Docker

工欲善其事,必先利其器。搭建一个稳定、可反复“破坏”的实验环境是第一步。虽然网上有很多一键Docker的教程,但我建议,尤其是初学者,最好能手动从GitHub拉取源码,在本地配置一个LAMP(Linux + Apache + MySQL + PHP)或WAMP环境。这个过程本身就能让你熟悉Web应用的基本运行架构。

2.1 手动部署Sqli-labs的细节与避坑

直接从GitHub克隆项目是最稳妥的方式:

git clone https://github.com/Audi-1/sqli-labs.git

将克隆下来的sqli-labs文件夹整个放到你的Web服务器根目录(例如Apache的/var/www/html/或 XAMPP 的htdocs)。接下来是关键的一步:数据库初始化。很多新手卡在这里,因为README里的说明可能不够详细。

  1. 修改数据库配置文件:找到sqli-labs/sql-connections目录下的db-creds.inc文件。用文本编辑器打开,你会看到类似下面的内容:

    <?php //give your mysql connection username and password $dbuser ='root'; $dbpass =''; $dbname ="security"; $host = 'localhost'; $dbname1 = "challenges"; ?>

    你需要根据自己本地MySQL的实际情况修改$dbpass(你的MySQL root密码)和$host(通常是localhost)。

  2. 创建数据库并导入数据:通过phpMyAdmin或者命令行登录MySQL,然后顺序执行以下操作:

    -- 创建名为 security 的数据库 CREATE DATABASE security; -- 使用这个数据库 USE security; -- 导入 sqli-labs 目录下的 SQL 文件来创建数据表 -- 你需要找到 sql-lab 目录下的 .sql 文件,例如: SOURCE /你的路径/sqli-labs/sql-lab/less-1.sql;

    注意:Sqli-labs的SQL文件可能分散在多个地方,主要的数据表结构通常在sql-lab目录下。如果导入失败,检查文件路径和MySQL用户的权限。一个常见的坑是,Windows系统下的文件路径需要使用反斜杠或双斜杠。

  3. 访问安装页面:在浏览器中输入http://localhost/sqli-labs/(具体路径根据你的放置位置调整),点击页面上的链接进行安装。如果一切顺利,你会看到所有关卡(Less-1, Less-2...)的链接列表。

2.2 核心工具链:Burp Suite与浏览器的协同

对于SQL注入实战,Burp Suite不是可选项,而是必需品。它不仅仅是一个抓包工具,更是你观察HTTP请求与响应、修改参数、进行自动化测试的“作战指挥中心”。

  • Burp Suite配置:确保你的浏览器代理设置正确指向Burp(默认127.0.0.1:8080),并在Burp中安装好CA证书以拦截HTTPS流量。对于Sqli-labs这类本地HTTP靶场,HTTP流量就足够了。
  • 浏览器开发者工具:与Burp互补。我习惯用开发者工具的“网络(Network)”标签页实时查看请求响应,用“控制台(Console)”执行一些简单的JavaScript来辅助测试(比如快速生成一个长字符串)。两者结合,能让你对数据流有立体的感知。

搭建好环境,你的“黑客实验室”就准备就绪了。接下来,我们将从最基础的关卡开始,逐步深入,并最终亮出“科学计数法绕过”这个绝招。

3. 从Less-1到Less-4:理解注入的基本类型与闭合

Sqli-labs的前几关是精心设计的入门教程,它们分别代表了不同的注入点类型和SQL语句闭合方式。理解这些,是写出有效payload的前提。

3.1 Less-1:基于错误的字符型注入与单引号闭合

打开Less-1,页面通常有一个输入框让你输入ID。随便输入一个数字,比如1,页面会返回对应的用户信息。我们的第一步永远是探测

  1. 探测注入点:输入一个单引号。如果页面返回了数据库错误信息(如“You have an error in your SQL syntax...”),那么这里很可能存在SQL注入漏洞,并且原始SQL语句使用了单引号来包裹用户输入。
  2. 判断列数:使用ORDER BY子句。在Burp中拦截请求,将ID参数修改为1‘ ORDER BY 3 --+--+是注释符(在URL中+号代表空格),用于注释掉原SQL语句中后续的部分。逐渐增加ORDER BY后面的数字(4,5...),直到页面报错或返回异常。如果ORDER BY 3正常而ORDER BY 4报错,说明当前查询结果有3列。
  3. 确定回显点:使用UNION SELECT语句。将payload修改为-1‘ UNION SELECT 1,2,3 --+。这里ID设为-1或一个不存在的值,是为了让原查询结果为空,从而确保页面显示的是我们UNION查询的结果。观察页面,看数字“1”、“2”、“3”哪个位置被显示了出来。假设数字2和3的位置被显示,那它们就是我们可以用来回显数据库信息的“回显点”。
  4. 获取信息:利用回显点。将payload修改为-1‘ UNION SELECT 1, database(), user() --+。这样,我们就能在页面上直接看到当前数据库名和数据库用户名了。后续可以进一步查询表名、列名和数据。

实操心得--+里的+在Burp的Repeater模块中发送时,有时需要手动编码为%2b,或者直接使用--(后面跟一个空格)。也可以使用#注释,但在URL中需要编码为%23。多试试几种,确保注释生效。

3.2 Less-2:数字型注入的简洁性

Less-2的页面和Less-1看起来一样,但输入单引号可能不报错。这时可以尝试输入1 and 1=2。如果页面正常返回ID=1的数据,说明and 1=2这个假条件没起作用,可能不是数字型。但如果页面返回空或错误,则可能是数字型注入。

对于数字型注入,闭合方式更简单,通常不需要单引号。探测列数的payload直接就是1 ORDER BY 3,UNION注入的payload是-1 UNION SELECT 1,2,3。少了引号的纠缠,整个过程更加直接。这一关的核心是让你意识到:并非所有注入点都需要处理引号闭合,这取决于后端代码如何处理输入参数。如果代码是$id = $_GET[‘id‘]; $sql = “SELECT ... FROM ... WHERE id=$id”;,那么就是数字型。

3.3 Less-3与Less-4:单引号括号与双引号括号闭合

这两关提升了难度,引入了括号()进行闭合。

  • Less-3:输入单引号报错信息可能是...near ‘‘‘)‘ LIMIT 0,1‘。这提示我们,原始SQL语句的格式可能是SELECT ... WHERE id=(‘$id‘)。所以我们的闭合需要构造为1‘) --+,先闭合单引号,再闭合括号。完整的探测payload例如:1‘) ORDER BY 3 --+
  • Less-4:输入单引号不报错,试试双引号。报错信息可能包含““),说明格式是SELECT ... WHERE id=(“$id“)。闭合方式则为1“) --+

这两关的训练价值在于,让你学会仔细阅读数据库的错误信息。错误信息是极好的调试工具,它常常会“泄露”出原始SQL语句的结构片段。通过观察错误信息中引号和括号的位置,你可以反推出正确的闭合方式。

关卡注入类型推测SQL结构测试Payload(探测)关键技巧
Less-1字符型(单引号)...WHERE id=‘$id‘ LIMIT 0,11‘ and ‘1‘=‘1利用单引号闭合,注意注释符使用
Less-2数字型...WHERE id=$id LIMIT 0,11 and 1=2无需处理引号,直接拼接逻辑语句
Less-3字符型(单引号+括号)...WHERE id=(‘$id‘) LIMIT 0,11‘) and (‘1‘)=‘1需同时闭合单引号和括号
Less-4字符型(双引号+括号)...WHERE id=(“$id“) LIMIT 0,11“) and (“1“)=“1需同时闭合双引号和括号

4. 中级挑战:盲注、报错注入与堆叠注入

闯过基础关卡后,你会遇到一些不再直接回显查询结果的挑战。这时候就需要更高级的技巧。

4.1 布尔盲注与时间盲注:当页面“沉默”时

在Less-5和Less-6等关卡,无论输入什么,页面都只返回一种固定的提示(如“You are in…”),不会显示数据库数据,也不会直接报错。这就是盲注(Blind Injection)

  • 布尔盲注:页面虽然不显示数据,但会根据SQL查询语句的真假返回不同的内容(比如一条简单的“存在”或“不存在”的信息)。我们可以通过and连接条件,像猜谜一样逐位判断。例如,猜解数据库名的第一个字母:1‘ and ascii(substr(database(),1,1))>100 --+。如果页面返回“存在”的状态,说明ASCII码大于100,然后我们再用二分法不断缩小范围(>150, <125...),直到确定准确的ASCII码值,再转换为字符。这个过程极其繁琐,必须借助自动化工具。
  • 时间盲注:页面返回内容完全一样,无法通过内容区分真假。这时我们利用SLEEP()函数。payload如:1‘ and if(ascii(substr(database(),1,1))>100, sleep(5), 0) --+。如果第一个字符的ASCII码大于100,页面会延迟5秒响应;否则立即返回。通过观察响应时间,同样可以逐位猜解。

注意事项:手工进行盲注是低效且痛苦的。实战中一定会使用工具,如SQLmap。但理解其原理至关重要。你可以用Python写一个简单的脚本,自动化发送请求和判断逻辑,这是很好的练习。

4.2 报错注入:让数据库自己“说”出来

在Less-11等关卡,页面会显示数据库的错误信息。我们可以故意构造一个会让数据库报错的语句,并让错误信息中包含我们想窃取的数据。这就是报错注入

常用的函数有updatexml()extractvalue()floor(rand()*2)结合count()产生的重复键错误。

  • updatexml()示例1‘ and updatexml(1, concat(0x7e, (select database()), 0x7e), 1) --+concat(0x7e, ..., 0x7e)中的0x7e是波浪号~的十六进制,用于在报错信息中凸显我们的数据。执行后,错误信息会提示“XPATH syntax error: ‘~database_name~‘”,从而泄露数据库名。
  • 原理updatexml()函数用于更新XML文档,第二个参数需要是合法的XPATH路径。我们传入一个由concat()拼接的非法路径(以~开头),数据库执行时会报错,并将这个非法字符串(即我们拼接的数据)一起显示在错误信息中。

报错注入的优点是一次性能提取较长的数据,效率高于盲注的逐位猜解。

4.3 堆叠注入:执行“多条语句”的威力

从Less-38开始,你会接触到堆叠注入(Stacked Injection)。它的原理是利用;分隔,在一次数据库调用中执行多条SQL语句。这赋予了攻击者更大的破坏力。

例如,一个可能的payload是:1‘; DROP TABLE users --+。如果后端使用了支持多语句查询的数据库驱动(如PHP中的mysqli_multi_query),那么这条语句不仅会执行原查询,还会执行删除users表的操作。

重要警告:在自家靶场可以随便玩,但在任何授权测试之外的真实环境,绝对禁止使用DROPDELETEUPDATE等破坏性语句。堆叠注入常被用于在注入后创建新的数据表、插入后门用户等持久化操作。在Sqli-labs中,你可以安全地尝试1‘; CREATE TABLE test (id int); --+来验证漏洞存在。

5. 高阶技巧:科学计数法绕过的原理与实战

现在,让我们聚焦到标题中提到的“科学计数法绕过”。这个技巧在过滤了某些字符但未过滤eE的场景下特别有效。

5.1 科学计数法在SQL中的本质

在MySQL、MariaDB等数据库中,科学计数法是一种合法的数字表示形式。1e1等于10,2.5e2等于250,1e0等于1。关键在于,数据库引擎在解析SQL时,会将科学计数法字符串先计算成对应的数字值

假设后端代码对用户输入进行了过滤,比如将“空格”替换为空,或者过滤了“and”、“or”等关键字,但允许数字和字母e通过。这时,传统的1 and 1=1可能会被拦截。

5.2 绕过场景实战解析

场景一:绕过空格过滤有些WAF或简单的过滤函数会删除或拦截空格。我们可以用科学计数法来替代某些数字,有时可以避免使用空格。

  • 原始Payload:1‘ and ‘1‘=‘1
  • 如果空格被过滤,可能变成:1‘and‘1‘=‘1,这可能导致语法错误。
  • 尝试利用科学计数法构造:1‘and‘1e0‘=‘1e0。这里1e0就是数字1。虽然看起来还有空格(实际上在and前后),但重点是,如果过滤规则是删除空格,这个payload被处理后会变成1‘and‘1e0‘=‘1e0,在SQL中1e0是一个合法的数值令牌,整个语句可能依然能被正确解析。更常见的用法是结合其他无空格技巧,如用括号()、注释/**/代替空格。

场景二:作为数字参与运算,绕过特定字符检测这是更常见的用途。在一些盲注或条件判断中,我们需要用到数字比较。

  • 假设我们需要判断数据库名的长度是否大于10:1‘ and length(database())>10 --+
  • 如果>符号被过滤了怎么办?我们可以利用科学计数法和等式判断。length(database())=11可以写成length(database())=1e1。但如何判断“大于”呢?一个技巧是使用减法:1‘ and length(database())-1e1>0 --+。如果>被过滤,这个思路可能受阻。
  • 更巧妙的绕过:利用between ... and ...语句。1‘ and length(database()) between 1e1 and 2e1 --+。这个语句判断长度是否在10到20之间。betweenand是SQL关键字,1e12e1是数字,整个payload可能绕过对><等比较符的过滤。

场景三:在报错注入中构造数字参数某些报错注入函数需要数字参数。例如exp()函数,当参数过大(>709)时会产生溢出错误。我们可以构造exp(~(select * from (select user())x))来报错输出用户信息。其中~是按位取反,会产生一个很大的数字。如果某些符号被过滤,我们可以尝试用科学计数法构造这个大数,但通常exp()配合~的方式已经足够。

5.3 一个综合案例:Less-?的绕过实战

假设某一关(我们可以设想一个场景)过滤了空格和and关键字,但我们可以使用&&代替and(在MySQL中,&&是逻辑与的另一种写法)。同时,它允许字母e通过。 我们的目标是判断一个条件的真假。

  1. 正常逻辑1‘ && length(database())=10 --+
  2. 如果=被过滤:我们可以尝试用likerlike。但比较数字时,可以尝试用科学计数法配合运算:1‘ && length(database())-1e1=0 --+。这里1e1是10,如果长度等于10,减法的结果就是0。
  3. 如果-=也被过滤(假设过滤得很奇怪):我们可以利用in关键字。1‘ && length(database()) in (1e1) --+in用于判断一个值是否在列表中,这里列表只有一个值1e1(即10)。

这个案例想说明的是,科学计数法1e1作为一个整体性的“数字令牌”,可以替代纯数字10出现在SQL语句的数值位置。当一些针对数字10的简单过滤规则(比如正则表达式\b10\b)生效时,1e1可能因为不符合该模式而成功绕过。它的价值在于提供了另一种数字表示形式,增加了payload的变体,与注释符、编码、等价函数替换等技巧组合使用,能有效提高绕过成功率。

6. 工具辅助与自动化测试:SQLmap的正确打开方式

手工注入是理解原理的必经之路,但实战中效率至上。SQLmap是每个Web安全工程师的必备神器。然而,直接sqlmap -u “url” --batch往往不是最优解。

6.1 针对Sqli-labs的SQLmap精细化使用

  1. 指定注入点和参数sqlmap -u “http://localhost/sqli-labs/Less-1/?id=1“ -p id
    • -p id指定只测试id这个参数,节省时间。
  2. 指定数据库类型sqlmap -u “...” --dbms=mysql
    • Sqli-labs用的是MySQL,直接指定可以跳过自动探测,加快速度。
  3. 设置级别和风险sqlmap -u “...” --level=2 --risk=2
    • --level越高,测试的payload越多越全面(也会更慢)。--risk越高,会使用风险更高的payload(如OR布尔注入可能造成大量数据返回)。对于靶场,level=2, risk=2是个不错的起点。
  4. 获取数据
    • 获取所有数据库:--dbs
    • 获取当前数据库:--current-db
    • 获取指定数据库的所有表:-D security --tables
    • 获取指定表的所有列:-D security -T users --columns
    • dump表数据:-D security -T users -C username,password --dump

6.2 结合Burp Suite进行高效测试

我更推荐的工作流是:

  1. 用浏览器和Burp Suite手工测试,确定存在注入点、类型和闭合方式。
  2. 将Burp中拦截到的含有注入点的请求,右键保存到文件(例如request.txt)。
  3. 使用SQLmap直接加载这个文件进行自动化测试:sqlmap -r request.txt这种方式会自动识别所有参数、Cookie等信息,最贴近真实请求,成功率很高。

实操心得:SQLmap的--tamper参数是绕过WAF的利器。它内置了很多脚本,可以对payload进行混淆、编码。例如,--tamper=space2comment会把空格替换成/**/。你可以针对靶场的过滤规则,编写或选择合适的tamper脚本。对于科学计数法绕过,如果SQLmap没有现成脚本,你可以通过观察手工成功的payload,用--tamper自定义一个简单的替换脚本(例如,把特定的数字10替换成1e1),但这需要一定的Python基础。

7. 防御视角:从攻击中学习如何编写安全代码

通过Sqli-labs的实战,我们站在攻击者的角度看到了各种漏洞的成因。现在切换回开发者视角,如何防御?

  1. 预处理语句(参数化查询):这是最根本、最有效的防御手段。使用像PDO(PHP)或MyBatis(Java)这样的数据库接口,它们会将SQL语句的结构(SELECT * FROM users WHERE id = ?)与数据(用户输入的id值)分开处理。数据库引擎会先编译语句结构,再将数据作为参数传入,从根本上杜绝了数据被解释为代码的可能性。这是绝对的首选方案
  2. 输入验证与过滤:如果因为某些历史原因无法使用预处理,则必须进行严格的输入验证。对于数字型参数,使用intval()ctype_digit()等函数确保输入是合法的整数。对于字符型,定义严格的白名单(只允许特定字符集),而非黑名单。黑名单永远会被绕过,科学计数法绕过就是一个例子——如果你只过滤了数字和空格,但没考虑到e,就可能被绕过。
  3. 最小权限原则:连接数据库的应用程序账号,不应该拥有DROPCREATE TABLEFILE等高危权限。只赋予其完成业务所必需的最小权限(通常是SELECTINSERTUPDATEDELETE),这样即使发生注入,危害也能被限制。
  4. 错误信息处理:切勿将详细的数据库错误信息直接返回给前端用户。应使用自定义的、模糊的错误页面。这能增加攻击者进行报错注入和盲注的难度。
  5. 使用Web应用防火墙(WAF):WAF可以作为一道额外的防线,基于规则拦截常见的攻击payload。但切记,WAF是“缓兵之计”,不能替代安全的代码编写。攻击者会不断研究新的绕过技巧(就像科学计数法绕过一样),规则总有滞后的可能。

玩转Sqli-labs靶场,特别是深入理解像科学计数法绕过这样的技巧,最终目的不是为了“黑”掉什么,而是为了在脑海中建立起一道坚固的防线。当你再看到自己写的SQL语句时,你会本能地思考:这里有没有拼接用户输入?我该怎么用参数化查询来重写它?这种从攻击者思维转化而来的防御意识,才是安全实战训练带给你的最宝贵的财富。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 23:16:01

Linux命令-reject(拒绝打印任务)

Linux命令-reject&#xff08;拒绝打印任务&#xff09;命令语法常用选项场景化实例1. 拒绝指定打印机2. 带原因说明拒绝3. 批量拒绝多个打印机4. 打印机故障自动处理5. 恢复打印机接受任务6. 通过 CUPS Web 接口管理7. 配合系统监控脚本查询打印队列状态最佳实践快速参考&…

作者头像 李华
网站建设 2026/7/5 23:15:08

BuildAnyPoint框架:建筑点云智能重建技术解析

1. 项目背景与核心价值去年在整理建筑可视化项目资料时&#xff0c;我遇到一个棘手问题&#xff1a;客户提供的点云数据质量参差不齐&#xff0c;传统建模工具处理起来效率极低。当时就想着&#xff0c;要是有个能自动理解建筑结构并生成规范模型的工具该多好。没想到今年CVPR上…

作者头像 李华
网站建设 2026/7/5 23:12:24

YOLOv11目标检测算法解析与实战指南

1. 从零开始理解YOLO&#xff1a;计算机视觉的"闪电战"第一次接触YOLO&#xff08;You Only Look Once&#xff09;这个算法时&#xff0c;最让我震撼的是它的速度。传统目标检测算法像老式扫描仪逐行读取文档&#xff0c;而YOLO则像人眼扫视——只需"看一眼&qu…

作者头像 李华
网站建设 2026/7/5 23:12:05

YOLO26实例分割技术:原理、实现与优化

1. YOLO26实例分割技术解析&#xff1a;从原理到实现 在计算机视觉领域&#xff0c;实例分割一直被认为是目标检测的"高阶版本"。它不仅需要像目标检测那样定位物体位置&#xff0c;还要精确到像素级别地勾勒出物体轮廓。想象一下&#xff0c;当自动驾驶汽车需要识别…

作者头像 李华
网站建设 2026/7/5 23:09:47

智能视频监控:三维重建与动态模型技术解析

1. 传统视频监控的瓶颈与突破方向 监控摄像头已经遍布城市的各个角落&#xff0c;但大多数系统仍然停留在"看得见"却"看不懂"的初级阶段。作为一名在安防行业摸爬滚打十年的老兵&#xff0c;我见过太多监控室里的尴尬场景&#xff1a;值班人员盯着几十个分…

作者头像 李华
网站建设 2026/7/5 23:04:00

BLDC电机六步换相控制与双闭环系统设计

1. 直流无刷电机控制概述直流无刷电机&#xff08;BLDC&#xff09;作为现代电机控制领域的重要成员&#xff0c;凭借其高效率、低噪音和长寿命等优势&#xff0c;在工业自动化、消费电子和航空航天等领域得到广泛应用。与传统有刷直流电机相比&#xff0c;无刷电机通过电子换相…

作者头像 李华