TrimarcJake / Locksmith

A small tool built to find and fix common misconfigurations in Active Directory Certificate Services.
https://github.com/TrimarcJake/Locksmith
Other
865 stars 85 forks source link

Error "You cannot call a method on a null-valued expression." #9

Closed rafalfitt closed 1 year ago

rafalfitt commented 1 year ago

You cannot call a method on a null-valued expression. At C:\Users\Administrator.xxx\Desktop\Invoke-Locksmith.ps1:336 char:13

TrimarcJake commented 1 year ago

Hello @rafalfitt ! Can you provide the full command you used when generating this issue?

rafalfitt commented 1 year ago

Hello @TrimarcJake

. "C:\Users\Administrator.xxx\Desktop\Invoke-Locksmith.ps1" -Mode 1

this error (and https://github.com/TrimarcJake/Locksmith/issues/10 ) is reported when using RDP connection with "Restricted Admin" mode enabled.

appelboom commented 1 year ago

Same.

You cannot call a method on a null-valued expression. At ----------------\Invoke-Locksmith.ps1:363 char

PowerShell 7 is a bit more verbose

Success Restart Needed Exit Code Feature Result


True No NoChangeNeeded {} Get-ADObject: Variable: 'CAHostName' found in expression: $CAHostName is not defined. 126 Get-ADObject: Variable: 'CAHostName' found in expression: $CAHostName is not defined. 126 Get-ADObject: Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again. Get-ADObject: Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again. InvalidOperation: ------- \Invoke-Locksmith.ps1:363 Line | 363 | $Issue | Add-Member -MemberType NoteProperty -Name Forest . | ~~~~~~~~~~~~~ | You cannot call a method on a null-valued expression.

TrimarcJake commented 1 year ago

@appelboom are you using Restricted admin mode also?

appelboom commented 1 year ago

Restricted admin mode

Yes, Enabled. If I set HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\DisableRestrictedAdmin=1 it runs fine

TrimarcJake commented 1 year ago

This is in our next sprint!

TrimarcJake commented 1 year ago

@appelboom @rafalfitt

The solution we are considering for this issue is to prompt for credentials at the beginning of the script... but that sort of ruins the point of using Restricted Admin mode. However, we'd be willing to institute this change with a very strongly worded warning + confirmation required.

Would you consider this issue resolved with this solution?

appelboom commented 1 year ago

Hi, Yes. No concerns

On Wed, 23 Nov 2022 at 04:02, Jake Hildreth @.***> wrote:

@appelboom https://github.com/appelboom @rafalfitt https://github.com/rafalfitt

The solution we are considering for this issue is to prompt for credentials at the beginning of the script... but that sort of ruins the point of using Restricted Admin mode. However, we'd be willing to institute this change with a very strongly worded warning + confirmation required.

Would you consider this issue resolved with this solution?

— Reply to this email directly, view it on GitHub https://github.com/TrimarcJake/Locksmith/issues/9#issuecomment-1324178167, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFCNFIKTZQXRPD3TDVCDW2TWJURFJANCNFSM6AAAAAARTPULOE . You are receiving this because you were mentioned.Message ID: @.***>

-- Kind regards Eric Appelboom CISA CISM CRISC CISSP-ISSAP CSSLP CGEIT CEH CCSE MCITP ITIL TOGAF MInfoSysSecurity SEC+ MCSA(SECURITY) MCSE MCTS MCITP http://www.linkedin.com/in/eappelboom

rafalfitt commented 1 year ago

Yes, warning is OK + IMHO it is enough in such situation.

0x11DFE commented 1 year ago

Is this the same issue? powershell_AVCIwhf0aW

techspence commented 1 year ago

Is this the same issue? powershell_AVCIwhf0aW

Yep, same issue. Restricted admin mode doesn't allow credentials to be passed, so those AD cmdlets fail. https://github.com/TrimarcJake/Locksmith/pull/16 should fix this

TrimarcJake commented 1 year ago

@0x11DFE @rafalfitt @appelboom

The changes required for proper operation in Restricted Admin Mode are now included in the testing branch. Would you mind testing in your environment?

0x11DFE commented 1 year ago

@0x11DFE @rafalfitt @appelboom

The changes required for proper operation in Restricted Admin Mode are now included in the testing branch. Would you mind testing in your environment?

powershell_ZfMLXqERio

I just tried and I am having the same exact issue.

techspence commented 1 year ago

@0x11DFE Can you please provide the full command you supplied when you get this error? The updated code should warn you that Restricted Admin Mode is enabled and instruct you to run again passing the -Credential argument with domain\username as a value.

TrimarcJake commented 1 year ago

@0x11DFE also, make sure you are using the testing branch. We have not pushed these changes to main yet.

0x11DFE commented 1 year ago

@0x11DFE also, make sure you are using the testing branch. We have not pushed these changes to main yet.

I am.

@0x11DFE Can you please provide the full command you supplied when you get this error? The updated code should warn you that Restricted Admin Mode is enabled and instruct you to run again passing the -Credential argument with domain\username as a value.

I don't have any passwords on this computer.

PS C:\Users\***\Desktop> .\Invoke-Locksmith.ps1
Get-ADForest : The term 'Get-ADForest' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:75 char:22
+ $DNSRoot = [string]((Get-ADForest).RootDomain | Get-ADDomain).DNSRoot
+                      ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-ADForest:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Get-ADForest : The term 'Get-ADForest' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:76 char:35
+ $EnterpriseAdminsSID = ([string]((Get-ADForest).RootDomain | Get-ADDo ...
+                                   ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-ADForest:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

New-Object : A constructor was not found. Cannot find an appropriate constructor for type
System.Security.Principal.SecurityIdentifier.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:77 char:19
+ ... rredOwner = New-Object System.Security.Principal.SecurityIdentifier($ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [New-Object], PSArgumentException
    + FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand

Get-ADForest : The term 'Get-ADForest' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:114 char:25
+             $Targets = (Get-ADForest).Name
+                         ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-ADForest:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Install-WindowsFeature : The term 'Install-WindowsFeature' is not recognized as the name of a cmdlet, function, script
file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct
and try again.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:632 char:5
+     Install-WindowsFeature -Name RSAT-AD-PowerShell
+     ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Install-WindowsFeature:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Gathering AD CS Objects from ...
Get-ADCSObject : Cannot bind argument to parameter 'Targets' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:646 char:44
+     $ADCSObjects = Get-ADCSObject -Targets $Targets
+                                            ~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADCSObject], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-ADCSObject

Set-AdditionalCAProperty : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:647 char:43
+     Set-AdditionalCAProperty -ADCSObjects $ADCSObjects
+                                           ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Set-AdditionalCAProperty], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Set-AdditionalCAProperty

Get-CAHostObject : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:648 char:51
+     $ADCSObjects += Get-CAHostObject -ADCSObjects $ADCSObjects
+                                                   ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-CAHostObject], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-CAHostObject

Get-CAHostObject : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:649 char:46
+     $CAHosts = Get-CAHostObject -ADCSObjects $ADCSObjects
+                                              ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-CAHostObject], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-CAHostObject

