1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
#!/bin/bash
# msec: system access
# check if we are run from main script
if [ -z "$MSEC_TMP" -o -z "$INFOS" -o -z "$SECURITY" -o -z "$DIFF" -o -z "$SECURITY_LOG" ]; then
# variables are set in security.sh and propagated to the subscripts
echo "Error: this check should be run by the main msec security check!"
echo " do not run it directly unless you know what you are doing."
return 1
fi
# check for changes in users
USERS_LIST_TODAY="/var/log/security/users_list.today"
USERS_LIST_YESTERDAY="/var/log/security/users_list.yesterday"
USERS_LIST_DIFF="/var/log/security/users_list.diff"
if [[ -f ${USERS_LIST_TODAY} ]]; then
mv ${USERS_LIST_TODAY} ${USERS_LIST_YESTERDAY};
fi
# check for changes in users
if [[ ${CHECK_USERS} == yes ]]; then
getent passwd | cut -f 1 -d : | sort > ${USERS_LIST_TODAY}
Diffcheck ${USERS_LIST_TODAY} ${USERS_LIST_YESTERDAY} ${USERS_LIST_DIFF} "local users"
Count ${INFOS} ${USERS_LIST_TODAY} "Total local users"
fi
# check for changes in groups
GROUPS_LIST_TODAY="/var/log/security/groups_list.today"
GROUPS_LIST_YESTERDAY="/var/log/security/groups_list.yesterday"
GROUPS_LIST_DIFF="/var/log/security/groups_list.diff"
if [[ -f ${GROUPS_LIST_TODAY} ]]; then
mv ${GROUPS_LIST_TODAY} ${GROUPS_LIST_YESTERDAY};
fi
# check for changes in groups
if [[ ${CHECK_GROUPS} == yes ]]; then
getent passwd | cut -f 1 -d : | sort > ${GROUPS_LIST_TODAY}
Diffcheck ${GROUPS_LIST_TODAY} ${GROUPS_LIST_YESTERDAY} ${GROUPS_LIST_DIFF} "local groups"
Count ${INFOS} ${GROUPS_LIST_TODAY} "Total local group"
fi
### Passwd file check
if [[ ${CHECK_PASSWD} == yes ]]; then
getent passwd | awk -F: '{
if ( $2 == "" )
printf("\t\t- /etc/passwd:%d: User \"%s\" has no password !\n", FNR, $1);
else if ($2 !~ /^[x*!]+$/)
printf("\t\t- /etc/passwd:%d: User \"%s\" has a real password (it is not shadowed).\n", FNR, $1);
else if ( $3 == 0 && $1 != "root" )
printf("\t\t- /etc/passwd:%d: User \"%s\" has id 0 !\n", FNR, $1);
}' > ${MSEC_TMP}
if [[ -s ${MSEC_TMP} ]]; then
printf "\nSecurity Warning: /etc/passwd check :\n" >> ${SECURITY}
cat ${MSEC_TMP} >> ${SECURITY}
Count ${INFOS} ${MSEC_TMP} "Issues found in /etc/passwd file"
fi
fi
### Shadow password file Check
if [[ ${CHECK_SHADOW} == yes ]]; then
awk -F: '{
if ( $2 == "" )
printf("\t\t- /etc/shadow:%d: User \"%s\" has no password !\n", FNR, $1);
}' < /etc/shadow > ${MSEC_TMP}
if [[ -s ${MSEC_TMP} ]]; then
printf "\nSecurity Warning: /etc/shadow check :\n" >> ${SECURITY}
cat ${MSEC_TMP} >> ${SECURITY}
Count ${INFOS} ${MSEC_TMP} "Issues found in /etc/shadow file"
fi
fi
### File systems should not be globally exported.
if [[ -s /etc/exports ]] ; then
awk '{
if (($1 ~ /^#/) || ($1 ~ /^$/)) next;
readonly = 0;
for (i = 2; i <= NF; ++i) {
if ($i ~ /^-ro$/)
readonly = 1;
else if ($i !~ /^-/)
next;
}
if (readonly) {
print "\t\t- Nfs File system " $1 " globally exported, read-only.";
} else print "\t\t- Nfs File system " $1 " globally exported, read-write.";
}' < /etc/exports > ${MSEC_TMP}
if [[ -s ${MSEC_TMP} ]] ; then
printf "\nSecurity Warning: Some NFS filesystem are exported globally :\n" >> ${SECURITY}
cat ${MSEC_TMP} >> ${SECURITY}
Count ${INFOS} ${MSEC_TMP} "Issues found in NFS exports"
fi
fi
### nfs mounts with missing nosuid
/bin/mount | /bin/grep -v nosuid | /bin/grep ' nfs ' > ${MSEC_TMP}
if [[ -s ${MSEC_TMP} ]] ; then
printf "\nSecurity Warning: The following NFS mounts haven't got the nosuid option set :\n" >> ${SECURITY}
cat ${MSEC_TMP} | awk '{ print "\t\t- "$0 }' >> ${SECURITY}
Count ${INFOS} ${MSEC_TMP} "Unsafe NFS exports"
fi
### Files that should not have + signs.
list="/etc/hosts.equiv /etc/shosts.equiv /etc/hosts.lpd"
for file in $list ; do
if [[ -s ${file} ]] ; then
awk '{
if ($0 ~ /^\+@.*$/)
next;
if ($0 ~ /^\+.*$/)
printf("\t\t- %s: %s\n", FILENAME, $0);
}' ${file}
fi
done > ${MSEC_TMP}
### Passwd file check
if [[ ${CHECK_SHOSTS} == yes ]]; then
getent passwd | awk -F: '{print $1" "$6}' |
while read username homedir; do
if ! expr "$homedir" : "$FILTER" > /dev/null; then
for file in .rhosts .shosts; do
if [[ -s ${homedir}/${file} ]] ; then
awk '{
if ($0 ~ /^\+@.*$/)
next;
if ($0 ~ /^\+.*$/)
printf("\t\t- %s: %s\n", FILENAME, $0);
}' ${homedir}/${file}
fi
done >> ${DIFF}
fi
done
if [[ -s ${MSEC_TMP} ]]; then
printf "\nSecurity Warning: '+' character found in hosts trusting files,\n" >> ${SECURITY}
printf "\tthis probably mean that you trust certains users/domain\n" >> ${SECURITY}
printf "\tto connect on this host without proper authentication :\n" >> ${SECURITY}
cat ${MSEC_TMP} >> ${SECURITY}
Count ${INFOS} ${MSEC_TMP} "Unsafe hosts trusting files"
fi
fi
### executables should not be in the aliases file.
list="/etc/aliases /etc/postfix/aliases"
for file in ${list}; do
if [[ -s ${file} ]]; then
grep -v '^#' ${file} | grep '|' | while read line; do
printf "\t\t- ${line}\n"
done > ${MSEC_TMP}
fi
if [[ -s ${MSEC_TMP} ]]; then
printf "\nSecurity Warning: The following programs are executed in your mail\n" >> ${SECURITY}
printf "\tvia ${file} files, this could lead to security problems :\n" >> ${SECURITY}
cat ${MSEC_TMP} >> ${SECURITY}
Count ${INFOS} ${MSEC_TMP} "Unsafe mail aliases"
fi
done
|