端口扫描脚本#

脚本说明#

端口扫描脚本用于扫描目标主机的开放端口,支持多种扫描方式,包括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 "$@"

使用说明#

  1. 添加执行权限:

    chmod +x port_scanner.sh
  2. 基本用法:

    # 扫描默认端口(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
  3. 高级用法:

    # 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: 用于高级扫描功能(可选)

注意事项#

  1. 端口扫描可能被视为入侵行为,请确保有授权
  2. 扫描大量端口可能需要较长时间
  3. 某些网络环境可能阻止扫描
  4. UDP扫描需要root权限
  5. 使用nmap可以获得更详细的信息
  6. 遵守当地法律法规