From fb9bf542a10459d355fde049aa1989522c859ad5 Mon Sep 17 00:00:00 2001 From: "thibault.dewailly" Date: Sat, 16 Apr 2016 17:25:48 +0200 Subject: [PATCH] 13.1_remove_empty_password_field.sh 13.2_remove_legacy_passwd_entries.sh 13.3_remove_legacy_shadow_entries.sh 13.4_remove_legacy_group_entries.sh 13.5_find_0_uid_non_root_account.sh 13.6_sanitize_root_path.sh --- bin/hardening/10.3_default_root_group.sh | 2 +- .../10.5_lock_inactive_user_account.sh | 2 +- ...sh => 13.1_remove_empty_password_field.sh} | 4 +- .../13.2_remove_legacy_passwd_entries.sh | 61 ++++++++++++++ .../13.3_remove_legacy_shadow_entries.sh | 61 ++++++++++++++ .../13.4_remove_legacy_group_entries.sh | 61 ++++++++++++++ .../13.5_find_0_uid_non_root_account.sh | 65 ++++++++++++++ bin/hardening/13.6_sanitize_root_path.sh | 84 +++++++++++++++++++ bin/hardenning.sh | 16 ++++ ...g => 13.1_remove_empty_password_field.cfg} | 0 .../13.2_remove_legacy_passwd_entries.cfg | 2 + .../13.3_remove_legacy_shadow_entries.cfg | 2 + .../13.4_remove_legacy_group_entries.cfg | 2 + .../13.5_find_0_uid_non_root_account.cfg | 4 + etc/conf.d/13.6_sanitize_root_path.cfg | 2 + lib/utils.sh | 6 +- 16 files changed, 367 insertions(+), 7 deletions(-) rename bin/hardening/{13.1_remove_empry_password_field.sh => 13.1_remove_empty_password_field.sh} (90%) create mode 100755 bin/hardening/13.2_remove_legacy_passwd_entries.sh create mode 100755 bin/hardening/13.3_remove_legacy_shadow_entries.sh create mode 100755 bin/hardening/13.4_remove_legacy_group_entries.sh create mode 100755 bin/hardening/13.5_find_0_uid_non_root_account.sh create mode 100755 bin/hardening/13.6_sanitize_root_path.sh create mode 100644 bin/hardenning.sh rename etc/conf.d/{13.1_remove_empry_password_field.cfg => 13.1_remove_empty_password_field.cfg} (100%) create mode 100644 etc/conf.d/13.2_remove_legacy_passwd_entries.cfg create mode 100644 etc/conf.d/13.3_remove_legacy_shadow_entries.cfg create mode 100644 etc/conf.d/13.4_remove_legacy_group_entries.cfg create mode 100644 etc/conf.d/13.5_find_0_uid_non_root_account.cfg create mode 100644 etc/conf.d/13.6_sanitize_root_path.cfg diff --git a/bin/hardening/10.3_default_root_group.sh b/bin/hardening/10.3_default_root_group.sh index a01fa34..d534d35 100755 --- a/bin/hardening/10.3_default_root_group.sh +++ b/bin/hardening/10.3_default_root_group.sh @@ -6,7 +6,7 @@ # # -# 10.1.3 Set Password Expiring Warning Days (Scored) +# 10.3 Set Default Group for root Account (Scored) # set -e # One error, it's over diff --git a/bin/hardening/10.5_lock_inactive_user_account.sh b/bin/hardening/10.5_lock_inactive_user_account.sh index 6d82eff..9c025ec 100755 --- a/bin/hardening/10.5_lock_inactive_user_account.sh +++ b/bin/hardening/10.5_lock_inactive_user_account.sh @@ -6,7 +6,7 @@ # # -# 10.4 Set Default umask for Users (Scored) +# 10.5 Lock Inactive User Accounts (Scored) # set -e # One error, it's over diff --git a/bin/hardening/13.1_remove_empry_password_field.sh b/bin/hardening/13.1_remove_empty_password_field.sh similarity index 90% rename from bin/hardening/13.1_remove_empry_password_field.sh rename to bin/hardening/13.1_remove_empty_password_field.sh index db05a19..6c17732 100755 --- a/bin/hardening/13.1_remove_empry_password_field.sh +++ b/bin/hardening/13.1_remove_empty_password_field.sh @@ -17,7 +17,7 @@ FILE='/etc/shadow' # This function will be called if the script status is on enabled / audit mode audit () { info "Checking if accounts have empty passwords" - RESULT=$(/bin/cat $FILE | /usr/bin/awk -F: '($2 == "" ) { print $1 }') + RESULT=$(cat $FILE | awk -F: '($2 == "" ) { print $1 }') if [ ! -z "$RESULT" ]; then crit "Some accounts have empty passwords" crit $RESULT @@ -28,7 +28,7 @@ audit () { # This function will be called if the script status is on enabled mode apply () { - RESULT=$(/bin/cat $FILE | /usr/bin/awk -F: '($2 == "" ) { print $1 }') + RESULT=$(cat $FILE | awk -F: '($2 == "" ) { print $1 }') if [ ! -z "$RESULT" ]; then warn "Some accounts have empty passwords" for ACCOUNT in $RESULT; do diff --git a/bin/hardening/13.2_remove_legacy_passwd_entries.sh b/bin/hardening/13.2_remove_legacy_passwd_entries.sh new file mode 100755 index 0000000..1ad0e75 --- /dev/null +++ b/bin/hardening/13.2_remove_legacy_passwd_entries.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# +# CIS Debian 7 Hardening +# Authors : Thibault Dewailly, OVH +# + +# +# 13.2 Verify No Legacy "+" Entries Exist in /etc/passwd File (Scored) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +FILE='/etc/passwd' +RESULT='' + +# This function will be called if the script status is on enabled / audit mode +audit () { + info "Checking if accounts have empty passwords" + if grep '^+:' $FILE -q; then + RESULT=$(grep '^+:' $FILE) + crit "Some accounts have legacy password entry" + crit $RESULT + else + ok "All accounts have a valid password entry format" + fi +} + +# This function will be called if the script status is on enabled mode +apply () { + if grep '^+:' $FILE -q; then + RESULT=$(grep '^+:' $FILE) + warn "Some accounts have legacy password entry" + for LINE in $RESULT; do + info "Removing $LINE from $FILE" + delete_line_in_file $FILE $LINE + done + else + ok "All accounts have a valid password entry format" + fi +} + +# This function will check config parameters required +check_config() { + : +} + +# Source Root Dir Parameter +if [ ! -r /etc/default/cis-hardenning ]; then + echo "There is no /etc/default/cis-hardenning file, cannot source CIS_ROOT_DIR variable, aborting" + exit 128 +else + . /etc/default/cis-hardenning + if [ -z $CIS_ROOT_DIR ]; then + echo "No CIS_ROOT_DIR variable, aborting" + fi +fi + +# Main function, will call the proper functions given the configuration (audit, enabled, disabled) +[ -r $CIS_ROOT_DIR/lib/main.sh ] && . $CIS_ROOT_DIR/lib/main.sh diff --git a/bin/hardening/13.3_remove_legacy_shadow_entries.sh b/bin/hardening/13.3_remove_legacy_shadow_entries.sh new file mode 100755 index 0000000..e272c64 --- /dev/null +++ b/bin/hardening/13.3_remove_legacy_shadow_entries.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# +# CIS Debian 7 Hardening +# Authors : Thibault Dewailly, OVH +# + +# +# 13.3 Verify No Legacy "+" Entries Exist in /etc/shadow File (Scored) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +FILE='/etc/shadow' +RESULT='' + +# This function will be called if the script status is on enabled / audit mode +audit () { + info "Checking if accounts have empty passwords" + if grep '^+:' $FILE -q; then + RESULT=$(grep '^+:' $FILE) + crit "Some accounts have legacy password entry" + crit $RESULT + else + ok "All accounts have a valid password entry format" + fi +} + +# This function will be called if the script status is on enabled mode +apply () { + if grep '^+:' $FILE -q; then + RESULT=$(grep '^+:' $FILE) + warn "Some accounts have legacy password entry" + for LINE in $RESULT; do + info "Removing $LINE from $FILE" + delete_line_in_file $FILE $LINE + done + else + ok "All accounts have a valid password entry format" + fi +} + +# This function will check config parameters required +check_config() { + : +} + +# Source Root Dir Parameter +if [ ! -r /etc/default/cis-hardenning ]; then + echo "There is no /etc/default/cis-hardenning file, cannot source CIS_ROOT_DIR variable, aborting" + exit 128 +else + . /etc/default/cis-hardenning + if [ -z $CIS_ROOT_DIR ]; then + echo "No CIS_ROOT_DIR variable, aborting" + fi +fi + +# Main function, will call the proper functions given the configuration (audit, enabled, disabled) +[ -r $CIS_ROOT_DIR/lib/main.sh ] && . $CIS_ROOT_DIR/lib/main.sh diff --git a/bin/hardening/13.4_remove_legacy_group_entries.sh b/bin/hardening/13.4_remove_legacy_group_entries.sh new file mode 100755 index 0000000..64c7cd4 --- /dev/null +++ b/bin/hardening/13.4_remove_legacy_group_entries.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# +# CIS Debian 7 Hardening +# Authors : Thibault Dewailly, OVH +# + +# +# 13.4 Verify No Legacy "+" Entries Exist in /etc/group File (Scored) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +FILE='/etc/group' +RESULT='' + +# This function will be called if the script status is on enabled / audit mode +audit () { + info "Checking if accounts have empty passwords" + if grep '^+:' $FILE -q; then + RESULT=$(grep '^+:' $FILE) + crit "Some accounts have legacy password entry" + crit $RESULT + else + ok "All accounts have a valid password entry format" + fi +} + +# This function will be called if the script status is on enabled mode +apply () { + if grep '^+:' $FILE -q; then + RESULT=$(grep '^+:' $FILE) + warn "Some accounts have legacy password entry" + for LINE in $RESULT; do + info "Removing $LINE from $FILE" + delete_line_in_file $FILE $LINE + done + else + ok "All accounts have a valid password entry format" + fi +} + +# This function will check config parameters required +check_config() { + : +} + +# Source Root Dir Parameter +if [ ! -r /etc/default/cis-hardenning ]; then + echo "There is no /etc/default/cis-hardenning file, cannot source CIS_ROOT_DIR variable, aborting" + exit 128 +else + . /etc/default/cis-hardenning + if [ -z $CIS_ROOT_DIR ]; then + echo "No CIS_ROOT_DIR variable, aborting" + fi +fi + +# Main function, will call the proper functions given the configuration (audit, enabled, disabled) +[ -r $CIS_ROOT_DIR/lib/main.sh ] && . $CIS_ROOT_DIR/lib/main.sh diff --git a/bin/hardening/13.5_find_0_uid_non_root_account.sh b/bin/hardening/13.5_find_0_uid_non_root_account.sh new file mode 100755 index 0000000..e6ab002 --- /dev/null +++ b/bin/hardening/13.5_find_0_uid_non_root_account.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# +# CIS Debian 7 Hardening +# Authors : Thibault Dewailly, OVH +# + +# +# 13.5 Verify No UID 0 Accounts Exist Other Than root (Scored) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +FILE='/etc/passwd' +RESULT='' + +# This function will be called if the script status is on enabled / audit mode +audit () { + info "Checking if accounts have uid 0" + RESULT=$(cat $FILE | awk -F: '($3 == 0 && $1!="root" ) { print $1 }') + for ACCOUNT in $RESULT; do + debug "Account : $ACCOUNT" + debug "Exceptions : $EXCEPTIONS" + debug "echo \"$EXCEPTIONS\" | grep -q $ACCOUNT" + if echo "$EXCEPTIONS" | grep -q $ACCOUNT; then + debug "$ACCOUNT is confirmed as an exception" + RESULT=$(sed "s!$ACCOUNT!!" <<< "$RESULT") + else + debug "$ACCOUNT not found in exceptions" + fi + done + if [ ! -z "$RESULT" ]; then + crit "Some accounts have uid 0" + crit $RESULT + else + ok "No account with suid 0 apart root" + fi +} + +# This function will be called if the script status is on enabled mode +apply () { + info "Removing accounts with uid 0 may seriously harm your system, report only here" +} + +# This function will check config parameters required +check_config() { + if [ -z "$EXCEPTIONS" ]; then + EXCEPTIONS="@" + fi +} + +# Source Root Dir Parameter +if [ ! -r /etc/default/cis-hardenning ]; then + echo "There is no /etc/default/cis-hardenning file, cannot source CIS_ROOT_DIR variable, aborting" + exit 128 +else + . /etc/default/cis-hardenning + if [ -z $CIS_ROOT_DIR ]; then + echo "No CIS_ROOT_DIR variable, aborting" + fi +fi + +# Main function, will call the proper functions given the configuration (audit, enabled, disabled) +[ -r $CIS_ROOT_DIR/lib/main.sh ] && . $CIS_ROOT_DIR/lib/main.sh diff --git a/bin/hardening/13.6_sanitize_root_path.sh b/bin/hardening/13.6_sanitize_root_path.sh new file mode 100755 index 0000000..73f03ea --- /dev/null +++ b/bin/hardening/13.6_sanitize_root_path.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +# +# CIS Debian 7 Hardening +# Authors : Thibault Dewailly, OVH +# + +# +# 13.6 Ensure root PATH Integrity (Scored) +# + +set -e # One error, it's over +set -u # One variable unset, it's over + +ERRORS=0 + +# This function will be called if the script status is on enabled / audit mode +audit () { + if [ "`echo $PATH | grep :: `" != "" ]; then + crit "Empty Directory in PATH (::)" + ERRORS=$((ERRORS+1)) + fi + if [ "`echo $PATH | grep :$`" != "" ]; then + crit "Trailing : in PATH $PATH" + ERRORS=$((ERRORS+1)) + fi + FORMATTED_PATH=$(echo $PATH | sed -e 's/::/:/' -e 's/:$//' -e 's/:/ /g') + set -- $FORMATTED_PATH + while [ "${1:-}" != "" ]; do + if [ "$1" = "." ]; then + crit "PATH contains ." + ERRORS=$((ERRORS+1)) + else + if [ -d $1 ]; then + dirperm=$(ls -ldH $1 | cut -f1 -d" ") + if [ $(echo $dirperm | cut -c6 ) != "-" ]; then + crit "Group Write permission set on directory $1" + ERRORS=$((ERRORS+1)) + fi + if [ $(echo $dirperm | cut -c9 ) != "-" ]; then + crit "Other Write permission set on directory $1" + ERRORS=$((ERRORS+1)) + fi + dirown=$(ls -ldH $1 | awk '{print $3}') + if [ "$dirown" != "root" ] ; then + crit "$1 is not owned by root" + ERRORS=$((ERRORS+1)) + fi + else + crit "$1 is not a directory" + ERRORS=$((ERRORS+1)) + fi + fi + shift + done + + if [ $ERRORS = 0 ]; then + ok "root PATH is secure" + fi +} + +# This function will be called if the script status is on enabled mode +apply () { + info "Editing items from PATH may seriously harm your system, report only here" +} + +# This function will check config parameters required +check_config() { + : +} + +# Source Root Dir Parameter +if [ ! -r /etc/default/cis-hardenning ]; then + echo "There is no /etc/default/cis-hardenning file, cannot source CIS_ROOT_DIR variable, aborting" + exit 128 +else + . /etc/default/cis-hardenning + if [ -z $CIS_ROOT_DIR ]; then + echo "No CIS_ROOT_DIR variable, aborting" + fi +fi + +# Main function, will call the proper functions given the configuration (audit, enabled, disabled) +[ -r $CIS_ROOT_DIR/lib/main.sh ] && . $CIS_ROOT_DIR/lib/main.sh diff --git a/bin/hardenning.sh b/bin/hardenning.sh new file mode 100644 index 0000000..d717d9b --- /dev/null +++ b/bin/hardenning.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# CIs Deb +# +# CIS Debian 7 Hardening +# Authors : Thibault Dewailly, OVH +# + +# +# Main script : Execute hardening considering configuration +# + +# Execute blindly binaries +# Audit mode + +# ls | sort -n diff --git a/etc/conf.d/13.1_remove_empry_password_field.cfg b/etc/conf.d/13.1_remove_empty_password_field.cfg similarity index 100% rename from etc/conf.d/13.1_remove_empry_password_field.cfg rename to etc/conf.d/13.1_remove_empty_password_field.cfg diff --git a/etc/conf.d/13.2_remove_legacy_passwd_entries.cfg b/etc/conf.d/13.2_remove_legacy_passwd_entries.cfg new file mode 100644 index 0000000..e1e4502 --- /dev/null +++ b/etc/conf.d/13.2_remove_legacy_passwd_entries.cfg @@ -0,0 +1,2 @@ +# Configuration for script of same name +status=enabled diff --git a/etc/conf.d/13.3_remove_legacy_shadow_entries.cfg b/etc/conf.d/13.3_remove_legacy_shadow_entries.cfg new file mode 100644 index 0000000..e1e4502 --- /dev/null +++ b/etc/conf.d/13.3_remove_legacy_shadow_entries.cfg @@ -0,0 +1,2 @@ +# Configuration for script of same name +status=enabled diff --git a/etc/conf.d/13.4_remove_legacy_group_entries.cfg b/etc/conf.d/13.4_remove_legacy_group_entries.cfg new file mode 100644 index 0000000..e1e4502 --- /dev/null +++ b/etc/conf.d/13.4_remove_legacy_group_entries.cfg @@ -0,0 +1,2 @@ +# Configuration for script of same name +status=enabled diff --git a/etc/conf.d/13.5_find_0_uid_non_root_account.cfg b/etc/conf.d/13.5_find_0_uid_non_root_account.cfg new file mode 100644 index 0000000..9b61b4a --- /dev/null +++ b/etc/conf.d/13.5_find_0_uid_non_root_account.cfg @@ -0,0 +1,4 @@ +# Configuration for script of same name +status=enabled +# Put here valid accounts with uid 0 separated by spaces +EXCEPTIONS="" diff --git a/etc/conf.d/13.6_sanitize_root_path.cfg b/etc/conf.d/13.6_sanitize_root_path.cfg new file mode 100644 index 0000000..e1e4502 --- /dev/null +++ b/etc/conf.d/13.6_sanitize_root_path.cfg @@ -0,0 +1,2 @@ +# Configuration for script of same name +status=enabled diff --git a/lib/utils.sh b/lib/utils.sh index adc3e30..e46a09f 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -125,7 +125,7 @@ add_line_file_before_pattern() { backup_file "$FILE" debug "Inserting $LINE before $PATTERN in $FILE" - PATTERN=$(sed 's@/@\/@g' <<< $PATTERN) + PATTERN=$(sed 's@/@\\\/@g' <<< $PATTERN) debug "sed -i '/$PATTERN/i $LINE' $FILE" sed -i "/$PATTERN/i $LINE" $FILE FNRET=0 @@ -138,7 +138,7 @@ replace_in_file() { backup_file "$FILE" debug "Replacing $SOURCE to $DESTINATION in $FILE" - SOURCE=$(sed 's@/@\/@g' <<< $SOURCE) + SOURCE=$(sed 's@/@\\\/@g' <<< $PATTERN) debug "sed -i 's/$SOURCE/$DESTINATION/g' $FILE" sed -i "s/$SOURCE/$DESTINATION/g" $FILE FNRET=0 @@ -150,7 +150,7 @@ delete_line_in_file() { backup_file "$FILE" debug "Deleting lines from $FILE containing $PATTERN" - PATTERN=$(sed 's@/@\/@g' <<< $PATTERN) + PATTERN=$(sed 's@/@\\\/@g' <<< $PATTERN) debug "sed -i '/$PATTERN/d' $FILE" sed -i "/$PATTERN/d" $FILE FNRET=0