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());