目录导航
侦察工具在过去十年中的兴起令人瞩目。
可以理解的是;网络安全继续在各个方面受到极大关注,从网络间谍的秘密账户到现在无处不在的企业违规场景,对全球组织施加压力。更好的安全性也是有代价的,在缺乏重要的安全措施的情况下,反模式会迅速发展,为不法分子提供充足的机会和目标。
虽然不分青红皂白的互联网扫描的存在在很大程度上被接受,但以有意义和富有成效的方式自动化信息收集过程需要认真努力,以达到最佳工具和技术的适当组合。最近,由 Nmap 等工具及其支持的Nmap 脚本 (NSE)平台驱动的细粒度智能暗示开源工具在处理足迹方面取得了成功——基础设施数据点的主动收集,以及其他有趣的方面,不仅仅是简单的枚举——识别暴露资产和应用程序的一个增长趋势。
在这篇博文中,我们将研究 nmapAutomator项目,因为它通过 Nmap 最突出的功能(包括端口扫描和类似方法)提供的传统触发器来自动化和扩展目标基础设施的分类和漏洞评估阶段。如果没有实际示例和潜在用例,包括一些提供无缝设置体验的说明,介绍这样的工具将是不完整的。
让我们看一看。
什么是 nmapAutomator?
Nmap 自动机,也称为nmapAutomator,本质上是一个兼容 POSIX 的 shell 脚本,它通过以独特的方式利用Nmap 命令来自动执行目标发现、枚举和侦察过程。通常,掌握像 Nmap 这样的工具不仅需要能够记住和应用无数命令行参数或标志,还需要能够将大量输出转化为可消费产品;因此,以这种详细程度进行扫描活动很容易需要几天(如果不是几周)才能完成。
根据特定的主机和网络条件,nmapAutomator 可以在 30 分钟内部署全方位的Nmap 漏洞扫描和 CVE 序列识别。这似乎很长一段时间,但请记住,扫描类型旨在生成尽可能多的关于目标的可操作情报。此外,nmapAutomator 包括运行工具的实例,例如 SSLscan、Nikto和 FFuF,在漏洞赏金和渗透测试生态系统中都是众所周知的。
nmapAutomator 支持以下扫描功能:
- 网络:显示主机网络中的所有活动主机(约 15 秒)
- 端口:显示所有打开的端口(~15 秒)
- 脚本:在找到的端口上运行脚本扫描(约 5 分钟)
- 完整:运行全范围端口扫描,然后对新端口运行彻底扫描(约 5-10 分钟)
- UDP:运行 UDP 扫描“需要 sudo”(约 5 分钟)
- 漏洞:在所有找到的端口上运行CVE扫描和 Nmap 漏洞扫描(约 5-15 分钟)
- 侦察:建议侦察命令,然后提示自动运行它们
- 全部:运行所有扫描(约 20-30 分钟)
例如,-Network选项允许提供单个 IP 地址并发现同一子网中的活动主机:
借助-r/–remote标志,可以通过 nmapAutomator 在远程主机上实现 Nmap 自动化。这个功能(仍在开发中)被称为远程模式,旨在在不依赖任何外部工具的情况下利用 POSIX shell 命令。
安装nmapAutomator
git clone https://github.com/21y4d/nmapAutomator.git
sudo ln -s $(pwd)/nmapAutomator/nmapAutomator.sh /usr/local/bin/
/usr/local/bin/nmapAutomator.sh

