itm4n / PrivescCheck

Privilege Escalation Enumeration Script for Windows
BSD 3-Clause "New" or "Revised" License
2.79k stars 416 forks source link

Error in New-StructureField: $WTS_CONNECTSTATE_CLASS is NULL #33

Closed AdrianVollmer closed 2 years ago

AdrianVollmer commented 2 years ago

I just tried to run the latest version and it threw an exception. I tracked it down to this line:

State = New-StructureField 1 $WTS_CONNECTSTATE_CLASS

and apparently $WTS_CONNECTSTATE_CLASS is NULL and can't be bound to parameter Type.

(btw I think it makes more sense to load the modules by replacing ./PrivescCheck.ps1:99 with $ScriptBlock = [Scriptblock]::Create($Decompressed); New-Module -ScriptBlock $ScriptBlock, because then exceptions work better)

I checked all recent commits and the issue first appeared with 885c7742dd2b8d6d4cc984cf150a4f573d0b8df6.

I don't really understand why it is Null. I guess something goes wrong in New-Enum. If you need more information about this particular system I'm running it on: I have access until the end of this week.

itm4n commented 2 years ago

Hello,

Thanks for reporting this issue. However, I cannot reproduce it. Could you provide more information about the way you run the script, and about the context (Windows version, PowerShell version)?

AdrianVollmer commented 2 years ago

Windows Version 10.0.19042

Power Shell 5

I load the script over the network with Net.WebClient and execute it in memory with Invoke-Expression.

I also tracked it down some more: the line return ($Module.GetType($FullName) returns NULL if $FullName equals WinApiModule.WTS_CONNECTSTATE_CLASS.

AdrianVollmer commented 2 years ago

I believe that the type simply does not exist on this system. It's hard to tell what causes this, but I assume this is not the only system where this is the case. I propose that $WTS_CONNECTSTATE_CLASS will only be added to $WTS_SESSION_INFO_1W if it is not null, otherwise maybe throw a warning. Sure, this risks that user enumeration will then fail, but that's better than not being able to load the entire script.

itm4n commented 2 years ago

Could you send me a copy of the exact exception error you get please?

AdrianVollmer commented 2 years ago

The error message was this:

Invoke-Expression : Das Argument kann nicht an den Parameter "Type" gebunden werden, da es NULL ist.
In Zeile:103 Zeichen:14
+ $AllScript | Invoke-Expression
+              ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

because this is not helpful, I applied the change I mentioned in my first post in parenthesis. Then I get this:

New-StructureField : Das Argument kann nicht an den Parameter "Type" gebunden werden, da es NULL ist.
In Zeile:1052 Zeichen:34
+     State = New-StructureField 1 $WTS_CONNECTSTATE_CLASS
+                                  ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [New-StructureField], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,New-StructureField

However, I just tried to reproduce this in a fresh powershell session and everything works as expected, so ... yeah.

itm4n commented 2 years ago

Yeah, this error does not make any sense to me. I cannot see what is going wrong here. This is not the only place where I use this kind of structure and enumeration definition. I do not understand why there would be an error for WTS_CONNECTSTATE_CLASS but not for other types that are defined the exact same way.

AdrianVollmer commented 2 years ago

For what it's worth, WinPEAS is showing the exact same error, except only in the relevant section. All other tests run fine. So it's more likely to be an issue of this particular system (or even this particular shell instance).

itm4n commented 2 years ago

Feel free to close this issue if you think it is no longer relevant.

AdrianVollmer commented 2 years ago

This particular issues is at least not specific to this repo, so I'm closing.

However, I guess it would make sense if the code was modularized more such that the rest of the script runs fine if only one check fails due to an exception. But since that's probably a non-trivial task, I leave the decision up to you ;) thanks for the quick response anyway!