【好靶场 sql注入-POST类型注入-1】实战记录

发布时间:2026/11/2 23:41:17
【好靶场 sql注入-POST类型注入-1】实战记录

文章目录

  • 【好靶场】SQL注入-POST类型注入-1 实战记录
    • 概要
    • 整体架构流程
    • 技术名词解释
    • 漏洞修复建议
    • 小结

【好靶场】SQL注入-POST类型注入-1 实战记录

概要

该文章记录个人通过靶场(sql注入-POST类型注入-1)的过程。

关于 POST 的吐槽与补充:
打完这关我很想吐槽:POST 究竟体现在哪?因为靶场太保姆级,给了个可视化输入框,连抓包的机会都不给。
在真实渗透中,POST 注入通常要开 Burp Suite 拦截,在请求体(Body)里改参数,而不是像 GET 那样在 URL 改。虽然也有大佬全程纯抓包改 Body 通关(那样确实更还原),但我这里还是用了输入框。万变不离其宗,脱库逻辑是一样的。

整体架构流程

首先开启靶场,你能看到一个如下的界面:

你可以看到一个输入框,这时候就可以开始尝试了。第一步你要试出来这个是字符串型还是数字型。

首先输入1并点击搜索试试:

没啥返回内容,这里可能因为数据库里没1这个内容,所以前面没回显。接下来直接试试1':

能看到回显sql语法错误,也就是说,这个时候肯定不是完整闭合的。如果是数字型,就是我们多塞了个';如果是字符串型,就是后面多了个'。接下来我们直接输入#注释来看看:

加入#发现界面恢复正常,也就是说,是字符串型,后面多了',我们给它注释了,就正常运作了。

接下来我们该判断,当前这个查询的表里面有多少个列,然后其中有多少个列是回显到前端的。
这里我们使用order by语句,并用二分法快速确定。最后得到列数是7。

得到列数后,我们可以使用联合查询,先看看页面回显了哪些列。这里我们可以看到,这七个列全给回显了。

也就是说,我们可以随便挑一个列,作为注入点,输入 payload。这里我选择位置2。先输入database(),来确定一下当前的库名:

通过图片可以看到,当前库名是sql_injection_lab。

接下来我们可以查询一下该库里面有哪些表,payload:
1' union select 1,group_concat(table_name),3,4,5,6,7 from information_schema.tables where table_schema='sql_injection_lab' #

我们可以看到,这个库里有两个表,分别是users和flag,一般来说目标就在flag表里,所以我们优先看看这个表。payload如下:
1' union select 1,group_concat(column_name),3,4,5,6,7 from information_schema.columns where table_name='flag' #

从图中可以看出来,这个flag表里有两个列:id和flag。依旧按照惯性,先看flag这个列。payload:
1' union select 1,(select flag from flag),3,4,5,6,7 #

最后拿到结果:
flag{4dcb7af0711841d698317e780287d79d}

(注:该类在线靶场通常为动态生成环境。如果在本地或新窗口复现时报错,需优先通过information_schema查询当前环境的真实结构。)

技术名词解释

  • UNION SELECT(联合查询):要求前后查询的列数必须完全一致,常用于将我们构造的查询结果拼接到原本的回显位上。
  • information_schema:MySQL 自带的系统库,记录了所有数据库、表、列的信息。在不知道目标结构时,优先查询此库获取基础信息。
  • 子查询:形如(select flag from flag),将内部的查询结果作为单一值,直接填入外层查询的对应位置。

漏洞修复建议

  • 预编译(不让代码和数据混在一起):后台先把 SQL 的架子搭好(比如留个问号),你输入的任何字符都只会被当成纯文本去匹配,你的注入直接变成废铁。
  • 输入校验(安检门):后台严格限制输入格式(比如纯数字),把你输入的引号、括号全给转义或干掉。
  • 最小权限原则(不给黑客留后路):数据库账号只给查询特定表的权限,就算你注进去了,也查不到别的东西,更别提提权了。

小结

本次实战印证了动态靶场环境的不确定性。相较于死记硬背某一套 Payload,掌握通过information_schema逐层探测库名、表名和列名的系统化逻辑,才是应对不断变化的环境、稳定挖掘出目标数据的核心能力。