nmapAutomator.sh文件代码
复制即用–效率才是生产力
#!/bin/sh
#by @21y4d
# Define ANSI color variables
RED='\033[0;31m'
YELLOW='\033[0;33m'
GREEN='\033[0;32m'
NC='\033[0m'
origIFS="${IFS}"
# Start timer
elapsedStart="$(date '+%H:%M:%S' | awk -F: '{print $1 * 3600 + $2 * 60 + $3}')"
REMOTE=false
# Parse flags
while [ $# -gt 0 ]; do
key="$1"
case "${key}" in
-H | --host)
HOST="$2"
shift
shift
;;
-t | --type)
TYPE="$2"
shift
shift
;;
-d | --dns)
DNS="$2"
shift
shift
;;
-o | --output)
OUTPUTDIR="$2"
shift
shift
;;
-s | --static-nmap)
NMAPPATH="$2"
shift
shift
;;
-r | --remote)
REMOTE=true
shift
;;
*)
POSITIONAL="${POSITIONAL} $1"
shift
;;
esac
done
set -- ${POSITIONAL}
# Legacy flags support, if run without -H/-t
if [ -z "${HOST}" ]; then
HOST="$1"
fi
if [ -z "${TYPE}" ]; then
TYPE="$2"
fi
# Legacy types support, if quick/basic used
if expr "${TYPE}" : '^\([Qq]uick\)$' >/dev/null; then
TYPE="Port"
elif expr "${TYPE}" : '^\([Bb]asic\)$' >/dev/null; then
TYPE="Script"
fi
# Set DNS or default to system DNS
if [ -n "${DNS}" ]; then
DNSSERVER="${DNS}"
DNSSTRING="--dns-server=${DNSSERVER}"
else
DNSSERVER="$(grep 'nameserver' /etc/resolv.conf | grep -v '#' | head -n 1 | awk {'print $NF'})"
DNSSTRING="--system-dns"
fi
# Set output dir or default to host-based dir
if [ -z "${OUTPUTDIR}" ]; then
OUTPUTDIR="${HOST}"
fi
# Set path to nmap binary or default to nmap in $PATH, or resort to --remote mode
if [ -z "${NMAPPATH}" ] && type nmap >/dev/null 2>&1; then
NMAPPATH="$(type nmap | awk {'print $NF'})"
elif [ -n "${NMAPPATH}" ]; then
NMAPPATH="$(cd "$(dirname ${NMAPPATH})" && pwd -P)/$(basename ${NMAPPATH})"
# Ensure static binary is executable and is nmap
if [ ! -x $NMAPPATH ]; then
printf "${RED}\nFile is not executable! Attempting chmod +x...${NC}\n"
chmod +x $NMAPPATH 2>/dev/null || (printf "${RED}Could not chmod. Running in Remote mode...${NC}\n\n" && REMOTE=true)
elif [ $($NMAPPATH -h | head -c4) != "Nmap" ]; then
printf "${RED}\nStatic binary does not appear to be Nmap! Running in Remote mode...${NC}\n\n" && REMOTE=true
fi
printf "${GREEN}\nUsing static nmap binary at ${NMAPPATH}${NC}\n"
else
printf "${RED}\nNmap is not installed and -s is not used. Running in Remote mode...${NC}\n\n" && REMOTE=true
fi
# Print usage menu and exit. Used when issues are encountered
# No args needed
usage() {
echo
printf "${RED}Usage: $(basename $0) -H/--host ${NC}<TARGET-IP>${RED} -t/--type ${NC}<TYPE>${RED}\n"
printf "${YELLOW}Optional: [-r/--remote ${NC}<REMOTE MODE>${YELLOW}] [-d/--dns ${NC}<DNS SERVER>${YELLOW}] [-o/--output ${NC}<OUTPUT DIRECTORY>${YELLOW}] [-s/--static-nmap ${NC}<STATIC NMAP PATH>${YELLOW}]\n\n"
printf "Scan Types:\n"
printf "${YELLOW}\tNetwork : ${NC}Shows all live hosts in the host's network ${YELLOW}(~15 seconds)\n"
printf "${YELLOW}\tPort : ${NC}Shows all open ports ${YELLOW}(~15 seconds)\n"
printf "${YELLOW}\tScript : ${NC}Runs a script scan on found ports ${YELLOW}(~5 minutes)\n"
printf "${YELLOW}\tFull : ${NC}Runs a full range port scan, then runs a script scan on new ports ${YELLOW}(~5-10 minutes)\n"
printf "${YELLOW}\tUDP : ${NC}Runs a UDP scan \"requires sudo\" ${YELLOW}(~5 minutes)\n"
printf "${YELLOW}\tVulns : ${NC}Runs CVE scan and nmap Vulns scan on all found ports ${YELLOW}(~5-15 minutes)\n"
printf "${YELLOW}\tRecon : ${NC}Suggests recon commands, then prompts to automatically run them\n"
printf "${YELLOW}\tAll : ${NC}Runs all the scans ${YELLOW}(~20-30 minutes)\n"
printf "${NC}\n"
exit 1
}
# Print initial header and set initial variables before scans start
# No args needed
header() {
echo
# Print scan type
if expr "${TYPE}" : '^\([Aa]ll\)$' >/dev/null; then
printf "${YELLOW}Running all scans on ${NC}${HOST}"
else
printf "${YELLOW}Running a ${TYPE} scan on ${NC}${HOST}"
fi
if expr "${HOST}" : '^\(\([[:alnum:]-]\{1,63\}\.\)*[[:alpha:]]\{2,6\}\)$' >/dev/null; then
urlIP="$(host -4 -W 1 ${HOST} ${DNSSERVER} 2>/dev/null | grep ${HOST} | head -n 1 | awk {'print $NF'})"
if [ -n "${urlIP}" ]; then
printf "${YELLOW} with IP ${NC}${urlIP}\n\n"
else
printf ".. ${RED}Could not resolve IP of ${NC}${HOST}\n\n"
fi
else
printf "\n"
fi
if $REMOTE; then
printf "${YELLOW}Running in Remote mode! Some scans will be limited.\n"
fi
# Set $subnet variable
if expr "${HOST}" : '^\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)$' >/dev/null; then
subnet="$(echo "${HOST}" | cut -d "." -f 1,2,3).0"
fi
# Set $nmapType variable based on ping
kernel="$(uname -s)"
checkPing="$(checkPing "${urlIP:-$HOST}")"
nmapType="$(echo "${checkPing}" | head -n 1)"
# Set if host is pingable 'for ping scans'
if expr "${nmapType}" : ".*-Pn$" >/dev/null; then
pingable=false
printf "${NC}\n"
printf "${YELLOW}No ping detected.. Will not use ping scans!\n"
printf "${NC}\n"
else
pingable=true
fi
# OS Detection
ttl="$(echo "${checkPing}" | tail -n 1)"
if [ "${ttl}" != "nmap -Pn" ]; then
osType="$(checkOS "${ttl}")"
printf "${NC}\n"
printf "${GREEN}Host is likely running ${osType}\n"
fi
echo
echo
}
# Used Before and After each nmap scan, to keep found ports consistent across the script
# $1 is $HOST
assignPorts() {
# Set $commonPorts based on Port scan
if [ -f "nmap/Port_$1.nmap" ]; then
commonPorts="$(awk -vORS=, -F/ '/^[0-9]/{print $1}' "nmap/Port_$1.nmap" | sed 's/.$//')"
fi
# Set $allPorts based on Full scan or both Port and Full scans
if [ -f "nmap/Full_$1.nmap" ]; then
if [ -f "nmap/Port_$1.nmap" ]; then
allPorts="$(awk -vORS=, -F/ '/^[0-9]/{print $1}' "nmap/Port_$1.nmap" "nmap/Full_$1.nmap" | sed 's/.$//')"
else
allPorts="$(awk -vORS=, -F/ '/^[0-9]/{print $1}' "nmap/Full_$1.nmap" | sed 's/.$//')"
fi
fi
# Set $udpPorts based on UDP scan
if [ -f "nmap/UDP_$1.nmap" ]; then
udpPorts="$(awk -vORS=, -F/ '/^[0-9]/{print $1}' "nmap/UDP_$1.nmap" | sed 's/.$//')"
if [ "${udpPorts}" = "Al" ]; then
udpPorts=""
fi
fi
}
# Test whether the host is pingable, and return $nmapType and $ttl
# $1 is $HOST
checkPing() {
# If ping is not returned within a second, then ping scan is disabled with -Pn
if [ $kernel = "Linux" ]; then TW="W"; else TW="t"; fi
pingTest="$(ping -c 1 -${TW} 1 "$1" 2>/dev/null | grep ttl)"
if [ -z "${pingTest}" ]; then
echo "${NMAPPATH} -Pn"
else
echo "${NMAPPATH}"
if expr "$1" : '^\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)$' >/dev/null; then
ttl="$(echo "${pingTest}" | cut -d " " -f 6 | cut -d "=" -f 2)"
else
ttl="$(echo "${pingTest}" | cut -d " " -f 7 | cut -d "=" -f 2)"
fi
echo "${ttl}"
fi
}
# Detect OS based on $ttl
# $1 is $ttl
checkOS() {
case "$1" in
25[456]) echo "OpenBSD/Cisco/Oracle" ;;
12[78]) echo "Windows" ;;
6[34]) echo "Linux" ;;
*) echo "Unknown OS!" ;;
esac
}
# Add any extra ports found in Full scan
# No args needed
cmpPorts() {
extraPorts="$(echo ",${allPorts}," | sed 's/,\('"$(echo "${commonPorts}" | sed 's/,/,\\|/g')"',\)\+/,/g; s/^,\|,$//g')"
}
# Print nmap progress bar
# $1 is $scanType, $2 is $percent, $3 is $elapsed, $4 is $remaining
progressBar() {
[ -z "${2##*[!0-9]*}" ] && return 1
[ "$(stty size | cut -d ' ' -f 2)" -le 120 ] && width=50 || width=100
fill="$(printf "%-$((width == 100 ? $2 : ($2 / 2)))s" "#" | tr ' ' '#')"
empty="$(printf "%-$((width - (width == 100 ? $2 : ($2 / 2))))s" " ")"
printf "In progress: $1 Scan ($3 elapsed - $4 remaining) \n"
printf "[${fill}>${empty}] $2%% done \n"
printf "\e[2A"
}
# Calculate current progress bar status based on nmap stats (with --stats-every)
# $1 is nmap command to be run, $2 is progress bar $refreshRate
nmapProgressBar() {
refreshRate="${2:-1}"
outputFile="$(echo $1 | sed -e 's/.*-oN \(.*\).nmap.*/\1/').nmap"
tmpOutputFile="${outputFile}.tmp"
# Run the nmap command
if [ ! -e "${outputFile}" ]; then
$1 --stats-every "${refreshRate}s" >"${tmpOutputFile}" 2>&1 &
fi
# Keep checking nmap stats and calling progressBar() every $refreshRate
while { [ ! -e "${outputFile}" ] || ! grep -q "Nmap done at" "${outputFile}"; } && { [ ! -e "${tmpOutputFile}" ] || ! grep -i -q "quitting" "${tmpOutputFile}"; }; do
scanType="$(tail -n 2 "${tmpOutputFile}" 2>/dev/null | sed -ne '/elapsed/{s/.*undergoing \(.*\) Scan.*/\1/p}')"
percent="$(tail -n 2 "${tmpOutputFile}" 2>/dev/null | sed -ne '/% done/{s/.*About \(.*\)\..*% done.*/\1/p}')"
elapsed="$(tail -n 2 "${tmpOutputFile}" 2>/dev/null | sed -ne '/elapsed/{s/Stats: \(.*\) elapsed.*/\1/p}')"
remaining="$(tail -n 2 "${tmpOutputFile}" 2>/dev/null | sed -ne '/remaining/{s/.* (\(.*\) remaining.*/\1/p}')"
progressBar "${scanType:-No}" "${percent:-0}" "${elapsed:-0:00:00}" "${remaining:-0:00:00}"
sleep "${refreshRate}"
done
printf "\033[0K\r\n\033[0K\r\n"
# Print final output, remove extra nmap noise
if [ -e "${outputFile}" ]; then
sed -n '/PORT.*STATE.*SERVICE/,/^# Nmap/H;${x;s/^\n\|\n[^\n]*\n# Nmap.*//gp}' "${outputFile}" | awk '!/^SF(:|-).*$/' | grep -v 'service unrecognized despite'
else
cat "${tmpOutputFile}"
fi
rm -f "${tmpOutputFile}"
}
# Nmap scan for live hosts
networkScan() {
printf "${GREEN}---------------------Starting Network Scan---------------------\n"
printf "${NC}\n"
origHOST="${HOST}"
HOST="${urlIP:-$HOST}"
if [ $kernel = "Linux" ]; then TW="W"; else TW="t"; fi
if ! $REMOTE; then
# Discover live hosts with nmap
nmapProgressBar "${nmapType} -T4 --max-retries 1 --max-scan-delay 20 -n -sn -oN nmap/Network_${HOST}.nmap ${subnet}/24"
printf "${YELLOW}Found the following live hosts:${NC}\n\n"
cat nmap/Network_${HOST}.nmap | grep -v '#' | grep "$(echo $subnet | sed 's/..$//')" | awk {'print $5'}
elif $pingable; then
# Discover live hosts with ping
echo >"nmap/Network_${HOST}.nmap"
for ip in $(seq 0 254); do
(ping -c 1 -${TW} 1 "$(echo $subnet | sed 's/..$//').$ip" 2>/dev/null | grep 'stat' -A1 | xargs | grep -v ', 0.*received' | awk {'print $2'} >>"nmap/Network_${HOST}.nmap") &
done
wait
sed -i '/^$/d' "nmap/Network_${HOST}.nmap"
sort -t . -k 3,3n -k 4,4n "nmap/Network_${HOST}.nmap"
else
printf "${YELLOW}No ping detected.. TCP Network Scan is not implemented yet in Remote mode.\n${NC}"
fi
HOST="${origHOST}"
echo
echo
echo
}
# Port Nmap port scan
portScan() {
printf "${GREEN}---------------------Starting Port Scan-----------------------\n"
printf "${NC}\n"
if ! $REMOTE; then
nmapProgressBar "${nmapType} -T4 --max-retries 1 --max-scan-delay 20 --open -oN nmap/Port_${HOST}.nmap ${HOST} ${DNSSTRING}"
assignPorts "${HOST}"
else
printf "${YELLOW}Port Scan is not implemented yet in Remote mode.\n${NC}"
fi
echo
echo
echo
}
# Nmap version and default script scan on found ports
scriptScan() {
printf "${GREEN}---------------------Starting Script Scan-----------------------\n"
printf "${NC}\n"
if ! $REMOTE; then
if [ -z "${commonPorts}" ]; then
printf "${YELLOW}No ports in port scan.. Skipping!\n"
else
nmapProgressBar "${nmapType} -sCV -p${commonPorts} --open -oN nmap/Script_${HOST}.nmap ${HOST} ${DNSSTRING}" 2
fi
# Modify detected OS if Nmap detects a different OS
if [ -f "nmap/Script_${HOST}.nmap" ] && grep -q "Service Info: OS:" "nmap/Script_${HOST}.nmap"; then
serviceOS="$(sed -n '/Service Info/{s/.* \([^;]*\);.*/\1/p;q}' "nmap/Script_${HOST}.nmap")"
if [ "${osType}" != "${serviceOS}" ]; then
osType="${serviceOS}"
printf "${NC}\n"
printf "${NC}\n"
printf "${GREEN}OS Detection modified to: ${osType}\n"
printf "${NC}\n"
fi
fi
else
printf "${YELLOW}Script Scan is not supported in Remote mode.\n${NC}"
fi
echo
echo
echo
}
# Nmap scan on all ports
fullScan() {
printf "${GREEN}---------------------Starting Full Scan------------------------\n"
printf "${NC}\n"
if ! $REMOTE; then
nmapProgressBar "${nmapType} -p- --max-retries 1 --max-rate 500 --max-scan-delay 20 -T4 -v --open -oN nmap/Full_${HOST}.nmap ${HOST} ${DNSSTRING}" 3
assignPorts "${HOST}"
# Nmap version and default script scan on found ports if Script scan was not run yet
if [ -z "${commonPorts}" ]; then
echo
echo
printf "${YELLOW}Making a script scan on all ports\n"
printf "${NC}\n"
nmapProgressBar "${nmapType} -sCV -p${allPorts} --open -oN nmap/Full_Extra_${HOST}.nmap ${HOST} ${DNSSTRING}" 2
assignPorts "${HOST}"
# Nmap version and default script scan if any extra ports are found
else
cmpPorts
if [ -z "${extraPorts}" ]; then
echo
echo
allPorts=""
printf "${YELLOW}No new ports\n"
printf "${NC}\n"
else
echo
echo
printf "${YELLOW}Making a script scan on extra ports: $(echo "${extraPorts}" | sed 's/,/, /g')\n"
printf "${NC}\n"
nmapProgressBar "${nmapType} -sCV -p${extraPorts} --open -oN nmap/Full_Extra_${HOST}.nmap ${HOST} ${DNSSTRING}" 2
assignPorts "${HOST}"
fi
fi
else
printf "${YELLOW}Full Scan is not implemented yet in Remote mode.\n${NC}"
fi
echo
echo
echo
}
# Nmap UDP scan
UDPScan() {
printf "${GREEN}----------------------Starting UDP Scan------------------------\n"
printf "${NC}\n"
if ! $REMOTE; then
# Ensure UDP scan runs with root priviliges
if [ "${USER}" != 'root' ]; then
echo "UDP needs to be run as root, running with sudo..."
sudo -v
echo
fi
nmapProgressBar "sudo ${nmapType} -sU --max-retries 1 --open --open -oN nmap/UDP_${HOST}.nmap ${HOST} ${DNSSTRING}" 3
assignPorts "${HOST}"
# Nmap version and default script scan on found UDP ports
if [ -n "${udpPorts}" ]; then
echo
echo
printf "${YELLOW}Making a script scan on UDP ports: $(echo "${udpPorts}" | sed 's/,/, /g')\n"
printf "${NC}\n"
if [ -f /usr/share/nmap/scripts/vulners.nse ]; then
sudo -v
nmapProgressBar "sudo ${nmapType} -sCVU --script vulners --script-args mincvss=7.0 -p${udpPorts} --open -oN nmap/UDP_Extra_${HOST}.nmap ${HOST} ${DNSSTRING}" 2
else
sudo -v
nmapProgressBar "sudo ${nmapType} -sCVU -p${udpPorts} --open -oN nmap/UDP_Extra_${HOST}.nmap ${HOST} ${DNSSTRING}" 2
fi
else
echo
echo
printf "${YELLOW}No UDP ports are open\n"
printf "${NC}\n"
fi
else
printf "${YELLOW}UDP Scan is not implemented yet in Remote mode.\n${NC}"
fi
echo
echo
echo
}
# Nmap vulnerability detection script scan
vulnsScan() {
printf "${GREEN}---------------------Starting Vulns Scan-----------------------\n"
printf "${NC}\n"
if ! $REMOTE; then
# Set ports to be scanned (common or all)
if [ -z "${allPorts}" ]; then
portType="common"
ports="${commonPorts}"
else
portType="all"
ports="${allPorts}"
fi
# Ensure the vulners script is available, then run it with nmap
if [ ! -f /usr/share/nmap/scripts/vulners.nse ]; then
printf "${RED}Please install 'vulners.nse' nmap script:\n"
printf "${RED}https://github.com/vulnersCom/nmap-vulners\n"
printf "${RED}\n"
printf "${RED}Skipping CVE scan!\n"
printf "${NC}\n"
else
printf "${YELLOW}Running CVE scan on ${portType} ports\n"
printf "${NC}\n"
nmapProgressBar "${nmapType} -sV --script vulners --script-args mincvss=7.0 -p${ports} --open -oN nmap/CVEs_${HOST}.nmap ${HOST} ${DNSSTRING}" 3
echo
fi
# Nmap vulnerability detection script scan
echo
printf "${YELLOW}Running Vuln scan on ${portType} ports\n"
printf "${YELLOW}This may take a while, depending on the number of detected services..\n"
printf "${NC}\n"
nmapProgressBar "${nmapType} -sV --script vuln -p${ports} --open -oN nmap/Vulns_${HOST}.nmap ${HOST} ${DNSSTRING}" 3
else
printf "${YELLOW}Vulns Scan is not supported in Remote mode.\n${NC}"
fi
echo
echo
echo
}
# Run reconRecommend(), ask user for tools to run, then run runRecon()
recon() {
IFS="
"
# Run reconRecommend()
reconRecommend "${HOST}" | tee "nmap/Recon_${HOST}.nmap"
allRecon="$(grep "${HOST}" "nmap/Recon_${HOST}.nmap" | cut -d " " -f 1 | sort | uniq)"
# Detect any missing tools
for tool in ${allRecon}; do
if ! type "${tool}" >/dev/null 2>&1; then
missingTools="$(echo ${missingTools} ${tool} | awk '{$1=$1};1')"
fi
done
# Exclude missing tools, and print help for installing them
if [ -n "${missingTools}" ]; then
printf "${RED}Missing tools: ${NC}${missingTools}\n"
printf "\n${RED}You can install with:\n"
printf "${YELLOW}sudo apt install ${missingTools} -y\n"
printf "${NC}\n\n"
availableRecon="$(echo "${allRecon}" | tr " " "\n" | awk -vORS=', ' '!/'"$(echo "${missingTools}" | tr " " "|")"'/' | sed 's/..$//')"
else
availableRecon="$(echo "${allRecon}" | tr "\n" " " | sed 's/\ /,\ /g' | sed 's/..$//')"
fi
secs=30
count=0
# Ask user for which recon tools to run, default to All if no answer is detected in 30s
if [ -n "${availableRecon}" ]; then
while [ "${reconCommand}" != "!" ]; do
printf "${YELLOW}\n"
printf "Which commands would you like to run?${NC}\nAll (Default), ${availableRecon}, Skip <!>\n\n"
while [ ${count} -lt ${secs} ]; do
tlimit=$((secs - count))
printf "\033[2K\rRunning Default in (${tlimit})s: "
# Waits 1 second for user's input - POSIX read -t
reconCommand="$(sh -c '{ { sleep 1; kill -sINT $$; } & }; exec head -n 1')"
count=$((count + 1))
[ -n "${reconCommand}" ] && break
done
if expr "${reconCommand}" : '^\([Aa]ll\)$' >/dev/null || [ -z "${reconCommand}" ]; then
runRecon "${HOST}" "All"
reconCommand="!"
elif expr " ${availableRecon}," : ".* ${reconCommand}," >/dev/null; then
runRecon "${HOST}" "${reconCommand}"
reconCommand="!"
elif [ "${reconCommand}" = "Skip" ] || [ "${reconCommand}" = "!" ]; then
reconCommand="!"
echo
echo
echo
else
printf "${NC}\n"
printf "${RED}Incorrect choice!\n"
printf "${NC}\n"
fi
done
else
printf "${YELLOW}No Recon Recommendations found...\n"
printf "${NC}\n\n\n"
fi
IFS="${origIFS}"
}
# Recommend recon tools/commands to be run on found ports
reconRecommend() {
printf "${GREEN}---------------------Recon Recommendations---------------------\n"
printf "${NC}\n"
IFS="
"
# Set $ports and $file variables
if [ -f "nmap/Full_Extra_${HOST}.nmap" ]; then
ports="${allPorts}"
file="$(cat "nmap/Script_${HOST}.nmap" "nmap/Full_Extra_${HOST}.nmap" | grep "open" | grep -v "#" | sort | uniq)"
elif [ -f "nmap/Script_${HOST}.nmap" ]; then
ports="${commonPorts}"
file="$(grep "open" "nmap/Script_${HOST}.nmap" | grep -v "#")"
fi
# SMTP recon
if echo "${file}" | grep -q "25/tcp"; then
printf "${NC}\n"
printf "${YELLOW}SMTP Recon:\n"
printf "${NC}\n"
echo "smtp-user-enum -U /usr/share/wordlists/metasploit/unix_users.txt -t \"${HOST}\" | tee \"recon/smtp_user_enum_${HOST}.txt\""
echo
fi
# DNS Recon
if echo "${file}" | grep -q "53/tcp" && [ -n "${DNSSERVER}" ]; then
printf "${NC}\n"
printf "${YELLOW}DNS Recon:\n"
printf "${NC}\n"
echo "host -l \"${HOST}\" \"${DNSSERVER}\" | tee \"recon/hostname_${HOST}.txt\""
echo "dnsrecon -r \"${subnet}/24\" -n \"${DNSSERVER}\" | tee \"recon/dnsrecon_${HOST}.txt\""
echo "dnsrecon -r 127.0.0.0/24 -n \"${DNSSERVER}\" | tee \"recon/dnsrecon-local_${HOST}.txt\""
echo "dig -x \"${HOST}\" @${DNSSERVER} | tee \"recon/dig_${HOST}.txt\""
echo
fi
# Web recon
if echo "${file}" | grep -i -q http; then
printf "${NC}\n"
printf "${YELLOW}Web Servers Recon:\n"
printf "${NC}\n"
# HTTP recon
for line in ${file}; do
if echo "${line}" | grep -i -q http; then
port="$(echo "${line}" | cut -d "/" -f 1)"
if echo "${line}" | grep -q ssl/http; then
urlType='https://'
echo "sslscan \"${HOST}\" | tee \"recon/sslscan_${HOST}_${port}.txt\""
echo "nikto -host \"${urlType}${HOST}:${port}\" -ssl | tee \"recon/nikto_${HOST}_${port}.txt\""
else
urlType='http://'
echo "nikto -host \"${urlType}${HOST}:${port}\" | tee \"recon/nikto_${HOST}_${port}.txt\""
fi
if type ffuf >/dev/null 2>&1; then
extensions="$(echo 'index' >./index && ffuf -s -w ./index:FUZZ -mc '200,302' -e '.asp,.aspx,.html,.jsp,.php' -u "${urlType}${HOST}:${port}/FUZZ" 2>/dev/null | awk -vORS=, -F 'index' '{print $2}' | sed 's/.$//' && rm ./index)"
echo "ffuf -ic -w /usr/share/wordlists/dirb/common.txt -e '${extensions}' -u \"${urlType}${HOST}:${port}/FUZZ\" | tee \"recon/ffuf_${HOST}_${port}.txt\""
else
extensions="$(echo 'index' >./index && gobuster dir -w ./index -t 30 -qnkx '.asp,.aspx,.html,.jsp,.php' -s '200,302' -u "${urlType}${HOST}:${port}" 2>/dev/null | awk -vORS=, -F 'index' '{print $2}' | sed 's/.$//' && rm ./index)"
echo "gobuster dir -w /usr/share/wordlists/dirb/common.txt -t 30 -ekx '${extensions}' -u \"${urlType}${HOST}:${port}\" -o \"recon/gobuster_${HOST}_${port}.txt\""
fi
echo
fi
done
# CMS recon
if [ -f "nmap/Script_${HOST}.nmap" ]; then
cms="$(grep http-generator "nmap/Script_${HOST}.nmap" | cut -d " " -f 2)"
if [ -n "${cms}" ]; then
for line in ${cms}; do
port="$(sed -n 'H;x;s/\/.*'"${line}"'.*//p' "nmap/Script_${HOST}.nmap")"
# case returns 0 by default (no match), so ! case returns 1
if ! case "${cms}" in Joomla | WordPress | Drupal) false ;; esac then
printf "${NC}\n"
printf "${YELLOW}CMS Recon:\n"
printf "${NC}\n"
fi
case "${cms}" in
Joomla!) echo "joomscan --url \"${HOST}:${port}\" | tee \"recon/joomscan_${HOST}_${port}.txt\"" ;;
WordPress) echo "wpscan --url \"${HOST}:${port}\" --enumerate p | tee \"recon/wpscan_${HOST}_${port}.txt\"" ;;
Drupal) echo "droopescan scan drupal -u \"${HOST}:${port}\" | tee \"recon/droopescan_${HOST}_${port}.txt\"" ;;
esac
done
fi
fi
fi
# SNMP recon
if [ -f "nmap/UDP_Extra_${HOST}.nmap" ] && grep -q "161/udp.*open" "nmap/UDP_Extra_${HOST}.nmap"; then
printf "${NC}\n"
printf "${YELLOW}SNMP Recon:\n"
printf "${NC}\n"
echo "snmp-check \"${HOST}\" -c public | tee \"recon/snmpcheck_${HOST}.txt\""
echo "snmpwalk -Os -c public -v1 \"${HOST}\" | tee \"recon/snmpwalk_${HOST}.txt\""
echo
fi
# LDAP recon
if echo "${file}" | grep -q "389/tcp"; then
printf "${NC}\n"
printf "${YELLOW}ldap Recon:\n"
printf "${NC}\n"
echo "ldapsearch -x -h \"${HOST}\" -s base | tee \"recon/ldapsearch_${HOST}.txt\""
echo "ldapsearch -x -h \"${HOST}\" -b \"\$(grep rootDomainNamingContext \"recon/ldapsearch_${HOST}.txt\" | cut -d ' ' -f2)\" | tee \"recon/ldapsearch_DC_${HOST}.txt\""
echo "nmap -Pn -p 389 --script ldap-search --script-args 'ldap.username=\"\$(grep rootDomainNamingContext \"recon/ldapsearch_${HOST}.txt\" | cut -d \\" \\" -f2)\"' \"${HOST}\" -oN \"recon/nmap_ldap_${HOST}.txt\""
echo
fi
# SMB recon
if echo "${file}" | grep -q "445/tcp"; then
printf "${NC}\n"
printf "${YELLOW}SMB Recon:\n"
printf "${NC}\n"
echo "smbmap -H \"${HOST}\" | tee \"recon/smbmap_${HOST}.txt\""
echo "smbclient -L \"//${HOST}/\" -U \"guest\"% | tee \"recon/smbclient_${HOST}.txt\""
if [ "${osType}" = "Windows" ]; then
echo "nmap -Pn -p445 --script vuln -oN \"recon/SMB_vulns_${HOST}.txt\" \"${HOST}\""
elif [ "${osType}" = "Linux" ]; then
echo "enum4linux -a \"${HOST}\" | tee \"recon/enum4linux_${HOST}.txt\""
fi
echo
elif echo "${file}" | grep -q "139/tcp" && [ "${osType}" = "Linux" ]; then
printf "${NC}\n"
printf "${YELLOW}SMB Recon:\n"
printf "${NC}\n"
echo "enum4linux -a \"${HOST}\" | tee \"recon/enum4linux_${HOST}.txt\""
echo
fi
# Oracle DB recon
if echo "${file}" | grep -q "1521/tcp"; then
printf "${NC}\n"
printf "${YELLOW}Oracle Recon:\n"
printf "${NC}\n"
echo "odat sidguesser -s \"${HOST}\" -p 1521"
echo "odat passwordguesser -s \"${HOST}\" -p 1521 -d XE --accounts-file accounts/accounts-multiple.txt"
echo
fi
IFS="${origIFS}"
echo
echo
echo
}
# Run chosen recon commands
runRecon() {
echo
echo
echo
printf "${GREEN}---------------------Running Recon Commands--------------------\n"
printf "${NC}\n"
IFS="
"
mkdir -p recon/
if [ "$2" = "All" ]; then
reconCommands="$(grep "${HOST}" "nmap/Recon_${HOST}.nmap")"
else
reconCommands="$(grep "${HOST}" "nmap/Recon_${HOST}.nmap" | grep "$2")"
fi
# Run each line
for line in ${reconCommands}; do
currentScan="$(echo "${line}" | cut -d ' ' -f 1)"
fileName="$(echo "${line}" | awk -F "recon/" '{print $2}')"
if [ -n "${fileName}" ] && [ ! -f recon/"${fileName}" ]; then
printf "${NC}\n"
printf "${YELLOW}Starting ${currentScan} scan\n"
printf "${NC}\n"
eval "${line}"
printf "${NC}\n"
printf "${YELLOW}Finished ${currentScan} scan\n"
printf "${NC}\n"
printf "${YELLOW}=========================\n"
fi
done
IFS="${origIFS}"
echo
echo
echo
}
# Print footer with total elapsed time
footer() {
printf "${GREEN}---------------------Finished all scans------------------------\n"
printf "${NC}\n\n"
elapsedEnd="$(date '+%H:%M:%S' | awk -F: '{print $1 * 3600 + $2 * 60 + $3}')"
elapsedSeconds=$((elapsedEnd - elapsedStart))
if [ ${elapsedSeconds} -gt 3600 ]; then
hours=$((elapsedSeconds / 3600))
minutes=$(((elapsedSeconds % 3600) / 60))
seconds=$(((elapsedSeconds % 3600) % 60))
printf "${YELLOW}Completed in ${hours} hour(s), ${minutes} minute(s) and ${seconds} second(s)\n"
elif [ ${elapsedSeconds} -gt 60 ]; then
minutes=$(((elapsedSeconds % 3600) / 60))
seconds=$(((elapsedSeconds % 3600) % 60))
printf "${YELLOW}Completed in ${minutes} minute(s) and ${seconds} second(s)\n"
else
printf "${YELLOW}Completed in ${elapsedSeconds} seconds\n"
fi
printf "${NC}\n"
}
# Choose run type based on chosen flags
main() {
assignPorts "${HOST}"
header
case "${TYPE}" in
[Nn]etwork) networkScan "${HOST}" ;;
[Pp]ort) portScan "${HOST}" ;;
[Ss]cript)
[ ! -f "nmap/Port_${HOST}.nmap" ] && portScan "${HOST}"
scriptScan "${HOST}"
;;
[Ff]ull) fullScan "${HOST}" ;;
[Uu]dp) UDPScan "${HOST}" ;;
[Vv]ulns)
[ ! -f "nmap/Port_${HOST}.nmap" ] && portScan "${HOST}"
vulnsScan "${HOST}"
;;
[Rr]econ)
[ ! -f "nmap/Port_${HOST}.nmap" ] && portScan "${HOST}"
[ ! -f "nmap/Script_${HOST}.nmap" ] && scriptScan "${HOST}"
recon "${HOST}"
;;
[Aa]ll)
portScan "${HOST}"
scriptScan "${HOST}"
fullScan "${HOST}"
UDPScan "${HOST}"
vulnsScan "${HOST}"
recon "${HOST}"
;;
esac
footer
}
# Ensure host and type are passed as arguments
if [ -z "${TYPE}" ] || [ -z "${HOST}" ]; then
usage
fi
# Ensure $HOST is an IP or a URL
if ! expr "${HOST}" : '^\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)$' >/dev/null && ! expr "${HOST}" : '^\(\([[:alnum:]-]\{1,63\}\.\)*[[:alpha:]]\{2,6\}\)$' >/dev/null; then
printf "${RED}\n"
printf "${RED}Invalid IP or URL!\n"
usage
fi
# Ensure selected scan type is among available choices, then run the selected scan
if ! case "${TYPE}" in [Nn]etwork | [Pp]ort | [Ss]cript | [Ff]ull | UDP | udp | [Vv]ulns | [Rr]econ | [Aa]ll) false ;; esac then
mkdir -p "${OUTPUTDIR}" && cd "${OUTPUTDIR}" && mkdir -p nmap/ || usage
main | tee "nmapAutomator_${HOST}_${TYPE}.txt"
else
printf "${RED}\n"
printf "${RED}Invalid Type!\n"
usage
fi
nmapAutomator 所需的许多道德黑客工具应该已经成为流行发行版的一部分,例如 Kali Linux 和 Parrot OS。除了 SSLscan、Nikto 和 FFuF,如前所述,该列表还包括:ldapsearch、snmpwalk、snmp-check、smtp-user-enum、droopescan、smbmap、enum4linux、dnsrecon、odat、wpscan、joomscan、gobuster 和 nmap_vulners。
脚本中使用的其他侦察工具包括:
nmap Vulners | sslscan | nikto | joomscan | wpscan |
---|---|---|---|---|
droopescan | smbmap | enum4linux | dnsrecon | odat |
smtp-user-enum | snmp-check | snmpwalk | ldapsearch |
其中大部分应该默认安装在Parrot OS和Kali Linux 中。
如果发现缺少任何侦察推荐工具,它们将被自动忽略,并通知用户。
例如,为了满足其中一些要求,可以安装FFluf和Gobuster等工具:
sudo apt update
sudo apt install ffuf -y
或者
sudo apt update
sudo apt install gobuster -y
此外,在运行 nmapAutomator 时,如果发现缺少任何推荐的工具,它们将被自动忽略,并会通知用户。
基本用法
./nmapAutomator.sh -h
用法: nmapAutomator.sh -H/--host <目标ip> -t/--type <类型>
可选: [-r/--remote <远程模式>] [-d/--dns <DNS服务器>] [-o/--output <输出目录>] [-s/--static-nmap <静态NMAP路径>]
扫描类型:
Network :显示主机网络中的所有活动主机(约 15 秒)
Port :显示所有打开的端口(~15 秒)
Script :在找到的端口上运行脚本扫描(约 5 分钟)
Full :运行全范围端口扫描,然后对新端口运行彻底扫描(约 5-10 分钟)
UDP :运行 UDP 扫描“需要 sudo”(约 5 分钟)
Vulns :在所有找到的端口上运行CVE扫描和 Nmap 漏洞扫描(约 5-15 分钟)
Recon :建议侦察命令,然后提示自动运行它们
ALL:运行所有扫描(约 20-30 分钟)
使用 nmapAutomator 很简单。条件由以下参数给出:
nmapAutomator.sh -H/–host -t/–type 其中目标主机可以采用 IPv4 地址 (1.1.1.1) 或主机名 (scanme.nmap.org) 的形式,-t选项指定扫描类型(例如,端口)。例如:
./nmapAutomator.sh --host 10.1.1.1 --type All
./nmapAutomator.sh -H 10.1.1.1 -t Basic
./nmapAutomator.sh -H example.com -t Recon -d 1.1.1.1
./nmapAutomator.sh -H 10.10.10.10 -t network -s ./nmap
此外,还有一些可选参数,例如-d允许您指定 DNS 服务器,或-o允许您设置最终报告所在的输出目录。NmapAutomator 将每种类型的扫描的输出保存到一个单独的文件中,在输出目录下,包括整个脚本输出,您可以稍后使用您喜欢的工具查看。

