itm4n / PrivescCheck

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

Check SMB signing required #55

Closed Acebond closed 1 month ago

Acebond commented 4 months ago

PrivescCheck covers the majority of the host checks I'd perform except SMB signing, which is often useful to know, especially as there are a bunch of different and whacky (like https://github.com/nccgroup/Change-Lockscreen) ways to coerce a SYSTEM/user account to authenticate to a capture/relay server.

https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/overview-server-message-block-signing

I've written a reference implementation below. I reckon it should probably be in the -Extended category?

function Get-SMBSigningStatus {
# NOTE: The EnableSecuritySignature registry setting for SMB2+ client and SMB2+ server is ignored.
# Therefore, this setting does nothing unless you're using SMB1. So we only care about RequireSecuritySignature.
# https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/overview-server-message-block-signing

    $SmbClientSettingsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanManWorkstation\Parameters"
    $SmbServerSettingsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"

    # Check if the registry value exists
    if (Test-Path $SmbClientSettingsPath) {

        $value = Get-ItemPropertyValue -Path $SmbClientSettingsPath -Name "RequireSecuritySignature" -ErrorAction SilentlyContinue
        $status = if ($value -eq 1) { "Required" } else { "NOT Required" }
        Write-Output "SMB Client signing is $status."

    } else {

        Write-Output "SMB Client signing settings not found"
    }

    # Check if the registry value exists
    if (Test-Path $SmbServerSettingsPath) {

        $value = Get-ItemPropertyValue -Path $SmbServerSettingsPath -Name "RequireSecuritySignature" -ErrorAction SilentlyContinue
        $status = if ($value -eq 1) { "Required" } else { "NOT Required" }
        Write-Output "SMB Server signing is $status."

    } else {

        Write-Output "SMB Server signing settings not found"
    }

}

Get-SMBSigningStatus
itm4n commented 4 months ago

Hey!

Well, I have mixed feelings about this. On the one hand, I totally get your point as this is something I would report during a pentest. But on the other hand, I would like to avoid turning PrivescCheck into a "configuration audit tool" as far as possible. That being said, SMB signing enforcement is a big topic, that might be worth considering on its own.

I'll have to think about it. :)

rustaska commented 2 months ago

@Acebond Your suggested method will currently work but not in the future. Microsoft decided to require SMB signing by default in future releases, which means the registry value "RequireSecuritySignature" does not necessarily have to be around to have SMB signing enabled.

You can read it in this blog post: https://techcommunity.microsoft.com/t5/storage-at-microsoft/smb-signing-required-by-default-in-windows-insider/ba-p/3831704

According to this, a future proof method will be using the Get-SmbServerConfiguration and Get-SmbClientConfiguration Cmdlet or the CIM classes MSFT_SmbClientConfiguration and MSFT_SmbServerConfiguration.

itm4n commented 1 month ago

Commit 099b4d3 prepares the ground for handling "configuration audit" checks. It adds a new check type - Audit - and the corresponding command line flag -Audit. This will allow me to add an SMB signing check in this category.

itm4n commented 1 month ago

Added with commit c323bcc6f7fc1cda719db731110fdb66b418ee80. I finally found a solution to get the configuration without breaking PSv2 compatibility.

You will have to use the option -Audit on the command line to enable this check.

Thanks @rustaska for the tips.

Sample output:

+----------+---------------------------------------------------+
| CATEGORY | TA0008 - Lateral Movement                         |
| NAME     | SMB configuration                                 |
+----------+---------------------------------------------------+
| Check whether SMBv1 is enabled (server), and whether signing |
| is required (server and client).                             |
+--------------------------------------------------------------+
[*] Status: Vulnerable - Low

Role        : Server
Parameter   : EnableSMB1Protocol
Value       : False
Vulnerable  : False
Description : SMBv1 is disabled.

Role        : Server
Parameter   : RequireSecuritySignature
Value       : False
Vulnerable  : True
Description : SMB signing is not required.

Role        : Client
Parameter   : RequireSecuritySignature
Value       : False
Vulnerable  : True
Description : SMB signing is not required.
Acebond commented 1 month ago

Legend. I just checked and it works for me. I'm going to close the issue.