From 4abd2aef3b6f451107c808229fca73c12b7a30ca Mon Sep 17 00:00:00 2001 From: Philos Date: Wed, 18 Jun 2025 09:28:38 -0400 Subject: [PATCH 1/5] WIP: ldap checking script (real) --- windows/powershell/ldapcheck.ps1 | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/windows/powershell/ldapcheck.ps1 b/windows/powershell/ldapcheck.ps1 index e69de29..21af213 100644 --- a/windows/powershell/ldapcheck.ps1 +++ b/windows/powershell/ldapcheck.ps1 @@ -0,0 +1,49 @@ +# Script still in testing phase. Idea behind it is very cool, but complexity is high, and I want to be able to document it well + +# Prompt user for input +# Hard code domain prior to running in comp + +# Will add the ability to pass in parameters later, but for now I need to run more testing first +$domain = Read-Host "Enter domain (example.com)" +$username = Read-Host "Enter username" +$password = Read-Host "Enter password" -AsSecureString +# Prevents the password from being displayed in plain text in the console. This makes the script messier, but more secure. +# When marshal is used to convert the secure string to a plain text string, it will expose the password in memory. This is not ideal +# Solution to the memory problem given by AI: + #$ptr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) + #$plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto($ptr) + +# Zero out and free the unmanaged memory (important for security) + #[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr) +# Requires more testing to see if this is trustworthy or neccesary + + +# Convert secure string to plain text for LDAP use +# Marshal is a NET class used to convert between managed and unmanaged code (In this case, raw memory) +# Second half turns the secure string into a BSTR (Binary String), and then returns a pointer to that BSTR (This is the piece that exposes the password in memory) +# The pointer is then converted to a plain string using the PtrToStringAuto +$plainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto( + [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) +) + +# Construct the LDAP path and credentials +$ldapPath = "LDAP://$domain" +$userPrincipal = "$domain\$username" + +try { + # Create the DirectoryEntry object with credentials + # This does not create an object in the directory, it creates a local object that represents the LDAP path and credentials you want to use to access it + $entry = New-Object System.DirectoryServices.DirectoryEntry($ldapPath, $userPrincipal, $plainPassword) + + # Attempt to access a property to trigger the bind + # This takes the path and credentials you provided before, and attempts to bind to the LDAP server using those credentials + # This seems like a really weird and specific way to do this, but stackoverflow said it was a good idea, and I cant see any reason why it wouldnt wory or be insecure. + $native = $entry.NativeObject + + Write-Host "LDAP authentication successful." +} +catch { + Write-Host "LDAP connection to $domain as $username failed with error:" -ForegroundColor Red + Write-Host $_.Exception.GetType().FullName "`n" -ForegroundColor Red + Write-Host $_.Exception.Message -ForegroundColor Red +} From cc1b5a494524d580dfc0c7160d162b718ba94ddb Mon Sep 17 00:00:00 2001 From: Philos Date: Fri, 20 Jun 2025 13:35:26 -0400 Subject: [PATCH 2/5] WIP: DNScheck script --- windows/dnscheck.ps1 | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 windows/dnscheck.ps1 diff --git a/windows/dnscheck.ps1 b/windows/dnscheck.ps1 new file mode 100644 index 0000000..d10a39b --- /dev/null +++ b/windows/dnscheck.ps1 @@ -0,0 +1,64 @@ + +# This script is probably way more complicated than neccesary. by far the one I'm the most unsure of atm +param ( + #Dns name being checked + [Parameter(Mandatory = $true)] + [string]$name, + + # Next 2 are only for listing + [Parameter(Mandatory = $false)] + [string]$dnsServer, + + [switch]$list +) + +# Returns all records on the DNS server +# this part of the script probably doesnt work but I cant test it, the @ was giving me problems despite the documentation saying it was correct +if ($list) { + if (-not $dnsServer) { + Write-Error "You must specify a Target DNS server when using the -list switch with -dnsServer" + exit 1 +} + dnscmd $dnsServer /enumrecords $name [@] +} + +# First section is a bit of a relic from when I was trying to display it a different way, but it works +else { + $dnsInfo = Get-DnsClientServerAddress | Where-Object { $_.AddressFamily -eq 2 } | Select-Object InterfaceAlias, ServerAddresses + + # Gives you a nuce little printout showing if it can contact the DNS server + foreach ($entry in $dnsInfo) { + # Skip if no DNS servers are listed + if (-not $entry.ServerAddresses -or $entry.ServerAddresses.Count -eq 0) { + continue + } + + Write-Host "`nInterface: $($entry.InterfaceAlias)" -ForegroundColor Cyan + + foreach ($server in $entry.ServerAddresses) { + Write-Host -NoNewline "Checking DNS server: $server... " + + if (Test-Connection -ComputerName $server -Count 2 -Quiet -ErrorAction SilentlyContinue) { + Write-Host "Reachable" -ForegroundColor Green + } + else { + Write-Host "Not reachable" -ForegroundColor Red + } + } + } + + # Attempt to resolve the DNS name using nslookup and Resolve-DnsName + try { + # Nslookup tells you what server is trying to resolve the name, and Resolve-DnsName gives you a much nicer output. Wish this could be a one liner + nslookup $name 2>&1 | Where-Object { $_ -match '^(Server:|Address:)' } -ForegroundColor Green + Resolve-DnsName -name $name -ErrorAction Stop + + } + catch { + # Main issue with this script atm is that its errors are not very useful. The exception message is almost always the same, despite the potential for it to be a couple issues + # the -list function was made to help testing problems, but isnt a great bandaid. Would be better if the DNS server check specifically tried to see if it was operational + # as a DNS server without trying to resolve the name. Maybe have it just try to resolve google.com or something? + Write-Host "DNS resolution failed." -ForegroundColor Red + Write-Host $_.Exception.Message + } +} \ No newline at end of file From 91669cfa2afb361fcd006cb1dddc4e74ba245796 Mon Sep 17 00:00:00 2001 From: Philos Date: Fri, 20 Jun 2025 13:42:03 -0400 Subject: [PATCH 3/5] Spelling errors. I can commit this bc its my own branch so you cant say yap andrew --- windows/{ => powershell}/dnscheck.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename windows/{ => powershell}/dnscheck.ps1 (89%) diff --git a/windows/dnscheck.ps1 b/windows/powershell/dnscheck.ps1 similarity index 89% rename from windows/dnscheck.ps1 rename to windows/powershell/dnscheck.ps1 index d10a39b..e56602c 100644 --- a/windows/dnscheck.ps1 +++ b/windows/powershell/dnscheck.ps1 @@ -1,5 +1,7 @@ # This script is probably way more complicated than neccesary. by far the one I'm the most unsure of atm +# Not very happy with the current state. + param ( #Dns name being checked [Parameter(Mandatory = $true)] @@ -19,6 +21,7 @@ if ($list) { Write-Error "You must specify a Target DNS server when using the -list switch with -dnsServer" exit 1 } + # @ should look at the zone root and enumerate all records in the zone. hypothetically. Microsoft says so. Powershell doesnt like it dnscmd $dnsServer /enumrecords $name [@] } @@ -26,7 +29,7 @@ if ($list) { else { $dnsInfo = Get-DnsClientServerAddress | Where-Object { $_.AddressFamily -eq 2 } | Select-Object InterfaceAlias, ServerAddresses - # Gives you a nuce little printout showing if it can contact the DNS server + # Gives you a nice little printout showing if it can contact the DNS server foreach ($entry in $dnsInfo) { # Skip if no DNS servers are listed if (-not $entry.ServerAddresses -or $entry.ServerAddresses.Count -eq 0) { From 58a5549cb435ab4cfc061d7a0f8aa2c9c0ce1409 Mon Sep 17 00:00:00 2001 From: Phil-OS Date: Sat, 9 Aug 2025 10:15:55 -0400 Subject: [PATCH 4/5] The weak old DNS checking script vs the Chad new DNS checking script. No really its insane just how much better this one is --- windows/powershell/dnscheck.ps1 | 148 +++++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 40 deletions(-) diff --git a/windows/powershell/dnscheck.ps1 b/windows/powershell/dnscheck.ps1 index e56602c..4c7aa30 100644 --- a/windows/powershell/dnscheck.ps1 +++ b/windows/powershell/dnscheck.ps1 @@ -1,67 +1,135 @@ - -# This script is probably way more complicated than neccesary. by far the one I'm the most unsure of atm -# Not very happy with the current state. - param ( - #Dns name being checked - [Parameter(Mandatory = $true)] - [string]$name, + # Domain name being checked + [Parameter(Mandatory = $false)] + [string]$Name, - # Next 2 are only for listing + # These 2 are only for listing [Parameter(Mandatory = $false)] - [string]$dnsServer, + [string]$DnsServer, - [switch]$list + [switch]$List ) -# Returns all records on the DNS server -# this part of the script probably doesnt work but I cant test it, the @ was giving me problems despite the documentation saying it was correct -if ($list) { - if (-not $dnsServer) { - Write-Error "You must specify a Target DNS server when using the -list switch with -dnsServer" +# Usage was done by AI but its so cool +function Show-Usage { + Write-Host "`nUsage:" -ForegroundColor Yellow + Write-Host " .\$(Split-Path -Leaf $PSCommandPath) -Name [-List] [-DnsServer ]" -ForegroundColor White + Write-Host "`nParameters:" -ForegroundColor Yellow + Write-Host " -Name Domain name to resolve or check." -ForegroundColor White + Write-Host " -List List all records for the given domain (requires -DnsServer)." -ForegroundColor White + Write-Host " -DnsServer Target DNS server for listing." -ForegroundColor White + Write-Host "`nExamples:" -ForegroundColor Yellow + Write-Host " Check DNS servers and resolve a name:" -ForegroundColor White + Write-Host " .\dnscheck.ps1 -Name example.com" -ForegroundColor DarkGray + Write-Host " List records from a specific DNS server:" -ForegroundColor White + Write-Host " .\dnscheck.ps1 -Name example.com -List -DnsServer 192.168.1.1" -ForegroundColor DarkGray + Write-Host "" +} + +# Show usage if parameters are invalid +if ($List -and -not $DnsServer) { + Write-Error "You must specify -DnsServer when using -List." + Show-Usage exit 1 } - # @ should look at the zone root and enumerate all records in the zone. hypothetically. Microsoft says so. Powershell doesnt like it - dnscmd $dnsServer /enumrecords $name [@] -} -# First section is a bit of a relic from when I was trying to display it a different way, but it works -else { - $dnsInfo = Get-DnsClientServerAddress | Where-Object { $_.AddressFamily -eq 2 } | Select-Object InterfaceAlias, ServerAddresses +if (-not $Name) { + Write-Error "Missing required parameter: -Name." + Show-Usage + exit 1 +} + + +# Function returns all of the records on a given DNS server. Only run when List is true +function Show-Records { + param( + [string]$Target, + [string]$Zone + ) + + try { + $records = dnscmd $Target /enumrecords $Zone '@' 2>&1 + # since dnscmd is a cmd utility and not a cmdlet, error handling was a bit weird. This should work + if ($LASTEXITCODE -ne 0) { + throw "Failed to enumerate records from $Target" + } + # Returns the string value of dnscommand + $records + } + catch { + Write-Error "Error retrieving DNS records: $_" + } +} + + +function Test-Servers { + $dnsInfo = Get-DnsClientServerAddress | # Grabs all DNS servers for each interface + Where-Object { $_.AddressFamily -eq 2 } | # Only ones with ipv4 addresses + Select-Object InterfaceAlias, ServerAddresses # Selects both the interface its on, and the IP of the dns server - # Gives you a nice little printout showing if it can contact the DNS server foreach ($entry in $dnsInfo) { - # Skip if no DNS servers are listed - if (-not $entry.ServerAddresses -or $entry.ServerAddresses.Count -eq 0) { - continue + if (-not $entry.ServerAddresses -or $entry.ServerAddresses.Count -eq 0) { # if the entry is either null or 0, skip it. This does happen, as if the record is only ipv6 then it will still grab it unfortunatly + continue # Continue is neat- it skips the current loop but doesnt break and moves on to the next item } - Write-Host "`nInterface: $($entry.InterfaceAlias)" -ForegroundColor Cyan + # if you are struggling to read the next 2 lines, its nested arrays. + Write-Host "`nInterface: $($entry.InterfaceAlias)" -ForegroundColor Cyan foreach ($server in $entry.ServerAddresses) { Write-Host -NoNewline "Checking DNS server: $server... " - - if (Test-Connection -ComputerName $server -Count 2 -Quiet -ErrorAction SilentlyContinue) { - Write-Host "Reachable" -ForegroundColor Green - } + # Test-NetConnection returns a bool when Informationlevel is set to Quiet. very neat! + if (Test-NetConnection -ComputerName $server -Port 53 -InformationLevel Quiet -ErrorAction SilentlyContinue) { + Write-Host "Port 53 Reachable and accepting." -ForegroundColor Green + } else { - Write-Host "Not reachable" -ForegroundColor Red + # Actually a great error check. This step *can* be slow, but it will give an overview of if it can connect to the host VIA ICMP, what its route was, etc etc. + Write-Host "Server is either unreachable or blocking traffic to port 53. Printing diagnostic overview" -ForegroundColor Red + Test-NetConnection -ComputerName $server -TraceRoute -informationlevel detailed } } } +} + +function Resolve-Dns { + param( + [string]$QueryName + ) - # Attempt to resolve the DNS name using nslookup and Resolve-DnsName try { - # Nslookup tells you what server is trying to resolve the name, and Resolve-DnsName gives you a much nicer output. Wish this could be a one liner - nslookup $name 2>&1 | Where-Object { $_ -match '^(Server:|Address:)' } -ForegroundColor Green - Resolve-DnsName -name $name -ErrorAction Stop + # prints out the responding DNS server, along with its address + $nsResult = nslookup $QueryName 2>&1 | Where-Object { $_ -match '^(Server:|Address:)' } + if ($nsResult) { + Write-Host "`nNSLookup Results:" -ForegroundColor Yellow + $nsResult + } + else { + Write-Warning "No nslookup results. Check to see if computer is on fire and/or someone ran chatgpt powershell" + } + # Resolve-DnsName + Write-Host "`nResolve-DnsName Results:" -ForegroundColor Yellow + Resolve-DnsName -Name $QueryName -ErrorAction Stop # throws if an error occurs. Otherwise prints all of the records associated with the query } catch { - # Main issue with this script atm is that its errors are not very useful. The exception message is almost always the same, despite the potential for it to be a couple issues - # the -list function was made to help testing problems, but isnt a great bandaid. Would be better if the DNS server check specifically tried to see if it was operational - # as a DNS server without trying to resolve the name. Maybe have it just try to resolve google.com or something? Write-Host "DNS resolution failed." -ForegroundColor Red - Write-Host $_.Exception.Message + Write-Warning $_.Exception.Message } -} \ No newline at end of file +} + +# --- Main --- + +if ($List) { + if (-not $DnsServer) { + Write-Error "You must specify a target DNS server with -DnsServer when using -List." + exit 1 + } + Show-Records -Target $DnsServer -Zone $Name +} +else { + Test-Servers + Resolve-Dns -QueryName $Name +} + + + + From e56636c028ea1d4ab3919d6806af4c49a192fb5b Mon Sep 17 00:00:00 2001 From: Phil-OS Date: Mon, 25 Aug 2025 19:15:11 -0400 Subject: [PATCH 5/5] Fix- Issue #3 --- windows/powershell/dnscheck.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/powershell/dnscheck.ps1 b/windows/powershell/dnscheck.ps1 index 4c7aa30..163e617 100644 --- a/windows/powershell/dnscheck.ps1 +++ b/windows/powershell/dnscheck.ps1 @@ -83,7 +83,7 @@ function Test-Servers { } else { # Actually a great error check. This step *can* be slow, but it will give an overview of if it can connect to the host VIA ICMP, what its route was, etc etc. - Write-Host "Server is either unreachable or blocking traffic to port 53. Printing diagnostic overview" -ForegroundColor Red + Write-Host "ICMP Check Failed. Target may be unreachable, or Port 53 may be closed" -ForegroundColor Red Test-NetConnection -ComputerName $server -TraceRoute -informationlevel detailed } }