Advertisement
Guest User

Untitled

a guest
Dec 27th, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.00 KB | None | 0 0
  1. #!/bin/sh
  2. # unix-privesc-check - Checks Unix system for simple privilege escalations
  3. # Copyright (C) 2008 pentestmonkey@pentestmonkey.net
  4. #
  5. #
  6. # License
  7. # -------
  8. # This tool may be used for legal purposes only. Users take full responsibility
  9. # for any actions performed using this tool. The author accepts no liability
  10. # for damage caused by this tool. If you do not accept these condition then
  11. # you are prohibited from using this tool.
  12. #
  13. # In all other respects the GPL version 2 applies:
  14. #
  15. # This program is free software; you can redistribute it and/or modify
  16. # it under the terms of the GNU General Public License version 2 as
  17. # published by the Free Software Foundation.
  18. #
  19. # This program is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License along
  25. # with this program; if not, write to the Free Software Foundation, Inc.,
  26. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27. #
  28. # You are encouraged to send comments, improvements or suggestions to
  29. # me at pentestmonkey@pentestmonkey.net
  30. #
  31. #
  32. # Description
  33. # -----------
  34. # Auditing tool to check for weak file permissions and other problems that
  35. # may allow local attackers to escalate privileges.
  36. #
  37. # It is intended to be run by security auditors and pentetration testers
  38. # against systems they have been engaged to assess, and also by system
  39. # admnisitrators who want to check for "obvious" misconfigurations. It
  40. # can even be run as a cron job so you can check regularly for misconfigurations
  41. # that might be introduced.
  42. #
  43. # Ensure that you have the appropriate legal permission before running it
  44. # someone else's system.
  45. #
  46. # TODO List
  47. # ---------
  48. # There's still plenty that this script doesn't do...
  49. # - Doesn't work for shell scripts! These appear as "/bin/sh my.sh" in the process listing.
  50. # This script only checks the perms of /bin/sh. Not what we're after. :-(
  51. # - Similarly for perl scripts. Probably python, etc. too.
  52. # - Check /proc/pid/cmdline for absolute path names. Check security of these (e.g. /etc/snmp/snmpd.conf)
  53. # - Check everything in root's path - how to find root's path?
  54. # - /proc/pid/maps, smaps are readable and lists some shared objects. We should check these.
  55. # - /proc/pid/fd contain symlinks to all open files (but you can't see other people FDs)
  56. # - check for trust relationships in /etc/hosts.equiv
  57. # - NFS imports / exports / automounter
  58. # - Insecure stuff in /etc/fstab (e.g. allowing users to mount file systems)
  59. # - Inspecting people's PATH. tricky. maybe read from /proc/pid/environ, .bashrc, /etc/profile, .bash_profile
  60. # - Check if /etc/init.d/* scripts are readable. Advise user to audit them if they are.
  61. # - .exrc?
  62. # - X11 trusts, apache passwd files, mysql trusts?
  63. # - Daemons configured in an insecure way: tftpd, sadmind, rexd
  64. # - World writable dirs aren't as bad if the sticky bit is set. Check for this before reporting vulns.
  65. # - Maybe do a strings of binaries (and their .so's?)
  66. # - Do a better job of parsing cron lines - search for full paths
  67. # - Maybe LDPATHs from /etc/env.d
  68. # - Check if ldd, ld.so.conf changes have broken this script on non-linux systems.
  69. # - Avoid check certain paths e.g. /-/_ clearly isn't a real directory.
  70. # - create some sort of readable report
  71. # - indicate when it's likely a result is a false positive and when it's not.
  72. # - Skip pseudo processes e.g. [usb-storage]
  73. # - File permission on kernel modules
  74. # - Replace calls to echo with a my_echo func. Should be passed a string and an "importance" value:
  75. # - my_echo 1 "This is important and should always be printed out"
  76. # - my_echo 2 "This is less important and should only be printed in verbose mode"
  77. # - We check some files / dirs multiple times. Slow. Can we implement a cache?
  78. # - grep for PRIVATE KEY to find private ssh and ssl keys. Where to grep?
  79. # - check SGID programs
  80.  
  81. VERSION="1.4"
  82. HOME_DIR_FILES=".netrc .ssh/id_rsa .ssh/id_dsa .rhosts .shosts .my.cnf .ssh/authorized_keys .bash_history .sh_history .forward"
  83. CONFIG_FILES="/etc/passwd /etc/group /etc/master.passwd /etc/inittab /etc/inetd.conf /etc/xinetd.con /etc/xinetd.d/* /etc/contab /etc/fstab /etc/profile /etc/sudoers"
  84. PGDIRS="/usr/local/pgsql/data ~postgres/postgresql/data ~postgres/data ~pgsql/data ~pgsql/pgsql/data /var/lib/postgresql/data /etc/postgresql/8.2/main /var/lib/pgsql/data"
  85.  
  86. get_owner () {
  87. GET_OWNER_FILE=$1
  88. GET_OWNER_RETURN=`ls -lLd "$GET_OWNER_FILE" | awk '{print $3}'`
  89. }
  90.  
  91. get_group () {
  92. GET_GROUP_FILE=$1
  93. GET_GROUP_RETURN=`ls -lLd "$GET_GROUP_FILE" | awk '{print $4}'`
  94. }
  95.  
  96. usage () {
  97. echo "unix-privesc-check v$VERSION ( http://pentestmonkey.net/tools/unix-privesc-check )"
  98. echo
  99. echo "Usage: unix-privesc-check { standard | detailed }"
  100. echo
  101. echo '"standard" mode: Speed-optimised check of lots of security settings.'
  102. echo
  103. echo '"detailed" mode: Same as standard mode, but also checks perms of open file'
  104. echo ' handles and called files (e.g. parsed from shell scripts,'
  105. echo ' linked .so files). This mode is slow and prone to false '
  106. echo ' positives but might help you find more subtle flaws in 3rd'
  107. echo ' party programs.'
  108. echo
  109. echo "This script checks file permissions and other settings that could allow"
  110. echo "local users to escalate privileges."
  111. echo
  112. echo "Use of this script is only permitted on systems which you have been granted"
  113. echo "legal permission to perform a security assessment of. Apart from this "
  114. echo "condition the GPL v2 applies."
  115. echo
  116. echo "Search the output for the word 'WARNING'. If you don't see it then this"
  117. echo "script didn't find any problems."
  118. echo
  119. }
  120.  
  121. banner () {
  122. echo "Starting unix-privesc-check v$VERSION ( http://pentestmonkey.net/tools/unix-privesc-check )"
  123. echo
  124. echo "This script checks file permissions and other settings that could allow"
  125. echo "local users to escalate privileges."
  126. echo
  127. echo "Use of this script is only permitted on systems which you have been granted"
  128. echo "legal permission to perform a security assessment of. Apart from this "
  129. echo "condition the GPL v2 applies."
  130. echo
  131. echo "Search the output below for the word 'WARNING'. If you don't see it then"
  132. echo "this script didn't find any problems."
  133. echo
  134. }
  135.  
  136. MODE=$1
  137.  
  138. if [ ! "$MODE" = "standard" ] && [ ! "$MODE" = "detailed" ]; then
  139. usage
  140. exit 0
  141. fi
  142.  
  143. # Parse any full paths from $1 (config files, progs, dirs).
  144. # Check the permissions on each of these.
  145. check_called_programs () {
  146. CCP_MESSAGE_STACK=$1
  147. CCP_FILE=$2
  148. CCP_USER=$3
  149. CCP_PATH=$4 # optional
  150.  
  151. # Check the perms of the supplied file regardless
  152. # The caller doesn't want to have to call check_perms as well as check_called_programs
  153. check_perms "$CCP_MESSAGE_STACK" "$CCP_FILE" "$CCP_USER" "$CCP_PATH"
  154.  
  155. # Skip the slow check if we're in quick mode
  156. if [ "$MODE" = "standard" ]; then
  157. return 0;
  158. fi
  159.  
  160. # Check if file is text or not
  161. IS_TEXT=`file "$CCP_FILE" | grep -i text`
  162. IS_DYNBIN=`file "$CCP_FILE" | grep -i 'dynamically linked'`
  163.  
  164. # Process shell scripts (would also work on config files that reference other files)
  165. if [ ! -z "$IS_TEXT" ]; then
  166. # Parse full paths from file - ignoring commented lines
  167. CALLED_FILES=`grep -v '^#' "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u`
  168. for CALLED_FILE in $CALLED_FILES; do
  169. # echo "$CCP_FILE contains a reference to $CALLED_FILE. Checking perms."
  170. check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH"
  171. done
  172. else
  173. # Process dynamically linked binaries
  174. if [ ! -z "$IS_DYNBIN" ]; then
  175.  
  176. CALLED_FILES=`ldd "$CCP_FILE" 2>/dev/null | grep '/' | sed 's/[^\/]*\//\//' | cut -f 1 -d ' '`
  177. for CALLED_FILE in $CALLED_FILES; do
  178. check_perms "$CCP_MESSAGE_STACK $CCP_FILE uses the library $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH"
  179. done
  180.  
  181. # Strings binary to look for hard-coded config files
  182. # or other programs that might be called.
  183. for CALLED_FILE in `strings "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u`; do
  184. check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH"
  185. done
  186. fi
  187. fi
  188. }
  189.  
  190. # Parse any full paths from $1 (config files, progs, dirs).
  191. # Check the permissions on each of these.
  192. check_called_programs_suid () {
  193. CCP_FILE=$1
  194. CCP_PATH=$2 # optional
  195.  
  196. get_owner $CCP_FILE; CCP_USER=$GET_OWNER_RETURN
  197. CCP_MESSAGE_STACK="$CCP_FILE is SUID $CCP_USER."
  198. LS=`ls -l $CCP_FILE`
  199. echo "Checking SUID-$CCP_USER program $CCP_FILE: $LS"
  200.  
  201. # Don't check perms of executable itself
  202. # check_perms "$CCP_MESSAGE_STACK" "$CCP_FILE" "$CCP_USER" "$CCP_PATH"
  203.  
  204. # Check if file is text or not
  205. IS_TEXT=`file "$CCP_FILE" | grep -i text`
  206. IS_DYNBIN=`file "$CCP_FILE" | grep -i 'dynamically linked'`
  207.  
  208. # Process shell scripts (would also work on config files that reference other files)
  209. if [ ! -z "$IS_TEXT" ]; then
  210. # Skip the slow check if we're in quick mode
  211. if [ "$MODE" = "standard" ]; then
  212. return 0;
  213. fi
  214.  
  215. # Parse full paths from file - ignoring commented lines
  216. CALLED_FILES=`grep -v '^#' "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u`
  217. for CALLED_FILE in $CALLED_FILES; do
  218. # echo "$CCP_FILE contains a reference to $CALLED_FILE. Checking perms."
  219. check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH"
  220. done
  221. else
  222. # Process dynamically linked binaries
  223. if [ ! -z "$IS_DYNBIN" ]; then
  224.  
  225. CALLED_FILES=`ldd "$CCP_FILE" 2>/dev/null | grep '/' | sed 's/[^\/]*\//\//' | cut -f 1 -d ' '`
  226. for CALLED_FILE in $CALLED_FILES; do
  227. check_perms "$CCP_MESSAGE_STACK $CCP_FILE uses the library $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH"
  228. done
  229.  
  230. # Skip the slow check if we're in quick mode
  231. if [ "$MODE" = "standard" ]; then
  232. return 0;
  233. fi
  234.  
  235. # Strings binary to look for hard-coded config files
  236. # or other programs that might be called.
  237. for CALLED_FILE in `strings "$CCP_FILE" | sed -e 's/^[^\/]*//' -e 's/["'\'':}$]/\x0a/g' | grep '/' | sed -e 's/[ \*].*//' | grep '^/[a-zA-Z0-9_/-]*$' | sort -u`; do
  238. check_perms "$CCP_MESSAGE_STACK $CCP_FILE contains the string $CALLED_FILE." "$CALLED_FILE" "$CCP_USER" "$CCP_PATH"
  239. done
  240. fi
  241. fi
  242. }
  243.  
  244. # Check if $1 can be changed by users who are not $2
  245. check_perms () {
  246. CP_MESSAGE_STACK=$1
  247. CHECK_PERMS_FILE=$2
  248. CHECK_PERMS_USER=$3
  249. CHECK_PERMS_PATH=$4 # optional
  250.  
  251. if [ ! -f "$CHECK_PERMS_FILE" ] && [ ! -d "$CHECK_PERMS_FILE" ] && [ ! -b "$CHECK_PERMS_FILE" ]; then
  252. CHECK_PERMS_FOUND=0
  253. if [ ! -z "$CHECK_PERMS_PATH" ]; then
  254. # Look for it in the supplied path
  255. for DIR in `echo "$CHECK_PERMS_PATH" | sed 's/:/ /g'`; do
  256. if [ -f "$DIR/$CHECK_PERMS_FILE" ]; then
  257. CHECK_PERMS_FOUND=1
  258. CHECK_PERMS_FILE="$DIR/$CHECK_PERMS_FILE"
  259. break
  260. fi
  261. done
  262. fi
  263.  
  264. #if [ "$CHECK_PERMS_FOUND" = "0" ]; then
  265. # echo "ERROR: File $CHECK_PERMS_FILE doesn't exist. Checking parent path anyway."
  266. # # return 0
  267. # fi
  268. fi
  269.  
  270. C=`echo "$CHECK_PERMS_FILE" | cut -c 1`
  271. if [ ! "$C" = "/" ]; then
  272. echo "ERROR: Can't find absolute path for $CHECK_PERMS_FILE. Skipping."
  273. return 0
  274. fi
  275.  
  276. echo " Checking if anyone except $CHECK_PERMS_USER can change $CHECK_PERMS_FILE"
  277.  
  278. while [ -n "$CHECK_PERMS_FILE" ]; do
  279. perms_secure "$CP_MESSAGE_STACK" $CHECK_PERMS_FILE $CHECK_PERMS_USER
  280. CHECK_PERMS_FILE=`echo $CHECK_PERMS_FILE | sed 's/\/[^\/]*$//'`
  281. done
  282. }
  283.  
  284. # Check if $1 can be read by users who are not $2
  285. check_read_perms () {
  286. CP_MESSAGE_STACK=$1
  287. CHECK_PERMS_FILE=$2
  288. CHECK_PERMS_USER=$3
  289.  
  290. if [ ! -f "$CHECK_PERMS_FILE" ] && [ ! -b "$CHECK_PERMS_FILE" ]; then
  291. echo "ERROR: File $CHECK_PERMS_FILE doesn't exist"
  292. return 0
  293. fi
  294.  
  295. echo " Checking if anyone except $CHECK_PERMS_USER can read file $CHECK_PERMS_FILE"
  296.  
  297. perms_secure_read "$CP_MESSAGE_STACK" "$CHECK_PERMS_FILE" "$CHECK_PERMS_USER"
  298. }
  299.  
  300. perms_secure_read () {
  301. PS_MESSAGE_STACK=$1
  302. PERMS_SECURE_FILE=$2
  303. PERMS_SECURE_USER=$3
  304.  
  305. if [ ! -b "$PERMS_SECURE_FILE" ] && [ ! -f "$PERMS_SECURE_FILE" ] && [ ! -d "$PERMS_SECURE_FILE" ]; then
  306. echo "ERROR: No such file or directory: $PERMS_SECURE_FILE. Skipping."
  307. return 0
  308. fi
  309.  
  310. # Check if owner is different (but ignore root ownership, that's OK)
  311. only_user_can_read "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER
  312.  
  313. # Check group read perm (but ignore root group, that's OK)
  314. group_can_read "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER
  315.  
  316. # Check world read perm
  317. world_can_read "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE
  318. }
  319.  
  320. perms_secure () {
  321. PS_MESSAGE_STACK=$1
  322. PERMS_SECURE_FILE=$2
  323. PERMS_SECURE_USER=$3
  324.  
  325. if [ ! -d "$PERMS_SECURE_FILE" ] && [ ! -f "$PERMS_SECURE_FILE" ] && [ ! -b "$PERMS_SECURE_FILE" ]; then
  326. # echo "ERROR: No such file or directory: $PERMS_SECURE_FILE. Skipping."
  327. return 0
  328. fi
  329.  
  330. # Check if owner is different (but ignore root ownership, that's OK)
  331. only_user_can_write "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER
  332.  
  333. # Check group write perm (but ignore root group, that's OK)
  334. group_can_write "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE $PERMS_SECURE_USER
  335.  
  336. # Check world write perm
  337. world_can_write "$PS_MESSAGE_STACK" $PERMS_SECURE_FILE
  338. }
  339.  
  340. only_user_can_write () {
  341. O_MESSAGE_STACK=$1
  342. O_FILE=$2
  343. O_USER=$3
  344.  
  345. # We just need to check the owner really as the owner
  346. # can always grant themselves write access
  347. get_owner $O_FILE; O_FILE_USER=$GET_OWNER_RETURN
  348. if [ ! "$O_USER" = "$O_FILE_USER" ] && [ ! "$O_FILE_USER" = "root" ]; then
  349. echo "WARNING: $O_MESSAGE_STACK The user $O_FILE_USER can write to $O_FILE"
  350. fi
  351. }
  352.  
  353. group_can_write () {
  354. O_MESSAGE_STACK=$1
  355. O_FILE=$2
  356. O_USER=$3 # ignore group write access $3 is only member of group
  357.  
  358. get_group $O_FILE; O_FILE_GROUP=$GET_GROUP_RETURN
  359. P=`ls -lLd $O_FILE | cut -c 6`
  360. if [ "$P" = "w" ] && [ ! "$O_GROUP" = "root" ]; then
  361. # check the group actually has some members other than $O_USER
  362. group_has_other_members "$O_FILE_GROUP" "$O_USER"; # sets OTHER_MEMBERS to 1 or 0
  363. if [ "$OTHER_MEMBERS" = "1" ]; then
  364. echo "WARNING: $O_MESSAGE_STACK The group $O_FILE_GROUP can write to $O_FILE"
  365. fi
  366. fi
  367. }
  368.  
  369. group_has_other_members () {
  370. G_GROUP=$1
  371. G_USER=$2
  372.  
  373. # If LDAP/NIS is being used this script can't check group memberships
  374. # we therefore assume the worst.
  375. if [ "$EXT_AUTH" = 1 ]; then
  376. OTHER_MEMBERS=1
  377. return 1
  378. fi
  379.  
  380. GROUP_LINE=`grep "^$G_GROUP:" /etc/group`
  381. MEMBERS=`echo "$GROUP_LINE" | cut -f 4 -d : | sed 's/,/ /g'`
  382.  
  383. GID=`echo "$GROUP_LINE" | cut -f 3 -d :`
  384. EXTRA_MEMBERS=`grep "^[^:]*:[^:]*:[0-9]*:$GID:" /etc/passwd | cut -f 1 -d : | xargs echo`
  385.  
  386. for M in $MEMBERS; do
  387. if [ ! "$M" = "$G_USER" ] && [ ! "$M" = "root" ]; then
  388. OTHER_MEMBERS=1
  389. return 1
  390. fi
  391. done
  392.  
  393. for M in $EXTRA_MEMBERS; do
  394. if [ ! "$M" = "$G_USER" ] && [ ! "$M" = "root" ]; then
  395. OTHER_MEMBERS=1
  396. return 1
  397. fi
  398. done
  399.  
  400. OTHER_MEMBERS=0
  401. return 0
  402. }
  403.  
  404. world_can_write () {
  405. O_MESSAGE_STACK=$1
  406. O_FILE=$2
  407.  
  408. P=`ls -lLd $O_FILE | cut -c 9`
  409. S=`ls -lLd $O_FILE | cut -c 10`
  410.  
  411. if [ "$P" = "w" ]; then
  412. if [ "$S" = "t" ]; then
  413. echo "WARNING: $O_MESSAGE_STACK World write is set for $O_FILE (but sticky bit set)"
  414. else
  415. echo "WARNING: $O_MESSAGE_STACK World write is set for $O_FILE"
  416. fi
  417. fi
  418. }
  419.  
  420. only_user_can_read () {
  421. O_MESSAGE_STACK=$1
  422. O_FILE=$2
  423. O_USER=$3
  424.  
  425. # We just need to check the owner really as the owner
  426. # can always grant themselves read access
  427. get_owner $O_FILE; O_FILE_USER=$GET_OWNER_RETURN
  428. if [ ! "$O_USER" = "$O_FILE_USER" ] && [ ! "$O_FILE_USER" = "root" ]; then
  429. echo "WARNING: $O_MESSAGE_STACK The user $O_FILE_USER can read $O_FILE"
  430. fi
  431. }
  432.  
  433. group_can_read () {
  434. O_MESSAGE_STACK=$1
  435. O_FILE=$2
  436. O_USER=$3
  437.  
  438. get_group $O_FILE; O_FILE_GROUP=$GET_GROUP_RETURN
  439. P=`ls -lLd $O_FILE | cut -c 5`
  440. if [ "$P" = "r" ] && [ ! "$O_GROUP" = "root" ]; then
  441. # check the group actually has some members other than $O_USER
  442. group_has_other_members "$O_FILE_GROUP" "$O_USER"; # sets OTHER_MEMBERS to 1 or 0
  443. if [ "$OTHER_MEMBERS" = "1" ]; then
  444. echo "WARNING: $O_MESSAGE_STACK The group $O_FILE_GROUP can read $O_FILE"
  445. fi
  446. fi
  447. }
  448.  
  449. world_can_read () {
  450. O_MESSAGE_STACK=$1
  451. O_FILE=$2
  452.  
  453. P=`ls -lLd $O_FILE | cut -c 8`
  454.  
  455. if [ "$P" = "w" ]; then
  456. echo "WARNING: $O_MESSAGE_STACK World read is set for $O_FILE"
  457. fi
  458. }
  459.  
  460. section () {
  461. echo
  462. echo '############################################'
  463. echo $1
  464. echo '############################################'
  465. }
  466.  
  467. # Guess OS
  468. if [ -x /usr/bin/showrev ]; then
  469. OS="solaris"
  470. SHADOW="/etc/shadow"
  471. elif [ -x /usr/sbin/sam -o -x /usr/bin/sam ]; then
  472. OS="hpux"
  473. SHADOW="/etc/shadow"
  474. elif [ -f /etc/master.passwd ]; then
  475. OS="bsd"
  476. SHADOW="/etc/master.passwd"
  477. else
  478. OS="linux"
  479. SHADOW="/etc/shadow"
  480. fi
  481. echo "Assuming the OS is: $OS"
  482. CONFIG_FILES="$CONFIG_FILES $SHADOW"
  483.  
  484. # Set path so we can access usual directories. HPUX and some linuxes don't have sbin in the path.
  485. PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin; export PATH
  486.  
  487. # Check dependent programs are installed
  488. # Assume "which" is installed!
  489. PROGS="ls awk grep cat mount xargs file ldd strings"
  490. for PROG in $PROGS; do
  491. which $PROG 2>&1 > /dev/null
  492. if [ ! $? = "0" ]; then
  493. echo "ERROR: Dependend program '$PROG' is mising. Can't run. Sorry!"
  494. exit 1
  495. fi
  496. done
  497.  
  498. banner
  499.  
  500. section "Recording hostname"
  501. hostname
  502.  
  503. section "Recording uname"
  504. uname -a
  505.  
  506. section "Recording Interface IP addresses"
  507. if [ $OS = 'hpux' ]; then
  508. for IFACE in `lanscan | grep x | awk '{print $5}' 2>/dev/null`; do
  509. ifconfig $IFACE 2>/dev/null
  510. done
  511. else
  512. ifconfig -a
  513. fi
  514.  
  515. section "Checking if external authentication is allowed in /etc/passwd"
  516. FLAG=`grep '^+:' /etc/passwd`
  517. if [ -n "$FLAG" ]; then
  518. echo "WARNING: /etc/passwd allows external authentcation:"
  519. grep '^+:' /etc/passwd
  520. EXT_AUTH=1
  521. else
  522. echo "No +:... line found in /etc/passwd"
  523. fi
  524.  
  525. section "Checking nsswitch.conf for addition authentication methods"
  526. if [ -r "/etc/nsswitch.conf" ]; then
  527. NIS=`grep '^passwd' /etc/nsswitch.conf | grep 'nis'`
  528. if [ -n "$NIS" ]; then
  529. echo "WARNING: NIS is used for authentication on this system"
  530. EXT_AUTH=1
  531. fi
  532. LDAP=`grep '^passwd' /etc/nsswitch.conf | grep 'ldap'`
  533. if [ -n "$LDAP" ]; then
  534. echo "WARNING: LDAP is used for authentication on this system"
  535. EXT_AUTH=1
  536. fi
  537.  
  538. if [ -z "$NIS" ] && [ -z "$LDAP" ]; then
  539. echo "Neither LDAP nor NIS are used for authentication"
  540. fi
  541. else
  542. echo "ERROR: File /etc/nsswitch.conf isn't readable. Skipping checks."
  543. fi
  544.  
  545. # Check important config files aren't writable
  546. section "Checking for writable config files"
  547. for FILE in $CONFIG_FILES; do
  548. if [ -f "$FILE" ]; then
  549. check_perms "$FILE is a critical config file." "$FILE" root
  550. fi
  551. done
  552.  
  553. section "Checking if $SHADOW is readable"
  554. check_read_perms "/etc/shadow holds authentication data" $SHADOW root
  555.  
  556. section "Checking for password hashes in /etc/passwd"
  557. FLAG=`grep -v '^[^:]*:[x\*]*:' /etc/passwd | grep -v '^#'`
  558. if [ -n "$FLAG" ]; then
  559. echo "WARNING: There seem to be some password hashes in /etc/passwd"
  560. grep -v '^[^:]*:[x\*]*:' /etc/passwd | grep -v '^#'
  561. EXT_AUTH=1
  562. else
  563. echo "No password hashes found in /etc/passwd"
  564. fi
  565.  
  566. section "Checking account settings"
  567. # Check for something nasty like r00t::0:0::/:/bin/sh in /etc/passwd
  568. # We only need read access to /etc/passwd to be able to check this.
  569. if [ -r "/etc/passwd" ]; then
  570. OPEN=`grep "^[^:][^:]*::" /etc/passwd | cut -f 1 -d ":"`
  571. if [ -n "$OPEN" ]; then
  572. echo "WARNING: The following accounts have no password:"
  573. grep "^[^:][^:]*::" /etc/passwd | cut -f 1 -d ":"
  574. fi
  575. fi
  576. if [ -r "$SHADOW" ]; then
  577. echo "Checking for accounts with no passwords"
  578. if [ "$OS" = "linux" ]; then
  579. passwd -S -a | while read LINE
  580. do
  581. USER=`echo "$LINE" | awk '{print $1}'`
  582. STATUS=`echo "$LINE" | awk '{print $2}'`
  583. if [ "$STATUS" = "NP" ]; then
  584. echo "WARNING: User $USER doesn't have a password"
  585. fi
  586. done
  587. elif [ "$OS" = "solaris" ]; then
  588. passwd -s -a | while read LINE
  589. do
  590. USER=`echo "$LINE" | awk '{print $1}'`
  591. STATUS=`echo "$LINE" | awk '{print $2}'`
  592. if [ "$STATUS" = "NP" ]; then
  593. echo "WARNING: User $USER doesn't have a password"
  594. fi
  595. done
  596. fi
  597. else
  598. echo "File $SHADOW isn't readable. Skipping some checks."
  599. fi
  600.  
  601. section "Checking library directories from /etc/ld.so.conf"
  602. if [ -f "/etc/ld.so.conf" ] && [ -r "/etc/ld.so.conf" ]; then
  603. for DIR in `grep '^/' /etc/ld.so.conf`; do
  604. check_perms "$DIR is in /etc/ld.so.conf." $DIR root
  605. done
  606.  
  607. #FILES=`grep '^include' /etc/ld.so.conf | sed 's/^include *//'`
  608. #if [ ! -z "$FILES" ]; then
  609. # for DIR in `echo $FILES | xargs cat | sort -u`; do
  610. # done
  611. #fi
  612. else
  613. echo "File /etc/ld.so.conf not present. Skipping checks."
  614. fi
  615.  
  616. # Check sudoers if we have permission - needs root normally
  617. section "Checking sudo configuration"
  618. if [ -f "/etc/sudoers" ] && [ -r "/etc/sudoers" ]; then
  619. echo -----------------
  620. echo "Checking if sudo is configured"
  621. SUDO_USERS=`grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep -v '^[ \t]*Default' | grep =`
  622. if [ ! -z "$SUDO_USERS" ]; then
  623. echo "WARNING: Sudo is configured. Manually check nothing unsafe is allowed:"
  624. grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep = | grep -v '^[ \t]*Default'
  625. fi
  626.  
  627. echo -----------------
  628. echo "Checking sudo users need a password"
  629. SUDO_NOPASSWD=`grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep NOPASSWD`
  630. if [ ! -z "$SUDO_NOPASSWD" ]; then
  631. echo "WARNING: Some users can use sudo without a password:"
  632. grep -v '^#' /etc/sudoers | grep -v '^[ \t]*$' | grep NOPASSWD
  633. fi
  634. else
  635. echo "File /etc/sudoers not present. Skipping checks."
  636. fi
  637.  
  638. section "Checking permissions on swap file(s)"
  639. for SWAP in `swapon -s | grep -v '^Filename' | cut -f 1 -d ' '`; do
  640. check_perms "$SWAP is used for swap space." $SWAP root
  641. check_read_perms "$SWAP is used for swap space." $SWAP root
  642. done
  643.  
  644. section "Checking programs run from inittab"
  645. if [ -f "/etc/inittab" ] && [ -r "/etc/inittab" ]; then
  646. for FILE in `cat /etc/inittab | grep : | grep -v '^#' | cut -f 4 -d : | grep '/' | cut -f 1 -d ' ' | sort -u`; do
  647. check_called_programs "$FILE is run from /etc/inittab as root." $FILE root
  648. done
  649. else
  650. echo "File /etc/inittab not present. Skipping checks."
  651. fi
  652.  
  653. section "Checking postgres trust relationships"
  654. for DIR in $PGDIRS; do
  655. if [ -d "$DIR" ] && [ -r "$DIR/pg_hba.conf" ]; then
  656. grep -v '^#' "$DIR/pg_hba.conf" | grep -v '^[ \t]*$' | while read LINE
  657. do
  658. AUTH=`echo "$LINE" | awk '{print $NF}'`
  659. if [ "$AUTH" = "trust" ]; then
  660. PGTRUST=1
  661. echo "WARNING: Postgres trust configured in $DIR/pg_hba.conf: $LINE"
  662. fi
  663. done
  664. fi
  665. done
  666.  
  667. PGVER1=`psql -U postgres template1 -c 'select version()' 2>/dev/null | grep version`
  668.  
  669. if [ -n "$PGVER1" ]; then
  670. PGTRUST=1
  671. echo "WARNING: Can connect to local postgres database as \"postgres\" without a password"
  672. fi
  673.  
  674. PGVER2=`psql -U pgsql template1 -c 'select version()' 2>/dev/null | grep version`
  675.  
  676. if [ -n "$PGVER2" ]; then
  677. PGTRUST=1
  678. echo "WARNING: Can connect to local postgres database as \"pgsql\" without a password"
  679. fi
  680.  
  681. if [ -z "$PGTRUST" ]; then
  682. echo "No postgres trusts detected"
  683. fi
  684.  
  685. # Check device files for mounted file systems are secure
  686. # cat /proc/mounts | while read LINE # Doesn't work so well when LVM is used - need to be root
  687. section "Checking permissions on device files for mounted partitions"
  688. if [ "$OS" = "linux" ]; then
  689. mount | while read LINE
  690. do
  691. DEVICE=`echo "$LINE" | awk '{print $1}'`
  692. FS=`echo "$LINE" | awk '{print $5}'`
  693. if [ "$FS" = "ext2" ] || [ "$FS" = "ext3" ] ||[ "$FS" = "reiserfs" ]; then
  694. echo "Checking device $DEVICE"
  695. check_perms "$DEVICE is a mounted file system." $DEVICE root
  696. fi
  697. done
  698. elif [ "$OS" = "bsd" ]; then
  699. mount | grep ufs | while read LINE
  700. do
  701. DEVICE=`echo "$LINE" | awk '{print $1}'`
  702. echo "Checking device $DEVICE"
  703. check_perms "$DEVICE is a mounted file system." $DEVICE root
  704. done
  705. elif [ "$OS" = "solaris" ]; then
  706. mount | grep xattr | while read LINE
  707. do
  708. DEVICE=`echo "$LINE" | awk '{print $3}'`
  709. if [ ! "$DEVICE" = "swap" ]; then
  710. echo "Checking device $DEVICE"
  711. check_perms "$DEVICE is a mounted file system." $DEVICE root
  712. fi
  713. done
  714. elif [ "$OS" = "hpux" ]; then
  715. mount | while read LINE
  716. do
  717. DEVICE=`echo "$LINE" | awk '{print $3}'`
  718. C=`echo $DEVICE | cut -c 1`
  719. if [ "$C" = "/" ]; then
  720. echo "Checking device $DEVICE"
  721. check_perms "$DEVICE is a mounted file system." $DEVICE root
  722. fi
  723. done
  724.  
  725. NFS=`mount | grep NFS`
  726. if [ -n "$NFS" ]; then
  727. echo "WARNING: This system is an NFS client. Check for nosuid and nodev options."
  728. mount | grep NFS
  729. fi
  730. fi
  731.  
  732. # Check cron jobs if they're readable
  733. # TODO check that cron is actually running
  734. section "Checking cron job programs aren't writable (/etc/crontab)"
  735. CRONDIRS=""
  736. if [ -f "/etc/crontab" ] && [ -r "/etc/crontab" ]; then
  737. MYPATH=`grep '^PATH=' /etc/crontab | cut -f 2 -d = `
  738. echo Crontab path is $MYPATH
  739.  
  740. # Check if /etc/cron.(hourly|daily|weekly|monthly) are being used
  741. CRONDIRS=`grep -v '^#' /etc/crontab | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | grep run-crons`
  742.  
  743. # Process run-parts
  744. grep -v '^#' /etc/crontab | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | grep run-parts | while read LINE
  745. do
  746. echo "Processing crontab run-parts entry: $LINE"
  747. USER=`echo "$LINE" | awk '{print $6}'`
  748. DIR=`echo "$LINE" | sed 's/.*run-parts[^()&|;\/]*\(\/[^ ]*\).*/\1/'`
  749. check_perms "$DIR holds cron jobs which are run as $USER." "$DIR" "$USER"
  750. if [ -d "$DIR" ]; then
  751. echo " Checking directory: $DIR"
  752. for FILE in $DIR/*; do
  753. FILENAME=`echo "$FILE" | sed 's/.*\///'`
  754. if [ "$FILENAME" = "*" ]; then
  755. echo " No files in this directory."
  756. continue
  757. fi
  758. check_called_programs "$FILE is run by cron as $USER." "$FILE" "$USER"
  759. done
  760. fi
  761. done
  762.  
  763. # TODO bsd'd periodic:
  764. # 1 3 * * * root periodic daily
  765. # 15 4 * * 6 root periodic weekly
  766. # 30 5 1 * * root periodic monthly
  767.  
  768. grep -v '^#' /etc/crontab | grep -v '^[ ]*$' | grep '[ ][^ ][^ ]*[ ][ ]*' | while read LINE
  769. do
  770. echo "Processing crontab entry: $LINE"
  771. USER=`echo "$LINE" | awk '{print $6}'`
  772. PROG=`echo "$LINE" | awk '{print $7}'`
  773. check_called_programs "$PROG is run from crontab as $USER." $PROG $USER $MYPATH
  774. done
  775. else
  776. echo "File /etc/crontab not present. Skipping checks."
  777. fi
  778.  
  779. # Do this if run-crons is run from /etc/crontab
  780. if [ -n "$CRONDIRS" ]; then
  781. USER=`echo "$CRONDIRS" | awk '{print $6}'`
  782. section "Checking /etc/cron.(hourly|daily|weekly|monthly)"
  783. for DIR in hourly daily weekly monthly; do
  784. if [ -d "/etc/cron.$DIR" ]; then
  785. echo " Checking directory: /etc/cron.$DIR"
  786. for FILE in /etc/cron.$DIR/*; do
  787. FILENAME=`echo "$FILE" | sed 's/.*\///'`
  788. if [ "$FILENAME" = "*" ]; then
  789. echo "No files in this directory."
  790. continue
  791. fi
  792. check_called_programs "$FILE is run via cron as $USER." "$FILE" $USER
  793. done
  794. fi
  795. done
  796. fi
  797.  
  798. section "Checking cron job programs aren't writable (/var/spool/cron/crontabs)"
  799. if [ -d "/var/spool/cron/crontabs" ]; then
  800. for FILE in /var/spool/cron/crontabs/*; do
  801. USER=`echo "$FILE" | sed 's/^.*\///'`
  802. if [ "$USER" = "*" ]; then
  803. echo "No user crontabs found in /var/spool/cron/crontabs. Skipping checks."
  804. continue
  805. fi
  806. echo "Processing crontab for $USER: $FILE"
  807. if [ -r "$FILE" ]; then
  808. MYPATH=`grep '^PATH=' "$FILE" | cut -f 2 -d = `
  809. if [ -n "$MYPATH" ]; then
  810. echo Crontab path is $MYPATH
  811. fi
  812. grep -v '^#' "$FILE" | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | while read LINE
  813. do
  814. echo "Processing crontab entry: $LINE"
  815. PROG=`echo "$LINE" | awk '{print $6}'`
  816. check_called_programs "$PROG is run via cron as $USER." "$PROG" $USER
  817. done
  818. else
  819. echo "ERROR: Can't read file $FILE"
  820. fi
  821. done
  822. else
  823. echo "Directory /var/spool/cron/crontabs is not present. Skipping checks."
  824. fi
  825.  
  826. section "Checking cron job programs aren't writable (/var/spool/cron/tabs)"
  827. if [ -d "/var/spool/cron/tabs" ]; then
  828. for FILE in /var/spool/cron/tabs/*; do
  829. USER=`echo "$FILE" | sed 's/^.*\///'`
  830. if [ "$USER" = "*" ]; then
  831. echo "No user crontabs found in /var/spool/cron/crontabs. Skipping checks."
  832. continue
  833. fi
  834. echo "Processing crontab for $USER: $FILE"
  835. if [ -r "$FILE" ]; then
  836. MYPATH=`grep '^PATH=' "$FILE" | cut -f 2 -d = `
  837. if [ -n "$MYPATH" ]; then
  838. echo Crontab path is $MYPATH
  839. fi
  840. grep -v '^#' "$FILE" | grep -v '^[ \t]*$' | grep '[ \t][^ \t][^ \t]*[ \t][ \t]*' | while read LINE
  841. do
  842. echo "Processing crontab entry: $LINE"
  843. PROG=`echo "$LINE" | awk '{print $6}'`
  844. check_called_programs "$PROG is run from cron as $USER." $PROG $USER $MYPATH
  845. done
  846. else
  847. echo "ERROR: Can't read file $FILE"
  848. fi
  849. done
  850. else
  851. echo "Directory /var/spool/cron/tabs is not present. Skipping checks."
  852. fi
  853.  
  854. # Check programs run from /etc/inetd.conf have secure permissions
  855. # TODO: check inetd is actually running
  856. section "Checking inetd programs aren't writable"
  857. if [ -f /etc/inetd.conf ] && [ -r /etc/inetd.conf ]; then
  858. grep -v '^#' /etc/inetd.conf | grep -v '^[ \t]*$' | while read LINE
  859. do
  860. USER=`echo $LINE | awk '{print $5}'`
  861. PROG=`echo $LINE | awk '{print $6}'` # could be tcpwappers ...
  862. PROG2=`echo $LINE | awk '{print $7}'` # ... and this is the real prog
  863. if [ -z "$PROG" ] || [ "$PROG" = "internal" ]; then
  864. # Not calling an external program
  865. continue
  866. fi
  867. echo Processing inetd line: $LINE
  868. if [ -f "$PROG" ]; then
  869. check_called_programs "$PROG is run from inetd as $USER." $PROG $USER
  870. fi
  871. if [ -f "$PROG2" ]; then
  872. check_called_programs "$PROG is run from inetd as $USER." $PROG2 $USER
  873. fi
  874. done
  875. else
  876. echo "File /etc/inetd.conf not present. Skipping checks."
  877. fi
  878.  
  879. # Check programs run from /etc/xinetd.d/*
  880. # TODO: check xinetd is actually running
  881. section "Checking xinetd programs aren't writeable"
  882. if [ -d /etc/xinetd.d ]; then
  883. for FILE in `grep 'disable[ \t]*=[ \t]*no' /etc/xinetd.d/* | cut -f 1 -d :`; do
  884. echo Processing xinetd service file: $FILE
  885. PROG=`grep '^[ \t]*server[ \t]*=[ \t]*' $FILE | sed 's/.*server.*=[ \t]*//'`
  886. USER=`grep '^[ \t]*user[ \t]*=[ \t]*' $FILE | sed 's/.*user.*=[ \t]*//'`
  887. check_called_programs "$PROG is run from xinetd as $USER." $PROG $USER
  888. done
  889. else
  890. echo "Directory /etc/xinetd.d not present. Skipping checks."
  891. fi
  892.  
  893. # Check for writable home directories
  894. section "Checking home directories aren't writable"
  895. cat /etc/passwd | grep -v '^#' | while read LINE
  896. do
  897. echo Processing /etc/passwd line: $LINE
  898. USER=`echo $LINE | cut -f 1 -d :`
  899. DIR=`echo $LINE | cut -f 6 -d :`
  900. SHELL=`echo $LINE | cut -f 7 -d :`
  901. if [ "$SHELL" = "/sbin/nologin" ] || [ "$SHELL" = "/bin/false" ]; then
  902. echo " Skipping user $USER. They don't have a shell."
  903. else
  904. if [ "$DIR" = "/dev/null" ]; then
  905. echo " Skipping /dev/null home directory"
  906. else
  907. check_perms "$DIR is the home directory of $USER." $DIR $USER
  908. fi
  909. fi
  910. done
  911.  
  912. # Check for readable files in home directories
  913. section "Checking for readable sensitive files in home directories"
  914. cat /etc/passwd | while read LINE
  915. do
  916. USER=`echo $LINE | cut -f 1 -d :`
  917. DIR=`echo $LINE | cut -f 6 -d :`
  918. SHELL=`echo $LINE | cut -f 7 -d :`
  919. for FILE in $HOME_DIR_FILES; do
  920. if [ -f "$DIR/$FILE" ]; then
  921. check_read_perms "$DIR/$FILE is in the home directory of $USER." "$DIR/$FILE" $USER
  922. fi
  923. done
  924. done
  925.  
  926. section "Checking SUID programs"
  927. if [ "$MODE" = "detailed" ]; then
  928. for FILE in `find / -type f -perm -04000 2>/dev/null`; do
  929. check_called_programs_suid $FILE
  930. done
  931. else
  932. echo "Skipping checks of SUID programs (it's slow!). Run again in 'detailed' mode."
  933. fi
  934.  
  935. # Check for private SSH keys in home directories
  936. section "Checking for Private SSH Keys home directories"
  937. for HOMEDIR in `cut -f 6 -d : /etc/passwd`; do
  938. if [ -d "$HOMEDIR/.ssh" ]; then
  939. PRIV_KEYS=`grep -l 'BEGIN [RD]SA PRIVATE KEY' $HOMEDIR/.ssh/* 2>/dev/null`
  940. if [ -n "$PRIV_KEYS" ]; then
  941. for KEY in $PRIV_KEYS; do
  942. ENC_KEY=`grep -l 'ENCRYPTED' "$KEY" 2>/dev/null`
  943. if [ -n "$ENC_KEY" ]; then
  944. echo "WARNING: Encrypted Private SSH Key Found in $KEY"
  945. else
  946. echo "WARNING: Unencrypted Private SSH Key Found in $KEY"
  947. fi
  948. done
  949. fi
  950. fi
  951. done
  952.  
  953. # Check for public SSH keys in home directories
  954. section "Checking for Public SSH Keys home directories"
  955. for HOMEDIR in `cut -f 6 -d : /etc/passwd`; do
  956. if [ -r "$HOMEDIR/.ssh/authorized_keys" ]; then
  957. KEYS=`grep '^ssh-' $HOMEDIR/.ssh/authorized_keys 2>/dev/null`
  958. if [ -n "$KEYS" ]; then
  959. echo "WARNING: Public SSH Key Found in $HOMEDIR/.ssh/authorized_keys"
  960. fi
  961. fi
  962. done
  963.  
  964. # Check for any SSH agents running on the box
  965. section "Checking for SSH agents"
  966. AGENTS=`ps -ef | grep ssh-agent | grep -v grep`
  967. if [ -n "$AGENTS" ]; then
  968. echo "WARNING: There are SSH agents running on this system:"
  969. ps -ef | grep ssh-agent | grep -v grep
  970. # for PID in `ps aux | grep ssh-agent | grep -v grep | awk '{print $2}'`; do
  971. for SOCK in `ls /tmp/ssh-*/agent.* 2>/dev/null`; do
  972. SSH_AUTH_SOCK=$SOCK; export SSH_AUTH_SOCK
  973. AGENT_KEYS=`ssh-add -l | grep -v 'agent has no identities.' 2>/dev/null`
  974. if [ -n "$AGENT_KEYS" ]; then
  975. echo "WARNING: SSH Agent has keys loaded [SSH_AUTH_SOCK=$SSH_AUTH_SOCK]"
  976. ssh-add -l
  977. fi
  978. done
  979. else
  980. echo "No SSH agents found"
  981. fi
  982.  
  983. # Check for any GPG agents running on the box
  984. section "Checking for GPG agents"
  985. AGENTS=`ps -ef | grep gpg-agent | grep -v grep`
  986. if [ -n "$AGENTS" ]; then
  987. echo "WARNING: There are GPG agents running on this system:"
  988. ps aux | grep gpg-agent | grep -v grep
  989. else
  990. echo "No GPG agents found"
  991. fi
  992.  
  993. # Check files in /etc/init.d/* can't be modified by non-root users
  994. section "Checking startup files (init.d / rc.d) aren't writable"
  995. for DIR in /etc/init.d /etc/rc.d /usr/local/etc/rc.d; do
  996. if [ -d "$DIR" ]; then
  997. for FILE in $DIR/*; do
  998. F=`echo "$FILE" | sed 's/^.*\///'`
  999. if [ "$F" = "*" ]; then
  1000. echo "No user startup script found in $DIR. Skipping checks."
  1001. continue
  1002. fi
  1003. echo Processing startup script $FILE
  1004. check_called_programs "$FILE is run by root at startup." $FILE root
  1005. done
  1006. fi
  1007. done
  1008.  
  1009. section "Checking if running programs are writable"
  1010. if [ $OS = "solaris" ]; then
  1011. # use the output of ps command
  1012. ps -ef -o user,comm | while read LINE
  1013. do
  1014. USER=`echo "$LINE" | awk '{print $1}'`
  1015. PROG=`echo "$LINE" | awk '{print $2}'`
  1016. check_called_programs "$PROG is currently running as $USER." "$PROG" "$USER"
  1017. done
  1018. elif [ $OS = "bsd" ]; then
  1019. # use the output of ps command
  1020. ps aux | while read LINE
  1021. do
  1022. USER=`echo "$LINE" | awk '{print $1}'`
  1023. PROG=`echo "$LINE" | awk '{print $11}'`
  1024. check_called_programs "$PROG is currently running as $USER." "$PROG" "$USER"
  1025. done
  1026. elif [ $OS = "hpux" ]; then
  1027. # use the output of ps command
  1028. ps -ef | while read LINE
  1029. do
  1030. USER=`echo "$LINE" | awk '{print $1}'`
  1031. PROG1=`echo "$LINE" | awk '{print $8}'`
  1032. PROG2=`echo "$LINE" | awk '{print $9}'`
  1033. if [ -f "$PROG1" ]; then
  1034. check_called_programs "$PROG is currently running as $USER." "$PROG1" "$USER"
  1035. fi
  1036. if [ -f "$PROG2" ]; then
  1037. check_called_programs "$PROG is currently running as $USER." "$PROG2" "$USER"
  1038. fi
  1039. done
  1040. elif [ $OS = "linux" ]; then
  1041. # use the /proc file system
  1042. for PROCDIR in /proc/[0-9]*; do
  1043. unset PROGPATH
  1044. PID=`echo $PROCDIR | cut -f 3 -d /`
  1045. echo ------------------------
  1046. echo "PID: $PID"
  1047. if [ -d "$PROCDIR" ]; then
  1048. if [ -r "$PROCDIR/exe" ]; then
  1049. PROGPATH=`ls -l "$PROCDIR/exe" 2>&1 | sed 's/ (deleted)//' | awk '{print $NF}'`
  1050. else
  1051. if [ -r "$PROCDIR/cmdline" ]; then
  1052. P=`cat $PROCDIR/cmdline | tr "\0" = | cut -f 1 -d = | grep '^/'`
  1053. if [ -z "$P" ]; then
  1054. echo "ERROR: Can't find full path of running program: "`cat $PROCDIR/cmdline`
  1055. else
  1056. PROGPATH=$P
  1057. fi
  1058. else
  1059. echo "ERROR: Can't find full path of running program: "`cat $PROCDIR/cmdline`
  1060. continue
  1061. fi
  1062. fi
  1063. get_owner $PROCDIR; OWNER=$GET_OWNER_RETURN
  1064. echo "Owner: $OWNER"
  1065. else
  1066. echo "ERROR: Can't find OWNER. Process has gone."
  1067. continue
  1068. fi
  1069.  
  1070. if [ -n "$PROGPATH" ]; then
  1071. get_owner $PROGPATH; PROGOWNER=$GET_OWNER_RETURN
  1072. echo "Program path: $PROGPATH"
  1073. check_called_programs "$PROGPATH is currently running as $OWNER." $PROGPATH $OWNER
  1074. fi
  1075.  
  1076. if [ "$MODE" == "detailed" ]; then
  1077. for FILE in $PROCDIR/fd/*; do
  1078. F=`echo "$FILE" | sed 's/^.*\///'`
  1079. if [ "$F" = "*" ]; then
  1080. continue
  1081. fi
  1082. check_perms "$FILE is an open file descriptor for process $PID running as $OWNER." $FILE $OWNER
  1083. done
  1084. fi
  1085. done
  1086. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement