应急响应(Linux)

最后更新于 2025-05-23 398 次阅读


应急响应的核心目标

  1. 快速止损:遏制攻击扩散,防止数据泄露或系统瘫痪。
  2. 恢复业务:尽快修复系统,保障业务连续性。
  3. 溯源取证:分析攻击路径、手法和攻击者身份,支持法律追责。
  4. 改进防御:通过事件复盘,修补漏洞并优化安全策略。

应急响应流程(NIST框架)

国际通用的流程基于NIST SP 800-61标准,分为六个阶段:

  1. 准备(Preparation)
    • 制定预案:明确团队职责、通信机制和处置流程。
    • 工具储备:部署监控系统(如SIEM)、取证工具(如Wireshark、Autopsy)。
    • 演练培训:定期模拟攻击场景(如勒索软件、APT攻击),提升实战能力。
  2. 检测与识别(Detection & Identification)
    • 监控告警:通过IDS/IPS、EDR、日志分析发现异常行为(如异常登录、加密流量)。
    • 初步分类:判断事件类型(如DDoS、数据泄露、恶意软件)和影响范围。
  3. 遏制(Containment)
    • 短期遏制:隔离受感染设备、关闭高危端口、阻断恶意IP。
    • 长期遏制:修复漏洞、调整防火墙策略,防止攻击横向扩散。
  4. 根除(Eradication)
    • 清除威胁:删除恶意文件、修复被篡改配置、升级补丁。
    • 深度检测:全盘扫描系统,确保无残留后门或持久化攻击。
  5. 恢复(Recovery)
    • 业务重启:从备份恢复数据,逐步上线系统并验证功能。
    • 持续监控:观察恢复后系统是否再次出现异常活动。
  6. 总结与改进(Post-Incident Analysis)
    • 事件报告:记录时间线、攻击手法、处置措施和损失评估。
    • 改进措施:更新应急预案、强化员工安全意识培训、优化技术防护
安全事件分级
一级事件
演习目标被控制,安全红色预警,一级响应

二级事件
重要系统或设备被控制,安全红色预警,一级响应

三级事件
内网一般设备被控制,安全橙色预警,二级响应

四级事件
DMZ区一般设备被控制,安全橙色预警,三级响应

五级事件
DMZ区设备遭到攻击或内网终端遭到攻击,安全黄色预警,三级响应

本文通过红队攻击层面进行逐层分析

Linux篇

攻击阶段1:侦察与信息收集

红队手法:

  • 扫描开放端口(SSH、HTTP等)、服务版本探测(Nmap、Masscan)。
  • 收集公开信息(GitHub代码泄漏、子域名枚举)。
  • 社工钓鱼

应急响应防御措施

  1. 日志监控
    • 监控/var/log/auth.log(SSH登录尝试)、/var/log/apache2/access.log(Web访问日志)。
    • 使用工具或者代码自动封禁多次登录失败的IP。
  2. 最小化暴露面
    • 关闭非必要服务(systemctl disable [service]),仅开放业务所需端口。
    • 使用CDN或防火墙隐藏真实服务器IP。
  3. 诱饵与欺骗
    • 部署蜜罐(如Cowrie模拟SSH服务)吸引攻击者,记录其行为。

审计日志

