SMBv1: Monitoring and Analyzing Access on Domain Controllers

What is SMB1 and What Does It Do?

Server Message Block Version 1 (SMB1) is an older protocol that facilitates file and printer sharing over a network. Widely used in Windows systems, it allows devices on a network to share data with each other.
However, due to security vulnerabilities, more modern and secure alternatives are recommended.

Advantages:

  • Compatible with older hardware.
  • Simplifies file and printer sharing over a network.

Disadvantages:

  • Prone to security issues and more vulnerable to ransomware attacks.
  • May have lower performance.


Finding SMB1 Access on Domain Controllers

To locate SMB1 access on Domain Controller (DC) servers, the first step is to ensure that the Audit-SMB1Access feature is enabled. This feature collects SMB1 access control logs, making them available for analysis.
These logs focus on specific periods (e.g., the last 10 days).

 

SMBAnalysis
SMBAnalysis

 

Enabling the Audit Feature
To enable SMB1 access logging on Domain Controller servers, use the following PowerShell command:

# Get Domain Controllers

$DomainControllers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Name

# Checking SMBServerConfiguration AuditSmb1Access

foreach ($DC in $DomainControllers) {

    try {

        # Set-SmbServerConfiguration

        $AuditSmb1Access = Invoke-Command -ComputerName $DC -ScriptBlock {

            Set-SmbServerConfiguration -AuditSmb1Access $true -Force

        }

        Write-Host ("Audit SMB1 Access on {0}: {1}" -f $DC, $true) -ForegroundColor Green

    } catch {

        Write-Host ("Failed to enable Audit SMB1 Access on {0}: {1}" -f $DC, $_.Exception.Message) -ForegroundColor Red

    }

}


To check SMB1 access logging on Domain Controller servers, use the following PowerShell command:

# Get Domain Controller

$DomainControllers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Name

# Checking SMBServerConfiguration AuditSmb1Access

foreach ($DC in $DomainControllers) {

    try {

        # Get-SmbServerConfiguration

        $AuditSmb1Access = Invoke-Command -ComputerName $DC -ScriptBlock {

            Get-SmbServerConfiguration | Select-Object -ExpandProperty AuditSmb1Access

        }

        Write-Host ("Audit SMB1 Access on {0}: {1}" -f $DC, $AuditSmb1Access) -ForegroundColor Green

    } catch {

        Write-Host ("Failed to check Audit SMB1 Access on {0}: {1}" -f $DC, $_.Exception.Message) -ForegroundColor Red

    }

}

Exporting SMB1 Audit Logs

To analyze SMB1 access logs on Domain Controller servers, use PowerShell to deduplicate this data and review activities over the last 10 days.

$DCList = Get-ADDomainController -Filter *

# Calculate the date 10 days ago

$CutOffDate = (Get-Date).AddDays(-10)

foreach ($DC in $DCList) {

    $DCname = $DC.HostName

    Write-Host "Processing domain controller: $DCname"

    Write-Host "---------------------------------------"

    # HashTable to store unique entries (IP as key, latest timestamp as value)

    $UniqueEntries = @{}

    # Retrieve SMB1 audit logs

    $SMB1Audits = Get-WinEvent -LogName Microsoft-Windows-SMBServer/Audit -ComputerName $DCname

    # Process each log message

    $SMB1Audits | Where-Object { $_.TimeCreated -ge $CutOffDate } | ForEach-Object {

        $eventTime = $_.TimeCreated # Get the event timestamp

        $text = $_.Message.ToString().Split([Environment]::NewLine)

        $client = $text | Where-Object {$_ -like "Client*"}

        if ($client) {

            # Extract and clean the IP address

            $clientIP = $client.Trim()

            # Update the hashtable with the latest event time for the IP

            if ($UniqueEntries.ContainsKey($clientIP)) {

                if ($eventTime -gt $UniqueEntries[$clientIP]) {

                    $UniqueEntries[$clientIP] = $eventTime

                }

            } else {

                $UniqueEntries[$clientIP] = $eventTime

            }

        }

    }

    # Write unique entries to the output file

    $OutputPath = "C:\Scripts\SMB1Analysis\$DCname.txt"

    $UniqueEntries.GetEnumerator() | ForEach-Object {

        "$($_.Value) - $($_.Key)"

    } | Set-Content -Path $OutputPath

    Write-Host "Unique client entries (last 10 days) saved to: $OutputPath"

}

