GithubHelp home page GithubHelp logo

googleprojectzero / sandbox-attacksurface-analysis-tools Goto Github PK

View Code? Open in Web Editor NEW
2.0K 2.0K 421.0 11.25 MB

Set of tools to analyze Windows sandboxes for exposed attack surface.

License: Apache License 2.0

C# 92.74% PowerShell 6.25% Smalltalk 1.01%

sandbox-attacksurface-analysis-tools's People

Contributors

1orenz0 avatar agametov avatar anhaehne avatar arthur-suleimanov avatar ccob avatar ceztko avatar diversenok avatar fllombard avatar irsl avatar leechristensen avatar lowleveldesign avatar monoxgas avatar qtc-de avatar rosalie79 avatar rsiestrunck avatar thierryfranzetti avatar tyranid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sandbox-attacksurface-analysis-tools's Issues

Errors on Win10 22H2

Hi James, Thanks for the great work.

When I run the work on Win10 22H2 (19045.2728) with the command $allrpc = ls "C:\Windows\system32\*" -Include "*.dll","*.exe" | Get-RpcServer, it has the following errors:

Get-RpcServer : Exception calling "ParsePeFile" with "4" argument(s): "Value cannot be null.
Parameter name: key"
At line:1 char:65
+ ... = ls "C:\Windows\system32\*" -Include "*.dll","*.exe" | Get-RpcServer
+                                                             ~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-RpcServer

This error just keep happening and it cannot parse any server. I guess this happens because Windows has changed its APIs? or because some kind of new Windows security policies?

btw, when I run the same command on Win10 1909, it has no problem.

How to Get-NtNamedPipeFile programmatically?

Hi,

With PowerShell we can run:

PS C:\WINDOWS\system32> Get-NtNamedPipeFile("\Device\NamedPipe\initShutdown")

Handle Name         NtTypeName Inherit ProtectFromClose
------ ----         ---------- ------- ----------------
2988   InitShutdown File       False   False

I want to do it programmatically with C#. I found how it is being called with C#:

public class GetNtNamedPipeFileCmdlet : GetNtFileCmdlet
{
/// <summary>
/// Method to create an object from a set of object attributes.
/// </summary>
/// <param name="obj_attributes">The object attributes to create/open from.</param>
/// <returns>The newly created object.</returns>
protected override object CreateObject(ObjectAttributes obj_attributes)
{
return NtFile.CreateNamedPipe(obj_attributes, Access, ShareMode, Options, FileDisposition.Open, NamedPipeType.Bytestream,
NamedPipeReadMode.ByteStream, NamedPipeCompletionMode.CompleteOperation, 0, 0, 0, NtWaitTimeout.FromMilliseconds(0));
}
/// <summary>
/// Constructor
/// </summary>
public GetNtNamedPipeFileCmdlet()
{
ShareMode = FileShareMode.Read | FileShareMode.Write;
Options = FileOpenOptions.SynchronousIoNonAlert;
Access = FileAccessRights.GenericRead | FileAccessRights.GenericWrite | FileAccessRights.Synchronize;
}
}

I made the below function but I don't know how to initialize NtObject root :

FileShareMode ShareMode = FileShareMode.Read | FileShareMode.Write;
FileOpenOptions Options = FileOpenOptions.SynchronousIoNonAlert;
FileAccessRights Access = FileAccessRights.GenericRead | FileAccessRights.GenericWrite | FileAccessRights.Synchronize;

using (ObjectAttributes obj_attributes = new ObjectAttributes(i_NamedPipe, AttributeFlags.CaseInsensitive, root))
{
    var a = NtFile.CreateNamedPipe(obj_attributes, Access, ShareMode, Options, FileDisposition.Open, NamedPipeType.Bytestream,
                NamedPipeReadMode.ByteStream, NamedPipeCompletionMode.CompleteOperation, 0, 0, 0, NtWaitTimeout.FromMilliseconds(0));
}

Is there a way to check if a certain fields threw an exception when using NtFile.Open?

I am using NtFileOpen on named pipes, sometimes some fields are throwing an exception while others are not:
image

Is there a way to check if a field threw an exception without using try..catch for every field?

For example, in the following code, we can get an object with fields that threw an exception:

namedPipeFileObject = (NtNamedPipeFileBase)NtFile.Open(obj_attributes, i_Access, i_ShareMode, i_Options);  
row.Cells[0].Value = namedPipeObject.NumberOfLinks;
row.Cells[1].Value = namedPipeObject.DirectoryGrantedAccess;
row.Cells[2].Value = namedPipeObject.GrantedAccess;
row.Cells[3].Value = namedPipeObject.GrantedAccessGeneric;    

But using try..catch for every field can be overkill, especially if we will go over all the fields.
Any suggestion how to handle it?

TokenViewer: Create Process -> black window?

This is more of a question (I'd be curious to understand roughly why this happens, even if there's no workaround):

I'm trying the following on Windows 10 (22H2): I start TokenViewer.exe elevated as a user that posseses "act as operating system" privileges. In the logon user tab I create a new processes (with Services4Users, i.e. without password). TokenViewer opens a new Windows in which displays the token of the new processes (which is Impersonation level, as expected). Now in the Operations tab I try to create a cmd.exe process (with Interactive enabled). This works, a process is started and a window appears. However the resulting Window is black/blank, with a blue (but also blank) title bar. (See screenshot below). Things that I type in the cmd.exe shell aren't visible, but are being accepted (i.e. typing exit + ENTER closes the window/process).

