Я столкнулся с концепцией «безопасного рабочего стола», используемой в Google Chrome и некоторых менеджерах паролей, таких как KeePass.В Chrome защищенный рабочий стол является рабочим столом с ограниченным доступом для процессов Chrome и надежно защищен, в KeePass так называемый безопасный рабочий стол предназначен для диалога мастер-пароля.Но в KeePass кажется, что они просто создают другой рабочий стол, не устанавливая DACL для его реальной защиты.Для меня безопасный рабочий стол - это то, что любой другой процесс, работающий на том же рабочем столе, не может открывать и вводить.
Я спросил себя, возможно ли иметь отдельный рабочий стол, на котором можно запустить приложение и отделить его?это из других процессов.Это включает в себя, например, собранное приложение, которое злоумышленник использует не по назначению для сбора нажатий клавиш или экрана.
С помощью функций API CreateDesktop, ConvertStringSecurityDescriptorToSecurityDescriptor и SetUserObjectSecurity я могу создать другой рабочий стол, а также уменьшить права доступа.Но если я слишком строг, я не могу запустить процесс там, и если я слишком небрежен, то вновь созданный рабочий стол слишком открыт, поэтому злоумышленник может открыть рабочий стол и переключить на него свой поток.
Кто-нибудь из вас, ребята, знает строковую комбинацию SecurityDescriptor, которую я могу использовать, чтобы вновь созданный рабочий стол был действительно защищен, поэтому никакое другое приложение, кроме Creator-Process и его дочерних процессов, которые запускают процессы на защищенном рабочем столе, не в состояниипереключать и создавать там процессы?
Любые предложения или подсказки приветствуются.
Допущения:
- Пользователь со стандартными (не администраторскими) привилегиями
- Система защищена SRP / AppLocker
- Никакой вредоносный процесс не рассматривается как отдельный процесс только как часть эксплойта в атакованном процессе (например, в браузере, офисе или программе просмотра PDF).
Вот мой код, который я сейчас использую:
#include <windows.h>
#include <stdio.h>
#include <Sddl.h>
#include <AclAPI.h>
#include <time.h>
static const unsigned char nameCharTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-[]()<>@~#.:%&$§=";
// create new desktop or open an already existing one
HDESK CreateHiddenDesktop(CHAR *desktop_name)
{
CHAR explorer_path[MAX_PATH];
HDESK hNewDesktop = NULL, hOldDesktop;
STARTUPINFOA startup_info = { 0 };
PROCESS_INFORMATION process_info = { 0 };
ExpandEnvironmentStringsA("%windir%\\notepad.exe", explorer_path, MAX_PATH - 1);
hNewDesktop = OpenDesktopA(desktop_name, NULL, FALSE, GENERIC_ALL);
if (!hNewDesktop)
{
hNewDesktop = CreateDesktopA(desktop_name, NULL, NULL, 0, GENERIC_ALL, NULL);
if (hNewDesktop)
{
hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
if (SetThreadDesktop(hNewDesktop))
{
BOOL bRet = FALSE;
PSECURITY_DESCRIPTOR SecDes = NULL;
// just for us to obtain hex values we can use with ConvertStringSecurityDescriptorToSecurityDescriptor
DWORD access = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER | DESKTOP_CREATEMENU |
DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS | ACCESS_SYSTEM_SECURITY;
access = DESKTOP_ENUMERATE | WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY;
printf("Access mask in hex: 0x%08x.\n", access);
//bRet = ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT("D:P(D;OICI;GARCSDWDWO;;;WD)(A;OICI;GAGRGWGXRCSDWDWOWPCCCR;;;CO)"), SDDL_REVISION_1, &SecDes, NULL);
bRet = ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT("D:P(OD;OICI;0x010c0040;;;WD)(OA;OICI;0xffffffff;;;WD)"), SDDL_REVISION_1, &SecDes, NULL);
if (bRet)
{
BOOL bSaclDefaulted = FALSE;
BOOL bSaclPresent = FALSE;
PACL SecACL = NULL;
SECURITY_INFORMATION si;
si = DACL_SECURITY_INFORMATION;
if (SetUserObjectSecurity(hNewDesktop, &si, SecDes)) {
printf("SetUserObjectSecurity succeeded.\n");
}
}
// create process and wait until it is initialized and ready
startup_info.cb = sizeof(startup_info);
startup_info.lpDesktop = desktop_name;
CreateProcessA(explorer_path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startup_info, &process_info);
WaitForInputIdle(process_info.hProcess, INFINITE);
// handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed.
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
SetThreadDesktop(hOldDesktop);
}
}
}
return hNewDesktop;
}
int main(int argc, char **argv) {
HDESK hOldDesktop, hNewDesktop;
MSG msg = { 0 };
char desktopName[128] = { 0 };
BOOLEAN binNewDesktop = FALSE;
srand((unsigned int)time(NULL));
for (int i = 0; i < 8; i++) {
desktopName[i] = nameCharTable[rand() % (sizeof(nameCharTable)-1)];
}
// just for debugging and testing: print the desktop's name
printf("Desktop's name: %s\n", desktopName);
hNewDesktop = CreateHiddenDesktop(desktopName);
hOldDesktop = GetThreadDesktop(GetCurrentThreadId());
printf("Entering the hidden desktop\n");
// switch thread into context of new desktop to register hotkeys
SetThreadDesktop(hNewDesktop);
SwitchDesktop(hNewDesktop);
binNewDesktop = TRUE;
RegisterHotKey(NULL, 0, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 0x53); // S = switch desktop
RegisterHotKey(NULL, 1, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 0x51); // Q = quit
while (GetMessage(&msg, NULL, 0, 0) != 0) {
if (msg.message==WM_HOTKEY) {
// switch Desktop hotkey
if (msg.wParam == 0) {
if (binNewDesktop) {
UnregisterHotKey(NULL, 0);
UnregisterHotKey(NULL, 1);
SetThreadDesktop(hOldDesktop);
SwitchDesktop(hOldDesktop);
RegisterHotKey(NULL, 0, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 0x53); // S = switch desktop
RegisterHotKey(NULL, 1, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 0x51); // Q = quit
binNewDesktop = FALSE;
}
else {
UnregisterHotKey(NULL, 0);
UnregisterHotKey(NULL, 1);
SetThreadDesktop(hNewDesktop);
SwitchDesktop(hNewDesktop);
RegisterHotKey(NULL, 0, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 0x53); // S = switch desktop
RegisterHotKey(NULL, 1, MOD_CONTROL | MOD_ALT | MOD_NOREPEAT, 0x51); // Q = quit
binNewDesktop = TRUE;
}
}
// switch Quit hotkey
if (msg.wParam == 1) {
printf("Exiting hidden desktop\n");
UnregisterHotKey(NULL, 0);
UnregisterHotKey(NULL, 1);
SwitchDesktop(hOldDesktop);
SetHandleInformation(hNewDesktop, 0, 0);
SwitchDesktop(hOldDesktop);
CloseDesktop(hNewDesktop);
CloseDesktop(hOldDesktop);
//getchar();
break;
}
}
}
return 0;
}