├── README.MD ├── del.exp ├── get.exp ├── hosts.txt ├── linuxcheck.sh ├── login.sh ├── put.exp └── sh.exp /README.MD: -------------------------------------------------------------------------------- 1 | # LinuxCheck 2 | 3 | LinuxCheck 是一个自动化的 Linux 系统安全检查工具,用于批量检查多台 Linux 服务器的安全状况。 4 | 可适应于Centos和Ubunt系统 5 | 6 | ## 功能特点 7 | 8 | - 自动化批量检查多台服务器 9 | - 全面的安全检查项目 10 | - 自动收集和整理检查结果 11 | - 最小化目标服务器影响,执行完成后自动清理 12 | 13 | ## 系统要求 14 | 15 | - Linux 操作系统(本地执行机和目标服务器) 16 | - expect 工具包 17 | - SSH 服务可用 18 | 19 | ## 快速开始 20 | 21 | ### 1. 准备工作 22 | 23 | 克隆仓库到本地: 24 | 25 | ```bash 26 | git clone https://github.com/feiniao112/LinuxCheck.git 27 | cd LinuxCheck 28 | ``` 29 | 30 | ### 2. 配置目标服务器 31 | 32 | 编辑 `hosts.txt` 文件,按以下格式添加服务器信息: 33 | 34 | ``` 35 | IP地址:普通用户名:普通用户密码:root密码 36 | ``` 37 | 38 | 示例: 39 | ``` 40 | 192.168.1.81:user:password123:rootpass 41 | 192.168.1.82:admin:password456:rootpass 42 | ``` 43 | 44 | ### 3. 执行检查 45 | 46 | ```bash 47 | sh login.sh 48 | ``` 49 | 同时也支持针对单台进行检查,只需要将linuxcheck.sh这个文件上传就可以进行检查 50 | 51 | 52 | ### 4. 检查结果 53 | 54 | 执行完成后,结果文件会自动收集到本地执行机器上。 55 | 56 | ## 文件说明 57 | 58 | - `linuxcheck.sh`: 主要的安全检查脚本 59 | - `login.sh`: 批量登录和执行脚本 60 | - `del.exp`: 清理脚本 61 | - `get.exp`: 获取结果脚本 62 | - `put.exp`: 上传脚本 63 | - `sh.exp`: 执行脚本 64 | - `hosts.txt`: 服务器配置文件 65 | 66 | ## 注意事项 67 | 68 | 1. 请确保本地执行机已安装 expect 工具包 69 | 2. 确保目标服务器的 SSH 服务正常运行 70 | 3. 建议使用普通用户执行,需要时会自动提升权限 71 | 4. 所有密码信息请妥善保管,避免泄露 72 | 73 | -------------------------------------------------------------------------------- /del.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | set ipadd [lindex $argv 0] 3 | set port [lindex $argv 1] 4 | set username [lindex $argv 2] 5 | set userpasswd [lindex $argv 3] 6 | set rootpasswd [lindex $argv 4] 7 | set timeout 10 8 | spawn ssh $username@$ipadd -p $port 9 | expect { 10 | "password" {send "$userpasswd\r";exp_continue} 11 | "*from*" {send "su - root\r";exp_continue} 12 | "*assword*" {send "$rootpasswd\r";exp_continue} 13 | "*]#" {send "rm -rf /tmp/*${ipadd}* /tmp/inuxcheck.sh /tmp/dangerstcpports.dat /tmp/dangersudports.dat\r"} 14 | } 15 | expect eof 16 | 17 | -------------------------------------------------------------------------------- /get.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | set ipadd [lindex $argv 0] 3 | set port [lindex $argv 1] 4 | set username [lindex $argv 2] 5 | set userpasswd [lindex $argv 3] 6 | set timeout 10 7 | spawn scp -P $port $username@$ipadd:/tmp/*${ipadd}* /tmp/ 8 | expect { 9 | "password" {send "$userpasswd\r"} 10 | } 11 | expect eof 12 | -------------------------------------------------------------------------------- /hosts.txt: -------------------------------------------------------------------------------- 1 | 192.168.78.145:22:root:123123:123123 2 | -------------------------------------------------------------------------------- /linuxcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ======================================================== 4 | # 工具名: Linux主机安全检查V2.0 5 | # 作者: 飞鸟 6 | # 版本:Create:201902 V1.0 7 | # Update:202504 V2.0 8 | 9 | # 主要检查流程: 10 | # 1. 基础环境检查:检测系统基本信息 11 | # 2. 网络安全检查:检测网络接口、ARP欺骗、开放端口和网络连接 12 | # 3. 系统安全检查:检测账户安全、启动项、计划任务、路由转发和进程 13 | # 4. 配置安全检查:检测系统安全相关配置 14 | # 5. 用户历史检查:检测用户历史命令 15 | # 6. 文件安全检查:检测文件完整性和已删除打开文件 16 | # 7. 日志安全检查:检测登录活动、dmesg日志和加载的内核模块 17 | # 8. 恶意软件检查:检测恶意软件和系统性能 18 | # 9. 后门检查:检测后门、防火墙配置、反弹Shell和库文件劫持 19 | # 10. 日志备份:备份系统日志文件 20 | 21 | # ======================================================== 22 | 23 | 24 | # 添加全局错误处理 25 | set -e # 遇到错误立即退出 26 | trap 'echo "在第 $LINENO 行发生错误"; exit 1' ERR 27 | 28 | # 定义目录变量 29 | LOG_DIR="/var/log/security_check" 30 | BACKUP_DIR="/var/log/backup" 31 | 32 | # 定义日志文件和危险文件 33 | IPADDR=$(ifconfig -a | grep -w inet | grep -v 127.0.0.1 | awk 'NR==1{print $2}' | cut -d':' -f2) 34 | DATE=$(date +"%Y-%m-%d_%H-%M-%S") 35 | 36 | LOG_FILE="${LOG_DIR}/linux_check_${IPADDR}_${DATE}.log" 37 | DANGER_FILE="${LOG_DIR}/linux_danger_${IPADDR}_${DATE}.log" 38 | BACKUP_FILE="${BACKUP_DIR}/logs_backup_${IPADDR}_${DATE}.zip" 39 | 40 | # 创建日志目录和备份目录 41 | mkdir -p $LOG_DIR 42 | mkdir -p $BACKUP_DIR 43 | 44 | # 添加日志轮转机制 45 | LOG_MAX_SIZE=10M 46 | LOG_BACKUP_COUNT=5 47 | 48 | rotate_log() { 49 | if [ -f "$LOG_FILE" ] && [ $(stat -f%z "$LOG_FILE") -gt $LOG_MAX_SIZE ]; then 50 | for i in $(seq $((LOG_BACKUP_COUNT-1)) -1 1); do 51 | [ -f "${LOG_FILE}.$i" ] && mv "${LOG_FILE}.$i" "${LOG_FILE}.$((i+1))" 52 | done 53 | mv "$LOG_FILE" "${LOG_FILE}.1" 54 | fi 55 | } 56 | 57 | # 定义颜色变量 58 | RED='\033[0;31m' 59 | GREEN='\033[0;32m' 60 | YELLOW='\033[1;33m' 61 | BLUE='\033[0;34m' 62 | PURPLE='\033[0;35m' 63 | NC='\033[0m' # No Color 64 | 65 | # 优化日志函数 66 | log() { 67 | local timestamp=$(date "+%Y-%m-%d %H:%M:%S") 68 | echo -e "【${timestamp}】:$1" | tee -a $LOG_FILE 69 | } 70 | 71 | log_danger() { 72 | local timestamp=$(date "+%Y-%m-%d %H:%M:%S") 73 | echo -e "【${timestamp}】:[危险] $1" | tee -a $DANGER_FILE 74 | } 75 | 76 | log_warning() { 77 | local timestamp=$(date "+%Y-%m-%d %H:%M:%S") 78 | echo -e "【${timestamp}】:[警告] $1" | tee -a $LOG_FILE 79 | } 80 | 81 | log_success() { 82 | local timestamp=$(date "+%Y-%m-%d %H:%M:%S") 83 | echo -e "【${timestamp}】:[正常] $1\n" | tee -a $LOG_FILE 84 | } 85 | 86 | # 修改日志输出函数 87 | log_complete() { 88 | local timestamp=$(date "+%Y-%m-%d %H:%M:%S") 89 | echo -e "【${timestamp}】:$1" | tee -a $LOG_FILE 90 | echo "" | tee -a $LOG_FILE 91 | } 92 | 93 | # 检查是否为 root 用户 94 | if [ "$(whoami)" != "root" ]; then 95 | echo "The security check must use the root account, otherwise some items cannot be checked" 96 | exit 1 97 | fi 98 | 99 | #检测系统基本信息 100 | check_systeminfo() { 101 | local ret=0 102 | { 103 | log "[1] 开始检查系统信息..." 104 | # 检测 IP 地址 105 | log "[1.1] 开始检查IP地址..." 106 | ip_addresses=$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}') 107 | if [ -z "$ip_addresses" ]; then 108 | log "未发现IP地址" 109 | else 110 | log "IP地址列表:" 111 | echo "$ip_addresses" | while IFS= read -r line; do 112 | log " $line" 113 | done 114 | fi 115 | log_complete "IP地址检查完成" 116 | 117 | # 检测操作系统版本 118 | log "[1.2] 开始检查操作系统版本..." 119 | os_version=$(cat /etc/redhat-release) 120 | if [ -z "$os_version" ]; then 121 | log "无法获取操作系统版本" 122 | else 123 | log "操作系统版本: $os_version" 124 | fi 125 | log_complete "操作系统版本检查完成" 126 | } || ret=$? 127 | 128 | if [ $ret -ne 0 ]; then 129 | log_danger "系统信息检查失败,错误代码 $ret" 130 | return $ret 131 | fi 132 | } 133 | 134 | # 检测 ARP 表以及ARP攻击 135 | check_arp_spoofing() { 136 | log "[2] 开始检查ARP欺骗" 137 | log "[2.1] 开始检查ARP表..." 138 | arp_table=$(arp -a) 139 | if [ -z "$arp_table" ]; then 140 | log "未发现ARP表项" 141 | else 142 | log "ARP表内容:" 143 | echo "$arp_table" | while IFS= read -r line; do 144 | log " $line" 145 | done 146 | fi 147 | log_complete "ARP表检查完成" 148 | 149 | # 检测ARP攻击 150 | log "[2.2] 开始检测ARP欺骗..." 151 | arp_entries=$(arp -a | awk '{print $4}' | sort | uniq -c | sort -nr) 152 | if [ -z "$arp_entries" ]; then 153 | log "未发现ARP表项" 154 | else 155 | log "ARP表项统计:" 156 | echo "$arp_entries" | while IFS= read -r line; do 157 | count=$(echo $line | awk '{print $1}') 158 | mac=$(echo $line | awk '{print $2}') 159 | if [ "$count" -gt 1 ]; then 160 | log "发现潜在的ARP欺骗: MAC地址 $mac 出现 $count 次" 161 | else 162 | log " $line" 163 | fi 164 | done 165 | fi 166 | log_complete "ARP欺骗检测完成" 167 | } 168 | 169 | 170 | check_open_port() { 171 | log "[3] 开始检查开放端口" 172 | # 检查开放的TCP端口和进程 173 | log "[3.1] 检查开放的TCP端口和对应进程..." 174 | tcpopen=$(netstat -anltp | grep LISTEN | awk '{print $4,$7}' | sed 's/:/ /g' | awk '{print $2,$3}' | sed 's/\// /g' | awk '{printf "%-20s%-10s\n", $1, $NF}' | sort -n | uniq) 175 | if [ -n "$tcpopen" ]; then 176 | log "服务器开放的TCP端口和对应进程如下:" 177 | echo "$tcpopen" | while IFS= read -r line; do 178 | log " $line" 179 | done 180 | fi 181 | log_complete "系统未开放TCP端口" 182 | 183 | # 检查对外开放的TCP端口 184 | log "[3.2] 开始检查对外开放的TCP端口" 185 | tcpports=$(netstat -anltp | grep LISTEN | awk '{print $4}' | egrep "(0.0.0.0|:::)" | awk -F: '{print $NF}' | sort -n | uniq) 186 | if [ -n "$tcpports" ]; then 187 | log "以下TCP端口对外开放:" 188 | for port in $tcpports; do 189 | log " $port" 190 | done 191 | fi 192 | log_complete "没有对外开放的TCP端口" 193 | 194 | # 检测潜在危险的tcp端口 195 | log "[3.3] 开始检测潜在危险的TCP端口" 196 | dangerous_ports="21 22 23 25 135 137 138 139 143 3389 8080" 197 | open_ports=$(netstat -anltp | grep LISTEN | awk '{print $4}' | egrep "(0.0.0.0|:::)" | awk -F: '{print $NF}' | sort -n | uniq) 198 | if [ -n "$open_ports" ]; then 199 | for port in $open_ports; do 200 | if [[ " ${dangerous_ports[@]} " =~ " ${port} " ]]; then 201 | log "危险的TCP端口 $port 对外开放" 202 | log_danger "危险的TCP端口 $port 对外开放" 203 | fi 204 | done 205 | else 206 | log "未发现潜在危险的TCP端口" 207 | fi 208 | log_complete "潜在危险的TCP端口检查完成" 209 | 210 | # 检查开放的UDP端口 211 | log "[3.4] 开始检查开放的UDP端口和对应进程..." 212 | udpopen=$( netstat -anlup | grep -v "udp6"| awk '{print $4,$NF}' | grep : | sed 's/:/ /g' | awk '{print $2,$3}' | sed 's/\// /g' | awk '{printf "%-20s%-10s\n", $1, $NF}' | sort -n | uniq) 213 | if [ -n "$udpopen" ]; then 214 | log "服务器开放的UDP端口和对应进程如下:" 215 | echo "$udpopen" | while IFS= read -r line; do 216 | log " $line" 217 | done 218 | fi 219 | log_complete "检查完成" 220 | 221 | 222 | 223 | # 检测潜在危险的UDP端口 224 | log "[3.5] 开始检测潜在危险的UDP端口" 225 | dangerous_ports="137 138 161 162 500 1900 5353" 226 | open_ports=$(netstat -anlup | awk '{print $4}' | egrep "(0.0.0.0|:::)" | awk -F: '{print $NF}' | sort -n | uniq) 227 | if [ -n "$open_ports" ]; then 228 | for port in $open_ports; do 229 | if [[ " ${dangerous_ports[@]} " =~ " ${port} " ]]; then 230 | log_danger "[3.6] 危险的UDP端口 $port 对外开放" 231 | fi 232 | done 233 | fi 234 | log_complete "危险的UDP端口检查完成" 235 | } 236 | 237 | 238 | # 检测活动的网络连接 239 | check_connections() { 240 | log "[4] 检查活动的网络连接..." 241 | active_connections=$(netstat -anp | grep -E 'tcp|udp' | grep ESTABLISHED) 242 | if [ -n "$active_connections" ]; then 243 | log "服务器存在以下活动的网络连接:" 244 | echo "$active_connections" | while IFS= read -r line; do 245 | log " $line" 246 | done 247 | fi 248 | log_complete "检查完成" 249 | } 250 | 251 | 252 | # 查询威胁情报 253 | 254 | # API 密钥 255 | APIKEY="" 256 | 257 | check_ip_threatbook() { 258 | log "[5] 开始检查IP威胁情报" 259 | ips=$(netstat -anltp | awk '{print $5}' | sed 's/:.*//' | grep -E '[0-9]' | grep -vwE "0.0.0.0|127.0.0.1" | uniq) 260 | for ip in $ips; do 261 | log "正在查询IP威胁情报: $ip" 262 | response=$(curl -s -X GET "https://api.threatbook.cn/v3/scene/ip_reputation?apikey=${APIKEY}&resource=$ip") 263 | formatted_response=$(echo "$response" | jq .) 264 | log "IP $ip 的威胁情报结果:" 265 | log "$formatted_response" 266 | log_complete "IP威胁情报检查完成" 267 | done 268 | } 269 | 270 | 271 | # 检测网卡基本信息 272 | check_interface() { 273 | log "[6] 开始检查网卡信息" 274 | log "[6.1] 检查网卡基本信息..." 275 | interfaces=$(ip link show | grep -oP '^\d+: \K\w+') 276 | if [ -n "$interfaces" ]; then 277 | for interface in $interfaces; do 278 | log "网卡: $interface" 279 | log " IP信息:" 280 | ip addr show $interface 2>/dev/null | while read -r line; do 281 | log " $line" 282 | done 283 | 284 | # 获取默认网关 285 | default_gateway=$(ip route | grep default | grep -oP 'via \K\S+' || echo "未找到") 286 | log " 默认网关: $default_gateway" 287 | 288 | # 获取 DNS 服务器 289 | if [ -f "/etc/resolv.conf" ]; then 290 | dns_servers=$(grep nameserver /etc/resolv.conf | awk '{print $2}') 291 | log " DNS服务器: $dns_servers" 292 | else 293 | log " 未找到DNS配置文件" 294 | fi 295 | 296 | 297 | # 检测网卡是否处于混杂模式 298 | if ip link show $interface | grep -q PROMISC; then 299 | log_danger "网卡 $interface 处于混杂模式" 300 | else 301 | log_success "网卡 $interface 未处于混杂模式" 302 | fi 303 | 304 | # 检测网卡是否处于监听模式 305 | if command -v iw >/dev/null 2>&1; then 306 | if iw dev $interface info 2>/dev/null | grep -q "type monitor"; then 307 | log_danger "网卡 $interface 处于监听模式" 308 | else 309 | log_success "网卡 $interface 未处于监听模式" 310 | fi 311 | else 312 | log "未找到iw命令,跳过监听模式检查" 313 | fi 314 | 315 | # 获取传输速率 316 | if command -v ethtool >/dev/null 2>&1; then 317 | speed=$(ethtool $interface 2>/dev/null | grep -oP 'Speed: \K\S+' || echo "未知") 318 | log " 传输速率: $speed" 319 | else 320 | log "未找到ethtool命令,跳过速率检查" 321 | fi 322 | 323 | # 获取错误计数器 324 | if command -v ethtool >/dev/null 2>&1; then 325 | errors=$(ethtool -S $interface 2>/dev/null | grep -E 'rx_errors|tx_errors|rx_dropped|tx_dropped' || echo "未发现错误") 326 | log " 错误计数器:" 327 | echo "$errors" | while read -r line; do 328 | log " $line" 329 | done 330 | fi 331 | done 332 | else 333 | log_warning "未发现网卡" 334 | fi 335 | 336 | log_complete "网卡检查完成" 337 | } 338 | 339 | 340 | check_account() { 341 | log "[7] 开始检查账户信息" 342 | # 检查空口令用户 343 | log "[7.1] 开始检查空口令用户..." 344 | empty_password_users=$(sudo awk -F: '($2 == "") {print $1}' /etc/shadow) 345 | if [ -z "$empty_password_users" ]; then 346 | log "未发现空口令用户" 347 | else 348 | log_danger "发现空口令用户: $empty_password_users" 349 | fi 350 | log_complete "空口令用户检查完成" 351 | 352 | # 检查空口令且可以登录的用户 353 | log "[7.2] 开始检查空口令且可登录的用户..." 354 | empty_password_users=$(sudo awk -F: '($2 == "") {print $1}' /etc/shadow) 355 | if [ -z "$empty_password_users" ]; then 356 | log "未发现空口令用户" 357 | else 358 | log "发现空口令用户:" 359 | echo "$empty_password_users" | while IFS= read -r user; do 360 | login_shell=$(grep "^$user:" /etc/passwd | cut -d: -f7) 361 | if [ "$login_shell" != "/sbin/nologin" ] && [ "$login_shell" != "/usr/sbin/nologin" ]; then 362 | log_danger "发现空口令且可登录的用户: $user,登录Shell: $login_shell" 363 | else 364 | log "发现空口令但无法登录的用户: $user,登录Shell: $login_shell" 365 | fi 366 | done 367 | fi 368 | log_complete "空口令且可登录用户检查完成" 369 | 370 | # 检查超级用户 371 | log "[7.3] 开始检查超级用户..." 372 | superusers=$(awk -F: '($3 == 0) && ($1 != "root") {print $1}' /etc/passwd) 373 | if [ -z "$superusers" ]; then 374 | log "未发现超级用户" 375 | else 376 | log_danger "发现超级用户: $superusers" 377 | fi 378 | log_complete "超级用户检查完成" 379 | 380 | # 检查克隆账号 381 | log "[7.4] 开始检查克隆账号..." 382 | log "[7.4.1] 检查具有相同用户名的账号..." 383 | duplicate_usernames=$(cut -d: -f1 /etc/passwd | sort | uniq -d) 384 | if [ -z "$duplicate_usernames" ]; then 385 | log "未发现具有相同用户名的账号" 386 | else 387 | log_danger "发现具有相同用户名的账号: $duplicate_usernames" 388 | fi 389 | log_complete "克隆账号检查完成" 390 | 391 | log "[7.4.2] 检查具有相同UID的账号..." 392 | duplicate_uids=$(cut -d: -f3 /etc/passwd | sort | uniq -d) 393 | if [ -z "$duplicate_uids" ]; then 394 | log "未发现具有相同UID的账号" 395 | else 396 | log_danger "发现具有相同UID的账号: $duplicate_uids" 397 | for uid in $duplicate_uids; do 398 | log_danger "UID为 $uid 的账号: $(grep ":$uid:" /etc/passwd)" 399 | done 400 | fi 401 | log_complete "相同UID的账号检查完成" 402 | 403 | # 检查可登录用户 404 | log "[7.5] 开始检测可登录用户..." 405 | valid_shells=$(getent passwd | awk -F: '($7 !~ /^(\/usr)?\/sbin\/nologin$|\/bin\/false$|\/usr\/lib\/gdm3\/gdm\-x\-session$/) {print $1}') 406 | while IFS= read -r user; do 407 | password_entry=$(sudo getent shadow "$user") 408 | if [[ -n "$password_entry" ]]; then 409 | password=$(echo "$password_entry" | cut -d: -f2) 410 | if ! echo "$password" | grep -qE '^\!|^\*'; then 411 | log "用户 $user 是一个有效的可登录用户" 412 | fi 413 | fi 414 | done <<< "$valid_shells" 415 | log_complete "可登录用户检测完成" 416 | 417 | # 检查非系统用户 418 | log "[7.6] 开始检查非系统用户..." 419 | non_system_users=$(awk -F: '($3 >= 1000) {print $1, $3, $7}' /etc/passwd) 420 | if [ -z "$non_system_users" ]; then 421 | log "未发现非系统用户" 422 | else 423 | log "发现以下非系统用户可以登录:" 424 | echo "$non_system_users" | while IFS=' ' read -r user uid shell; do 425 | log "用户: $user" 426 | done 427 | fi 428 | log_complete "非系统用户检查完成" 429 | } 430 | 431 | 432 | # 检测系统启动项 433 | check_startup() { 434 | log "[8] 开始检查系统启动项" 435 | log "[8.1] 检查系统服务..." 436 | 437 | # 检查 Systemd 服务 438 | systemd_services=$(systemctl list-unit-files --state=enabled --type=service | awk 'NR>1 {print $1}' ) 439 | if [ -n "$systemd_services" ]; then 440 | log "已启用的Systemd服务:" 441 | echo "$systemd_services" | while IFS= read -r line; do 442 | log " $line" 443 | done 444 | else 445 | log "未发现已启用的Systemd服务" 446 | fi 447 | log_complete "检查完成" 448 | 449 | 450 | # 检查 /etc/rc.local 451 | log "[8.2] 检查/etc/rc.local文件..." 452 | if [ -f /etc/rc.local ]; then 453 | rc_local_content=$(cat /etc/rc.local) 454 | if [ -n "$rc_local_content" ]; then 455 | log "/etc/rc.local文件内容:" 456 | echo "$rc_local_content" | while IFS= read -r line; do 457 | log " $line" 458 | done 459 | else 460 | log "/etc/rc.local文件为空" 461 | fi 462 | else 463 | log "/etc/rc.local文件不存在" 464 | fi 465 | log_complete "/etc/rc.local文件检查完成" 466 | 467 | # 检查 /etc/init.d 目录下的启动脚本 468 | log "[8.3] 检查/etc/init.d目录..." 469 | initd_scripts=$(ls -1 /etc/init.d/) 470 | if [ -n "$initd_scripts" ]; then 471 | log "/etc/init.d目录下的脚本:" 472 | for script in $initd_scripts; do 473 | if [ -x /etc/init.d/$script ]; then 474 | log " $script" 475 | fi 476 | done 477 | else 478 | log "/etc/init.d目录下没有脚本" 479 | fi 480 | log_complete "/etc/init.d目录检查完成" 481 | 482 | # 检查 chkconfig 管理的启动项 483 | log "[8.4] 检查chkconfig管理的启动项..." 484 | if command -v chkconfig &> /dev/null; then 485 | chkconfig_items=$(chkconfig --list | grep -E ":on|启用|开" | awk '{print $1}' ) 486 | if [ -n "$chkconfig_items" ]; then 487 | log "chkconfig管理的启动项:" 488 | echo "$chkconfig_items" | while IFS= read -r line; do 489 | log " $line" 490 | done 491 | else 492 | log "未发现chkconfig管理的启动项" 493 | fi 494 | else 495 | log "未找到chkconfig命令" 496 | fi 497 | log_complete "系统启动项检查完成" 498 | } 499 | 500 | 501 | # 检测 Crontab 任务 502 | check_crontab() { 503 | log "[9] 开始检查计划任务" 504 | # 检测用户级别的 Crontab 任务 505 | log "[9.1] 检查用户计划任务..." 506 | 507 | # 获取所有用户 508 | users=$(cut -d: -f1 /etc/passwd) 509 | # 检查每个用户的计划任务 510 | for user in $users; do 511 | output=$(sudo crontab -l -u $user 2>&1) 512 | if [[ $? -eq 0 ]] && ! echo "$output" | grep -q "no crontab for"; then 513 | log "用户 $user 的计划任务:" 514 | log "$output" 515 | fi 516 | done 517 | log_complete "用户计划任务检查完成" 518 | 519 | # 检测系统级别的定时任务 520 | log "[9.2] 检查系统级计划任务..." 521 | 522 | # 检查 /etc/crontab 523 | if [ -f /etc/crontab ]; then 524 | log "/etc/crontab文件内容:" 525 | cat /etc/crontab | while IFS= read -r line; do 526 | log " $line" 527 | done 528 | else 529 | log "/etc/crontab文件不存在" 530 | fi 531 | 532 | # 检查 /etc/cron.d 目录 533 | log "[9.3] 检查/etc/cron.d目录..." 534 | if [ -d /etc/cron.d ]; then 535 | log "/etc/cron.d目录内容:" 536 | for file in /etc/cron.d/*; do 537 | if [ -f "$file" ]; then 538 | log " 文件: $file" 539 | cat "$file" | while IFS= read -r line; do 540 | log " $line" 541 | done 542 | fi 543 | done 544 | else 545 | log "/etc/cron.d目录不存在" 546 | fi 547 | 548 | log "[9.4] 检查定时任务目录..." 549 | # 检查 /etc/cron.daily, /etc/cron.hourly, /etc/cron.monthly, /etc/cron.weekly 550 | for dir in /etc/cron.{daily,hourly,monthly,weekly}; do 551 | if [ -d "$dir" ]; then 552 | log "$dir" 553 | for file in "$dir"/*; do 554 | if [ -f "$file" ]; then 555 | log " $file" 556 | fi 557 | done 558 | else 559 | log "目录 $dir 不存在" 560 | fi 561 | done 562 | log_complete "计划任务检查完成" 563 | } 564 | 565 | 566 | # 检测路由和转发 567 | check_routing_forwarded() { 568 | log "[10] 开始检查路由和转发" 569 | log "[10.1] 检查路由表..." 570 | # 检测路由 571 | routing_table=$(route -n) 572 | if [ -n "$routing_table" ]; then 573 | log "路由表条目:" 574 | echo "$routing_table" | while IFS= read -r line; do 575 | log " $line" 576 | done 577 | else 578 | log "未发现路由表条目" 579 | fi 580 | log_complete "路由表检查完成" 581 | # 检测 IP 转发设置 582 | log "[10.2] 检查IPv4转发设置..." 583 | # 检查 IPv4 转发 584 | ipv4_forward=$(sysctl net.ipv4.ip_forward | awk '{print $3}') 585 | if [ "$ipv4_forward" -eq 1 ]; then 586 | log "IPv4转发已启用" 587 | else 588 | log "IPv4转发已禁用" 589 | fi 590 | log_complete "IPv4转发设置检查完成" 591 | 592 | # 检查 IPv6 转发 593 | log "[10.3] 检查IPv6转发设置..." 594 | ipv6_forward=$(sysctl net.ipv6.conf.all.forwarding | awk '{print $3}') 595 | if [ "$ipv6_forward" -eq 1 ]; then 596 | log "IPv6转发已启用" 597 | else 598 | log "IPv6转发已禁用" 599 | fi 600 | log_complete "IPv6转发设置检查完成" 601 | } 602 | 603 | 604 | # 检测进程 605 | check_processes() { 606 | log "[11] 开始检查进程" 607 | log "[11.1] 检查所有进程..." 608 | # 获取所有进程信息 609 | processes=$(ps aux) 610 | if [ -n "$processes" ]; then 611 | log "所有进程:" 612 | echo "$processes" | while IFS= read -r line; do 613 | log " $line" 614 | done 615 | else 616 | log "未发现进程" 617 | fi 618 | log_complete "所有进程检查完成" 619 | 620 | # 检测高资源消耗的进程 621 | log "[11.2] 检查高资源消耗的进程..." 622 | # 获取CPU和内存使用率前10的进程 623 | high_cpu=$(ps aux --sort=-%cpu | head -n 11) 624 | high_mem=$(ps aux --sort=-%mem | head -n 11) 625 | 626 | if [ -n "$high_cpu" ]; then 627 | log "高CPU使用率的进程:" 628 | echo "$high_cpu" | while IFS= read -r line; do 629 | log " $line" 630 | done 631 | else 632 | log "未发现高CPU使用率的进程" 633 | fi 634 | log_complete "高CPU使用率的进程检查完成" 635 | 636 | if [ -n "$high_mem" ]; then 637 | log "高内存使用率的进程:" 638 | echo "$high_mem" | while IFS= read -r line; do 639 | log " $line" 640 | done 641 | else 642 | log "未发现高内存使用率的进程" 643 | fi 644 | log_complete "高内存使用率的进程检查完成" 645 | 646 | # 检测隐藏进程 647 | log "[11.3] 检查隐藏进程..." 648 | 649 | # 检查 /proc 目录下是否有隐藏的 PID 650 | hidden_pids=$(ls -l /proc/ | grep -oP '^\d+' | sort -n | uniq) 651 | if [ -n "$hidden_pids" ]; then 652 | for pid in $hidden_pids; do 653 | if ! ps -p $pid > /dev/null 2>&1; then 654 | log_danger "发现隐藏进程: PID $pid" 655 | fi 656 | done 657 | else 658 | log "未发现隐藏进程" 659 | fi 660 | log_complete "隐藏进程检查完成" 661 | } 662 | 663 | 664 | 665 | # 检测重要的文件和配置 666 | check_config() { 667 | 668 | log "[12] 开始检查重要的文件和配置" 669 | # 检测 hosts 文件 670 | log "[12.1] 检查/etc/hosts文件..." 671 | 672 | if [ -f /etc/hosts ]; then 673 | log "/etc/hosts文件内容:" 674 | cat /etc/hosts | while IFS= read -r line; do 675 | log " $line" 676 | done 677 | else 678 | log "/etc/hosts文件不存在" 679 | fi 680 | log_complete "hosts文件检查完成" 681 | 682 | # 检测 DNS 配置 683 | log "[12.2] 检查DNS配置..." 684 | 685 | if [ -f /etc/resolv.conf ]; then 686 | log "/etc/resolv.conf文件内容:" 687 | cat /etc/resolv.conf | while IFS= read -r line; do 688 | log " $line" 689 | done 690 | else 691 | log "/etc/resolv.conf文件不存在" 692 | fi 693 | log_complete "DNS配置检查完成" 694 | # 检测 Nginx 配置文件 695 | log "[12.3] 检查Nginx配置文件..." 696 | #检查是否加载了第三方.so文件 697 | load_modules=$(grep -i 'load_module' /etc/nginx/nginx.conf) 698 | if [ -n "$load_modules" ]; then 699 | log "已加载第三方.so文件:" 700 | echo "$load_modules" | while IFS= read -r module; do 701 | log " $module" 702 | done 703 | else 704 | log "未加载第三方.so文件" 705 | fi 706 | log_complete "Nginx配置文件检查完成" 707 | 708 | # 检查 proxy_pass,以检测可能存在的hosts碰撞攻击 709 | log "[12.4]开始检查proxy_pass" 710 | proxy_pass_lines=$(grep -i 'proxy_pass' /etc/nginx/nginx.conf) 711 | 712 | if [ -n "$proxy_pass_lines" ]; then 713 | log "[*] proxy_pass directives found in the configuration:" 714 | echo "$proxy_pass_lines" | while IFS= read -r line; do 715 | log " $line" 716 | done 717 | log "[*] WARNING: proxy_pass directives are present. This may indicate potential security issues." 718 | else 719 | log "[*] 配置文件中未发现 proxy_passs配置" 720 | fi 721 | log_complete "Nginx配置文件检查完成" 722 | 723 | # 检测 SSH 公私钥文件 724 | log "[12.5] 开始检查SSH key 文件....." 725 | 726 | ssh_dir="/root/.ssh" 727 | if [ -d $ssh_dir ]; then 728 | log "[*] SSH directory: $ssh_dir" 729 | 730 | # 检查公钥文件 731 | if [ -f $ssh_dir/id_rsa.pub ]; then 732 | log "[*] Public key file: $ssh_dir/id_rsa.pub" 733 | cat $ssh_dir/id_rsa.pub | while IFS= read -r line; do 734 | log " $line" 735 | done 736 | else 737 | log "[*] Public key file not found at $ssh_dir/id_rsa.pub." 738 | fi 739 | log_complete "SSH公钥文件检查完成" 740 | 741 | # 检查私钥文件 742 | if [ -f $ssh_dir/id_rsa ]; then 743 | log "[*] Private key file: $ssh_dir/id_rsa" 744 | else 745 | log "[*] Private key file not found at $ssh_dir/id_rsa." 746 | fi 747 | else 748 | log "[!!!] SSH目录未发现 $ssh_dir." 749 | fi 750 | log_complete "SSH公私钥文件检查完成" 751 | 752 | 753 | # 检测 SSH 配置文件 754 | log "[12.6] 开始检查ssh_config配置文件" 755 | # 检查是否允许空口令用户 756 | 757 | allow_empty_password=$(grep -i '^PermitEmptyPasswords' /etc/ssh/sshd_config | awk '{print $2}') 758 | if [ "$allow_empty_password" == "yes" ]; then 759 | log "WARNING: PermitEmptyPasswords is set to yes. This allows empty password authentication." 760 | else 761 | log "PermitEmptyPasswords未配置." 762 | fi 763 | log_complete "SSH配置文件检查完成" 764 | 765 | # 检查是否禁止 root 登录 766 | log "[12.7] 开始检查是否禁止 root 登录" 767 | if [[ "$line" =~ ^PermitRootLogin\ no$ ]]; then 768 | log "PermitRootLogin 未设置" 769 | elif [[ "$line" =~ ^PermitRootLogin\ yes$ ]]; then 770 | log_danger "PermitRootLogin配置了" 771 | fi 772 | log_complete "检查完成" 773 | 774 | # 检查是否启用公钥认证 775 | log "[12.8] 开始检查是否启用公钥认证" 776 | if [[ "$line" =~ ^PubkeyAuthentication\ yes$ ]]; then 777 | log "PubkeyAuthentication 未配置." 778 | elif [[ "$line" =~ ^PubkeyAuthentication\ no$ ]]; then 779 | log "PubkeyAuthentication 已配置." 780 | fi 781 | log_complete "是否启用公钥认证检查完成" 782 | 783 | # 检查是否启用 X11 转发 784 | log "[12.9] 开始检查是否启用 X11 转发" 785 | if [[ "$line" =~ ^X11Forwarding\ yes$ ]]; then 786 | log "X11Forwarding 未配置" 787 | elif [[ "$line" =~ ^X11Forwarding\ no$ ]]; then 788 | log "X11Forwarding 已配置." 789 | fi 790 | log_complete "是否启用 X11 转发检查完成" 791 | 792 | # 检查是否启用 AgentForwarding 793 | log "[12.10] 开始检查是否启用 AgentForwarding" 794 | if [[ "$line" =~ ^AllowAgentForwarding\ yes$ ]]; then 795 | log "AllowAgentForwarding 未配置." 796 | elif [[ "$line" =~ ^AllowAgentForwarding\ no$ ]]; then 797 | log "AllowAgentForwarding 已配置." 798 | fi 799 | log_complete " AgentForwarding检查完成" 800 | 801 | # 检测环境变量配置 802 | log "【12.11】开始检查环境变量" 803 | env_files=("/etc/profile" "/etc/bashrc" "~/.bashrc") 804 | for env_file in "${env_files[@]}"; do 805 | if [ -f $env_file ]; then 806 | log "发现环境变量" 807 | cat $env_file | while IFS= read -r line; do 808 | log " $line" 809 | done 810 | else 811 | log "环境变量未发现" 812 | fi 813 | done 814 | log_complete "环境变量检查完成 " 815 | } 816 | 817 | 818 | # 检测用户的 history 文件 819 | log "[13] 开始检查用户的历史命令..." 820 | check_user_history() { 821 | local user=$1 822 | local home_dir=$(getent passwd "$user" | cut -d: -f6) 823 | local history_file="$home_dir/.bash_history" 824 | 825 | if [ -f "$history_file" ]; then 826 | log "检查用户 $user 的历史命令文件: $history_file" 827 | 828 | # 读取历史命令 829 | while IFS= read -r command; do 830 | log " $command" 831 | 832 | # 检查恶意命令 833 | if [[ "$command" =~ ^sudo.* ]] || \ 834 | [[ "$command" =~ ^rm.* ]] || \ 835 | [[ "$command" =~ ^wget.* ]] || \ 836 | [[ "$command" =~ ^curl.* ]] || \ 837 | [[ "$command" =~ ^nc.* ]] || \ 838 | [[ "$command" =~ ^bash.* ]] || \ 839 | [[ "$command" =~ ^python.* ]] || \ 840 | [[ "$command" =~ ^perl.* ]] || \ 841 | [[ "$command" =~ ^telnet.* ]] || \ 842 | [[ "$command" =~ ^useradd.* ]] || \ 843 | [[ "$command" =~ ^userdel.* ]] || \ 844 | [[ "$command" =~ ^passwd.* ]] || \ 845 | [[ "$command" =~ ^nmap.* ]] || \ 846 | [[ "$command" =~ ^ssh.* ]] || \ 847 | [[ "$command" =~ ^scp.* ]] || \ 848 | [[ "$command" =~ ^ftp.* ]] || \ 849 | [[ "$command" =~ ^tftp.* ]] || \ 850 | [[ "$command" =~ ^openssl.* ]] || \ 851 | [[ "$command" =~ ^netcat.* ]]; then 852 | log_danger "发现用户 $user 的潜在恶意命令: $command" 853 | fi 854 | done < "$history_file" 855 | else 856 | log_complete "用户 $user 未发现历史命令" 857 | fi 858 | } 859 | 860 | # 检测所有用户的 history 文件 861 | check_all_user_histories() { 862 | log "[14] 开始检查所有用户的历史命令..." 863 | 864 | # 获取所有用户 865 | users=$(cut -d: -f1 /etc/passwd) 866 | 867 | for user in $users; do 868 | check_user_history "$user" 869 | done 870 | 871 | log "所有用户的历史命令检查完成" 872 | } 873 | 874 | # 定义关键文件列表 875 | KEY_FILES=( 876 | "/usr/bin/awk" 877 | "/usr/bin/bash" 878 | "/usr/bin/cat" 879 | "/usr/bin/chattr" 880 | "/usr/bin/chmod" 881 | "/usr/bin/chown" 882 | "/usr/bin/cp" 883 | "/usr/bin/csh" 884 | "/usr/bin/curl" 885 | "/usr/bin/cut" 886 | "/usr/bin/date" 887 | "/usr/bin/df" 888 | "/usr/bin/diff" 889 | "/usr/bin/dirname" 890 | "/usr/bin/dmesg" 891 | "/usr/bin/du" 892 | "/usr/bin/echo" 893 | "/usr/bin/ed" 894 | "/usr/bin/egrep" 895 | "/usr/bin/env" 896 | "/usr/bin/fgrep" 897 | "/usr/bin/file" 898 | "/usr/bin/find" 899 | "/usr/bin/gawk" 900 | "/usr/bin/GET" 901 | "/usr/bin/grep" 902 | "/usr/bin/groups" 903 | "/usr/bin/head" 904 | "/usr/bin/id" 905 | "/usr/bin/ipcs" 906 | "/usr/bin/kill" 907 | "/usr/bin/killall" 908 | "/usr/bin/kmod" 909 | "/usr/bin/last" 910 | "/usr/bin/lastlog" 911 | "/usr/bin/ldd" 912 | "/usr/bin/less" 913 | "/usr/bin/locate" 914 | "/usr/bin/logger" 915 | "/usr/bin/login" 916 | "/usr/bin/ls" 917 | "/usr/bin/lsattr" 918 | "/usr/bin/lynx" 919 | "/usr/bin/mail" 920 | "/usr/bin/mailx" 921 | "/usr/bin/md5sum" 922 | "/usr/bin/mktemp" 923 | "/usr/bin/more" 924 | "/usr/bin/mount" 925 | "/usr/bin/mv" 926 | "/usr/bin/netstat" 927 | "/usr/bin/newgrp" 928 | "/usr/bin/numfmt" 929 | "/usr/bin/passwd" 930 | "/usr/bin/perl" 931 | "/usr/bin/pgrep" 932 | "/usr/bin/ping" 933 | "/usr/bin/pkill" 934 | "/usr/bin/ps" 935 | "/usr/bin/pstree" 936 | "/usr/bin/pwd" 937 | "/usr/bin/readlink" 938 | "/usr/bin/runcon" 939 | "/usr/bin/sed" 940 | "/usr/bin/sh" 941 | "/usr/bin/sha1sum" 942 | "/usr/bin/sha224sum" 943 | "/usr/bin/sha256sum" 944 | "/usr/bin/sha384sum" 945 | "/usr/bin/sha512sum" 946 | "/usr/bin/size" 947 | "/usr/bin/sort" 948 | "/usr/bin/ssh" 949 | "/usr/bin/stat" 950 | "/usr/bin/strace" 951 | "/usr/bin/strings" 952 | "/usr/bin/su" 953 | "/usr/bin/sudo" 954 | "/usr/bin/systemctl" 955 | "/usr/bin/tail" 956 | "/usr/bin/tcsh" 957 | "/usr/bin/telnet" 958 | "/usr/bin/test" 959 | "/usr/bin/top" 960 | "/usr/bin/touch" 961 | "/usr/bin/tr" 962 | "/usr/bin/uname" 963 | "/usr/bin/uniq" 964 | "/usr/bin/users" 965 | "/usr/bin/vmstat" 966 | "/usr/bin/w" 967 | "/usr/bin/watch" 968 | "/usr/bin/wc" 969 | "/usr/bin/wget" 970 | "/usr/bin/whatis" 971 | "/usr/bin/whereis" 972 | "/usr/bin/which" 973 | "/usr/bin/who" 974 | "/usr/bin/whoami" 975 | "/usr/lib/systemd/s" 976 | "/usr/local/bin/rkh" 977 | "/usr/sbin/adduser" 978 | "/usr/sbin/chkconfi" 979 | "/usr/sbin/chroot" 980 | "/usr/sbin/depmod" 981 | "/usr/sbin/fsck" 982 | "/usr/sbin/fuser" 983 | "/usr/sbin/groupadd" 984 | "/usr/sbin/groupdel" 985 | "/usr/sbin/groupmod" 986 | "/usr/sbin/grpck" 987 | "/usr/sbin/ifconfig" 988 | "/usr/sbin/ifdown" 989 | "/usr/sbin/ifup" 990 | "/usr/sbin/init" 991 | "/usr/sbin/insmod" 992 | "/usr/sbin/ip" 993 | "/usr/sbin/lsmod" 994 | "/usr/sbin/lsof" 995 | "/usr/sbin/modinfo" 996 | "/usr/sbin/modprobe" 997 | "/usr/sbin/nologin" 998 | "/usr/sbin/pwck" 999 | "/usr/sbin/rmmod" 1000 | "/usr/sbin/route" 1001 | "/usr/sbin/rsyslogd" 1002 | "/usr/sbin/runlevel" 1003 | "/usr/sbin/sestatus" 1004 | "/usr/sbin/sshd" 1005 | "/usr/sbin/sulogin" 1006 | "/usr/sbin/sysctl" 1007 | "/usr/sbin/tcpd" 1008 | "/usr/sbin/useradd" 1009 | "/usr/sbin/userdel" 1010 | "/usr/sbin/usermod" 1011 | "/usr/sbin/vipw" 1012 | ) 1013 | 1014 | # 利用md5sum检测文件完整性 1015 | check_filemd5() { 1016 | log "[15] 开始使用 md5sum 检查关键文件完整性..." 1017 | 1018 | # 遍历每个关键文件并验证其完整性 1019 | log "[15.1] 开始检查文件 MD5" 1020 | for file in "${KEY_FILES[@]}"; do 1021 | if [ -f "$file" ]; then 1022 | current_md5=$(md5sum "$file" | awk '{print $1}') 1023 | log "$file MD5: $current_md5" 1024 | fi 1025 | done 1026 | log_complete "关键文件完整性检查完成" 1027 | } 1028 | 1029 | 1030 | # 检测已删除但仍被打开的文件 1031 | check_deleted_open_files() { 1032 | log "[16] 检测已删除但仍被打开的文件..." 1033 | deleted_files=$(find /proc/ -name exe 2>/dev/null | xargs ls -altr 2>/dev/null | grep deleted) 1034 | 1035 | if [ -z "$deleted_files" ]; then 1036 | log "未发现已删除但仍被打开的文件" 1037 | else 1038 | log "发现已删除但仍被打开的文件:" 1039 | echo "$deleted_files" | while read -r line; do 1040 | log "$line" 1041 | pid=$(echo "$line" | awk '{print $9}' | sed 's/\/proc\///' | sed 's/\/exe//') 1042 | 1043 | # 保存 /proc//exe 文件 1044 | exe_file="/proc/$pid/exe" 1045 | if [ -f "$exe_file" ]; then 1046 | target_file="${LOG_DIR}/exe_${pid}_${DATE}" 1047 | cat "$exe_file" >> "$target_file" 1048 | else 1049 | log "文件 $exe_file 不存在" 1050 | fi 1051 | done 1052 | fi 1053 | log_complete "检查完成" 1054 | } 1055 | 1056 | 1057 | # 检测/var/log中的登录成功、登录失败、本机登录和新增用户 1058 | check_login_activity() { 1059 | log "[17] 开始检查登录活动..." 1060 | 1061 | # 检测登录成功 1062 | log "[17.1] 检查成功登录记录..." 1063 | successful_logins=$(grep 'Accepted' /var/log/secure) 1064 | if [ -n "$successful_logins" ]; then 1065 | log "发现成功登录记录:" 1066 | echo "$successful_logins" | while IFS= read -r line; do 1067 | log " $line" 1068 | done 1069 | else 1070 | log "未发现成功登录记录" 1071 | fi 1072 | log_complete "检查完成" 1073 | 1074 | # 检测登录失败 1075 | log "[17.2] 检查失败登录记录..." 1076 | failed_logins=$(grep 'Failed' /var/log/secure) 1077 | if [ -n "$failed_logins" ]; then 1078 | log "发现失败登录记录:" 1079 | echo "$failed_logins" | while IFS= read -r line; do 1080 | log " $line" 1081 | done 1082 | else 1083 | log "未发现失败登录记录" 1084 | fi 1085 | log_complete "检查完成" 1086 | 1087 | # 检测本机登录 1088 | log "[17.3] 检查本地登录记录..." 1089 | local_logins=$(last | grep 'tty') 1090 | if [ -n "$local_logins" ]; then 1091 | log "发现本地登录记录:" 1092 | echo "$local_logins" | while IFS= read -r line; do 1093 | log " $line" 1094 | done 1095 | else 1096 | log "未发现本地登录记录" 1097 | fi 1098 | log_complete "检查完成" 1099 | 1100 | # 检测新增用户 1101 | log "[17.4] 检查新增用户..." 1102 | new_users=$(grep 'useradd' /var/log/secure) 1103 | if [ -n "$new_users" ]; then 1104 | log "发现新增用户:" 1105 | echo "$new_users" | while IFS= read -r line; do 1106 | log " $line" 1107 | done 1108 | else 1109 | log "未发现新增用户" 1110 | fi 1111 | log_complete "检查完成" 1112 | 1113 | # 检测 ZMODEM 传输 1114 | log "[17.5] 检查ZMODEM传输记录..." 1115 | zmodem_transfers=$(grep "ZMODEM:.*BPS" /var/log/messages* | awk -F '[]/]' '{print $0}' | sort | uniq) 1116 | if [ -n "$zmodem_transfers" ]; then 1117 | log "发现ZMODEM传输记录:" 1118 | echo "$zmodem_transfers" | while IFS= read -r line; do 1119 | log " $line" 1120 | done 1121 | else 1122 | log "未发现ZMODEM传输记录" 1123 | fi 1124 | log_complete "检查完成" 1125 | 1126 | # 检测使用的 DNS 服务器 1127 | log "[17.6] 检查使用的DNS服务器..." 1128 | 1129 | log "[17.6] 检查使用的 DNS 服务器..." 1130 | dns_servers=$(grep "using nameserver" /var/log/messages* | awk '{print $NF}' | awk -F# '{print $1}' | sort | uniq) 1131 | if [ -n "$dns_servers" ]; then 1132 | log "发现 DNS 服务器:" 1133 | echo "$dns_servers" | while IFS= read -r line; do 1134 | log " $line" 1135 | done 1136 | else 1137 | log "未发现 DNS 服务器" 1138 | fi 1139 | log_complete "检查完成" 1140 | 1141 | # 检测定时任务中的 wget 和 curl 命令 1142 | log "[17.7] 检查 cron 任务中的 wget 或 curl 命令..." 1143 | cron_tasks=$(grep -E "wget|curl" /var/log/cron* | sort | uniq) 1144 | if [ -n "$cron_tasks" ]; then 1145 | log "发现 cron 任务中使用 wget 或 curl:" 1146 | echo "$cron_tasks" | while IFS= read -r line; do 1147 | log " $line" 1148 | done 1149 | else 1150 | log "未发现 cron 任务中使用 wget 或 curl" 1151 | fi 1152 | log_complete "检查完成" 1153 | 1154 | 1155 | # 检测软件安装情况 1156 | log "[17.8] 检查已安装的软件..." 1157 | installed_software=$(grep Installed /var/log/yum* | awk '{print $NF}' | sort | uniq) 1158 | if [ -n "$installed_software" ]; then 1159 | log "发现已安装的软件:" 1160 | echo "$installed_software" | while IFS= read -r line; do 1161 | log " $line" 1162 | done 1163 | else 1164 | log "未发现已安装的软件" 1165 | fi 1166 | log_complete "检查完成" 1167 | 1168 | } 1169 | 1170 | # 打包日志文件 1171 | backup_logs() { 1172 | log "[18] 开始备份日志..." 1173 | 1174 | # 使用 zip 命令将 /var/log/ 目录下的日志文件打包 1175 | zip -r $BACKUP_FILE /var/log/ 1176 | 1177 | if [ $? -eq 0 ]; then 1178 | log "日志备份成功完成。备份文件: $BACKUP_FILE" 1179 | else 1180 | log "日志备份失败" 1181 | fi 1182 | } 1183 | 1184 | 1185 | # 检测 dmesg 日志中的安全相关事件 1186 | check_dmesg_security() { 1187 | log "[19] 开始检查 dmesg 安全审计..." 1188 | 1189 | # 获取 dmesg 日志 1190 | dmesg_output=$(dmesg) 1191 | 1192 | # 检测内核警告 1193 | log "[19.1] 检查内核警告..." 1194 | kernel_warnings=$(echo "$dmesg_output" | grep -i 'warning') 1195 | if [ -n "$kernel_warnings" ]; then 1196 | log "发现内核警告:" 1197 | echo "$kernel_warnings" | while IFS= read -r line; do 1198 | log " $line" 1199 | done 1200 | else 1201 | log "未发现内核警告" 1202 | fi 1203 | log_complete "检查完成" 1204 | 1205 | # 检测内核错误 1206 | log "[19.2] 检查内核错误..." 1207 | kernel_errors=$(echo "$dmesg_output" | grep -i 'error') 1208 | if [ -n "$kernel_errors" ]; then 1209 | log "发现内核错误:" 1210 | echo "$kernel_errors" | while IFS= read -r line; do 1211 | log " $line" 1212 | done 1213 | else 1214 | log "未发现内核错误" 1215 | fi 1216 | log_complete "检查完成" 1217 | 1218 | # 检测驱动程序问题 1219 | log "[19.3] 检查驱动程序问题..." 1220 | driver_issues=$(echo "$dmesg_output" | grep -i 'driver') 1221 | if [ -n "$driver_issues" ]; then 1222 | log "发现驱动程序问题:" 1223 | echo "$driver_issues" | while IFS= read -r line; do 1224 | log " $line" 1225 | done 1226 | else 1227 | log "未发现驱动程序问题" 1228 | fi 1229 | log_complete "检查完成" 1230 | 1231 | # 检测非法访问尝试 1232 | log "[19.4] 检查非法访问尝试..." 1233 | illegal_access=$(echo "$dmesg_output" | grep -i 'illegal') 1234 | if [ -n "$illegal_access" ]; then 1235 | log "发现非法访问尝试:" 1236 | echo "$illegal_access" | while IFS= read -r line; do 1237 | log " $line" 1238 | done 1239 | else 1240 | log "未发现非法访问尝试" 1241 | fi 1242 | 1243 | # 检测安全相关的事件 1244 | log "[19.5] 检查安全相关事件..." 1245 | security_events=$(echo "$dmesg_output" | grep -iE 'security|audit|suspicious') 1246 | if [ -n "$security_events" ]; then 1247 | log "发现安全相关事件:" 1248 | echo "$security_events" | while IFS= read -r line; do 1249 | log " $line" 1250 | done 1251 | else 1252 | log "未发现安全相关事件" 1253 | fi 1254 | log_complete "检查完成" 1255 | 1256 | # 检测内存问题 1257 | log "[19.6] 检查内存问题..." 1258 | memory_issues=$(echo "$dmesg_output" | grep -iE 'memory|out of memory|oom') 1259 | if [ -n "$memory_issues" ]; then 1260 | log "发现内存问题:" 1261 | echo "$memory_issues" | while IFS= read -r line; do 1262 | log " $line" 1263 | done 1264 | else 1265 | log "未发现内存问题" 1266 | fi 1267 | 1268 | # 检测网络问题 1269 | log "[19.7] 检查网络问题..." 1270 | network_issues=$(echo "$dmesg_output" | grep -iE 'network|eth|wlan|tcp|udp|ip') 1271 | if [ -n "$network_issues" ]; then 1272 | log "发现网络问题:" 1273 | echo "$network_issues" | while IFS= read -r line; do 1274 | log " $line" 1275 | done 1276 | else 1277 | log "未发现网络问题" 1278 | fi 1279 | log_complete "检查完成" 1280 | 1281 | # 检测硬件问题 1282 | log "[19.8] 检查硬件问题..." 1283 | hardware_issues=$(echo "$dmesg_output" | grep -iE 'hardware|device|firmware') 1284 | if [ -n "$hardware_issues" ]; then 1285 | log "发现硬件问题:" 1286 | echo "$hardware_issues" | while IFS= read -r line; do 1287 | log " $line" 1288 | done 1289 | else 1290 | log "未发现硬件问题" 1291 | fi 1292 | log_complete "检查完成" 1293 | 1294 | # 检测系统挂起或崩溃 1295 | log "[19.9] 检查系统挂起或崩溃..." 1296 | system_issues=$(echo "$dmesg_output" | grep -iE 'hang|crash|panic|reboot|shutdown') 1297 | if [ -n "$system_issues" ]; then 1298 | log "发现系统挂起或崩溃问题:" 1299 | echo "$system_issues" | while IFS= read -r line; do 1300 | log " $line" 1301 | done 1302 | else 1303 | log "未发现系统挂起或崩溃问题" 1304 | fi 1305 | log_complete "检查完成" 1306 | } 1307 | 1308 | 1309 | # 检测 lsmod 输出中的安全相关事件 1310 | check_lsmod_security() { 1311 | log "[20] 开始检查 lsmod 安全审计..." 1312 | 1313 | # 获取 lsmod 输出 1314 | lsmod_output=$(lsmod) 1315 | 1316 | # 记录所有加载的模块 1317 | log "[20.1] 已加载的模块:" 1318 | echo "$lsmod_output" | while IFS= read -r line; do 1319 | log " $line" 1320 | done 1321 | log_complete "检查完成" 1322 | 1323 | # 检测可疑的模块名称 1324 | log "[20.2] 检查可疑的模块名称..." 1325 | suspicious_modules=$(echo "$lsmod_output" | grep -iE 'rootkit|hack|malware|exploit|inject|hidden|backdoor') 1326 | if [ -n "$suspicious_modules" ]; then 1327 | log "发现可疑模块:" 1328 | echo "$suspicious_modules" | while IFS= read -r line; do 1329 | log " $line" 1330 | done 1331 | else 1332 | log "未发现可疑模块" 1333 | fi 1334 | log_complete "检查完成" 1335 | 1336 | # 检测加载的模块数量 1337 | log "[20.3] 检查已加载模块数量..." 1338 | module_count=$(echo "$lsmod_output" | wc -l) 1339 | log "已加载模块数量: $module_count" 1340 | 1341 | # 检测模块大小 1342 | log "[20.4] 检查模块大小..." 1343 | large_modules=$(echo "$lsmod_output" | awk '{if ($2 > 1000000) print $0}') 1344 | if [ -n "$large_modules" ]; then 1345 | log "发现大型模块 大于1MB:" 1346 | echo "$large_modules" | while IFS= read -r line; do 1347 | log " $line" 1348 | done 1349 | else 1350 | log "未发现大型模块" 1351 | fi 1352 | log_complete "检查完成" 1353 | 1354 | # 检测模块依赖关系 1355 | log "[20.5] 检查模块依赖关系..." 1356 | echo "$lsmod_output" | tail -n +2 | while IFS= read -r line; do 1357 | module_name=$(echo "$line" | awk '{print $1}') 1358 | dependencies=$(echo "$line" | awk '{print $4}') 1359 | if [ "$dependencies" != "-" ]; then 1360 | log "模块 $module_name 的依赖项: $dependencies" 1361 | fi 1362 | done 1363 | log_complete "检查完成" 1364 | 1365 | # 检测模块参数 1366 | log "[20.6] 检查模块参数..." 1367 | echo "$lsmod_output" | tail -n +2 | while IFS= read -r line; do 1368 | module_name=$(echo "$line" | awk '{print $1}') 1369 | parameters=$(modinfo -p $module_name 2>/dev/null) 1370 | if [ -n "$parameters" ]; then 1371 | log "模块 $module_name 的参数:" 1372 | echo "$parameters" | while IFS= read -r param; do 1373 | log " $param" 1374 | done 1375 | fi 1376 | done 1377 | log_complete "检查完成" 1378 | 1379 | # 检测模块签名 1380 | log "[20.7] 检查模块签名..." 1381 | echo "$lsmod_output" | tail -n +2 | while IFS= read -r line; do 1382 | module_name=$(echo "$line" | awk '{print $1}') 1383 | signature=$(modinfo -F signer $module_name 2>/dev/null) 1384 | if [ -n "$signature" ]; then 1385 | log "模块 $module_name 由以下签名者签名: $signature" 1386 | else 1387 | log "模块 $module_name 未签名" 1388 | fi 1389 | done 1390 | log_complete "检查完成" 1391 | 1392 | # 检测模块来源 1393 | log "[20.8] 检查模块来源..." 1394 | echo "$lsmod_output" | tail -n +2 | while IFS= read -r line; do 1395 | module_name=$(echo "$line" | awk '{print $1}') 1396 | source=$(modinfo -F filename $module_name 2>/dev/null) 1397 | if [ -n "$source" ]; then 1398 | log "模块 $module_name 来源: $source" 1399 | else 1400 | log "未找到模块 $module_name 的来源" 1401 | fi 1402 | done 1403 | log_complete "检查完成" 1404 | } 1405 | 1406 | 1407 | 1408 | # 检测已安装的软件 1409 | check_malware_software() { 1410 | log "[21] 开始检查软件安装..." 1411 | # 获取已安装的软件列表 1412 | installed_packages=$(which dpkg >/dev/null 2>&1 && dpkg -l | awk '{print $2}' || ls -l /usr/bin) 1413 | 1414 | log "[21.1] 发现已安装的软件:" 1415 | echo "$installed_packages" | while IFS= read -r package; do 1416 | log " $package" 1417 | done 1418 | 1419 | log_complete "检查完成" 1420 | 1421 | # 检测恶意软件 1422 | log "[21.2] 开始检测恶意软件..." 1423 | # 定义恶意软件黑名单 1424 | malware_blacklist=( 1425 | "rootkit" 1426 | "hack" 1427 | "malware" 1428 | "exploit" 1429 | "inject" 1430 | "hidden" 1431 | "backdoor" 1432 | "trojan" 1433 | "virus" 1434 | "worm" 1435 | "spyware" 1436 | "adware" 1437 | "ransomware" 1438 | "keylogger" 1439 | "botnet" 1440 | "miner" 1441 | "cryptojacking" 1442 | "ddos" 1443 | "phishing" 1444 | "shellcode" 1445 | "kit" 1446 | "kitteh" 1447 | "mirai" 1448 | "darkcomet" 1449 | "netbus" 1450 | "sub7" 1451 | "gh0st" 1452 | "njrat" 1453 | "poisonivy" 1454 | "zeus" 1455 | "conficker" 1456 | "cryptolocker" 1457 | "locky" 1458 | "wannacry" 1459 | "petya" 1460 | "notpetya" 1461 | "emotet" 1462 | "trickbot" 1463 | "qakbot" 1464 | "dridex" 1465 | "gandcrab" 1466 | "samSam" 1467 | "cobaltstrike" 1468 | "meterpreter" 1469 | "nmap" 1470 | "hydra" 1471 | "sqlmap" 1472 | "john" 1473 | "hashcat" 1474 | "metasploit" 1475 | "msfconsole" 1476 | "ncat" 1477 | "netcat" 1478 | "socat" 1479 | "sshpass" 1480 | "proftpd" 1481 | "vsftpd" 1482 | "openbsd-inetd" 1483 | "inetd" 1484 | "xinetd" 1485 | "sshd" 1486 | "dropbear" 1487 | ) 1488 | 1489 | # 检查已安装的软件是否在黑名单中 1490 | for package in $(echo "$installed_packages"); do 1491 | for malware in "${malware_blacklist[@]}"; do 1492 | if [[ $package == *$malware* ]]; then 1493 | log "发现恶意软件: $package" 1494 | fi 1495 | done 1496 | done 1497 | log_complete "检查完成" 1498 | } 1499 | 1500 | # 针对使用的性能进行检测 1501 | check_performanc() { 1502 | #检测磁盘使用情况 1503 | log "[22] 开始检查磁盘使用情况..." 1504 | disk_usage=$(df -h) 1505 | log "[22.1] 磁盘使用情况:" 1506 | echo "$disk_usage" | while IFS= read -r line; do 1507 | log " $line" 1508 | done 1509 | log "磁盘使用情况检查完成" 1510 | 1511 | # 检测 CPU 使用率 1512 | log "[22.2] 开始检查CPU使用率..." 1513 | cpu_usage=$(top -b -n 1 | grep "Cpu(s)") 1514 | log "CPU使用率:" 1515 | log " $cpu_usage" 1516 | log_complete "CPU使用率检查完成" 1517 | 1518 | # 检测内存使用情况 1519 | log "[22.3] 开始检查内存使用情况..." 1520 | memory_usage=$(free -m) 1521 | log "内存使用情况:" 1522 | echo "$memory_usage" | while IFS= read -r line; do 1523 | log " $line" 1524 | done 1525 | log_complete "内存使用情况检查完成" 1526 | 1527 | # 检测网络连接 1528 | log "[22.4] 开始检查网络连接..." 1529 | network_connections=$(ss -tuln) 1530 | log "网络连接:" 1531 | echo "$network_connections" | while IFS= read -r line; do 1532 | log " $line" 1533 | done 1534 | log_complete "网络连接检查完成" 1535 | 1536 | # 检测高 CPU 使用率的进程 1537 | log "[22.5] 开始检查CPU使用率>50的进程..." 1538 | high_cpu_processes=$(ps aux --sort=-%cpu | awk 'NR==1 || $3 >= 50 {print $0}') 1539 | log "CPU使用率>50的进程:" 1540 | echo "$high_cpu_processes" | while IFS= read -r line; do 1541 | log " $line" 1542 | done 1543 | log_complete "检查完成" 1544 | 1545 | # 检测高内存使用率的进程 1546 | log "[22.6] 开始检查内存使用>=50%的进程..." 1547 | high_memory_processes=$(ps aux --sort=-%mem | awk 'NR==1 || $4 >= 50 {print $0}') 1548 | log "内存使用>=50%的进程:" 1549 | echo "$high_memory_processes" | while IFS= read -r line; do 1550 | log " $line" 1551 | done 1552 | log_complete "检查完成" 1553 | } 1554 | 1555 | 1556 | #检测后门以及持久化 1557 | check_backdoor_persistence(){ 1558 | 1559 | # 检测隐藏文件 1560 | log "[23.1] 开始检测隐藏文件..." 1561 | # 检查根目录及其子目录下的隐藏文件,排除 /var 和 /sys 目录 1562 | hidden_files=$(find / -path /var -prune -o -path /sys -prune -o -name ".*" -type f 2>/dev/null) 1563 | 1564 | if [ -z "$hidden_files" ]; then 1565 | log "未发现隐藏文件" 1566 | else 1567 | log "发现隐藏文件:" 1568 | echo "$hidden_files" | while read -r file; do 1569 | log " $file" 1570 | done 1571 | fi 1572 | log_complete "检查完成" 1573 | 1574 | # 检测具有a和i属性的文件 1575 | log "[23.2]开始检测特殊属性文件..." 1576 | 1577 | # 检查根目录及其子目录下具有 a 和 i 属性的文件 1578 | special_files=$(lsattr -R / 2>/dev/null | grep -- '-ia-') 1579 | 1580 | if [ -z "$special_files" ]; then 1581 | log "未发现具有特殊属性 a 或 i 的文件" 1582 | else 1583 | log "发现具有特殊属性 a 或 i 的文件:" 1584 | echo "$special_files" | while read -r file; do 1585 | log " $file" 1586 | done 1587 | fi 1588 | 1589 | log_complete "特殊属性文件检测完成" 1590 | 1591 | 1592 | # 检测隐藏的 crontab 后门 1593 | 1594 | log "[23.3] 开始检测隐藏的 crontab 后门..." 1595 | # 读取 /var/spool/cron/root 文件,使用 cat -A 查看隐藏字符 1596 | log "使用 cat -A 读取 /var/spool/cron/root..." 1597 | hidden_content=$(cat -A /var/spool/cron/root) 1598 | 1599 | if [ -n "$hidden_content" ]; then 1600 | log "在 /var/spool/cron/root 中发现隐藏内容:" 1601 | log "$hidden_content" 1602 | log "可能存在隐藏的 crontab 后门" 1603 | else 1604 | log "在 /var/spool/cron/root 中未发现隐藏内容" 1605 | fi 1606 | 1607 | log_complete "隐藏的 crontab 后门检测完成" 1608 | 1609 | 1610 | # 检测端口复用情况 1611 | log "[23.4] 开始检测端口复用..." 1612 | 1613 | listening_ports=$(netstat -anltp | grep 'LISTEN' | awk '{split($4, addr, ":"); print addr[2]}') 1614 | 1615 | # 检查每个端口的 PID 1616 | while IFS= read -r port; do 1617 | if [ -n "$port" ]; then 1618 | # 使用 lsof 检查该端口是否有多个进程 1619 | pid_count=$(lsof -i :$port | grep -v "/usr/bin" | awk 'NR>1 {print $1}' | sort | uniq | wc -l) 1620 | 1621 | if [ "$pid_count" -gt 1 ]; then 1622 | log "端口 $port 被多个进程复用" 1623 | # 获取具体 PID 1624 | pids=$(lsof -i :$port | awk 'NR>1 {print $1}' | sort | uniq) 1625 | log "使用端口 $port 的进程: $(echo "$pids" | tr '\n' ', ' | sed 's/,$//')" 1626 | fi 1627 | fi 1628 | done <<< "$listening_ports" 1629 | 1630 | log_complete "端口复用检测完成" 1631 | 1632 | } 1633 | 1634 | #检测防火墙配置 1635 | check_firewall_iptables() { 1636 | log "[24] 开始检查防火墙配置" 1637 | # 检查 SELinux 状态 1638 | selinux_status=$(sestatus) 1639 | log "[24.1] SELinux 状态:" 1640 | echo "$selinux_status" | while read -r line; do 1641 | log " $line" 1642 | done 1643 | 1644 | # 检查 SELinux 配置文件 1645 | log "[24.2] 开始检测 SELinux 配置..." 1646 | selinux_config_file="/etc/selinux/config" 1647 | if [ -f "$selinux_config_file" ]; then 1648 | log "发现 SELinux 配置文件: $selinux_config_file" 1649 | log "SELinux 配置:" 1650 | while IFS='=' read -r key value; do 1651 | if [[ "$key" =~ ^SELINUX|^SELINUXTYPE ]]; then 1652 | log " $key=$value" 1653 | fi 1654 | done < "$selinux_config_file" 1655 | else 1656 | log "未找到 SELinux 配置文件: $selinux_config_file" 1657 | fi 1658 | 1659 | log_complete "SELinux 配置检测完成" 1660 | 1661 | 1662 | # 检测 iptables 配置 1663 | log "[24.3] 开始检测 iptables 配置..." 1664 | 1665 | # 检查 iptables 规则 1666 | iptables_rules=$(iptables -L -v -n) 1667 | log "iptables 规则:" 1668 | echo "$iptables_rules" | while read -r line; do 1669 | log " $line" 1670 | done 1671 | log_complete "iptables 配置检测完成" 1672 | 1673 | # 检查 iptables 保存的规则文件 1674 | log "[24.4] 开始检测 iptables 保存的规则文件" 1675 | iptables_save_file="/etc/sysconfig/iptables" 1676 | if [ -f "$iptables_save_file" ]; then 1677 | log "发现 iptables 保存的规则文件: $iptables_save_file" 1678 | log "iptables 保存的规则文件内容:" 1679 | while read -r line; do 1680 | log " $line" 1681 | done < "$iptables_save_file" 1682 | else 1683 | log "未找到 iptables 保存的规则文件: $iptables_save_file" 1684 | fi 1685 | 1686 | log_complete "iptables 配置检测完成" 1687 | 1688 | 1689 | # 检测恶意配置 1690 | log "[24.5] Starting malicious configuration detection..." 1691 | 1692 | # 检查 SELinux 配置文件中的恶意配置 1693 | selinux_config_file="/etc/selinux/config" 1694 | if [ -f "$selinux_config_file" ]; then 1695 | log "Checking for malicious SELinux configuration..." 1696 | while IFS='=' read -r key value; do 1697 | if [[ "$key" == "SELINUX" && "$value" == "permissive" || "$value" == "disabled" ]]; then 1698 | log " Warning: SELinux is set to permissive or disabled: $key=$value" 1699 | fi 1700 | done < "$selinux_config_file" 1701 | fi 1702 | log_complete "SELinux 配置检测完成" 1703 | 1704 | # 检查 iptables 规则中的恶意配置 1705 | iptables_rules=$(iptables -L -v -n) 1706 | log "[24.6] Checking for malicious iptables rules..." 1707 | echo "$iptables_rules" | while read -r line; do 1708 | if echo "$line" | grep -qE 'ACCEPT|DROP|REJECT' && ! echo "$line" | grep -qE 'lo|127\.0\.0\.1'; then 1709 | log " Warning: Suspicious iptables rule: $line" 1710 | fi 1711 | done 1712 | 1713 | log_complete "恶意配置检测完成" 1714 | 1715 | } 1716 | 1717 | 1718 | # 检测反弹Shell 1719 | check_reversed_shell() { 1720 | log "【25】开始检测反弹shell" 1721 | # 获取所有ESTABLISHED连接并且文件描述符为 0u、1u 或 2u 的进程 PID 1722 | pids=$(lsof -n | grep ESTABLISHED | grep -wE '0u|1u|2u' | awk '{print $2}' | uniq) 1723 | 1724 | # 检查可疑 PID 的文件描述符 1725 | for pid in $pids; do 1726 | fd_info=$(ls -al /proc/$pid/fd 2>/dev/null) 1727 | if echo "$fd_info" | grep -q 'socket'; then 1728 | log "Reversed shell detected for PID $pid" 1729 | fi 1730 | done 1731 | log_complete "反弹shell检测完成" 1732 | 1733 | # 通过检测进程中的可疑操作来检测 1734 | log "[13.2] 开始检查可疑进程和命令行参数..." 1735 | suspicious_processes=$(ps aux | grep -E 'nc|netcat|bash -i|python -c|perl -e|ruby -e|ruby -rsocket|php -r|socat' | grep -v grep | awk '{print $2}') 1736 | 1737 | if [ -n "$suspicious_processes" ]; then 1738 | log "Suspicious processes found:" 1739 | echo "$suspicious_processes" | while read -r line; do 1740 | log " $line" 1741 | done 1742 | else 1743 | log "未发现可疑进程和命令" 1744 | fi 1745 | log_complete "可疑进程和命令行参数检查完成" 1746 | } 1747 | 1748 | # 检查库文件劫持 1749 | check_library_hijack() { 1750 | log "【26】开始检查库文件劫持..." 1751 | 1752 | # 检查 LD_PRELOAD 环境变量 1753 | log "[26.1] 检查LD_PRELOAD环境变量..." 1754 | ld_preload_inject=$(echo $LD_PRELOAD) 1755 | if [ -n "$ld_preload_inject" ]; then 1756 | log "LD_PRELOAD设置为: $ld_preload_inject" 1757 | else 1758 | log "未设置LD_PRELOAD环境变量" 1759 | fi 1760 | log_complete "库文件劫持检查完成" 1761 | 1762 | 1763 | # 检查/etc/ld.so.preload劫持 1764 | log "[26.2] 开始检查/etc/ld.so.preload文件" 1765 | preload_content=$(busybox cat /etc/ld.so.preload 2>/dev/null) 1766 | if [ $? -ne 0 ]; then 1767 | log "无法读取/etc/ld.so.preload" 1768 | else 1769 | log "检测到库文件劫持:" 1770 | log "$preload_content" 1771 | fi 1772 | log_complete "/etc/ld.so.preload 文件检查完成" 1773 | 1774 | 1775 | # 检测默认加载的动态库是否被篡改 1776 | log "[26.3] 开始检查默认库文件变更..." 1777 | 1778 | # 执行 strace 命令并捕获输出 1779 | output=$(strace -f -e trace=file /bin/whoami 2>&1 | grep 'access("[^"]*", R_OK)' | grep -oP 'access\("\K[^"]*') 1780 | if [[ -z "$output" ]]; then 1781 | log "未发现访问调用" 1782 | return 1783 | fi 1784 | 1785 | # 检查默认的动态库是否为/etc/ld.so.preload 1786 | if echo "$output" | grep -q '/etc/ld.so.preload'; then 1787 | log "默认动态库检查通过" 1788 | else 1789 | log "默认动态库已被篡改,发现可疑路径:" 1790 | for path in $output; do 1791 | log "可疑路径: $path" 1792 | done 1793 | fi 1794 | 1795 | log_complete "默认库文件检查完成" 1796 | 1797 | 1798 | # 检查 /etc/ld.so.conf 文件 1799 | log "[26.4] 开始检查/etc/ld.so.conf..." 1800 | 1801 | # 读取 /etc/ld.so.conf 文件内容 1802 | content=$(cat /etc/ld.so.conf 2>/dev/null) 1803 | 1804 | if [[ -z "$content" ]]; then 1805 | log "/etc/ld.so.conf为空或不存在" 1806 | return 1807 | fi 1808 | log_complete "/etc/ld.so.conf文件检查完成" 1809 | 1810 | # 将内容按行分割 1811 | IFS=$'\n' read -d '' -ra lines <<< "$content" 1812 | 1813 | # 定义常见系统目录 1814 | common_dirs=("/lib" "/usr/lib" "/lib64" "/usr/lib64") 1815 | 1816 | # 初始化可疑路径和重复路径数组 1817 | suspicious_paths=() 1818 | duplicate_paths=() 1819 | unique_paths=() 1820 | 1821 | for line in "${lines[@]}"; do 1822 | # 跳过注释和空行 1823 | if [[ -z "$line" || $line =~ ^# ]]; then 1824 | continue 1825 | fi 1826 | 1827 | # 检查路径是否包含可疑目录 1828 | if echo "$line" | grep -qE '(/tmp|/home|/var/tmp)'; then 1829 | suspicious_paths+=("$line") 1830 | log "发现可疑路径: $line" 1831 | fi 1832 | 1833 | # 检查路径是否重复 1834 | if [[ " ${unique_paths[@]} " =~ " ${line} " ]]; then 1835 | duplicate_paths+=("$line") 1836 | log "发现重复路径: $line" 1837 | else 1838 | unique_paths+=("$line") 1839 | fi 1840 | 1841 | # 检查路径是否在常见系统目录中 1842 | if ! echo "${common_dirs[@]}" | grep -q "$line"; then 1843 | log "发现未知路径: $line" 1844 | fi 1845 | done 1846 | 1847 | if [[ ${#suspicious_paths[@]} -eq 0 ]] && [[ ${#duplicate_paths[@]} -eq 0 ]]; then 1848 | log "在/etc/ld.so.conf中未发现可疑或重复路径" 1849 | fi 1850 | 1851 | log_complete "/etc/ld.so.conf检查完成" 1852 | 1853 | 1854 | # 检查关键系统二进制文件的库依赖 1855 | log "[26.5] 检查关键系统二进制文件的库依赖..." 1856 | critical_binaries=( 1857 | "/bin/ls" "/bin/ps" "/bin/netstat" "/usr/bin/who" "/usr/bin/top" "/usr/sbin/lsof" 1858 | "/bin/cat" "/bin/chmod" "/bin/chown" "/bin/cp" "/bin/date" "/bin/df" "/bin/echo" 1859 | "/bin/grep" "/bin/kill" "/bin/ln" "/bin/mkdir" "/bin/mv" "/bin/ping" "/bin/rm" 1860 | "/bin/touch" "/sbin/ifconfig" "/sbin/ip" "/sbin/netstat" "/sbin/service" "/sbin/shutdown" 1861 | "/usr/bin/curl" "/usr/bin/find" "/usr/bin/gawk" "/usr/bin/less" "/usr/bin/nmap" 1862 | "/usr/bin/nc" "/usr/bin/ps" "/usr/bin/sudo" "/usr/bin/tar" "/usr/bin/wget" 1863 | ) 1864 | for binary in "${critical_binaries[@]}"; do 1865 | if [ -f "$binary" ]; then 1866 | log "检查文件 $binary 的库依赖..." 1867 | ldd $binary 2>/dev/null | tee -a $LOG_FILE 1868 | else 1869 | log_danger "二进制文件不存在: $binary" 1870 | fi 1871 | done 1872 | 1873 | log_complete "库文件劫持检查完成" 1874 | } 1875 | 1876 | 1877 | # 检查并安装busybox 1878 | check_and_install_busybox() { 1879 | if ! command -v busybox &> /dev/null; then 1880 | log "【27】开始安装busybox..." 1881 | commands=( 1882 | "wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64 -O /tmp/busybox-x86_64" 1883 | "cp /tmp/busybox-x86_64 /usr/local/bin/busybox" 1884 | "chmod +x /usr/local/bin/busybox" 1885 | ) 1886 | 1887 | # 执行命令并检查返回值 1888 | for cmd in "${commands[@]}"; do 1889 | if ! $cmd; then 1890 | log "busybox安装失败" 1891 | exit 1 1892 | fi 1893 | done 1894 | 1895 | log_complete "busybox安装成功" 1896 | fi 1897 | 1898 | } 1899 | 1900 | # 检查并安装unhide 1901 | check_and_install_unhide() { 1902 | if ! command -v unhide &> /dev/null; then 1903 | log "【28】unhide未安装,正在安装..." 1904 | yum install -y unhide 1905 | if [[ $? -ne 0 ]]; then 1906 | log "unhide安装失败" 1907 | exit 1 1908 | fi 1909 | log_complete "unhide安装成功" 1910 | fi 1911 | } 1912 | 1913 | 1914 | # 检测隐藏进程 1915 | detect_hidden_process() { 1916 | log "【29】开始检测隐藏进程..." 1917 | hidden_pids=$(unhide proc | grep -oP 'Found HIDDEN PID: \K\d+') 1918 | if [[ -n "$hidden_pids" ]]; then 1919 | log "发现隐藏进程: $hidden_pids" 1920 | else 1921 | log "未发现隐藏进程" 1922 | return 1 1923 | fi 1924 | log_complete "隐藏进程检测完成" 1925 | } 1926 | 1927 | # 检测进程挂载 1928 | detect_process_mount() { 1929 | log "【30】开始检测进程挂载..." 1930 | # 获取 /proc/ 下的挂载点 1931 | mounts=$(cat /proc/mounts | grep '/proc/' | grep -oP '/proc/\K\d+') 1932 | if [[ -n "$mounts" ]]; then 1933 | # 运行 netstat -anltp,提取出 PID 1934 | netstat_pids=$(netstat -anltp | awk '{print $7}' | awk -F'/' '{print $1}' | grep -oE '[0-9]+' | sort -nu) 1935 | if [[ -n "$netstat_pids" ]]; then 1936 | for pid1 in $mounts; do 1937 | if ! echo "$netstat_pids" | grep -q "^$pid1$"; then 1938 | log "通过进程挂载发现PID $pid1" 1939 | umount -l /proc/$pid1 1940 | log "PID $pid1 已被响应并可以正常查看" 1941 | fi 1942 | done 1943 | fi 1944 | else 1945 | log "未发现进程挂载" 1946 | fi 1947 | log_complete "进程挂载检测完成" 1948 | } 1949 | 1950 | # 检测库文件劫持 1951 | detect_library_hijacking() { 1952 | log "【31】开始检测库文件劫持..." 1953 | 1954 | # 检查 LD_PRELOAD 环境变量 1955 | ld_preload_inject=$(echo $LD_PRELOAD) 1956 | if [ -n "$ld_preload_inject" ]; then 1957 | log "LD_PRELOAD设置为: $ld_preload_inject" 1958 | fi 1959 | log_complete "LD_PRELOAD检查完成" 1960 | 1961 | # 检查/etc/ld.so.preload劫持 1962 | preload_content=$(busybox cat /etc/ld.so.preload 2>/dev/null) 1963 | if [ $? -ne 0 ]; then 1964 | log "无法读取/etc/ld.so.preload" 1965 | else 1966 | log "检测到库文件劫持:$preload_content" 1967 | fi 1968 | log_complete "/etc/ld.so.preload检查完成" 1969 | 1970 | # 检查默认的动态库是否为/etc/ld.so.preload 1971 | output=$(strace -f -e trace=file /bin/whoami 2>&1 | grep 'access("[^"]*", R_OK)' | grep -oP 'access\("\K[^"]*' | grep -q '/etc/ld.so.preload') 1972 | if [[ -n "$output" ]]; then 1973 | for path in $output; do 1974 | log "默认动态库已被篡改,发现可疑路径:$path" 1975 | done 1976 | fi 1977 | log_complete "库文件劫持检测完成" 1978 | } 1979 | 1980 | # 检测 Diamorphine rootkit 1981 | detect_diamorphine_rootkit() { 1982 | log "【32】开始检测Diamorphine rootkit..." 1983 | 1984 | # 检查安装后相关文件与日志是否存在 1985 | find_output=$(busybox find / -name diamorphine 2>/dev/null) 1986 | dmesg_output=$(dmesg | grep diamorphine 2>/dev/null) 1987 | sys_module_output=$(ls -l /sys/module/diamorphine 2>/dev/null) 1988 | if [[ -n "$find_output" ]] || [[ -n "$dmesg_output" ]] || [[ -n "$sys_module_output" ]]; then 1989 | log "发现Diamorphine Rootkit!" 1990 | # 检查Diamorphine使用默认参数-31来隐藏进程 1991 | pids1=$(netstat -anltp | grep -oP '\b\d+/\S+' | cut -d/ -f1 | sort -u) 1992 | 1993 | # 将 PID 存储到数组中 1994 | IFS=$'\n' read -r -d '' -a pid1_array <<< "$pids1" 1995 | 1996 | # 检测隐藏进程 1997 | hidden_pids=$(unhide proc | grep -oP 'Found HIDDEN PID: \K\d+') 1998 | if [[ -n "$hidden_pids" ]]; then 1999 | IFS=$'\n' read -r -d '' -a pid2_array <<< "$hidden_pids" 2000 | for pid2 in "${pid2_array[@]}"; do 2001 | kill -31 $pid2 2>/dev/null 2002 | # 再次获取 PID 列表 2003 | pids3=$(netstat -anltp | grep -oP '\b\d+/\S+' | cut -d/ -f1 | sort -u) 2004 | IFS=$'\n' read -r -d '' -a pid3_array <<< "$pids3" 2005 | 2006 | # 检查 PID 是否在新的列表中 2007 | if [[ " ${pid3_array[*]} " =~ " $pid2 " ]] && ! [[ " ${pid1_array[*]} " =~ " $pid2 " ]]; then 2008 | log "检测到LKM Rootkit: PID $pid2" 2009 | log "PID $pid2 已被响应并可以正常查看" 2010 | fi 2011 | done 2012 | fi 2013 | fi 2014 | log_complete "Diamorphine rootkit检测完成" 2015 | } 2016 | 2017 | # 进度显示函数 2018 | show_progress() { 2019 | local current=$1 2020 | local total=$2 2021 | local prefix=$3 2022 | local width=50 2023 | local percentage=$((current * 100 / total)) 2024 | local completed=$((width * current / total)) 2025 | local remaining=$((width - completed)) 2026 | 2027 | printf "\r${prefix} [%-${width}s] %d%%" "$(printf "%${completed}s" | tr ' ' '#')$(printf "%${remaining}s" | tr ' ' '-')" "$percentage" 2028 | if [ "$current" -eq "$total" ]; then 2029 | echo 2030 | fi 2031 | } 2032 | 2033 | print_section_header() { 2034 | local title=$1 2035 | echo -e "\n${PURPLE}============== $title ==============${NC}" 2036 | } 2037 | 2038 | # 全局计数器 2039 | declare -i TOTAL_CHECKS=0 2040 | declare -i PASSED_CHECKS=0 2041 | declare -i WARNING_CHECKS=0 2042 | declare -i DANGER_CHECKS=0 2043 | 2044 | # 在每个检查函数末尾添加计数 2045 | count_check_result() { 2046 | local status=$1 2047 | ((TOTAL_CHECKS++)) 2048 | case "$status" in 2049 | "pass") ((PASSED_CHECKS++));; 2050 | "warning") ((WARNING_CHECKS++));; 2051 | "danger") ((DANGER_CHECKS++));; 2052 | esac 2053 | } 2054 | 2055 | # 在main函数结束时显示统计 2056 | print_summary() { 2057 | echo -e "\n${PURPLE}============== 检查结果统计 ==============${NC}" 2058 | echo -e "总检查项: ${TOTAL_CHECKS}" 2059 | echo -e "${GREEN}通过项: ${PASSED_CHECKS}${NC}" 2060 | echo -e "${YELLOW}警告项: ${WARNING_CHECKS}${NC}" 2061 | echo -e "${RED}危险项: ${DANGER_CHECKS}${NC}" 2062 | 2063 | # 计算得分 2064 | local score=$((100 * PASSED_CHECKS / TOTAL_CHECKS)) 2065 | echo -e "\n系统安全得分: ${score}/100" 2066 | } 2067 | 2068 | # 主函数,按顺序执行所有检查 2069 | main() { 2070 | # 设置错误处理 2071 | set +e # 临时禁用错误退出 2072 | 2073 | log "开始进行Linux主机安全检查..." 2074 | check_systeminfo 2075 | check_arp_spoofing 2076 | check_open_port 2077 | check_connections 2078 | check_interface 2079 | check_account 2080 | check_startup 2081 | check_crontab 2082 | check_routing_forwarded 2083 | check_processes 2084 | check_config 2085 | check_all_user_histories 2086 | check_filemd5 2087 | check_deleted_open_files 2088 | check_login_activity 2089 | check_dmesg_security 2090 | check_lsmod_security 2091 | check_malware_software 2092 | check_performanc 2093 | check_and_install_busybox 2094 | check_and_install_unhide 2095 | check_backdoor_persistence 2096 | check_firewall_iptables 2097 | check_reversed_shell 2098 | check_library_hijack 2099 | detect_hidden_process 2100 | detect_process_mount 2101 | detect_library_hijacking 2102 | detect_diamorphine_rootkit 2103 | backup_logs 2104 | 2105 | log "安全检查完成。详细结果请查看日志文件:$LOG_FILE" 2106 | log "危险项记录请查看:$DANGER_FILE" 2107 | log "日志备份文件:$BACKUP_FILE" 2108 | 2109 | set -e # 重新启用错误退出 2110 | } 2111 | 2112 | 2113 | # 运行主函数 2114 | main 2115 | -------------------------------------------------------------------------------- /login.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Version:1.3" 3 | echo "Author:飞鸟" 4 | echo "Mail:liuquyong112@gmail.com" 5 | echo "Date:2022-01-10" 6 | 7 | cat <