存档

文章标签 ‘MS08-067’

MS08-067网马

2008年11月2日 没有评论 104 views

已经出来有一周了,很多人还在忙着编译,放个可以做网马的exploit出来。
又一场腥风血雨

#include 

// This is the decompiled function sub_5B86A51B in netapi32.dll on XP SP3

int ms08_067(wchar_t* path)
{
wchar_t* p;
wchar_t* q;
wchar_t* previous_slash = NULL;
wchar_t* current_slash = NULL;
wchar_t ch;

// If the path starts with a server name, skip it

if ((path[0] == L'\\' || path[0] == L'/') &&
(path[1] == L'\\' || path[1] == L'/'))
{
p = path+2;

while (*p != L'\\' || *p != L'/') {
if (*p == L'\0')
return 0;
p++;
}

p++;

// make path point after the server name

path = p;

// make sure the server name is followed by a single slash

if (path[0] == L'\\' || path[0] == L'/')
return 0;
}

if (path[0] == L'\0') // return if the path is empty
return 1;

// Iterate through the path and canonicalize ..\ and .\

p = path;

while (1) {
if (*p == L'\\') {
// we have a slash

if (current_slash == p-1) // don't allow consequtive slashes
return 0;

// store the locations of the current and previous slashes

previous_slash = current_slash;
current_slash = p;
}
else if (*p == L'.' && (current_slash == p-1 || p == path)) {
// we have \. or ^.

if (p[1] == L'.' && (p[2] == L'\\' || p[2] == L'\0')) {
// we have a \..\, \..$, ^..\ or ^..$ sequence

if (previous_slash == NULL)
return 0;

// example: aaa\bbb\..\ccc
// ^ ^ ^
// | | &p[2]
// | |
// | current_slash
// |
// previous_slash

ch = p[2];

wcscpy(previous_slash, &p[2]);

if (ch == L'\0')
return 1;

current_slash = previous_slash;
p = previous_slash;

// find the slash before p

// BUG: if previous_slash points to the beginning of the
// string, we'll go beyond the start of the buffer
//
// example string: \a\..\

q = p-1;

while (*q != L'\\' && q != path)
q--;

if (*p == L'\\')
previous_slash = q;
else
previous_slash = NULL;
}
else if (p[1] == L'\\') {
// we have \.\ or ^.\

if (current_slash != NULL) {
wcscpy(current_slash, &p[1]);
goto end_of_loop;
}
else { // current_slash == NULL
wcscpy(p, p+2);
goto end_of_loop;
}
}
else if (p[1] != L'\0') {
// we have \. or ^. followed by some other char

if (current_slash != NULL) {
p = current_slash;
}
*p = L'\0';
return 1;
}
}

p++;

end_of_loop:
if (*p == L'\0')
return 1;
}
}

// Run this program to simulate the MS08-067 vulnerability

