-
Notifications
You must be signed in to change notification settings - Fork 192
Expand file tree
/
Copy pathlinuxcheck.sh
More file actions
2114 lines (1851 loc) · 64.7 KB
/
Copy pathlinuxcheck.sh
File metadata and controls
2114 lines (1851 loc) · 64.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# ========================================================
# 工具名: Linux主机安全检查V2.0
# 作者: 飞鸟
# 版本:Create:201902 V1.0
# Update:202504 V2.0
# 主要检查流程:
# 1. 基础环境检查:检测系统基本信息
# 2. 网络安全检查:检测网络接口、ARP欺骗、开放端口和网络连接
# 3. 系统安全检查:检测账户安全、启动项、计划任务、路由转发和进程
# 4. 配置安全检查:检测系统安全相关配置
# 5. 用户历史检查:检测用户历史命令
# 6. 文件安全检查:检测文件完整性和已删除打开文件
# 7. 日志安全检查:检测登录活动、dmesg日志和加载的内核模块
# 8. 恶意软件检查:检测恶意软件和系统性能
# 9. 后门检查:检测后门、防火墙配置、反弹Shell和库文件劫持
# 10. 日志备份:备份系统日志文件
# ========================================================
# 添加全局错误处理
set -e # 遇到错误立即退出
trap 'echo "在第 $LINENO 行发生错误"; exit 1' ERR
# 定义目录变量
LOG_DIR="/var/log/security_check"
BACKUP_DIR="/var/log/backup"
# 定义日志文件和危险文件
IPADDR=$(ifconfig -a | grep -w inet | grep -v 127.0.0.1 | awk 'NR==1{print $2}' | cut -d':' -f2)
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
LOG_FILE="${LOG_DIR}/linux_check_${IPADDR}_${DATE}.log"
DANGER_FILE="${LOG_DIR}/linux_danger_${IPADDR}_${DATE}.log"
BACKUP_FILE="${BACKUP_DIR}/logs_backup_${IPADDR}_${DATE}.zip"
# 创建日志目录和备份目录
mkdir -p $LOG_DIR
mkdir -p $BACKUP_DIR
# 添加日志轮转机制
LOG_MAX_SIZE=10M
LOG_BACKUP_COUNT=5
rotate_log() {
if [ -f "$LOG_FILE" ] && [ $(stat -f%z "$LOG_FILE") -gt $LOG_MAX_SIZE ]; then
for i in $(seq $((LOG_BACKUP_COUNT-1)) -1 1); do
[ -f "${LOG_FILE}.$i" ] && mv "${LOG_FILE}.$i" "${LOG_FILE}.$((i+1))"
done
mv "$LOG_FILE" "${LOG_FILE}.1"
fi
}
# 定义颜色变量
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
# 优化日志函数
log() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "【${timestamp}】:$1" | tee -a $LOG_FILE
}
log_danger() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "【${timestamp}】:[危险] $1" | tee -a $DANGER_FILE
}
log_warning() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "【${timestamp}】:[警告] $1" | tee -a $LOG_FILE
}
log_success() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "【${timestamp}】:[正常] $1\n" | tee -a $LOG_FILE
}
# 修改日志输出函数
log_complete() {
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo -e "【${timestamp}】:$1" | tee -a $LOG_FILE
echo "" | tee -a $LOG_FILE
}
# 检查是否为 root 用户
if [ "$(whoami)" != "root" ]; then
echo "The security check must use the root account, otherwise some items cannot be checked"
exit 1
fi
#检测系统基本信息
check_systeminfo() {
local ret=0
{
log "[1] 开始检查系统信息..."
# 检测 IP 地址
log "[1.1] 开始检查IP地址..."
ip_addresses=$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}')
if [ -z "$ip_addresses" ]; then
log "未发现IP地址"
else
log "IP地址列表:"
echo "$ip_addresses" | while IFS= read -r line; do
log " $line"
done
fi
log_complete "IP地址检查完成"
# 检测操作系统版本
log "[1.2] 开始检查操作系统版本..."
os_version=$(cat /etc/redhat-release)
if [ -z "$os_version" ]; then
log "无法获取操作系统版本"
else
log "操作系统版本: $os_version"
fi
log_complete "操作系统版本检查完成"
} || ret=$?
if [ $ret -ne 0 ]; then
log_danger "系统信息检查失败,错误代码 $ret"
return $ret
fi
}
# 检测 ARP 表以及ARP攻击
check_arp_spoofing() {
log "[2] 开始检查ARP欺骗"
log "[2.1] 开始检查ARP表..."
arp_table=$(arp -a)
if [ -z "$arp_table" ]; then
log "未发现ARP表项"
else
log "ARP表内容:"
echo "$arp_table" | while IFS= read -r line; do
log " $line"
done
fi
log_complete "ARP表检查完成"
# 检测ARP攻击
log "[2.2] 开始检测ARP欺骗..."
arp_entries=$(arp -a | awk '{print $4}' | sort | uniq -c | sort -nr)
if [ -z "$arp_entries" ]; then
log "未发现ARP表项"
else
log "ARP表项统计:"
echo "$arp_entries" | while IFS= read -r line; do
count=$(echo $line | awk '{print $1}')
mac=$(echo $line | awk '{print $2}')
if [ "$count" -gt 1 ]; then
log "发现潜在的ARP欺骗: MAC地址 $mac 出现 $count 次"
else
log " $line"
fi
done
fi
log_complete "ARP欺骗检测完成"
}
check_open_port() {
log "[3] 开始检查开放端口"
# 检查开放的TCP端口和进程
log "[3.1] 检查开放的TCP端口和对应进程..."
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)
if [ -n "$tcpopen" ]; then
log "服务器开放的TCP端口和对应进程如下:"
echo "$tcpopen" | while IFS= read -r line; do
log " $line"
done
fi
log_complete "系统未开放TCP端口"
# 检查对外开放的TCP端口
log "[3.2] 开始检查对外开放的TCP端口"
tcpports=$(netstat -anltp | grep LISTEN | awk '{print $4}' | egrep "(0.0.0.0|:::)" | awk -F: '{print $NF}' | sort -n | uniq)
if [ -n "$tcpports" ]; then
log "以下TCP端口对外开放:"
for port in $tcpports; do
log " $port"
done
fi
log_complete "没有对外开放的TCP端口"
# 检测潜在危险的tcp端口
log "[3.3] 开始检测潜在危险的TCP端口"
dangerous_ports="21 22 23 25 135 137 138 139 143 3389 8080"
open_ports=$(netstat -anltp | grep LISTEN | awk '{print $4}' | egrep "(0.0.0.0|:::)" | awk -F: '{print $NF}' | sort -n | uniq)
if [ -n "$open_ports" ]; then
for port in $open_ports; do
if [[ " ${dangerous_ports[@]} " =~ " ${port} " ]]; then
log "危险的TCP端口 $port 对外开放"
log_danger "危险的TCP端口 $port 对外开放"
fi
done
else
log "未发现潜在危险的TCP端口"
fi
log_complete "潜在危险的TCP端口检查完成"
# 检查开放的UDP端口
log "[3.4] 开始检查开放的UDP端口和对应进程..."
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)
if [ -n "$udpopen" ]; then
log "服务器开放的UDP端口和对应进程如下:"
echo "$udpopen" | while IFS= read -r line; do
log " $line"
done
fi
log_complete "检查完成"
# 检测潜在危险的UDP端口
log "[3.5] 开始检测潜在危险的UDP端口"
dangerous_ports="137 138 161 162 500 1900 5353"
open_ports=$(netstat -anlup | awk '{print $4}' | egrep "(0.0.0.0|:::)" | awk -F: '{print $NF}' | sort -n | uniq)
if [ -n "$open_ports" ]; then
for port in $open_ports; do
if [[ " ${dangerous_ports[@]} " =~ " ${port} " ]]; then
log_danger "[3.6] 危险的UDP端口 $port 对外开放"
fi
done
fi
log_complete "危险的UDP端口检查完成"
}
# 检测活动的网络连接
check_connections() {
log "[4] 检查活动的网络连接..."
active_connections=$(netstat -anp | grep -E 'tcp|udp' | grep ESTABLISHED)
if [ -n "$active_connections" ]; then
log "服务器存在以下活动的网络连接:"
echo "$active_connections" | while IFS= read -r line; do
log " $line"
done
fi
log_complete "检查完成"
}
# 查询威胁情报
# API 密钥
APIKEY=""
check_ip_threatbook() {
log "[5] 开始检查IP威胁情报"
ips=$(netstat -anltp | awk '{print $5}' | sed 's/:.*//' | grep -E '[0-9]' | grep -vwE "0.0.0.0|127.0.0.1" | uniq)
for ip in $ips; do
log "正在查询IP威胁情报: $ip"
response=$(curl -s -X GET "https://api.threatbook.cn/v3/scene/ip_reputation?apikey=${APIKEY}&resource=$ip")
formatted_response=$(echo "$response" | jq .)
log "IP $ip 的威胁情报结果:"
log "$formatted_response"
log_complete "IP威胁情报检查完成"
done
}
# 检测网卡基本信息
check_interface() {
log "[6] 开始检查网卡信息"
log "[6.1] 检查网卡基本信息..."
interfaces=$(ip link show | grep -oP '^\d+: \K\w+')
if [ -n "$interfaces" ]; then
for interface in $interfaces; do
log "网卡: $interface"
log " IP信息:"
ip addr show $interface 2>/dev/null | while read -r line; do
log " $line"
done
# 获取默认网关
default_gateway=$(ip route | grep default | grep -oP 'via \K\S+' || echo "未找到")
log " 默认网关: $default_gateway"
# 获取 DNS 服务器
if [ -f "/etc/resolv.conf" ]; then
dns_servers=$(grep nameserver /etc/resolv.conf | awk '{print $2}')
log " DNS服务器: $dns_servers"
else
log " 未找到DNS配置文件"
fi
# 检测网卡是否处于混杂模式
if ip link show $interface | grep -q PROMISC; then
log_danger "网卡 $interface 处于混杂模式"
else
log_success "网卡 $interface 未处于混杂模式"
fi
# 检测网卡是否处于监听模式
if command -v iw >/dev/null 2>&1; then
if iw dev $interface info 2>/dev/null | grep -q "type monitor"; then
log_danger "网卡 $interface 处于监听模式"
else
log_success "网卡 $interface 未处于监听模式"
fi
else
log "未找到iw命令,跳过监听模式检查"
fi
# 获取传输速率
if command -v ethtool >/dev/null 2>&1; then
speed=$(ethtool $interface 2>/dev/null | grep -oP 'Speed: \K\S+' || echo "未知")
log " 传输速率: $speed"
else
log "未找到ethtool命令,跳过速率检查"
fi
# 获取错误计数器
if command -v ethtool >/dev/null 2>&1; then
errors=$(ethtool -S $interface 2>/dev/null | grep -E 'rx_errors|tx_errors|rx_dropped|tx_dropped' || echo "未发现错误")
log " 错误计数器:"
echo "$errors" | while read -r line; do
log " $line"
done
fi
done
else
log_warning "未发现网卡"
fi
log_complete "网卡检查完成"
}
check_account() {
log "[7] 开始检查账户信息"
# 检查空口令用户
log "[7.1] 开始检查空口令用户..."
empty_password_users=$(sudo awk -F: '($2 == "") {print $1}' /etc/shadow)
if [ -z "$empty_password_users" ]; then
log "未发现空口令用户"
else
log_danger "发现空口令用户: $empty_password_users"
fi
log_complete "空口令用户检查完成"
# 检查空口令且可以登录的用户
log "[7.2] 开始检查空口令且可登录的用户..."
empty_password_users=$(sudo awk -F: '($2 == "") {print $1}' /etc/shadow)
if [ -z "$empty_password_users" ]; then
log "未发现空口令用户"
else
log "发现空口令用户:"
echo "$empty_password_users" | while IFS= read -r user; do
login_shell=$(grep "^$user:" /etc/passwd | cut -d: -f7)
if [ "$login_shell" != "/sbin/nologin" ] && [ "$login_shell" != "/usr/sbin/nologin" ]; then
log_danger "发现空口令且可登录的用户: $user,登录Shell: $login_shell"
else
log "发现空口令但无法登录的用户: $user,登录Shell: $login_shell"
fi
done
fi
log_complete "空口令且可登录用户检查完成"
# 检查超级用户
log "[7.3] 开始检查超级用户..."
superusers=$(awk -F: '($3 == 0) && ($1 != "root") {print $1}' /etc/passwd)
if [ -z "$superusers" ]; then
log "未发现超级用户"
else
log_danger "发现超级用户: $superusers"
fi
log_complete "超级用户检查完成"
# 检查克隆账号
log "[7.4] 开始检查克隆账号..."
log "[7.4.1] 检查具有相同用户名的账号..."
duplicate_usernames=$(cut -d: -f1 /etc/passwd | sort | uniq -d)
if [ -z "$duplicate_usernames" ]; then
log "未发现具有相同用户名的账号"
else
log_danger "发现具有相同用户名的账号: $duplicate_usernames"
fi
log_complete "克隆账号检查完成"
log "[7.4.2] 检查具有相同UID的账号..."
duplicate_uids=$(cut -d: -f3 /etc/passwd | sort | uniq -d)
if [ -z "$duplicate_uids" ]; then
log "未发现具有相同UID的账号"
else
log_danger "发现具有相同UID的账号: $duplicate_uids"
for uid in $duplicate_uids; do
log_danger "UID为 $uid 的账号: $(grep ":$uid:" /etc/passwd)"
done
fi
log_complete "相同UID的账号检查完成"
# 检查可登录用户
log "[7.5] 开始检测可登录用户..."
valid_shells=$(getent passwd | awk -F: '($7 !~ /^(\/usr)?\/sbin\/nologin$|\/bin\/false$|\/usr\/lib\/gdm3\/gdm\-x\-session$/) {print $1}')
while IFS= read -r user; do
password_entry=$(sudo getent shadow "$user")
if [[ -n "$password_entry" ]]; then
password=$(echo "$password_entry" | cut -d: -f2)
if ! echo "$password" | grep -qE '^\!|^\*'; then
log "用户 $user 是一个有效的可登录用户"
fi
fi
done <<< "$valid_shells"
log_complete "可登录用户检测完成"
# 检查非系统用户
log "[7.6] 开始检查非系统用户..."
non_system_users=$(awk -F: '($3 >= 1000) {print $1, $3, $7}' /etc/passwd)
if [ -z "$non_system_users" ]; then
log "未发现非系统用户"
else
log "发现以下非系统用户可以登录:"
echo "$non_system_users" | while IFS=' ' read -r user uid shell; do
log "用户: $user"
done
fi
log_complete "非系统用户检查完成"
}
# 检测系统启动项
check_startup() {
log "[8] 开始检查系统启动项"
log "[8.1] 检查系统服务..."
# 检查 Systemd 服务
systemd_services=$(systemctl list-unit-files --state=enabled --type=service | awk 'NR>1 {print $1}' )
if [ -n "$systemd_services" ]; then
log "已启用的Systemd服务:"
echo "$systemd_services" | while IFS= read -r line; do
log " $line"
done
else
log "未发现已启用的Systemd服务"
fi
log_complete "检查完成"
# 检查 /etc/rc.local
log "[8.2] 检查/etc/rc.local文件..."
if [ -f /etc/rc.local ]; then
rc_local_content=$(cat /etc/rc.local)
if [ -n "$rc_local_content" ]; then
log "/etc/rc.local文件内容:"
echo "$rc_local_content" | while IFS= read -r line; do
log " $line"
done
else
log "/etc/rc.local文件为空"
fi
else
log "/etc/rc.local文件不存在"
fi
log_complete "/etc/rc.local文件检查完成"
# 检查 /etc/init.d 目录下的启动脚本
log "[8.3] 检查/etc/init.d目录..."
initd_scripts=$(ls -1 /etc/init.d/)
if [ -n "$initd_scripts" ]; then
log "/etc/init.d目录下的脚本:"
for script in $initd_scripts; do
if [ -x /etc/init.d/$script ]; then
log " $script"
fi
done
else
log "/etc/init.d目录下没有脚本"
fi
log_complete "/etc/init.d目录检查完成"
# 检查 chkconfig 管理的启动项
log "[8.4] 检查chkconfig管理的启动项..."
if command -v chkconfig &> /dev/null; then
chkconfig_items=$(chkconfig --list | grep -E ":on|启用|开" | awk '{print $1}' )
if [ -n "$chkconfig_items" ]; then
log "chkconfig管理的启动项:"
echo "$chkconfig_items" | while IFS= read -r line; do
log " $line"
done
else
log "未发现chkconfig管理的启动项"
fi
else
log "未找到chkconfig命令"
fi
log_complete "系统启动项检查完成"
}
# 检测 Crontab 任务
check_crontab() {
log "[9] 开始检查计划任务"
# 检测用户级别的 Crontab 任务
log "[9.1] 检查用户计划任务..."
# 获取所有用户
users=$(cut -d: -f1 /etc/passwd)
# 检查每个用户的计划任务
for user in $users; do
output=$(sudo crontab -l -u $user 2>&1)
if [[ $? -eq 0 ]] && ! echo "$output" | grep -q "no crontab for"; then
log "用户 $user 的计划任务:"
log "$output"
fi
done
log_complete "用户计划任务检查完成"
# 检测系统级别的定时任务
log "[9.2] 检查系统级计划任务..."
# 检查 /etc/crontab
if [ -f /etc/crontab ]; then
log "/etc/crontab文件内容:"
cat /etc/crontab | while IFS= read -r line; do
log " $line"
done
else
log "/etc/crontab文件不存在"
fi
# 检查 /etc/cron.d 目录
log "[9.3] 检查/etc/cron.d目录..."
if [ -d /etc/cron.d ]; then
log "/etc/cron.d目录内容:"
for file in /etc/cron.d/*; do
if [ -f "$file" ]; then
log " 文件: $file"
cat "$file" | while IFS= read -r line; do
log " $line"
done
fi
done
else
log "/etc/cron.d目录不存在"
fi
log "[9.4] 检查定时任务目录..."
# 检查 /etc/cron.daily, /etc/cron.hourly, /etc/cron.monthly, /etc/cron.weekly
for dir in /etc/cron.{daily,hourly,monthly,weekly}; do
if [ -d "$dir" ]; then
log "$dir"
for file in "$dir"/*; do
if [ -f "$file" ]; then
log " $file"
fi
done
else
log "目录 $dir 不存在"
fi
done
log_complete "计划任务检查完成"
}
# 检测路由和转发
check_routing_forwarded() {
log "[10] 开始检查路由和转发"
log "[10.1] 检查路由表..."
# 检测路由
routing_table=$(route -n)
if [ -n "$routing_table" ]; then
log "路由表条目:"
echo "$routing_table" | while IFS= read -r line; do
log " $line"
done
else
log "未发现路由表条目"
fi
log_complete "路由表检查完成"
# 检测 IP 转发设置
log "[10.2] 检查IPv4转发设置..."
# 检查 IPv4 转发
ipv4_forward=$(sysctl net.ipv4.ip_forward | awk '{print $3}')
if [ "$ipv4_forward" -eq 1 ]; then
log "IPv4转发已启用"
else
log "IPv4转发已禁用"
fi
log_complete "IPv4转发设置检查完成"
# 检查 IPv6 转发
log "[10.3] 检查IPv6转发设置..."
ipv6_forward=$(sysctl net.ipv6.conf.all.forwarding | awk '{print $3}')
if [ "$ipv6_forward" -eq 1 ]; then
log "IPv6转发已启用"
else
log "IPv6转发已禁用"
fi
log_complete "IPv6转发设置检查完成"
}
# 检测进程
check_processes() {
log "[11] 开始检查进程"
log "[11.1] 检查所有进程..."
# 获取所有进程信息
processes=$(ps aux)
if [ -n "$processes" ]; then
log "所有进程:"
echo "$processes" | while IFS= read -r line; do
log " $line"
done
else
log "未发现进程"
fi
log_complete "所有进程检查完成"
# 检测高资源消耗的进程
log "[11.2] 检查高资源消耗的进程..."
# 获取CPU和内存使用率前10的进程
high_cpu=$(ps aux --sort=-%cpu | head -n 11)
high_mem=$(ps aux --sort=-%mem | head -n 11)
if [ -n "$high_cpu" ]; then
log "高CPU使用率的进程:"
echo "$high_cpu" | while IFS= read -r line; do
log " $line"
done
else
log "未发现高CPU使用率的进程"
fi
log_complete "高CPU使用率的进程检查完成"
if [ -n "$high_mem" ]; then
log "高内存使用率的进程:"
echo "$high_mem" | while IFS= read -r line; do
log " $line"
done
else
log "未发现高内存使用率的进程"
fi
log_complete "高内存使用率的进程检查完成"
# 检测隐藏进程
log "[11.3] 检查隐藏进程..."
# 检查 /proc 目录下是否有隐藏的 PID
hidden_pids=$(ls -l /proc/ | grep -oP '^\d+' | sort -n | uniq)
if [ -n "$hidden_pids" ]; then
for pid in $hidden_pids; do
if ! ps -p $pid > /dev/null 2>&1; then
log_danger "发现隐藏进程: PID $pid"
fi
done
else
log "未发现隐藏进程"
fi
log_complete "隐藏进程检查完成"
}
# 检测重要的文件和配置
check_config() {
log "[12] 开始检查重要的文件和配置"
# 检测 hosts 文件
log "[12.1] 检查/etc/hosts文件..."
if [ -f /etc/hosts ]; then
log "/etc/hosts文件内容:"
cat /etc/hosts | while IFS= read -r line; do
log " $line"
done
else
log "/etc/hosts文件不存在"
fi
log_complete "hosts文件检查完成"
# 检测 DNS 配置
log "[12.2] 检查DNS配置..."
if [ -f /etc/resolv.conf ]; then
log "/etc/resolv.conf文件内容:"
cat /etc/resolv.conf | while IFS= read -r line; do
log " $line"
done
else
log "/etc/resolv.conf文件不存在"
fi
log_complete "DNS配置检查完成"
# 检测 Nginx 配置文件
log "[12.3] 检查Nginx配置文件..."
#检查是否加载了第三方.so文件
load_modules=$(grep -i 'load_module' /etc/nginx/nginx.conf)
if [ -n "$load_modules" ]; then
log "已加载第三方.so文件:"
echo "$load_modules" | while IFS= read -r module; do
log " $module"
done
else
log "未加载第三方.so文件"
fi
log_complete "Nginx配置文件检查完成"
# 检查 proxy_pass,以检测可能存在的hosts碰撞攻击
log "[12.4]开始检查proxy_pass"
proxy_pass_lines=$(grep -i 'proxy_pass' /etc/nginx/nginx.conf)
if [ -n "$proxy_pass_lines" ]; then
log "[*] proxy_pass directives found in the configuration:"
echo "$proxy_pass_lines" | while IFS= read -r line; do
log " $line"
done
log "[*] WARNING: proxy_pass directives are present. This may indicate potential security issues."
else
log "[*] 配置文件中未发现 proxy_passs配置"
fi
log_complete "Nginx配置文件检查完成"
# 检测 SSH 公私钥文件
log "[12.5] 开始检查SSH key 文件....."
ssh_dir="/root/.ssh"
if [ -d $ssh_dir ]; then
log "[*] SSH directory: $ssh_dir"
# 检查公钥文件
if [ -f $ssh_dir/id_rsa.pub ]; then
log "[*] Public key file: $ssh_dir/id_rsa.pub"
cat $ssh_dir/id_rsa.pub | while IFS= read -r line; do
log " $line"
done
else
log "[*] Public key file not found at $ssh_dir/id_rsa.pub."
fi
log_complete "SSH公钥文件检查完成"
# 检查私钥文件
if [ -f $ssh_dir/id_rsa ]; then
log "[*] Private key file: $ssh_dir/id_rsa"
else
log "[*] Private key file not found at $ssh_dir/id_rsa."
fi
else
log "[!!!] SSH目录未发现 $ssh_dir."
fi
log_complete "SSH公私钥文件检查完成"
# 检测 SSH 配置文件
log "[12.6] 开始检查ssh_config配置文件"
# 检查是否允许空口令用户
allow_empty_password=$(grep -i '^PermitEmptyPasswords' /etc/ssh/sshd_config | awk '{print $2}')
if [ "$allow_empty_password" == "yes" ]; then
log "WARNING: PermitEmptyPasswords is set to yes. This allows empty password authentication."
else
log "PermitEmptyPasswords未配置."
fi
log_complete "SSH配置文件检查完成"
# 检查是否禁止 root 登录
log "[12.7] 开始检查是否禁止 root 登录"
if [[ "$line" =~ ^PermitRootLogin\ no$ ]]; then
log "PermitRootLogin 未设置"
elif [[ "$line" =~ ^PermitRootLogin\ yes$ ]]; then
log_danger "PermitRootLogin配置了"
fi
log_complete "检查完成"
# 检查是否启用公钥认证
log "[12.8] 开始检查是否启用公钥认证"
if [[ "$line" =~ ^PubkeyAuthentication\ yes$ ]]; then
log "PubkeyAuthentication 未配置."
elif [[ "$line" =~ ^PubkeyAuthentication\ no$ ]]; then
log "PubkeyAuthentication 已配置."
fi
log_complete "是否启用公钥认证检查完成"
# 检查是否启用 X11 转发
log "[12.9] 开始检查是否启用 X11 转发"
if [[ "$line" =~ ^X11Forwarding\ yes$ ]]; then
log "X11Forwarding 未配置"
elif [[ "$line" =~ ^X11Forwarding\ no$ ]]; then
log "X11Forwarding 已配置."
fi
log_complete "是否启用 X11 转发检查完成"
# 检查是否启用 AgentForwarding
log "[12.10] 开始检查是否启用 AgentForwarding"
if [[ "$line" =~ ^AllowAgentForwarding\ yes$ ]]; then
log "AllowAgentForwarding 未配置."
elif [[ "$line" =~ ^AllowAgentForwarding\ no$ ]]; then
log "AllowAgentForwarding 已配置."
fi
log_complete " AgentForwarding检查完成"
# 检测环境变量配置
log "【12.11】开始检查环境变量"
env_files=("/etc/profile" "/etc/bashrc" "~/.bashrc")
for env_file in "${env_files[@]}"; do
if [ -f $env_file ]; then
log "发现环境变量"
cat $env_file | while IFS= read -r line; do
log " $line"
done
else
log "环境变量未发现"
fi
done
log_complete "环境变量检查完成 "
}
# 检测用户的 history 文件
log "[13] 开始检查用户的历史命令..."
check_user_history() {
local user=$1
local home_dir=$(getent passwd "$user" | cut -d: -f6)
local history_file="$home_dir/.bash_history"
if [ -f "$history_file" ]; then
log "检查用户 $user 的历史命令文件: $history_file"
# 读取历史命令
while IFS= read -r command; do
log " $command"
# 检查恶意命令
if [[ "$command" =~ ^sudo.* ]] || \
[[ "$command" =~ ^rm.* ]] || \
[[ "$command" =~ ^wget.* ]] || \
[[ "$command" =~ ^curl.* ]] || \
[[ "$command" =~ ^nc.* ]] || \
[[ "$command" =~ ^bash.* ]] || \
[[ "$command" =~ ^python.* ]] || \
[[ "$command" =~ ^perl.* ]] || \
[[ "$command" =~ ^telnet.* ]] || \
[[ "$command" =~ ^useradd.* ]] || \
[[ "$command" =~ ^userdel.* ]] || \
[[ "$command" =~ ^passwd.* ]] || \
[[ "$command" =~ ^nmap.* ]] || \
[[ "$command" =~ ^ssh.* ]] || \
[[ "$command" =~ ^scp.* ]] || \
[[ "$command" =~ ^ftp.* ]] || \
[[ "$command" =~ ^tftp.* ]] || \
[[ "$command" =~ ^openssl.* ]] || \
[[ "$command" =~ ^netcat.* ]]; then
log_danger "发现用户 $user 的潜在恶意命令: $command"
fi
done < "$history_file"
else
log_complete "用户 $user 未发现历史命令"
fi
}
# 检测所有用户的 history 文件
check_all_user_histories() {
log "[14] 开始检查所有用户的历史命令..."
# 获取所有用户
users=$(cut -d: -f1 /etc/passwd)
for user in $users; do
check_user_history "$user"
done
log "所有用户的历史命令检查完成"
}
# 定义关键文件列表
KEY_FILES=(
"/usr/bin/awk"
"/usr/bin/bash"
"/usr/bin/cat"
"/usr/bin/chattr"
"/usr/bin/chmod"
"/usr/bin/chown"
"/usr/bin/cp"
"/usr/bin/csh"
"/usr/bin/curl"
"/usr/bin/cut"
"/usr/bin/date"
"/usr/bin/df"
"/usr/bin/diff"
"/usr/bin/dirname"
"/usr/bin/dmesg"
"/usr/bin/du"
"/usr/bin/echo"
"/usr/bin/ed"
"/usr/bin/egrep"
"/usr/bin/env"
"/usr/bin/fgrep"
"/usr/bin/file"
"/usr/bin/find"
"/usr/bin/gawk"
"/usr/bin/GET"
"/usr/bin/grep"
"/usr/bin/groups"
"/usr/bin/head"
"/usr/bin/id"
"/usr/bin/ipcs"
"/usr/bin/kill"
"/usr/bin/killall"
"/usr/bin/kmod"
"/usr/bin/last"
"/usr/bin/lastlog"
"/usr/bin/ldd"
"/usr/bin/less"
"/usr/bin/locate"
"/usr/bin/logger"
"/usr/bin/login"
"/usr/bin/ls"
"/usr/bin/lsattr"
"/usr/bin/lynx"
"/usr/bin/mail"
"/usr/bin/mailx"
"/usr/bin/md5sum"
"/usr/bin/mktemp"
"/usr/bin/more"
"/usr/bin/mount"
"/usr/bin/mv"
"/usr/bin/netstat"
"/usr/bin/newgrp"
"/usr/bin/numfmt"
"/usr/bin/passwd"
"/usr/bin/perl"
"/usr/bin/pgrep"
"/usr/bin/ping"
"/usr/bin/pkill"
"/usr/bin/ps"
"/usr/bin/pstree"
"/usr/bin/pwd"
"/usr/bin/readlink"
"/usr/bin/runcon"
"/usr/bin/sed"
"/usr/bin/sh"
"/usr/bin/sha1sum"
"/usr/bin/sha224sum"
"/usr/bin/sha256sum"
"/usr/bin/sha384sum"
"/usr/bin/sha512sum"
"/usr/bin/size"
"/usr/bin/sort"
"/usr/bin/ssh"
"/usr/bin/stat"
"/usr/bin/strace"
"/usr/bin/strings"
"/usr/bin/su"
"/usr/bin/sudo"
"/usr/bin/systemctl"
"/usr/bin/tail"
"/usr/bin/tcsh"
"/usr/bin/telnet"
"/usr/bin/test"
"/usr/bin/top"
"/usr/bin/touch"
"/usr/bin/tr"
"/usr/bin/uname"
"/usr/bin/uniq"
"/usr/bin/users"
"/usr/bin/vmstat"
"/usr/bin/w"
"/usr/bin/watch"
"/usr/bin/wc"
"/usr/bin/wget"
"/usr/bin/whatis"
"/usr/bin/whereis"
"/usr/bin/which"
"/usr/bin/who"
"/usr/bin/whoami"
"/usr/lib/systemd/s"
"/usr/local/bin/rkh"
"/usr/sbin/adduser"
"/usr/sbin/chkconfi"
"/usr/sbin/chroot"
"/usr/sbin/depmod"
"/usr/sbin/fsck"
"/usr/sbin/fuser"
"/usr/sbin/groupadd"
"/usr/sbin/groupdel"
"/usr/sbin/groupmod"
"/usr/sbin/grpck"
"/usr/sbin/ifconfig"
"/usr/sbin/ifdown"
"/usr/sbin/ifup"
"/usr/sbin/init"
"/usr/sbin/insmod"
"/usr/sbin/ip"
"/usr/sbin/lsmod"
"/usr/sbin/lsof"
"/usr/sbin/modinfo"
"/usr/sbin/modprobe"
"/usr/sbin/nologin"
"/usr/sbin/pwck"
"/usr/sbin/rmmod"
"/usr/sbin/route"