Создание безопасного рабочего стола в текущей сессии Windows (Winsta0 \ default) - PullRequest
0 голосов
/ 01 декабря 2018

Я столкнулся с концепцией «безопасного рабочего стола», используемой в 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...