Google Project Zero Sandbox Attack Surface Analysis Tools

repository·main·Indexed 25 days ago

https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools

A suite of PowerShell tools and managed libraries for analyzing Windows sandbox attack surfaces. The toolkit includes NtObjectManager for inspecting and manipulating the NT Object Manager namespace, NtCoreLib for accessing NT system calls, TokenViewer for process token manipulation, and EditSection for memory section analysis. It allows users to impersonate process tokens to determine access permissions from specific security contexts.

Tokens
2.1K
Snippets
5
Records
12
Agent score
56%

What's inside sandbox-attacksurface-analysis-tools

  1. Overview of sandbox-attacksurface-analysis-tools

    main

    This suite of PowerShell tools is designed to test various properties of sandboxes on Windows. Most tools utilize a -ProcessId flag to specify the PID of a sandboxed process. The tool then impersonates that process's token to determine the access allowed from that specific security context.

    Recommendation: Run these tools as an Administrator or Local System to ensure full system enumeration capabilities.

  2. Inspect and manipulate the NT Object Manager namespace

    main

    The NtObjectManager module provides a PowerShell drive provider to interact with the NT Object Manager, which functions similarly to a filesystem. This allows you to enumerate entries and modify properties within the namespace that are typically hidden from the Win32 API.

    Default Drives

    • NtObject:: Accesses the root namespace.
    • NtObjectSession:: Points to the current user session's BaseNamedObjects directory.

    Registry Access

    • NtKey:: Maps to the root of the Registry.
    • NtKeyUser:: Maps to the current user hive.

    Note: If you create a new drive with SeBackupPrivilege enabled, it will set backup mode, which bypasses most access control for the Registry.

  3. Prevent resource deletion when creating named resources

    main

    When creating named resources (e.g., using New-Nt* cmdlets), the name only persists as long as a handle to that resource exists. If the object is not assigned to a script variable, the garbage collector may finalize it, causing the kernel to delete the resource.

    To ensure all necessary parent directories and objects persist during creation, use the -CreateDirectories parameter. This parameter returns a list where the new object is at the head of the list, followed by the newly created directory objects. You must hold references to all objects in this list to keep the resource name alive.

    $ev = New-NtEvent \BaseNamedObjects\ABC\XYZ\EventName -CreateDirectories
    try {
      # Print out created event
      $ev[0] | Format-List
    } finally {
      # Dispose objects
      $ev.Dispose()
    }
  4. How to work with NT objects via the PS provider

    main

    Accessing the namespace follows standard PowerShell provider patterns. You can use Get-ChildItems to enumerate items and Get-Item to retrieve individual objects. The items returned are directory entries containing metadata like Name, Type, and SecurityDescriptor.

    Converting to a Handle

    To perform operations on an object (rather than just viewing its metadata), you must convert the directory entry into a handle using the .ToObject() method.

    CRITICAL: You must call the .Close() method on the object after you have finished using the handle to prevent resource leaks.

    $event = Get-Item NtObjectSession:\Eventname
    $event_obj = $event.ToObject()
    # ... perform operations ...
    $event_obj.Close()
  5. Component overview of the tool suite

    main

    The suite consists of several specialized tools and libraries:

    • EditSection: View and manipulate memory sections.
    • TokenViewer: View and manipulate various process token values.
    • NtCoreLib: A basic managed library for accessing NT system calls and objects.
    • NtCoreLib.Forms: Simple forms for viewing security descriptors and tokens.
    • NtObjectManager: A PowerShell module (using NtApiDotNet) that exposes the NT object manager.
    • ViewSecurityDescriptor: View security descriptors from an SDDL string or an inherited object.
  6. Mount private namespaces and custom drives

    main

    You can use New-PSDrive to mount specific parts of the NT namespace or private namespaces.

    Mounting Private Namespaces

    To map a private namespace, use the root name format: ntpriv:[SID[:SID]@]NAME. SIDs can be provided in SDDL format (e.g., S-X-X-X or short forms like BA).

    Examples

    Mount a global directory (e.g., BaseNamedObjects):

    New-PSDrive -PSProvider NtObjectManager -Name BNO -Root nt:BaseNamedObjects

    Mount a private namespace (e.g., with Everyone and Low Mandatory Level SIDs):

    New-PSDrive -PSProvider NtObjectManager -Name PrivNS -Root ntpriv:WD:LW@ABC

    Mount the Machine Registry Key:

    New-PSDrive -PSProvider NtObjectManager -Name MACHINEKEY -Root ntkey:MACHINE
  7. Manage resource lifetime in a pipeline using -CloseRoot

    main

    If you are creating a new object based on an existing object passed through the pipeline (the "root" object) and you do not need to maintain a reference to that root object, use the -CloseRoot parameter. This automatically closes the root object once the new object has been successfully created.

    $software_key = Get-NtKey \Registry\Machine\Software | New-NtKey MyKey -CloseRoot
    # Key object to \Registry\Machine\Software is automatically closed.
  8. Automatically dispose objects using Use-NtObject

    main

    The Use-NtObject cmdlet is used to execute a ScriptBlock with an input object (which can be from the pipeline) and ensures the object is disposed of immediately after the ScriptBlock completes.

    This is useful for:

    • Managing NtObject lifetimes.
    • Managing any IDisposable objects (like FileStream).
    • Disposing enumerations of IDisposable objects.

    To avoid polluting the variable namespace, you can pass the object directly into the cmdlet and use a param block within the script block.

    # Example 3: Using Use-NtObject to automatically close a list of processes
    $pinfo = Use-NtObject($ps = Get-NtProcess) { $ps | select Name, CommandLine }
    # $ps is now disposed of.
    
    # Example 4: Same as 3 but not polluting the variable namespace
    $pinfo = Use-NtObject (Get-NtProcess) { param($ps); $ps | select Name, CommandLine }
    # $ps no longer in scope
  9. Create new NT objects using New-Item

    main

    You can create several types of objects using New-Item. When using New-Item, the returned value is a handle to the underlying object (rather than a directory entry) to ensure the kernel does not delete the object immediately after creation.

    Supported -ItemType values:

    • Event
    • Directory
    • SymbolicLink (Use -ItemType Link for symbolic links)
    • Mutant
    • Semaphore (Requires -Value to specify the maximum semaphore count)

    Usage Examples:

    Create a Directory:

    $obj = New-Item NtObjectSession:\ABC -ItemType Directory
    $obj.Close()

    Create a Symbolic Link: Note: You must use -ItemType Link and provide a target via -Value.

    $obj = New-Item NtObjectSession:\ABC -ItemType Link -Value \BaseNamedObjects
    $obj.Close()

    Create an Event:

    $obj = New-Item NtObjectSession:\ABC -ItemType Event
    $obj.Close()

    Create a Semaphore: Note: Use -Value for the maximum count.

    $obj = New-Item NtObjectSession:\ABC -ItemType Semaphore -Value 10
    $obj.Close()

    Create a Mutant:

    $obj = New-Item NtObjectSession:\ABC -ItemType Mutant
    $obj.Close()