0%

windows下的奇妙文件名

windows下的奇妙文件名

起因是看了看红明谷杯线下的一篇wp,然后又进行了递归式学习。从discuz RCE学到windows文件名格式

8dot3文件名格式

也称为短文件名格式,在远古的DOS系统上,规定主文件名不能超过8个字符,后缀不能超过3个字符,这个格式就成为8dot3格式。windows向前兼容远古的MS-DOS,因此对于所有违背上述规定的文件名都会创建一个8dot3格式的短文件名,主文件名超过八位就截取前6位,然后接一个~1,如果存在前缀相同就数字递增,后缀超过三位就截取前三位,在cmd中直接敲dir /x就可以看到对应的短文件名

C:\Users\xxx\Desktop\test>dir /x
 驱动器 C 中的卷是 Windows-SSD
 卷的序列号是 06C1-0E48

 C:\Users\xxx\Desktop\test 的目录

2021/04/24  15:23    <DIR>                       .
2021/04/24  15:23    <DIR>                       ..
2021/04/24  15:23                 0 123~1.TXT    123.txtttt
2021/04/24  15:23                 0 123456~2.TXT 123456780.txt
2021/04/24  15:22                 0 123456~1.TXT 123456789.txt
               3 个文件              0 字节
               2 个目录 12,907,061,248 可用字节

可以使用fsutil 8dot3name set 1关闭该8dot3文件格式的支持

winAPI的玄妙通配符

windows系统在处理文件名的时候,FindFirstFileExW()/FindFirstFile()这两个API会对< > "这三个字符做特殊处理,效果分别对应Linux下的通配符* ? .,只要当最终实现是用这个API的就会受到影响,比如参考文章中提到的getimagesize()函数
感觉大部分的文件操作都会用这个API实现,本地测了一下file_get_contents也能通配符获取数据,直接file_get_contents("inde<.html")就行。和PHP版本没什么关系,也和web服务器类型没什么关系,只要windowsAPI没改就能通杀

update

后来又进行了测试,似乎通配符只能通配一个路径,比如一个目录名或一个文件名,当同时去匹配两个及以上的目录或文件名时将无法匹配,例如存在一个目录C:/htdocs/index.php,那么C:/ht<</index<<是无法匹配到htdocs目录下的index.php的。且<*的功能并不完全相同,单个小于号似乎匹配到.就会停止匹配,比如C:/htdocs/index.<能匹配上index.php,但C:/htdocs/index<就不行,而<<就能进行任意匹配了,即使目标文件名存在多个点号
但是C:/<</index.php也无法成功匹配,匹配时似乎至少得有一个字符存在,比如C:/h<</index.php,但若直接存在C:/index.php的话则不需要任何字符也能用上述语句进行匹配

同理,在有类似功能且参数可控的情况下,可以利用通配符进行快速的文件名猜解。

短文件名,通配符与windows的web服务

关系比较乱。。。并且我本地只有Apache和IIS环境,就只这两个进行验证了,网上找了个野生的Nginx但是由于是别人的站也就不好下手。。。。主要是参考文末的文章

当函数调用最后通过windowsAPI时均支持通配符,与使用的语言和webserver类型无关

windows+IIS

支持短文件名猜解,通配符访问文件(不可访问文件夹)
不支持短文件名访问
话说能猜解短文件名但是猜解出来又不能访问有什么用。。。。脑洞补全吗
也可以猜解出来再通配符访问吧,但是本地复现时是不能通配符访问的

IIS全版本短文件名猜解

远古洞,是IIS6配合.net的时候导致的短文件名猜解。猜解需求当然是目标存在短文件名,可以猜解出短文件名来。在这种情况下可以通过*通配单个字符,在猜测正确的情况下返回404,错误返回400
在后续的IIS版本上修了这个问题,但是当请求方法从GET变成OPTION或者TRACE之后,仍然会出现布尔结果,约等于全版本通杀
在远古的远古版本似乎还能进行短文件名访问,后来给修了

本地复现失败

本地Winserver12的IIS8.5+.NET 4.0测试,不支持通配符访问文件夹和文件,不知道是不是配置PHP环境后才行
支持OPTIONS方法猜解,猜测成功404,失败200,需要*~1*这么个格式,没有这个~1就无法猜解,并且不能使用已经猜测出的短文件目录名进行进一步的猜解
即我拥有testguessfolder/ind33333x.html这样子一个文件,可以猜测出文件夹短文件名为TESTGU~1,但在猜解文件名的时候,不能使用TESTGU~1作为文件夹名,而是得使用testguessfolder全名才能继续猜解ind33333x.html这个文件

windows+Apache

支持短文件名访问,目录和文件均可
不支持通配符访问和短文件名猜解,本地环境加奇怪的字符会直接导致403,fuzz了一遍不给用的是一堆不可见字符和" * : < > |,刚好包括我们的三个通配符和短文件名猜测时的星号,可能是Apache的过滤

windows+Nginx

对野生Nginx/1.18.0的测试结果
支持短文件名访问,通配符访问文件(不可访问文件夹)短文件名因为找不到能用的所以没有实测。。。。
不支持短文件名猜解

总结

感觉返回来IIS变成最安全的了,虽然能进行短文件名猜解,但猜解出来了又不给访问,完整文件名靠脑洞补全
Apache次之,discuz的数据库备份就能被直接访问上,但是不能通配符访问文件名
Nginx比较危险,虽然不能短文件名猜解,但是既支持短文件名访问又支持通配符访问,并且这等于可以猜解完整文件名了,并且通配符访问本身就挺危险的吧。。。

小trick

判断服务器是Linux还是windows的最有效方法之一应该是文件名的大小写,找到一个有效文件改改大小写看看会不会404就知道平台类型了,触发报错或者偶尔看看响应头应该也能找到些什么?
windows默认是不分大小写的,创建一个a.txt和A.txt会导致文件名冲突,不过听说windows在某次更新后支持了对文件名的大小写区分,但是需要额外配置

discuz RCE

红明谷杯那个线下事实上是个discuz的题,第一步是用到了windows下短文件名访问获取到了discuz的数据库备份获取到了UC_key然后各种操作RCE的,对discuz完全不熟,只能把各位神仙的文章记录一下了
空指针-Base on windows Writeup – 最新版DZ3.4实战渗透
这是一篇“不一样”的真实渗透测试案例分析文章 这个挺有意思的就是太难了呜呜
红明谷数据安全大赛线下赛Discuz题解

参考链接

PHP源码调试之Windows文件通配符分析
IIS深入浅出之短文件漏洞知多少
windows短文件名安全问题 数据库备份爆破
FindFirstFile undocumented wildcard or bug?
Windows下的”你画我猜” – 告别效率低下的目录扫描方法