Skip to content

4) samsrv!SampGetCurrentAdminPassword()

用IDA Pro逆向英文版XP SP1的samsrv!SampGetCurrentAdminPassword:

下面是C风格的伪代码:


/ * 标号SampUpdateEncryption_exit不直接对应汇编代码中的标号 * * 由主调函数确保第一形参UserInfoBuf不为NULL / NTSTATUS __stdcall SampGetCurrentAdminPassword ( PSAM_USER_OWF_PASSWORD_INFORMATION UserInfoBuf // 第01形参,[EBP+0x008] ) { PSAM_USER_OWF_PASSWORD_INFORMATION UserOWFPasswordInfo; // 第01个局部变量,[EBP-0x004] NTSTATUS status; // 第02个局部变量,[EBP-0x008] HANDLE UserHandle; // 第03个局部变量,[EBP-0x00C] HANDLE DomainHandle; // 第04个局部变量,[EBP-0x010] / * typedef struct _POLICY_ACCOUNT_DOMAIN_INFO * { * LSA_UNICODE_STRING DomainName; * PSID DomainSid; * } POLICY_ACCOUNT_DOMAIN_INFO, PPOLICY_ACCOUNT_DOMAIN_INFO; */ PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo; // 第05个局部变量,[EBP-0x014] HANDLE SamHandle; // 第06个局部变量,[EBP-0x018]

PolicyAccountDomainInfo = ( PPOLICY_ACCOUNT_DOMAIN_INFO )NULL;
UserOWFPasswordInfo     = ( PSAM_USER_OWF_PASSWORD_INFORMATION )NULL;
SamHandle               = ( HANDLE )NULL;
DomainHandle            = ( HANDLE )NULL;
UserHandle              = ( HANDLE )NULL;
status                  = SamIConnect
                          (
                              0,
                              &SamHandle,   // [out]参数
                              0x10000000,   // Access Mask,参SamrConnect2()的Ethereal解码
                              1
                          );
if ( !NT_SUCCESS( status ) )
{
    goto SampGetCurrentAdminPassword_exit;
}
/*
 * 隐式动态分配空间,需要释放!
 */
status                  = SampGetAccountDomainInfo
                          (
                              &PolicyAccountDomainInfo
                          );
if ( !NT_SUCCESS( status ) )
{
    goto SampGetCurrentAdminPassword_exit;
}
status                  = SamrOpenDomain
                          (
                              SamHandle,
                              0x10000000,                           // Access Mask,参Ethereal解码
                              PolicyAccountDomainInfo->DomainSid,
                              &DomainHandle                         // [out]参数
                          );
if ( !NT_SUCCESS( status ) )
{
    goto SampGetCurrentAdminPassword_exit;
}
status                  = SamrOpenUser
                          (
                              DomainHandle,
                              0x10000000,       // Access Mask,参Ethereal解码
                              500,              // RID,0x1F4,Administrator
                              &UserHandle       // [out]参数
                          );
if ( !NT_SUCCESS( status ) )
{
    goto SampGetCurrentAdminPassword_exit;
}
/*
 * 隐式动态分配空间,需要释放!
 */
status                  = SamrQueryInformationUser2
                          (
                              UserHandle,
                              SamUserOWFPasswordInformation,    // InformationClass,0x12
                              &UserOWFPasswordInfo
                          );
if ( !NT_SUCCESS( status ) )
{
    goto SampGetCurrentAdminPassword_exit;
}
/*
 * 这里居然没有动用SEH机制进行保护,不可思议,想必在外圈另有保护吧。
 */
CopyMemory
(
    UserInfoBuf,                                    // dst
    UserOWFPasswordInfo,                            // src
    sizeof( SAM_USER_OWF_PASSWORD_INFORMATION )     // 35个字节
);
/*
 * 安全起见,对用过的敏感数据缓冲区清零。
 */
ZeroMemory
(
    UserOWFPasswordInfo,
    sizeof( SAM_USER_OWF_PASSWORD_INFORMATION )     // 35个字节
);

SampGetCurrentAdminPassword_exit:

if ( NULL != UserOWFPasswordInfo )
{
    /*
     * 与SamrQueryInformationUser2()配对
     */
    SamIFree_SAMPR_USER_INFO_BUFFER
    (
        UserOWFPasswordInfo,
        SamUserOWFPasswordInformation   // InformationClass,0x12
    );
}
if ( NULL != UserHandle )
{
    /*
     * 与SamrOpenUser()配对
     */
    SamrCloseHandle( &UserHandle );
}
if ( NULL != DomainHandle )
{
    /*
     * 与SamrOpenDomain()配对
     */
    SamrCloseHandle( &DomainHandle );
}
if ( NULL != PolicyAccountDomainInfo )
{
    /*
     * 与SampGetAccountDomainInfo()配对
     */
    LsaIFree_LSAPR_POLICY_INFORMATION
    (
        PolicyAccountDomainInformation,     // PolicyAccountDomainInformation(5),枚举值
        PolicyAccountDomainInfo
    );
}
if ( NULL != SamHandle )
{
    /*
     * 与SamIConnect()配对
     */
    SamrCloseHandle( &SamHandle );
}
return( status );

} / end of SampGetCurrentAdminPassword /

将SampUpdateEncryption、SampGetCurrentAdminPassword结合一下,获取LM Hash、 NTLM Hash的流程跃然纸上。