其他功能目前正在开发中,并将在未来版本中添加,包括在一次扫描中启用多种扫描类型、在一次扫描中扫描多个主机以及在所有扫描中实施远程模式。
输出
nmapAutomator 将每种类型的扫描的输出保存到一个单独的文件中,在输出目录下。
整个脚本输出也被保存,您可以使用 来查看less -r outputDir/nmapAutomator_host_type.txt
,也可以简单地使用cat
读取它。
测试 nmapAutomator
再一次,nmapAutomator 的设计考虑了易用性;因此,我们将针对域scanme.nmap.org创建一个简单的测试用例——这是 Nmap 项目提供的服务器,该服务器已授权用户扫描此端点以进行测试,只要扫描活动不过度或太侵入。
使用-t Recon scan 选项,您的结果应该类似于:

如您所见,Nikto 启动了其 Web 服务器侦察,我们可以看到以下结果:

现在是时候看看 FFuF 的运行情况了:

类似地,我们可以在发现的端口上尝试-t Script选项——这些脚本构成了默认设置,相当于使用 Nmap 的 -sC 或 -A 标志,它们被认为是安全的,因为它们不会执行任何可能干扰目标主机上的正常操作。但是,有些肯定会触发IDS 或 IPS事件,因此请谨慎操作。
让我们在内部 Apache 服务器上运行上面的代码并观察结果:

