Alexander Sotirov逆出来的MS08-067问题函数伪代码
2008-10-27 13:30:31 来源:WEB开发网这个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'')
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'') // 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'')) {
// we have a .., ..$, ^.. or ^..$ sequence
if (previous_slash == NULL)
return 0;
// example: aaabbb..ccc
// ^ ^ ^
// | | &p[2]
// | |
// | current_slash
// |
// previous_slash
ch = p[2];
wcscpy(previous_slash, &p[2]);
if (ch == L'')
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'') {
// we have . or ^. followed by some other char
if (current_slash != NULL) {
p = current_slash;
}
*p = L'';
return 1;
}
}
p++;
end_of_loop:
if (*p == L'')
return 1;
}
}
// Run this program to simulate the MS08-067 vulnerability
int main()
{
return ms08_067(L"a..");
}
更多精彩
赞助商链接