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的流程跃然纸上。