- 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 );
将SampUpdateEncryption、SampGetCurrentAdminPassword结合一下,获取LM Hash、 NTLM Hash的流程跃然纸上。