int main()
{
return ms08_067(L"\\a\\..\\");

分类: 矩阵毒刺 标签: ,

MS08-067 check

2008年10月31日 没有评论 65 views

This tool can be used to anonymously check if a target machine or a list of target machines are affected by MS08-067 (Vulnerability in Server Service Could Allow Remote Code Execution)

Usage
$ python ms08-067_check.py -h
Usage: ms08-067_check.py [-d] {-t |-l }

Options:
--version show program's version number and exit
-h, --help show this help message and exit
-d show description and exit
-t TARGET target IP or hostname
-l LIST text file with list of targets
-s be silent

Example
$ python ms08-067_check.py -t 192.168.123.30
192.168.123.30: VULNERABLE

下载地址:ms08-067_check.py
 

分类: 资源共享 标签:

ASPXshell MS08-067插件

2008年10月30日 没有评论 121 views

作者:cnqing

ASPXshell MS08-067插件
感谢hi群众兄测试,附赠几个插件。。。
1.扫可写目录插件
使用方法:设置扫描起始目录,设置扫描成功N个后停止,扫描。

2.无组件打包插件
使用方法:设置要打包的目录,设置打包到的位置,不建议打包很大的文件(1G?)。下载到本地用点击“解压”工具解压。

3.MS-08067 for CN 插件

下载地址:http://www.cncert.net/up_files/soft/20081028_plugs.rar
原始客户端:http://www.cncert.net/DOWN/script/2008-10-13/167.html
更新方法:
将*.dll放到根目录
将*.dll2放到remoter目录

 

重新启动程序

分类: 资源共享 标签: ,

MS08-067漏洞的触发条件

2008年10月29日 没有评论 139 views

  通常在溢出成功后目标主机的监听端口为4444,其对应的PID为840(随机)。毫无疑问它应该和某个系统服务相对应,输入tasklist /svc后发现其对于的进程是svchost.exe。该进程在系统中有多个,但PID为840的这个svchost.exe进程是一个宿主进程,其中包含了诸如lanmanserver, lanmanworkstation, Netman等多个系统服务。

那到底是哪个系统服务触发了该漏洞呢?测试,当Computer Browser、Server、Workstation这三个系统服务中的任何一个服务被关闭后,用MS08067.exe进行溢出测试均失败

通过上面的测试,可见是这三个系统服务造成了MS08-067漏洞,这和微软的漏洞说明“Server服务在处理RPC请求过程中存在的一个严重漏洞”不谋而合。那么这三个服务都是干什么的,相互之间有什么关系呢?server是Windows系统的一个重要服务,其主要作用是“支持此计算机通过网络的文件、打印、和命名”。

  而Computer Browser服务的作用是“维护网络上计算机的更新列表,并将列表提供该计算机指定浏览”与server是依存关系。另外,Workstation服务的作用是“创建和维护到远程服务的客户端网络连接”,与Computer Browser是依存关系。上面的分析为我们预防MS08-067漏洞提供了一条思路。

 漏洞预防

  (1)、最彻底的措施是,通过第三方工具下载KB958644补丁包打上该漏洞补丁。

  (2)、如果用户对微软的补丁存有戒心可以采取变通的措施,将Computer Browser、Server、Workstation这三个系统服务关闭,毕竟这三个服务在大多数情况下是用不到的。

 

分类: 技术文章 标签:

MS08-067 Exploit for CN 2k/xp/2003 .net version

2008年10月29日 没有评论 188 views

作者:cnqing

来源于EMM's Exp,以socket方式重放攻击。
本机可为任意平台,从这个角度讲成功率稍高于EMM'S exp。
原版不成功时,可以试试这个。

src&exe http://www.cncert.net/up_files/soft/ms08067.net.rar

分类: 资源共享 标签: ,

Alexander Sotirov逆出来的MS08-067问题函数伪代码

2008年10月26日 没有评论 40 views

作者:tombkeeper

这个Biu漏洞分配给了小四。小四说,不必着急,一定会有人指着这个扬名立万,可以稍微等等。果不其然,吃完午饭上来,就有人放PoC出来了。

昨天晚上,“Father of China PT”又问我想不想写ms08-067的代码。我说这么赶着写这个干嘛呀,咱们也不急着下大雨。“Father of China PT”说:这个漏洞大家都在盯着,写了就流芳百世了。我说:关键是想流芳百世的人那么多,咱们又不急用,等两天,各种代码肯定会乌泱乌泱铺天盖地而来,就 跟当年ms03-026一样,咱们可以捡个现成。

结果今天早晨发现Alexander Sotirov连逆的代码贴出来了。这段代码很有教学意义,我打算收到我的案例库里去。

顺便说一句,这个Alexander Sotirov下个月会来XCon演讲“Bypassing browser memory protections in Windows Vista”。

From http://www.phreedom.org/blog/2008/decompiling-ms08-067/
Decompiling the vulnerable function for MS08-067
Oct 24, 2008

I spent a couple of hours tonight reversing the vulnerable code responsible for the MS08-067 vulnerability. This bug is pretty interesting, because it is in the same area of code as the MS06-040 buffer overflow, but it was completely missed by all security researchers and Microsoft. It's quite embarassing.

Here's the code of the vulnerable function on Windows XP SP3:

#include <wchar.h>

// This is the decompiled function sub_5B86A51B in netapi32.dll on XP SP3

int ms08_067(wchar_t* path)
{
wchar_t* p;
wchar_t* q;
wchar_t* previous_slash = NULL;
wchar_t* current_slash  = NULL;
wchar_t  ch;

// If the path starts with a server name, skip it

if ((path[0] == L'\\' || path[0] == L'/') &&
(path[1] == L'\\' || path[1] == L'/'))
{
p = path+2;

while (*p != L'\\' || *p != L'/') {
if (*p == L'\0')
return 0;
p++;
}

p++;

// make path point after the server name

path = p;

// make sure the server name is followed by a single slash

if (path[0] == L'\\' || path[0] == L'/')
return 0;
}

if (path[0] == L'\0')   // return if the path is empty
return 1;

// Iterate through the path and canonicalize ..\ and .\

p = path;

while (1) {
if (*p == L'\\') {
// we have a slash

if (current_slash == p-1)   // don't allow consequtive slashes
return 0;

// store the locations of the current and previous slashes

previous_slash = current_slash;
current_slash = p;
}
else if (*p == L'.' && (current_slash == p-1 || p == path)) {
// we have \. or ^.

if (p[1] == L'.' && (p[2] == L'\\' || p[2] == L'\0')) {
// we have a \..\, \..$, ^..\ or ^..$ sequence

if (previous_slash == NULL)
return 0;

// example: aaa\bbb\..\ccc
//             ^   ^  ^
//             |   |  &p[2]
//             |   |
//             |   current_slash
//             |
//             previous_slash

ch = p[2];

wcscpy(previous_slash, &p[2]);

if (ch&nbs
p;== L'\0')
return 1;

current_slash = previous_slash;
p = previous_slash;

// find the slash before p

// BUG: if previous_slash points to the beginning of the
// string, we'll go beyond the start of the buffer
//
// example string: \a\..\

q = p-1;

while (*q != L'\\' && q != path)
q--;

if (*p == L'\\')
previous_slash = q;
else
previous_slash = NULL;
}
else if (p[1] == L'\\') {
// we have \.\ or ^.\

if (current_slash != NULL) {
wcscpy(current_slash, &p[1]);
goto end_of_loop;
}
else { // current_slash == NULL
wcscpy(p, p+2);
goto end_of_loop;
}
}
else if (p[1] != L'\0') {
// we have \. or ^. followed by some other char

if (current_slash != NULL) {
p = current_slash;
}
*p = L'\0';
return 1;
}
}

p++;

end_of_loop:
if (*p == L'\0')
return 1;
}
}

// Run this program to simulate the MS08-067 vulnerability

int main()
{
return ms08_067(L"\\a\\..\\");
}

分类: 技术文章 标签:

关于MS08-067的一点细节

2008年10月26日 没有评论 57 views

作者:

这个漏洞就不介绍了,已经沸沸扬扬了。

首先milw0rm上那个exp的编译问题,作者在里面放的些小trick很容易fix,主要麻烦的是midl编译idl文件后,在VC6环境下编译可能出现rcpt库的错误。可能是SDK的版本导致的,云舒用最新的SDK(好像是2008?)编译成功了。

其次是触发问题,什么权限都不需要,空连接后就能触发。

ncacn_np:\\\\192.168.152.101[\\pipe\\srvsvc] 直接请求就可以了。

问题还是出在 NetpwPathCanonicalize() 的第二个参数,这个漏洞非常奇特。

首先这个参数的长度不能超过 0x207(unicode)

71BB58F6    81FF 07020000   CMP EDI,207
71BB58FC ^ 0F87 F447FFFF   JA NETAPI32.71BAA0F6   // 如果大于了就直接函数返回了
71BB5902 ^ E9 1247FFFF     JMP NETAPI32.71BAA019

然后会走到一个wcscat的地方,这里没有问题,因为空间是足够的
71BAA019    8D85 E8FBFFFF   LEA EAX,DWORD PTR SS:[EBP-418]
71BAA01F    53              PUSH EBX
71BAA020    50              PUSH EAX
71BAA021    FF15 9810BA71   CALL DWORD PTR DS:[<&msvcrt.wcscat>]     ; msvcrt.wcscat

继续往下会把所有的 "/" 替换为 "\" 这里也无关紧要

然后就走到出问题的函数

71BAA05A    8D85 E8FBFFFF   LEA EAX,DWORD PTR SS:[EBP-418]
71BAA060    50              PUSH EAX
71BAA061    E8 AB020000     CALL NETAPI32.71BAA311

跟进去后很复杂,可以参考下这里的伪代码

http://www.phreedom.org/blog/2008/decompiling-ms08-067/

估计很多人在这里绕晕了,我跟了一晚上,总算搞明白了一点。

首先是为什么老是会上溢的问题,这个就是这个漏洞的原因所在了。cocoruder在blog上引用了这么一段话:
There are two copies, the first copy is OK, but when there is another "..\", it will lead to start the another copy (repeat the first copy codes), the second copy firstly does not calculate the base pointer correctly (firstly it is basePointer-2, so the 'JZ' checking in the loop of searching character '\' will never come ture), that lead to get an unexpected stack pointer which is below the base pointer, after the wrong calculation, it starts the second copy and uses the unexpected pointer as the first parameter of function "wcscpy()", therefore, the wrong-calculation memory will be rewritten. The EIP will be controlled in the main function, probably.

实际上就是在找目录的时候,

\x\..\yyyyyyyyyyyyy

会拷贝为 \yyyyyyyyyyyy   中间的 \x\.. 就没有了。

然后程序会往栈的上面去找 "\" 的存在,但是往往栈低址里没有 "\"的存在,所以就找完了整个栈,上溢了。

很多同学估计都卡在这个地方了。

bp 0x71baa398 first copy 第一次拷贝,这里没问题

71BCDC12    8D46 04         LEA EAX,DWORD PTR DS:[ESI+4]
71BCDC15    8BCE            MOV ECX,ESI
71BCDC17    50              PUSH EAX
71BCDC18    51              PUSH ECX
71BCDC19    FF15 2C10BA71   CALL DWORD PTR DS:[<&msvcrt.wcscpy>]     ; msvcrt.wcscpy

此时 si = 0x2e 然后前后判断是否是 \..\

71BAA363    8D46 FE         LEA EAX,DWORD PTR DS:[ESI-2]
71BAA366    3BD8            CMP EBX,EAX
71BAA368    0F85 50380200   JNZ NETAPI32.71BCDBBE
71BAA36E    8D46 02         LEA EAX,DWORD PTR DS:[ESI+2]
71BAA371    66:8B10         MOV DX,WORD PTR DS:[EAX]
71BAA374    66:83FA 2E      CMP DX,2E
71BAA378    0F85 8A380200   JNZ NETAPI32.71BCDC08
71BAA37E    8D46 04         LEA EAX,DWORD PTR DS:[ESI+4]
71BAA381    66:8B18         MOV BX,WORD PTR DS:[EAX]
71BAA384    66:83FB 5C      CMP BX,5C

second copy 第二个拷贝,把中间的 \x\.. 弄没了
71BAA388   /0F85 3D380200   JNZ NETAPI32.71BCDBCB
71BAA38E   |85FF            TEST EDI,EDI
71BAA390   |0F84 0B630000   JE NETAPI32.71BB06A1
71BAA396   |50              PUSH EAX
71BAA397   |57              PUSH EDI
71BAA398   |FF15 2C10BA71   CALL DWORD PTR DS:[<&msvcrt.wcscpy>]     ; msvcrt.wcscpy

漏洞代码就是下面这个:
71BCDBDE    8D47 FE         LEA EAX,DWORD PTR DS:[EDI-2]
71BCDBE1    66:8338 5C      CMP WORD PTR DS:[EAX],5C
71BCDBE5   /75 18           JNZ SHORT NETAPI32.71BCDBFF
71BCDBE7   |66:8B38         MOV DI,WORD PTR DS:[EAX]
71BCDBEA   |8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]
71BCDBED   |66:83EF 5C      SUB DI,5C
71BCDBF1   |66:F7DF         NEG DI
71BCDBF4   |1BFF            SBB EDI,EDI
71BCDBF6   |F7D7            NOT EDI
71BCDBF8   |23F8            AND EDI,EAX
71BCDBFA ^|E9 55C7FDFF     JMP NETAPI32.71BAA354
71BCDBFF   \3B45 08         CMP EAX,DWORD PTR SS:[EBP+8]
71BCDC02 ^ 74 E3           JE SHORT NETAPI32.71BCDBE7
71BCDC04    48              DEC EAX
71BCDC05    48              DEC EAX
71BCDC06 ^ EB D9           JMP SHORT NETAPI32.71BCDBE1