I've also tried things like conhost.exe, conhost.exe cmd.exe, conemu.exe, but this produced the same. This is also the case when trying to start other GUI apps like notepad.exe.

If anyone could point me in the direction of an explanation, I'd highly appreciate it. Thanks in advance!

image

Get-AccessibleWnf: Access denied errors

Running Get-AccessibleWnf results in an access denied error when running as a lower-privileged user:

Get-AccessibleWnf : (0xC0000022) - {Access Denied}
A process has requested access to an object, but has not been granted those access rights.

The exception's stacktrace shows the following:

PS C:\> error[0].Exception.StackTrace
   at NtApiDotNet.NtObjectUtils.CreateResult[T](NtStatus status, Boolean throw_on_error, Func`2 create_func, Action`1 error_func) in C:\code\sandbox-attacksurface-analysis-tools\NtApiDotNet\NtObjectUtils.cs:line 566
   at NtApiDotNet.NtObjectUtils.CreateResult[T](NtStatus status, Boolean throw_on_error, Func`1 create_func) in C:\code\sandbox-attacksurface-analysis-tools\NtApiDotNet\NtObjectUtils.cs:line 533
   at NtApiDotNet.NtWnf.Query[T](UInt64 state_name, WnfStateNameInformation info_class, Boolean throw_on_error) in C:\code\sandbox-attacksurface-analysis-tools\NtApiDotNet\NtWnf.cs:line 0
   at NtApiDotNet.NtWnf.get_SubscribersPresent() in C:\code\sandbox-attacksurface-analysis-tools\NtApiDotNet\NtWnf.cs:line 310
   at NtObjectManager.Cmdlets.Accessible.WnfAccessCheckResult..ctor(NtWnf wnf, AccessMask granted_access, SecurityDescriptor sd, TokenInformation token_info) in C:\code\sandbox-attacksurface-analysis-tools\NtObjectManager\Cmdlets\Accessible\WnfAccessCheckResult.cs:line 42
   at NtObjectManager.Cmdlets.Accessible.GetAccessibleWnfCmdlet.RunAccessCheck(IEnumerable`1 tokens) in C:\code\sandbox-attacksurface-analysis-tools\NtObjectManager\Cmdlets\Accessible\GetAccessibleWnfCmdlet.cs:line 74
   at NtObjectManager.Cmdlets.Accessible.CommonAccessBaseCmdlet.ProcessRecord() in C:\code\sandbox-attacksurface-analysis-tools\NtObjectManager\Cmdlets\Accessible\CommonAccessBaseCmdlet.cs:line 282
   at System.Management.Automation.CommandProcessor.ProcessRecord()

I worked around it temporarily by setting this code to not throw errors, but don't know how much that changes expected behavior elsewhere:

public bool SubscribersPresent => Query<int>(StateName, WnfStateNameInformation.SubscribersPresent, false).Result != 0;

Procedure names auto-labeled incorrectly when symbols fail to resolve

Observation:
When symbols fail to resolve for a binary, Get-RpcServer appears to assign RPC procedure names incorrectly:
image