Addressing Security Concerns

  • Identify Security Vulnerabilities: SMB1 has inherent security vulnerabilities and, as an older protocol, is more susceptible to ransomware attacks and network threats. Analyze SMB1 logs to identify potential security risks and breaches.
  • Remediation and Updates: If critical security flaws are found in devices using SMB1, it is essential to update them with security patches. Additionally, consider disabling SMB1 or migrating these devices to a more secure SMB version (SMB2 or SMB3).

Protocol Transition and Reconfiguration

  • Transition from SMB1 to SMB2 or SMB3: To close security gaps associated with SMB1 and enhance overall network security, transition all devices from SMB1 to a more modern and secure SMB version (SMB2 or SMB3). This transition can also improve network performance.
  • Configuration Changes: Adjust Domain Controller settings to disable SMB1 access. This can be done via PowerShell or Group Policy.

Updating Network Security Policies

  • Firewall Rules: SMB1 should only be used on trusted networks, with firewall rules restricting SMB1 access. If necessary, SMB1 should not be accessible to the outside world.
  • Monitoring and Auditing: Continuously monitor and audit SMB1 access on all network devices to detect security breaches early. Regularly review audit logs and address any issues promptly.

User Awareness and Training

  • Limit SMB1 Usage: Educate users about the security risks associated with SMB1 and discourage its use. Provide guidance and training to migrate users to more secure alternatives like SMB2 or SMB3.
  • Documentation: Maintain detailed documentation on changes made and security measures taken. This will serve as a reference in case of similar situations in the future and can be used as a resource for network management.

Periodic Checks and Maintenance

  • Regular Checks: SMB1 usage and security audits should be performed regularly. Periodically check SMB1 logs and network security settings to enhance overall network security and quickly identify potential issues.
  • Security Updates and Patching: Regularly update devices with security patches to protect against new vulnerabilities. This is particularly critical for older hardware.

These steps summarize the fundamental processes needed to enhance your network’s security and resilience against potential threats.

Have a nice day !

Efficient DNS Zone Management: Scripts for Forward, Reverse Lookup Zones and Recovery

At its core, DNS is a system that eliminates the complexity of accessing services via IP addresses by allowing users to connect effortlessly using domain names.

  • It facilitates domain name resolution and management.
  • Directs queries to the appropriate destinations.

DNS zones and reverse lookup zones are crucial components of a robust and secure network infrastructure.

In this article, I will share several scripts that you can use as needed. These scripts are designed to address the following requirements:

  • Exporting the names of all zones in DNS
  • Extracting all records associated with the zones listed in the exported file
  • Exporting all records from a specific zone of your choice
  • Restoring a deleted zone if necessary
  • Add Reverse Lookup Zones

Exporting All Zones in DNS

# Output file path

$outputFile = "C:\Script\DNSOperation\DNSZoneNameExport.csv"

try {

    # Fetching DNS zones

    $zones = Get-DnsServerZone

    if ($zones) {

        # Preparing data for export

        $zoneData = $zones | Select-Object -Property ZoneName

        # Exporting to CSV

        $zoneData | Export-Csv -Path $outputFile -NoTypeInformation -Encoding UTF8

        Write-Host "DNS zones have been successfully exported to $outputFile" -ForegroundColor Green

    } else {

        Write-Host "No DNS zones found." -ForegroundColor Yellow

    }

} catch {

    Write-Host "An error occurred while fetching DNS zones: $_" -ForegroundColor Red

}