日志类型文件路径说明
整体日志/var/log/message系统整体日志(通常为 /var/log/messages
登录注销日志(last)/var/log/wtmp记录用户登录和注销历史
登录日志(lastlog)/var/log/lastlog显示用户最近一次登录信息
登录失败日志(lastb)/var/log/btmp记录失败的登录尝试
当前用户(w/who/users)/var/log/utmp记录当前登录用户信息
定时任务日志/var/log/cron记录定时任务(Cron)的执行日志
系统应用登录日志/var/log/secure记录系统安全事件(如 SSH 登录)
软件安装日志/var/log/yum.log记录通过 YUM/DNF 安装的软件信息

cat /var/log/yum.log | tail -n 20

自动阻断爆破代码

#! /usr/bin/env python3

import re
import subprocess
import time

#安全日志
logFile = '/var/log/secure'
#黑名单
hostDeny = '/etc/hosts.deny'
#获取已经在黑名单的IP,转换为字典
def getDenies():
    deniedDict = {}
    list = open(hostDeny).readlines()
    for ip in list:
        group = re.search(r'(\d+\.\d+\.\d+\.\d+)',ip)
        if group:
            deniedDict[group[1]] = '1'
    return deniedDict


#监控方法
def monitorLog(Logfile):
    #已经封禁的IP
    deniedDict = getDenies()
    #统计密码错误的次数
    tempIP = {}
    #阀值
    password_wrong_num = 10
    #读取安全日志
    popen = subprocess.Popen('tail -f '+logFile,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
    #开始监控
    while True:
        time.sleep(0.2)
        line = popen.stdout.readline().strip()
        if line:
            group = re.search('Invalid user \w+ from (\d+\.\d+\.\d+\.\d+)',str(line))
            #不存在用户直接封
            if group and not deniedDict.get(group[1]):
                subprocess.getoutput('echo \'sshd:{} >> {}'.format(group[1],hostDeny))
                deniedDict[group[1]] = '1'
                time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                print('{} --------- add ip {} to hosts.deny for invalid user'.format(time_str,group[1]))
                continue

            #用户名合法,密码错误
            group = re.search('Failed password for \w+ from (\d+\.\d+\.\d+\.\d+)',str(line))
            if group:
                ip = group
                #统计IP错误次数
                if not tempIP.get(ip):
                    tempIP[ip] = '1'
                else:
                    tempIP[ip] = tempIP[ip]+1
                #如果错误次数大于阀值
                if tempIP[ip] > password_wrong_num and not deniedDict.get(ip):
                    del tempIP[ip]
                    subprocess.getoutput('echo \'sshd:{} >> {}'.format(group[1], hostDeny))
                    deniedDict[group[1]] = '1'
                    time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                    print('{} --------- add ip{} to hosts.deny for invalid user'.format(time_str, group[1]))

if __name__ == '__main__':
    monitorLog(logFile)

攻击阶段2:初始入侵

红队手法

  • 利用Web应用漏洞(如SQL注入、RCE)获取Shell。
  • 暴力破解SSH弱密码或利用密钥泄漏。
  • 通过恶意软件(如Web Shell、反弹Shell)建立控制。

应急响应防御措施

  1. 入侵检测与阻断
    • 监控文件变化(如/tmp目录)、异常进程。
    • 检查账号安全情况
    • 部署IDS(主机入侵检测系统)检测Rootkit、隐藏进程。
  2. 快速隔离
    • 发现异常立即隔离主机(断开网络或移至隔离VLAN)。
  3. 取证分析
    • 分析磁盘镜像,查找Web Shell路径(如/var/www/html/upload/)。
    • 通过lsof -inetstat -tulnp检查异常网络连接。
用户名字典:

grep "Failed password" /var/log/secure|perl -e 'while($_=<>){ /for(.*?) from/; print "$1\n";}'|uniq -c|sort -nr

有多少IP在暴破root密码:

grep "Failed password for root" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more

定位暴破的IP

grep "Failed password" /var/log/secure|grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0- 9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0- 5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"|uniq -c

登录成功的IP

grep "Accepted " /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more

登录成功的日期、用户名、IP:

grep "Accepted " /var/log/secure | awk '{print $1,$2,$3,$9,$11}'

攻击阶段3:权限提升

红队手法

  • 利用SUDO配置错误(如允许普通用户执行/bin/bash)。
  • 内核漏洞提权(如Dirty Cow、Dirty Pipe)。
  • 劫持动态链接库(LD_PRELOAD)

应急响应防御措施

  1. 权限审计
    • 检查/etc/sudoers文件,限制不必要的SUDO权限(visudo)。
    • 使用Lynis扫描系统配置弱点。
  2. 补丁与加固
    • 定期更新内核和软件包(apt update && apt upgrade)。
    • 禁用危险内核功能(如user namespace)。
  3. 进程监控
    • 使用安全工具(如EDR)监控敏感系统调用(如execveptrace

攻击阶段4:横向移动

红队手法

  • 利用SSH密钥或凭证在内部网络横向传播。
  • 通过SMB/NFS共享或漏洞(如Log4j)攻击其他主机。
  • 部署后门或C2通道(如Metasploit、Cobalt Strike)。

应急响应防御措施

  1. 网络分段
    • 划分VLAN,限制主机间通信(仅允许必需端口)。
    • 限制出站流量(如阻止非业务域名解析)。
  2. 凭证保护
    • 禁用密码登录,强制SSH密钥认证(PasswordAuthentication no)。
    • 定期轮换SSH密钥和API令牌。
  3. 流量分析
    • 检测异常协议(如DNS隧道、ICMP隐蔽通信)。

检测异常流量命令

# 查看所有 TCP/UDP 连接和监听端口(Linux)
netstat -tulnp

# 使用 ss(更现代的替代工具)
ss -tulnp

# 查找异常外部 IP 连接
netstat -antp | grep ESTABLISHED

攻击阶段5:持久化与数据窃取

红队手法

  • 添加定时任务(Cron)、Systemd服务或SSH后门(如~/.ssh/authorized_keys注入)。
  • 加密或外传敏感数据(通过HTTP/SSH/FTP)。

应急响应防御措施

  1. 持久化检测
    • 检查/etc/cron.*//etc/systemd/system/中的异常任务或服务。
  2. 数据防泄漏(DLP)
    • 监控大文件传输行为(如iftopnethogs)。
    • 使用ClamAV扫描恶意文件,部署Vault管理敏感数据。
  3. 备份与恢复
    • 定期验证备份完整性(如sha256sum),确保离线备份可用(3+2+1文件备份策略)

查看ssh key

启动项和服务

chkconfig --list
systemctl list-units
/etc/rc.local
/etc/rc.d/rc.local

检测定时任务

crontab -l
cat /etc/crontab
ll /etc/cron.*
cat /etc/anacrontab 查看异步定时任务
more /var/log/cron 查看计划任务日志

其他排查点

1.系统资源

CPU
top -c -o %CPU 
ps -aux --sort=-pcpu|head -10
内存:
free -m
top -c -o %MEM
磁盘:
df -Th
进程
ps -ef
ps -aux grep "name"
pidof "name"
pstree (需要安装)
杀进程
ps -elf | grep [pid]
kill -9 [pid]
删文件
ls -al /proc/[pid]/exe
rm -f [exe_path]
杀毒软件
ClamAV
网络连接
lsof -i
netstat -antpl

-a: 显示所有连接,包括正在监听的和非监听的连接。
-n: 使用数字形式显示地址和端口号,而不进行域名解析。
-t: 仅显示TCP协议的连接。
-p: 显示建立相关连接的进程ID(PID)和进程名称。
-l: 仅显示正在监听的连接。

iptables -L
系统用户
/etc/passwd
/etc/shadow
删除
userdel xxx
rm -rf /home/xxx

awk -F: '$3==0{print $1}' /etc/passwd (以冒号为分隔符,第三位是0的用户)
who (查看当前登录的用户)
w(显示已登陆的用户,且在执行的命令)
last (查看登录成功的用户)
lastb(查看最近登录失败的用户) 
lastlog (查看所有用户最近登录的时间)

2.历史命令

history
隐藏和删除:
set +o history
命令前加空格  # 在命令前加空格(仅当 HISTCONTROL 包含 ignorespace 或 ignoreboth 时生效)
histocy -c && >~./bash_history # 清空历史记录文件

3.系统命令篡改和别名

#找出被修改过的系统文件
find /usr/bin/ /usr/sbin/ /bin/ /usr/local/bin/ -type f -mtime -7 | xargs ls -alh
#alias
cat ~/.bashrc

自动化脚本

#!/usr/bin/env python3

import os
import re
import sys
import shutil
import subprocess
import zipfile
from datetime import datetime


class LinuxSecurityCheck:
    def __init__(self):
        self.ipadd = self.get_ip_address()
        self.date = datetime.now().strftime("%Y%m%d-%H%M%S")
        self.base_dir = f"/tmp/buying_{self.ipadd}_{self.date}/"
        self.check_file = os.path.join(self.base_dir, "check_file")
        self.danger_file = os.path.join(self.base_dir, "danger_file.txt")
        self.log_file = os.path.join(self.base_dir, "log")
        self.saveresult = os.path.join(self.check_file, "checkresult.txt")

        self.init_dirs()
        self.check_root()

    def init_dirs(self):
        """初始化目录并清空历史数据"""
        shutil.rmtree(self.base_dir, ignore_errors=True)
        os.makedirs(self.check_file, exist_ok=True)
        os.makedirs(self.log_file, exist_ok=True)
        with open(self.danger_file, "w") as f:
            f.write("检查发现危险项,请注意:\n\n")

    def check_root(self):
        """检查是否以root权限运行"""
        if os.geteuid() != 0:
            print("安全检查必须使用root账号,否则某些项无法检查")
            sys.exit(1)

    def run_command(self, cmd):
        """执行系统命令并返回输出"""
        try:
            result = subprocess.check_output(
                cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True
            )
            return result.strip()
        except subprocess.CalledProcessError:
            return ""

    def save_result(self, content, danger=False, filename=None):
        """保存检查结果"""
        mode = "a" if os.path.exists(self.saveresult) else "w"
        with open(self.saveresult, mode) as f:
            f.write(content + "\n")

        if danger:
            with open(self.danger_file, "a") as f:
                f.write(content + "\n")

        if filename:
            with open(os.path.join(self.check_file, filename), "a") as f:
                f.write(content + "\n")

    def get_ip_address(self):
        """获取本机IP地址"""
        output = self.run_command("ifconfig -a")
        match = re.search(r"inet (\d+\.\d+\.\d+\.\d+)", output)
        return match.group(1) if match else "Unknown"

    def check_ip_info(self):
        """检查IP地址信息"""
        self.save_result("\n-------------0.IP及版本-------------------")
        output = self.run_command("ifconfig -a | grep -w inet")
        if output:
            self.save_result("[*]本机IP地址信息:\n" + output)
        else:
            self.save_result("[!!!]本机未配置IP地址", danger=True)

    def check_users(self):
        """检查用户相关信息"""
        self.save_result("\n------------1查看登录用户------------------")
        logged_users = self.run_command("who")
        self.save_result("[*]系统登录用户:\n" + logged_users)

        self.save_result("\n------------2查看用户信息------------------")
        passwd_content = self.run_command("cat /etc/passwd")
        self.save_result("[*]用户信息:\n" + passwd_content)

    def check_superusers(self):
        """检查超级用户"""
        self.save_result("\n------------3检查超级用户---------------------")
        superusers = self.run_command(
            "awk -F: '($3 == 0 && $1 != \"root\") {print $1}' /etc/passwd"
        )
        if superusers:
            self.save_result(f"[!!!]发现超级用户: {superusers}", danger=True)
        else:
            self.save_result("[*]未发现超级用户")

    def check_history(self):
        """检查命令历史"""
        self.save_result("\n------------4历史命令--------------------------")
        history = self.run_command("cat /root/.bash_history")
        if history:
            self.save_result("[*]历史命令:\n" + history)
        else:
            self.save_result("[!!!]未发现历史命令", danger=True)

    def check_processes(self):
        """检查进程信息"""
        self.save_result("\n------------5.进程分析--------------------")
        processes = self.run_command("ps -aux")
        self.save_result("[*]系统进程:\n" + processes)

    def check_services(self):
        """检查运行服务"""
        self.save_result("\n------------9.运行服务----------------------")
        services = self.run_command("systemctl list-units --type=service --state=running")
        if services:
            self.save_result("[*]运行服务:\n" + services)
        else:
            self.save_result("[!!!]未发现运行服务", danger=True)

    def check_cpu(self):
        """检查CPU使用情况"""
        self.save_result("\n------------6CPU分析-----------------")
        cpu_info = self.run_command("lscpu")
        self.save_result("[*]CPU信息:\n" + cpu_info)

        top_processes = self.run_command("ps -aux --sort=-%cpu | head -n 5")
        self.save_result("[*]CPU占用前5进程:\n" + top_processes)

    def analyze_logs(self):
        """分析系统日志"""
        self.save_result("\n------------7 日志分析------------------------------")
        # 示例:分析安全日志
        failed_logins = self.run_command("grep 'Failed password' /var/log/secure*")
        if failed_logins:
            self.save_result("[!!!]发现失败登录尝试:\n" + failed_logins, danger=True)

        # 打包日志文件
        try:
            with zipfile.ZipFile(os.path.join(self.log_file, "system_log.zip"), "w") as zf:
                for root, _, files in os.walk("/var/log"):
                    for file in files:
                        zf.write(os.path.join(root, file))
            self.save_result("[*]日志打包成功")
        except Exception as e:
            self.save_result(f"[!!!]日志打包失败: {str(e)}", danger=True)

    def run_checks(self):
        """执行所有检查项"""
        checks = [
            self.check_ip_info,
            self.check_users,
            self.check_superusers,
            self.check_history,
            self.check_processes,
            self.check_services,
            self.check_cpu,
            self.analyze_logs
        ]

        for check in checks:
            try:
                check()
            except Exception as e:
                print(f"检查过程中发生错误: {str(e)}")

        print("\n检查结束!结果保存在:", self.base_dir)


if __name__ == "__main__":
    checker = LinuxSecurityCheck()
    checker.run_checks()

Linux应急响应手册

https://github.com/Just-Hack-For-Fun/Linux-INCIDENT-RESPONSE-COOKBOOK