├── LINUX ├── CentOS │ ├── CentOS6_Script.sh │ └── CentOS7_Script.sh ├── Fedora │ └── Fedora38_Script.sh ├── Rocky │ └── Rocky_Script.sh └── Ubuntu │ └── Ubuntu_Script.sh └── readme.md /LINUX/CentOS/CentOS6_Script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | resultfile="Results_$(date '+%F_%H:%M:%S').txt" 4 | 5 | U_01() { 6 | echo "" >> $resultfile 2>&1 7 | echo "▶ U-01(상) | 1. 계정관리 > 1.1 root 계정 원격접속 제한 ◀" >> $resultfile 2>&1 8 | echo " 양호 판단 기준 : 원격 터미널 서비스를 사용하지 않거나, 사용 시 root 직접 접속을 차단한 경우" >> $resultfile 2>&1 9 | if [ -f /etc/services ]; then 10 | # /etc/services 파일 내 telnet 서비스의 포트 번호가 설정되어 있는지 확인하고, 설정되어 있다면 실행 중인지 확인함 11 | telnet_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="telnet" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 12 | if [ $telnet_port_count -gt 0 ]; then 13 | telnet_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="telnet" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 14 | for ((i=0; i<${#telnet_port[@]}; i++)) 15 | do 16 | netstat_telnet_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${telnet_port[$i]} " | wc -l` 17 | if [ $netstat_telnet_count -gt 0 ]; then 18 | if [ -f /etc/pam.d/login ]; then 19 | pam_securetty_so_count=`grep -vE '^#|^\s#' /etc/pam.d/login | grep -i 'pam_securetty.so' | wc -l` 20 | if [ $pam_securetty_so_count -gt 0 ]; then 21 | if [ -f /etc/securetty ]; then 22 | etc_securetty_pts_count=`grep -vE '^#|^\s#' /etc/securetty | grep '^ *pts' | wc -l` 23 | if [ $etc_securetty_pts_count -gt 0 ]; then 24 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 25 | echo " telnet 서비스를 사용하고, /etc/securetty 파일에 pts 부분이 제거 또는 주석 처리되어 있지 않습니다." >> $resultfile 2>&1 26 | return 0 27 | fi 28 | else 29 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 30 | echo " telnet 서비스를 사용하고, /etc/securetty 파일이 없습니다." >> $resultfile 2>&1 31 | return 0 32 | fi 33 | else 34 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 35 | echo " telnet 서비스를 사용하고, /etc/pam.d/login 파일에 pam_securetty.so 모듈이 제거 또는 주석 처리되어 있습니다." >> $resultfile 2>&1 36 | return 0 37 | fi 38 | else 39 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 40 | echo " telnet 서비스를 사용하고, /etc/pam.d/login 파일이 없습니다." >> $resultfile 2>&1 41 | return 0 42 | fi 43 | fi 44 | done 45 | fi 46 | fi 47 | # 위 과정에서 확인되지 않을 경우를 대비하여 ps 명령으로 telnet 서비스가 실행 중인지 확인함 48 | ps_telnet_count=`ps -ef | grep -i 'telnet' | grep -v 'grep' | wc -l` 49 | if [ $ps_telnet_count -gt 0 ]; then 50 | if [ -f /etc/pam.d/login ]; then 51 | pam_securetty_so_count=`grep -vE '^#|^\s#' /etc/pam.d/login | grep -i 'pam_securetty.so' | wc -l` 52 | if [ $pam_securetty_so_count -gt 0 ]; then 53 | if [ -f /etc/securetty ]; then 54 | etc_securetty_pts_count=`grep -vE '^#|^\s#' /etc/securetty | grep '^ *pts' | wc -l` 55 | if [ $etc_securetty_pts_count -gt 0 ]; then 56 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 57 | echo " telnet 서비스를 사용하고, /etc/securetty 파일에 pts 부분이 제거 또는 주석 처리되어 있지 않습니다." >> $resultfile 2>&1 58 | return 0 59 | fi 60 | else 61 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 62 | echo " telnet 서비스를 사용하고, /etc/securetty 파일이 없습니다." >> $resultfile 2>&1 63 | return 0 64 | fi 65 | else 66 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 67 | echo " telnet 서비스를 사용하고, /etc/pam.d/login 파일에 pam_securetty.so 모듈이 제거 또는 주석 처리되어 있습니다." >> $resultfile 2>&1 68 | return 0 69 | fi 70 | else 71 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 72 | echo " telnet 서비스를 사용하고, /etc/pam.d/login 파일이 없습니다." >> $resultfile 2>&1 73 | return 0 74 | 75 | fi 76 | fi 77 | # sshd_config 파일의 존재 여부를 검색하고, 존재한다면 ssh 서비스가 실행 중일 때 점검할 별도의 배열에 저장함 78 | sshd_config_count=`find / -name 'sshd_config' -type f 2> /dev/null | wc -l` 79 | if [ $sshd_config_count -gt 0 ]; then 80 | sshd_config_file=(`find / -name 'sshd_config' -type f 2> /dev/null`) 81 | fi 82 | # /etc/services 파일 내 ssh 서비스의 포트 번호가 설정되어 있는지 확인하고, 설정되어 있다면 실행 중인지 확인함 83 | if [ -f /etc/services ]; then 84 | ssh_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ssh" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 85 | if [ $ssh_port_count -gt 0 ]; then 86 | ssh_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ssh" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 87 | for ((i=0; i<${#ssh_port[@]}; i++)) 88 | do 89 | netstat_sshd_enable_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ssh_port[$i]} " | wc -l` 90 | if [ $netstat_sshd_enable_count -gt 0 ]; then 91 | if [ ${#sshd_config_file[@]} -eq 0 ]; then 92 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 93 | echo " ssh 서비스를 사용하고, sshd_config 파일이 없습니다." >> $resultfile 2>&1 94 | return 0 95 | fi 96 | for ((j=0; j<${#sshd_config_file[@]}; j++)) 97 | do 98 | sshd_permitrootlogin_no_count=`grep -vE '^#|^\s#' ${sshd_config_file[$j]} | grep -i 'permitrootlogin' | grep -i 'no' | wc -l` 99 | if [ $sshd_permitrootlogin_no_count -eq 0 ]; then 100 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 101 | echo " ssh 서비스를 사용하고, sshd_config 파일에서 root 계정의 원격 접속이 허용되어 있습니다." >> $resultfile 2>&1 102 | return 0 103 | fi 104 | done 105 | fi 106 | done 107 | fi 108 | fi 109 | # 위 과정에서 확인되지 않을 경우를 대비하여 sshd_config 파일 내 ssh 서비스의 포트 번호가 설정되어 있는지 확인하고, 설정되어 있다면 실행 중인지 확인함 110 | if [ ${#sshd_config_file[@]} -gt 0 ]; then 111 | for ((i=0; i<${#sshd_config_file[@]}; i++)) 112 | do 113 | ssh_port_count=`grep -vE '^#|^\s#' ${sshd_config_file[$i]} | grep -i 'port' | awk '{print $2}' | wc -l` 114 | if [ $ssh_port_count -gt 0 ]; then 115 | ssh_port=(`grep -vE '^#|^\s#' ${sshd_config_file[$i]} | grep -i 'port' | awk '{print $2}'`) 116 | for ((j=0; j<${#ssh_port[@]}; j++)) 117 | do 118 | netstat_sshd_enable_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ssh_port[$j]} " | wc -l` 119 | if [ $netstat_sshd_enable_count -gt 0 ]; then 120 | for ((k=0; k<${#sshd_config_file[@]}; k++)) 121 | do 122 | sshd_permitrootlogin_no_count=`grep -vE '^#|^\s#' ${sshd_config_file[$k]} | grep -i 'permitrootlogin' | grep -i 'no' | wc -l` 123 | if [ $sshd_permitrootlogin_no_count -eq 0 ]; then 124 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 125 | echo " ssh 서비스를 사용하고, sshd_config 파일에서 root 계정의 원격 접속이 허용되어 있습니다." >> $resultfile 2>&1 126 | return 0 127 | fi 128 | done 129 | fi 130 | done 131 | fi 132 | done 133 | fi 134 | # 위 과정에서 확인되지 않을 경우를 대비하여 ps 명령으로 ssh 서비스가 실행 중인지 확인함 135 | ps_sshd_enable_count=`ps -ef | grep -i 'sshd' | grep -v 'grep' | wc -l` 136 | if [ $ps_sshd_enable_count -gt 0 ]; then 137 | if [ ${#sshd_config_file[@]} -eq 0 ]; then 138 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 139 | echo " ssh 서비스를 사용하고, sshd_config 파일이 없습니다." >> $resultfile 2>&1 140 | return 0 141 | fi 142 | for ((i=0; i<${#sshd_config_file[@]}; i++)) 143 | do 144 | sshd_permitrootlogin_no_count=`grep -vE '^#|^\s#' ${sshd_config_file[$i]} | grep -i 'permitrootlogin' | grep -i 'no' | wc -l` 145 | if [ $sshd_permitrootlogin_no_count -eq 0 ]; then 146 | echo "※ U-01 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 147 | echo " ssh 서비스를 사용하고, sshd_config 파일에서 root 계정의 원격 접속이 허용되어 있습니다." >> $resultfile 2>&1 148 | return 0 149 | fi 150 | done 151 | fi 152 | echo "※ U-01 결과 : 양호(Good)" >> $resultfile 2>&1 153 | return 0 154 | } 155 | 156 | U_02() { 157 | echo "" >> $resultfile 2>&1 158 | echo "▶ U-02(상) | 1. 계정관리 > 1.2 패스워드 복잡성 설정 ◀" >> $resultfile 2>&1 159 | echo " 양호 판단 기준 : 패스워드 최소길이 8자리 이상, 영문·숫자·특수문자 최소 입력 기능이 설정된 경우" >> $resultfile 2>&1 160 | file_exists_count=0 # 패스워드 설정 파일 존재 시 카운트할 변수 161 | minlen_file_exists_count=0 # 패스워드 최소 길이 설정 파일 존재 시 카운트할 변수 162 | no_settings_in_minlen_file=0 # 설정 파일 존재하는데, 최소 길이에 대한 설정이 없을 때 카운트할 변수 -> 추후 file_exists_count 변수와 값을 비교하여 동일하면 모든 파일에 패스워드 최소 길이 설정이 없는 것이므로 취약으로 판단함 163 | mininput_file_exists_count=0 # 패스워드 최소 입력 설정 파일 존재 시 카운트할 변수 164 | no_settings_in_mininput_file=0 # 설정 파일 존재하는데, 최소 입력에 대한 설정이 없을 때 카운트할 변수 -> 추후 mininput_file_exists_count 변수와 값을 비교하여 동일하면 모든 파일에 패스워드 최소 입력 설정이 없는 것이므로 취약으로 판단함 165 | input_options=("lcredit" "ucredit" "dcredit" "ocredit") 166 | input_modules=("pam_pwquality.so" "pam_cracklib.so" "pam_unix.so") 167 | # /etc/login.defs 파일 내 패스워드 최소 길이 설정 확인함 168 | if [ -f /etc/login.defs ]; then 169 | ((file_exists_count++)) 170 | ((minlen_file_exists_count++)) 171 | etc_logindefs_minlen_count=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MIN_LEN' | awk '{print $2}' | wc -l` 172 | if [ $etc_logindefs_minlen_count -gt 0 ]; then 173 | etc_logindefs_minlen_value=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MIN_LEN' | awk '{print $2}'` 174 | if [ $etc_logindefs_minlen_value -lt 8 ]; then 175 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 176 | echo " /etc/login.defs 파일에 최소 길이(PASS_MIN_LEN)가 8 미만으로 설정되어 있습니다." >> $resultfile 2>&1 177 | return 0 178 | fi 179 | else 180 | ((no_settings_in_minlen_file++)) 181 | fi 182 | fi 183 | # /etc/pam.d/system-auth, /etc/pam.d/password-auth 파일 내 패스워드 최소 길이와 최소 입력 확인함 184 | pw_settings_files=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth") 185 | for ((i=0; i<${#pw_settings_files[@]}; i++)) 186 | do 187 | if [ -f ${pw_settings_files[$i]} ]; then 188 | ((file_exists_count++)) 189 | # 패스워드 최소 길이 체크 190 | for ((j=0; j<${#input_modules[@]}; j++)) 191 | do 192 | ((minlen_file_exists_count++)) 193 | pw_settings_file_minlen_count=`grep -vE '^#|^\s#' ${pw_settings_files[$i]} | grep -i 'minlen' | grep -i ${input_modules[$j]} | wc -l` 194 | if [ $pw_settings_file_minlen_count -gt 0 ]; then 195 | pw_settings_file_minlen_value=`grep -vE '^#|^\s#' ${pw_settings_files[$i]} | grep -i 'minlen' | grep -i ${input_modules[$j]} | awk -F 'minlen' '{gsub(" ", "", $0); print substr($2,2,1)}'` 196 | if [ $pw_settings_file_minlen_value -lt 8 ]; then 197 | pw_settings_file_minlen_second_value=`grep -vE '^#|^\s#' ${pw_settings_files[$i]} | grep -i 'minlen' | grep -i ${input_modules[$j]} | awk -F 'minlen' '{gsub(" ", "", $0); print substr($2,3,1)}'` 198 | if [[ $pw_settings_file_minlen_second_value != [0-9] ]]; then 199 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 200 | echo " ${pw_settings_files[$i]} 파일에 최소 길이(minlen)가 8 미만으로 설정되어 있습니다." >> $resultfile 2>&1 201 | return 0 202 | fi 203 | fi 204 | else 205 | ((no_settings_in_minlen_file++)) 206 | fi 207 | done 208 | # 패스워드 최소 입력 체크 209 | for ((j=0; j<${#input_modules[@]}; j++)) 210 | do 211 | for ((k=0; k<${#input_options[@]}; k++)) 212 | do 213 | ((mininput_file_exists_count++)) 214 | pw_settings_file_mininput_count=`grep -vE '^#|^\s#' ${pw_settings_files[$i]} | grep -i ${input_options[$k]} | grep -i ${input_modules[$j]} | wc -l` 215 | if [ $pw_settings_file_mininput_count -gt 0 ]; then 216 | pw_settings_file_mininput_dash=`grep -vE '^#|^\s#' ${pw_settings_files[$i]} | grep -i ${input_options[$k]} | grep -i ${input_modules[$j]} | awk -F ${input_options[$k]} '{gsub(" ", "", $0); print substr($2,2,1)}'` 217 | if [[ $pw_settings_file_mininput_dash =~ - ]]; then 218 | pw_settings_file_mininput_value=`grep -vE '^#|^\s#' ${pw_settings_files[$i]} | grep -i ${input_options[$k]} | grep -i ${input_modules[$j]} | awk -F ${input_options[$k]} '{gsub(" ", "", $0); print substr($2,3,1)}'` 219 | if [ $pw_settings_file_mininput_value -lt 1 ]; then 220 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 221 | echo " ${pw_settings_files[$i]} 파일에 영문, 숫자, 특수문자의 최소 입력이 1 미만으로 설정되어 있습니다." >> $resultfile 2>&1 222 | return 0 223 | fi 224 | else 225 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 226 | echo " /${pw_settings_files[$i]} 파일에 영문, 숫자, 특수문자의 최소 입력에 대한 설정이 없습니다." >> $resultfile 2>&1 227 | return 0 228 | fi 229 | else 230 | ((no_settings_in_mininput_file++)) 231 | fi 232 | done 233 | done 234 | fi 235 | done 236 | if [ $file_exists_count -eq 0 ]; then 237 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 238 | echo " 패스워드의 복잡성을 설정하는 파일이 없습니다." >> $resultfile 2>&1 239 | return 0 240 | elif [ $minlen_file_exists_count -eq $no_settings_in_minlen_file ]; then 241 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 242 | echo " 패스워드의 최소 길이를 설정한 파일이 없습니다." >> $resultfile 2>&1 243 | return 0 244 | elif [ $mininput_file_exists_count -eq $no_settings_in_mininput_file ]; then 245 | echo "※ U-02 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 246 | echo " 패스워드의 영문, 숫자, 특수문자의 최소 입력을 설정한 파일이 없습니다." >> $resultfile 2>&1 247 | return 0 248 | fi 249 | echo "※ U-02 결과 : 양호(Good)" >> $resultfile 2>&1 250 | return 0 251 | } 252 | 253 | U_03() { 254 | echo "" >> $resultfile 2>&1 255 | echo "▶ U-03(상) | 1. 계정관리 > 1.3 계정 잠금 임계값 설정 ◀" >> $resultfile 2>&1 256 | echo " 양호 판단 기준 : 계정 잠금 임계값이 10회 이하의 값으로 설정되어 있는 경우" >> $resultfile 2>&1 257 | file_exists_count=0 258 | deny_file_exists_count=0 259 | no_settings_in_deny_file=0 260 | deny_modules=("pam_tally2.so" "pam_faillock.so") 261 | # /etc/pam.d/system-auth, /etc/pam.d/password-auth 파일 내 계정 잠금 임계값 설정 확인함 262 | deny_settings_files=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth") 263 | for ((i=0; i<${#deny_settings_files[@]}; i++)) 264 | do 265 | if [ -f ${deny_settings_files[$i]} ]; then 266 | ((file_exists_count++)) 267 | for ((i=0; i<${#deny_modules[@]}; i++)) 268 | do 269 | ((deny_file_exists_count++)) 270 | deny_settings_file_deny_count=`grep -vE '^#|^\s#' ${deny_settings_files[$i]} | grep -i ${deny_modules[$i]} | grep -i 'deny' | wc -l` 271 | if [ $deny_settings_file_deny_count -gt 0 ]; then 272 | deny_settings_file_deny_value=`grep -vE '^#|^\s#' ${deny_settings_files[$i]} | grep -i ${deny_modules[$i]} | grep -i 'deny' | awk -F 'deny' '{gsub(" ", "", $0); print substr($2,2,1)}'` 273 | deny_settings_file_deny_second_value=`grep -vE '^#|^\s#' ${deny_settings_files[$i]} | grep -i ${deny_modules[$i]} | grep -i 'deny' | awk -F 'deny' '{gsub(" ", "", $0); print substr($2,3,1)}'` 274 | deny_settings_file_deny_third_value=`grep -vE '^#|^\s#' ${deny_settings_files[$i]} | grep -i ${deny_modules[$i]} | grep -i 'deny' | awk -F 'deny' '{gsub(" ", "", $0); print substr($2,4,1)}'` 275 | if [ $deny_settings_file_deny_value -eq 0 ]; then 276 | continue 277 | elif [ $deny_settings_file_deny_value -eq 1 ]; then 278 | if [[ $deny_settings_file_deny_second_value =~ [1-9] ]]; then 279 | echo "※ U-03 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 280 | echo " ${deny_settings_files[$i]} 파일에 계정 잠금 임계값이 11회 이상으로 설정되어 있습니다." >> $resultfile 2>&1 281 | return 0 282 | else 283 | if [[ $deny_settings_file_deny_third_value =~ [0-9] ]]; then 284 | echo "※ U-03 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 285 | echo " ${deny_settings_files[$i]} 파일에 계정 잠금 임계값이 11회 이상으로 설정되어 있습니다." >> $resultfile 2>&1 286 | return 0 287 | fi 288 | fi 289 | else 290 | if [[ $deny_settings_file_deny_second_value =~ [0-9] ]]; then 291 | echo "※ U-03 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 292 | echo " ${deny_settings_files[$i]} 파일에 계정 잠금 임계값이 11회 이상으로 설정되어 있습니다." >> $resultfile 2>&1 293 | return 0 294 | fi 295 | fi 296 | else 297 | ((no_settings_in_deny_file++)) 298 | fi 299 | done 300 | fi 301 | done 302 | if [ $file_exists_count -eq 0 ]; then 303 | echo "※ U-03 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 304 | echo " 계정 잠금 임계값을 설정하는 파일이 없습니다." >> $resultfile 2>&1 305 | return 0 306 | elif [ $deny_file_exists_count -eq $no_settings_in_deny_file ]; then 307 | echo "※ U-03 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 308 | echo " 계정 잠금 임계값을 설정한 파일이 없습니다." >> $resultfile 2>&1 309 | return 0 310 | fi 311 | echo "※ U-03 결과 : 양호(Good)" >> $resultfile 2>&1 312 | return 0 313 | } 314 | 315 | U_04() { 316 | echo "" >> $resultfile 2>&1 317 | echo "▶ U-04(상) | 1. 계정관리 > 1.4 패스워드 파일 보호 ◀" >> $resultfile 2>&1 318 | echo " 양호 판단 기준 : 쉐도우 패스워드를 사용하거나, 패스워드를 암호화하여 저장하는 경우" >> $resultfile 2>&1 319 | if [ `awk -F : '$2!="x"' /etc/passwd | wc -l` -gt 0 ]; then 320 | echo "※ U-04 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 321 | echo " 쉐도우 패스워드를 사용하고 있지 않습니다." >> $resultfile 2>&1 322 | return 0 323 | else 324 | echo "※ U-04 결과 : 양호(Good)" >> $resultfile 2>&1 325 | return 0 326 | fi 327 | } 328 | 329 | U_05() { 330 | echo "" >> $resultfile 2>&1 331 | echo "▶ U-05(상) | 2. 파일 및 디렉토리 관리 > 2.1 root홈, 패스 디렉터리 권한 및 패스 설정 ◀" >> $resultfile 2>&1 332 | echo " 양호 판단 기준 : PATH 환경변수에 “.” 이 맨 앞이나 중간에 포함되지 않은 경우" >> $resultfile 2>&1 333 | if [ `echo $PATH | grep -E '\.:|::' | wc -l` -gt 0 ]; then 334 | echo "※ U-05 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 335 | echo " PATH 환경 변수 내에 "." 또는 "::"이 포함되어 있습니다." >> $resultfile 2>&1 336 | return 0 337 | else 338 | # /etc 디렉터리 내 설정 파일의 PATH 변수 중 누락이 있을 가능성을 생각하여 추가 확인함 339 | path_settings_files=("/etc/profile" "/etc/.login" "/etc/csh.cshrc" "/etc/csh.login" "/etc/environment") 340 | for ((i=0; i<${#path_settings_files[@]}; i++)) 341 | do 342 | if [ -f ${path_settings_files[$i]} ]; then 343 | path_settings_file_path_variable_exists_count=`grep -vE '^#|^\s#' ${path_settings_files[$i]} | grep 'PATH=' | wc -l` 344 | if [ $path_settings_file_path_variable_exists_count -gt 0 ]; then 345 | path_settings_file_path_variable_value_count=`grep -vE '^#|^\s#' ${path_settings_files[$i]} | grep 'PATH=' | grep -E '\.:|::' | wc -l` 346 | if [ $path_settings_file_path_variable_value_count -gt 0 ]; then 347 | echo "※ U-05 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 348 | echo " /etc 디렉터리 내 Start Profile에 설정된 PATH 환경 변수 내에 "." 또는 "::"이 포함되어 있습니다." >> $resultfile 2>&1 349 | return 0 350 | fi 351 | fi 352 | fi 353 | done 354 | # 사용자 홈 디렉터리 내 설정 파일의 PATH 변수 중 누락이 있을 가능성을 생각하여 추가 확인함 355 | path_settings_files=(".profile" ".cshrc" ".login" ".kshrc" ".bash_profile" ".bashrc" ".bash_login") 356 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd | uniq`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 357 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 358 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 359 | do 360 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 361 | done 362 | user_homedirectory_path[${#user_homedirectory_path[@]}]=/root 363 | for ((i=0; i<${#user_homedirectory_path[@]}; i++)) 364 | do 365 | for ((j=0; j<${#path_settings_files[@]}; j++)) 366 | do 367 | if [ -f ${user_homedirectory_path[$i]}/${path_settings_files[$j]} ]; then 368 | path_settings_file_path_variable_exists_count=`grep -vE '^#|^\s#' ${user_homedirectory_path[$i]}/${path_settings_files[$j]} | grep 'PATH=' | wc -l` 369 | if [ $path_settings_file_path_variable_exists_count -gt 0 ]; then 370 | path_settings_file_path_variable_value_count=`grep -vE '^#|^\s#' ${user_homedirectory_path[$i]}/${path_settings_files[$j]} | grep 'PATH=' | grep -E '\.:|::' | wc -l` 371 | if [ $path_settings_file_path_variable_value_count -gt 0 ]; then 372 | echo "※ U-05 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 373 | echo " ${user_homedirectory_path[$i]} 디렉터리 내 ${path_settings_files[$j]} 파일에 설정된 PATH 환경 변수 내에 "." 또는 "::"이 포함되어 있습니다." >> $resultfile 2>&1 374 | return 0 375 | fi 376 | fi 377 | fi 378 | done 379 | done 380 | fi 381 | echo "※ U-05 결과 : 양호(Good)" >> $resultfile 2>&1 382 | return 0 383 | } 384 | 385 | U_06() { 386 | echo "" >> $resultfile 2>&1 387 | echo "▶ U-06(상) | 2. 파일 및 디렉토리 관리 > 2.2 파일 및 디렉터리 소유자 설정 ◀" >> $resultfile 2>&1 388 | echo " 양호 판단 기준 : 소유자가 존재하지 않는 파일 및 디렉터리가 존재하지 않는 경우" >> $resultfile 2>&1 389 | if [ `find / \( -nouser -or -nogroup \) 2>/dev/null | wc -l` -gt 0 ]; then 390 | echo "※ U-06 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 391 | echo " 소유자가 존재하지 않는 파일 및 디렉터리가 존재합니다." >> $resultfile 2>&1 392 | return 0 393 | else 394 | echo "※ U-06 결과 : 양호(Good)" >> $resultfile 2>&1 395 | return 0 396 | fi 397 | } 398 | 399 | U_07() { 400 | echo "" >> $resultfile 2>&1 401 | echo "▶ U-07(상) | 2. 파일 및 디렉토리 관리 > 2.3 /etc/passwd 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 402 | echo " 양호 판단 기준 : /etc/passwd 파일의 소유자가 root이고, 권한이 644 이하인 경우" >> $resultfile 2>&1 403 | if [ -f /etc/passwd ]; then 404 | etc_passwd_owner_name=`ls -l /etc/passwd | awk '{print $3}'` 405 | if [[ $etc_passwd_owner_name =~ root ]]; then 406 | etc_passwd_permission=`stat /etc/passwd | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 407 | if [ $etc_passwd_permission -le 644 ]; then 408 | etc_passwd_owner_permission=`stat /etc/passwd | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 409 | if [ $etc_passwd_owner_permission -eq 0 ] || [ $etc_passwd_owner_permission -eq 2 ] || [ $etc_passwd_owner_permission -eq 4 ] || [ $etc_passwd_owner_permission -eq 6 ]; then 410 | etc_passwd_group_permission=`stat /etc/passwd | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 411 | if [ $etc_passwd_group_permission -eq 0 ] || [ $etc_passwd_group_permission -eq 4 ]; then 412 | etc_passwd_other_permission=`stat /etc/passwd | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 413 | if [ $etc_passwd_other_permission -eq 0 ] || [ $etc_passwd_other_permission -eq 4 ]; then 414 | echo "※ U-07 결과 : 양호(Good)" >> $resultfile 2>&1 415 | return 0 416 | else 417 | echo "※ U-07 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 418 | echo " /etc/passwd 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 419 | return 0 420 | fi 421 | else 422 | echo "※ U-07 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 423 | echo " /etc/passwd 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 424 | return 0 425 | fi 426 | else 427 | echo "※ U-07 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 428 | echo " /etc/passwd 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 429 | return 0 430 | fi 431 | else 432 | echo "※ U-07 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 433 | echo " /etc/passwd 파일의 권한이 644보다 큽니다." >> $resultfile 2>&1 434 | return 0 435 | fi 436 | else 437 | echo "※ U-07 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 438 | echo " /etc/passwd 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 439 | return 0 440 | fi 441 | else 442 | echo "※ U-07 결과 : N/A" >> $resultfile 2>&1 443 | echo " /etc/passwd 파일이 없습니다." >> $resultfile 2>&1 444 | return 0 445 | fi 446 | } 447 | 448 | U_08() { 449 | echo "" >> $resultfile 2>&1 450 | echo "▶ U-08(상) | 2. 파일 및 디렉토리 관리 > 2.4 /etc/shadow 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 451 | echo " 양호 판단 기준 : /etc/shadow 파일의 소유자가 root이고, 권한이 400 이하인 경우" >> $resultfile 2>&1 452 | if [ -f /etc/shadow ]; then 453 | etc_shadow_owner_name=`ls -l /etc/shadow | awk '{print $3}'` 454 | if [[ $etc_shadow_owner_name =~ root ]]; then 455 | etc_shadow_permission=`stat /etc/shadow | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 456 | if [ $etc_shadow_permission -le 400 ]; then 457 | etc_shadow_owner_permission=`stat /etc/shadow | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 458 | if [ $etc_shadow_owner_permission -eq 0 ] || [ $etc_shadow_owner_permission -eq 4 ]; then 459 | etc_shadow_group_permission=`stat /etc/shadow | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 460 | if [ $etc_shadow_group_permission -eq 0 ]; then 461 | etc_shadow_other_permission=`stat /etc/shadow | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 462 | if [ $etc_shadow_other_permission -eq 0 ]; then 463 | echo "※ U-08 결과 : 양호(Good)" >> $resultfile 2>&1 464 | return 0 465 | else 466 | echo "※ U-08 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 467 | echo " /etc/shadow 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 468 | return 0 469 | fi 470 | else 471 | echo "※ U-08 결과 : N/A" >> $resultfile 2>&1 472 | echo " /etc/shadow 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 473 | return 0 474 | fi 475 | else 476 | echo "※ U-08 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 477 | echo " /etc/shadow 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 478 | return 0 479 | fi 480 | else 481 | echo "※ U-08 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 482 | echo " /etc/shadow 파일의 권한이 400보다 큽니다." >> $resultfile 2>&1 483 | return 0 484 | fi 485 | else 486 | echo "※ U-08 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 487 | echo " /etc/shadow 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 488 | return 0 489 | fi 490 | else 491 | echo "※ U-08 결과 : N/A" >> $resultfile 2>&1 492 | echo " /etc/shadow 파일이 없습니다." >> $resultfile 2>&1 493 | return 0 494 | fi 495 | } 496 | 497 | U_09() { 498 | echo "" >> $resultfile 2>&1 499 | echo "▶ U-09(상) | 2. 파일 및 디렉토리 관리 > 2.5 /etc/hosts 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 500 | echo " 양호 판단 기준 : /etc/hosts 파일의 소유자가 root이고, 권한이 600인 이하인 경우" >> $resultfile 2>&1 501 | if [ -f /etc/hosts ]; then 502 | etc_hosts_owner_name=`ls -l /etc/hosts | awk '{print $3}'` 503 | if [[ $etc_hosts_owner_name =~ root ]]; then 504 | etc_hosts_permission=`stat /etc/hosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 505 | if [ $etc_hosts_permission -le 600 ]; then 506 | etc_hosts_owner_permission=`stat /etc/hosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 507 | if [ $etc_hosts_owner_permission -eq 0 ] || [ $etc_hosts_owner_permission -eq 2 ] || [ $etc_hosts_owner_permission -eq 4 ] || [ $etc_hosts_owner_permission -eq 6 ]; then 508 | etc_hosts_group_permission=`stat /etc/hosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 509 | if [ $etc_hosts_group_permission -eq 0 ]; then 510 | etc_hosts_other_permission=`stat /etc/hosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 511 | if [ $etc_hosts_other_permission -eq 0 ]; then 512 | echo "※ U-09 결과 : 양호(Good)" >> $resultfile 2>&1 513 | return 0 514 | else 515 | echo "※ U-09 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 516 | echo " /etc/hosts 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 517 | return 0 518 | fi 519 | else 520 | echo "※ U-09 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 521 | echo " /etc/hosts 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 522 | return 0 523 | fi 524 | else 525 | echo "※ U-09 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 526 | echo " /etc/hosts 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 527 | return 0 528 | fi 529 | else 530 | echo "※ U-09 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 531 | echo " /etc/hosts 파일의 권한이 600보다 큽니다." >> $resultfile 2>&1 532 | return 0 533 | fi 534 | else 535 | echo "※ U-09 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 536 | echo " /etc/hosts 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 537 | return 0 538 | fi 539 | else 540 | echo "※ U-09 결과 : N/A" >> $resultfile 2>&1 541 | echo " /etc/hosts 파일이 없습니다." >> $resultfile 2>&1 542 | return 0 543 | fi 544 | } 545 | 546 | U_10() { 547 | echo "" >> $resultfile 2>&1 548 | echo "▶ U-10(상) | 2. 파일 및 디렉토리 관리 > 2.6 /etc/(x)inetd.conf 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 549 | echo " 양호 판단 기준 : /etc/inetd.conf 파일의 소유자가 root이고, 권한이 600인 경우" >> $resultfile 2>&1 550 | file_exists_count=0 551 | if [ -f /etc/xinetd.conf ]; then 552 | ((file_exists_count++)) 553 | etc_xinetdconf_owner_name=`ls -l /etc/xinetd.conf | awk '{print $3}'` 554 | if [[ $etc_xinetdconf_owner_name =~ root ]]; then 555 | etc_xinetdconf_permission=`stat /etc/xinetd.conf | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 556 | if [ $etc_xinetdconf_permission -ne 600 ]; then 557 | echo "※ U-10 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 558 | echo " /etc/xinetd.conf 파일의 권한이 600이 아닙니다." >> $resultfile 2>&1 559 | return 0 560 | fi 561 | else 562 | echo "※ U-10 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 563 | echo " /etc/xinetd.conf 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 564 | return 0 565 | fi 566 | fi 567 | if [ -d /etc/xinetd.d ]; then 568 | etc_xinetdd_file_count=`find /etc/xinetd.d -type f 2>/dev/null | wc -l` 569 | if [ $etc_xinetdd_file_count -gt 0 ]; then 570 | xinetdd_files=(`find /etc/xinetd.d -type f 2>/dev/null`) 571 | for ((i=0; i<${#xinetdd_files[@]}; i++)) 572 | do 573 | xinetdd_file_owner_name=`ls -l ${xinetdd_files[$i]} | awk '{print $3}'` 574 | if [[ $xinetdd_file_owner_name =~ root ]]; then 575 | xinetdd_file_permission=`stat ${xinetdd_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 576 | if [ $xinetdd_file_permission -ne 600 ]; then 577 | echo "※ U-10 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 578 | echo " /etc/xinetd.d 디렉터리 내 파일의 권한이 600이 아닙니다." >> $resultfile 2>&1 579 | return 0 580 | fi 581 | else 582 | echo "※ U-10 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 583 | echo " /etc/xinetd.d 디렉터리 내 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 584 | return 0 585 | fi 586 | done 587 | fi 588 | fi 589 | if [ -f /etc/inetd.conf ]; then 590 | ((file_exists_count++)) 591 | etc_inetdconf_owner_name=`ls -l /etc/inetd.conf | awk '{print $3}'` 592 | if [[ $etc_inetdconf_owner_name =~ root ]]; then 593 | etc_inetdconf_permission=`stat /etc/inetd.conf | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 594 | if [ $etc_inetdconf_permission -ne 600 ]; then 595 | echo "※ U-10 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 596 | echo " /etc/inetd.conf 파일의 권한이 600이 아닙니다." >> $resultfile 2>&1 597 | return 0 598 | fi 599 | else 600 | echo "※ U-10 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 601 | echo " /etc/inetd.conf 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 602 | return 0 603 | fi 604 | fi 605 | if [ $file_exists_count -eq 0 ]; then 606 | echo "※ U-10 결과 : N/A" >> $resultfile 2>&1 607 | echo " /etc/(x)inetd.conf 파일이 없습니다." >> $resultfile 2>&1 608 | else 609 | echo "※ U-10 결과 : 양호(Good)" >> $resultfile 2>&1 610 | fi 611 | } 612 | 613 | U_11() { 614 | echo "" >> $resultfile 2>&1 615 | echo "▶ U-11(상) | 2. 파일 및 디렉토리 관리 > 2.7 /etc/syslog.conf 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 616 | echo " 양호 판단 기준 : /etc/syslog.conf 파일의 소유자가 root(또는 bin, sys)이고, 권한이 640 이하인 경우" >> $resultfile 2>&1 617 | syslogconf_files=("/etc/rsyslog.conf" "/etc/syslog.conf" "/etc/syslog-ng.conf") 618 | file_exists_count=0 619 | for ((i=0; i<${#syslogconf_files[@]}; i++)) 620 | do 621 | if [ -f ${syslogconf_files[$i]} ]; then 622 | ((file_exists_count++)) 623 | syslogconf_file_owner_name=`ls -l ${syslogconf_files[$i]} | awk '{print $3}'` 624 | if [[ $syslogconf_file_owner_name =~ root ]] || [[ $syslogconf_file_owner_name =~ bin ]] || [[ $syslogconf_file_owner_name =~ sys ]]; then 625 | syslogconf_file_permission=`stat ${syslogconf_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 626 | if [ $syslogconf_file_permission -le 640 ]; then 627 | syslogconf_file_owner_permission=`stat ${syslogconf_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 628 | if [ $syslogconf_file_owner_permission -eq 6 ] || [ $syslogconf_file_owner_permission -eq 4 ] || [ $syslogconf_file_owner_permission -eq 2 ] || [ $syslogconf_file_owner_permission -eq 0 ]; then 629 | syslogconf_file_group_permission=`stat ${syslogconf_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 630 | if [ $syslogconf_file_group_permission -eq 4 ] || [ $syslogconf_file_group_permission -eq 2 ] || [ $syslogconf_file_group_permission -eq 0 ]; then 631 | syslogconf_file_other_permission=`stat ${syslogconf_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 632 | if [ $syslogconf_file_other_permission -ne 0 ]; then 633 | echo "※ U-11 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 634 | echo " ${syslogconf_files[$i]} 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 635 | return 0 636 | fi 637 | else 638 | echo "※ U-11 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 639 | echo " ${syslogconf_files[$i]} 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 640 | return 0 641 | fi 642 | else 643 | echo "※ U-11 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 644 | echo " ${syslogconf_files[$i]} 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 645 | return 0 646 | fi 647 | else 648 | echo "※ U-11 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 649 | echo " ${syslogconf_files[$i]} 파일의 권한이 640보다 큽니다." >> $resultfile 2>&1 650 | return 0 651 | fi 652 | else 653 | echo "※ U-11 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 654 | echo " ${syslogconf_files[$i]} 파일의 소유자(owner)가 root(또는 bin, sys)가 아닙니다." >> $resultfile 2>&1 655 | return 0 656 | fi 657 | fi 658 | done 659 | if [ $file_exists_count -eq 0 ]; then 660 | echo "※ U-11 결과 : N/A" >> $resultfile 2>&1 661 | echo " /etc/syslog.conf 파일이 없습니다." >> $resultfile 2>&1 662 | return 0 663 | else 664 | echo "※ U-11 결과 : 양호(Good)" >> $resultfile 2>&1 665 | return 0 666 | fi 667 | } 668 | 669 | U_12() { 670 | echo "" >> $resultfile 2>&1 671 | echo "▶ U-12(상) | 2. 파일 및 디렉토리 관리 > 2.8 /etc/services 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 672 | echo " 양호 판단 기준 : /etc/services 파일의 소유자가 root(또는 bin, sys)이고, 권한이 644 이하인 경우" >> $resultfile 2>&1 673 | if [ -f /etc/services ]; then 674 | etc_services_owner_name=`ls -l /etc/services | awk '{print $3}'` 675 | if [[ $etc_services_owner_name =~ root ]] || [[ $etc_services_owner_name =~ bin ]] || [[ $etc_services_owner_name =~ sys ]]; then 676 | etc_services_permission=`stat /etc/services | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 677 | if [ $etc_services_permission -le 644 ]; then 678 | etc_services_owner_permission=`stat /etc/services | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 679 | if [ $etc_services_owner_permission -eq 6 ] || [ $etc_services_owner_permission -eq 4 ] || [ $etc_services_owner_permission -eq 2 ] || [ $etc_services_owner_permission -eq 0 ]; then 680 | etc_services_group_permission=`stat /etc/services | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 681 | if [ $etc_services_group_permission -eq 4 ] || [ $etc_services_group_permission -eq 0 ]; then 682 | etc_services_other_permission=`stat /etc/services | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 683 | if [ $etc_services_other_permission -eq 4 ] || [ $etc_services_other_permission -eq 0 ]; then 684 | echo "※ U-12 결과 : 양호(Good)" >> $resultfile 2>&1 685 | return 0 686 | else 687 | echo "※ U-12 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 688 | echo " /etc/services 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 689 | return 0 690 | fi 691 | else 692 | echo "※ U-12 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 693 | echo " /etc/services 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 694 | return 0 695 | fi 696 | else 697 | echo "※ U-12 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 698 | echo " /etc/services 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 699 | return 0 700 | fi 701 | else 702 | echo "※ U-12 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 703 | echo " /etc/services 파일의 권한이 644보다 큽니다." >> $resultfile 2>&1 704 | return 0 705 | fi 706 | else 707 | echo "※ U-12 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 708 | echo " /etc/services 파일의 파일의 소유자(owner)가 root(또는 bin, sys)가 아닙니다." >> $resultfile 2>&1 709 | return 0 710 | fi 711 | else 712 | echo "※ U-12 결과 : N/A" >> $resultfile 2>&1 713 | echo " /etc/services 파일이 없습니다." >> $resultfile 2>&1 714 | return 0 715 | fi 716 | } 717 | 718 | U_13() { 719 | echo "" >> $resultfile 2>&1 720 | echo "▶ U-13(상) | 2. 파일 및 디렉토리 관리 > 2.9 SUID, SGID, 설정 파일점검 ◀" >> $resultfile 2>&1 721 | echo " 양호 판단 기준 : 주요 실행파일의 권한에 SUID와 SGID에 대한 설정이 부여되어 있지 않은 경우" >> $resultfile 2>&1 722 | executables=("/sbin/dump" "/sbin/restore" "/sbin/unix_chkpwd" "/usr/bin/at" "/usr/bin/lpq" "/usr/bin/lpq-lpd" "/usr/bin/lpr" "/usr/bin/lpr-lpd" "/usr/bin/lprm" "/usr/bin/lprm-lpd" "/usr/bin/newgrp" "/usr/sbin/lpc" "/usr/sbin/lpc-lpd" "/usr/sbin/traceroute") 723 | for ((i=0; i<${#executables[@]}; i++)) 724 | do 725 | if [ -f ${executables[$i]} ]; then 726 | if [ `ls -l ${executables[$i]} | awk '{print substr($1,2,9)}' | grep -i 's' | wc -l` -gt 0 ]; then 727 | echo "※ U-13 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 728 | echo " 주요 실행 파일의 권한에 SUID나 SGID에 대한 설정이 부여되어 있습니다." >> $resultfile 2>&1 729 | return 0 730 | fi 731 | fi 732 | done 733 | echo "※ U-13 결과 : 양호(Good)" >> $resultfile 2>&1 734 | return 0 735 | } 736 | 737 | U_14() { 738 | echo "" >> $resultfile 2>&1 739 | echo "▶ U-14(상) | 2. 파일 및 디렉토리 관리 > 2.10 사용자, 시스템 시작파일 및 환경파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 740 | echo " 양호 판단 기준 : 홈 디렉터리 환경변수 파일 소유자가 root 또는, 해당 계정으로 지정되어 있고, 홈 디렉터리 환경변수 파일에 root와 소유자만 쓰기 권한이 부여된 경우" >> $resultfile 2>&1 741 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 742 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 743 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 744 | do 745 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 746 | done 747 | user_homedirectory_owner_name=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $1}' /etc/passwd`) # /etc/passwd 파일에 설정된 사용자명 배열 생성 748 | user_homedirectory_owner_name2=() # user_homedirectory_path2 배열에서 사용자명만 따로 출력하여 저장할 빈 배열 생성 749 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 750 | do 751 | user_homedirectory_owner_name2[${#user_homedirectory_owner_name2[@]}]=`echo ${user_homedirectory_path2[$i]} | awk -F / '{print $3}'` # user_homedirectory_path2 배열에서 사용자명만 따로 출력하여 배열에 저장함 752 | done 753 | for ((i=0; i<${#user_homedirectory_owner_name2[@]}; i++)) 754 | do 755 | user_homedirectory_owner_name[${#user_homedirectory_owner_name[@]}]=${user_homedirectory_owner_name2[$i]} # 두 개의 배열 합침 756 | done 757 | start_files=(".profile" ".cshrc" ".login" ".kshrc" ".bash_profile" ".bashrc" ".bash_login") 758 | for ((i=0; i<${#user_homedirectory_path[@]}; i++)) 759 | do 760 | for ((j=0; j<${#start_files[@]}; j++)) 761 | do 762 | if [ -f ${user_homedirectory_path[$i]}/${start_files[$j]} ]; then 763 | user_homedirectory_owner_name2=`ls -l ${user_homedirectory_path[$i]}/${start_files[$j]} | awk '{print $3}'` 764 | if [[ $user_homedirectory_owner_name2 =~ root ]] || [[ $user_homedirectory_owner_name2 =~ ${user_homedirectory_owner_name[$i]} ]]; then 765 | user_homedirectory_other_execute_permission=`ls -l ${user_homedirectory_path[$i]}/${start_files[$j]} | awk '{print substr($1,9,1)}'` 766 | if [[ $user_homedirectory_other_execute_permission =~ w ]]; then 767 | echo "※ U-14 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 768 | echo " ${user_homedirectory_path[$i]} 홈 디렉터리 내 ${start_files[$j]} 환경 변수 파일에 다른 사용자(other)의 쓰기(w) 권한이 부여 되어 있습니다." >> $resultfile 2>&1 769 | return 0 770 | fi 771 | else 772 | echo "※ U-14 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 773 | echo " ${user_homedirectory_path[$i]} 홈 디렉터리 내 ${start_files[$j]} 환경 변수 파일의 소유자(owner)가 root 또는 해당 계정이 아닙니다." >> $resultfile 2>&1 774 | return 0 775 | fi 776 | fi 777 | done 778 | done 779 | echo "※ U-14 결과 : 양호(Good)" >> $resultfile 2>&1 780 | return 0 781 | } 782 | 783 | U_15() { 784 | echo "" >> $resultfile 2>&1 785 | echo "▶ U-15(상) | 2. 파일 및 디렉토리 관리 > 2.11 world writable 파일 점검 ◀" >> $resultfile 2>&1 786 | echo " 양호 판단 기준 : 시스템 중요 파일에 world writable 파일이 존재하지 않거나, 존재 시 설정 이유를 확인하고 있는 경우" >> $resultfile 2>&1 787 | if [ `find / -type f -perm -2 2>/dev/null | wc -l` -gt 0 ]; then 788 | echo "※ U-15 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 789 | echo " world writable 설정이 되어있는 파일이 있습니다." >> $resultfile 2>&1 790 | return 0 791 | else 792 | echo "※ U-15 결과 : 양호(Good)" >> $resultfile 2>&1 793 | return 0 794 | fi 795 | } 796 | 797 | U_16() { 798 | echo "" >> $resultfile 2>&1 799 | echo "▶ U-16(상) | 2. 파일 및 디렉토리 관리 > 2.12 /dev에 존재하지 않는 device 파일 점검 ◀" >> $resultfile 2>&1 800 | echo " 양호 판단 기준 : /dev에 대한 파일 점검 후 존재하지 않은 device 파일을 제거한 경우" >> $resultfile 2>&1 801 | if [ `find /dev -type f 2>/dev/null | wc -l` -gt 0 ]; then 802 | echo "※ U-16 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 803 | echo " /dev 디렉터리에 존재하지 않는 device 파일이 존재합니다." >> $resultfile 2>&1 804 | return 0 805 | else 806 | echo "※ U-16 결과 : 양호(Good)" >> $resultfile 2>&1 807 | return 0 808 | fi 809 | } 810 | 811 | U_17() { 812 | echo "" >> $resultfile 2>&1 813 | echo "▶ U-17(상) | 2. 파일 및 디렉토리 관리 > 2.13 $HOME/.rhosts, hosts.equiv 사용 금지 ◀" >> $resultfile 2>&1 814 | echo " 양호 판단 기준 : login, shell, exec 서비스를 사용하지 않거나, 사용 시 아래와 같은 설정이 적용된 경우" >> $resultfile 2>&1 815 | echo " 1. /etc/hosts.equiv 및 $HOME/.rhosts 파일 소유자가 root 또는, 해당 계정인 경우" >> $resultfile 2>&1 816 | echo " 2. /etc/hosts.equiv 및 $HOME/.rhosts 파일 권한이 600 이하인 경우" >> $resultfile 2>&1 817 | echo " 3. /etc/hosts.equiv 및 $HOME/.rhosts 파일 설정에 ‘+’ 설정이 없는 경우" >> $resultfile 2>&1 818 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 819 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 820 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 821 | do 822 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 823 | done 824 | user_homedirectory_owner_name=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $1}' /etc/passwd`) # /etc/passwd 파일에 설정된 사용자명 배열 생성 825 | user_homedirectory_owner_name2=() # user_homedirectory_path2 배열에서 사용자명만 따로 출력하여 저장할 빈 배열 생성 826 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 827 | do 828 | user_homedirectory_owner_name2[${#user_homedirectory_owner_name2[@]}]=`echo ${user_homedirectory_path2[$i]} | awk -F / '{print $3}'` # user_homedirectory_path2 배열에서 사용자명만 따로 출력하여 배열에 저장함 829 | done 830 | for ((i=0; i<${#user_homedirectory_owner_name2[@]}; i++)) 831 | do 832 | user_homedirectory_owner_name[${#user_homedirectory_owner_name[@]}]=${user_homedirectory_owner_name2[$i]} # 두 개의 배열 합침 833 | done 834 | r_command=("rsh" "rlogin" "rexec" "shell" "login" "exec") 835 | # /etc/xinetd.d 디렉터리 내 r command 파일 확인함 836 | if [ -d /etc/xinetd.d ]; then 837 | for ((i=0; i<${#r_command[@]}; i++)) 838 | do 839 | if [ -f /etc/xinetd.d/${r_command[$i]} ]; then 840 | etc_xinetdd_rcommand_disable_count=`grep -vE '^#|^\s#' /etc/xinetd.d/${r_command[$i]} | grep -i 'disable' | grep -i 'yes' | wc -l` 841 | if [ $etc_xinetdd_rcommand_disable_count -eq 0 ]; then 842 | if [ -f /etc/hosts.equiv ]; then 843 | etc_hostsequiv_owner_name=`ls -l /etc/hosts.equiv | awk '{print $3}'` 844 | if [[ $etc_hostsequiv_owner_name =~ root ]]; then 845 | etc_hostsequiv_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 846 | if [ $etc_hostsequiv_permission -le 600 ]; then 847 | etc_hostsequiv_owner_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 848 | if [ $etc_hostsequiv_owner_permission -eq 6 ] || [ $etc_hostsequiv_owner_permission -eq 4 ] || [ $etc_hostsequiv_owner_permission -eq 2 ] || [ $etc_hostsequiv_owner_permission -eq 0 ]; then 849 | etc_hostsequiv_group_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 850 | if [ $etc_hostsequiv_group_permission -eq 0 ]; then 851 | etc_hostsequiv_other_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 852 | if [ $etc_hostsequiv_other_permission -eq 0 ]; then 853 | etc_hostsequiv_plus_count=`grep -vE '^#|^\s#' /etc/hosts.equiv | grep '+' | wc -l` 854 | if [ $etc_hostsequiv_plus_count -gt 0 ]; then 855 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 856 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일에 '+' 설정이 있습니다." >> $resultfile 2>&1 857 | return 0 858 | fi 859 | else 860 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 861 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 862 | return 0 863 | fi 864 | else 865 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 866 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 867 | return 0 868 | fi 869 | else 870 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 871 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 872 | return 0 873 | fi 874 | else 875 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 876 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 권한이 600보다 큽니다." >> $resultfile 2>&1 877 | return 0 878 | fi 879 | else 880 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 881 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 882 | return 0 883 | fi 884 | fi 885 | # 사용자 홈 디렉터리 내 .rhosts 파일 확인함 886 | for ((j=0; j<${#user_homedirectory_path[@]}; j++)) 887 | do 888 | if [ -f ${user_homedirectory_path[$j]}/.rhosts ]; then 889 | user_homedirectory_rhosts_owner_name=`ls -l ${user_homedirectory_path[$j]}/.rhosts | awk '{print $3}'` 890 | if [[ $user_homedirectory_rhosts_owner_name =~ root ]] || [[ $user_homedirectory_rhosts_owner_name =~ ${user_homedirectory_owner_name[$j]} ]]; then 891 | user_homedirectory_rhosts_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 892 | if [ $user_homedirectory_rhosts_permission -le 600 ]; then 893 | user_homedirectory_rhosts_owner_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 894 | if [ $user_homedirectory_rhosts_owner_permission -eq 6 ] || [ $user_homedirectory_rhosts_owner_permission -eq 4 ] || [ $user_homedirectory_rhosts_owner_permission -eq 2 ] || [ $user_homedirectory_rhosts_owner_permission -eq 0 ]; then 895 | user_homedirectory_rhosts_group_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 896 | if [ $user_homedirectory_rhosts_group_permission -eq 0 ]; then 897 | user_homedirectory_rhosts_other_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 898 | if [ $user_homedirectory_rhosts_other_permission -eq 0 ]; then 899 | user_homedirectory_rhosts_plus_count=`grep -vE '^#|^\s#' ${user_homedirectory_path[$j]}/.rhosts | grep '+' | wc -l` 900 | if [ $user_homedirectory_rhosts_plus_count -gt 0 ]; then 901 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 902 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일에 '+' 설정이 있습니다." >> $resultfile 2>&1 903 | return 0 904 | fi 905 | else 906 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 907 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 908 | return 0 909 | fi 910 | else 911 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 912 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 913 | return 0 914 | fi 915 | else 916 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 917 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 918 | return 0 919 | fi 920 | else 921 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 922 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 권한이 600보다 큽니다." >> $resultfile 2>&1 923 | return 0 924 | fi 925 | else 926 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 927 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 소유자(owner)가 root 또는 해당 계정이 아닙니다." >> $resultfile 2>&1 928 | return 0 929 | fi 930 | fi 931 | done 932 | fi 933 | fi 934 | done 935 | fi 936 | # /etc/inetd.conf 파일 내 r command 서비스 확인함 937 | if [ -f /etc/inetd.conf ]; then 938 | for ((i=0; i<${#r_command[@]}; i++)) 939 | do 940 | if [ `grep -vE '^#|^\s#' /etc/inetd.conf | grep ${r_command[$i]} | wc -l` -gt 0 ]; then 941 | if [ -f /etc/hosts.equiv ]; then 942 | etc_hostsequiv_owner_name=`ls -l /etc/hosts.equiv | awk '{print $3}'` 943 | if [[ $etc_hostsequiv_owner_name =~ root ]]; then 944 | etc_hostsequiv_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 945 | if [ $etc_hostsequiv_permission -le 600 ]; then 946 | etc_hostsequiv_owner_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 947 | if [ $etc_hostsequiv_owner_permission -eq 6 ] || [ $etc_hostsequiv_owner_permission -eq 4 ] || [ $etc_hostsequiv_owner_permission -eq 2 ] || [ $etc_hostsequiv_owner_permission -eq 0 ]; then 948 | etc_hostsequiv_group_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 949 | if [ $etc_hostsequiv_group_permission -eq 0 ]; then 950 | etc_hostsequiv_other_permission=`stat /etc/hosts.equiv | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 951 | if [ $etc_hostsequiv_other_permission -eq 0 ]; then 952 | etc_hostsequiv_plus_count=`grep -vE '^#|^\s#' /etc/hosts.equiv | grep '+' | wc -l` 953 | if [ $etc_hostsequiv_plus_count -gt 0 ]; then 954 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 955 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일에 '+' 설정이 있습니다." >> $resultfile 2>&1 956 | return 0 957 | fi 958 | else 959 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 960 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 961 | return 0 962 | fi 963 | else 964 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 965 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 966 | return 0 967 | fi 968 | else 969 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 970 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 971 | return 0 972 | fi 973 | else 974 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 975 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 권한이 600보다 큽니다." >> $resultfile 2>&1 976 | return 0 977 | fi 978 | else 979 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 980 | echo " r 계열 서비스를 사용하고, /etc/hosts.equiv 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 981 | return 0 982 | fi 983 | fi 984 | # 사용자 홈 디렉터리 내 .rhosts 파일 확인함 985 | for ((j=0; j<${#user_homedirectory_path[@]}; j++)) 986 | do 987 | if [ -f ${user_homedirectory_path[$j]}/.rhosts ]; then 988 | user_homedirectory_rhosts_owner_name=`ls -l ${user_homedirectory_path[$j]}/.rhosts | awk '{print $3}'` 989 | if [[ $user_homedirectory_rhosts_owner_name =~ root ]] || [[ $user_homedirectory_rhosts_owner_name =~ ${user_homedirectory_owner_name[$j]} ]]; then 990 | user_homedirectory_rhosts_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 991 | if [ $user_homedirectory_rhosts_permission -le 600 ]; then 992 | user_homedirectory_rhosts_owner_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 993 | if [ $user_homedirectory_rhosts_owner_permission -eq 6 ] || [ $user_homedirectory_rhosts_owner_permission -eq 4 ] || [ $user_homedirectory_rhosts_owner_permission -eq 2 ] || [ $user_homedirectory_rhosts_owner_permission -eq 0 ]; then 994 | user_homedirectory_rhosts_group_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 995 | if [ $user_homedirectory_rhosts_group_permission -eq 0 ]; then 996 | user_homedirectory_rhosts_other_permission=`stat ${user_homedirectory_path[$j]}/.rhosts | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 997 | if [ $user_homedirectory_rhosts_other_permission -eq 0 ]; then 998 | user_homedirectory_rhosts_plus_count=`grep -vE '^#|^\s#' ${user_homedirectory_path[$j]}/.rhosts | grep '+' | wc -l` 999 | if [ $user_homedirectory_rhosts_plus_count -gt 0 ]; then 1000 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1001 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일에 '+' 설정이 있습니다." >> $resultfile 2>&1 1002 | return 0 1003 | fi 1004 | else 1005 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1006 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1007 | return 0 1008 | fi 1009 | else 1010 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1011 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1012 | return 0 1013 | fi 1014 | else 1015 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1016 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1017 | return 0 1018 | fi 1019 | else 1020 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1021 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 권한이 600보다 큽니다." >> $resultfile 2>&1 1022 | return 0 1023 | fi 1024 | else 1025 | echo "※ U-17 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1026 | echo " r 계열 서비스를 사용하고, 사용자 홈 디렉터리 내 .rhosts 파일의 소유자(owner)가 root 또는 해당 계정이 아닙니다." >> $resultfile 2>&1 1027 | return 0 1028 | fi 1029 | fi 1030 | done 1031 | fi 1032 | done 1033 | fi 1034 | echo "※ U-17 결과 : 양호(Good)" >> $resultfile 2>&1 1035 | return 0 1036 | } 1037 | 1038 | U_18() { 1039 | echo "" >> $resultfile 2>&1 1040 | echo "▶ U-18(상) | 2. 파일 및 디렉토리 관리 > 2.14 접속 IP 및 포트 제한 ◀" >> $resultfile 2>&1 1041 | echo " 양호 판단 기준 : 접속을 허용할 특정 호스트에 대한 IP 주소 및 포트 제한을 설정한 경우" >> $resultfile 2>&1 1042 | echo " ### /etc/hosts.deny 파일에 ALL:ALL 설정이 없거나 /etc/hosts.allow 파일에 ALL:ALL 설정이 있을 경우 취약으로 판단" >> $resultfile 2>&1 1043 | echo " ### iptables 사용 시 수동 점검을 추가로 진행하세요." >> $resultfile 2>&1 1044 | if [ -f /etc/hosts.deny ]; then 1045 | etc_hostsdeny_allall_count=`grep -vE '^#|^\s#' /etc/hosts.deny | awk '{gsub(" ", "", $0); print}' | grep -i 'all:all' | wc -l` 1046 | if [ $etc_hostsdeny_allall_count -gt 0 ]; then 1047 | if [ -f /etc/hosts.allow ]; then 1048 | etc_hostsallow_allall_count=`grep -vE '^#|^\s#' /etc/hosts.allow | awk '{gsub(" ", "", $0); print}' | grep -i 'all:all' | wc -l` 1049 | if [ $etc_hostsallow_allall_count -gt 0 ]; then 1050 | echo "※ U-18 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1051 | echo " /etc/hosts.allow 파일에 'ALL : ALL' 설정이 있습니다." >> $resultfile 2>&1 1052 | return 0 1053 | else 1054 | echo "※ U-18 결과 : 양호(Good)" >> $resultfile 2>&1 1055 | return 0 1056 | fi 1057 | else 1058 | echo "※ U-18 결과 : 양호(Good)" >> $resultfile 2>&1 1059 | return 0 1060 | fi 1061 | else 1062 | echo "※ U-18 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1063 | echo " /etc/hosts.deny 파일에 'ALL : ALL' 설정이 없습니다." >> $resultfile 2>&1 1064 | return 0 1065 | fi 1066 | else 1067 | echo "※ U-18 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1068 | echo " /etc/hosts.deny 파일이 없습니다." >> $resultfile 2>&1 1069 | return 0 1070 | fi 1071 | } 1072 | 1073 | U_19() { 1074 | echo "" >> $resultfile 2>&1 1075 | echo "▶ U-19(상) | 3. 서비스 관리 > 3.1 Finger 서비스 비활성화 ◀" >> $resultfile 2>&1 1076 | echo " 양호 판단 기준 : Finger 서비스가 비활성화 되어 있는 경우" >> $resultfile 2>&1 1077 | if [ -f /etc/services ]; then 1078 | finger_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="finger" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 1079 | if [ $finger_port_count -gt 0 ]; then 1080 | finger_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="finger" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 1081 | for ((i=0; i<${#finger_port[@]}; i++)) 1082 | do 1083 | netstat_finger_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${finger_port[$i]} " | wc -l` 1084 | if [ $netstat_finger_count -gt 0 ]; then 1085 | echo "※ U-19 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1086 | echo " finger 서비스가 실행 중입니다." >> $resultfile 2>&1 1087 | return 0 1088 | fi 1089 | done 1090 | fi 1091 | fi 1092 | ps_finger_count=`ps -ef | grep -i 'finger' | grep -v 'grep' | wc -l` 1093 | if [ $ps_finger_count -gt 0 ]; then 1094 | echo "※ U-19 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1095 | echo " finger 서비스가 실행 중입니다." >> $resultfile 2>&1 1096 | return 0 1097 | else 1098 | echo "※ U-19 결과 : 양호(Good)" >> $resultfile 2>&1 1099 | return 0 1100 | fi 1101 | } 1102 | 1103 | U_20() { 1104 | echo "" >> $resultfile 2>&1 1105 | echo "▶ U-20(상) | 3. 서비스 관리 > 3.2 Anonymous FTP 비활성화 ◀" >> $resultfile 2>&1 1106 | echo " 양호 판단 기준 : Anonymous FTP (익명 ftp) 접속을 차단한 경우" >> $resultfile 2>&1 1107 | if [ -f /etc/passwd ]; then 1108 | if [ `awk -F : '$1=="ftp" || $1=="anonymous"' /etc/passwd | wc -l` -gt 0 ]; then 1109 | file_exists_count=0 1110 | if [ `find / -name 'proftpd.conf' -type f 2>/dev/null | wc -l` -gt 0 ]; then 1111 | proftpdconf_settings_files=(`find / -name 'proftpd.conf' -type f 2>/dev/null`) 1112 | for ((i=0; i<${#proftpdconf_settings_files[@]}; i++)) 1113 | do 1114 | ((file_exists_count++)) 1115 | proftpdconf_anonymous_start_line_count=`grep -vE '^#|^\s#' ${proftpdconf_settings_files[$i]} | grep '' | wc -l` 1117 | if [ $proftpdconf_anonymous_start_line_count -gt 0 ] && [ $proftpdconf_anonymous_end_line_count -gt 0 ]; then 1118 | proftpdconf_anonymous_start_line=`grep -vE '^#|^\s#' ${proftpdconf_settings_files[$i]} | grep -n '' | awk -F : '{print $1}'` 1120 | proftpdconf_anonymous_contents_range=$((proftpdconf_anonymous_end_line-proftpdconf_anonymous_start_line)) 1121 | proftpdconf_anonymous_enable_count=`grep -vE '^#|^\s#' ${proftpdconf_settings_files[$i]} | grep -A $proftpdconf_anonymous_contents_range '> $resultfile 2>&1 1124 | echo " ${proftpdconf_settings_files[$i]} 파일에서 'User' 또는 'UserAlias' 옵션이 삭제 또는 주석 처리되어 있지 않습니다." >> $resultfile 2>&1 1125 | return 0 1126 | fi 1127 | fi 1128 | done 1129 | fi 1130 | if [ `find / -name 'vsftpd.conf' -type f 2>/dev/null | wc -l` -gt 0 ]; then 1131 | ((file_exists_count++)) 1132 | vsftpdconf_settings_files=(`find / -name 'vsftpd.conf' -type f 2>/dev/null`) 1133 | settings_in_vsftpdconf=0 1134 | for ((i=0; i<${#vsftpdconf_settings_files[@]}; i++)) 1135 | do 1136 | vsftpdconf_anonymous_enable_count=`grep -vE '^#|^\s#' ${vsftpdconf_settings_files[$i]} | grep -i 'anonymous_enable' | wc -l` 1137 | if [ $vsftpdconf_anonymous_enable_count -gt 0 ]; then 1138 | ((settings_in_vsftpdconf++)) 1139 | vsftpdconf_anonymous_enable_value=`grep -vE '^#|^\s#' ${vsftpdconf_settings_files[$i]} | grep -i 'anonymous_enable' | awk '{gsub(" ", "", $0); print tolower($0)}' | awk -F 'anonymous_enable=' '{print $2}'` 1140 | if [[ $vsftpdconf_anonymous_enable_value =~ yes ]]; then 1141 | echo "※ U-20 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1142 | echo " ${vsftpdconf_settings_files[$i]} 파일에서 익명 ftp 접속을 허용하고 있습니다." >> $resultfile 2>&1 1143 | return 0 1144 | fi 1145 | fi 1146 | done 1147 | if [ $settings_in_vsftpdconf -eq 0 ]; then 1148 | echo "※ U-20 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1149 | echo " vsftpd.conf 파일에 익명 ftp 접속을 설정하는 옵션이 없습니다." >> $resultfile 2>&1 1150 | return 0 1151 | fi 1152 | fi 1153 | if [ $file_exists_count -eq 0 ]; then 1154 | echo "※ U-20 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1155 | echo " 익명 ftp 접속을 설정하는 파일이 없습니다." >> $resultfile 2>&1 1156 | return 0 1157 | fi 1158 | fi 1159 | fi 1160 | echo "※ U-20 결과 : 양호(Good)" >> $resultfile 2>&1 1161 | return 0 1162 | } 1163 | 1164 | U_21() { 1165 | echo "" >> $resultfile 2>&1 1166 | echo "▶ U-21(상) | 3. 서비스 관리 > 3.3 r 계열 서비스 비활성화 ◀" >> $resultfile 2>&1 1167 | echo " 양호 판단 기준 : 불필요한 r 계열 서비스가 비활성화 되어 있는 경우" >> $resultfile 2>&1 1168 | r_command=("rsh" "rlogin" "rexec" "shell" "login" "exec") 1169 | if [ -d /etc/xinetd.d ]; then 1170 | for ((i=0; i<${#r_command[@]}; i++)) 1171 | do 1172 | if [ -f /etc/xinetd.d/${r_command[$i]} ]; then 1173 | etc_xinetdd_rcommand_disable_count=`grep -vE '^#|^\s#' /etc/xinetd.d/${r_command[$i]} | grep -i 'disable' | grep -i 'yes' | wc -l` 1174 | if [ $etc_xinetdd_rcommand_disable_count -eq 0 ]; then 1175 | echo "※ U-21 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1176 | echo " 불필요한 ${r_command[$i]} 서비스가 실행 중입니다." >> $resultfile 2>&1 1177 | return 0 1178 | fi 1179 | fi 1180 | done 1181 | fi 1182 | if [ -f /etc/inetd.conf ]; then 1183 | for ((i=0; i<${#r_command[@]}; i++)) 1184 | do 1185 | etc_inetdconf_enable_count=`grep -vE '^#|^\s#' /etc/inetd.conf | grep ${r_command[$i]} | wc -l` 1186 | if [ $etc_inetdconf_enable_count -gt 0 ]; then 1187 | echo "※ U-21 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1188 | echo " 불필요한 ${r_command[$i]} 서비스가 실행 중입니다." >> $resultfile 2>&1 1189 | return 0 1190 | fi 1191 | done 1192 | fi 1193 | echo "※ U-21 결과 : 양호(Good)" >> $resultfile 2>&1 1194 | return 0 1195 | } 1196 | 1197 | U_22() { 1198 | echo "" >> $resultfile 2>&1 1199 | echo "▶ U-22(상) | 3. 서비스 관리 > 3.4 crond 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 1200 | echo " 양호 판단 기준 : crontab 명령어 일반사용자 금지 및 cron 관련 파일 640 이하인 경우" >> $resultfile 2>&1 1201 | crontab_path=("/usr/bin/crontab" "/usr/sbin/crontab" "/bin/crontab") 1202 | if [ `which crontab 2>/dev/null | wc -l` -gt 0 ]; then 1203 | crontab_path[${#crontab_path[@]}]=`which crontab 2>/dev/null` 1204 | fi 1205 | for ((i=0; i<${#crontab_path[@]}; i++)) 1206 | do 1207 | if [ -f ${crontab_path[$i]} ]; then 1208 | crontab_permission=`stat ${crontab_path[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,2)}'` # group, owner 권한만 추출함 1209 | if [ $crontab_permission -le 50 ]; then 1210 | crontab_group_permission=`stat ${crontab_path[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 1211 | if [ $crontab_group_permission -eq 5 ] || [ $crontab_group_permission -eq 4 ] || [ $crontab_group_permission -eq 1 ] || [ $crontab_group_permission -eq 0 ]; then 1212 | crontab_other_permission=`stat ${crontab_path[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 1213 | if [ $crontab_other_permission -ne 0 ]; then 1214 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1215 | echo " ${crontab_path[$i]} 명령어의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1216 | return 0 1217 | fi 1218 | else 1219 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1220 | echo " ${crontab_path[$i]} 명령어의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1221 | return 0 1222 | fi 1223 | else 1224 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1225 | echo " ${crontab_path[$i]} 명령어의 권한이 750보다 큽니다." >> $resultfile 2>&1 1226 | return 0 1227 | fi 1228 | fi 1229 | done 1230 | cron_directory=("/etc/cron.hourly" "/etc/cron.daily" "/etc/cron.weekly" "/etc/cron.monthly" "/var/spool/cron" "/var/spool/cron/crontabs") 1231 | cron_file=("/etc/crontab" "/etc/cron.allow" "/etc/cron.deny") 1232 | for ((i=0; i<${#cron_directory[@]}; i++)) 1233 | do 1234 | cron_file_count=`find ${cron_directory[$i]} -type f 2>/dev/null | wc -l` 1235 | if [ $cron_file_count -gt 0 ]; then 1236 | cron_file2=(`find ${cron_directory[$i]} -type f 2>/dev/null`) 1237 | for ((j=0; j<${#cron_file2[@]}; j++)) 1238 | do 1239 | cron_file[${#cron_file[@]}]=${cron_file2[$j]} 1240 | done 1241 | fi 1242 | done 1243 | for ((i=0; i<${#cron_file[@]}; i++)) 1244 | do 1245 | if [ -f ${cron_file[$i]} ]; then 1246 | cron_file_owner_name=`ls -l ${cron_file[$i]} | awk '{print $3}'` 1247 | if [[ $cron_file_owner_name =~ root ]]; then 1248 | cron_file_permission=`stat ${cron_file[$i]}| grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 1249 | if [ $cron_file_permission -le 640 ]; then 1250 | cron_file_owner_permission=`stat ${cron_file[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 1251 | if [ $cron_file_owner_permission -eq 6 ] || [ $cron_file_owner_permission -eq 4 ] || [ $cron_file_owner_permission -eq 2 ] || [ $cron_file_owner_permission -eq 0 ]; then 1252 | cron_file_group_permission=`stat ${cron_file[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 1253 | if [ $cron_file_group_permission -eq 4 ] || [ $cron_file_group_permission -eq 0 ]; then 1254 | cron_file_other_permission=`stat ${cron_file[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 1255 | if [ $cron_file_other_permission -ne 0 ]; then 1256 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1257 | echo " ${cron_file[$i]} 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1258 | return 0 1259 | fi 1260 | else 1261 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1262 | echo " ${cron_file[$i]} 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1263 | return 0 1264 | fi 1265 | else 1266 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1267 | echo " ${cron_file[$i]} 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 1268 | return 0 1269 | fi 1270 | else 1271 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1272 | echo " ${cron_file[$i]} 파일의 권한이 640보다 큽니다." >> $resultfile 2>&1 1273 | return 0 1274 | fi 1275 | else 1276 | echo "※ U-22 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1277 | echo " ${cron_file[$i]} 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 1278 | return 0 1279 | fi 1280 | fi 1281 | done 1282 | echo "※ U-22 결과 : 양호(Good)" >> $resultfile 2>&1 1283 | return 0 1284 | } 1285 | 1286 | U_23() { 1287 | echo "" >> $resultfile 2>&1 1288 | echo "▶ U-23(상) | 3. 서비스 관리 > 3.5 DoS 공격에 취약한 서비스 비활성화 ◀" >> $resultfile 2>&1 1289 | echo " 양호 판단 기준 : 사용하지 않는 DoS 공격에 취약한 서비스가 비활성화된 경우" >> $resultfile 2>&1 1290 | services=("echo" "discard" "daytime" "chargen") 1291 | if [ -d /etc/xinetd.d ]; then 1292 | for ((i=0; i<${#services[@]}; i++)) 1293 | do 1294 | if [ -f /etc/xinetd.d/${services[$i]} ]; then 1295 | etc_xinetdd_service_disable_yes_count=`grep -vE '^#|^\s#' /etc/xinetd.d/${services[$i]} | grep -i 'disable' | grep -i 'yes' | wc -l` 1296 | if [ $service_disable_yes_count -eq 0 ]; then 1297 | echo "※ U-23 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1298 | echo " ${services[$i]} 서비스가 /etc/xinetd.d 디렉터리 내 서비스 파일에서 실행 중입니다." >> $resultfile 2>&1 1299 | return 0 1300 | fi 1301 | fi 1302 | done 1303 | fi 1304 | if [ -f /etc/inetd.conf ]; then 1305 | for ((i=0; i<${#services[@]}; i++)) 1306 | do 1307 | etc_inetdconf_enable_count=`grep -vE '^#|^\s#' /etc/inetd.conf | grep ${services[$i]} | wc -l` 1308 | if [ $etc_inetdconf_enable_count -gt 0 ]; then 1309 | echo "※ U-23 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1310 | echo " ${services[$i]} 서비스가 /etc/inetd.conf 파일에서 실행 중입니다." >> $resultfile 2>&1 1311 | return 0 1312 | fi 1313 | done 1314 | fi 1315 | echo "※ U-23 결과 : 양호(Good)" >> $resultfile 2>&1 1316 | return 0 1317 | } 1318 | 1319 | U_24() { 1320 | echo "" >> $resultfile 2>&1 1321 | echo "▶ U-24(상) | 3. 서비스 관리 > 3.6 NFS 서비스 비활성화 ◀" >> $resultfile 2>&1 1322 | echo " 양호 판단 기준 : 불필요한 NFS 서비스 관련 데몬이 비활성화 되어 있는 경우" >> $resultfile 2>&1 1323 | if [ `ps -ef | grep -iE 'nfs|rpc.statd|statd|rpc.lockd|lockd' | grep -ivE 'grep|kblockd|rstatd|' | wc -l` -gt 0 ]; then 1324 | echo "※ U-24 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1325 | echo " 불필요한 NFS 서비스 관련 데몬이 실행 중입니다." >> $resultfile 2>&1 1326 | return 0 1327 | else 1328 | echo "※ U-24 결과 : 양호(Good)" >> $resultfile 2>&1 1329 | return 0 1330 | fi 1331 | } 1332 | 1333 | U_25() { 1334 | echo "" >> $resultfile 2>&1 1335 | echo "▶ U-25(상) | 3. 서비스 관리 > 3.7 NFS 접근 통제 ◀" >> $resultfile 2>&1 1336 | echo " 양호 판단 기준 : 불필요한 NFS 서비스를 사용하지 않거나, 불가피하게 사용 시 everyone 공유를 제한한 경우" >> $resultfile 2>&1 1337 | if [ `ps -ef | grep -iE 'nfs|rpc.statd|statd|rpc.lockd|lockd' | grep -ivE 'grep|kblockd|rstatd|' | wc -l` -gt 0 ]; then 1338 | if [ -f /etc/exports ]; then 1339 | etc_exports_all_count=`grep -vE '^#|^\s#' /etc/exports | grep '/' | grep '*' | wc -l` 1340 | etc_exports_insecure_count=`grep -vE '^#|^\s#' /etc/exports | grep '/' | grep -i 'insecure' | wc -l` 1341 | etc_exports_directory_count=`grep -vE '^#|^\s#' /etc/exports | grep '/' | wc -l` 1342 | etc_exports_squash_count=`grep -vE '^#|^\s#' /etc/exports | grep '/' | grep -iE 'root_squash|all_squash' | wc -l` 1343 | if [ $etc_exports_all_count -gt 0 ]; then 1344 | echo "※ U-25 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1345 | echo " /etc/exports 파일에 '*' 설정이 있습니다." >> $resultfile 2>&1 1346 | echo " ### '*' 설정 = 모든 클라이언트에 대해 전체 네트워크 공유 허용" >> $resultfile 2>&1 1347 | return 0 1348 | elif [ $etc_exports_insecure_count -gt 0 ]; then 1349 | echo "※ U-25 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1350 | echo " /etc/exports 파일에 'insecure' 옵션이 설정되어 있습니다." >> $resultfile 2>&1 1351 | return 0 1352 | else 1353 | if [ $etc_exports_directory_count -ne $etc_exports_squash_count ]; then 1354 | echo "※ U-25 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1355 | echo " /etc/exports 파일에 'root_squash' 또는 'all_squash' 옵션이 설정되어 있지 않습니다." >> $resultfile 2>&1 1356 | return 0 1357 | fi 1358 | fi 1359 | fi 1360 | else 1361 | echo "※ U-25 결과 : 양호(Good)" >> $resultfile 2>&1 1362 | return 0 1363 | fi 1364 | } 1365 | 1366 | U_26() { 1367 | echo "" >> $resultfile 2>&1 1368 | echo "▶ U-26(상) | 3. 서비스 관리 > 3.8 automountd 제거 ◀" >> $resultfile 2>&1 1369 | echo " 양호 판단 기준 : automountd 서비스가 비활성화 되어 있는 경우" >> $resultfile 2>&1 1370 | if [ `ps -ef | grep -iE 'automount|autofs' | grep -v 'grep' | wc -l` -gt 0 ]; then 1371 | echo "※ U-26 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1372 | echo " automountd 서비스가 실행 중입니다." >> $resultfile 2>&1 1373 | return 0 1374 | else 1375 | echo "※ U-26 결과 : 양호(Good)" >> $resultfile 2>&1 1376 | return 0 1377 | fi 1378 | } 1379 | 1380 | U_27() { 1381 | echo "" >> $resultfile 2>&1 1382 | echo "▶ U-27(상) | 3. 서비스 관리 > 3.9 RPC 서비스 확인 ◀" >> $resultfile 2>&1 1383 | echo " 양호 판단 기준 : 불필요한 RPC 서비스가 비활성화 되어 있는 경우" >> $resultfile 2>&1 1384 | rpc_services=("rpc.cmsd" "rpc.ttdbserverd" "sadmind" "rusersd" "walld" "sprayd" "rstatd" "rpc.nisd" "rexd" "rpc.pcnfsd" "rpc.statd" "rpc.ypupdated" "rpc.rquotad" "kcms_server" "cachefsd") 1385 | if [ -d /etc/xinetd.d ]; then 1386 | for ((i=0; i<${#rpc_services[@]}; i++)) 1387 | do 1388 | if [ -f /etc/xinetd.d/${rpc_services[$i]} ]; then 1389 | etc_xinetdd_rpcservice_disable_count=`grep -vE '^#|^\s#' /etc/xinetd.d/${rpc_services[$i]} | grep -i 'disable' | grep -i 'yes' | wc -l` 1390 | if [ $etc_xinetdd_rpcservice_disable_count -eq 0 ]; then 1391 | echo "※ U-27 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1392 | echo " 불필요한 RPC 서비스가 /etc/xinetd.d 디렉터리 내 서비스 파일에서 실행 중입니다." >> $resultfile 2>&1 1393 | return 0 1394 | fi 1395 | fi 1396 | done 1397 | fi 1398 | if [ -f /etc/inetd.conf ]; then 1399 | for ((i=0; i<${#rpc_services[@]}; i++)) 1400 | do 1401 | etc_inetdconf_rpcservice_enable_count=`grep -vE '^#|^\s#' /etc/inetd.conf | grep -w ${rpc_services[$i]} | wc -l` 1402 | if [ $etc_inetdconf_rpcservice_enable_count -gt 0 ]; then 1403 | echo "※ U-27 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1404 | echo " 불필요한 RPC 서비스가 /etc/inetd.conf 파일에서 실행 중입니다." >> $resultfile 2>&1 1405 | return 0 1406 | fi 1407 | done 1408 | fi 1409 | echo "※ U-27 결과 : 양호(Good)" >> $resultfile 2>&1 1410 | return 0 1411 | } 1412 | 1413 | U_28() { 1414 | echo "" >> $resultfile 2>&1 1415 | echo "▶ U-28(상) | 3. 서비스 관리 > 3.10 NIS, NIS+ 점검 ◀" >> $resultfile 2>&1 1416 | echo " 양호 판단 기준 : NIS 서비스가 비활성화 되어 있거나, 필요 시 NIS+를 사용하는 경우" >> $resultfile 2>&1 1417 | if [ `ps -ef | grep -iE 'ypserv|ypbind|ypxfrd|rpc.yppasswdd|rpc.ypupdated' | grep -v 'grep' | wc -l` -gt 0 ]; then 1418 | echo "※ U-28 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1419 | echo " NIS 서비스가 실행 중입니다." >> $resultfile 2>&1 1420 | return 0 1421 | else 1422 | echo "※ U-28 결과 : 양호(Good)" >> $resultfile 2>&1 1423 | return 0 1424 | fi 1425 | } 1426 | 1427 | U_29() { 1428 | echo "" >> $resultfile 2>&1 1429 | echo "▶ U-29(상) | 3. 서비스 관리 > 3.11 tftp, talk 서비스 비활성화 ◀" >> $resultfile 2>&1 1430 | echo " 양호 판단 기준 : tftp, talk, ntalk 서비스가 비활성화 되어 있는 경우" >> $resultfile 2>&1 1431 | services=("tftp" "talk" "ntalk") 1432 | if [ -d /etc/xinetd.d ]; then 1433 | for ((i=0; i<${#services[@]}; i++)) 1434 | do 1435 | if [ -f /etc/xinetd.d/${services[$i]} ]; then 1436 | etc_xinetdd_service_disable_count=`grep -vE '^#|^\s#' /etc/xinetd.d/${services[$i]} | grep -i 'disable' | grep -i 'yes' | wc -l` 1437 | if [ $etc_xinetdd_service_disable_count -eq 0 ]; then 1438 | echo "※ U-29 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1439 | echo " ${services[$i]} 서비스가 /etc/xinetd.d 디렉터리 내 서비스 파일에서 실행 중입니다." >> $resultfile 2>&1 1440 | return 0 1441 | fi 1442 | fi 1443 | done 1444 | fi 1445 | if [ -f /etc/inetd.conf ]; then 1446 | for ((i=0; i<${#services[@]}; i++)) 1447 | do 1448 | etc_inetdconf_service_enable_count=`grep -vE '^#|^\s#' /etc/inetd.conf | grep ${services[$i]} | wc -l` 1449 | if [ $etc_inetdconf_service_enable_count -gt 0 ]; then 1450 | echo "※ U-29 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1451 | echo " ${services[$i]} 서비스가 /etc/inetd.conf 파일에서 실행 중입니다." >> $resultfile 2>&1 1452 | return 0 1453 | fi 1454 | done 1455 | fi 1456 | echo "※ U-29 결과 : 양호(Good)" >> $resultfile 2>&1 1457 | return 0 1458 | } 1459 | 1460 | U_30() { 1461 | echo "" >> $resultfile 2>&1 1462 | echo "▶ U-30(상) | 3. 서비스 관리 > 3.12 Sendmail 버전 점검 ◀" >> $resultfile 2>&1 1463 | echo " 양호 판단 기준 : Sendmail 버전이 최신버전인 경우" >> $resultfile 2>&1 1464 | if [ -f /etc/services ]; then 1465 | smtp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 1466 | if [ $smtp_port_count -gt 0 ]; then 1467 | smtp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 1468 | for ((i=0; i<${#smtp_port[@]}; i++)) 1469 | do 1470 | netstat_smtp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${smtp_port[$i]} " | wc -l` 1471 | if [ $netstat_smtp_count -gt 0 ]; then 1472 | rpm_smtp_version=`rpm -qa 2>/dev/null | grep 'sendmail' | awk -F 'sendmail-' '{print $2}'` 1473 | dnf_smtp_version=`dnf list installed sendmail 2>/dev/null | grep -v 'Installed Packages' | awk '{print $2}'` 1474 | if [[ $rpm_smtp_version != 8.17.1* ]] && [[ $dnf_smtp_version != 8.17.1* ]]; then 1475 | echo "※ U-30 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1476 | echo " sendmail 버전이 최신 버전(8.17.1)이 아닙니다." >> $resultfile 2>&1 1477 | return 0 1478 | fi 1479 | fi 1480 | done 1481 | fi 1482 | fi 1483 | ps_smtp_count=`ps -ef | grep -iE 'smtp|sendmail' | grep -v 'grep' | wc -l` 1484 | if [ $ps_smtp_count -gt 0 ]; then 1485 | rpm_smtp_version=`rpm -qa 2>/dev/null | grep 'sendmail' | awk -F 'sendmail-' '{print $2}'` 1486 | dnf_smtp_version=`dnf list installed sendmail 2>/dev/null | grep -v 'Installed Packages' | awk '{print $2}'` 1487 | if [[ $rpm_smtp_version != 8.17.1* ]] && [[ $dnf_smtp_version != 8.17.1* ]]; then 1488 | echo "※ U-30 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1489 | echo " sendmail 버전이 최신 버전(8.17.1)이 아닙니다." >> $resultfile 2>&1 1490 | return 0 1491 | fi 1492 | fi 1493 | echo "※ U-30 결과 : 양호(Good)" >> $resultfile 2>&1 1494 | return 0 1495 | } 1496 | 1497 | U_31() { 1498 | echo "" >> $resultfile 2>&1 1499 | echo "▶ U-31(상) | 3. 서비스 관리 > 3.13 스팸 메일 릴레이 제한 ◀" >> $resultfile 2>&1 1500 | echo " 양호 판단 기준 : SMTP 서비스를 사용하지 않거나 릴레이 제한이 설정되어 있는 경우" >> $resultfile 2>&1 1501 | if [ -f /etc/services ]; then 1502 | smtp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 1503 | if [ $smtp_port_count -gt 0 ]; then 1504 | smtp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 1505 | for ((i=0; i<${#smtp_port[@]}; i++)) 1506 | do 1507 | netstat_smtp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${smtp_port[$i]} " | wc -l` 1508 | if [ $netstat_smtp_count -gt 0 ]; then 1509 | sendmailcf_exists_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 1510 | if [ $sendmailcf_exists_count -gt 0 ]; then 1511 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 1512 | if [ ${#sendmailcf_files[@]} -gt 0 ]; then 1513 | for ((j=0; j<${#sendmailcf_files[@]}; j++)) 1514 | do 1515 | sendmailcf_relaying_denied_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$j]} | grep -i 'R$\*' | grep -i 'Relaying denied' | wc -l` 1516 | if [ $sendmailcf_relaying_denied_count -eq 0 ]; then 1517 | echo "※ U-31 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1518 | echo " ${sendmailcf_files[$j]} 파일에 릴레이 제한이 설정되어 있지 않습니다." >> $resultfile 2>&1 1519 | return 0 1520 | fi 1521 | done 1522 | fi 1523 | fi 1524 | fi 1525 | done 1526 | fi 1527 | fi 1528 | ps_smtp_count=`ps -ef | grep -iE 'smtp|sendmail' | grep -v 'grep' | wc -l` 1529 | if [ $ps_smtp_count -gt 0 ]; then 1530 | sendmailcf_exists_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 1531 | if [ $sendmailcf_exists_count -gt 0 ]; then 1532 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 1533 | if [ ${#sendmailcf_files[@]} -gt 0 ]; then 1534 | for ((i=0; i<${#sendmailcf_files[@]}; i++)) 1535 | do 1536 | sendmailcf_relaying_denied_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$i]} | grep -i 'R$\*' | grep -i 'Relaying denied' | wc -l` 1537 | if [ $sendmailcf_relaying_denied_count -eq 0 ]; then 1538 | echo "※ U-31 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1539 | echo " ${sendmailcf_files[$i]} 파일에 릴레이 제한이 설정되어 있지 않습니다." >> $resultfile 2>&1 1540 | return 0 1541 | fi 1542 | done 1543 | fi 1544 | fi 1545 | fi 1546 | echo "※ U-31 결과 : 양호(Good)" >> $resultfile 2>&1 1547 | return 0 1548 | } 1549 | 1550 | U_32() { 1551 | echo "" >> $resultfile 2>&1 1552 | echo "▶ U-32(상) | 3. 서비스 관리 > 3.14 일반사용자의 Sendmail 실행 방지 ◀" >> $resultfile 2>&1 1553 | echo " 양호 판단 기준 : SMTP 서비스 미사용 또는, 일반 사용자의 Sendmail 실행 방지가 설정된 경우" >> $resultfile 2>&1 1554 | if [ -f /etc/services ]; then 1555 | smtp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 1556 | if [ $smtp_port_count -gt 0 ]; then 1557 | smtp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 1558 | for ((i=0; i<${#smtp_port[@]}; i++)) 1559 | do 1560 | netstat_smtp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${smtp_port[$i]} " | wc -l` 1561 | if [ $netstat_smtp_count -gt 0 ]; then 1562 | sendmailcf_exists_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 1563 | if [ $sendmailcf_exists_count -gt 0 ]; then 1564 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 1565 | for ((j=0; j<${#sendmailcf_files[@]}; j++)) 1566 | do 1567 | sendmailcf_file_restrictqrun_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$j]} | awk '{gsub(" ", "", $0); print tolower($0)}' | awk -F 'privacyoptions=' '{print $2}' | grep 'restrictqrun' | wc -l` 1568 | if [ $sendmailcf_file_restrictqrun_count -eq 0 ]; then 1569 | echo "※ U-32 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1570 | echo " ${sendmailcf_files[$j]} 파일에 restrictqrun 옵션이 설정되어 있지 않습니다." >> $resultfile 2>&1 1571 | return 0 1572 | fi 1573 | done 1574 | else 1575 | echo "※ U-32 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1576 | echo " sendmail.cf 파일이 없습니다." >> $resultfile 2>&1 1577 | return 0 1578 | fi 1579 | fi 1580 | done 1581 | fi 1582 | fi 1583 | ps_smtp_count=`ps -ef | grep -iE 'smtp|sendmail' | grep -v 'grep' | wc -l` 1584 | if [ $ps_smtp_count -gt 0 ]; then 1585 | sendmailcf_exists_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 1586 | if [ $sendmailcf_exists_count -gt 0 ]; then 1587 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 1588 | for ((i=0; i<${#sendmailcf_files[@]}; i++)) 1589 | do 1590 | sendmailcf_file_restrictqrun_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$i]} | awk '{gsub(" ", "", $0); print tolower($0)}' | awk -F 'privacyoptions=' '{print $2}' | grep 'restrictqrun' | wc -l` 1591 | if [ $sendmailcf_file_restrictqrun_count -eq 0 ]; then 1592 | echo "※ U-32 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1593 | echo " ${sendmailcf_files[$i]} 파일에 restrictqrun 옵션이 설정되어 있지 않습니다." >> $resultfile 2>&1 1594 | return 0 1595 | fi 1596 | done 1597 | else 1598 | echo "※ U-32 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1599 | echo " sendmail.cf 파일이 없습니다." >> $resultfile 2>&1 1600 | return 0 1601 | fi 1602 | fi 1603 | echo "※ U-32 결과 : 양호(Good)" >> $resultfile 2>&1 1604 | return 0 1605 | } 1606 | 1607 | U_33() { 1608 | echo "" >> $resultfile 2>&1 1609 | echo "▶ U-33(상) | 3. 서비스 관리 > 3.15 DNS 보안 버전 패치 ◀" >> $resultfile 2>&1 1610 | echo " 양호 판단 기준 : DNS 서비스를 사용하지 않거나 주기적으로 패치를 관리하고 있는 경우" >> $resultfile 2>&1 1611 | echo " ### 9.19 이상 버전은 개발 및 테스트 중이므로 9.18 버전으로 점검" >> $resultfile 2>&1 1612 | if [ `ps -ef | grep -i 'named' | grep -v 'grep' | wc -l` -gt 0 ]; then 1613 | rpm_bind9_minor_version=(`rpm -qa 2>/dev/null | grep '^bind' | awk -F '9.' '{print $2}' | grep -v '^$' | uniq`) 1614 | yum_bind_version=`yum info bind | grep -A 5 'Installed Packages' | grep 'Version' | awk -F : '{gsub(" ", "", $0); print $2}'` 1615 | if [ ${#rpm_bind9_minor_version[@]} -gt 0 ] || [ ${#yum_bind_version[@]} -gt 0 ]; then 1616 | for ((i=0; i<${#rpm_bind9_minor_version[@]}; i++)) 1617 | do 1618 | if [[ ${rpm_bind9_minor_version[$i]} =~ 18.* ]]; then 1619 | rpm_bind9_patch_version=(`rpm -qa 2>/dev/null | grep '^bind' | awk -F '18.' '{print $2}' | grep -v '^$' | uniq`) 1620 | if [ ${#rpm_bind9_patch_version[@]} -gt 0 ]; then 1621 | for ((j=0; j<${#rpm_bind9_patch_version[@]}; j++)) 1622 | do 1623 | if [[ ${rpm_bind9_patch_version[$j]} != [7-9]* ]] || [[ ${rpm_bind9_patch_version[$j]} != 1[0-6]* ]]; then 1624 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1625 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1626 | return 0 1627 | fi 1628 | done 1629 | else 1630 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1631 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1632 | return 0 1633 | fi 1634 | else 1635 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1636 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1637 | return 0 1638 | fi 1639 | done 1640 | for ((i=0; i<${#yum_bind_version[@]}; i++)) 1641 | do 1642 | if [[ ${yum_bind_version[$i]} == 9.18.* ]]; then 1643 | yum_bind_patch_version=`yum info bind | grep -A 5 'Installed Packages' | grep 'Version' | awk -F : '{gsub(" ", "", $0); print $2}' | awk -F '18.' '{print $2}'` 1644 | if [ ${#yum_bind_patch_version[@]} -gt 0 ]; then 1645 | for ((j=0; j<${#yum_bind_patch_version[@]}; j++)) 1646 | do 1647 | if [[ ${yum_bind_patch_version[$j]} != [7-9]* ]] || [[ ${yum_bind_patch_version[$j]} != 1[0-6]* ]]; then 1648 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1649 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1650 | return 0 1651 | fi 1652 | done 1653 | else 1654 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1655 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1656 | return 0 1657 | fi 1658 | else 1659 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1660 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1661 | return 0 1662 | fi 1663 | done 1664 | else 1665 | echo "※ U-33 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1666 | echo " BIND 버전이 최신 버전(9.18.7 이상)이 아닙니다." >> $resultfile 2>&1 1667 | return 0 1668 | fi 1669 | fi 1670 | echo "※ U-33 결과 : 양호(Good)" >> $resultfile 2>&1 1671 | return 0 1672 | } 1673 | 1674 | U_34() { 1675 | echo "" >> $resultfile 2>&1 1676 | echo "▶ U-34(상) | 3. 서비스 관리 > 3.16 DNS Zone Transfer 설정 ◀" >> $resultfile 2>&1 1677 | echo " 양호 판단 기준 : DNS 서비스 미사용 또는, Zone Transfer를 허가된 사용자에게만 허용한 경우" >> $resultfile 2>&1 1678 | ps_dns_count=`ps -ef | grep -i 'named' | grep -v 'grep' | wc -l` 1679 | if [ $ps_dns_count -gt 0 ]; then 1680 | if [ -f /etc/named.conf ]; then 1681 | etc_namedconf_allowtransfer_count=`grep -vE '^#|^\s#' /etc/named.conf | grep -i 'allow-transfer' | grep -i 'any' | wc -l` 1682 | if [ $etc_namedconf_allowtransfer_count -gt 0 ]; then 1683 | echo "※ U-34 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1684 | echo " /etc/named.conf 파일에 allow-transfer { any; } 설정이 있습니다." >> $resultfile 2>&1 1685 | return 0 1686 | fi 1687 | fi 1688 | fi 1689 | echo "※ U-34 결과 : 양호(Good)" >> $resultfile 2>&1 1690 | return 0 1691 | } 1692 | 1693 | U_35() { 1694 | echo "" >> $resultfile 2>&1 1695 | echo "▶ U-35(상) | 3. 서비스 관리 > 3.17 웹서비스 디렉토리 리스팅 제거 ◀" >> $resultfile 2>&1 1696 | echo " 양호 판단 기준 : 디렉터리 검색 기능을 사용하지 않는 경우" >> $resultfile 2>&1 1697 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf" "userdir.conf") 1698 | for ((i=0; i<${#webconf_files[@]}; i++)) 1699 | do 1700 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1701 | if [ $find_webconf_file_count -gt 0 ]; then 1702 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1703 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1704 | do 1705 | if [[ ${find_webconf_files[$j]} =~ userdir.conf ]]; then 1706 | userdirconf_disabled_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'userdir' | grep -i 'disabled' | wc -l` 1707 | if [ $userdirconf_disabled_count -eq 0 ]; then 1708 | userdirconf_indexes_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'Options' | grep -iv '\-indexes' | grep -i 'indexes' | wc -l` 1709 | if [ $userdirconf_indexes_count -gt 0 ]; then 1710 | echo "※ U-35 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1711 | echo " Apache 설정 파일에 디렉터리 검색 기능을 사용하도록 설정되어 있습니다." >> $resultfile 2>&1 1712 | return 0 1713 | fi 1714 | fi 1715 | else 1716 | webconf_file_indexes_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'Options' | grep -iv '\-indexes' | grep -i 'indexes' | wc -l` 1717 | if [ $webconf_file_indexes_count -gt 0 ]; then 1718 | echo "※ U-35 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1719 | echo " Apache 설정 파일에 디렉터리 검색 기능을 사용하도록 설정되어 있습니다." >> $resultfile 2>&1 1720 | return 0 1721 | fi 1722 | fi 1723 | done 1724 | fi 1725 | done 1726 | echo "※ U-35 결과 : 양호(Good)" >> $resultfile 2>&1 1727 | return 0 1728 | } 1729 | 1730 | U_36() { 1731 | echo "" >> $resultfile 2>&1 1732 | echo "▶ U-36(상) | 3. 서비스 관리 > 3.18 웹서비스 웹 프로세스 권한 제한 ◀" >> $resultfile 2>&1 1733 | echo " 양호 판단 기준 : Apache 데몬이 root 권한으로 구동되지 않는 경우" >> $resultfile 2>&1 1734 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf") 1735 | for ((i=0; i<${#webconf_files[@]}; i++)) 1736 | do 1737 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1738 | if [ $find_webconf_file_count -gt 0 ]; then 1739 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1740 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1741 | do 1742 | webconf_file_group_root_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -B 1 '^\s*Group' | grep 'root' | wc -l` 1743 | if [ $webconf_file_group_root_count -gt 0 ]; then 1744 | echo "※ U-36 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1745 | echo " Apache 데몬이 root 권한으로 구동되도록 설정되어 있습니다." >> $resultfile 2>&1 1746 | return 0 1747 | else 1748 | webconf_file_group_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep '^\s*Group' | awk '{print $2}' | sed 's/{//' | sed 's/}//' | wc -l` 1749 | if [ $webconf_file_group_count -gt 0 ]; then 1750 | webconf_file_group=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep '^\s*Group' | awk '{print $2}' | sed 's/{//' | sed 's/}//'` 1751 | webconf_file_group_root_count=`eval echo $webconf_file_group | grep 'root' | wc -l` 1752 | if [ $webconf_file_group_root_count -gt 0 ]; then 1753 | echo "※ U-36 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1754 | echo " Apache 데몬이 root 권한으로 구동되도록 설정되어 있습니다." >> $resultfile 2>&1 1755 | return 0 1756 | fi 1757 | fi 1758 | fi 1759 | done 1760 | fi 1761 | done 1762 | echo "※ U-36 결과 : 양호(Good)" >> $resultfile 2>&1 1763 | return 0 1764 | } 1765 | 1766 | U_37() { 1767 | echo "" >> $resultfile 2>&1 1768 | echo "▶ U-37(상) | 3. 서비스 관리 > 3.19 웹서비스 상위 디렉토리 접근 금지 ◀" >> $resultfile 2>&1 1769 | echo " 양호 판단 기준 : 상위 디렉터리에 이동제한을 설정한 경우" >> $resultfile 2>&1 1770 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf" "userdir.conf") 1771 | file_exists_count=0 1772 | for ((i=0; i<${#webconf_files[@]}; i++)) 1773 | do 1774 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1775 | if [ $find_webconf_file_count -gt 0 ]; then 1776 | ((file_exists_count++)) 1777 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1778 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1779 | do 1780 | if [[ ${find_webconf_files[$j]} =~ userdir.conf ]]; then 1781 | userdirconf_disabled_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'userdir' | grep -i 'disabled' | wc -l` 1782 | if [ $userdirconf_disabled_count -eq 0 ]; then 1783 | userdirconf_allowoverride_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'AllowOverride' | wc -l` 1784 | if [ $userdirconf_allowoverride_count -gt 0 ]; then 1785 | userdirconf_allowoverride_none_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'AllowOverride' | grep -i 'None' | wc -l` 1786 | if [ $userdirconf_allowoverride_none_count -gt 0 ]; then 1787 | echo "※ U-37 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1788 | echo " 웹 서비스 상위 디렉터리에 이동 제한을 설정하지 않았습니다." >> $resultfile 2>&1 1789 | return 0 1790 | fi 1791 | else 1792 | echo "※ U-37 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1793 | echo " 웹 서비스 상위 디렉터리에 이동 제한을 설정하지 않았습니다." >> $resultfile 2>&1 1794 | return 0 1795 | fi 1796 | fi 1797 | else 1798 | webconf_file_allowoverride_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'AllowOverride' | wc -l` 1799 | if [ $webconf_file_allowoverride_count -gt 0 ]; then 1800 | webconf_file_allowoverride_none_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'AllowOverride' | grep -i 'None' | wc -l` 1801 | if [ $webconf_file_allowoverride_none_count -gt 0 ]; then 1802 | echo "※ U-37 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1803 | echo " 웹 서비스 상위 디렉터리에 이동 제한을 설정하지 않았습니다." >> $resultfile 2>&1 1804 | return 0 1805 | fi 1806 | else 1807 | echo "※ U-37 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1808 | echo " 웹 서비스 상위 디렉터리에 이동 제한을 설정하지 않았습니다." >> $resultfile 2>&1 1809 | return 0 1810 | fi 1811 | fi 1812 | done 1813 | fi 1814 | done 1815 | ps_apache_count=`ps -ef | grep -iE 'httpd|apache2' | grep -v 'grep' | wc -l` 1816 | if [ $ps_apache_count -gt 0 ] && [ $file_exists_count -eq 0 ]; then 1817 | echo "※ U-37 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1818 | echo " Apache 서비스를 사용하고, 웹 서비스 상위 디렉터리에 이동 제한을 설정하는 파일이 없습니다." >> $resultfile 2>&1 1819 | return 0 1820 | else 1821 | echo "※ U-37 결과 : 양호(Good)" >> $resultfile 2>&1 1822 | return 0 1823 | fi 1824 | } 1825 | 1826 | U_38() { 1827 | echo "" >> $resultfile 2>&1 1828 | echo "▶ U-38(상) | 3. 서비스 관리 > 3.20 웹서비스 불필요한 파일 제거 ◀" >> $resultfile 2>&1 1829 | echo " 양호 판단 기준 : 기본으로 생성되는 불필요한 파일 및 디렉터리가 제거되어 있는 경우" >> $resultfile 2>&1 1830 | serverroot_directory=() 1831 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf") 1832 | for ((i=0; i<${#webconf_files[@]}; i++)) 1833 | do 1834 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1835 | if [ $find_webconf_file_count -gt 0 ]; then 1836 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1837 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1838 | do 1839 | webconf_serverroot_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep'ServerRoot' | grep '/' | wc -l` 1840 | if [ $webconf_serverroot_count -gt 0 ]; then 1841 | serverroot_directory[${#serverroot_directory[@]}]=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep 'ServerRoot' | grep '/' | awk '{gsub(/"/, "", $0); print $2}'` 1842 | fi 1843 | done 1844 | fi 1845 | done 1846 | apache2_serverroot_count=`apache2 -V 2>/dev/ull | grep -i 'root' | awk -F '"' '{gsub(" ", "", $0); print $2}' | wc -l` 1847 | if [ $apache2_serverroot_count -gt 0 ];then 1848 | serverroot_directory[${#serverroot_directory[@]}]=`apache2 -V 2>/dev/ull | grep -i 'root' | awk -F '"' '{gsub(" ", "", $0); print $2}'` 1849 | fi 1850 | httpd_serverroot_count=`httpd -V 2>/dev/ull | grep -i 'root' | awk -F '"' '{gsub(" ", "", $0); print $2}' | wc -l` 1851 | if [ $httpd_serverroot_count -gt 0 ]; then 1852 | serverroot_directory[${#serverroot_directory[@]}]=`httpd -V 2>/dev/ull | grep -i 'root' | awk -F '"' '{gsub(" ", "", $0); print $2}'` 1853 | fi 1854 | for ((i=0; i<${#serverroot_directory[@]}; i++)) 1855 | do 1856 | manual_file_exists_count=`find ${serverroot_directory[$i]} -name 'manual' -type f 2>/dev/null | wc -l` 1857 | if [ $manual_file_exists_count -gt 0 ]; then 1858 | echo "※ U-38 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1859 | echo " Apache 홈 디렉터리 내 기본으로 생성되는 불필요한 파일 및 디렉터리가 제거되어 있지 않습니다." >> $resultfile 2>&1 1860 | return 0 1861 | fi 1862 | done 1863 | echo "※ U-38 결과 : 양호(Good)" >> $resultfile 2>&1 1864 | return 0 1865 | } 1866 | 1867 | U_39() { 1868 | echo "" >> $resultfile 2>&1 1869 | echo "▶ U-39(상) | 3. 서비스 관리 > 3.21 웹서비스 링크 사용금지 ◀" >> $resultfile 2>&1 1870 | echo " 양호 판단 기준 : 심볼릭 링크, aliases 사용을 제한한 경우" >> $resultfile 2>&1 1871 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf" "userdir.conf") 1872 | for ((i=0; i<${#webconf_files[@]}; i++)) 1873 | do 1874 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1875 | if [ $find_webconf_file_count -gt 0 ]; then 1876 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1877 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1878 | do 1879 | if [[ ${find_webconf_files[$j]} =~ userdir.conf ]]; then 1880 | userdirconf_disabled_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'userdir' | grep -i 'disabled' | wc -l` 1881 | if [ $userdirconf_disabled_count -eq 0 ]; then 1882 | userdirconf_followsymlinks_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'Options' | grep -iv '\-FollowSymLinks' | grep -i 'FollowSymLinks' | wc -l` 1883 | if [ $userdirconf_followsymlinks_count -gt 0 ]; then 1884 | echo "※ U-39 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1885 | echo " Apache 설정 파일에 심볼릭 링크 사용을 제한하도록 설정하지 않습니다." >> $resultfile 2>&1 1886 | return 0 1887 | fi 1888 | fi 1889 | else 1890 | webconf_file_followSymlinks_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'Options' | grep -iv '\-FollowSymLinks' | grep -i 'FollowSymLinks' | wc -l` 1891 | if [ $webconf_file_followSymlinks_count -gt 0 ]; then 1892 | echo "※ U-39 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1893 | echo " Apache 설정 파일에 심볼릭 링크 사용을 제한하도록 설정하지 않습니다." >> $resultfile 2>&1 1894 | return 0 1895 | fi 1896 | fi 1897 | done 1898 | fi 1899 | done 1900 | echo "※ U-39 결과 : 양호(Good)" >> $resultfile 2>&1 1901 | return 0 1902 | } 1903 | 1904 | U_40() { 1905 | echo "" >> $resultfile 2>&1 1906 | echo "▶ U-40(상) | 3. 서비스 관리 > 3.22 웹서비스 파일 업로드 및 다운로드 제한 ◀" >> $resultfile 2>&1 1907 | echo " 양호 판단 기준 : 파일 업로드 및 다운로드를 제한한 경우" >> $resultfile 2>&1 1908 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf" "userdir.conf") 1909 | for ((i=0; i<${#webconf_files[@]}; i++)) 1910 | do 1911 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1912 | if [ $find_webconf_file_count -gt 0 ]; then 1913 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1914 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1915 | do 1916 | if [[ ${find_webconf_files[$j]} =~ userdir.conf ]]; then 1917 | userdirconf_disabled_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'userdir' | grep -i 'disabled' | wc -l` 1918 | if [ $userdirconf_disabled_count -eq 0 ]; then 1919 | userdirconf_limitrequestbody_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'LimitRequestBody' | wc -l` 1920 | if [ $userdirconf_limitrequestbody_count -eq 0 ]; then 1921 | echo "※ U-40 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1922 | echo " Apache 설정 파일에 파일 업로드 및 다운로드를 제한하도록 설정하지 않았습니다." >> $resultfile 2>&1 1923 | return 0 1924 | fi 1925 | fi 1926 | else 1927 | webconf_limitrequestbody_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'LimitRequestBody' | wc -l` 1928 | if [ $webconf_limitrequestbody_count -eq 0 ]; then 1929 | echo "※ U-40 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1930 | echo " Apache 설정 파일에 파일 업로드 및 다운로드를 제한하도록 설정하지 않았습니다." >> $resultfile 2>&1 1931 | return 0 1932 | fi 1933 | fi 1934 | done 1935 | fi 1936 | done 1937 | echo "※ U-40 결과 : 양호(Good)" >> $resultfile 2>&1 1938 | return 0 1939 | } 1940 | 1941 | U_41() { 1942 | echo "" >> $resultfile 2>&1 1943 | echo "▶ U-41(상) | 3. 서비스 관리 > 3.23 웹서비스 영역의 분리 ◀" >> $resultfile 2>&1 1944 | echo " 양호 판단 기준 : DocumentRoot를 별도의 디렉터리로 지정한 경우" >> $resultfile 2>&1 1945 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf") 1946 | file_exists_count=0 1947 | for ((i=0; i<${#webconf_files[@]}; i++)) 1948 | do 1949 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 1950 | if [ $find_webconf_file_count -gt 0 ]; then 1951 | ((file_exists_count++)) 1952 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 1953 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 1954 | do 1955 | webconf_file_documentroot_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'DocumentRoot' | grep '/' | wc -l` 1956 | if [ $webconf_file_documentroot_count -gt 0 ]; then 1957 | webconf_file_documentroot_basic_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'DocumentRoot' | grep '/' | awk '{gsub(/"/, "", $0); print $2}' | grep -E '/usr/local/apache/htdocs|/usr/local/apache2/htdocs|/var/www/html' | wc -l` 1958 | if [ $webconf_file_documentroot_basic_count -gt 0 ]; then 1959 | echo "※ U-41 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1960 | echo " Apache DocumentRoot를 기본 디렉터리로 설정했습니다." >> $resultfile 2>&1 1961 | return 0 1962 | fi 1963 | else 1964 | echo "※ U-41 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1965 | echo " Apache DocumentRoot를 설정하지 않았습니다." >> $resultfile 2>&1 1966 | return 0 1967 | fi 1968 | done 1969 | fi 1970 | done 1971 | ps_apache_count=`ps -ef | grep -iE 'httpd|apache2' | grep -v 'grep' | wc -l` 1972 | if [ $ps_apache_count -gt 0 ] && [ $file_exists_count -eq 0 ]; then 1973 | echo "※ U-41 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 1974 | echo " Apache 서비스를 사용하고, DocumentRoot를 설정하는 파일이 없습니다." >> $resultfile 2>&1 1975 | return 0 1976 | else 1977 | echo "※ U-41 결과 : 양호(Good)" >> $resultfile 2>&1 1978 | return 0 1979 | fi 1980 | } 1981 | 1982 | U_42() { 1983 | echo "" >> $resultfile 2>&1 1984 | echo "▶ U-42(상) | 4 패치 관리 > 4.1 최신 보안패치 및 벤더 권고사항 적용 ◀" >> $resultfile 2>&1 1985 | echo " 양호 판단 기준 : 패치 적용 정책을 수립하여 주기적으로 패치관리를 하고 있으며, 패치 1986 | 관련 내용을 확인하고 적용했을 경우" >> $resultfile 2>&1 1987 | echo "※ U-42 결과 : N/A" >> $resultfile 2>&1 1988 | echo " 수동으로 점검하세요." >> $resultfile 2>&1 1989 | } 1990 | 1991 | U_43() { 1992 | echo "" >> $resultfile 2>&1 1993 | echo "▶ U-43(상) | 5. 로그 관리 > 5.1 로그의 정기적 검토 및 보고 ◀" >> $resultfile 2>&1 1994 | echo " 양호 판단 기준 : 접속기록 등의 보안 로그, 응용 프로그램 및 시스템 로그 기록에 대해 정기적으로 검토, 분석, 리포트 작성 및 보고 등의 조치가 이루어지는 경우" >> $resultfile 2>&1 1995 | echo "※ U-43 결과 : N/A" >> $resultfile 2>&1 1996 | echo " 수동으로 점검하세요." >> $resultfile 2>&1 1997 | } 1998 | 1999 | U_44() { 2000 | echo "" >> $resultfile 2>&1 2001 | echo "▶ U-44(중) | 1. 계정관리 > 1.5 root 이외의 UID가 '0' 금지 ◀" >> $resultfile 2>&1 2002 | echo " 양호 판단 기준 : root 계정과 동일한 UID를 갖는 계정이 존재하지 않는 경우" >> $resultfile 2>&1 2003 | if [ -f /etc/passwd ]; then 2004 | if [ `awk -F : '$3==0 {print $1}' /etc/passwd | grep -vx 'root' | wc -l` -gt 0 ]; then 2005 | echo "※ U-44 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2006 | echo " root 계정과 동일한 UID(0)를 갖는 계정이 존재합니다." >> $resultfile 2>&1 2007 | return 0 2008 | else 2009 | echo "※ U-44 결과 : 양호(Good)" >> $resultfile 2>&1 2010 | return 0 2011 | fi 2012 | fi 2013 | } 2014 | 2015 | U_45() { 2016 | echo "" >> $resultfile 2>&1 2017 | echo "▶ U-45(하) | 1. 계정관리 > 1.6 root 계정 su 제한 ◀" >> $resultfile 2>&1 2018 | echo " 양호 판단 기준 : su 명령어를 특정 그룹에 속한 사용자만 사용하도록 제한되어 있는 경우" >> $resultfile 2>&1 2019 | echo " ### pam_rootok.so 모듈을 사용하지 않는 경우 U_45 함수 수정 필요" >> $resultfile 2>&1 2020 | echo " ### pam_rootok.so 모듈 사용과 함께 trust 문구를 추가한 경우 U_45 함수 수정 필요" >> $resultfile 2>&1 2021 | rpm_libpam_count=`rpm -qa 2>/dev/null | grep '^libpam' | wc -l` 2022 | yum_libpam_count=`yum list installed | grep '^libpam' | wc -l` 2023 | if [ $rpm_libpam_count -gt 0 ] && [ $yum_libpam_count -gt 0 ]; then 2024 | # !!! pam_rootok.so 설정을 하지 않은 경우 하단의 첫 번째 if 문을 삭제하세요. 2025 | etc_pamd_su_rootokso_count=`grep -vE '^#|^\s#' /etc/pam.d/su | grep 'pam_rootok.so' | wc -l` 2026 | if [ $etc_pamd_su_rootokso_count -gt 0 ]; then 2027 | # !!! pam_wheel.so 설정에 trust 문구를 추가한 경우 하단의 if 문 조건절에 'grep 'trust'를 추가하세요. 2028 | etc_pamd_su_wheelso_count=`grep -vE '^#|^\s#' /etc/pam.d/su | grep 'pam_wheel.so' | wc -l` 2029 | if [ $etc_pamd_su_wheelso_count -eq 0 ]; then 2030 | echo "※ U-45 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2031 | echo " /etc/pam.d/su 파일에 pam_wheel.so 모듈이 없습니다." >> $resultfile 2>&1 2032 | return 0 2033 | fi 2034 | else 2035 | echo "※ U-45 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2036 | echo " /etc/pam.d/su 파일에서 pam_rootok.so 모듈이 없습니다." >> $resultfile 2>&1 2037 | return 0 2038 | fi 2039 | else 2040 | su_executables=("/bin/su" "/usr/bin/su") 2041 | if [ `which su 2>/dev/null | wc -l` -gt 0 ]; then 2042 | su_executables[${#su_executables[@]}]=`which su 2>/dev/null` 2043 | fi 2044 | for ((i=0; i<${#su_executables[@]}; i++)) 2045 | do 2046 | if [ -f ${su_executables[$i]} ]; then 2047 | su_group_permission=`stat ${su_executables[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 2048 | if [ $su_group_permission -eq 5 ] || [ $su_group_permission -eq 4 ] || [ $su_group_permission -eq 1 ] || [ $su_group_permission -eq 0 ]; then 2049 | su_other_permission=`stat ${su_executables[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 2050 | if [ $su_other_permission -ne 0 ]; then 2051 | echo "※ U-45 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2052 | echo " ${su_executables[$i]} 실행 파일의 다른 사용자(other)에 대한 권한 취약합니다." >> $resultfile 2>&1 2053 | return 0 2054 | fi 2055 | else 2056 | echo "※ U-45 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2057 | echo " ${su_executables[$i]} 실행 파일의 그룹 사용자(group)에 대한 권한 취약합니다." >> $resultfile 2>&1 2058 | return 0 2059 | fi 2060 | fi 2061 | done 2062 | fi 2063 | echo "※ U-45 결과 : 양호(Good)" >> $resultfile 2>&1 2064 | return 0 2065 | } 2066 | 2067 | U_46() { 2068 | echo "" >> $resultfile 2>&1 2069 | echo "▶ U-46(중) | 1. 계정관리 > 1.7 패스워드 최소 길이 설정 ◀" >> $resultfile 2>&1 2070 | echo " 양호 판단 기준 : 패스워드 최소 길이가 8자 이상으로 설정되어 있는 경우" >> $resultfile 2>&1 2071 | file_exists_count=0 2072 | minlen_file_exists_count=0 2073 | no_settings_in_minlen_file=0 2074 | input_modules=("pam_pwquality.so" "pam_cracklib.so" "pam_unix.so") 2075 | # /etc/login.defs 파일 내 패스워드 최소 길이 설정 확인함 2076 | if [ -f /etc/login.defs ]; then 2077 | ((file_exists_count++)) 2078 | ((minlen_file_exists_count++)) 2079 | etc_logindefs_minlen_count=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MIN_LEN' | awk '{print $2}' | wc -l` 2080 | if [ $etc_logindefs_minlen_count -gt 0 ]; then 2081 | etc_logindefs_minlen_value=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MIN_LEN' | awk '{print $2}'` 2082 | if [ $etc_logindefs_minlen_value -lt 8 ]; then 2083 | echo "※ U-46 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2084 | echo " /etc/login.defs 파일에서 패스워드 최소 길이가 8 미만으로 설정되어 있습니다." >> $resultfile 2>&1 2085 | return 0 2086 | fi 2087 | else 2088 | ((no_settings_in_minlen_file++)) 2089 | fi 2090 | fi 2091 | # /etc/pam.d/system-auth, /etc/pam.d/password-auth 파일 내 패스워드 최소 길이와 최소 입력 확인함 2092 | minlen_settings_files=("/etc/pam.d/system-auth" "/etc/pam.d/password-auth") 2093 | for ((i=0; i<${#minlen_settings_files[@]}; i++)) 2094 | do 2095 | if [ -f ${minlen_settings_files[$i]} ]; then 2096 | ((file_exists_count++)) 2097 | for ((j=0; j<${#input_modules[@]}; j++)) 2098 | do 2099 | ((minlen_file_exists_count++)) 2100 | minlen_settings_file_minlen_count=`grep -vE '^#|^\s#' ${minlen_settings_files[$i]} | grep -i 'minlen' | grep -i ${input_modules[$j]} | wc -l` 2101 | if [ $minlen_settings_file_minlen_count -gt 0 ]; then 2102 | minlen_settings_file_minlen_value=`grep -vE '^#|^\s#' ${minlen_settings_files[$i]} | grep -i 'minlen' | grep -i ${input_modules[$j]} | awk -F 'minlen' '{gsub(" ", "", $0); print substr($2,2,1)}'` 2103 | if [ $minlen_settings_file_minlen_value -lt 8 ]; then 2104 | minlen_settings_file_minlen_second_value=`grep -vE '^#|^\s#' ${minlen_settings_files[$i]} | grep -i 'minlen' | grep -i ${input_modules[$j]} | awk -F 'minlen' '{gsub(" ", "", $0); print substr($2,3,1)}'` 2105 | if [[ $minlen_settings_file_minlen_second_value != [0-9] ]]; then 2106 | echo "※ U-46 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2107 | echo " ${u46_file[$i]} 파일에 패스워드 최소 길이가 8 미만으로 설정되어 있습니다." >> $resultfile 2>&1 2108 | return 0 2109 | fi 2110 | fi 2111 | else 2112 | ((no_settings_in_minlen_file++)) 2113 | fi 2114 | done 2115 | fi 2116 | done 2117 | if [ $file_exists_count -eq 0 ]; then 2118 | echo "※ U-46 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2119 | echo " 패스워드 최소 길이를 설정하는 파일이 없습니다." >> $resultfile 2>&1 2120 | return 0 2121 | elif [ $minlen_file_exists_count -eq $no_settings_in_minlen_file ]; then 2122 | echo "※ U-46 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2123 | echo " 패스워드 최소 길이를 설정한 파일이 없습니다." >> $resultfile 2>&1 2124 | return 0 2125 | else 2126 | echo "※ U-46 결과 : 양호(Good)" >> $resultfile 2>&1 2127 | return 0 2128 | fi 2129 | } 2130 | 2131 | U_47() { 2132 | echo "" >> $resultfile 2>&1 2133 | echo "▶ U-47(중) | 1. 계정관리 > 1.8 패스워드 최대 사용기간 설정 ◀" >> $resultfile 2>&1 2134 | echo " 양호 판단 기준 : 패스워드 최대 사용기간이 90일(12주) 이하로 설정되어 있는 경우" >> $resultfile 2>&1 2135 | if [ -f /etc/login.defs ]; then 2136 | etc_logindefs_maxdays_count=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MAX_DAYS' | awk '{print $2}' | wc -l` 2137 | if [ $etc_logindefs_maxdays_count -gt 0 ]; then 2138 | etc_logindefs_maxdays_value=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MAX_DAYS' | awk '{print $2}'` 2139 | if [ $etc_logindefs_maxdays_value -gt 90 ]; then 2140 | echo "※ U-47 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2141 | echo " /etc/login.defs 파일에 패스워드 최대 사용 기간이 91일 이상으로 설정되어 있습니다." >> $resultfile 2>&1 2142 | return 0 2143 | else 2144 | echo "※ U-47 결과 : 양호(Good)" >> $resultfile 2>&1 2145 | return 0 2146 | fi 2147 | else 2148 | echo "※ U-47 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2149 | echo " /etc/login.defs 파일에 패스워드 최대 사용 기간이 설정되어 있지 않습니다." >> $resultfile 2>&1 2150 | return 0 2151 | fi 2152 | else 2153 | echo "※ U-47 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2154 | echo " /etc/login.defs 파일이 없습니다." >> $resultfile 2>&1 2155 | return 0 2156 | fi 2157 | } 2158 | 2159 | U_48() { 2160 | echo "" >> $resultfile 2>&1 2161 | echo "▶ U-48(중) | 1. 계정관리 > 1.9 패스워드 최소 사용기간 설정 ◀" >> $resultfile 2>&1 2162 | echo " 양호 판단 기준 : 패스워드 최소 사용기간이 1일 이상 설정되어 있는 경우" >> $resultfile 2>&1 2163 | if [ -f /etc/login.defs ]; then 2164 | etc_logindefs_mindays_count=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MIN_DAYS' | awk '{print $2}' | wc -l` 2165 | if [ $etc_logindefs_mindays_count -gt 0 ]; then 2166 | etc_logindefs_mindays_value=`grep -vE '^#|^\s#' /etc/login.defs | grep -i 'PASS_MIN_DAYS' | awk '{print $2}'` 2167 | if [ $etc_logindefs_mindays_value -lt 1 ]; then 2168 | echo "※ U-48 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2169 | echo " /etc/login.defs 파일에 패스워드 최소 사용 기간이 1일 미만으로 설정되어 있습니다." >> $resultfile 2>&1 2170 | return 0 2171 | else 2172 | echo "※ U-48 결과 : 양호(Good)" >> $resultfile 2>&1 2173 | return 0 2174 | fi 2175 | else 2176 | echo "※ U-48 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2177 | echo " /etc/login.defs 파일에 패스워드 최소 사용 기간이 설정되어 있지 않습니다." >> $resultfile 2>&1 2178 | return 0 2179 | fi 2180 | else 2181 | echo "※ U-48 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2182 | echo " /etc/login.defs 파일이 없습니다." >> $resultfile 2>&1 2183 | return 0 2184 | fi 2185 | } 2186 | 2187 | U_49() { 2188 | echo "" >> $resultfile 2>&1 2189 | echo "▶ U-49(하) | 1. 계정관리 > 1.10 불필요한 계정 제거 ◀" >> $resultfile 2>&1 2190 | echo " 양호 판단 기준 : 불필요한 계정이 존재하지 않는 경우" >> $resultfile 2>&1 2191 | echo " ### 로그를 통한 확인은 수동으로 점검하세요." >> $resultfile 2>&1 2192 | echo " ### 불필요한 계정에 대한 변경 필요 시 U_49 함수 수정 필요" >> $resultfile 2>&1 2193 | echo " ### 불필요한 계정 = daemon, bin, sys, adm, listen, nobody, nobody4, noaccess, diag, operator, gopher, games, ftp, apache, httpd, www-data, mysql, mariadb, postgres, mail, postfix, news, lp, uucp, nuucp" >> $resultfile 2>&1 2194 | if [ -f /etc/passwd ]; then 2195 | # !!! 불필요한 계정을 변경할 경우 하단의 grep 명령어를 수정하세요. 2196 | if [ `awk -F : '{print $1}' /etc/passwd | grep -wE 'daemon|bin|sys|adm|listen|nobody|nobody4|noaccess|diag|operator|gopher|games|ftp|apache|httpd|www-data|mysql|mariadb|postgres|mail|postfix|news|lp|uucp|nuucp' | wc -l` -gt 0 ]; then 2197 | echo "※ U-49 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2198 | echo " 불필요한 계정이 존재합니다." >> $resultfile 2>&1 2199 | return 0 2200 | fi 2201 | fi 2202 | echo "※ U-49 결과 : 양호(Good)" >> $resultfile 2>&1 2203 | return 0 2204 | } 2205 | 2206 | U_50() { 2207 | echo "" >> $resultfile 2>&1 2208 | echo "▶ U-50(하) | 1. 계정관리 > 1.11 관리자 그룹에 최소한의 계정 포함 ◀" >> $resultfile 2>&1 2209 | echo " 양호 판단 기준 : 관리자 그룹에 불필요한 계정이 등록되어 있지 않은 경우" >> $resultfile 2>&1 2210 | echo " ### 불필요한 계정에 대한 변경 필요 시 U_50 함수 수정 필요" >> $resultfile 2>&1 2211 | echo " ### 불필요한 계정 = daemon, bin, sys, adm, listen, nobody, nobody4, noaccess, diag, operator, gopher, games, ftp, apache, httpd, www-data, mysql, mariadb, postgres, mail, postfix, news, lp, uucp, nuucp" >> $resultfile 2>&1 2212 | if [ -f /etc/group ]; then 2213 | # !!! 불필요한 계정에 대한 변경은 하단의 grep 명령어를 수정하세요. 2214 | if [ `awk -F : '$1=="root" {gsub(" ", "", $0); print $4}' /etc/group | awk '{gsub(",","\n",$0); print}' | grep -wE 'daemon|bin|sys|adm|listen|nobody|nobody4|noaccess|diag|operator|gopher|games|ftp|apache|httpd|www-data|mysql|mariadb|postgres|mail|postfix|news|lp|uucp|nuucp' | wc -l` -gt 0 ]; then 2215 | echo "※ U-50 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2216 | echo " 관리자 그룹(root)에 불필요한 계정이 등록되어 있습니다." >> $resultfile 2>&1 2217 | return 0 2218 | fi 2219 | fi 2220 | echo "※ U-50 결과 : 양호(Good)" >> $resultfile 2>&1 2221 | return 0 2222 | } 2223 | 2224 | U_51() { 2225 | echo "" >> $resultfile 2>&1 2226 | echo "▶ U-51(하) | 1. 계정관리 > 1.12 계정이 존재하지 않는 GID 금지 ◀" >> $resultfile 2>&1 2227 | echo " 양호 판단 기준 : 시스템 관리나 운용에 불필요한 그룹이 삭제 되어있는 경우" >> $resultfile 2>&1 2228 | echo " ### 불필요한 그룹 = 그룹에 계정이 존재하지 않는 그룹" >> $resultfile 2>&1 2229 | unnecessary_groups=(`grep -vE '^#|^\s#' /etc/group | awk -F : '$3>=500 && $4==null {print $3}' | uniq`) 2230 | for ((i=0; i<${#unnecessary_groups[@]}; i++)) 2231 | do 2232 | if [ `awk -F : '{print $4}' /etc/passwd | uniq | grep ${unnecessary_groups[$i]} | wc -l` -eq 0 ]; then 2233 | echo "※ U-51 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2234 | echo " 불필요한 그룹이 존재합니다." >> $resultfile 2>&1 2235 | return 0 2236 | fi 2237 | done 2238 | echo "※ U-51 결과 : 양호(Good)" >> $resultfile 2>&1 2239 | return 0 2240 | } 2241 | 2242 | U_52() { 2243 | echo "" >> $resultfile 2>&1 2244 | echo "▶ U-52(중) | 1. 계정관리 > 1.13 동일한 UID 금지 ◀" >> $resultfile 2>&1 2245 | echo " 양호 판단 기준 : 동일한 UID로 설정된 사용자 계정이 존재하지 않는 경우" >> $resultfile 2>&1 2246 | if [ -f /etc/passwd ]; then 2247 | if [ `awk -F : '{print $3}' /etc/passwd | sort | uniq -d | wc -l` -gt 0 ]; then 2248 | echo "※ U-52 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2249 | echo " 동일한 UID로 설정된 사용자 계정이 존재합니다." >> $resultfile 2>&1 2250 | return 0 2251 | fi 2252 | fi 2253 | echo "※ U-52 결과 : 양호(Good)" >> $resultfile 2>&1 2254 | return 0 2255 | } 2256 | 2257 | U_53() { 2258 | echo "" >> $resultfile 2>&1 2259 | echo "▶ U-53(하) | 1. 계정관리 > 1.14 사용자 shell 점검 ◀" >> $resultfile 2>&1 2260 | echo " 양호 판단 기준 : 로그인이 필요하지 않은 계정에 /bin/false(/sbin/nologin) 쉘이 부여되어 있는 경우" >> $resultfile 2>&1 2261 | echo " ### 불필요한 계정에 대한 변경 필요 시 U_53 함수 수정 필요" >> $resultfile 2>&1 2262 | echo " ### 불필요한 계정 = daemon, bin, sys, adm, listen, nobody, nobody4, noaccess, diag, operator, gopher, games, ftp, apache, httpd, www-data, mysql, mariadb, postgres, mail, postfix, news, lp, uucp, nuucp" >> $resultfile 2>&1 2263 | if [ -f /etc/passwd ]; then 2264 | # !!! 불필요한 계정에 대한 변경은 하단의 grep 명령어를 수정하세요. 2265 | if [ `grep -E '^(daemon|bin|sys|adm|listen|nobody|nobody4|noaccess|diag|operator|gopher|games|ftp|apache|httpd|www-data|mysql|mariadb|postgres|mail|postfix|news|lp|uucp|nuucp):' /etc/passwd | awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" {print}' | wc -l` -gt 0 ]; then 2266 | echo "※ U-53 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2267 | echo " 로그인이 필요하지 않은 불필요한 계정에 /bin/false 또는 /sbin/nologin 쉘이 부여되지 않았습니다." >> $resultfile 2>&1 2268 | return 0 2269 | fi 2270 | fi 2271 | echo "※ U-53 결과 : 양호(Good)" >> $resultfile 2>&1 2272 | return 0 2273 | } 2274 | 2275 | U_54() { 2276 | echo "" >> $resultfile 2>&1 2277 | echo "▶ U-54(하) | 1. 계정관리 > 1.15 Session Timeout 설정 ◀" >> $resultfile 2>&1 2278 | echo " 양호 판단 기준 : Session Timeout이 600초(10분) 이하로 설정되어 있는 경우" >> $resultfile 2>&1 2279 | file_exists_count=0 # 세션 타임아웃 설정 파일 존재 시 카운트할 변수 2280 | no_tmout_setting_file=0 # 설정 파일 존재하는데, 세션 타임아웃 설정이 없을 때 카운트할 변수 -> 추후 file_exists_count 변수와 값을 비교하여 동일하면 모든 파일에 세션 타임아웃 설정이 없는 것이므로 취약으로 판단함 2281 | # /etc/profile 파일 내 세션 타임아웃 설정 확인함 2282 | if [ -f /etc/profile ]; then 2283 | ((file_exists_count++)) 2284 | etc_profile_tmout_count=`grep -vE '^#|^\s#' /etc/profile | grep -i 'TMOUT' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 2285 | if [ $etc_profile_tmout_count -gt 0 ]; then 2286 | etc_profile_tmout_value=`grep -vE '^#|^\s#' /etc/profile | grep -i 'TMOUT' | awk -F = '{gsub(" ", "", $0); print $2}'` 2287 | if [ $etc_profile_tmout_value -gt 600 ]; then 2288 | echo "※ U-54 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2289 | echo " /etc/profile 파일에 세션 타임아웃이 600초 이하로 설정되지 않았습니다." >> $resultfile 2>&1 2290 | return 0 2291 | fi 2292 | else 2293 | ((no_tmout_setting_file++)) 2294 | fi 2295 | fi 2296 | # 사용자 홈 디렉터리 내 .profile 파일에서 세션 타임아웃 설정 확인함 2297 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd | uniq`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 2298 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 2299 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 2300 | do 2301 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 2302 | done 2303 | for ((i=0; i<${#user_homedirectory_path[@]}; i++)) 2304 | do 2305 | if [ -f ${user_homedirectory_path[$i]}/.profile ]; then 2306 | ((file_exists_count++)) 2307 | user_homedirectory_profile_tmout_count=`grep -vE '^#|^\s#' ${user_homedirectory_path[$i]}/.profile | grep -i 'TMOUT' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 2308 | if [ $user_homedirectory_profile_tmout_count -gt 0 ]; then 2309 | user_homedirectory_profile_tmout_value=`grep -vE '^#|^\s#' ${user_homedirectory_path[$i]}/.profile | grep -i 'TMOUT' | awk -F = '{gsub(" ", "", $0); print $2}'` 2310 | if [ $user_homedirectory_profile_tmout_value -gt 600 ]; then 2311 | echo "※ U-54 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2312 | echo " ${user_homedirectory_path[$i]}/.profile 파일에 세션 타임아웃이 600초 이하로 설정되지 않았습니다." >> $resultfile 2>&1 2313 | return 0 2314 | fi 2315 | else 2316 | ((no_tmout_setting_file++)) 2317 | fi 2318 | fi 2319 | done 2320 | # /etc/csh.login 파일 내 세션 타임아웃 설정 확인함 2321 | if [ -f /etc/csh.login ]; then 2322 | ((file_exists_count++)) 2323 | etc_cshlogin_tmout_count=`grep -vE '^#|^\s#' /etc/csh.login | grep -i 'set' | grep -i 'autologout' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 2324 | if [ $etc_cshlogin_tmout_count -gt 0 ]; then 2325 | etc_cshlogin_tmout_value=`grep -vE '^#|^\s#' /etc/csh.login | grep -i 'set' | grep -i 'autologout' | awk -F = '{gsub(" ", "", $0); print $2}'` 2326 | if [ $etc_cshlogin_tmout_value -gt 10 ]; then 2327 | echo "※ U-54 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2328 | echo " /etc/csh.login 파일에 세션 타임아웃이 10분 이하로 설정되지 않았습니다." >> $resultfile 2>&1 2329 | return 0 2330 | fi 2331 | else 2332 | ((no_tmout_setting_file++)) 2333 | fi 2334 | fi 2335 | # /etc/csh.cshrc 파일 내 세션 타임아웃 설정 확인함 2336 | if [ -f /etc/csh.cshrc ]; then 2337 | ((file_exists_count++)) 2338 | etc_cshrc_tmout_count=`grep -vE '^#|^\s#' /etc/csh.cshrc | grep -i 'set' | grep -i 'autologout' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 2339 | if [ $etc_cshrc_tmout_count -gt 10 ]; then 2340 | etc_cshrc_tmout_value=`grep -vE '^#|^\s#' /etc/csh.cshrc | grep -i 'set' | grep -i 'autologout' | awk -F = '{gsub(" ", "", $0); print $2}'` 2341 | if [ $etc_cshrc_tmout_value -gt 10 ]; then 2342 | echo "※ U-54 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2343 | echo " /etc/csh.cshrc 파일에 세션 타임아웃이 10분 이하로 설정되지 않았습니다." >> $resultfile 2>&1 2344 | return 0 2345 | fi 2346 | else 2347 | ((no_tmout_setting_file++)) 2348 | fi 2349 | fi 2350 | if [ $file_exists_count -eq 0 ]; then 2351 | echo "※ U-54 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2352 | echo " 세션 타임아웃을 설정하는 파일이 없습니다." >> $resultfile 2>&1 2353 | return 0 2354 | elif [ $file_exists_count -eq $no_tmout_setting_file ]; then 2355 | echo "※ U-54 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2356 | echo " 세션 타임아웃을 설정한 파일이 없습니다." >> $resultfile 2>&1 2357 | return 0 2358 | else 2359 | echo "※ U-54 결과 : 양호(Good)" >> $resultfile 2>&1 2360 | return 0 2361 | fi 2362 | } 2363 | 2364 | U_55() { 2365 | echo "" >> $resultfile 2>&1 2366 | echo "▶ U-55(하) | 2. 파일 및 디렉토리 관리 > 2.15 hosts.lpd 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 2367 | echo " 양호 판단 기준 : hosts.lpd 파일이 삭제되어 있거나 불가피하게 hosts.lpd 파일을 사용할 시 파일의 소유자가 root이고 권한이 600인 경우" >> $resultfile 2>&1 2368 | if [ -f /etc/hosts.lpd ]; then 2369 | etc_hostslpd_owner_name=`ls -l /etc/hosts.lpd | awk '{print $3}'` 2370 | if [[ $etc_hostslpd_owner_name =~ root ]]; then 2371 | etc_hostslpd_permission=`stat /etc/hosts.lpd | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 2372 | if [ $etc_hostslpd_permission -eq 600 ]; then 2373 | echo "※ U-55 결과 : 양호(Good)" >> $resultfile 2>&1 2374 | return 0 2375 | else 2376 | echo "※ U-55 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2377 | echo " /etc/hosts.lpd 파일의 권한이 600이 아닙니다." >> $resultfile 2>&1 2378 | return 0 2379 | fi 2380 | else 2381 | echo "※ U-55 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2382 | echo " /etc/hosts.lpd 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 2383 | return 0 2384 | fi 2385 | else 2386 | echo "※ U-55 결과 : 양호(Good)" >> $resultfile 2>&1 2387 | return 0 2388 | fi 2389 | } 2390 | 2391 | U_56() { 2392 | echo "" >> $resultfile 2>&1 2393 | echo "▶ U-56(중) | 2. 파일 및 디렉토리 관리 > 2.17 UMASK 설정 관리 ◀" >> $resultfile 2>&1 2394 | echo " 양호 판단 기준 : UMASK 값이 022 이상으로 설정된 경우" >> $resultfile 2>&1 2395 | umaks_value=`umask` 2396 | if [ ${umaks_value:2:1} -lt 2 ]; then 2397 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2398 | echo " 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2399 | return 0 2400 | elif [ ${umaks_value:3:1} -lt 2 ]; then 2401 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2402 | echo " 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2403 | return 0 2404 | fi 2405 | # /etc/profile 파일 내 umask 설정 확인함 2406 | etc_profile_umask_count=`grep -vE '^#|^\s#' /etc/profile | grep -i 'umask' | grep -vE 'if|\`' | grep '=' | wc -l` # 설정 파일에 형식으로 umask 값이 설정된 경우 2407 | etc_profile_umask_count2=`grep -vE '^#|^\s#' /etc/profile | grep -i 'umask' | grep -vE 'if|\`' | awk '{print $2}' | wc -l` # 설정 파일에 형식으로 umask 값이 설정된 경우 2408 | if [ -f /etc/profile ]; then 2409 | if [ $etc_profile_umask_count -gt 0 ]; then 2410 | umaks_value=(`grep -vE '^#|^\s#' /etc/profile | grep -i 'umask' | grep -vE 'if|\`' | awk -F = '{gsub(" ", "", $0); print $2}'`) 2411 | for ((i=0; i<${#umaks_value[@]}; i++)) 2412 | do 2413 | if [ ${#umaks_value[$i]} -eq 2 ]; then 2414 | if [ ${umaks_value[$i]:0:1} -lt 2 ]; then 2415 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2416 | echo " /etc/profile 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2417 | return 0 2418 | elif [ ${umaks_value[$i]:1:1} -lt 2 ]; then 2419 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2420 | echo " /etc/profile 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2421 | return 0 2422 | fi 2423 | elif [ ${#umaks_value[$i]} -eq 4 ]; then 2424 | if [ ${umaks_value[$i]:2:1} -lt 2 ]; then 2425 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2426 | echo " /etc/profile 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2427 | return 0 2428 | elif [ ${umaks_value[$i]:3:1} -lt 2 ]; then 2429 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2430 | echo " /etc/profile 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2431 | return 0 2432 | fi 2433 | elif [ ${#umaks_value[$i]} -eq 3 ]; then 2434 | if [ ${umaks_value[$i]:1:1} -lt 2 ]; then 2435 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2436 | echo " /etc/profile 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2437 | return 0 2438 | elif [ ${umaks_value[$i]:2:1} -lt 2 ]; then 2439 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2440 | echo " /etc/profile 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2441 | return 0 2442 | fi 2443 | elif [ ${#umaks_value[$i]} -eq 1 ]; then 2444 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2445 | echo " /etc/profile 파일에 umask 값이 0022 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2446 | return 0 2447 | else 2448 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2449 | echo " /etc/profile 파일에 설정된 umask 값이 보안 설정에 부합하지 않습니다." >> $resultfile 2>&1 2450 | return 0 2451 | fi 2452 | done 2453 | elif [ $etc_profile_umask_count2 -gt 0 ]; then 2454 | umaks_value=(`grep -vE '^#|^\s#' /etc/profile | grep -i 'umask' | grep -vE 'if|\`' | awk '{print $2}'`) 2455 | for ((i=0; i<${#umaks_value[@]}; i++)) 2456 | do 2457 | if [ ${#umaks_value[$i]} -eq 2 ]; then 2458 | if [ ${umaks_value[$i]:0:1} -lt 2 ]; then 2459 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2460 | echo " /etc/profile 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2461 | return 0 2462 | elif [ ${umaks_value[$i]:1:1} -lt 2 ]; then 2463 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2464 | echo " /etc/profile 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2465 | return 0 2466 | fi 2467 | elif [ ${#umaks_value[$i]} -eq 4 ]; then 2468 | if [ ${umaks_value[$i]:2:1} -lt 2 ]; then 2469 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2470 | echo " /etc/profile 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2471 | return 0 2472 | elif [ ${umaks_value[$i]:3:1} -lt 2 ]; then 2473 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2474 | echo " /etc/profile 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2475 | return 0 2476 | fi 2477 | elif [ ${#umaks_value[$i]} -eq 3 ]; then 2478 | if [ ${umaks_value[$i]:1:1} -lt 2 ]; then 2479 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2480 | echo " /etc/profile 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2481 | return 0 2482 | elif [ ${umaks_value[$i]:2:1} -lt 2 ]; then 2483 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2484 | echo " /etc/profile 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2485 | return 0 2486 | fi 2487 | elif [ ${#umaks_value[$i]} -eq 1 ]; then 2488 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2489 | echo " /etc/profile 파일에 umask 값이 0022 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2490 | return 0 2491 | else 2492 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2493 | echo " /etc/profile 파일에 설정된 umask 값이 보안 설정에 부합하지 않습니다." >> $resultfile 2>&1 2494 | return 0 2495 | fi 2496 | done 2497 | fi 2498 | fi 2499 | # /etc/bashrc, /etc/csh.login, /etc/csh.cshrc 파일 내 umask 설정 확인함 2500 | umask_settings_files=("/etc/bashrc" "/etc/csh.login" "/etc/csh.cshrc") 2501 | for ((i=0; i<${#umask_settings_files[@]}; i++)) 2502 | do 2503 | if [ -f ${umask_settings_files[$i]} ]; then 2504 | file_umask_count=`grep -vE '^#|^\s#' ${umask_settings_files[$i]} | grep -i 'umask' | grep -vE 'if|\`' | awk '{print $2}' | wc -l` 2505 | if [ $file_umask_count -gt 0 ]; then 2506 | umaks_value=(`grep -vE '^#|^\s#' ${umask_settings_files[$i]} | grep -i 'umask' | grep -vE 'if|\`' | awk '{print $2}'`) 2507 | for ((j=0; j<${#umaks_value[@]}; j++)) 2508 | do 2509 | if [ ${#umaks_value[$j]} -eq 2 ]; then 2510 | if [ ${umaks_value[$j]:0:1} -lt 2 ]; then 2511 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2512 | echo " ${umask_settings_files[$i]} 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2513 | return 0 2514 | elif [ ${umaks_value[$j]:1:1} -lt 2 ]; then 2515 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2516 | echo " ${umask_settings_files[$i]} 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2517 | return 0 2518 | fi 2519 | elif [ ${#umaks_value[$j]} -eq 4 ]; then 2520 | if [ ${umaks_value[$j]:2:1} -lt 2 ]; then 2521 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2522 | echo " ${umask_settings_files[$i]} 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2523 | return 0 2524 | elif [ ${umaks_value[$j]:3:1} -lt 2 ]; then 2525 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2526 | echo " ${umask_settings_files[$i]} 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2527 | return 0 2528 | fi 2529 | elif [ ${#umaks_value[$j]} -eq 3 ]; then 2530 | if [ ${umaks_value[$j]:1:1} -lt 2 ]; then 2531 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2532 | echo " ${umask_settings_files[$i]} 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2533 | return 0 2534 | elif [ ${umaks_value[$j]:2:1} -lt 2 ]; then 2535 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2536 | echo " ${umask_settings_files[$i]} 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2537 | return 0 2538 | fi 2539 | elif [ ${#umaks_value[$j]} -eq 1 ]; then 2540 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2541 | echo " ${umask_settings_files[$i]} 파일에 umask 값이 0022 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2542 | return 0 2543 | else 2544 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2545 | echo " ${umask_settings_files[$i]} 파일에 설정된 umask 값이 보안 설정에 부합하지 않습니다." >> $resultfile 2>&1 2546 | return 0 2547 | fi 2548 | done 2549 | fi 2550 | fi 2551 | done 2552 | # 사용자 홈 디렉터리 내 설정 파일에서 umask 설정 확인함 2553 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd | uniq`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 2554 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 2555 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 2556 | do 2557 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 2558 | done 2559 | umask_settings_files=(".cshrc" ".profile" ".login" ".bashrc" ".kshrc") 2560 | for ((i=0; i<${#user_homedirectory_path[@]}; i++)) 2561 | do 2562 | for ((j=0; j<${#umask_settings_files[@]}; j++)) 2563 | do 2564 | if [ -f ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} ]; then 2565 | user_homedirectory_setting_umask_count=`grep -vE '^#|^\s#' ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} | grep -i 'umask' | grep -vE 'if|\`' | awk '{print $2}' | wc -l` 2566 | if [ $user_homedirectory_setting_umask_count -gt 0 ]; then 2567 | umaks_value=(`grep -vE '^#|^\s#' ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} | grep -i 'umask' | grep -vE 'if|\`' | awk '{print $2}'`) 2568 | for ((k=0; k<${#umaks_value[@]}; k++)) 2569 | do 2570 | if [ ${#umaks_value[$k]} -eq 2 ]; then 2571 | if [ ${umaks_value[$k]:0:1} -lt 2 ]; then 2572 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2573 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2574 | return 0 2575 | elif [ ${umaks_value[$k]:1:1} -lt 2 ]; then 2576 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2577 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2578 | return 0 2579 | fi 2580 | elif [ ${#umaks_value[$k]} -eq 4 ]; then 2581 | if [ ${umaks_value[$k]:2:1} -lt 2 ]; then 2582 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2583 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2584 | return 0 2585 | elif [ ${umaks_value[$k]:3:1} -lt 2 ]; then 2586 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2587 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2588 | return 0 2589 | fi 2590 | elif [ ${#umaks_value[$k]} -eq 3 ]; then 2591 | if [ ${umaks_value[$k]:1:1} -lt 2 ]; then 2592 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2593 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 그룹 사용자(group)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2594 | return 0 2595 | elif [ ${umaks_value[$k]:2:1} -lt 2 ]; then 2596 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2597 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 다른 사용자(other)에 대한 umask 값이 2 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2598 | return 0 2599 | fi 2600 | elif [ ${#umaks_value[$k]} -eq 1 ]; then 2601 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2602 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 umask 값이 0022 이상으로 설정되지 않았습니다." >> $resultfile 2>&1 2603 | return 0 2604 | else 2605 | echo "※ U-56 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2606 | echo " ${user_homedirectory_path[$i]}/${umask_settings_files[$j]} 파일에 설정된 umask 값이 보안 설정에 부합하지 않습니다." >> $resultfile 2>&1 2607 | return 0 2608 | fi 2609 | done 2610 | fi 2611 | fi 2612 | done 2613 | done 2614 | echo "※ U-56 결과 : 양호(Good)" >> $resultfile 2>&1 2615 | return 0 2616 | } 2617 | 2618 | U_57() { 2619 | echo "" >> $resultfile 2>&1 2620 | echo "▶ U-57(중) | 2. 파일 및 디렉토리 관리 > 2.18 홈디렉토리 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 2621 | echo " 양호 판단 기준 : 홈 디렉터리 소유자가 해당 계정이고, 타 사용자 쓰기 권한이 제거된 경우" >> $resultfile 2>&1 2622 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 2623 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 2624 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 2625 | do 2626 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 2627 | done 2628 | user_homedirectory_owner_name=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $1}' /etc/passwd`) # /etc/passwd 파일에 설정된 사용자명 배열 생성 2629 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 2630 | do 2631 | user_homedirectory_owner_name[${#user_homedirectory_owner_name[@]}]=`echo ${user_homedirectory_path2[$i]} | awk -F / '{print $3}'` # user_homedirectory_path2 배열에서 사용자명만 따로 출력하여 배열에 저장함 2632 | done 2633 | for ((i=0; i<${#user_homedirectory_path[@]}; i++)) 2634 | do 2635 | if [ -d ${user_homedirectory_path[$i]} ]; then 2636 | homedirectory_owner_name=`ls -ld ${user_homedirectory_path[$i]} | awk '{print $3}'` 2637 | if [[ $homedirectory_owner_name =~ ${user_homedirectory_owner_name[$i]} ]]; then 2638 | homedirectory_other_permission=`stat ${user_homedirectory_path[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 2639 | if [ $homedirectory_other_permission -eq 7 ] || [ $homedirectory_other_permission -eq 6 ] || [ $homedirectory_other_permission -eq 3 ] || [ $homedirectory_other_permission -eq 2 ]; then 2640 | echo "※ U-57 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2641 | echo " ${user_homedirectory_path[$i]} 홈 디렉터리에 다른 사용자(other)의 쓰기 권한이 부여되어 있습니다." >> $resultfile 2>&1 2642 | return 0 2643 | fi 2644 | else 2645 | echo "※ U-57 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2646 | echo " ${user_homedirectory_path[$i]} 홈 디렉터리의 소유자가 ${user_homedirectory_owner_name[$i]}이(가) 아닙니다." >> $resultfile 2>&1 2647 | return 0 2648 | fi 2649 | fi 2650 | done 2651 | echo "※ U-57 결과 : 양호(Good)" >> $resultfile 2>&1 2652 | return 0 2653 | } 2654 | 2655 | U_58() { 2656 | echo "" >> $resultfile 2>&1 2657 | echo "▶ U-58(중) | 2. 파일 및 디렉토리 관리 > 2.19 홈디렉토리로 지정한 디렉토리의 존재 관리 ◀" >> $resultfile 2>&1 2658 | echo " 양호 판단 기준 : 홈 디렉터리가 존재하지 않는 계정이 발견되지 않는 경우" >> $resultfile 2>&1 2659 | homedirectory_null_count=`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6==null' /etc/passwd | wc -l` 2660 | if [ $homedirectory_null_count -gt 0 ]; then 2661 | echo "※ U-58 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2662 | echo " 홈 디렉터리가 존재하지 않는 계정이 있습니다." >> $resultfile 2>&1 2663 | return 0 2664 | else 2665 | homedirectory_slash_count=`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $1!="root" && $6=="/"' /etc/passwd | wc -l` 2666 | if [ $homedirectory_slash_count -gt 0 ]; then 2667 | echo "※ U-58 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2668 | echo " 관리자 계정(root)이 아닌데 홈 디렉터리가 '/'로 설정된 계정이 있습니다." >> $resultfile 2>&1 2669 | return 0 2670 | else 2671 | echo "※ U-58 결과 : 양호(Good)" >> $resultfile 2>&1 2672 | return 0 2673 | fi 2674 | fi 2675 | } 2676 | 2677 | U_59() { 2678 | echo "" >> $resultfile 2>&1 2679 | echo "▶ U-59(하) | 2. 파일 및 디렉토리 관리 > 2.20 숨겨진 파일 및 디렉토리 검색 및 제거 ◀" >> $resultfile 2>&1 2680 | echo " 양호 판단 기준 : 불필요하거나 의심스러운 숨겨진 파일 및 디렉터리를 삭제한 경우" >> $resultfile 2>&1 2681 | if [ `find / -name '.*' -type f 2>/dev/null | wc -l` -gt 0 ]; then 2682 | echo "※ U-59 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2683 | echo " 숨겨진 파일이 있습니다." >> $resultfile 2>&1 2684 | return 0 2685 | elif [ `find / -name '.*' -type d 2>/dev/null | wc -l` -gt 0 ]; then 2686 | echo "※ U-59 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2687 | echo " 숨겨진 디렉터리가 있습니다." >> $resultfile 2>&1 2688 | return 0 2689 | else 2690 | echo "※ U-59 결과 : 양호(Good)" >> $resultfile 2>&1$resultfile 2>&1 2691 | return 0 2692 | fi 2693 | } 2694 | 2695 | U_60() { 2696 | echo "" >> $resultfile 2>&1 2697 | echo "▶ U-60(중) | 3. 서비스 관리 > 3.24 ssh 원격접속 허용 ◀" >> $resultfile 2>&1 2698 | echo " 양호 판단 기준 : 원격 접속 시 SSH 프로토콜을 사용하는 경우" >> $resultfile 2>&1 2699 | echo " ### ssh, telnet이 동시에 설치되어 있는 경우 취약한 것으로 평가됨" >> $resultfile 2>&1 2700 | if [ -f /etc/services ]; then 2701 | telent_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="telnet" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 2702 | if [ $telent_port_count -gt 0 ]; then 2703 | telent_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="telnet" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 2704 | for ((i=0; i<${#telent_port[@]}; i++)) 2705 | do 2706 | netstat_telnet_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${telent_port[$i]} " | wc -l` 2707 | if [ $netstat_telnet_count -gt 0 ]; then 2708 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2709 | echo " Telnet 서비스가 실행 중입니다." >> $resultfile 2>&1 2710 | return 0 2711 | fi 2712 | done 2713 | fi 2714 | ftp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 2715 | if [ $ftp_port_count -gt 0 ]; then 2716 | ftp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 2717 | for ((i=0; i<${#ftp_port[@]}; i++)) 2718 | do 2719 | netstat_ftp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ftp_port[$i]} " | wc -l` 2720 | if [ $netstat_ftp_count -gt 0 ]; then 2721 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2722 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2723 | return 0 2724 | fi 2725 | done 2726 | fi 2727 | fi 2728 | find_vsftpdconf_count=`find / -name 'vsftpd.conf' -type f 2>/dev/null | wc -l` 2729 | if [ $find_vsftpdconf_count -gt 0 ]; then 2730 | vsftpdconf_files=(`find / -name 'vsftpd.conf' -type f 2>/dev/null`) 2731 | for ((i=0; i<${#vsftpdconf_files[@]}; i++)) 2732 | do 2733 | if [ -f ${vsftpdconf_files[$i]} ]; then 2734 | vsftpdconf_file_port_count=`grep -vE '^#|^\s#' ${vsftpdconf_files[$i]} | grep 'listen_port' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 2735 | if [ $vsftpdconf_file_port_count -gt 0 ]; then 2736 | telent_port=(`grep -vE '^#|^\s#' ${vsftpdconf_files[$i]} | grep 'listen_port' | awk -F = '{gsub(" ", "", $0); print $2}'`) 2737 | for ((j=0; j<${#telent_port[@]}; j++)) 2738 | do 2739 | if [ `netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${telent_port[$j]} " | wc -l` -gt 0 ]; then 2740 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2741 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2742 | return 0 2743 | fi 2744 | done 2745 | fi 2746 | fi 2747 | done 2748 | fi 2749 | find_proftpdconf_count=`find / -name 'proftpd.conf' -type f 2>/dev/null | wc -l` 2750 | if [ $find_proftpdconf_count -gt 0 ]; then 2751 | proftpdconf_files=(`find / -name 'proftpd.conf' -type f 2>/dev/null`) 2752 | for ((i=0; i<${#proftpdconf_files[@]}; i++)) 2753 | do 2754 | if [ -f ${proftpdconf_files[$i]} ]; then 2755 | if [ `grep -vE '^#|^\s#' ${proftpdconf_files[$i]} | grep 'Port' | awk '{print $2}' | wc -l` -gt 0 ]; then 2756 | telent_port=(`grep -vE '^#|^\s#' ${proftpdconf_files[$i]} | grep 'Port' | awk '{print $2}'`) 2757 | for ((j=0; j<${#telent_port[@]}; j++)) 2758 | do 2759 | if [ `netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${telent_port[$j]} " | wc -l` -gt 0 ]; then 2760 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2761 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2762 | return 0 2763 | fi 2764 | done 2765 | fi 2766 | fi 2767 | done 2768 | fi 2769 | ps_telnet_count=`ps -ef | grep -i 'telnet' | grep -v 'grep' | wc -l` 2770 | if [ $ps_telnet_count -gt 0 ]; then 2771 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2772 | echo " Telnet 서비스가 실행 중입니다." >> $resultfile 2>&1 2773 | return 0 2774 | fi 2775 | ps_ftp_count=`ps -ef | grep -i 'ftp' | grep -v 'grep' | wc -l` 2776 | if [ $ps_ftp_count -gt 0 ]; then 2777 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2778 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2779 | return 0 2780 | fi 2781 | find_sshdconfig_count=`find / -name 'sshd_config' -type f 2>/dev/null | wc -l` 2782 | if [ $find_sshdconfig_count -gt 0 ]; then 2783 | sshdconfig_files=(`find / -name 'sshd_config' -type f 2>/dev/null`) 2784 | for ((i=0; i<${#sshdconfig_files[@]}; i++)) 2785 | do 2786 | if [ -f ${sshdconfig_files[$i]} ]; then 2787 | if [ `grep -vE '^#|^\s#' ${sshdconfig_files[$i]} | grep -i 'Port' | awk '{print $2}' | wc -l` -gt 0 ]; then 2788 | ssh_port=(`grep -vE '^#|^\s#' ${sshdconfig_files[$i]} | grep -i 'Port' | awk '{print $2}'`) 2789 | for ((j=0; j<${#ssh_port[@]}; j++)) 2790 | do 2791 | netstat_ssh_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ssh_port[$j]} " | wc -l` 2792 | if [ $netstat_ssh_count -eq 0 ]; then 2793 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2794 | echo " SSH 서비스가 비활성화 상태입니다." >> $resultfile 2>&1 2795 | return 0 2796 | fi 2797 | done 2798 | fi 2799 | fi 2800 | done 2801 | fi 2802 | ps_ssh_count=`ps -ef | grep -i 'sshd' | grep -v 'grep' | wc -l` 2803 | if [ $ps_ssh_count -eq 0 ]; then 2804 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2805 | echo " SSH 서비스가 비활성화 상태입니다." >> $resultfile 2>&1 2806 | return 0 2807 | fi 2808 | rpm_ssh_count=`rpm -qa 2>/dev/null | grep '^openssh' | wc -l` 2809 | yum_ssh_count=`yum list installed | grep '^openssh' | wc -l` 2810 | rpm_telnet_count=`rpm -qa 2>/dev/null | grep '^telnet' | wc -l` 2811 | yum_telnet_count=`yum list installed | grep '^telnet' | wc -l` 2812 | if [ $rpm_ssh_count -gt 0 ] && [ $yum_ssh_count -gt 0 ] && [ $rpm_telnet_count -gt 0 ] && [ $yum_telnet_count -gt 0 ]; then 2813 | echo "※ U-60 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2814 | echo " SSH 서비스와 Telnet 서비스가 동시에 설치되어 있습니다." >> $resultfile 2>&1 2815 | return 0 2816 | else 2817 | echo "※ U-60 결과 : 양호(Good)" >> $resultfile 2>&1 2818 | return 0 2819 | fi 2820 | } 2821 | 2822 | U_61() { 2823 | echo "" >> $resultfile 2>&1 2824 | echo "▶ U-61(하) | 3. 서비스 관리 > 3.25 ftp 서비스 확인 ◀" >> $resultfile 2>&1 2825 | echo " 양호 판단 기준 : FTP 서비스가 비활성화 되어 있는 경우" >> $resultfile 2>&1 2826 | if [ -f /etc/services ]; then 2827 | ftp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 2828 | if [ $ftp_port_count -gt 0 ]; then 2829 | ftp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 2830 | for ((i=0; i<${#ftp_port[@]}; i++)) 2831 | do 2832 | netstat_ftp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ftp_port[$i]} " | wc -l` 2833 | if [ $netstat_ftp_count -gt 0 ]; then 2834 | echo "※ U-61 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2835 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2836 | return 0 2837 | fi 2838 | done 2839 | fi 2840 | fi 2841 | find_vsftpdconf_count=`find / -name 'vsftpd.conf' -type f 2>/dev/null | wc -l` 2842 | if [ $find_vsftpdconf_count -gt 0 ]; then 2843 | vsftpdconf_files=(`find / -name 'vsftpd.conf' -type f 2>/dev/null`) 2844 | for ((i=0; i<${#vsftpdconf_files[@]}; i++)) 2845 | do 2846 | if [ -f ${vsftpdconf_files[$i]} ]; then 2847 | vsftpdconf_file_port_count=`grep -vE '^#|^\s#' ${vsftpdconf_files[$i]} | grep 'listen_port' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 2848 | if [ $vsftpdconf_file_port_count -gt 0 ]; then 2849 | ftp_port=(`grep -vE '^#|^\s#' ${vsftpdconf_files[$i]} | grep 'listen_port' | awk -F = '{gsub(" ", "", $0); print $2}'`) 2850 | for ((j=0; j<${#ftp_port[@]}; j++)) 2851 | do 2852 | netstat_ftp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ftp_port[$j]} " | wc -l` 2853 | if [ $netstat_ftp_count -gt 0 ]; then 2854 | echo "※ U-61 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2855 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2856 | return 0 2857 | fi 2858 | done 2859 | fi 2860 | fi 2861 | done 2862 | fi 2863 | find_proftpdconf_count=`find / -name 'proftpd.conf' -type f 2>/dev/null | wc -l` 2864 | if [ $find_proftpdconf_count -gt 0 ]; then 2865 | proftpdconf_files=(`find / -name 'proftpd.conf' -type f 2>/dev/null`) 2866 | for ((i=0; i<${#proftpdconf_files[@]}; i++)) 2867 | do 2868 | if [ -f ${proftpdconf_files[$i]} ]; then 2869 | proftpdconf_file_port_count=`grep -vE '^#|^\s#' ${proftpdconf_files[$i]} | grep 'Port' | awk '{print $2}' | wc -l` 2870 | if [ $proftpdconf_file_port_count -gt 0 ]; then 2871 | ftp_port=(`grep -vE '^#|^\s#' ${proftpdconf_files[$i]} | grep 'Port' | awk '{print $2}'`) 2872 | for ((j=0; j<${#ftp_port[@]}; j++)) 2873 | do 2874 | netstat_ftp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ftp_port[$j]} " | wc -l` 2875 | if [ $netstat_ftp_count -gt 0 ]; then 2876 | echo "※ U-61 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2877 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2878 | return 0 2879 | fi 2880 | done 2881 | fi 2882 | fi 2883 | done 2884 | fi 2885 | ps_ftp_count=`ps -ef | grep -iE 'ftp|vsftpd|proftp' | grep -v 'grep' | wc -l` 2886 | if [ $ps_ftp_count -gt 0 ]; then 2887 | echo "※ U-61 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2888 | echo " ftp 서비스가 실행 중입니다." >> $resultfile 2>&1 2889 | return 0 2890 | else 2891 | echo "※ U-61 결과 : 양호(Good)" >> $resultfile 2>&1 2892 | return 0 2893 | fi 2894 | } 2895 | 2896 | U_62() { 2897 | echo "" >> $resultfile 2>&1 2898 | echo "▶ U-62(중) | 3. 서비스 관리 > 3.26 ftp 계정 shell 제한 ◀" >> $resultfile 2>&1 2899 | echo " 양호 판단 기준 : ftp 계정에 /bin/false 쉘이 부여되어 있는 경우" >> $resultfile 2>&1 2900 | if [ `awk -F : '$1=="ftp" && $7=="/bin/false"' /etc/passwd | wc -l` -gt 0 ]; then 2901 | echo "※ U-62 결과 : 양호(Good)" >> $resultfile 2>&1 2902 | return 0 2903 | else 2904 | echo "※ U-62 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2905 | echo " ftp 계정에 /bin/false 쉘이 부여되어 있지 않습니다." >> $resultfile 2>&1 2906 | return 0 2907 | fi 2908 | } 2909 | 2910 | U_63() { 2911 | echo "" >> $resultfile 2>&1 2912 | echo "▶ U-63(하) | 3. 서비스 관리 > 3.27 ftpusers 파일 소유자 및 권한 설정 ◀" >> $resultfile 2>&1 2913 | echo " 양호 판단 기준 : ftpusers 파일의 소유자가 root이고, 권한이 640 이하인 경우" >> $resultfile 2>&1 2914 | file_exists_count=0 2915 | ftpusers_files=("/etc/ftpusers" "/etc/pure-ftpd/ftpusers" "/etc/wu-ftpd/ftpusers" "/etc/vsftpd/ftpusers" "/etc/proftpd/ftpusers" "/etc/ftpd/ftpusers" "/etc/vsftpd.ftpusers" "/etc/vsftpd.user_list" "/etc/vsftpd/user_list") 2916 | for ((i=0; i<${#ftpusers_files[@]}; i++)) 2917 | do 2918 | if [ -f ${ftpusers_files[$i]} ]; then 2919 | ((file_exists_count++)) 2920 | ftpusers_file_owner_name=`ls -l ${ftpusers_files[$i]} | awk '{print $3}'` 2921 | if [[ $ftpusers_file_owner_name =~ root ]]; then 2922 | ftpusers_file_permission=`stat ${ftpusers_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 2923 | if [ $ftpusers_file_permission -le 640 ]; then 2924 | ftpusers_file_owner_permission=`stat ${ftpusers_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 2925 | if [ $ftpusers_file_owner_permission -eq 6 ] || [ $ftpusers_file_owner_permission -eq 4 ] || [ $ftpusers_file_owner_permission -eq 2 ] || [ $ftpusers_file_owner_permission -eq 0 ]; then 2926 | ftpusers_file_group_permission=`stat ${ftpusers_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 2927 | if [ $ftpusers_file_group_permission -eq 4 ] || [ $ftpusers_file_group_permission -eq 0 ]; then 2928 | ftpusers_file_other_permission=`stat ${ftpusers_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 2929 | if [ $ftpusers_file_other_permission -ne 0 ]; then 2930 | echo "※ U-63 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2931 | echo " ${ftpusers_files[$i]} 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 2932 | return 0 2933 | fi 2934 | else 2935 | echo "※ U-63 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2936 | echo " ${ftpusers_files[$i]} 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 2937 | return 0 2938 | fi 2939 | else 2940 | echo "※ U-63 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2941 | echo " ${ftpusers_files[$i]} 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 2942 | return 0 2943 | fi 2944 | else 2945 | echo "※ U-63 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2946 | echo " ${ftpusers_files[$i]} 파일의 권한이 640보다 큽니다." >> $resultfile 2>&1 2947 | return 0 2948 | fi 2949 | else 2950 | echo "※ U-63 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2951 | echo " ${ftpusers_files[$i]} 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 2952 | return 0 2953 | fi 2954 | fi 2955 | done 2956 | if [ $file_exists_count -eq 0 ]; then 2957 | echo "※ U-63 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2958 | echo " ftp 접근제어 파일이 없습니다." >> $resultfile 2>&1 2959 | return 0 2960 | else 2961 | echo "※ U-63 결과 : 양호(Good)" >> $resultfile 2>&1 2962 | return 0 2963 | fi 2964 | } 2965 | 2966 | U_64() { 2967 | echo "" >> $resultfile 2>&1 2968 | echo "▶ U-64(중) | 3. 서비스 관리 > 3.28 ftpusers 파일 설정(FTP 서비스 root 계정 접근제한) ◀" >> $resultfile 2>&1 2969 | echo " 양호 판단 기준 : FTP 서비스가 비활성화 되어 있거나, 활성화 시 root 계정 접속을 차단한 경우" >> $resultfile 2>&1 2970 | ftpusers_files=("/etc/ftpusers" "/etc/ftpd/ftpusers" "/etc/proftpd.conf" "/etc/vsftp/ftpusers" "/etc/vsftp/user_list" "/etc/vsftpd.ftpusers" "/etc/vsftpd.user_list") 2971 | ftp_running_count=0 # ftp 서비스 실행 중일 때 카운트 2972 | ftpusers_file_exists_count=0 # ftpusers 파일 존재 시 카운트 2973 | if [ -f /etc/services ]; then 2974 | ftp_port_count=`grep -vE '^#|^\s#' /etc/services | awk -F " " 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 2975 | if [ $ftp_port_count -gt 0 ]; then 2976 | ftp_port=(`grep -vE '^#|^\s#' /etc/services | awk -F " " 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 2977 | for ((i=0; i<${#ftp_port[@]}; i++)) 2978 | do 2979 | netstat_ftp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ftp_port[$i]} " | wc -l` 2980 | if [ $netstat_ftp_count -gt 0 ]; then 2981 | ((ftp_running_count++)) 2982 | for ((j=0; j<${#ftpusers_files[@]}; j++)) 2983 | do 2984 | if [ -f ${ftpusers_files[$j]} ]; then 2985 | ((ftpusers_file_exists_count++)) 2986 | if [[ ${ftpusers_files[$j]} =~ /etc/proftpd.conf ]]; then 2987 | etc_proftpdconf_rootlogin_on_count=`grep -vE '^#|^\s#' ${ftpusers_files[$j]} | grep -i 'RootLogin' | grep -i 'on' | wc -l` 2988 | if [ $etc_proftpdconf_rootlogin_on_count -gt 0 ]; then 2989 | echo "※ U-64 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2990 | echo " ${ftpusers_files[$j]} 파일에 'RootLogin on' 설정이 있습니다." >> $resultfile 2>&1 2991 | return 0 2992 | fi 2993 | else 2994 | ftp_root_count=`grep -vE '^#|^\s#' ${ftpusers_files[$j]} | grep -w 'root' | wc -l` 2995 | if [ $ftp_root_count -eq 0 ]; then 2996 | echo "※ U-64 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 2997 | echo " ${ftpusers_files[$j]} 파일에 'root' 계정이 없습니다." >> $resultfile 2>&1 2998 | return 0 2999 | fi 3000 | fi 3001 | fi 3002 | done 3003 | fi 3004 | done 3005 | fi 3006 | fi 3007 | if [ $ftp_running_count -gt 0 ] && [ $ftpusers_file_exists_count -eq 0 ]; then 3008 | echo "※ U-64 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3009 | echo " ftp 서비스를 사용하고, 'root' 계정의 접근을 제한할 파일이 없습니다." >> $resultfile 2>&1 3010 | return 0 3011 | fi 3012 | ftp_running_count=0 # ftp 서비스 실행 중일 때 카운트 3013 | ftpusers_file_exists_count=0 # ftpusers 파일 존재 시 카운트 3014 | ps_ftp_count=`ps -ef | grep -iE 'ftp|vsftpd|proftp' | grep -v 'grep' | wc -l` 3015 | if [ $ps_ftp_count -gt 0 ]; then 3016 | ((ftp_running_count++)) 3017 | for ((i=0; i<${#ftpusers_files[@]}; i++)) 3018 | do 3019 | if [ -f ${ftpusers_files[$i]} ]; then 3020 | ((ftpusers_file_exists_count++)) 3021 | if [[ ${ftpusers_files[$i]} =~ /etc/proftpd.conf ]]; then 3022 | etc_proftpdconf_rootlogin_on_count=`grep -vE '^#|^\s#' ${ftpusers_files[$i]} | grep -i 'RootLogin' | grep -i 'on' | wc -l` 3023 | if [ $etc_proftpdconf_rootlogin_on_count -gt 0 ]; then 3024 | echo "※ U-64 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3025 | echo " ${ftpusers_files[$i]} 파일에 'RootLogin on' 설정이 있습니다." >> $resultfile 2>&1 3026 | return 0 3027 | fi 3028 | else 3029 | ftp_root_count=`grep -vE '^#|^\s#' ${ftpusers_files[$i]} | grep -w 'root' | wc -l` 3030 | if [ $ftp_root_count -eq 0 ]; then 3031 | echo "※ U-64 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3032 | echo " ${ftpusers_files[$i]} 파일에 'root' 계정이 없습니다." >> $resultfile 2>&1 3033 | return 0 3034 | fi 3035 | fi 3036 | fi 3037 | done 3038 | fi 3039 | if [ $ftp_running_count -gt 0 ] && [ $ftpusers_file_exists_count -eq 0 ]; then 3040 | echo "※ U-64 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3041 | echo " ftp 서비스를 사용하고, 'root' 계정의 접근을 제한할 파일이 없습니다." >> $resultfile 2>&1 3042 | return 0 3043 | fi 3044 | echo "※ U-64 결과 : 양호(Good)" >> $resultfile 2>&1 3045 | return 0 3046 | } 3047 | 3048 | U_65() { 3049 | echo "" >> $resultfile 2>&1 3050 | echo "▶ U-65(중) | 3. 서비스 관리 > 3.29 at 서비스 권한 설정 ◀" >> $resultfile 2>&1 3051 | echo " 양호 판단 기준 : at 명령어 일반사용자 금지 및 at 관련 파일 640 이하인 경우" >> $resultfile 2>&1 3052 | user_homedirectory_path=(`awk -F : '$7!="/bin/false" && $7!="/sbin/nologin" && $6!=null {print $6}' /etc/passwd | uniq`) # /etc/passwd 파일에 설정된 홈 디렉터리 배열 생성 3053 | user_homedirectory_path2=(/home/*) # /home 디렉터래 내 위치한 홈 디렉터리 배열 생성 3054 | for ((i=0; i<${#user_homedirectory_path2[@]}; i++)) 3055 | do 3056 | user_homedirectory_path[${#user_homedirectory_path[@]}]=${user_homedirectory_path2[$i]} # 두 개의 배열 합침 3057 | done 3058 | path_setting_files=(".profile" ".cshrc" ".login" ".kshrc" ".bash_profile" ".bashrc" ".bash_login") 3059 | path=(`echo $PATH | awk -F : '{for (i=1; i<=NF; i++) {print $i}}'`) 3060 | for ((i=0; i<${#user_homedirectory_path[@]}; i++)) 3061 | do 3062 | for ((j=0; j<${#path_setting_files[@]}; j++)) 3063 | do 3064 | if [ -f ${user_homedirectory_path[$i]}/${path_setting_files[$j]} ]; then 3065 | user_homedirectory_path_count=`grep -i 'path' ${user_homedirectory_path[$i]}/${path_setting_files[$j]} | wc -l` 3066 | if [ $user_homedirectory_path_count -gt 0 ]; then 3067 | path_setting_file_in_path=(`grep -i 'PATH' ${user_homedirectory_path[$i]}/${path_setting_files[$j]} | awk -F \" '{print $2}' | awk -F : '{for (l=1;l<=NF;l++) {print $l}}'`) 3068 | for ((k=0; k<${#path_setting_file_in_path[@]}; k++)) 3069 | do 3070 | if [[ ${path_setting_file_in_path[$k]} != \$PATH ]]; then 3071 | if [[ ${path_setting_file_in_path[$k]} == \$HOME* ]]; then 3072 | path_setting_file_in_path[$k]=$(echo ${path_setting_file_in_path[$k]} | awk -v u65_awk=${user_homedirectory_path[i]} '{gsub("\\$HOME",u65_awk,$0)} 1') 3073 | fi 3074 | path[${#path[@]}]=${path_setting_file_in_path[$k]} 3075 | fi 3076 | done 3077 | fi 3078 | fi 3079 | done 3080 | done 3081 | for ((i=0; i<${#path[@]}; i++)) 3082 | do 3083 | if [ -f ${path[$i]}/at ]; then 3084 | at_file_group_permission=`stat ${path[$i]}/at | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 3085 | if [ $at_file_group_permission -eq 5 ] || [ $at_file_group_permission -eq 4 ] || [ $at_file_group_permission -eq 1 ] || [ $at_file_group_permission -eq 0 ]; then 3086 | at_file_other_permission=`stat ${path[$i]}/at | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 3087 | if [ $at_file_other_permission -ne 0 ]; then 3088 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3089 | echo " ${path[$i]}/at 실행 파일이 다른 사용자(other)에 의해 실행이 가능합니다." >> $resultfile 2>&1 3090 | return 0 3091 | fi 3092 | else 3093 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3094 | echo " ${path[$i]}/at 실행 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3095 | return 0 3096 | fi 3097 | fi 3098 | done 3099 | at_access_control_files=("/etc/at.allow" "/etc/at.deny") 3100 | for ((i=0; i<${#at_access_control_files[@]}; i++)) 3101 | do 3102 | if [ -f ${at_access_control_files[$i]} ]; then 3103 | at_file_owner_name=`ls -l ${at_access_control_files[$i]} | awk '{print $3}'` 3104 | if [[ $at_file_owner_name =~ root ]]; then 3105 | at_file_permission=`stat ${at_access_control_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 3106 | if [ $at_file_permission -le 640 ]; then 3107 | at_file_owner_permission=`stat ${at_access_control_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 3108 | if [ $at_file_owner_permission -eq 6 ] || [ $at_file_owner_permission -eq 4 ] || [ $at_file_owner_permission -eq 2 ] || [ $at_file_owner_permission -eq 0 ]; then 3109 | at_file_group_permission=`stat ${at_access_control_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 3110 | if [ $at_file_group_permission -eq 4 ] || $at_file_owner_permission -eq 0 ]; then 3111 | at_file_other_permission=`stat ${at_access_control_files[$i]} | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 3112 | if [ $at_file_other_permission -ne 0 ]; then 3113 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3114 | echo " ${at_access_control_files[$i]} 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3115 | return 0 3116 | fi 3117 | else 3118 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3119 | echo " ${at_access_control_files[$i]} 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3120 | return 0 3121 | fi 3122 | else 3123 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3124 | echo " ${at_access_control_files[$i]} 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3125 | return 0 3126 | fi 3127 | else 3128 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3129 | echo " ${at_access_control_files[$i]} 파일의 권한이 640보다 큽니다." >> $resultfile 2>&1 3130 | return 0 3131 | fi 3132 | else 3133 | echo "※ U-65 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3134 | echo " ${at_access_control_files[$i]} 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 3135 | return 0 3136 | fi 3137 | fi 3138 | done 3139 | echo "※ U-65 결과 : 양호(Good)" >> $resultfile 2>&1 3140 | return 0 3141 | } 3142 | 3143 | U_66() { 3144 | echo "" >> $resultfile 2>&1 3145 | echo "▶ U-66(중) | 3. 서비스 관리 > 3.30 SNMP 서비스 구동 점검 ◀" >> $resultfile 2>&1 3146 | echo " 양호 판단 기준 : SNMP 서비스를 사용하지 않는 경우" >> $resultfile 2>&1 3147 | if [ `ps -ef | grep -i 'snmp' | grep -v 'grep' | wc -l` -gt 0 ]; then 3148 | echo "※ U-66 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3149 | echo " SNMP 서비스를 사용하고 있습니다." >> $resultfile 2>&1 3150 | return 0 3151 | else 3152 | echo "※ U-66 결과 : 양호(Good)" >> $resultfile 2>&1 3153 | return 0 3154 | fi 3155 | } 3156 | 3157 | U_67() { 3158 | echo "" >> $resultfile 2>&1 3159 | echo "▶ U-67(중) | 3. 서비스 관리 > 3.31 SNMP 서비스 Community String의 복잡성 설정 ◀" >> $resultfile 2>&1 3160 | echo " 양호 판단 기준 : SNMP Community 이름이 public, private 이 아닌 경우" >> $resultfile 2>&1 3161 | ps_snmp_count=`ps -ef | grep -i 'snmp' | grep -v 'grep' | wc -l` 3162 | if [ $ps_snmp_count -gt 0 ]; then 3163 | find_snmpdconf_count=`find / -name 'snmpd.conf' -type f 2>/dev/null | wc -l` 3164 | if [ $find_snmpdconf_count -gt 0 ]; then 3165 | snmpdconf_files=(`find / -name 'snmpd.conf' -type f 2>/dev/null`) 3166 | for ((i=0; i<${#snmpdconf_files[@]}; i++)) 3167 | do 3168 | snmpconf_public_private_count=`grep -vE '^#|^\s#' ${snmpdconf_files[$i]} | grep -iE 'public|private' | wc -l` 3169 | if [ $snmpconf_public_private_count -gt 0 ]; then 3170 | echo "※ U-67 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3171 | echo " SNMP Community String이 public 또는 private으로 설정되어 있습니다." >> $resultfile 2>&1 3172 | return 0 3173 | fi 3174 | done 3175 | else 3176 | echo "※ U-67 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3177 | echo " SNMP 서비스를 사용하고, Community String을 설정하는 파일이 없습니다." >> $resultfile 2>&1 3178 | return 0 3179 | fi 3180 | fi 3181 | echo "※ U-67 결과 : 양호(Good)" >> $resultfile 2>&1 3182 | return 0 3183 | } 3184 | 3185 | U_68() { 3186 | echo "" >> $resultfile 2>&1 3187 | echo "▶ U-68(하) | 3. 서비스 관리 > 3.32 로그온 시 경고 메시지 제공 ◀" >> $resultfile 2>&1 3188 | echo " 양호 판단 기준 : 서버 및 Telnet, FTP, SMTP, DNS 서비스에 로그온 메시지가 설정되어 있는 경우" >> $resultfile 2>&1 3189 | echo " ### DNS 배너의 경우 '/etc/named.conf' 또는 '/var/named' 파일을 수동으로 점검하세요." >> $resultfile 2>&1 3190 | if [ -f /etc/motd ]; then 3191 | if [ `grep -vE '^ *#|^$' /etc/motd | wc -l` -eq 0 ]; then 3192 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3193 | echo " /etc/motd 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3194 | return 0 3195 | fi 3196 | else 3197 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3198 | echo " /etc/motd 파일이 없습니다." >> $resultfile 2>&1 3199 | return 0 3200 | fi 3201 | if [ -f /etc/services ]; then 3202 | telnet_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="telnet" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 3203 | if [ $telnet_port_count -gt 0 ]; then 3204 | telnet_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="telnet" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 3205 | for ((i=0; i<${#telnet_port[@]}; i++)) 3206 | do 3207 | netstat_telnet_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${telnet_port[$i]} " | wc -l` 3208 | if [ $netstat_telnet_count -gt 0 ]; then 3209 | if [ -f /etc/issue.net ]; then 3210 | if [ `grep -vE '^ *#|^$' /etc/issue.net | wc -l` -eq 0 ]; then 3211 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3212 | echo " telnet 서비스를 사용하고, /etc/issue.net 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3213 | return 0 3214 | fi 3215 | else 3216 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3217 | echo " telnet 서비스를 사용하고, /etc/issue.net 파일이 없습니다." >> $resultfile 2>&1 3218 | return 0 3219 | fi 3220 | fi 3221 | done 3222 | fi 3223 | fi 3224 | ps_telnet_count=`ps -ef | grep -i 'telnet' | grep -v 'grep' | wc -l` 3225 | if [ $ps_telnet_count -gt 0 ]; then 3226 | if [ -f /etc/issue.net ]; then 3227 | if [ `grep -vE '^ *#|^$' /etc/issue.net | wc -l` -eq 0 ]; then 3228 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3229 | echo " telnet 서비스를 사용하고, /etc/issue.net 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3230 | return 0 3231 | fi 3232 | else 3233 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3234 | echo " telnet 서비스를 사용하고, /etc/issue.net 파일이 없습니다." >> $resultfile 2>&1 3235 | return 0 3236 | fi 3237 | fi 3238 | if [ -f /etc/services ]; then 3239 | ftp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 3240 | if [ $ftp_port_count -gt 0 ]; then 3241 | ftp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="ftp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 3242 | for ((i=0; i<${#ftp_port[@]}; i++)) 3243 | do 3244 | netstat_ftp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${ftp_port[$i]} " | wc -l` 3245 | if [ $netstat_ftp_count -gt 0 ]; then 3246 | ftpdconf_file_exists_count=0 3247 | if [ -f /etc/vsftpd.conf ]; then 3248 | ((ftpdconf_file_exists_count++)) 3249 | vsftpdconf_banner_count=`grep -vE '^#|^\s#' /etc/vsftpd.conf | grep 'ftpd_banner' | awk -F = '$2!=" " {print $2}' | wc -l` 3250 | if [ $vsftpdconf_banner_count -eq 0 ]; then 3251 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3252 | echo " ftp 서비스를 사용하고, /etc/vsftpd.conf 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3253 | return 0 3254 | fi 3255 | fi 3256 | if [ -f /etc/proftpd/proftpd.conf ]; then 3257 | ((ftpdconf_file_exists_count++)) 3258 | proftpdconf_banner_count=`grep -vE '^#|^\s#' /etc/proftpd/proftpd.conf | grep 'ServerIdent' | wc -l` 3259 | if [ $proftpdconf_banner_count -eq 0 ]; then 3260 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3261 | echo " ftp 서비스를 사용하고, /etc/proftpd/proftpd.conf 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3262 | return 0 3263 | fi 3264 | fi 3265 | if [ -f /etc/pure-ftpd/conf/WelcomeMsg ]; then 3266 | ((ftpdconf_file_exists_count++)) 3267 | pureftpd_conf_banner_count=`grep -vE '^ *#|^$' /etc/pure-ftpd/conf/WelcomeMsg | wc -l` 3268 | if [ $pureftpd_conf_banner_count -eq 0 ]; then 3269 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3270 | echo " ftp 서비스를 사용하고, /etc/pure-ftpd/conf/WelcomeMsg 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3271 | return 0 3272 | fi 3273 | fi 3274 | if [ $ftpdconf_file_exists_count -eq 0 ]; then 3275 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3276 | echo " ftp 서비스를 사용하고, 로그온 메시지를 설정하는 파일이 없습니다." >> $resultfile 2>&1 3277 | return 0 3278 | fi 3279 | 3280 | fi 3281 | done 3282 | fi 3283 | fi 3284 | ps_ftp_count=`ps -ef | grep -i 'ftp' | grep -vE 'grep|tftp|sftp' | wc -l` 3285 | if [ $ps_ftp_count -gt 0 ]; then 3286 | ftpdconf_file_exists_count=0 3287 | if [ -f /etc/vsftpd.conf ]; then 3288 | ((ftpdconf_file_exists_count++)) 3289 | vsftpdconf_banner_count=`grep -vE '^#|^\s#' /etc/vsftpd.conf | grep 'ftpd_banner' | awk -F = '$2!=" " {print $2}' | wc -l` 3290 | if [ $vsftpdconf_banner_count -eq 0 ]; then 3291 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3292 | echo " ftp 서비스를 사용하고, /etc/vsftpd.conf 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3293 | return 0 3294 | fi 3295 | fi 3296 | if [ -f /etc/proftpd/proftpd.conf ]; then 3297 | ((ftpdconf_file_exists_count++)) 3298 | proftpdconf_banner_count=`grep -vE '^#|^\s#' /etc/proftpd/proftpd.conf | grep 'ServerIdent' | wc -l` 3299 | if [ $proftpdconf_banner_count -eq 0 ]; then 3300 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3301 | echo " ftp 서비스를 사용하고, /etc/proftpd/proftpd.conf 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3302 | return 0 3303 | fi 3304 | fi 3305 | if [ -f /etc/pure-ftpd/conf/WelcomeMsg ]; then 3306 | ((ftpdconf_file_exists_count++)) 3307 | pureftpd_conf_banner_count=`grep -vE '^ *#|^$' /etc/pure-ftpd/conf/WelcomeMsg | wc -l` 3308 | if [ $pureftpd_conf_banner_count -eq 0 ]; then 3309 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3310 | echo " ftp 서비스를 사용하고, /etc/pure-ftpd/conf/WelcomeMsg 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3311 | return 0 3312 | fi 3313 | fi 3314 | if [ $ftpdconf_file_exists_count -eq 0 ]; then 3315 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3316 | echo " ftp 서비스를 사용하고, 로그온 메시지를 설정하는 파일이 없습니다." >> $resultfile 2>&1 3317 | return 0 3318 | fi 3319 | fi 3320 | if [ -f /etc/services ]; then 3321 | smtp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 3322 | if [ $smtp_port_count -gt 0 ]; then 3323 | smtp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 3324 | for ((i=0; i<${#smtp_port[@]}; i++)) 3325 | do 3326 | netstat_smtp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${smtp_port[$i]} " | wc -l` 3327 | if [ $netstat_smtp_count -gt 0 ]; then 3328 | find_sendmailcf_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 3329 | if [ $find_sendmailcf_count -gt 0 ]; then 3330 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 3331 | for ((j=0; j<${#sendmailcf_files[@]}; j++)) 3332 | do 3333 | sendmailcf_banner_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$j]} | grep 'Smtp' | grep 'GreetingMessage' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 3334 | if [ $sendmailcf_banner_count -eq 0 ]; then 3335 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3336 | echo " smtp 서비스를 사용하고, ${sendmailcf_files[$j]} 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3337 | return 0 3338 | fi 3339 | done 3340 | else 3341 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3342 | echo " smtp 서비스를 사용하고, 로그온 메시지를 설정하는 파일이 없습니다." >> $resultfile 2>&1 3343 | return 0 3344 | fi 3345 | fi 3346 | done 3347 | fi 3348 | fi 3349 | ps_smtp_count=`ps -ef | grep -iE 'smtp|sendmail' | grep -v 'grep' | wc -l` 3350 | if [ $ps_smtp_count -gt 0 ]; then 3351 | find_sendmailcf_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 3352 | if [ $find_sendmailcf_count -gt 0 ]; then 3353 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 3354 | for ((i=0; i<${#sendmailcf_files[@]}; i++)) 3355 | do 3356 | sendmailcf_banner_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$i]} | grep 'Smtp' | grep 'GreetingMessage' | awk -F = '{gsub(" ", "", $0); print $2}' | wc -l` 3357 | if [ $sendmailcf_banner_count -eq 0 ]; then 3358 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3359 | echo " smtp 서비스를 사용하고, ${sendmailcf_files[$i]} 파일에 로그온 메시지를 설정하지 않았습니다." >> $resultfile 2>&1 3360 | return 0 3361 | fi 3362 | done 3363 | else 3364 | echo "※ U-68 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3365 | echo " smtp 서비스를 사용하고, 로그온 메시지를 설정하는 파일이 없습니다." >> $resultfile 2>&1 3366 | return 0 3367 | fi 3368 | fi 3369 | echo "※ U-68 결과 : 양호(Good)" >> $resultfile 2>&1 3370 | return 0 3371 | } 3372 | 3373 | U_69() { 3374 | echo "" >> $resultfile 2>&1 3375 | echo "▶ U-69(중) | 3. 서비스 관리 > 3.33 NFS 설정파일 접근권한 ◀" >> $resultfile 2>&1 3376 | echo " 양호 판단 기준 : NFS 접근제어 설정파일의 소유자가 root 이고, 권한이 644 이하인 경우" >> $resultfile 2>&1 3377 | if [ -f /etc/exports ]; then 3378 | etc_exports_owner_name=`ls -l /etc/exports | awk '{print $3}'` 3379 | if [[ $etc_exports_owner_name =~ root ]]; then 3380 | etc_exports_permission=`stat /etc/exports | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,3)}'` 3381 | if [ $etc_exports_permission -le 644 ]; then 3382 | etc_exports_owner_permission=`stat /etc/exports | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,3,1)}'` 3383 | if [ $etc_exports_owner_permission -eq 6 ] || [ $etc_exports_owner_permission -eq 4 ] || [ $etc_exports_owner_permission -eq 2 ] || [ $etc_exports_owner_permission -eq 0 ]; then 3384 | etc_exports_group_permission=`stat /etc/exports | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,4,1)}'` 3385 | if [ $etc_exports_group_permission -eq 4 ] || [ $etc_exports_group_permission -eq 0 ]; then 3386 | etc_exports_other_permission=`stat /etc/exports | grep -i 'Uid' | awk '{print $2}' | awk -F / '{print substr($1,5,1)}'` 3387 | if [ $etc_exports_other_permission -eq 4 ] || [ $etc_exports_other_permission -eq 0 ]; then 3388 | echo "※ U-69 결과 : 양호(Good)" >> $resultfile 2>&1 3389 | return 0 3390 | else 3391 | echo "※ U-69 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3392 | echo " /etc/exports 파일의 다른 사용자(other)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3393 | return 0 3394 | fi 3395 | else 3396 | echo "※ U-69 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3397 | echo " /etc/exports 파일의 그룹 사용자(group)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3398 | return 0 3399 | fi 3400 | else 3401 | echo "※ U-69 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3402 | echo " /etc/exports 파일의 사용자(owner)에 대한 권한이 취약합니다." >> $resultfile 2>&1 3403 | return 0 3404 | fi 3405 | else 3406 | echo "※ U-69 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3407 | echo " /etc/exports 파일의 권한이 644보다 큽니다." >> $resultfile 2>&1 3408 | return 0 3409 | fi 3410 | else 3411 | echo "※ U-69 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3412 | echo " /etc/exports 파일의 소유자(owner)가 root가 아닙니다." >> $resultfile 2>&1 3413 | return 0 3414 | fi 3415 | else 3416 | echo "※ U-69 결과 : N/A" >> $resultfile 2>&1 3417 | echo " /etc/exports 파일이 없습니다." >> $resultfile 2>&1 3418 | return 0 3419 | fi 3420 | } 3421 | 3422 | U_70() { 3423 | echo "" >> $resultfile 2>&1 3424 | echo "▶ U-70(중) | 3. 서비스 관리 > 3.34 expn, vrfy 명령어 제한 ◀" >> $resultfile 2>&1 3425 | echo " 양호 판단 기준 : SMTP 서비스 미사용 또는, noexpn, novrfy 옵션이 설정되어 있는 경우" >> $resultfile 2>&1 3426 | if [ -f /etc/services ]; then 3427 | smtp_port_count=`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}' | wc -l` 3428 | if [ $smtp_port_count -gt 0 ]; then 3429 | smtp_port=(`grep -vE '^#|^\s#' /etc/services | awk 'tolower($1)=="smtp" {print $2}' | awk -F / 'tolower($2)=="tcp" {print $1}'`) 3430 | for ((i=0; i<${#smtp_port[@]}; i++)) 3431 | do 3432 | netstat_smtp_count=`netstat -nat 2>/dev/null | grep -w 'tcp' | grep -Ei 'listen|established|syn_sent|syn_received' | grep ":${smtp_port[$i]} " | wc -l` 3433 | if [ $netstat_smtp_count -gt 0 ]; then 3434 | find_sendmailcf_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 3435 | if [ $find_sendmailcf_count -gt 0 ]; then 3436 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 3437 | for ((j=0; j<${#sendmailcf_files[@]}; j++)) 3438 | do 3439 | sendmailcf_goaway_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$j]} | grep -i 'PrivacyOptions' | grep -i 'goaway' | wc -l` 3440 | sendmailcf_noexpnt_novrfy_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$j]} | grep -i 'PrivacyOptions' | grep -i 'noexpn' | grep -i 'novrfy' | wc -l` 3441 | if [ $sendmailcf_goaway_count -eq 0 ] && [ $sendmailcf_noexpnt_novrfy_count -eq 0 ]; then 3442 | echo "※ U-70 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3443 | echo " ${sendmailcf_files[$j]} 파일에 noexpn, novrfy 또는 goaway 설정이 없습니다." >> $resultfile 2>&1 3444 | return 0 3445 | fi 3446 | done 3447 | else 3448 | echo "※ U-70 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3449 | echo " noexpn, novrfy 또는 goaway 옵션을 설정하는 파일이 없습니다." >> $resultfile 2>&1 3450 | return 0 3451 | fi 3452 | fi 3453 | done 3454 | fi 3455 | fi 3456 | ps_smtp_count=`ps -ef | grep -iE 'smtp|sendmail' | grep -v 'grep' | wc -l` 3457 | if [ $ps_smtp_count -gt 0 ]; then 3458 | find_sendmailcf_count=`find / -name 'sendmail.cf' -type f 2>/dev/null | wc -l` 3459 | if [ $find_sendmailcf_count -gt 0 ]; then 3460 | sendmailcf_files=(`find / -name 'sendmail.cf' -type f 2>/dev/null`) 3461 | for ((i=0; i<${#sendmailcf_files[@]}; i++)) 3462 | do 3463 | sendmailcf_goaway_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$i]} | grep -i 'PrivacyOptions' | grep -i 'goaway' | wc -l` 3464 | sendmailcf_noexpnt_novrfy_count=`grep -vE '^#|^\s#' ${sendmailcf_files[$i]} | grep -i 'PrivacyOptions' | grep -i 'noexpn' | grep -i 'novrfy' | wc -l` 3465 | if [ $sendmailcf_goaway_count -eq 0 ] && [ $sendmailcf_noexpnt_novrfy_count -eq 0 ]; then 3466 | echo "※ U-70 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3467 | echo " ${sendmailcf_files[$i]} 파일에 noexpn, novrfy 또는 goaway 설정이 없습니다." >> $resultfile 2>&1 3468 | return 0 3469 | fi 3470 | done 3471 | else 3472 | echo "※ U-70 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3473 | echo " noexpn, novrfy 또는 goaway 옵션을 설정하는 파일이 없습니다." >> $resultfile 2>&1 3474 | return 0 3475 | fi 3476 | fi 3477 | echo "※ U-70 결과 : 양호(Good)" >> $resultfile 2>&1 3478 | return 0 3479 | } 3480 | 3481 | U_71() { 3482 | echo "" >> $resultfile 2>&1 3483 | echo "▶ U-71(중) | 3. 서비스 관리 > 3.35 Apache 웹 서비스 정보 숨김 ◀" >> $resultfile 2>&1 3484 | echo " 양호 판단 기준 : ServerTokens Prod, ServerSignature Off로 설정되어있는 경우" >> $resultfile 2>&1 3485 | webconf_file_exists_count=0 3486 | webconf_files=(".htaccess" "httpd.conf" "apache2.conf") 3487 | for ((i=0; i<${#webconf_files[@]}; i++)) 3488 | do 3489 | find_webconf_file_count=`find / -name ${webconf_files[$i]} -type f 2>/dev/null | wc -l` 3490 | if [ $find_webconf_file_count -gt 0 ]; then 3491 | ((webconf_file_exists_count++)) 3492 | find_webconf_files=(`find / -name ${webconf_files[$i]} -type f 2>/dev/null`) 3493 | for ((j=0; j<${#find_webconf_files[@]}; j++)) 3494 | do 3495 | webconf_servertokens_prod_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'ServerTokens' | grep -i 'Prod' | wc -l` 3496 | if [ $webconf_servertokens_prod_count -gt 0 ]; then 3497 | webconf_serversignature_off_count=`grep -vE '^#|^\s#' ${find_webconf_files[$j]} | grep -i 'ServerSignature' | grep -i 'Off' | wc -l` 3498 | if [ $webconf_serversignature_off_count -eq 0 ]; then 3499 | echo "※ U-71 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3500 | echo " ${find_webconf_files[$j]} 파일에 ServerSignature off 설정이 없습니다." >> $resultfile 2>&1 3501 | return 0 3502 | fi 3503 | else 3504 | echo "※ U-71 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3505 | echo " ${find_webconf_files[$j]} 파일에 ServerTokens Prod 설정이 없습니다." >> $resultfile 2>&1 3506 | return 0 3507 | fi 3508 | done 3509 | fi 3510 | done 3511 | ps_apache_count=`ps -ef | grep -iE 'httpd|apache2' | grep -v 'grep' | wc -l` 3512 | if [ $ps_apache_count -gt 0 ] && [ $webconf_file_exists_count -eq 0 ]; then 3513 | echo "※ U-71 결과 : 취약(Vulnerable)" >> $resultfile 2>&1 3514 | echo " Apache 서비스를 사용하고, ServerTokens Prod, ServerSignature Off를 설정하는 파일이 없습니다." >> $resultfile 2>&1 3515 | return 0 3516 | else 3517 | echo "※ U-71 결과 : 양호(Good)" >> $resultfile 2>&1 3518 | return 0 3519 | fi 3520 | } 3521 | 3522 | U_72() { 3523 | echo "" >> $resultfile 2>&1 3524 | echo "▶ U-72(하) | 5. 로그 관리 > 5.2 정책에 따른 시스템 로깅 설정 ◀" >> $resultfile 2>&1 3525 | echo " 양호 판단 기준 : 로그 기록 정책이 정책에 따라 설정되어 수립되어 있으며 보안정책에 따라 로그를 남기고 있을 경우" >> $resultfile 2>&1 3526 | echo "※ U-72 결과 : N/A" >> $resultfile 2>&1 3527 | echo " 수동으로 점검하세요." >> $resultfile 2>&1 3528 | } 3529 | 3530 | echo "" > $resultfile 2>&1 3531 | echo " 점검일 : `date +'%F %H:%M:%S'`" >> $resultfile 2>&1 3532 | echo "##############################################################################" >> $resultfile 2>&1 3533 | echo "# #" >> $resultfile 2>&1 3534 | echo "# CentOS 6 vulnerability assessment results Version 1.1.3 #" >> $resultfile 2>&1 3535 | echo "# Copyright (c) 2023 Kim Jei #" >> $resultfile 2>&1 3536 | echo "# #" >> $resultfile 2>&1 3537 | echo "##############################################################################" >> $resultfile 2>&1 3538 | 3539 | U_01 3540 | U_02 3541 | U_03 3542 | U_04 3543 | U_05 3544 | U_06 3545 | U_07 3546 | U_08 3547 | U_09 3548 | U_10 3549 | U_11 3550 | U_12 3551 | U_13 3552 | U_14 3553 | U_15 3554 | U_16 3555 | U_17 3556 | U_18 3557 | U_19 3558 | U_20 3559 | U_21 3560 | U_22 3561 | U_23 3562 | U_24 3563 | U_25 3564 | U_26 3565 | U_27 3566 | U_28 3567 | U_29 3568 | U_30 3569 | U_31 3570 | U_32 3571 | U_33 3572 | U_34 3573 | U_35 3574 | U_36 3575 | U_37 3576 | U_38 3577 | U_39 3578 | U_40 3579 | U_41 3580 | U_42 3581 | U_43 3582 | U_44 3583 | U_45 3584 | U_46 3585 | U_47 3586 | U_48 3587 | U_49 3588 | U_50 3589 | U_51 3590 | U_52 3591 | U_53 3592 | U_54 3593 | U_55 3594 | U_56 3595 | U_57 3596 | U_58 3597 | U_59 3598 | U_60 3599 | U_61 3600 | U_62 3601 | U_63 3602 | U_64 3603 | U_65 3604 | U_66 3605 | U_67 3606 | U_68 3607 | U_69 3608 | U_70 3609 | U_71 3610 | U_72 3611 | 3612 | echo "" >> $resultfile 2>&1 3613 | echo "================================ 진단 결과 요약 ================================" >> $resultfile 2>&1 3614 | echo "" >> $resultfile 2>&1 3615 | echo " ★ 항목 개수 = `cat $resultfile | grep '결과 : ' | wc -l`" >> $resultfile 2>&1 3616 | echo " ☆ 취약 개수 = `cat $resultfile | grep '결과 : 취약' | wc -l`" >> $resultfile 2>&1 3617 | echo " ★ 양호 개수 = `cat $resultfile | grep '결과 : 양호' | wc -l`" >> $resultfile 2>&1 3618 | echo " ☆ N/A 개수 = `cat $resultfile | grep '결과 : N/A' | wc -l`" >> $resultfile 2>&1 3619 | echo "" >> $resultfile 2>&1 3620 | echo "==============================================================================" >> $resultfile 2>&1 3621 | echo "" >> $resultfile 2>&1 -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 주요정보통신기반시설 기술적 취약점 분석·평가 상세가이드를 기반으로 취약점을 점검하는 기업 및 기관에 조금이라도 도움이 되기 위하여 직접 개발한 스크립트 코드를 공유합니다. 3 | 4 | ## Environment 5 | 현재(2023-12-27)까지 스크립트가 동작되는 OS는 CentOS 6-7, Ubuntu 16.04, 18.04, 20.04, 22.04, Fedora 38, Rocky 8, 9입니다. 6 | 7 | ## Usage 8 | 쉘 스트립트에 실행 권한을 부여한 뒤(**chmod +x 스크립트명**), 쉘 스크립트가 존재하는 디렉터리에서 "**bash 스크립트명**" 명령을 입력하여 실행하세요. "./스트립트명", "sh 스트립트명" 등의 명령으로 실행 시 에러가 발생할 수 있습니다. 9 | 10 | 점검 항목 중 관리자 권한(UID=0)을 가지는 사용자가 실행해야 하는 명령어가 많으므로 스크립트를 실행할 때 관리자(UID=0) 권한으로 실행하시면 점검이 수월합니다. 11 | 12 | ## Error 13 | 사용 중 발생한 에러는 **catember30@gmail.com**으로 신고 메일을 보내주세요.
에러 메시지를 캡처 또는 복사 해주시고, 점검한 OS와 버전을 말해주시면 최대한 빠른 시일 내로 수정 후 재배포하겠습니다. :) 14 | - 스크립트 실행 시 '/bin/bash^M: bad interpreter' 메시지가 뜨는 경우 dos2unix 패키지를 설치한 뒤 "dos2unix 스크립트명" 명령어를 입력한 뒤 다시 실행하시면 됩니다.
-> 설치 명령어 = yum install dos2unix(CentOS/RHEL/Rocky), apt install dos2unix(Ubuntu/Debian) 15 | 16 | ## Copyright 17 | - (23.12.27) CentOS 6-7, Ubuntu 16.04, 18.04, 20.04, 22.04, Fedora 38, Rocky 8.8, 9.2의 Version 1.1.3에 대한 저작권은 **김제이**에게 있습니다. 18 | - (23.12.26) CentOS 6-7, Ubuntu 16.04, 18.04, 20.04, 22.04, Fedora 38, Rocky 8.8, 9.2의 Version 1.1.2에 대한 저작권은 **김제이**에게 있습니다. 19 | - (23.07.30) CentOS 6-7, Ubuntu 16.04, 18.04, 20.04, 22.04, Fedora 38, Rocky 8.8, 9.2의 Version 1.1.1에 대한 저작권은 **김제이**에게 있습니다. 20 | - (23.07.03) CentOS 6-7, Ubuntu 16.04, 18.04, 20.04, 22.04, Fedora 38, Rocky 8.8, 9.2의 Version 1.0.0에 대한 저작권은 **김제이, 서경민, 이예은, 정다연**에게 있습니다. --------------------------------------------------------------------------------