Tested with the latest code on Github as well as the version of NtObjectManager in the PSGallery. Confirmed that the symbol does not exist with symchk as well (can't grab it via winbindex either).

Expected outcome:
If symbol resolution fails, assign an out-generated procedure name (e.g., Proc0, Proc1, Proc2, etc.). Might also throw a warning if symbols are configured but no symbols were found.

Link to example binary (hash C391E5024F1B8FAB6DCD88BBE3B36F71FAE02DD815EA9273D9ACB247781955FB): spoolsv.exe.txt

[Question] - Link NewCredentials To Process

Love the module. Thanks for all the work. I like to open my WindowsTerminal.exe and/or ssms.exe ( e.g. _SQL Server Management Studio ) with Network Credentials. When I have a few windows open it would be nice to run a command to check if the current process has negotiated the network credentials and what credentials did it negotiate with.

I'm essentially using Get-NtlogonSession to get the LogonId where the LogonType is NewCredentials. Then I can pass the LogonSession into Get-KerberosTicket to view the potential negotiated credential name. Now in order to map the LogonId to a process, I was using get-NtProcess -access QueryLimitedInformation to grab all the ProcessIds. Then I was using get-NttokenfromProcess to grab the AuthenticationId to map back to the LogonId from Get-NtLogonSession.

Is this the ideal way to do it or is there a more straightforward approach?

Access violation when processing some dlls with Get-RpcServer

0:026> !dumpstack
OS Thread Id: 0x2ae4 (26)
Current frame: VCRUNTIME140_CLR0400!memcpy+0xff
Child-SP         RetAddr          Caller, Callee
000000fbf164ce10 00007ffb89cbab46 clr!SafeBuffer::PtrToStructure+0x16, calling VCRUNTIME140_CLR0400!memcpy
000000fbf164ce20 00007ffb89cbab13 clr!SafeBuffer::SizeOfType+0x43, calling clr!MethodTable::GetClass
000000fbf164ce40 00007ffb2a66cc9c (MethodDesc 00007ffb2aa03620 +0x2c System.Runtime.InteropServices.SafeBuffer.GenericPtrToStructure[[System.Byte, mscorlib]](Byte*, Byte ByRef, UInt32)), calling 00007ffb89cbab30 (stub for System.Runtime.InteropServices.SafeBuffer.PtrToStructureNative(Byte*, TypedReference, UInt32))
000000fbf164ce58 00007ffb89b56c5f clr!SafeHandle::DangerousAddRef+0x6f, calling clr!LazyMachStateCaptureState
000000fbf164ce80 00007ffb2a66ca22 (MethodDesc 00007ffb2aa035c0 +0x112 System.Runtime.InteropServices.SafeBuffer.ReadArray[[System.Byte, mscorlib]](UInt64, Byte[], Int32, Int32)), calling (MethodDesc 00007ffb2aa03620 +0 System.Runtime.InteropServices.SafeBuffer.GenericPtrToStructure[[System.Byte, mscorlib]](Byte*, Byte ByRef, UInt32))
000000fbf164cf00 00007ffb2a66c8e8 (MethodDesc 00007ffb2a9e4738 +0x48 NtApiDotNet.Win32.ImageSection.ToArray()), calling (MethodDesc 00007ffb2aa035c0 +0 System.Runtime.InteropServices.SafeBuffer.ReadArray[[System.Byte, mscorlib]](UInt64, Byte[], Int32, Int32))
000000fbf164cf10 00007ffb70abdb8a (MethodDesc 00007ffb706e6918 +0x1a System.Guid.ToByteArray()), calling clr!JIT_NewArr1VC_MP_InlineGetThread
000000fbf164cf40 00007ffb2a66c646 (MethodDesc 00007ffb2a9ec490 +0x56 NtApiDotNet.Win32.RpcServer+<FindRpcServerInterfaces>d__60.MoveNext()), calling (MethodDesc 00007ffb2a9e4738 +0 NtApiDotNet.Win32.ImageSection.ToArray())
000000fbf164cf60 00007ffb2a66c5c1 (MethodDesc 00007ffb2a9ec500 +0x51 NtApiDotNet.Win32.RpcServer+<FindRpcServerInterfaces>d__60.System.Collections.Generic.IEnumerable<NtApiDotNet.Win32.RpcServer.RpcOffset>.GetEnumerator()), calling clr!JIT_WriteBarrier
000000fbf164cf70 00007ffb2a66c445 (MethodDesc 00007ffb2a9e3988 +0x15 NtApiDotNet.Win32.RpcServer+<>c__DisplayClass51_0.<ParsePeFile>b__0(NtApiDotNet.Win32.ImageSection)), calling (MethodDesc 00007ffb2a9e59c8 +0 NtApiDotNet.NtObjectUtils.HasFlagSet[[NtApiDotNet.Win32.RpcServerParserFlags, NtApiDotNet]](NtApiDotNet.Win32.RpcServerParserFlags, NtApiDotNet.Win32.RpcServerParserFlags))
000000fbf164cfa0 00007ffb2a66c2c5 (MethodDesc 00007ffb2a9ebec0 +0x155 System.Linq.Enumerable+<SelectManyIterator>d__17`2[[System.__Canon, mscorlib],[NtApiDotNet.Win32.RpcServer+RpcOffset, NtApiDotNet]].MoveNext()), calling 00007ffb2a53d760
000000fbf164cfc0 00007ffb2a66c14c (MethodDesc 00007ffb2a9ebf30 +0x5c System.Linq.Enumerable+<SelectManyIterator>d__17`2[[System.__Canon, mscorlib],[NtApiDotNet.Win32.RpcServer+RpcOffset, NtApiDotNet]].System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()), calling clr!JIT_WriteBarrier
000000fbf164cfd0 00007ffb89b5b319 clr!JIT_GetCurrentManagedThreadId+0x9, calling clr!GetThread
000000fbf164d000 00007ffb2a66c015 (MethodDesc 00007ffb2a9e5720 +0x45 System.Linq.Enumerable.Any[[NtApiDotNet.Win32.RpcServer+RpcOffset, NtApiDotNet]](System.Collections.Generic.IEnumerable`1<RpcOffset>)), calling 00007ffb2a53d8a0
000000fbf164d050 00007ffb2a6695ae (MethodDesc 00007ffb2a9e14f8 +0x15e NtApiDotNet.Win32.RpcServer.ParsePeFile(System.String, System.String, System.String, NtApiDotNet.Win32.RpcServerParserFlags)), calling (MethodDesc 00007ffb2a9e5720 +0 System.Linq.Enumerable.Any[[NtApiDotNet.Win32.RpcServer+RpcOffset, NtApiDotNet]](System.Collections.Generic.IEnumerable`1<RpcOffset>))
000000fbf164d080 00007ffb89b769ef clr!GCInterface::SuppressFinalize+0x3f

The issue is reproduced with latest chrome.dll, presumably caused by the presence of .retplne section with zero attributes, which is mapped as PAGE_NOACCESS:

0:026> !vprot rdx
BaseAddress:       00007ffb36665000
AllocationBase:    00007ffb2d5b0000
AllocationProtect: 00000080  PAGE_EXECUTE_WRITECOPY
RegionSize:        0000000000001000
State:             00001000  MEM_COMMIT
Protect:           00000001  PAGE_NOACCESS
Type:              01000000  MEM_IMAGE

image

Suggested fix is to check Characteristics in SafeLoadLibraryHandle.SetupValues:

        for (int i = 0; i < header.FileHeader.NumberOfSections; ++i)
        {
            ImageSectionHeader section = (ImageSectionHeader)Marshal.PtrToStructure(buffer + i * header_size, typeof(ImageSectionHeader));
            ImageSection sect = new ImageSection(section, MappedAsImage, base_ptr);
            _image_sections.Add(sect);
        }

Getting Access Denied when calling NtFile.Open on a named pipe

Hi James,

I am creating the following dummy named pipe without Dacl in Powershell:

function CreateDummyPipeForTesting {
  $pipeSecurity = New-Object System.IO.Pipes.PipeSecurity
  $pipeSecurity.SetAccessRuleProtection($true, $true)
  $pipeServer = New-Object System.IO.Pipes.NamedPipeServerStream("myPipe", [System.IO.Pipes.PipeDirection]::InOut, -1, [System.IO.Pipes.PipeTransmissionMode]::Byte, [System.IO.Pipes.PipeOptions]::None, 4096, 4096, $pipeSecurity)
  Write-Output "Waiting for client connection..."
  $pipeServer.WaitForConnection()
  Write-Output "Client connected."
  $reader = New-Object System.IO.StreamReader($pipeServer)
  $writer = New-Object System.IO.StreamWriter($pipeServer)
  while ($true) {
    $message = $reader.ReadLine()
    Write-Output "Received message: $message"
    $writer.WriteLine("Hello from the server!")
    $writer.Flush()
  }
}

CreateDummyPipeForTesting

When I run the PowerShell GetNtFile, everything works fine:

PS C:\Users\eviatar> $b = Get-NtFile("\Device\NamedPipe\myPipe")
PS C:\Users\eviatar> $b.SecurityDescriptor | fl


Dacl                 : {}
Sacl                 :

But when I am trying to use the C# parallel function (NtFile.Open()) like that:

public static NtNamedPipeFileBase GetNamedPipeObjectClient2()
{
	NtNamedPipeFileBase namedPipeFileObject = null;

	string i_NamedPipe = @"\Device\NamedPipe\myPipe";
	//i_NamedPipe = @"\Device\NamedPipe\InitShutdown";
	FileShareMode ShareMode = FileShareMode.Read | FileShareMode.Write;
	FileOpenOptions Options = FileOpenOptions.SynchronousIoNonAlert;
	FileAccessRights Access = FileAccessRights.GenericRead | FileAccessRights.GenericWrite | FileAccessRights.Synchronize;


	using (ObjectAttributes obj_attributes = new ObjectAttributes(i_NamedPipe))
	{
		try
		{
			namedPipeFileObject = (NtNamedPipeFileBase)NtFile.Open(obj_attributes, Access, ShareMode, Options);
			// namedPipeFileObject = NtFile.CreateNamedPipe(obj_attributes, Access, ShareMode, Options, FileDisposition.Open, NamedPipeType.Bytestream,
		   // NamedPipeReadMode.ByteStream, NamedPipeCompletionMode.CompleteOperation, 0, 0, 0, NtWaitTimeout.FromMilliseconds(0));

		}
		catch (Exception e)
		{
			// 
		}

	};


	return namedPipeFileObject;
}

I am getting an exception:

{"(0xC0000022) - {Access Denied}
A process has requested access to an object, but has not been granted those access rights."}

I also tried to run it with admin permissions with no success.
I used Get-NtFile with standard permissions (not admin) and it worked, and I used the same user with the C# function, so I am not sure why it doesn't work.
Maybe my FileAccessRights is wrong?
I tried to follow the source code but didn't see the use of the default permissions:

protected override object CreateObject(ObjectAttributes obj_attributes)
{
using (Transaction?.Enable())
{
FileOpenOptions opts = Options;
if (OpenById)
opts |= FileOpenOptions.OpenByFileId;
if (Directory)
opts |= FileOpenOptions.DirectoryFile;
return NtFile.Create(obj_attributes, Access, FileAttribute,
ShareMode, opts, Disposition, EaBuffer, AllocationSize);
}
}
/// <summary>
/// Constructor
/// </summary>
public NewNtFileCmdlet()
{
Disposition = FileDisposition.Create;
FileAttribute = FileAttributes.Normal;
}
}

compile error

้”™่ฏฏ CS0165 ไฝฟ็”จไบ†ๆœช่ต‹ๅ€ผ็š„ๅฑ€้ƒจๅ˜้‡โ€œticketโ€ NtApiDotNet D:\sandbox-attacksurface-analysis-tools\NtApiDotNet\Win32\Security\Authentication\Kerberos\Builder\KerberosTicketBuilder.cs 208 ๆดปๅŠจ

How to get RPC procedures from the Endpoints

I am not sure if this is possible but I have a svchost.exe process that I want to see its procedures.
I used the following commands to get all the servers:

$a = Get-RpcAlpcServer | where-object {$_.ProcessName -eq "svchost.exe"}

I see the endpoints of each process but is there a way to find what procedures it has?
For example, in RPCView, I can see svchost.exe with PID 2288 and it has two endpoints and two interfaces that shows the procedures:
image

I tried to check of the Endpoints object has a way to get it but didn't see something:
image

[Enhancement/Idea] Get RPC server by the running process PID

Hi James,

Amazing project :)

