文章目录
- 【好靶场】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逐层探测库名、表名和列名的系统化逻辑,才是应对不断变化的环境、稳定挖掘出目标数据的核心能力。