Exporting All Zones in Records

# Zones CSV Path

$zonesFile = "C:\Script\DNSOperation\DNSZoneNameExport.csv"

$zones = Import-Csv -Path $zonesFile

foreach ($zone in $zones) {

    $zoneName = $zone.ZoneName

    $OutputFile = "C:\Script\DNSOperation\$zoneName.csv"

    $Report = [System.Collections.Generic.List[Object]]::new()

    $zoneInfo = Get-DnsServerResourceRecord -ZoneName $zoneName

    foreach ($info in $zoneInfo) {

        $timestamp = if ($info.Timestamp) { $info.Timestamp } else { "static" }

        $timetolive = $info.TimeToLive.TotalSeconds

        $recordData = switch ($info.RecordType) {

            'A' { $info.RecordData.IPv4Address }

            'CNAME' { $info.RecordData.HostnameAlias }

            'NS' { $info.RecordData.NameServer }

            'SOA' { "[$($info.RecordData.SerialNumber)] $($info.RecordData.PrimaryServer), $($info.RecordData.ResponsiblePerson)" }

            'SRV' { $info.RecordData.DomainName }

            'PTR' { $info.RecordData.PtrDomainName }

            'MX' { $info.RecordData.MailExchange }

            'AAAA' { $info.RecordData.IPv6Address }

            'TXT' { $info.RecordData.DescriptiveText }

            default { $null }

        }

        $ReportLine = [PSCustomObject]@{

            Name       = $zoneName

            Hostname   = $info.Hostname

            Type       = $info.RecordType

            Data       = $recordData

            Timestamp  = $timestamp

            TimeToLive = $timetolive

        }

        $Report.Add($ReportLine)

    }

    $Report | Export-Csv -Path $OutputFile -NoTypeInformation -Encoding utf8

    Write-Host "DNS records for $zoneName exported successfully." -ForegroundColor Green

}


Exporting Specific Zone in Records

try {

    $Report = [System.Collections.Generic.List[Object]]::new()

    $zoneName = "yusufustundag.com"

    # Fetching zone information

    try {

        $zoneInfo = Get-DnsServerResourceRecord -ZoneName $zoneName -ErrorAction Stop

    } catch {

        Write-Host "Error: Unable to fetch zone information. Zone name: $zoneName" -ForegroundColor Red

        throw $_

    }

    # Processing records

    foreach ($info in $zoneInfo) {

        try {

            $timestamp = if ($info.Timestamp) { $info.Timestamp } else { "static" }

            $timetolive = if ($info.TimeToLive) { $info.TimeToLive.TotalSeconds } else { "N/A" }

            $recordData = switch ($info.RecordType) {

                'A'      { if ($info.RecordData.IPv4Address) { $info.RecordData.IPv4Address } else { "No IP" } }

                'CNAME'  { if ($info.RecordData.HostnameAlias) { $info.RecordData.HostnameAlias } else { "No Alias" } }

                'NS'     { if ($info.RecordData.NameServer) { $info.RecordData.NameServer } else { "No NameServer" } }

                'SOA'    { if ($info.RecordData) { "[$($info.RecordData.SerialNumber)] $($info.RecordData.PrimaryServer), $($info.RecordData.ResponsiblePerson)" } else { "No SOA Information" } }

                'SRV'    { if ($info.RecordData.DomainName) { $info.RecordData.DomainName } else { "No Domain" } }

                'PTR'    { if ($info.RecordData.PtrDomainName) { $info.RecordData.PtrDomainName } else { "No PTR" } }

                'MX'     { if ($info.RecordData.MailExchange) { $info.RecordData.MailExchange } else { "No Mail Exchange" } }

                'AAAA'   { if ($info.RecordData.IPv6Address) { $info.RecordData.IPv6Address } else { "No IPv6" } }

                'TXT'    { if ($info.RecordData.DescriptiveText) { $info.RecordData.DescriptiveText } else { "No TXT" } }

                default  { "Unsupported record type: $($info.RecordType)" }

            }

            $ReportLine = [PSCustomObject]@{

                Name       = $zoneName

                Hostname   = $info.Hostname

                Type       = $info.RecordType

                Data       = $recordData

                Timestamp  = $timestamp

                TimeToLive = $timetolive

            }

            $Report.Add($ReportLine)

        } catch {

            Write-Host "Error: An issue occurred while processing the record. Hostname: $($info.Hostname), Type: $($info.RecordType)" -ForegroundColor Red

            Write-Host "Details: $_" -ForegroundColor Yellow

        }

    }

    # Writing to CSV

    try {

        $Report | Export-Csv "C:\Script\DNSOperation\DNSZoneRecord.csv" -NoTypeInformation -Encoding utf8

        Write-Host "DNS records have been successfully exported." -ForegroundColor Green

    } catch {

        Write-Host "Error: Failed to write to the CSV file." -ForegroundColor Red

        throw $_

    }

} catch {

    Write-Host "An unexpected error occurred: $_" -ForegroundColor Red

}

 