The property 'Name' cannot be found on this object. Verify that the property exists.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:650 char:33
+     $CAHosts | ForEach-Object { $SafeUsers += '|' + $_.Name }
+                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

Identifying auditing issues...
Find-AuditingIssue : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:656 char:58
+ [array]$AuditingIssues = Find-AuditingIssue -ADCSObjects $ADCSObjects
+                                                          ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Find-AuditingIssue], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Find-AuditingIssue

Identifying AD CS templates with dangerous configurations...
Find-ESC1 : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:661 char:39
+ [array]$ESC1 = Find-ESC1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUs ...
+                                       ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Find-ESC1], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Find-ESC1

Find-ESC2 : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:662 char:39
+ [array]$ESC2 = Find-ESC2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUs ...
+                                       ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Find-ESC2], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Find-ESC2

Identifying AD CS template and other objects with poor access control...
Find-ESC4 : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:667 char:39
+ [array]$ESC4 = Find-ESC4 -ADCSObjects $ADCSObjects -SafeUsers $SafeUs ...
+                                       ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Find-ESC4], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Find-ESC4

Find-ESC5 : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:668 char:39
+ [array]$ESC5 = Find-ESC5 -ADCSObjects $ADCSObjects -SafeUsers $SafeUs ...
+                                       ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Find-ESC5], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Find-ESC5

Find-ESC6 : Cannot bind argument to parameter 'ADCSObjects' because it is null.
At C:\Users\***\Desktop\Invoke-Locksmith.ps1:669 char:39
+ [array]$ESC6 = Find-ESC6 -ADCSObjects $ADCSObjects
+                                       ~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Find-ESC6], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Find-ESC6
techspence commented 1 year ago

If you look at the first error message in your output, it would appear as though you do not have RSAT tools installed. image

It also looks like you're running this from a non-server os since you're also getting this error message image

Locksmith currently only supports installing RSAT AD PowerShell cmdlets via the server Install-WindowsFeature cmdlet. For Windows10 if you wanted to install ALL RSAT features, you could use this command:

Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online

Or if you just want the ActiveDirectory PowerShell cmdlets, this should work:

Add-WindowsCapability -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 -Online

After you've installed the appropriate PowerShell cmdlets, be sure to use the testing branch and try to run Locksmith again. Please let us know if that resolves your issue.

0x11DFE commented 1 year ago

powershell_Na0o2on4lb

Didn't do it

techspence commented 1 year ago

Are you running Locksmith using a DOMAIN account? Unfortunately, your screenshot doesn't provide a lot of information to go on. I'd recommend trying to troubleshoot your connection with the Domain/ADCS first by trying things like: Get-ADForest and certutil.exe -ping <ADCS server>.

0x11DFE commented 1 year ago

Are you running Locksmith using a DOMAIN account? Unfortunately, your screenshot doesn't provide a lot of information to go on. I'd recommend trying to troubleshoot your connection with the Domain/ADCS first by trying things like: Get-ADForest and certutil.exe -ping <ADCS server>.

I am testing it on my local system account, Am I not supposed to?

TrimarcJake commented 1 year ago

I am testing it on my local system account, Am I not supposed to?

Running Locksmith as a local account will not work in a properly configured Active Directory. Part of hardening AD is removing anonymous access to the directory. In very old AD environments that needed compatibility with NT4 domains, it may work correctly with a local account, but that's certainly not an expected use case.

Instead, Locksmith should be run in the context of a standard domain user. It's only been tested on domain-joined Windows machines, but I believe it should be able to work on a standalone computer if you use the -Credential switch.