I am using the NtObjectManager and for now it helps me a lot.
I had an idea I wanted to share.

The Problem
Today, as far as I know, when I want to export RpcServer functions, I can use such command:

Get-RpcServer 'C:\windows\system32\combase.dll' -DbgHelpPath "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll"

But when I used RPCView, you can see that svchost.exe also exports RPC functions but when trying to export it like that:

Get-RpcServer 'C:\windows\system32\svchost.exe'

It won't work. The reason is that it uses DLLs that have the RPC functions.
For example this svchost:

C:\Windows\system32\svchost.exe C:\Windows\system32\svchost.exe -k LocalServiceNetworkRestricted -p -s TimeBrokerSvc

According to RPCView, it uses:

C:\Windows\system32\combase.dll
C:\Windows\system32\BrokerLib.dll
C:\Windows\system32\TimeBrokerServer.dll  

They export the functions of the DLLs.
image

The Idea
A new function, maybe Get-RpcServerByPid.
It will know to export processes like svchost.exe.
I don't know how they did it, but I suppose they listed the modules of the process and checked each of its modules.

Example:
Get-RpcServerByPid <pid_of_svchost>
It will run Get-RpcServer on svchost.exe and list all its loaded modules and run it on them.

I spoke about svchost.exe but of course it should be generic and the logic will run on each process PID that you will decide.

