From c6a93e708086c6531f3f6ebc9ed0aecaf5891f11 Mon Sep 17 00:00:00 2001 From: Rephl3x Date: Wed, 24 Sep 2025 00:32:16 +0000 Subject: [PATCH] Add cartographer.ps1 --- cartographer.ps1 | 316 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 cartographer.ps1 diff --git a/cartographer.ps1 b/cartographer.ps1 new file mode 100644 index 0000000..c7df3ea --- /dev/null +++ b/cartographer.ps1 @@ -0,0 +1,316 @@ +# Cartographer - DNS Record Mapping Tool with GUI - Map - IP to DNS record based on subnet +# Import required assemblies for GUI +Add-Type -AssemblyName System.Windows.Forms +Add-Type -AssemblyName System.Drawing + +# Convert IP addresses to integers for comparison +function Convert-IPToInt { + param ( + [string]$IPAddress + ) + [array]$octets = $IPAddress.Split('.') + return [int]($octets[0]) * 16777216 + [int]($octets[1]) * 65536 + [int]($octets[2]) * 256 + [int]($octets[3]) +} + +# Convert integer back to IP address +function Convert-IntToIP { + param ( + [int64]$Integer + ) + $octet1 = [Math]::Floor($Integer / 16777216) + $remainder = $Integer % 16777216 + $octet2 = [Math]::Floor($remainder / 65536) + $remainder = $remainder % 65536 + $octet3 = [Math]::Floor($remainder / 256) + $octet4 = $remainder % 256 + return "$octet1.$octet2.$octet3.$octet4" +} + +# Get subnet range based on IP and mask +function Get-SubnetRange { + param ( + [string]$IPAddress + ) + + # Assuming /24 subnet + $octets = $IPAddress.Split('.') + $networkPrefix = "$($octets[0]).$($octets[1]).$($octets[2])" + $rangeStart = "$networkPrefix.1" + $rangeEnd = "$networkPrefix.254" + + return @{ + Start = $rangeStart + End = $rangeEnd + } +} + +# Get available DNS servers +function Get-AvailableDnsServers { +# $dnsServers = @("localhost") + + $clientDnsServers = Get-DnsClientServerAddress | + Where-Object { $_.ServerAddresses -ne $null } | + ForEach-Object { + $_.ServerAddresses | Where-Object { $_ -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' } + } | + Select-Object -Unique + + $dnsServers += $clientDnsServers + + # Try to add domain controllers if we're in a domain environment + try { + $domainControllers = Get-ADDomainController -Filter * | + ForEach-Object { $_.HostName } + $dnsServers += $domainControllers + } catch { + # Not in a domain environment or AD module not available, continue without it + } + + return $dnsServers | Select-Object -Unique +} + +# Query DNS for records +function Search-DnsRecords { + param ( + [string]$DnsServer, + [string]$IPRangeStart, + [string]$IPRangeEnd + ) + + $StartInt = Convert-IPToInt $IPRangeStart + $EndInt = Convert-IPToInt $IPRangeEnd + + $Results = @() + + try { + $Zones = Get-DnsServerZone -ComputerName $DnsServer -ErrorAction Stop + + foreach ($Zone in $Zones) { + $Records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ComputerName $DnsServer -ErrorAction SilentlyContinue + foreach ($Record in $Records) { + if ($Record.RecordType -eq "A") { + $IPInt = Convert-IPToInt $Record.RecordData.IPv4Address.ToString() + if ($IPInt -ge $StartInt -and $IPInt -le $EndInt) { + $Results += [PSCustomObject]@{ + IPAddress = $Record.RecordData.IPv4Address + Hostname = $Record.HostName + Zone = $Zone.ZoneName + } + } + } + } + } + } catch { + [System.Windows.Forms.MessageBox]::Show("Error querying DNS server: $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) + } + + return $Results +} + +# Create the main form +$form = New-Object System.Windows.Forms.Form +$form.Text = "Cartographer - DNS Record Mapping Tool" +$form.Size = New-Object System.Drawing.Size(800, 600) +$form.StartPosition = "CenterScreen" +$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog +$form.MaximizeBox = $false + +# DNS Server selection +$dnsServerLabel = New-Object System.Windows.Forms.Label +$dnsServerLabel.Text = "DNS Server:" +$dnsServerLabel.Location = New-Object System.Drawing.Point(20, 20) +$dnsServerLabel.Size = New-Object System.Drawing.Size(100, 20) +$form.Controls.Add($dnsServerLabel) + +$dnsServerComboBox = New-Object System.Windows.Forms.ComboBox +$dnsServerComboBox.Location = New-Object System.Drawing.Point(130, 20) +$dnsServerComboBox.Size = New-Object System.Drawing.Size(200, 20) +$dnsServerComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList +$form.Controls.Add($dnsServerComboBox) + +# Populate DNS Server dropdown +$dnsServers = Get-AvailableDnsServers +foreach ($server in $dnsServers) { + $dnsServerComboBox.Items.Add($server) +} +if ($dnsServerComboBox.Items.Count -gt 0) { + $dnsServerComboBox.SelectedIndex = 0 +} + +# IP Range Selection Group +$ipRangeGroupBox = New-Object System.Windows.Forms.GroupBox +$ipRangeGroupBox.Text = "IP Range Selection" +$ipRangeGroupBox.Location = New-Object System.Drawing.Point(20, 50) +$ipRangeGroupBox.Size = New-Object System.Drawing.Size(750, 120) +$form.Controls.Add($ipRangeGroupBox) + +# Radio buttons for range selection +$subnetRadioButton = New-Object System.Windows.Forms.RadioButton +$subnetRadioButton.Text = "Scan Full /24 Subnet" +$subnetRadioButton.Location = New-Object System.Drawing.Point(20, 20) +$subnetRadioButton.Size = New-Object System.Drawing.Size(150, 20) +$subnetRadioButton.Checked = $true +$ipRangeGroupBox.Controls.Add($subnetRadioButton) + +$customRangeRadioButton = New-Object System.Windows.Forms.RadioButton +$customRangeRadioButton.Text = "Custom IP Range" +$customRangeRadioButton.Location = New-Object System.Drawing.Point(20, 50) +$customRangeRadioButton.Size = New-Object System.Drawing.Size(150, 20) +$ipRangeGroupBox.Controls.Add($customRangeRadioButton) + +# Subnet IP entry +$subnetIPLabel = New-Object System.Windows.Forms.Label +$subnetIPLabel.Text = "Subnet IP Address:" +$subnetIPLabel.Location = New-Object System.Drawing.Point(180, 20) +$subnetIPLabel.Size = New-Object System.Drawing.Size(120, 20) +$ipRangeGroupBox.Controls.Add($subnetIPLabel) + +$subnetIPTextBox = New-Object System.Windows.Forms.TextBox +$subnetIPTextBox.Location = New-Object System.Drawing.Point(300, 20) +$subnetIPTextBox.Size = New-Object System.Drawing.Size(150, 20) +$subnetIPTextBox.Text = "192.168.1.1" +$ipRangeGroupBox.Controls.Add($subnetIPTextBox) + +# Custom range IP entries +$startIPLabel = New-Object System.Windows.Forms.Label +$startIPLabel.Text = "Start IP Address:" +$startIPLabel.Location = New-Object System.Drawing.Point(180, 50) +$startIPLabel.Size = New-Object System.Drawing.Size(120, 20) +$ipRangeGroupBox.Controls.Add($startIPLabel) + +$startIPTextBox = New-Object System.Windows.Forms.TextBox +$startIPTextBox.Location = New-Object System.Drawing.Point(300, 50) +$startIPTextBox.Size = New-Object System.Drawing.Size(150, 20) +$startIPTextBox.Text = "192.168.1.1" +$startIPTextBox.Enabled = $false +$ipRangeGroupBox.Controls.Add($startIPTextBox) + +$endIPLabel = New-Object System.Windows.Forms.Label +$endIPLabel.Text = "End IP Address:" +$endIPLabel.Location = New-Object System.Drawing.Point(460, 50) +$endIPLabel.Size = New-Object System.Drawing.Size(120, 20) +$ipRangeGroupBox.Controls.Add($endIPLabel) + +$endIPTextBox = New-Object System.Windows.Forms.TextBox +$endIPTextBox.Location = New-Object System.Drawing.Point(580, 50) +$endIPTextBox.Size = New-Object System.Drawing.Size(150, 20) +$endIPTextBox.Text = "192.168.1.254" +$endIPTextBox.Enabled = $false +$ipRangeGroupBox.Controls.Add($endIPTextBox) + +# Radio button event handlers +$subnetRadioButton.Add_CheckedChanged({ + if ($subnetRadioButton.Checked) { + $subnetIPTextBox.Enabled = $true + $startIPTextBox.Enabled = $false + $endIPTextBox.Enabled = $false + } +}) + +$customRangeRadioButton.Add_CheckedChanged({ + if ($customRangeRadioButton.Checked) { + $subnetIPTextBox.Enabled = $false + $startIPTextBox.Enabled = $true + $endIPTextBox.Enabled = $true + } +}) + +# Auto-calculate subnet range from subnet IP +$subnetIPTextBox.Add_TextChanged({ + if ($subnetRadioButton.Checked -and $subnetIPTextBox.Text -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') { + $range = Get-SubnetRange -IPAddress $subnetIPTextBox.Text + $startIPTextBox.Text = $range.Start + $endIPTextBox.Text = $range.End + } +}) + +# Search Button +$searchButton = New-Object System.Windows.Forms.Button +$searchButton.Text = "Search DNS Records" +$searchButton.Location = New-Object System.Drawing.Point(20, 180) +$searchButton.Size = New-Object System.Drawing.Size(150, 30) +$form.Controls.Add($searchButton) + +# Status Label +$statusLabel = New-Object System.Windows.Forms.Label +$statusLabel.Text = "Ready" +$statusLabel.Location = New-Object System.Drawing.Point(180, 185) +$statusLabel.Size = New-Object System.Drawing.Size(590, 20) +$form.Controls.Add($statusLabel) + +# Results DataGridView +$resultsDataGridView = New-Object System.Windows.Forms.DataGridView +$resultsDataGridView.Location = New-Object System.Drawing.Point(20, 220) +$resultsDataGridView.Size = New-Object System.Drawing.Size(750, 300) +$resultsDataGridView.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnsMode]::Fill +$resultsDataGridView.AllowUserToAddRows = $false +$resultsDataGridView.AllowUserToDeleteRows = $false +$resultsDataGridView.ReadOnly = $true +$resultsDataGridView.MultiSelect = $false +$resultsDataGridView.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect +$form.Controls.Add($resultsDataGridView) + +# Export Button +$exportButton = New-Object System.Windows.Forms.Button +$exportButton.Text = "Export Results" +$exportButton.Location = New-Object System.Drawing.Point(20, 530) +$exportButton.Size = New-Object System.Drawing.Size(120, 30) +$exportButton.Enabled = $false +$form.Controls.Add($exportButton) + +# Search button click event +$searchButton.Add_Click({ + $statusLabel.Text = "Searching DNS records..." + $resultsDataGridView.DataSource = $null + $exportButton.Enabled = $false + + $selectedDnsServer = $dnsServerComboBox.SelectedItem.ToString() + + $ipRangeStart = "" + $ipRangeEnd = "" + + if ($subnetRadioButton.Checked) { + $range = Get-SubnetRange -IPAddress $subnetIPTextBox.Text + $ipRangeStart = $range.Start + $ipRangeEnd = $range.End + } else { + $ipRangeStart = $startIPTextBox.Text + $ipRangeEnd = $endIPTextBox.Text + } + + $results = Search-DnsRecords -DnsServer $selectedDnsServer -IPRangeStart $ipRangeStart -IPRangeEnd $ipRangeEnd + + if ($results.Count -gt 0) { + $dataTable = New-Object System.Data.DataTable + $dataTable.Columns.Add("IPAddress", [string]) + $dataTable.Columns.Add("Hostname", [string]) + $dataTable.Columns.Add("Zone", [string]) + + foreach ($result in $results) { + $dataTable.Rows.Add($result.IPAddress.ToString(), $result.Hostname, $result.Zone) + } + + $resultsDataGridView.DataSource = $dataTable + $statusLabel.Text = "Found $($results.Count) DNS records" + $exportButton.Enabled = $true + } else { + $statusLabel.Text = "No DNS records found in the specified range" + } +}) + +# Export button click event +$exportButton.Add_Click({ + $saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog + $saveFileDialog.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*" + $saveFileDialog.Title = "Export DNS Records" + $saveFileDialog.FileName = "DNSRecords_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" + + if ($saveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { + $dataTable = $resultsDataGridView.DataSource + $dataTable | Export-Csv -Path $saveFileDialog.FileName -NoTypeInformation + $statusLabel.Text = "Exported to $($saveFileDialog.FileName)" + } +}) + +# Show the form +[void]$form.ShowDialog() \ No newline at end of file