试图往栈低址去寻找"\",结果错误计算了开始的地址,导致根本找不到。

按照cocoruder的说法,在计算错误后,有机会第二次执行第二个 wcscpy ,从而覆盖那个错误计算出的地址。

不过我没找到能再次执行拷贝的方法,我的整个栈低址几乎就是一片0,每次都上溢了.

有的机器里也许能够找到那个“\”
吧,或者存在一种能够稳定利用的方法。

使用 \\pipe\browser 好像也有机会控制EIP,可以继续搞搞。

瞎扯到这里,不说了,大家再一起继续郁闷吧。

分类: 技术文章 标签:

MS08067补丁前后比较分析结果

2008年10月26日 没有评论 80 views

作者:Friddy

MS08-067: Server 服务中的漏洞可能允许远程代码执行
http://www.microsoft.com/china/technet/security/bulletin/MS08-067.mspx
这条更新为重要,可以说与当年的冲击波类似。上午我对补丁前后分析,定位到微软修改过的函数结果如下:

发生缓冲区溢出的函数:
signed int __stdcall sub_5FDDA180(int a1, wchar_t *a2, int a3, int a4, int a5)
{
wchar_t *v5; // ebx@1
size_t v6; // edi@1
int v7; // esi@1
int v8; // edi@3
signed int result; // eax@4
wchar_t *v10; // eax@5
unsigned int v11; // eax@10
size_t v12; // eax@14
__int16 v13; // ax@16
size_t v14; // eax@3
int v15; // [sp+428h] [bp-4h]@1
wchar_t *v16; // [sp+10h] [bp-41Ch]@1
int v17; // [sp+Ch] [bp-420h]@1
wchar_t v18; // [sp+14h] [bp-418h]@2

v5 = a2;
v15 = dword_5FE1E18C;
v7 = a1;
v16 = (wchar_t *)a3;
v6 = 0;
v17 = a5;
if ( a1 && *(_WORD *)a1 )
{
v12 = wcslen((const wchar_t *)a1);
v6 = v12;
if ( v12 )
{
if ( v12 > 0x208 )
return 123;
wcscpy(&v18, (const wchar_t *)v7);
v13 = LOWORD((&v16)[v6 + 1]);
if ( v13 != 92 )
{
if ( v13 != 47 )
{
wcscat(&v18, &word_5FDECBD4);
++v6;
}
}
if ( *v5 == 92 || *v5 == 47 )
++v5;
}
}
else
{
v18 = 0;
}
v14 = wcslen(v5);
v8 = v14 + v6;
if ( v8 < v14 )
return 123;
if ( (unsigned int)v8 > 0x207 )
return 123;
wcscat(&v18, v5);
v10 = &v18;
if ( v18 )
{
do
{
if ( *v10 == 47 )
*v10 = 92;
++v10;
}
while ( *v10 );
}
if ( !sub_5FDD9F7A(&v18) && !sub_5FDDA26B((int)&v18) )//这个函数修改过了
return 123;
v11 = 2 * wcslen(&v18) + 2;
if ( v11 > a4 )
{
if ( v17 )
*(_DWORD *)v17 = v11;
result = 2123;
}
else
{
wcscpy(v16, &v18);//缓冲区溢出点
result = 0;
}
return result;
}