即将推出的功能
[v]支持 URL/DNS - 谢谢@KatsuragiCSL
[v]为 http recon 添加扩展模糊测试
[v]添加nmap进度条
[v]列出侦察中缺少的工具
[v]添加选项以更改输出文件夹
[v]将完整的脚本输出保存到文件
[v]提高脚本的性能和效率 - 感谢 @caribpa
[v]使 nmapAutomater 100% 兼容 POSIX。- 非常感谢@caribpa
[v]添加网络扫描类型,以便 nmapAutomator 可以发现网络上的活动主机。
[ ]在一次扫描中启用多种扫描类型。
[ ]在一次扫描中启用多台主机的扫描。
[ ]对所有扫描完全实施远程模式
最后的话
在我们所有的测试中,nmapAutomator 展示了令人印象深刻的运行时间和扫描动态。具有以自动化方式作为后台进程运行的能力,很难想象这样的工具不会成为侦察和枚举库存的永久补充,即使这些空间充满了经过时间考验的原则和应用程序。
我们邀请您尝试使用 nmapAutomator,亲眼看看该工具的众多优势,该工具可让您专注于侦察和渗透测试,同时抛开过于复杂的配置。
你不会失望的。
您可以在后台运行脚本

GitHub地址:
https://github.com/21y4d/nmapAutomator
测试截图
仅使用侦察命令:





转载请注明出处及链接