Security Policy violation Binary Artifacts

This issue was automatically created by Allstar.

Security Policy Violation
Project is out of compliance with Binary Artifacts policy: binaries present in source code

Rule Description
Binary Artifacts are an increased security risk in your repository. Binary artifacts cannot be reviewed, allowing the introduction of possibly obsolete or maliciously subverted executables. For more information see the Security Scorecards Documentation for Binary Artifacts.

Remediation Steps
To remediate, remove the generated executable artifacts from the repository.

Artifacts Found

  • third_party/Be.Windows.Forms.HexBox/Be.Windows.Forms.HexBox.dll

Additional Information
This policy is drawn from Security Scorecards, which is a tool that scores a project's adherence to security best practices. You may wish to run a Scorecards scan directly on this repository for more details.


Allstar has been installed on all Google managed GitHub orgs. Policies are gradually being rolled out and enforced by the GOSST and OSPO teams. Learn more at http://go/allstar

This issue will auto resolve when the policy is in compliance.

Issue created by Allstar. See https://github.com/ossf/allstar/ for more information. For questions specific to the repository, please contact the owner or maintainer.

GitHub Actions?

Does it make sense to have a GitHub Actions Workflow to automatically build the source and respective Release.7z artifact of this repository? If you want that, I can probably do a PR.

Provide .net standard nuget packages

Hi,

is it possible you provide Nuget packages targeting .net standard?

I saw the NtApiDotNet.Core.csproj but couldn't find a corresponding nuget package.

System.AccessViolationException using RpcEndpointMapper against Windows Server 2022 Host

Code to Reproduce:

foreach (var computer in computers)
{
    var potentialString = $"ncacn_ip_tcp:{computer}";
    var results = RpcEndpointMapper.QueryEndpoints(potentialString);

    foreach (var result in results)
    {
        if (result.ProtocolSequence == "ncacn_ip_tcp")
        {
            Console.WriteLine($"Got result: {result}");
        }
    }
}

Result:

Multiple results are returned but fails when pinvoking RpcMgmtEpEltInqNext. authlogics02.authlogics.com is running Windows Server 2022, we don't see this behavior on other machines.

