mirror of
https://github.com/Heretic312/devsecops-wrappers.git
synced 2025-12-17 17:56:35 +00:00
Add files via upload
pingsweep.sh scans networks.txt with nmap, tries TCP pings if ICMP fails, and produces inventory.csv with IP plus method. scan_multi_concurrent.sh Multi-Subnet Scanner that produces a CSV with ip, hostname, mac, vendor.
This commit is contained in:
parent
6810cff3fb
commit
b54a338ecf
31
linux/pingsweep.sh
Normal file
31
linux/pingsweep.sh
Normal file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ./pingsweep.sh
|
||||
#
|
||||
# Author: Victor Bishop (Heretic312)
|
||||
# Date: 10/31/2025
|
||||
#
|
||||
# About:
|
||||
# This scans networks.txt with Nmap, tries TCP pings if ICMP fails, and produces inventory.csv with IP plus method.
|
||||
#
|
||||
# Usage:
|
||||
# Make a file networks.txt listing each routed subnet you want to scan:
|
||||
# 10.0.10.0/24
|
||||
# 10.0.20.0/24
|
||||
# 192.168.50.0/24
|
||||
#
|
||||
# Notes:
|
||||
# Replace default .txt and .csv names as needed
|
||||
nets="networks.txt"
|
||||
out="inventory.csv"
|
||||
echo "ip,method" > $out
|
||||
|
||||
# ICMP sweep
|
||||
nmap -sn -iL $nets -oG - | awk '/Up$/{print $2",icmp"}' >> $out
|
||||
|
||||
# TCP fallback for networks with no hits (optional)
|
||||
nmap -sn -PS22,80,443 -iL $nets -oG tcpfallback.gnmap
|
||||
awk '/Up$/{print $2",tcp"}' tcpfallback.gnmap >> $out
|
||||
|
||||
# dedupe
|
||||
sort -u $out -o $out
|
||||
210
linux/scan_multi_concurrent.sh
Normal file
210
linux/scan_multi_concurrent.sh
Normal file
@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# scan_multi_concurrent.sh
|
||||
#
|
||||
# Author: Victor Bishop (Heretic312)
|
||||
# Date: 10/29/2025
|
||||
# About:
|
||||
# Multi-Subnet Scanner that produces a CSV with ip, hostname, mac, vendor.
|
||||
#
|
||||
# Key Features:
|
||||
# Accepts subnets with an argument or environment variable, else fallback to default subnet.
|
||||
# Passing one or more subnets on the command line (./scan_multi_concurrent.sh 192.168.1.0/24 10.0.0.0/16)
|
||||
# Comma-separated SUBNETS environment variable (SUBNETS="10.0.0.0/8,192.168.1.0/24" ./scan_multi_concurrent.sh)
|
||||
# File listed in SUBNET_FILE where each line is a subnet/CIDR
|
||||
# Validates each subnet with Python's "ipaddress"
|
||||
# Saves per-subnet XML results for accurate parsing of MAC/vendor/hostnames.
|
||||
# Consolidates all results into internal_ips_YYYY-MM-DD_HH-MM-SS.csv.
|
||||
# Includes a short note about the MAC/vendor limitation.
|
||||
#
|
||||
# Usage examples:
|
||||
# ./scan_multi_concurrent.sh 192.168.1.0/24 10.0.0.0/24
|
||||
# SUBNETS="192.168.1.0/24,10.0.0.0/24" ./scan_multi_concurrent.sh
|
||||
# SUBNET_FILE=subnets.txt CONCURRENCY=6 ./scan_multi_concurrent.sh
|
||||
#
|
||||
# Output:
|
||||
# internal_ips_<timestamp>.csv (columns: ip,hostname,mac,vendor)
|
||||
# per-subnet XML files used for parsing
|
||||
#
|
||||
# Notes:
|
||||
# - Requires: nmap, python3, xargs (for parallel). If you prefer GNU parallel, you can modify.
|
||||
# - MAC & vendor info is only available for hosts on the same L2 (local VLAN). Remote routed hosts won't show MACs.
|
||||
# - Run as root to get MAC/vendor on local networks: sudo ./scan_multi_concurrent.sh 192.168.1.0/24 192.168.2.0/24
|
||||
# - Increase concurrency by settings CONCURRENCY: CONCURRENCY=8 ./scan_multi_concurrent.sh ...
|
||||
|
||||
|
||||
# Default values
|
||||
DEFAULT_SUBNET="10.2.1.110/14"
|
||||
CONCURRENCY="${CONCURRENCY:-4}" # default number of parallel nmap jobs
|
||||
WORKDIR="${WORKDIR:-./scan_results}"
|
||||
|
||||
# gather subnets into an array
|
||||
subnets=()
|
||||
if [ "$#" -gt 0 ]; then
|
||||
for a in "$@"; do subnets+=("$a"); done
|
||||
elif [ -n "${SUBNETS:-}" ]; then
|
||||
IFS=',' read -r -a tmp <<< "${SUBNETS}"
|
||||
for s in "${tmp[@]}"; do subnets+=("$(echo "$s" | xargs)"); done
|
||||
elif [ -n "${SUBNET_FILE:-}" ]; then
|
||||
while IFS= read -r line; do
|
||||
line="$(echo "$line" | xargs)" # trim whitespace
|
||||
[ -z "$line" ] && continue
|
||||
subnets+=("$line")
|
||||
done < "$SUBNET_FILE"
|
||||
else
|
||||
subnets+=("$DEFAULT_SUBNET")
|
||||
fi
|
||||
|
||||
# checks
|
||||
for cmd in python3 nmap xargs; do
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
echo "ERROR: required command '$cmd' not found in PATH." >&2
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
timestamp="$(date +%F_%H-%M-%S)"
|
||||
mkdir -p "$WORKDIR"
|
||||
|
||||
# canonicalize subnets (use python ipaddress)
|
||||
canonicalize() {
|
||||
local raw="$1"
|
||||
python3 - <<PY
|
||||
import sys, ipaddress
|
||||
try:
|
||||
net = ipaddress.ip_network(sys.argv[1], strict=False)
|
||||
print(str(net))
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
PY "$raw"
|
||||
}
|
||||
|
||||
# build a list of canonical subnets to scan
|
||||
canonical_subnets=()
|
||||
for s in "${subnets[@]}"; do
|
||||
if can=$(canonicalize "$s") ; then
|
||||
canonical_subnets+=("$can")
|
||||
else
|
||||
echo "WARNING: invalid subnet/CIDR '$s' - skipping." >&2
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#canonical_subnets[@]} -eq 0 ]; then
|
||||
echo "No valid subnets to scan. Exiting." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting concurrent scans (concurrency=$CONCURRENCY). Workdir: $WORKDIR"
|
||||
echo "Subnets:"
|
||||
for s in "${canonical_subnets[@]}"; do printf " - %s\n" "$s"; done
|
||||
|
||||
# Create a commands file for xargs; each line runs one nmap scan producing XML
|
||||
cmdfile="$(mktemp)"
|
||||
trap 'rm -f "$cmdfile"' EXIT
|
||||
|
||||
for can in "${canonical_subnets[@]}"; do
|
||||
safe="${can//\//-}"
|
||||
xmlout="${WORKDIR}/nmap_${safe}_${timestamp}.xml"
|
||||
# use -sn for ping/host discovery and -oX for XML; use --privileged behavior (run as root to get MAC info on L2)
|
||||
# Note: running as root yields better ARP discovery and MAC vendor info on local networks.
|
||||
printf "nmap -sn %s -oX %s\n" "$can" "$xmlout" >> "$cmdfile"
|
||||
done
|
||||
|
||||
# run the commands in parallel using xargs -P
|
||||
# xargs will take each line and run it via sh -c
|
||||
echo "Launching scans..."
|
||||
cat "$cmdfile" | xargs -I CMD -P "$CONCURRENCY" sh -c 'echo "CMD: $0"; $0'
|
||||
|
||||
echo "All nmap scans finished. Parsing XML files to CSV..."
|
||||
|
||||
# Python parser: read all xml files in WORKDIR with the timestamp and produce CSV
|
||||
csv_out="internal_ips_${timestamp}.csv"
|
||||
|
||||
python3 - <<PYTHON
|
||||
import xml.etree.ElementTree as ET
|
||||
import glob, csv, os, sys, re
|
||||
|
||||
workdir = os.path.abspath("${WORKDIR}")
|
||||
timestamp = "${timestamp}"
|
||||
pattern = os.path.join(workdir, f"nmap_*_{timestamp}.xml")
|
||||
files = sorted(glob.glob(pattern))
|
||||
out = "${csv_out}"
|
||||
|
||||
# helper to normalize strings
|
||||
def clean(s):
|
||||
if s is None:
|
||||
return ""
|
||||
return re.sub(r'\\s+', ' ', s.strip())
|
||||
|
||||
rows = []
|
||||
for f in files:
|
||||
try:
|
||||
tree = ET.parse(f)
|
||||
except Exception as e:
|
||||
# skip bad xml files
|
||||
continue
|
||||
root = tree.getroot()
|
||||
# iterate hosts
|
||||
for host in root.findall('host'):
|
||||
ip = ""
|
||||
hostname = ""
|
||||
mac = ""
|
||||
vendor = ""
|
||||
# addresses
|
||||
for addr in host.findall('address'):
|
||||
addrtype = addr.get('addrtype')
|
||||
addrval = addr.get('addr')
|
||||
if addrtype == 'ipv4' or addrtype == 'ip':
|
||||
ip = addrval
|
||||
elif addrtype == 'mac':
|
||||
mac = addrval
|
||||
vendor = addr.get('vendor') or vendor
|
||||
# hostnames (take first if present)
|
||||
hs = host.find('hostnames')
|
||||
if hs is not None:
|
||||
h = hs.find('hostname')
|
||||
if h is not None:
|
||||
hostname = h.get('name') or hostname
|
||||
# sanity: if no ip, try to find in status/ports lines (rare)
|
||||
if not ip:
|
||||
# fallback: search for address/@addr with ipv4
|
||||
for addr in host.findall('address'):
|
||||
if addr.get('addrtype') in ('ipv4','ip'):
|
||||
ip = addr.get('addr')
|
||||
rows.append({
|
||||
'ip': clean(ip),
|
||||
'hostname': clean(hostname),
|
||||
'mac': clean(mac),
|
||||
'vendor': clean(vendor),
|
||||
})
|
||||
|
||||
# dedupe rows by ip (keep first)
|
||||
seen = set()
|
||||
deduped = []
|
||||
for r in rows:
|
||||
key = r['ip']
|
||||
if not key:
|
||||
continue
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
deduped.append(r)
|
||||
|
||||
# write csv
|
||||
with open(out, 'w', newline='') as csvfile:
|
||||
w = csv.DictWriter(csvfile, fieldnames=['ip','hostname','mac','vendor'])
|
||||
w.writeheader()
|
||||
for r in sorted(deduped, key=lambda x: tuple(int(p) if p.isdigit() else 0 for p in x['ip'].split('.'))):
|
||||
w.writerow(r)
|
||||
|
||||
print(f"Wrote CSV: {out}")
|
||||
print(f"Parsed {len(deduped)} unique IP(s) from {len(files)} XML file(s).")
|
||||
PYTHON
|
||||
|
||||
echo ""
|
||||
echo "Completed. CSV: $csv_out"
|
||||
echo ""
|
||||
echo "IMPORTANT NOTES:"
|
||||
echo " - MAC/vendor columns are only available when scanning on the same L2 (local VLAN)."
|
||||
echo " - Run this script as root (sudo) if you want ARP-based discovery and MAC/vendor info on local networks."
|
||||
Loading…
x
Reference in New Issue
Block a user