NTFS ADS数据交换流 带来的WEB安全问题

2013 年 7 月 25 日4330

  ADS带来的WEB安全问题并不是什么新鲜事了,几个月前偶然的原因和好友Rstar一起系统地做了很多测试,Rstar前段时间已经公开过,我把当时写的paper也发出来吧,希望能有更多的攻击场景被发掘。一个下午赶出来的paper,部分语句还有问题,之后一直没时间改了,将就看吧,slide因为涉及公司内容就暂时不放出来了:)

  NTFSADS带来的WEB安全问题

  NTFSADS简介

  NTFS流全称为NTFS交换数据流(NTFSAlternateDataStreams),ADS的诞生是为了兼容HierarchicalFileSystem。HFS---分层文件系统,是由苹果公司推出的文件系统,其工作模式是将不同数据存在不同的分支文件,文件数据存放在数据分支而文件参数存放在资源分支。类似的,NTFS流使用资源派生来维持与宿主文件相关的信息。ADS有点类似文件的属性信息一样,依附于文件的传统边界之外。

  来看一个ADS的实例,通常这个例子在讲到ADS的地方都会提到。新建一个文件,命名为test.txt,该文件即是宿主文件;打开文件,输入内容”test”。在该目录下执行命令echo"Thisisastream">test.txt:stream.txt建立后cmd不会有任何提示且对于Windows资源管理器来说宿主文件没有发生任何变化(包括其大小、修改时间等)。这是因为windows下不是所有程序都能支持ADS导致的。同样dir、type等也不能看到。Notepad能够部分支持ADS,可以打开test.txt:stream.txt,但notepad也不能完全支持,另存为时会出现参数错误。

  注:

  1、修改宿主文件的内容不会影响流的内容。

  2、修改流的内容不会影响宿主文件的内容。

  MSDN上给出了一个完整的流的格式,如下:<filename>:<streamname>:<streamtype>

  filename宿主文件的文件名

  streamname流名

  streamtype流类型

  注:

  1、其中streamtype也叫attributetype(属性类型)。

  2、用户不能创建一个新的流类型,流类型总是以\$符号作为开始。

  对NTFS格式下的一个文件而言,至少包含一个流,即data流(其streamtype为\$DATA),data流是文件的主流,默认的data流其streamname为空。ADS可以省略streamname,但不能省略streamtype。默认一个文件如果被指派了流,而该流没有streamtype的话会在存储时自动添加\$DATA。例如上面看到的例子test.txt:stream.txt在存储时实际上是为test.txt:stream.txt:\$DATA,但在查询结果中需要去除:\$DATA,否则会出现参数错误,这个是notepad不能很好的支持流所导致的。

  对文件夹而言,没有data流,其主流是directory流(streamtype为\$INDEX_ALLOCATION),directory流默认的streamname是\$I30。尽管文件夹默认没有data流,但用户可为其指派data流。

  在NTFS中,有如下的这些attributetype:

  \$ATTRIBUTE_LIST

  ListsthelocationofallattributerecordsthatdonotfitintheMFTrecord

  \$BITMAP

  AttributeforBitmaps

  \$DATA

  Containsdefaultfiledata

  \$EA

  Extendedattributeindex

  \$EA_INFORMATION

  Extendedattributeinformation

  \$FILE_NAME

  Filename

  \$INDEX_ALLOCATION

  ThetypenameforaDirectoryStream.Astringfortheattributecodeforindexallocation

  \$INDEX_ROOT

  Usedtosupportfoldersandotherindexes

  \$LOGGED_UTILITY_STREAM

  Usebytheencryptingfilesystem

  \$OBJECT_ID

  UniqueGUIDforeveryMFTrecord

  \$PROPERTY_SET

  Obsolete

  \$REPARSE_POINT

  Usedforvolumemountpoints

  \$SECURITY_DESCRIPTOR

  SecuritydescriptorstoresACLandSIDs

  \$STANDARD_INFORMATION

  Standardinformationsuchasfiletimesandquotadata

  \$SYMBOLIC_LINK

  Obsolete

  \$TXF_DATA

  TransactionalNTFSdata

  \$VOLUME_INFORMATION

  Versionandstateofthevolume

  \$VOLUME_NAME

  Nameofthevolume

  \$VOLUME_VERSION

  Obsolete.Volumeversion

  ADS带来的WEB安全问题

  早在多年前就有人想出将恶意代码隐藏在ADS中并捆绑在自解压文件中,从而躲过杀软的检测的方法。在WEB安全领域,ADS的特殊性和隐蔽性也带来了不少的问题。

  ::\$DATA请求泄露

  MicrosoftIIS3.0/4.0::\$DATA请求泄露ASP源代码漏洞(MS98-003)CVE-1999-0278

  这是一个很古老的漏洞,早期版本的IIS在处理文件请求时会先判断文件扩展名是否在可执行文件扩展名列表中,如果在,则执行并返回结果,如果不在,则直接返回文件内容。NTFS文件系统支持在文件中包含额外的数据流。\$DATA是在NTFS文件系统中存储数据流的属性。当我们对一个在NTFS分区中的ASP文件发出包含\$DATA请求,IIS会检查最后一个“.”后面的扩展名,因为多了“::\$DATA”,结果IIS不认为这是一个ASP文件,而文件系统可以识别该请求,于是ASP的源代码被返回。在高版本的IIS以及其他的WebServer中测试没有发现该问题。

  隐藏webshell问题

  这种利用思路最早由80sec提出,很好的利用了ADS的隐蔽性。由于目前的webshell检测程序都还没能考虑到ADS层面的检测,所以,这是种隐藏web后门的很好的方式。

  来看一个很简单的demo:在test.php中添加<?phpinclude(“1.php:.jpg”);?>,在1.php:.jpg中写入后门代码。访问test.php时,后门代码能成功解析。

  BypassHTTPBasicAuthentication

  对于IIS6.0+PHP、IIS7.5+asp、IIS7.5+php环境下,如果某目录通过HTTPBasic来认证,假设其目录下有index.php文件,我们可以通过构造如下方式来绕过认证直接访问其目录下的文件。

  /admin::\$INDEX_ALLOCATION/index.php

  /admin:\$i30:\$INDEX_ALLOCATION/index.asp

  Bypass黑名单验证上传

  对于windows环境的服务器,上传1.asp:.jpg类型的文件,当文件传到服务端时,windows会将该文件识别成ADS,从而认为其宿主文件名为1.asp而将.jpg识别为流名。在测试过程中(测试环境中WEBServer为IIS、Apache、Nginx)无论如何构造都无法访问可以解析的文件。

  前面我们提到,对于1.asp:.jpg这类ADS,其完整的全称为1.asp:.jpg:\$DATA,streamname可以省略但streamtype是不能省略且不能自定义的。我们在测试中发现,当上传1.php::\$DATA时(文件内容为phpinfo),在存储时会出现逻辑问题,导致生成非空的1.php文件,当中的内容为1.php::\$DATA的内容且可以正常在webserver下解析。该逻辑问题与语言无关与webserver无关,也就是说上传1.asp::\$DATA也会生成非空的1.asp文件,1.jsp::\$DATA同样。

  另外,当1.php::\$INDEX_ALLOCATION或1.php:\$I30:\$INDEX_ALLOCATION时,存储时逻辑同样会出现问题,会把该文件误认为是文件夹,从而建立一个1.php的空文件夹。(注:directory流默认streamname为\$I30)

  Windows还有个特性,就是当文件夹名或文件名末尾的任意个数的空格或点,在存储时都会自动去除,所以当上传1.php::\$DATA………….或1.php::\$INDEX_ALLOCATION……………此类文件同样会造成上述的存储时的逻辑错误。

  在MySQLUDF提权中的利用

  MySQL5.1及其之后的版本,使用UDF提权时,指定UDF必须导出在MySQL目录下的lib\plugin下才有用,而非完全版的Mysql默认安装后没有plugin这个目录,且在MySQL中没有可创建文件夹的函数。(通常很多时候在webshell中也无权限建立该目录),可用如下的SQL建立文件夹

  select‘xxx’intooutfile‘c:\\test::\$INDEX_ALLOCALTION\\’;

  同样由于windows在处理时会把c:\test::\$INDEX_ALLOCALTION\当做ADS处理,从而生成一个test文件夹。

0 0