端口扫描脚本#
脚本说明#
端口扫描脚本用于扫描目标主机的开放端口,支持多种扫描方式,包括TCP连接扫描、UDP扫描、服务版本检测等。
脚本代码#
#!/bin/bash
# 端口扫描脚本
# 功能:扫描目标主机的开放端口
# 作者:System Admin
# 日期:2026-01-01
set -euo pipefail
# 配置变量
TARGET=""
PORT_RANGE="1-1024"
SCAN_TYPE="tcp"
TIMEOUT=1
OUTPUT_FILE=""
VERBOSE=false
COMMON_PORTS=false
# 常用端口列表
COMMON_PORTS_LIST=(21 22 23 25 53 80 110 143 443 993 995 3306 3389 5432 5900 8080 8443)
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 日志函数
log() {
local level=$1
shift
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $@"
}
log_info() {
log "INFO" "$@"
}
log_error() {
log "ERROR" "$@"
}
log_warning() {
log "WARNING" "$@"
}
# 检查nc命令
check_nc() {
if ! command -v nc &> /dev/null; then
log_error "nc命令未安装,请先安装netcat"
return 1
fi
return 0
}
# 检查nmap命令
check_nmap() {
if ! command -v nmap &> /dev/null; then
log_warning "nmap未安装,将使用nc进行扫描"
return 1
fi
return 0
}
# TCP端口扫描
tcp_scan() {
local target=$1
local ports=$2
log_info "TCP端口扫描: $target:$ports"
local open_ports=()
if check_nmap; then
# 使用nmap扫描
local result=$(nmap -p "$ports" --open -T4 "$target" 2>/dev/null | grep "^PORT\|open")
echo "$result"
# 提取开放端口
open_ports=($(echo "$result" | grep -oP '\d+(?=/tcp)' | sort -n))
else
# 使用nc扫描
IFS=',' read -ra PORT_ARRAY <<< "$ports"
for port in "${PORT_ARRAY[@]}"; do
if [[ $port =~ ^[0-9]+$ ]]; then
if timeout $TIMEOUT bash -c "echo > /dev/tcp/$target/$port" 2>/dev/null; then
echo -e "${GREEN}[OPEN]${NC} $target:$port"
open_ports+=($port)
else
if [ "$VERBOSE" = true ]; then
echo -e "${RED}[CLOSED]${NC} $target:$port"
fi
fi
elif [[ $port =~ ^[0-9]+-[0-9]+$ ]]; then
local start=$(echo "$port" | cut -d- -f1)
local end=$(echo "$port" | cut -d- -f2)
for ((p=start; p<=end; p++)); do
if timeout $TIMEOUT bash -c "echo > /dev/tcp/$target/$p" 2>/dev/null; then
echo -e "${GREEN}[OPEN]${NC} $target:$p"
open_ports+=($p)
fi
done
fi
done
fi
return 0
}
# UDP端口扫描
udp_scan() {
local target=$1
local ports=$2
log_info "UDP端口扫描: $target:$ports"
if ! check_nmap; then
log_error "UDP扫描需要nmap"
return 1
fi
# 使用nmap扫描UDP端口
nmap -sU -p "$ports" --open -T4 "$target" 2>/dev/null | grep "^PORT\|open"
}
# 服务版本检测
service_detection() {
local target=$1
local port=$2
log_info "服务版本检测: $target:$port"
if ! check_nmap; then
log_error "服务版本检测需要nmap"
return 1
fi
# 使用nmap检测服务版本
nmap -sV -p "$port" "$target" 2>/dev/null | grep "^PORT\|open"
}
# 操作系统检测
os_detection() {
local target=$1
log_info "操作系统检测: $target"
if ! check_nmap; then
log_error "操作系统检测需要nmap"
return 1
fi
# 使用nmap检测操作系统
nmap -O "$target" 2>/dev/null | grep "OS details\|Running"
}
# 常用端口扫描
common_ports_scan() {
local target=$1
log_info "常用端口扫描: $target"
local ports=$(IFS=,; echo "${COMMON_PORTS_LIST[*]}")
tcp_scan "$target" "$ports"
}
# 快速扫描
quick_scan() {
local target=$1
log_info "快速扫描: $target"
if check_nmap; then
# 使用nmap快速扫描
nmap -F --open "$target" 2>/dev/null | grep "^PORT\|open"
else
# 扫描常用端口
common_ports_scan "$target"
fi
}
# 全面扫描
full_scan() {
local target=$1
log_info "全面扫描: $target"
if ! check_nmap; then
log_error "全面扫描需要nmap"
return 1
fi
# 使用nmap全面扫描
nmap -p- --open -sV -O "$target" 2>/dev/null
}
# 生成扫描报告
generate_report() {
local target=$1
local output_file=$2
log_info "生成扫描报告: $output_file"
{
echo "端口扫描报告"
echo "============"
echo ""
echo "目标主机: $target"
echo "扫描时间: $(date)"
echo ""
echo "===== 开放端口 ====="
tcp_scan "$target" "$PORT_RANGE" | grep "OPEN"
echo ""
echo "===== 服务版本 ====="
for port in $(tcp_scan "$target" "$PORT_RANGE" | grep -oP '\d+(?=/tcp)'); do
service_detection "$target" "$port"
done
echo ""
echo "===== 操作系统 ====="
os_detection "$target"
} > "$output_file"
log_info "扫描报告已生成: $output_file"
}
# 显示帮助
show_help() {
echo "用法: $0 [选项] <目标>"
echo ""
echo "选项:"
echo " -p <端口范围> 端口范围(默认: 1-1024)"
echo " -t <类型> 扫描类型(tcp/udp,默认: tcp)"
echo " -T <超时> 连接超时(秒,默认: 1)"
echo " -o <文件> 输出到文件"
echo " -c 扫描常用端口"
echo " -v 详细输出"
echo " -h 显示帮助信息"
echo ""
echo "扫描模式:"
echo " --quick 快速扫描"
echo " --full 全面扫描"
echo ""
echo "示例:"
echo " $0 192.168.1.1"
echo " $0 -p 1-65535 192.168.1.1"
echo " $0 -t udp 192.168.1.1"
echo " $0 -c 192.168.1.1"
echo " $0 --quick 192.168.1.1"
echo " $0 --full 192.168.1.1"
}
# 主函数
main() {
# 解析选项
while getopts "p:t:T:o:cvh" opt; do
case $opt in
p)
PORT_RANGE="$OPTARG"
log_info "端口范围: $PORT_RANGE"
;;
t)
SCAN_TYPE="$OPTARG"
log_info "扫描类型: $SCAN_TYPE"
;;
T)
TIMEOUT="$OPTARG"
log_info "连接超时: ${TIMEOUT}秒"
;;
o)
OUTPUT_FILE="$OPTARG"
log_info "输出文件: $OUTPUT_FILE"
;;
c)
COMMON_PORTS=true
log_info "扫描常用端口"
;;
v)
VERBOSE=true
log_info "详细输出"
;;
h)
show_help
exit 0
;;
*)
log_error "无效选项: $opt"
show_help
exit 1
;;
esac
done
shift $((OPTIND - 1))
# 检查目标
if [ $# -eq 0 ]; then
log_error "缺少目标主机"
show_help
exit 1
fi
TARGET="$1"
# 检查命令
if ! check_nc; then
exit 1
fi
# 显示扫描信息
log_info "===== 开始端口扫描 ====="
log_info "目标主机: $TARGET"
log_info "扫描类型: $SCAN_TYPE"
if [ "$COMMON_PORTS" = true ]; then
common_ports_scan "$TARGET"
else
# 执行扫描
case $SCAN_TYPE in
tcp)
tcp_scan "$TARGET" "$PORT_RANGE"
;;
udp)
udp_scan "$TARGET" "$PORT_RANGE"
;;
*)
log_error "无效的扫描类型: $SCAN_TYPE"
exit 1
;;
esac
fi
# 生成报告
if [ -n "$OUTPUT_FILE" ]; then
generate_report "$TARGET" "$OUTPUT_FILE"
fi
log_info "===== 端口扫描完成 ====="
}
# 扫描模式处理
if [[ "$1" == "--quick" ]]; then
shift
if ! check_nc; then
exit 1
fi
log_info "===== 快速扫描 ====="
quick_scan "$1"
exit 0
elif [[ "$1" == "--full" ]]; then
shift
if ! check_nmap; then
exit 1
fi
log_info "===== 全面扫描 ====="
full_scan "$1"
exit 0
fi
# 执行主函数
main "$@"使用说明#
添加执行权限:
chmod +x port_scanner.sh基本用法:
# 扫描默认端口(1-1024) ./port_scanner.sh 192.168.1.1 # 扫描指定端口范围 ./port_scanner.sh -p 1-65535 192.168.1.1 # 扫描常用端口 ./port_scanner.sh -c 192.168.1.1高级用法:
# UDP端口扫描 ./port_scanner.sh -t udp 192.168.1.1 # 快速扫描 ./port_scanner.sh --quick 192.168.1.1 # 全面扫描 ./port_scanner.sh --full 192.168.1.1 # 输出到文件 ./port_scanner.sh -o scan_report.txt 192.168.1.1
功能特点#
- TCP端口扫描
- UDP端口扫描
- 服务版本检测
- 操作系统检测
- 常用端口扫描
- 快速扫描
- 全面扫描
- 详细输出
- 扫描报告生成
依赖项#
- nc (netcat): 用于端口扫描
- nmap: 用于高级扫描功能(可选)
注意事项#
- 端口扫描可能被视为入侵行为,请确保有授权
- 扫描大量端口可能需要较长时间
- 某些网络环境可能阻止扫描
- UDP扫描需要root权限
- 使用nmap可以获得更详细的信息
- 遵守当地法律法规