WEB开发网
开发学院网络安全安全技术 Alexander Sotirov逆出来的MS08-067问题函数伪代码... 阅读

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

 2008-10-27 13:30:31 来源:WEB开发网   
核心提示:这个Biu漏洞分配给了小四,小四说,Alexander Sotirov逆出来的MS08-067问题函数伪代码,不必着急,一定会有人指着这个扬名立万,我打算收到我的案例库里去,顺便说一句,可以稍微等等,果不其然

这个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..");
}

Tags:Alexander Sotirov 出来

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接