/* * Windows XP WEP key recovery program * * Copyright (C) 2006,2007 Thomas d'Otreppe * Copyright (C) 2004,2005 Christophe Devine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "console.h" int prompt_exit( int retval ) { int i; printf( "\n Keys have been stored in C:\\wepkeys.txt. Press Ctrl-C.\n" ); scanf( "%d", &i ); exit( retval ); } int zero_key[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; int xor_key[32] = { 0x56, 0x66, 0x09, 0x42, 0x08, 0x03, 0x98, 0x01, 0x4D, 0x67, 0x08, 0x66, 0x11, 0x56, 0x66, 0x09, 0x42, 0x08, 0x03, 0x98, 0x01, 0x4D, 0x67, 0x08, 0x66, 0x11, 0x56, 0x66, 0x09, 0x42, 0x08, 0x03 }; #define WZCSVC_LIST "Software\\Microsoft\\WZCSVC\\Parameters\\Interfaces" char ServiceName[] = "WZCOOK"; char DisplayName[] = "WEP/WPA-PMK key recovery service"; typedef struct { DWORD cbData; BYTE* pbData; } DATA_BLOB; typedef BOOL (WINAPI *PROC1) (DATA_BLOB *,void *,void *,void *, void *,void *,DATA_BLOB *); char * filename = "c:\\wepkeys.txt"; void WINAPI myHandler( DWORD fdwControl ) { if( fdwControl == SERVICE_CONTROL_SHUTDOWN ) { ExitProcess( 0 ); } } void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv ) { FILE *f_out; char buffer[1024]; char keystr[1024]; int length, keytype, i; int keyidx1, keyidx2; HMODULE hCrypt32dll; PROC1 CryptUnprotectData; HKEY regkey_iface; HKEY regkey_wzcsvc; DATA_BLOB pIn, pOut; SERVICE_STATUS_HANDLE sth; SERVICE_STATUS status; sth = RegisterServiceCtrlHandler( ServiceName, myHandler ); memset( &status, 0, sizeof( SERVICE_STATUS ) ); status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; status.dwCurrentState = SERVICE_RUNNING; status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN; status.dwWin32ExitCode = NO_ERROR; SetServiceStatus( sth, &status ); if( ( f_out = fopen( filename, "w+" ) ) == NULL ) exit( 1 ); *stdin = *f_out; *stdout = *f_out; *stderr = *f_out; if( ! ( hCrypt32dll = LoadLibrary( "Crypt32.dll" ) ) ) { printf( " Fatal: LoadLibrary(Crypt32.dll) failed\n" ); exit( 1 ); } if( ! ( CryptUnprotectData = (PROC1) GetProcAddress( hCrypt32dll, "CryptUnprotectData" ) ) ) { printf( " Fatal: GetProcAddress(CryptUnprotectData) failed\n" ); exit( 1 ); } if( RegOpenKey( HKEY_LOCAL_MACHINE, WZCSVC_LIST, ®key_wzcsvc ) != ERROR_SUCCESS ) { printf( " Fatal: RegOpenKey(%s) failed\n", WZCSVC_LIST ); exit( 1 ); } keyidx1 = 0; printf( "\n ESSID WEP KEY / WPA PMK\n\n" ); while( RegEnumKey( regkey_wzcsvc, keyidx1, buffer, sizeof( buffer ) ) == ERROR_SUCCESS ) { sprintf( keystr, "%s\\%s", WZCSVC_LIST, buffer ); if( RegOpenKey( HKEY_LOCAL_MACHINE, keystr, ®key_iface ) != ERROR_SUCCESS ) { printf( " Error: RegOpenKey(%s) failed\n", keystr ); continue; } keyidx2 = 0; while( 1 ) { sprintf( keystr, "Static#%04d", keyidx2 ); length = sizeof( buffer ); memset( buffer, 0, length ); if( RegQueryValueEx( regkey_iface, keystr, NULL, &keytype, buffer, &length ) != ERROR_SUCCESS ) break; pIn.cbData = length - *(int *)(buffer); pIn.pbData = buffer + *(int *)(buffer); pOut.cbData = 0; pOut.pbData = 0; if( CryptUnprotectData( &pIn, NULL, NULL, NULL, NULL, 0, &pOut ) != TRUE ) { printf( " Error: CryptUnprotectData failed\n" ); keyidx2++; continue; } if( ! memcmp( pOut.pbData, zero_key, 32 ) ) { keyidx2++; continue; } printf( " %-32s ", buffer + 0x14 ); for( i = 0; i < (int) pOut.cbData; i++ ) printf( "%02X", pOut.pbData[i] ^ xor_key[i % 32] ); printf( "\n" ); keyidx2++; } RegCloseKey( regkey_iface ); keyidx1++; } RegCloseKey( regkey_wzcsvc ); exit( 0 ); } int main( int argc, char *argv[] ) { FILE *f_in; int userlen, silent; char buffer[512]; SC_HANDLE sc1, sc2; SERVICE_TABLE_ENTRY ste[2] = { { ServiceName, ServiceMain }, { NULL, NULL } }; silent = 0; userlen = sizeof( buffer ); GetUserName( buffer, &userlen ); if( ! strcmp( buffer, "SYSTEM" ) ) { StartServiceCtrlDispatcher( ste ); return( 1 ); } if (argc == 2) { silent = (strncmp(argv[1], "--silent", 8) == 0); } if (silent == 0) { set_console_icon( " WZCOOK - WEP/WPA-PMK Key Recovery Service from " \ "XP's Wireless Zero Configuration utility " ); set_console_size( 50, 102 ); } if( sc1 = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ) ) { if( sc2 = OpenService( sc1, ServiceName, SERVICE_ALL_ACCESS ) ) { DeleteService( sc2 ); if (silent == 0) MessageBox( NULL, "WZCOOK service has been deleted", "Information", MB_OK | MB_ICONINFORMATION ); } else { if( GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST ) { sc2 = CreateService( sc1, ServiceName, DisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, GetCommandLine(), NULL, NULL, NULL, NULL, NULL ); if( sc2 != NULL ) { StartService( sc2, 0, NULL ); Sleep( 2000 ); DeleteService( sc2 ); } else { if (silent == 0) MessageBox( NULL, "Could not create WZCOOK service", "Fatal error", MB_OK | MB_ICONERROR ); exit( 1 ); } } else { if (argc == 1) MessageBox( NULL, "Could not open WZCOOK service", "Fatal error", MB_OK | MB_ICONERROR ); exit( 1 ); } } } else { if (silent == 0) MessageBox( NULL, "Could not open service manager,\n" \ "maybe you're not an administrator ?", "Fatal error", MB_OK | MB_ICONERROR ); exit( 1 ); } if( sc2 != NULL ) CloseServiceHandle( sc2 ); if( sc1 != NULL ) CloseServiceHandle( sc1 ); if( ( f_in = fopen( filename, "r" ) ) == NULL ) { if (silent == 0) MessageBox( NULL, "Could not read c:\\wepkeys.txt, the " \ "WZCOOK service probably failed unexpectedly", "Fatal error", MB_OK | MB_ICONERROR ); exit( 1 ); } if (silent == 0) { while( fgets( buffer, sizeof( buffer ) - 1, f_in ) ) { printf( "%s", buffer ); Sleep( 500 ); } } fclose( f_in ); if (silent == 0) prompt_exit( 0 ); return( 0 ); }