Fix race condition on /etc/passwd, /etc/shadow and /etc/group

This commit is contained in:
Thibault Ayanides 2020-11-16 14:09:12 +01:00
parent 501ce8c651
commit fbd26ceefa
14 changed files with 21 additions and 17 deletions

View File

@ -18,7 +18,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
for DIR in $(cat /etc/passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for DIR in $(get_db passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $DIR"
for FILE in $DIR/.[A-Za-z0-9]*; do
if [ ! -h "$FILE" -a -f "$FILE" ]; then
@ -42,7 +42,7 @@ audit () {
# This function will be called if the script status is on enabled mode
apply () {
for DIR in $(cat /etc/passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for DIR in $(get_db passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for FILE in $DIR/.[A-Za-z0-9]*; do
if [ ! -h "$FILE" -a -f "$FILE" ]; then
FILEPERM=$(ls -ld $FILE | cut -f1 -d" ")

View File

@ -19,7 +19,7 @@ FILENAME='.forward'
# This function will be called if the script status is on enabled / audit mode
audit () {
for DIR in $(cat /etc/passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for DIR in $(get_db passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $DIR"
for FILE in $DIR/$FILENAME; do
if [ ! -h "$FILE" -a -f "$FILE" ]; then

View File

@ -19,7 +19,7 @@ FILENAME='.netrc'
# This function will be called if the script status is on enabled / audit mode
audit () {
for DIR in $(cat /etc/passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for DIR in $(get_db passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $DIR"
for FILE in $DIR/$FILENAME; do
if [ ! -h "$FILE" -a -f "$FILE" ]; then

View File

@ -19,7 +19,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
for DIR in $(cat /etc/passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for DIR in $(get_db passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $DIR"
for FILE in $DIR/.netrc; do
if [ ! -h "$FILE" -a -f "$FILE" ]; then

View File

@ -19,7 +19,7 @@ FILENAME=".rhosts"
# This function will be called if the script status is on enabled / audit mode
audit () {
for DIR in $(cat /etc/passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for DIR in $(get_db passwd | egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $DIR"
for FILE in $DIR/$FILENAME; do
if [ ! -h "$FILE" -a -f "$FILE" ]; then

View File

@ -21,7 +21,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
RESULT=$(cut -f3 -d":" < /etc/passwd | sort -n | uniq -c | awk '{print $1":"$2}' )
RESULT=$(get_db passwd | cut -f3 -d":" | sort -n | uniq -c | awk '{print $1":"$2}' )
FOUND_EXCEPTIONS=""
for LINE in $RESULT; do
debug "Working on line $LINE"

View File

@ -20,7 +20,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
RESULT=$(cut -f3 -d":" /etc/group | sort -n | uniq -c | awk '{print $1":"$2}' )
RESULT=$(get_db group | cut -f3 -d":" | sort -n | uniq -c | awk '{print $1":"$2}' )
for LINE in $RESULT; do
debug "Working on line $LINE"
OCC_NUMBER=$(awk -F: '{print $1}' <<< "$LINE")

View File

@ -18,7 +18,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
RESULT=$(cat /etc/passwd | cut -f1 -d":" | sort -n | uniq -c | awk {'print $1":"$2'} )
RESULT=$(get_db passwd | cut -f1 -d":" | sort -n | uniq -c | awk {'print $1":"$2'} )
for LINE in $RESULT; do
debug "Working on line $LINE"
OCC_NUMBER=$(awk -F: {'print $1'} <<< $LINE)

View File

@ -18,7 +18,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
RESULT=$(cat /etc/group | cut -f1 -d":" | sort -n | uniq -c | awk {'print $1":"$2'} )
RESULT=$(get_db group | cut -f1 -d":" | sort -n | uniq -c | awk {'print $1":"$2'} )
for LINE in $RESULT; do
debug "Working on line $LINE"
OCC_NUMBER=$(awk -F: {'print $1'} <<< $LINE)

View File

@ -14,12 +14,11 @@ set -u # One variable unset, it's over
HARDENING_LEVEL=1
DESCRIPTION="Ensure password fields are not empty in /etc/shadow."
FILE='/etc/shadow'
# This function will be called if the script status is on enabled / audit mode
audit () {
info "Checking if accounts have an empty password"
RESULT=$($SUDO_CMD cat $FILE | awk -F: '($2 == "" ) { print $1 }')
RESULT=$(get_db shadow | awk -F: '($2 == "" ) { print $1 }')
if [ ! -z "$RESULT" ]; then
crit "Some accounts have an empty password"
crit $RESULT
@ -30,7 +29,7 @@ audit () {
# This function will be called if the script status is on enabled mode
apply () {
RESULT=$(cat $FILE | awk -F: '($2 == "" ) { print $1 }')
RESULT=$(get_db shadow | awk -F: '($2 == "" ) { print $1 }')
if [ ! -z "$RESULT" ]; then
warn "Some accounts have an empty password"
for ACCOUNT in $RESULT; do

View File

@ -18,7 +18,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
RESULT=$(cat /etc/passwd | awk -F: '{ print $1 ":" $3 ":" $6 }')
RESULT=$(get_db passwd | awk -F: '{ print $1 ":" $3 ":" $6 }')
for LINE in $RESULT; do
debug "Working on $LINE"
USER=$(awk -F: {'print $1'} <<< $LINE)

View File

@ -18,7 +18,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
for dir in $(cat /etc/passwd | /bin/egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for dir in $(get_db passwd | /bin/egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $dir"
debug "Exceptions : $EXCEPTIONS"
debug "echo \"$EXCEPTIONS\" | grep -q $dir"
@ -57,7 +57,7 @@ audit () {
# This function will be called if the script status is on enabled mode
apply () {
for dir in $(cat /etc/passwd | /bin/egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
for dir in $(get_db passwd | /bin/egrep -v '(root|halt|sync|shutdown)' | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/sbin/nologin" && $7 != "/bin/false" && $7 !="/nonexistent" ) { print $6 }'); do
debug "Working on $dir"
debug "Exceptions : $EXCEPTIONS"
debug "echo \"$EXCEPTIONS\" | grep -q $dir"

View File

@ -21,7 +21,7 @@ ERRORS=0
# This function will be called if the script status is on enabled / audit mode
audit () {
debug "Checking homedir exists"
RESULT=$(cat /etc/passwd | awk -F: '{ print $1 ":" $3 ":" $6 }')
RESULT=$(get_db passwd | awk -F: '{ print $1 ":" $3 ":" $6 }')
for LINE in $RESULT; do
debug "Working on $LINE"
USER=$(awk -F: {'print $1'} <<< $LINE)

View File

@ -126,6 +126,11 @@ _does_pattern_exist_in_file() {
fi
}
get_db() {
local DB="$1"
$SUDO_CMD getent --service files "$DB"
}
# Look for pattern in file that can spread over multiple lines
# The func will remove commented lines (that begin with '#')
# and consider the file as one long line.