detect sandboxie

出于对sandboxie的兴趣,研究了一下sandboxie实现机制,再回到sandboxie detect这个大众话题,想了几个新的猥琐方式来检测sandboxie。
1) check_1 利用sandboxie创建的WindowStation
2) check_2 sandboxie对窗口的重命名 (实际上不仅仅是窗口,api前后设置/获取不一致都可以)
3) check_3 sandboxie与驱动的通信,打开的设备名
4) check_4 利用部分api实现的缺陷

typedef
NTSTATUS
(APIENTRY* _NtUserBuildNameList)(
    HWINSTA hWindowStation,
    ULONG dwSize,
    PVOID lpBuffer,
    PULONG pRequiredSize);

typedef BOOL(APIENTRY*
    _NtUserGetObjectInformation)(
        HANDLE hObject,
        DWORD nIndex,
        PVOID pvInformation,
        DWORD nLength,
        PDWORD nLengthNeeded);

typedef BOOL
(APIENTRY* _NtUserGetClassInfoEx)(
    IN HINSTANCE hInstance OPTIONAL,
    IN PUNICODE_STRING pstrClassName,
    IN OUT LPWNDCLASSEXW lpWndClass,
    OUT LPWSTR* ppszMenuName,
    IN BOOL bAnsi);

typedef
int
(APIENTRY* _NtUserGetClassName)(
	IN HWND hwnd,
	IN BOOL bReal,
	IN OUT PUNICODE_STRING pstrClassName);


_NtUserBuildNameList g_NtUserBuildNameList = NULL;
_NtUserGetObjectInformation g_NtUserGetObjectInformation = NULL;
_NtUserGetClassInfoEx g_NtUserGetClassInfoEx = NULL;
_NtUserGetClassName g_NtUserGetClassName = NULL;

bool init() {
    HMODULE h =  LoadLibraryW(L"win32u.dll");
    g_NtUserBuildNameList = (_NtUserBuildNameList)GetProcAddress(h, "NtUserBuildNameList");
    g_NtUserGetObjectInformation = (_NtUserGetObjectInformation)GetProcAddress(h, "NtUserGetObjectInformation");
    g_NtUserGetClassInfoEx = (_NtUserGetClassInfoEx)GetProcAddress(h, "NtUserGetClassInfoEx");
    g_NtUserGetClassName = (_NtUserGetClassName)GetProcAddress(h, "NtUserGetClassName");

    return true;
}

BOOL check_1() {

    vector<wstring> all_station;

    //Station
	PWCHAR Name;
	NTSTATUS Status;
	ULONG RequiredSize;
	ULONG CurrentEntry, EntryCount;
    ULONG pRequiredSize = 0;

    char NameList[1024 * 4] = { 0 };
    NTSTATUS  ret = g_NtUserBuildNameList(0, _countof(NameList), NameList, &pRequiredSize);

    if (NT_SUCCESS(ret))
    {
		EntryCount = *((DWORD*)NameList + 1);
		Name = (PWCHAR)((PCHAR)NameList + sizeof(DWORD) + sizeof(DWORD));
		
		for (CurrentEntry = 0; CurrentEntry < EntryCount; ++CurrentEntry)
		{
		    printf("%s %ws\n", __FUNCTION__, Name);

			all_station.push_back(Name);
			Name += wcslen(Name) + 1;
		}
    }

    return all_station.size() == 1 && all_station.at(0).find(L"Sandboxie_WinSta") != wstring::npos;
}


bool check_2() {
	WNDCLASSEX wcx;
	//初始化窗口结构体

	wcx.cbSize = sizeof(WNDCLASSEX);
	wcx.style = CS_HREDRAW | CS_VREDRAW;
	wcx.lpfnWndProc = DefWindowProc;
	wcx.cbClsExtra = 0;
	wcx.cbWndExtra = 0;
	wcx.hInstance = NULL;
	wcx.hIcon = LoadIcon(0, IDI_APPLICATION);
	wcx.hCursor = LoadCursor(0, IDC_ARROW);
	wcx.hbrBackground = 0;
	wcx.lpszMenuName = NULL;
	wcx.lpszClassName = L"MainWindow";
	wcx.hIconSm = 0;

	//注册一个窗口
	static ATOM wc = RegisterClassEx(&wcx);

	if (wc)
	{
		HWND hWnd = CreateWindow(L"MainWindow", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
        if (hWnd)
        {
            TCHAR buf[MAX_PATH] = { 0 };
			UNICODE_STRING strClassName;

			strClassName.MaximumLength = (USHORT)sizeof(buf);
			strClassName.Buffer = buf;

            if (NT_SUCCESS(g_NtUserGetClassName(hWnd, 0, &strClassName))) {
                printf("%s %ws\n", __FUNCTION__, strClassName.Buffer);

                if (StrStrW(strClassName.Buffer, L"Sandbox:"))
                {
                    return true;
                }
            }
        }
	}

	return false;
}


bool check_3() {
    
    string str;
    str.resize(1024 * 4);
    ULONG ReturnLength = 0;
	for (;;)
	{
        NTSTATUS ErrorCode = NtQuerySystemInformation(SystemHandleInformation, (PVOID)str.data(), ULONG(str.size()), &ReturnLength);
		if (ErrorCode != STATUS_INFO_LENGTH_MISMATCH)
			break;
		
        str.resize(ReturnLength);
	}
    PSYSTEM_HANDLE_INFORMATION phi = (PSYSTEM_HANDLE_INFORMATION)str.data();
    for (ULONG  i = 0; i < phi->NumberOfHandles; ++i)
    {
        if (phi->Handles[i].UniqueProcessId != GetCurrentProcessId())
        {
            continue;
        }

        char buf[1024 * 4] = { 0 };
        if (NT_SUCCESS(NtQueryObject((HANDLE)phi->Handles[i].HandleValue, ObjectNameInformation, buf, _countof(buf), NULL)))
        {
            OBJECT_TYPE_INFORMATION* oti = (OBJECT_TYPE_INFORMATION*)buf;
            if (oti->TypeName.Buffer && 0 == memcmp(oti->TypeName.Buffer, L"\\Device\\SandboxieDriverApi", oti->TypeName.Length))
			{
                printf("%s %ws\n", __FUNCTION__, oti->TypeName.Buffer);
                return true;
            }
        }
    }
	return false;
}

bool check_4() {
 
    struct xxx {
        void* p1;
        void* p2;
        ULONG_PTR tag;
        char buf[MAX_PATH];
    };

    xxx x;
    ZeroMemory(&x, sizeof(x));
    x.tag = 'xobs';
 

	__try {
        return UnhookWindowsHookEx((HHOOK)(&x));
	}
	__except (EXCEPTION_EXECUTE_HANDLER) {
        return true;
	}

    return false;
}


init();
printf("check_1 result %x\n", check_1());
printf("check_2 result %x\n", check_2());
printf("check_3 result %x\n", check_3());
printf("check_4 result %x\n", check_4());


posted @ 2022-05-24 13:11  tieyan  阅读(148)  评论(0编辑  收藏  举报