addition: subscan

This commit is contained in:
Theodore Kaczynski
2026-05-15 03:43:46 +03:00
commit d3a70cadc1
2 changed files with 191 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
# VPN TOOLS
## SubScan
A Bash script that scans an IPv4 subnet for hosts with TCP port 443 open, extracts TLS certificate domains (SANs), and validates whether any SAN resolves (forward DNS) to the scanned IP. Outputs a Markdown report.
### Usage
Required: bash, nmap, dig, openssl.
Basic invocation:
```
./script.sh 82.22.146.0/24
```
Output: a timestamped Markdown file named like `subscan_82.22.146.0-24_YYYYMMDD_HHMMSS.md`.
### What it does (high level)
- Verifies required tools (prompts to install on Debian/Ubuntu via apt-get if missing).
- Runs nmap to find hosts with port 443 open.
- Connects to each host with openssl s_client, extracts certificate subjectAltName DNS entries.
- For each extracted domain, performs forward DNS (dig) and checks if any A record matches the host IP.
- Produces a Markdown report grouping hosts into "Valid" (a SAN resolves back to the IP) and "Invalid" (no SANs or no matching forward DNS).
- Cleans up temporary files.
### Key behavior and defaults
- nmap options: -Pn -p443 --open -T4 --min-rate=1000 (fast scan, treats hosts as up).
- openssl s_client: 4s timeout per connection (using timeout command).
- dig: +short +timeout=3 +tries=2.
- Report file: `subscan_<subnet_with_slash_replaced_by_dash>_YYYYMMDD_HHMMSS.md`.
- Exit codes:
- 0 on success (report written),
- 1 if usage error, missing tools and user declined install, or no hosts with 443 open.
### Important notes & limitations
- Requires network access and privileges to run nmap and install packages if chosen.
- The script assumes IPv4 addresses and that visible A records map directly to the scanned IP.
- TLS extraction relies on the certificate presented when connecting without using a specific SNI (the script sets SNI to `dummy`); some servers may require a correct SNI to present relevant certificates.
- False negatives possible if:
- Certificate SANs are absent or located only in the certificate presented for a different SNI.
- DNS uses CNAMEs, load balancers, or geo/anycast addressing where the certificate domain resolves to different IPs.
- Hosts use IPv6-only addresses.
- Use responsibly and only on networks you are authorized to scan.
### Example output (trimmed)
The generated Markdown report includes metadata and two sections:
### Valid (TLS domain resolves back to IP)
- 203.0.113.5 → example.com
### Invalid (No match or no TLS domains)
- 198.51.100.12 → No TLS domains found
- 198.51.100.20 → site1.example.net site2.example.org
### Installation (optional)
On Debian/Ubuntu, if you allow the script to auto-install it will run:
```
sudo apt-get update
sudo apt-get install -y nmap dnsutils openssl
```
### License
No license specified — treat as permissive example code. Modify and use as needed.
Executable
+130
View File
@@ -0,0 +1,130 @@
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m'
SUBNET="$1"
if [ -z "$SUBNET" ]; then
echo -e "${RED}Usage: $0 <subnet> (example: 82.22.146.0/24)${NC}"
exit 1
fi
echo -e "${GREEN}[+] Starting scan on subnet: ${CYAN}$SUBNET${NC}"
echo
check_dependencies() {
local missing=()
command -v nmap >/dev/null 2>&1 || missing+=("nmap")
command -v dig >/dev/null 2>&1 || missing+=("dig")
command -v openssl >/dev/null 2>&1 || missing+=("openssl")
if [ ${#missing[@]} -ne 0 ]; then
echo -e "${RED}[-] Missing tools: ${missing[*]}${NC}"
read -p "Install them automatically? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
sudo apt-get update
sudo apt-get install -y nmap dnsutils openssl
else
echo -e "${RED}Please install missing tools and try again.${NC}"
exit 1
fi
fi
}
check_dependencies
SAFE_SUBNET=$(echo "$SUBNET" | tr '/' '-')
OUTPUT_FILE="subscan_${SAFE_SUBNET}_$(date +%Y%m%d_%H%M%S).md"
echo -e "${GREEN}[+] Scanning for open port 443...${NC}"
nmap -Pn -p443 --open -T4 --min-rate=1000 -oG - "$SUBNET" 2>/dev/null | \
grep "443/open" | awk '{print $2}' > /tmp/open_443.txt
mapfile -t IPS < /tmp/open_443.txt
TOTAL=${#IPS[@]}
if [ "$TOTAL" -eq 0 ]; then
echo -e "${RED}[-] No hosts with port 443 open found.${NC}"
rm -f /tmp/open_443.txt
exit 1
fi
echo -e "${GREEN}[+] Found ${CYAN}$TOTAL${GREEN} hosts with port 443 open.${NC}"
echo -e "${GREEN}[+] Extracting TLS domains + validating with forward DNS...${NC}"
VALID=()
INVALID=()
CURRENT=0
for ip in "${IPS[@]}"; do
CURRENT=$((CURRENT + 1))
printf "\r${GREEN}[+] Progress: ${CYAN}%d/%d${NC}" "$CURRENT" "$TOTAL"
tls_domains=$(echo | timeout 4 openssl s_client -connect "$ip":443 -servername dummy 2>/dev/null | \
openssl x509 -noout -subject -ext subjectAltName 2>/dev/null | \
grep -oE 'DNS:[^, ]+' | sed 's/DNS://' | tr '\n' ' ' | sed 's/ $//')
if [ -z "$tls_domains" ]; then
INVALID+=("$ip → No TLS domains found")
continue
fi
is_valid=0
matched_domain=""
for domain in $tls_domains; do
forward_ips=$(dig "$domain" +short +timeout=3 +tries=2 2>/dev/null | \
grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$')
if echo "$forward_ips" | grep -q "^${ip}$"; then
is_valid=1
matched_domain="$domain"
break
fi
done
if [ $is_valid -eq 1 ]; then
VALID+=("$ip$matched_domain")
else
INVALID+=("$ip$tls_domains")
fi
done
printf "\r${GREEN}[+] Progress: ${CYAN}%d/%d${GREEN} - Done!${NC}%*s\n" "$TOTAL" "$TOTAL" 20 ""
{
echo "---"
echo "TLS + DNS Validation Report"
echo "Subnet : $SUBNET"
echo "Total Hosts: $TOTAL"
echo "Valid : ${#VALID[@]}"
echo "Invalid : ${#INVALID[@]}"
echo "Date : $(date)"
echo "---"
echo ""
echo "## Valid (TLS domain resolves back to IP)"
for line in "${VALID[@]}"; do
echo "- $line"
done
echo ""
echo "## Invalid (No match or no TLS domains)"
for line in "${INVALID[@]}"; do
echo "- $line"
done
} > "$OUTPUT_FILE"
echo
echo -e "${GREEN}[+] Scan completed!${NC}"
echo -e "${GREEN}[+] Results saved to: ${CYAN}$OUTPUT_FILE${NC}"
echo
echo -e "${YELLOW}Tip: Valid entries are best for SNI imitation.${NC}"
rm -f /tmp/open_443.txt