Got result: [50abc2a4-574d-40b3-9d66-ee4fd5fba076, 5.0] ncacn_ip_tcp:authlogics02.authlogics.com[58522]
Got result: [6bffd098-a112-3610-9833-46c3f874532d, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[58502]
Got result: [5b821720-f63b-11d0-aad2-00c04fc324db, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[58502]
Got result: [897e2e5f-93f3-4376-9c9c-fd2277495c27, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[58483]
Got result: [367abb81-9844-35f1-ad32-98f038001003, 2.0] ncacn_ip_tcp:authlogics02.authlogics.com[58464]
Got result: [12345678-1234-abcd-ef00-0123456789ab, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49676]
Got result: [0b6edbfa-4a24-4fc6-8a23-942b1eca65d1, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49676]
Got result: [ae33069b-a2a8-46ee-a235-ddfd339be281, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49676]
Got result: [4a452661-8290-4b36-8fbe-7f4093a94978, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49676]
Got result: [76f03f96-cdfd-44fc-a22c-64950a001209, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49676]
Got result: [29770a8f-829b-4158-90a2-78cd488501f7, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49671]
Got result: [86d35949-83c9-4044-b424-db363231fd0c, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49668]
Got result: [3a9ef155-691d-4449-8d05-09ad57031823, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49668]
Got result: [f6beaff7-1e19-4fbb-9f8f-b89e2018337c, 1.0] ncacn_ip_tcp:authlogics02.authlogics.com[49666]

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at NtApiDotNet.Win32.Win32NativeMethods.RpcMgmtEpEltInqNext(SafeRpcInquiryHandle InquiryContext, RPC_IF_ID IfId, SafeRpcBindingHandle& Binding, UUID ObjectUuid, SafeRpcStringHandle& Annotation)
at NtApiDotNet.Win32.RpcEndpointMapper.d__0.MoveNext() in D:\Github\sandbox-attacksurface-analysis-tools\NtApiDotNet\Win32\RpcEndpointMapper.cs:line 88

Can Get-RpcAlpcServer retrieve information from process inside a container?

Does Get-RpcAlpcServer can get the RpcAlpcServer from a process inside a container?
I had a container running with process CExecSvc.exe (PID 4880) but when I tried to get it with the above function it didn't find it:

PS C:\Windows\system32> Get-RpcAlpcServer| where {$_.ProcessName -eq "cexecsvc.exe"}
PS C:\Windows\system32> Get-RpcAlpcServer -ProcessId 4880
PS C:\Windows\system32>

I noticed that RPCView also can't get this information.
This is not critical for me because I used the workaround with Get-RpcServer on the file itself, just wondering if this is a bug or currently not possible.

image

Reference:

private static IEnumerable<RpcAlpcServer> GetAlpcServersInternal(IEnumerable<NtHandle> handles)
{
NtType alpc_type = NtType.GetTypeByType<NtAlpc>();
foreach (var handle in handles.Where(h => h.NtType == alpc_type
&& h.Name.StartsWith(@"\RPC Control\", StringComparison.OrdinalIgnoreCase)))
{
List<RpcEndpoint> endpoints = new List<RpcEndpoint>();
try
{
endpoints.AddRange(RpcEndpointMapper.QueryEndpointsForAlpcPort(handle.Name));
}
catch (SafeWin32Exception)
{
}
if (endpoints.Count > 0)
{
yield return new RpcAlpcServer(handle, endpoints);
}
}
}

Get-NtNamedPipeFile failed with "Object Name invalid"

I have a named pipe with the following name:

PS C:\WINDOWS\system32> $pipes = [System.IO.Directory]::GetFiles("\\.\\pipe\\")
PS C:\WINDOWS\system32> $pipes[5]
\\.\\pipe\\Winsock2\CatalogChangeListener-5f4-0

When I run Get-NtNamedPipeFile it fails:

PS C:\WINDOWS\system32> $b = Get-NtNamedPipeFile("\\Device\\NamedPipe\\Winsock2\\CatalogChangeListener-5f4-0")
Get-NtNamedPipeFile : (0xC0000033) - Object Name invalid.
At line:1 char:6
+ $b = Get-NtNamedPipeFile("\\Device\\NamedPipe\\Winsock2\\CatalogChang ...
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-NtNamedPipeFile], NtException
    + FullyQualifiedErrorId : NtApiDotNet.NtException,NtObjectManager.Cmdlets.Object.GetNtNamedPipeFileCmdlet  

What can be the reason for that and is it possible to solve it?

NtApiDotNet.Win32.RpcServer.ParsePeFile doesn't return RPC servers

Hi James,

The RPC functions from PowerShell works good:

PS C:\WINDOWS\system32> Get-RpcServer "C:\tmp\CExecSvc.exe" -DbgHelpPath "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll"

Name         UUID                                 Ver Procs EPs Service Running
----         ----                                 --- ----- --- ------- -------
CExecSvc.exe 75ef42c7-22f4-44a0-8200-9351cd316e01 1.0 4     0           False

I wanted to use the Get-RpcServer from C# code. I searched in the PowerShell script and found that you are using [NtApiDotNet.Win32.RpcServer]::ParsePeFile to do it:

PROCESS {
try {
$servers = switch($PSCmdlet.ParameterSetName) {
"FromDll" {
$FullName = Resolve-Path -LiteralPath $FullName -ErrorAction Stop
Write-Progress -Activity "Parsing RPC Servers" -CurrentOperation "$FullName"
[NtApiDotNet.Win32.RpcServer]::ParsePeFile($FullName, $DbgHelpPath, $SymbolPath, $ParserFlags)
}

I wrote it in C#:

// string symbols = @"srv*c:\symbols*http://msdl.microsoft.com/download/symbols";
string dbg = @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll";
string rpcFile = @"C:\tmp\CExecSvc.exe";
var rpcServer = NtApiDotNet.Win32.RpcServer.ParsePeFile(rpcFile, dbg, "", NtApiDotNet.Win32.RpcServerParserFlags.None);

But the rpcServer variable is empty (Count=0). Any idea what I am missing here?
Notice that I also tried with symbols without success.
I am using NtApiDoNet.dll version 1.1.33

some process can not show?

image

the two softwares with different version can show different num of typora process

I think the latest commits shows wrong

NtApiDotNet, symbol package and SourceLink

It would be excellent if you could publish symbols for the nuget package, and adding sourcelink metadata would also be appreciated :)

I was going to submit a PR for it, but the contribution guidelines mention signing a copyright transfer thingie, which seems like too much work for this. Just adding a few lines to the csproj is all that's needed.

<PropertyGroup>
  <IncludeSymbols>true</IncludeSymbols>
  <SymbolPackageFormat>snupkg</SymbolPackageFormat>
  <PublishRepositoryUrl>true</PublishRepositoryUrl>  
</PropertyGroup>

<ItemGroup>
  <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>

That should be all that's needed to add the sourcelink info and publish a symbol package to the nuget symbol server :)

RTL_USER_PROCESS_PARAMETERS

Hello,
I was searching for RTL_USER_PROCESS_PARAMETERS in your project but can't find it. You did not implement it ?

Get-NtApiSet seems to not resolve ALL ApiSet versions

Forgive me for not knowing all of the proper terminology to use here, I'll do my best to describe what I'm observing. I've been using Get-NtApiSet to resolve ApiSet names to their implementation DLL. Recently, I was analyzing kernel32!OpenProcess to use as a demonstration in a workshop and noticed what I suspect is a looping issue. As I'm sure you're aware, kernel32!OpenProcess is a simple wrapper that calls an imported function. On the version of Windows that I am using (), it is calling api-ms-win-core-processthreads-l1-1-2!OpenProcess. Now I know that the implementation is in kernelbase.dll, but because this is for a workshop I want to show my work. To do this, I've been relying on Get-NtApiSet as it seems to be the best solution for this type of resolution. However, this particular time I noticed an issue with the resolution. Here is the command and output:

Get-NtApiSet -Name api-ms-win-core-processthreads-l1-1-2

Name                                  HostModule   Flags
----                                  ----------   -----
api-ms-win-core-processthreads-l1-1-3 kernel32.dll Sealed

Now I think I only noticed this because I knew that the resulting HostModule should have been kernelbase.dll, but also notice that I requested version l1-1-2 and it returned version l1-1-3. I decided to just list all ApiSets that were known to the tool and found a pattern that when the final number in the version (the minor version maybe) is non zero, the results will only include the largest value. For example, here is the output for the example mentioned above:

api-ms-win-core-processsecurity-l1-1-0                     kernel32.dll                        Sealed
api-ms-win-core-processsnapshot-l1-1-0                     kernelbase.dll                      Sealed
api-ms-win-core-processthreads-l1-1-3                      kernel32.dll                        Sealed

I did however notice that in cases where the 2nd to last number in the version (the major number?) is non zero, it includes both versions:

api-ms-win-core-processtopology-l1-1-0                     kernelbase.dll                      Sealed
api-ms-win-core-processtopology-l1-2-0                     kernelbase.dll                      Sealed

This leads me to suspect that maybe there is some issue with the looping where the results being aren't being added to the list at the lowest level? I looked through the code to see if I could spot anything, but haven't found it yet. I'll keep looking, but thought I'd put this on your radar in case you can think of a quick solution or know something that I don't about ApiSets and their versions.

RpcServer.ParsePeFile throw and uncatchable error

When I am calling RpcServer.ParsePeFile like that:

string name = @"C:\Windows\winsxs\x86_wcf-system.identitymodel_b03f5f7f11d50a3a_10.0.19041.1_none_e690fdc7d17e3f70\System.IdentityModel.dll";  
string symbolsPath = @"srv*c:\symbols*http://msdl.microsoft.com/download/symbols";
string dbgHelp = @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll";
NtApiDotNet.Win32.RpcServer.ParsePeFile(name, dbgHelp , symbolsPath , NtApiDotNet.Win32.RpcServerParserFlags.None);

I am getting the following error:

C:\Windows\winsxs\x86_wcf-system.identitymodel_b03f5f7f11d50a3a_10.0.19041.1_none_e690fdc7d17e3f70\System.IdentityModel.dll is either not designed to run on Windows or it contains an error. Try installing the program again using the original installation media or contact your system administator or the software vendor for support. Error status: 0xc000012f.

image

The problem is that I when I tried to use try...catch it doesn't work on these kind of errors.
Any idea how to solve\workaround it?

I noticed that the DLL PE magic starts with DCS which is related to Delta Compression Application.
More reference from this answer.

I think I can workaround it by checking the magic of the file by reading it first before moving it to the function but it might affect the performance a bit.
The problem can also repeat if you run it like that:

rpcFile = @"C:\Windows\winsxs\x86_wcf-system.identitymodel_b03f5f7f11d50a3a_10.0.19041.1_none_e690fdc7d17e3f70\System.IdentityModel.dll";
using (var result = SafeLoadLibraryHandle.LoadLibrary(rpcFile, LoadLibraryFlags.DontResolveDllReferences, false))
{
}

I noticed that it won't help to check for MZ as magic file because there are files like:

C:\Windows\winsxs\x86_microsoft-windows-n..nd-syswow64-payload_31bf3856ad364e35_1.0.19041.1_none_beac3411b23832d5\compobj.dll

Which starts with MZ but still have bad image.

Thanks

Win32Utils: Incorrect spelling in CreateSecurityCapabilities

James, I was just testing out some of the new features introduced with the most recent 1.1.29 release and I came across some spelling mistakes in the code. Particularly, I've got a lot of interest in Added proper enumeration of AppContainer profiles and support creating with capabilities. So when I was digging into that code, I came across the spelling mistakes which I believe date back further in time.

Quick search: https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/search?q=%22CreateSecuityCapabilities%22

Incorrect: Win32Utils.CreateSecuityCapabilities
Correct: Win32Utils.CreateSecurityCapabilities

  1. https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/master/NtApiDotNet/Win32/Win32ProcessConfig.cs#L449
  2. https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/master/NtApiDotNet/Win32/TokenUtils.cs#L420
  3. https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/master/NtApiDotNet/Win32/Win32Utils.cs#L435

I don't know if this would cause any functional issues or whether it is just a benign spelling typo in the code, but figured I should mention it to you. Cheers!

Get-AccessibleFile feature

Get-AccessibleFile -Recurse currently doesn't follow symlink and junction directories and I suppose this makes sense. However, I can see some cases where it's useful to follow such directories.

Could it be considered implementing an additional flag for this, that can be used in combination with the recurse flag?

Does Params object contains too much parameters: "Cannot find an overload..."

Hi James,
I was checking the function HcsRpc_ShutdownSystem (from vmcompute.exe - HCS service):

PS> $a = Get-RpcServer "C:\windows\system32\vmcompute.exe" -DbgHelpPath "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll"

PS> $a.Procedures[4]

Name             : HcsRpc_ShutdownSystem
Params           : {FC_SUPPLEMENT - NdrSupplementTypeReference - IsIn, , FC_UP - NdrPointerTypeReference - MustSize, MustFree, IsIn, FC_HYPER - NdrSimpleTypeReference - IsIn,
                   IsBasetype...}

l saw it has 4 arguments (there is a fifth without a Name so I don't know if I should include it):

PS> $a.Procedures[4].Params


Attributes      : IsIn
Type            : FC_SUPPLEMENT - NdrSupplementTypeReference
ServerAllocSize : 0
Offset          : 0
Name            : p0
IsIn            : True
IsOut           : False
IsInOut         : False
IsSimpleRef     : False

Explicit        : True
Generic         : False
Attributes      : 0
Type            : FC_BIND_CONTEXT - NdrSimpleTypeReference
ServerAllocSize : 0
Offset          : 0
Name            :
IsIn            : False
IsOut           : False
IsInOut         : False
IsSimpleRef     : False

Attributes      : MustSize, MustFree, IsIn
Type            : FC_UP - NdrPointerTypeReference
ServerAllocSize : 0
Offset          : 8
Name            : p1
IsIn            : True
IsOut           : False
IsInOut         : False
IsSimpleRef     : False

Attributes      : IsIn, IsBasetype
Type            : FC_HYPER - NdrSimpleTypeReference
ServerAllocSize : 0
Offset          : 16
Name            : p2
IsIn            : True
IsOut           : False
IsInOut         : False
IsSimpleRef     : False

Attributes      : MustSize, MustFree, IsOut
Type            : FC_RP - NdrPointerTypeReference
ServerAllocSize : 8
Offset          : 24
Name            : p3
IsIn            : False
IsOut           : True
IsInOut         : False
IsSimpleRef     : False

I connected the client:

PS> $a.Endpoints

UUID                                 Version Protocol Endpoint                Annotation
e7a216af-1ec1-447f-8d3f-a87278db564d 1.0     ncalrpc  LRPC-6981a149a72e0ebb3e

PS> $client = Get-RpcClient $rpc
PS> Connect-RpcClient $c -EndpointPath "LRPC-6981a149a72e0ebb3e"
PS> $c.Connected
True

But when I tried to call it with 4 parameters (p0,p1,p2 and p3) it didn't accept it:

PS> $c.HcsRpc_ShutdownSystem([NullString]::Value, [NullString]::Value, [NullString]::Value, [NullString]::Value)
Cannot find an overload for "HcsRpc_ShutdownSystem" and the argument count: "4".

But with 3 parameters it didn't throw the "Cannot find an overload" error.
It throw other error about using the wrong type but this is a different issue.

I am currently want to understand why the Params shows me 4 (maybe 5) parameters when the client can send only 3.

I reversed the vmcompute.exe and vmcompute.dll, it seems that in both (server and client) it receives 4 parameters and not 3:
image

Why I am getting the overload error when using 4 parameters?

Bug in FromByteArray while handling IO_REPARSE_TAG_AF_UNIX

I encountered the following bug in FromByteArray while executing DumpReparsePoints with the handling of the IO_REPARSE_TAG_AF_UNIX tag.

filename: "C:\Users\xxxx\AppData\Local\Packages\TheDebianProject.DebianGNULinux_76v4gfsz19hv4\LocalState\fsserver" ends up with the bytestream: 230000800000000000000000000000000000000000000000

BinaryReader reader = new BinaryReader(new MemoryStream(ba), Encoding.Unicode); // results in IO_REPARSE_TAG_AF_UNIX (0x80000023)
ReparseTag tag = (ReparseTag)reader.ReadUInt32(); // results in IO_REPARSE_TAG_AF_UNIX (0x80000023)
int data_length = reader.ReadUInt16(); // results in 0 
// Reserved
reader.ReadUInt16();  // obsolete
long remaining_length = reader.RemainingLength(); // results in 16 (Remaining null bytes)
long expected_length = data_length; // results in 0 
if (!NtFileUtils.IsReparseTagMicrosoft(tag)) // returns false, doesn't enter the if statement
{
    expected_length += 16; // obsolete
}

if (remaining_length != expected_length) // 16 != 0, enters the if statement
{
    // Corrupted buffer. Return an opaque buffer with all the data until the end.
    return new OpaqueReparseBuffer(tag, reader.ReadToEnd()); // reader.ReadToEnd() ends with a System.OutOfMemoryException
}

[Enhancement/Idea]A token viewer with export option and capability to compare two processes security parameters would be nice to have

Token viewer is a very nice tool which is useful in wide variety of use cases w.r.t analysis of a process's security. It would be great if the below use cases are supported

  1. An export capability which would help in sharing the data with others.
  2. Comparing two instance of processes to see what is different among them w.r.t security parameters/token.

The need of second one arose when I was analyzing a store app where I was not able to access a file from one of the process running in a container. But a command prompt launched in the same security context with the tool called Hover (as per the documentation) was able to access it. I wanted to see how the privilege of command prompt launched from Hover is different from the actual process which failed to access a file. A comparison view which would result in showing the difference between these two processes would help in easier analysis.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.