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