-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathvulnerability_check_sh.sh
More file actions
457 lines (419 loc) · 18 KB
/
Copy pathvulnerability_check_sh.sh
File metadata and controls
457 lines (419 loc) · 18 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
#!/bin/sh
#===============================================================================
# Linux Server Vulnerability Check Script (Logic Correction v3.1)
# Version: 3.1 (Corrected U-07 to Manual Check & Reviewed subjective items)
#===============================================================================
set -e
export LANG=C
REPORT_FILE="vulnerability_report_$(date +%Y%m%d_%H%M%S).txt"
DET_REPORT_FILE="vulnerability_detailed_report_$(date +%Y%m%d_%H%M%S).txt"
TEMP_RESULT="result_$(date +%Y%m%d_%H%M%S).tmp"
OS_FAMILY=""
TOTAL=67
cleanup() { rm -f "$TEMP_RESULT"; }
trap cleanup EXIT
detect_os() {
if [ -f /etc/os-release ]; then . /etc/os-release; OS_FAMILY=$ID; else OS_FAMILY="unknown"; fi
}
show_progress() {
_cur=$1; _total=$2; _msg="${3:-""}"
_pct=$((_cur * 100 / _total))
_f=$((_pct / 5)); _e=$((20 - _f)); _bar=""; _c=0
while [ $_c -lt $_f ]; do _bar="${_bar}="; _c=$((_c+1)); done
_c=0; while [ $_c -lt $_e ]; do _bar="${_bar} "; _c=$((_c+1)); done
printf "\r[%s] %3d%% %-20s" "$_bar" "$_pct" "$_msg"
}
get_title() {
case "$1" in
U-01) echo "root 계정 원격 접속 제한" ;;
U-02) echo "비밀번호 관리정책 설정" ;;
U-03) echo "계정 잠금 임계값 설정" ;;
U-04) echo "비밀번호 파일 보호" ;;
U-05) echo "root 이외의 UID '0' 금지" ;;
U-06) echo "사용자 계정 su 기능 제한" ;;
U-07) echo "불필요한 계정 제거" ;;
U-08) echo "관리자 그룹에 최소한의 계정 포함" ;;
U-09) echo "계정이 존재하지 않는 GID 금지" ;;
U-10) echo "동일한 UID 금지" ;;
U-11) echo "사용자 Shell 점검" ;;
U-12) echo "세션 종료 시간 설정" ;;
U-13) echo "안전한 비밀번호 암호화 알고리즘 사용" ;;
U-14) echo "root 홈, 패스 디렉터리 권한 및 패스 설정" ;;
U-15) echo "파일 및 디렉터리 소유자 설정" ;;
U-16) echo "/etc/passwd 파일 소유자 및 권한 설정" ;;
U-17) echo "시스템 시작 스크립트 권한 설정" ;;
U-18) echo "/etc/shadow 파일 소유자 및 권한 설정" ;;
U-19) echo "/etc/hosts 파일 소유자 및 권한 설정" ;;
U-20) echo "/etc/xinetd.conf 파일 소유자 및 권한 설정" ;;
U-21) echo "/etc/syslog.conf 파일 소유자 및 권한 설정" ;;
U-22) echo "/etc/services 파일 소유자 및 권한 설정" ;;
U-23) echo "SUID, SGID, Sticky bit 설정 파일 점검" ;;
U-24) echo "사용자, 시스템 환경변수 파일 소유자 및 권한 설정" ;;
U-25) echo "World Writable 파일 점검" ;;
U-26) echo "/dev에 존재하지 않는 device 파일 점검" ;;
U-27) echo "r-command 사용 금지" ;;
U-28) echo "접속 IP 및 포트 제한" ;;
U-29) echo "hosts.lpd 파일 소유자 및 권한 설정" ;;
U-30) echo "UMASK 설정 관리" ;;
U-31) echo "홈 디렉토리 소유자 및 권한 설정" ;;
U-32) echo "홈 디렉토리로 지정한 디렉토리의 존재 관리" ;;
U-33) echo "숨겨진 파일 및 디렉토리 검색 및 제거" ;;
U-34) echo "Finger 서비스 비활성화" ;;
U-35) echo "공유 서비스에 대한 익명 접근 제한 설정" ;;
U-36) echo "r 계열 서비스 비활성화" ;;
U-37) echo "crontab 설정파일 권한 설정 미흡" ;;
U-38) echo "DoS 공격에 취약한 서비스 비활성화" ;;
U-39) echo "불필요한 NFS 서비스 비활성화" ;;
U-40) echo "NFS 접근 통제" ;;
U-41) echo "불필요한 automountd 제거" ;;
U-42) echo "불필요한 RPC 서비스 비활성화" ;;
U-43) echo "NIS, NIS+ 점검" ;;
U-44) echo "tftp, talk 서비스 비활성화" ;;
U-45) echo "메일 서비스 버전 점검" ;;
U-46) echo "일반 사용자의 메일 서비스 실행 방지" ;;
U-47) echo "스팸 메일 릴레이 제한" ;;
U-48) echo "expn, vrfy 명령어 제한" ;;
U-49) echo "DNS 보안 버전 패치" ;;
U-50) echo "DNS Zone Transfer 설정" ;;
U-51) echo "DNS 서비스의 취약한 동적 업데이트 설정 금지" ;;
U-52) echo "Telnet 서비스 비활성화" ;;
U-53) echo "FTP 서비스 정보 노출 제한" ;;
U-54) echo "암호화되지 않는 FTP 서비스 비활성화" ;;
U-55) echo "FTP 계정 Shell 제한" ;;
U-56) echo "FTP 서비스 접근 제어 설정" ;;
U-57) echo "Ftpusers 파일 설정" ;;
U-58) echo "불필요한 SNMP 서비스 구동 점검" ;;
U-59) echo "안전한 SNMP 버전 사용" ;;
U-60) echo "SNMP Community String 복잡성 설정" ;;
U-61) echo "SNMP Access Control 설정" ;;
U-62) echo "로그인 시 경고 메시지 설정" ;;
U-63) echo "sudo 명령어 접근 관리" ;;
U-64) echo "주기적 보안 패치 및 벤더 권고사항 적용" ;;
U-65) echo "NTP 및 시각 동기화 설정" ;;
U-66) echo "정책에 따른 시스템 로깅 설정" ;;
U-67) echo "로그 디렉터리 소유자 및 권한 설정" ;;
*) echo "보안 점검 항목" ;;
esac
}
#-------------------------------------------------------------------------------
# Check Functions
#-------------------------------------------------------------------------------
is_svc_active() {
svc=$1
if command -v systemctl >/dev/null; then
if systemctl is-active "$svc" 2>/dev/null | grep -q "^active$"; then return 0; fi
fi
if ps -ef | grep -v grep | grep -q "$svc"; then return 0; fi
return 1
}
check_file_perm() {
file=$1; max=$2; owner=$3
if [ ! -e "$file" ]; then echo "해당없음|파일 미존재 ($file)"; return; fi
p=$(stat -c "%a" "$file"); o=$(stat -c "%U" "$file")
if [ "$p" -le "$max" ] && [ "$o" = "$owner" ]; then
echo "양호|권한:$p 소유자:$o"
else
echo "취약|권한:$p 소유자:$o (기준:$max/$owner)"
fi
}
check_U01() {
if [ -f /etc/ssh/sshd_config ]; then
val=$(grep -E "^[[:space:]]*PermitRootLogin" /etc/ssh/sshd_config | awk '{print $2}' | tail -1)
if [ "$val" = "no" ]; then
echo "양호|SSH PermitRootLogin이 no로 설정됨"
else
echo "취약|SSH PermitRootLogin 설정 미흡 ($val)"
fi
else
if is_svc_active sshd; then
echo "수동점검|SSHD 실행 중이나 설정 파일 미발견 (경로 확인 필요)"
else
echo "양호|SSHD 미실행 (원격 접속 제한)"
fi
fi
}
check_U02() {
evidence=""
found=0
if [ -f /etc/security/pwquality.conf ]; then
val=$(grep -E "minlen|credit" /etc/security/pwquality.conf | xargs)
if [ -n "$val" ]; then evidence="pwquality.conf: $val"; found=1; fi
fi
if [ -f /etc/pam.d/common-password ]; then
val=$(grep "pam_pwquality.so" /etc/pam.d/common-password | grep -v "^#" | xargs)
if [ -n "$val" ]; then evidence="$evidence / common-password 설정됨"; found=1; fi
fi
if [ "$found" -eq 1 ]; then echo "양호|설정 확인: $evidence"; else echo "수동점검|패스워드 복잡성 설정 파일 미발견 (확인 필요)"; fi
}
check_U03() {
found=0; val=""
for f in /etc/pam.d/system-auth /etc/pam.d/password-auth /etc/pam.d/common-auth; do
if [ -f "$f" ]; then
res=$(grep -E "pam_tally2|pam_faillock" "$f" | grep -v "^#" | head -1)
if [ -n "$res" ]; then
deny=$(echo "$res" | grep -o "deny=[0-9]*" | cut -d= -f2)
if [ -n "$deny" ]; then val="파일:$f 임계값:$deny"; if [ "$deny" -le 10 ]; then found=1; fi; fi
fi
fi
done
if [ "$found" -eq 1 ]; then echo "양호|$val"; else echo "수동점검|임계값 설정 미발견 (수동 확인 필요)"; fi
}
check_U04() {
if [ ! -f /etc/shadow ]; then
echo "취약|/etc/shadow 파일 없음 (패스워드 노출 위험)"
else
if awk -F: '$2 != "x" {print $1}' /etc/passwd | grep -q .; then
echo "취약|쉐도우 미사용 계정 존재"
else
echo "양호|쉐도우 패스워드 사용 중"
fi
fi
}
check_U05() {
users=$(awk -F: '$3 == 0 && $1 != "root" {print $1}' /etc/passwd)
if [ -n "$users" ]; then echo "취약|root 외 UID 0 계정 존재: $users"; else echo "양호|root 외 UID 0 계정 없음"; fi
}
check_U06() {
pam_check=0
if [ -f /etc/pam.d/su ]; then
if grep -q "pam_wheel.so" /etc/pam.d/su | grep -v "^#"; then pam_check=1; fi
fi
perm_check=0
if [ -f /usr/bin/su ]; then
perm=$(stat -c "%a" /usr/bin/su)
group=$(stat -c "%G" /usr/bin/su)
if [ "$perm" = "4750" ] && [ "$group" = "wheel" ]; then perm_check=1; fi
fi
if [ "$pam_check" -eq 1 ] || [ "$perm_check" -eq 1 ]; then
echo "양호|su 제한 설정됨 (PAM 또는 권한)"
else
echo "취약|su 제한 설정 미흡 (PAM 주석/미설정 및 권한 4750 아님)"
fi
}
check_U07() {
echo "수동점검|관리자 검토 필요 (운영 목적상 불필요한 계정 /etc/passwd 확인)"
}
check_U08() {
members=$(grep "^root:" /etc/group | cut -d: -f4)
if [ -z "$members" ]; then echo "양호|root 그룹에 추가 계정 없음"; else echo "취약|root 그룹 구성원 확인 필요: $members"; fi
}
check_U09() {
echo "수동점검|/etc/group 무결성 확인 필요"
}
check_U10() {
dups=$(awk -F: '{print $3}' /etc/passwd | sort | uniq -d)
if [ -n "$dups" ]; then echo "취약|중복 UID 발견: $dups"; else echo "양호|중복 UID 없음"; fi
}
check_U11() {
bad=0
for u in daemon bin sys adm listen nobody nobody4 noaccess diag operator games gopher; do
shell=$(grep "^$u:" /etc/passwd | awk -F: '{print $7}')
if [ -n "$shell" ] && [ "$shell" != "/bin/false" ] && [ "$shell" != "/usr/sbin/nologin" ] && [ "$shell" != "/sbin/nologin" ]; then
bad=1; break
fi
done
if [ "$bad" -eq 1 ]; then echo "취약|시스템 계정에 로그인 쉘 부여됨"; else echo "양호|시스템 계정 쉘 제한됨"; fi
}
check_U12() {
val=$(grep -h "TMOUT" /etc/profile /etc/bashrc /etc/bash.bashrc /etc/profile.d/*.sh 2>/dev/null | grep -v "#" | awk -F= '{print $2}' | head -1)
if [ -n "$val" ] && [ "$val" -le 600 ]; then echo "양호|TMOUT=$val"; else echo "취약|TMOUT 미설정 또는 600초 초과"; fi
}
check_U13() {
method=$(grep "^ENCRYPT_METHOD" /etc/login.defs 2>/dev/null | awk '{print $2}')
if [ "$method" = "SHA512" ] || [ "$method" = "SHA256" ]; then echo "양호|암호화 방식: $method"; else echo "취약|암호화 방식: $method (SHA512 권장)"; fi
}
check_U14() {
if echo "$PATH" | grep -qE "\.:|::|:\."; then echo "취약|PATH에 '.' 포함됨"; else echo "양호|PATH 환경변수 설정 양호"; fi
}
check_U15() {
echo "수동점검|소유자 없는 파일 점검 (find 명령 부하 방지)"
}
check_U16() { check_file_perm "/etc/passwd" 644 "root"; }
check_U17() { check_file_perm "/etc/inetd.conf" 600 "root"; }
check_U18() { check_file_perm "/etc/shadow" 400 "root"; }
check_U19() { check_file_perm "/etc/hosts" 644 "root"; }
check_U20() { check_file_perm "/etc/xinetd.conf" 600 "root"; }
check_U21() {
if [ -f /etc/rsyslog.conf ]; then check_file_perm "/etc/rsyslog.conf" 644 "root";
else echo "취약|Syslog 설정 파일 없음"; fi
}
check_U22() { check_file_perm "/etc/services" 644 "root"; }
check_U23() {
echo "수동점검|전체 검색 생략"
}
check_U24() {
echo "수동점검|홈 환경변수 파일 권한 확인 필요"
}
check_U25() {
echo "수동점검|전체 검색 생략"
}
check_U26() {
echo "수동점검|/dev 장치 파일 확인 필요"
}
check_U27() {
files=""
[ -f /etc/hosts.equiv ] && files="/etc/hosts.equiv"
[ -f /root/.rhosts ] && files="$files /root/.rhosts"
count=0
for d in /home/*;
do
if [ -f "$d/.rhosts" ]; then files="$files $d/.rhosts"; fi
count=$((count+1)); if [ "$count" -ge 5 ]; then break; fi
done
if [ -n "$files" ]; then echo "취약|r-command 설정 파일 존재: $files"; else echo "양호|r-command 설정 파일 미발견"; fi
}
check_U28() {
if [ -f /etc/hosts.deny ]; then
if grep -q "ALL:ALL" /etc/hosts.deny; then echo "양호|hosts.deny 설정됨"; return; fi
fi
if command -v iptables >/dev/null && iptables -L -n 2>/dev/null | grep -q "Chain"; then
echo "수동점검|Firewall 활성화됨 (규칙 확인 필요)"; return
fi
echo "취약|접근 제어 미설정 (hosts.deny, iptables 등 미확인)"
}
check_U29() { check_file_perm "/etc/hosts.lpd" 600 "root"; }
check_U30() {
val=$(grep -i "umask" /etc/profile /etc/bashrc /etc/login.defs 2>/dev/null | grep -v "#" | awk '{print $NF}' | head -1)
if [ -n "$val" ]; then
if [ "$val" = "022" ] || [ "$val" = "027" ]; then echo "양호|UMASK: $val"; else echo "취약|UMASK: $val"; fi
else echo "수동점검|UMASK 자동 확인 불가"; fi
}
check_U31() {
echo "수동점검|홈 디렉토리 소유자/권한 확인 필요"
}
check_U32() {
echo "수동점검|홈 디렉토리 존재 여부 확인 필요"
}
check_U33() {
echo "수동점검|숨겨진 파일/디렉토리 확인 필요"
}
check_svc() {
svc=$1
if ! systemctl list-unit-files "$svc*" 2>/dev/null | grep -q "$svc"; then
echo "양호|$svc 미설치"
return
fi
if is_svc_active "$svc"; then
echo "취약|$svc 실행 중";
else
echo "양호|$svc 비활성화";
fi
}
check_U34() { check_svc "finger"; }
check_U35() { if [ -d /var/ftp/pub ]; then echo "취약|익명 FTP 폴더 존재"; else echo "양호|익명 FTP 폴더 미발견"; fi }
check_U36() { check_svc "rsh"; }
check_U37() {
if [ -f /etc/cron.allow ]; then check_file_perm "/etc/cron.allow" 640 "root";
elif [ -f /etc/cron.deny ]; then check_file_perm "/etc/cron.deny" 640 "root";
else echo "양호|cron 접근제어 파일 없음"; fi
}
check_U38() {
echo "수동점검|DoS 취약 서비스(echo, discard 등) 확인 필요"
}
check_U39() { check_svc "nfs-server"; }
check_U40() { check_svc "nfs"; }
check_U41() { check_svc "autofs"; }
check_U42() { check_svc "rpcbind"; }
check_U43() { check_svc "ypserv"; }
check_U44() { check_svc "tftp"; }
check_U45() {
echo "수동점검|메일 서비스 버전 확인 필요"
}
check_U46() {
if [ -f /etc/mail/sendmail.cf ]; then
if grep -q "restrictqrun" /etc/mail/sendmail.cf; then echo "양호|restrictqrun 설정됨"; else echo "취약|restrictqrun 미설정"; fi
else
if is_svc_active sendmail;
then
echo "수동점검|Sendmail 실행 중이나 설정 파일 미발견"
else
echo "양호|Sendmail 미실행"
fi
fi
}
check_U47() {
if [ -f /etc/mail/sendmail.cf ]; then
if grep -q "Relaying denied" /etc/mail/sendmail.cf; then echo "양호|Relaying denied 설정됨"; else echo "취약|릴레이 제한 미설정"; fi
else
if is_svc_active sendmail;
then
echo "수동점검|Sendmail 실행 중이나 설정 파일 미발견"
else
echo "양호|Sendmail 미실행"
fi
fi
}
check_U48() {
echo "수동점검"
}
check_U49() {
echo "수동점검"
}
check_U50() {
echo "수동점검"
}
check_U51() {
echo "수동점검"
}
check_U52() { check_svc "telnet.socket"; }
check_U53() {
echo "수동점검"
}
check_U54() { check_svc "vsftpd"; }
check_U55() {
if grep -q "^ftp:" /etc/passwd;
then
shell=$(grep "^ftp:" /etc/passwd | awk -F: '{print $7}')
if [ "$shell" = "/bin/false" ] || [ "$shell" = "/usr/sbin/nologin" ]; then echo "양호|FTP 쉘 제한됨"; else echo "취약|FTP 쉘: $shell"; fi
else echo "양호|FTP 계정 없음"; fi
}
check_U56() {
echo "수동점검|FTP 접근 제어 설정 확인 (ftpusers 등)"
}
check_U57() { if grep -q "root" /etc/ftpusers 2>/dev/null; then echo "양호|root 차단 설정됨"; else echo "수동점검|ftpusers 미발견 또는 root 미포함"; fi }
check_U58() { check_svc "snmpd"; }
check_U59() {
echo "수동점검"
}
check_U60() {
echo "수동점검"
}
check_U61() {
echo "수동점검"
}
check_U62() { if [ -s /etc/motd ]; then echo "양호|경고 메시지 파일 존재"; else echo "취약|경고 메시지 파일이 비어있거나 없음"; fi }
check_U63() { check_file_perm "/etc/sudoers" 440 "root"; }
check_U64() {
echo "수동점검"
}
check_U65() {
if is_svc_active chronyd || is_svc_active ntpd; then echo "양호|시간 동기화 서비스 동작 중"; else echo "취약|시간 동기화 서비스 미실행"; fi
}
check_U66() { check_file_perm "/etc/rsyslog.conf" 644 "root"; }
check_U67() {
p=$(stat -c "%a" /var/log); if [ "$p" -le 755 ]; then echo "양호|/var/log 권한: $p"; else echo "취약|/var/log 권한: $p"; fi
}
main() {
detect_os
{ echo "ID|Status|Reason"; } > "$TEMP_RESULT"
i=1
while [ "$i" -le "$TOTAL" ]; do
if [ "$i" -lt 10 ]; then id="U-0$i"; else id="U-$i"; fi
printf "\rChecking %s ... " "$id"
fn_suffix=$(echo "$id" | tr -d '-')
fn="check_$fn_suffix"
if command -v "$fn" >/dev/null; then res=$($fn); else res="점검불가|스크립트 미구현"; fi
echo "$id|$res" >> "$TEMP_RESULT"
i=$((i+1))
done
printf "\rDone. \n"
{ echo "Linux Vulnerability Check Report"; echo "Date: $(date)"; echo "----------------------------------------------------"; } > "$REPORT_FILE"
{ echo "Linux Vulnerability Detailed Report"; echo "Date: $(date)"; echo "----------------------------------------------------"; printf "% -6s | % -40s | %s\n" "ID" "Item" "Result"; } > "$DET_REPORT_FILE"
tail -n +2 "$TEMP_RESULT" | while IFS='|' read -r r_id r_status r_reason; do
printf "% -6s : %s\n" "$r_id" "$r_status" >> "$REPORT_FILE"
title=$(get_title "$r_id")
printf "% -6s | % -40s | %s (%s)\n" "$r_id" "$title" "$r_status" "$r_reason" >> "$DET_REPORT_FILE"
done
rm -f "$TEMP_RESULT"
}
main "$@"