被修改的函数:
//----- (5FDDA26B) --------------------------------------------------------
signed int __stdcall sub_5FDDA26B(int a1)
{
wchar_t v1; // ax@1
int v2; // ecx@1
int v3; // ebx@1
int v4; // edi@1
int v5; // esi@3
int v6; // eax@10
__int16 v7; // dx@10
__int16 v8; // bx@11
__int16 v10; // dx@17
int v11; // ecx@18
__int16 v12; // ax@19
int v13; // eax@34
wchar_t *v14; // ecx@41
char v15; // zf@1
int v16; // [sp+Ch] [bp-4h]@1

v2 = a1;
v1 = *(_WORD *)a1;
v3 = 0;
v4 = 0;
v15 = *(_WORD *)a1 == 92;
v16 = 0;
if ( v15 || v1 == 47 )
{
v10 = *(_WORD *)(a1 + 2);
if ( v10 == 92 || v10 == 47 )
{
v11 = a1 + 4;
while ( 1 )
{
v12 = *(_WORD *)v11;
if ( *(_WORD *)v11 == 92 )
break;
if ( v12 == 47 )
break;
if ( !v12 )
return 0;
v11 += 2;
}
if ( !*(_WORD *)v11 || (v2 = v11 + 2, v1 = *(_WORD *)v2, a1 = v2, v1 == 92) || v1 == 47 )
return 0;
}
}
v5 = v2;
if ( !v1 )
return 1;
while ( 1 )
{
if ( v1 == 92 )
{
if ( v3 == v5 - 2 )
return 0;
v4 = v3;
v16 = v5;
goto LABEL_6;
}
if ( v1 != 46 || v3 != v5 - 2 && v5 != v2 )
goto LABEL_6;
v6 = v5 + 2;
v7 = *(_WORD *)(v5 + 2);
if ( v7 == 46 )
{
v8 = *(_WORD *)(v5 + 4);
if ( v8 == 92 || !v8 )
{
if ( !v4 )
return 0;
wcscpy((wchar_t *)v4, (const wchar_t *)(v5 + 4)); //可能会发生缓冲区溢出
if ( !v8 )
return 1;
v16 = v4;
v5 = v4;
v13 = v4 - 2;
while ( *(_WORD *)v13 != 92 && v13 != a1 )
v13 -= 2;
v2 = a1;
v4 = v13 & -(*(_WORD *)v13 == 92);
}
goto LABEL_6;
}
if ( v7 != 92 )
break;
if ( v3 )
{
v14 = (wchar_t *)v3;
}
else
{
v6 = v5 + 4;
v14 = (wchar_t *)v5;
}
wcscpy(v14, (const wchar_t *)v6);//可能会发生缓冲区溢出
v2 = a1;
LABEL_7:
v1 = *(_WORD *)v5;
if ( !*(_WORD *)v5 )
return 1;
v3 = v16;
}
if ( v7 )
{
LABEL_6:
v5 += 2;
goto LABEL_7;
}
if ( v3 )
v5 = v3;
*(_WORD *)v5 = 0;
return 1;
}

分类: 技术文章 标签: