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

admin 2017年4月29日07:36:20评论251 views字数 2593阅读8分38秒阅读模式
摘要

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

作者: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//..//"); }

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2017年4月29日07:36:20
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Alexander Sotirov逆出来的MS08-067问题函数伪代码 'shttps://cn-sec.com/archives/45723.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息