These scripts might seem a bit complex, but the .csv data they generate can effectively meet your needs in situations requiring reporting or verification.

Reading data may not always be easier than working with a .csv file, but in the event of a zone deletion, our other script utilizing the Export-DnsServerZone and dnscmd commands will provide a quick recovery solution.

Recovery – Export Import Specific Zone

Export-DNSServerZone -name yusufustundag.com -FileName yusufustundagExport

After completing the export process, you can find the exported file under the C:\Windows\System32\dns directory.

Now, here’s a critical point: suppose you’ve exported all your zones using this method, but someone accidentally deleted one or more zones. How can you quickly recover them in such a scenario?

The script we will use for this recovery must include the zone name and the name of the exported zone, as shown below.

dnscmd /zoneadd "yusufustundag.com" /primary /file yusufustundagExport /Load

 

Add Reverse Lookup Zone

$Zones = @(

    "1.1.0.0/24",  # Subnet /24 (255.255.255.0)

    "2.2.0.0/24",

    "10.10.151.0/24"

)

foreach ($Zone in $Zones) {

    try {

        # Split the NetworkID and Subnet Mask

        $SubnetArray = $Zone -split '/'

        $IPAddress = $SubnetArray[0]

        $SubnetMask = [int]$SubnetArray[1]

        # Generate the Reverse Lookup Zone Name based on Subnet Mask

        $Octets = $IPAddress -split '\.'

        if ($SubnetMask -le 8) {

            $RevZone = "$($Octets[0]).in-addr.arpa"

        } elseif ($SubnetMask -le 16) {

            $RevZone = "$($Octets[1]).$($Octets[0]).in-addr.arpa"

        } elseif ($SubnetMask -le 24) {

            $RevZone = "$($Octets[2]).$($Octets[1]).$($Octets[0]).in-addr.arpa"

        } else {

            $RevZone = "$($Octets[3]).$($Octets[2]).$($Octets[1]).$($Octets[0]).in-addr.arpa"

        }

        # Check if the Reverse Zone Already Exists

        $ExistingZone = Get-DnsServerZone -Name $RevZone -ErrorAction SilentlyContinue

        

        if ($ExistingZone) {

            Write-Output "Reverse Lookup Zone '$RevZone' already exists."

        } else {

            # Add the Reverse Lookup Zone

            Add-DnsServerPrimaryZone -NetworkID $Zone -ReplicationScope "Domain"

            Write-Output "Reverse Lookup Zone '$RevZone' added successfully."

        }

    } catch {

        # Handle Errors Gracefully

        if ($_.Exception.Message -match "ResourceExists") {

            Write-Output "Reverse Lookup Zone '$RevZone' already exists (error caught)."

        } else {

            Write-Error "Failed to add Reverse Lookup Zone '$RevZone': $_"

        }

    }

}

 

Have a nice day!