作者: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 == 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//..//"); }
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论