Questo è uno strumento molto potente che permette di enumerare una macchina Linux per agevolare una privilage escalation, questo software si può trovare alla seguente pagina. Questo software permette di effettuare due tipi di scansioni una più superficile e una più profonda, è consigliabile utilizzare quella più profonda.
Il codice sorgente è il seguente:
#!/bin/sh
# shellcheck disable=1003,1091,2006,2016,2034,2039,3043
# vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et:
# Author: Diego Blanco <[email protected]>
# GitHub: https://github.com/diego-treitos/linux-smart-enumeration
#
lse_version="4.14nw"
##( Colors
#
#( fg
red='\e[31m'
lred='\e[91m'
green='\e[32m'
lgreen='\e[92m'
yellow='\e[33m'
lyellow='\e[93m'
blue='\e[34m'
lblue='\e[94m'
magenta='\e[35m'
lmagenta='\e[95m'
cyan='\e[36m'
lcyan='\e[96m'
grey='\e[90m'
lgrey='\e[37m'
white='\e[97m'
black='\e[30m'
##)
#( bg
b_red='\e[41m'
b_lred='\e[101m'
b_green='\e[42m'
b_lgreen='\e[102m'
b_yellow='\e[43m'
b_lyellow='\e[103m'
b_blue='\e[44m'
b_lblue='\e[104m'
b_magenta='\e[45m'
b_lmagenta='\e[105m'
b_cyan='\e[46m'
b_lcyan='\e[106m'
b_grey='\e[100m'
b_lgrey='\e[47m'
b_white='\e[107m'
b_black='\e[40m'
##)
#( special
reset='\e[0;0m'
bold='\e[01m'
italic='\e[03m'
underline='\e[04m'
inverse='\e[07m'
conceil='\e[08m'
crossedout='\e[09m'
bold_off='\e[22m'
italic_off='\e[23m'
underline_off='\e[24m'
inverse_off='\e[27m'
conceil_off='\e[28m'
crossedout_off='\e[29m'
##)
#)
##( Globals
#
# user
lse_user_id="`id -u`"
lse_user="$USER"
[ -z "$lse_user" ] && lse_user="`id -nu`"
lse_pass=""
lse_home="$HOME"
[ -z "$lse_home" ] && lse_home="`(grep -E "^$lse_user:" /etc/passwd | cut -d: -f6)2>/dev/null`"
# system
lse_arch="`uname -m`"
lse_linux="`uname -r`"
lse_hostname="`hostname`"
lse_distro=`command -v lsb_release >/dev/null 2>&1 && lsb_release -d | sed 's/Description:\s*//' 2>/dev/null`
[ -z "$lse_distro" ] && lse_distro="`(. /etc/os-release && echo "$PRETTY_NAME")2>/dev/null`"
lse_distro_codename="" # retrieved below with lse_get_distro_codename
# lse
lse_passed_tests=""
lse_executed_tests=""
lse_DEBUG=false
lse_procmon_data=`mktemp`
lse_procmon_lock=`mktemp`
lse_cve_tmp=''
# printf
printf "$reset" | grep -q '\\' && alias printf="env printf"
#( internal data
lse_common_setuid="
/bin/fusermount
/bin/mount
/bin/ntfs-3g
/bin/ping
/bin/ping6
/bin/su
/bin/umount
/lib64/dbus-1/dbus-daemon-launch-helper
/sbin/mount.ecryptfs_private
/sbin/mount.nfs
/sbin/pam_timestamp_check
/sbin/pccardctl
/sbin/unix2_chkpwd
/sbin/unix_chkpwd
/usr/bin/Xorg
/usr/bin/arping
/usr/bin/at
/usr/bin/beep
/usr/bin/chage
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/expiry
/usr/bin/firejail
/usr/bin/fusermount
/usr/bin/fusermount-glusterfs
/usr/bin/fusermount3
/usr/bin/gpasswd
/usr/bin/kismet_capture
/usr/bin/mount
/usr/bin/mtr
/usr/bin/newgidmap
/usr/bin/newgrp
/usr/bin/newuidmap
/usr/bin/ntfs-3g
/usr/bin/passwd
/usr/bin/pkexec
/usr/bin/pmount
/usr/bin/procmail
/usr/bin/pumount
/usr/bin/staprun
/usr/bin/su
/usr/bin/sudo
/usr/bin/sudoedit
/usr/bin/traceroute6.iputils
/usr/bin/umount
/usr/bin/weston-launch
/usr/lib/chromium-browser/chrome-sandbox
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/dbus-1/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/lib/pt_chown
/usr/lib/snapd/snap-confine
/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/xorg/Xorg.wrap
/usr/libexec/Xorg.wrap
/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache
/usr/libexec/cockpit-session
/usr/libexec/dbus-1/dbus-daemon-launch-helper
/usr/libexec/gstreamer-1.0/gst-ptp-helper
/usr/libexec/openssh/ssh-keysign
/usr/libexec/polkit-1/polkit-agent-helper-1
/usr/libexec/polkit-agent-helper-1
/usr/libexec/pt_chown
/usr/libexec/qemu-bridge-helper
/usr/libexec/spice-client-glib-usb-acl-helper
/usr/libexec/spice-gtk-x86_64/spice-client-glib-usb-acl-helper
/usr/local/share/panasonic/printer/bin/L_H0JDUCZAZ
/usr/sbin/exim4
/usr/sbin/grub2-set-bootflag
/usr/sbin/mount.nfs
/usr/sbin/mtr-packet
/usr/sbin/pam_timestamp_check
/usr/sbin/pppd
/usr/sbin/pppoe-wrapper
/usr/sbin/suexec
/usr/sbin/unix_chkpwd
/usr/sbin/userhelper
/usr/sbin/usernetctl
/usr/sbin/uuidd
"
#)
#( regex rules for common setuid
lse_common_setuid="$lse_common_setuid
/snap/core.*
/var/tmp/mkinitramfs.*
"
#)
#( critical writable files
lse_critical_writable="
/etc/apache2/apache2.conf
/etc/apache2/httpd.conf
/etc/bash.bashrc
/etc/bash_completion
/etc/bash_completion.d/*
/etc/environment
/etc/environment.d/*
/etc/hosts.allow
/etc/hosts.deny
/etc/httpd/conf/httpd.conf
/etc/httpd/httpd.conf
/etc/incron.conf
/etc/incron.d/*
/etc/logrotate.d/*
/etc/modprobe.d/*
/etc/pam.d/*
/etc/passwd
/etc/php*/fpm/pool.d/*
/etc/php/*/fpm/pool.d/*
/etc/profile
/etc/profile.d/*
/etc/rc*.d/*
/etc/rsyslog.d/*
/etc/shadow
/etc/skel/*
/etc/sudoers
/etc/sudoers.d/*
/etc/supervisor/conf.d/*
/etc/supervisor/supervisord.conf
/etc/sysctl.conf
/etc/sysctl.d/*
/etc/uwsgi/apps-enabled/*
/root/.ssh/authorized_keys
"
#critical writable directories
lse_critical_writable_dirs="
/etc/bash_completion.d
/etc/cron.d
/etc/cron.daily
/etc/cron.hourly
/etc/cron.weekly
/etc/environment.d
/etc/logrotate.d
/etc/modprobe.d
/etc/pam.d
/etc/profile.d
/etc/rsyslog.d/
/etc/sudoers.d/
/etc/sysctl.d
/root
"
#)
#( CVE list (populated by the lse packager)
lse_cve_list="
" #CVElistMARKER
#)
#)
##( Options
lse_color=true
lse_alt_color=false
lse_interactive=true
lse_proc_time=60
lse_level=0 #Valid levels 0:default, 1:interesting, 2:all
lse_selection="" #Selected tests to run. Empty means all.
lse_find_opts='-path /proc -prune -o -path /sys -prune -o -path /dev -prune -o' #paths to exclude from searches
lse_grep_opts='--color=always'
#)
##( Lib
cecho() { #(
if $lse_color; then
printf "%b" "$@"
else
# If color is disabled we remove it
printf "%b" "$@" | sed -r 's/(\x1B|\\e)\[[0-9;:]+[A-Za-z]//g'
fi
} #)
lse_recolor() { #(
o_white="$white"
o_lyellow="$lyellow"
o_grey="$grey"
o_lred="$lred"
o_lgreen="$lgreen"
o_lcyan="$lcyan"
white="$o_grey"
lyellow="$o_lred"
grey="$lgrey"
lred="$red"
lgreen="$b_lgreen$black"
lcyan="$cyan"
} #)
lse_error() { #(
cecho "${red}ERROR: ${reset}$*\n" >&2
} #)
lse_exclude_paths() { #(
local IFS="
"
for p in `printf "%s" "$1" | tr ',' '\n'`; do
[ "`printf \"%s\" \"$p\" | cut -c1`" = "/" ] || lse_error "'$p' is not an absolute path."
p="${p:*}"; done'
}
#)
##################################################################( file system
lse_run_tests_filesystem() {
lse_header "fst" "file system"
#writable files outside user's home. NOTE: Does not check if user can write in symlink destination (performance reasons: -L implies -noleaf)
lse_test "fst000" "1" \
"Writable files outside user's home" \
'find / -path "$lse_home" -prune -o $lse_find_opts -not -type l -writable -print;
# Add symlinks owned by the user (so the user can change where they point)
find / -path "$lse_home" -prune -o $lse_find_opts -type l -user $lse_user -print' \
"" \
"lse_user_writable" \
"rootskip"
#get setuid binaries
lse_test "fst010" "1" \
"Binaries with setuid bit" \
'find / $lse_find_opts -perm -4000 -type f -print' \
"" \
"lse_setuid_binaries"
#uncommon setuid binaries
lse_test "fst020" "0" \
"Uncommon setuid binaries" \
'local setuidbin="$lse_setuid_binaries"; local IFS="
"; for cs in ${lse_common_setuid}; do setuidbin=`printf "$setuidbin\n" | grep -Ev "^$cs$"`;done ; printf "$setuidbin\n"' \
"fst010"
#can we write to any setuid binary
lse_test "fst030" "0" \
"Can we write to any setuid binary?" \
'for b in $lse_setuid_binaries; do [ -x "$b" ] && [ -w "$b" ] && echo "$b" ;done' \
"fst010"
#get setgid binaries
lse_test "fst040" "1" \
"Binaries with setgid bit" \
'find / $lse_find_opts -perm -2000 -type f -print' \
"lse_setgid_binaries"
#uncommon setgid binaries
lse_test "fst050" "0" \
"Uncommon setgid binaries" \
'printf "$lse_setgid_binaries\n" | grep -Ev "^/(bin|sbin|usr/bin|usr/lib|usr/sbin)"' \
"fst040"
#can we write to any setgid binary
lse_test "fst060" "0" \
"Can we write to any setgid binary?" \
'for b in $lse_setgid_binaries; do [ -x "$b" ] && [ -w "$b" ] && echo "$b" ;done' \
"fst040"
#can we read /root
lse_test "fst070" "1" \
"Can we read /root?" \
'ls -ahl /root/'
#check /home permissions
lse_test "fst080" "1" \
"Can we read subdirectories under /home?" \
'for h in /home/*; do [ -d "$h" ] && [ "$h" != "$lse_home" ] && ls -la "$h/"; done'
#check for SSH files in home directories
lse_test "fst090" "1" \
"SSH files in home directories" \
'for h in $(cut -d: -f6 /etc/passwd | sort -u | grep -Ev "^(/|/dev|/bin|/proc|/run/.*|/var/run/.*)$"); do find "$h" \( -name "*id_dsa*" -o -name "*id_rsa*" -o -name "*id_ecdsa*" -o -name "*id_ed25519*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" \) -exec ls -la {} \; ; done'
#check useful binaries
lse_test "fst100" "1" \
"Useful binaries" \
'which curl; which dig; which gcc; which nc.openbsd; which nc; which netcat; which nmap; which socat; which wget'
#check for interesting files in home directories
lse_test "fst110" "1" \
"Other interesting files in home directories" \
'for h in $(cut -d: -f6 /etc/passwd); do find "$h" \( -name "*.rhosts" -o -name ".git-credentials" -o -name ".*history" \) -maxdepth 1 -exec ls -la {} \; ;'
#looking for credentials in /etc/fstab and /etc/mtab
lse_test "fst120" "0" \
"Are there any credentials in fstab/mtab?" \
'grep $lse_grep_opts -Ei "(user|username|login|pass|password|pw|credentials|cred)[=:]" /etc/fstab /etc/mtab'
#check if current user has mail
lse_test "fst130" "1" \
"Does '$lse_user' have mail?" \
'ls -l "/var/mail/$lse_user"'
#check if we can access other users mail mail
lse_test "fst140" "0" \
"Can we access other users mail?" \
'for f in /var/mail/*; do [ "$f" != "/var/mail/$lse_user" ] && [ -r "$f" ] && echo "$f"; done'
#check for code repositories
lse_test "fst150" "1" \
"Looking for GIT/SVN repositories" \
'find / $lse_find_opts \( -name ".git" -o -name ".svn" \) -print'
#can we write to files that can give us root
lse_test "fst160" "0" \
"Can we write to critical files?" \
'for uw in $lse_user_writable; do [ -f "$uw" ] && IFS="
"; for cw in ${lse_critical_writable}; do [ "$cw" = "$uw" ] && [ -w "$cw" ] && ls -l $cw; done ; done' \
"fst000"
#can we write to directories that can give us root
lse_test "fst170" "0" \
"Can we write to critical directories?" \
'for uw in $lse_user_writable; do [ -d "$uw" ] && IFS="
"; for cw in ${lse_critical_writable_dirs}; do [ "$cw" = "$uw" ] && [ -w "$cw" ] && ls -ld $cw; done ; done' \
"fst000"
#can we write to directories inside PATHS
lse_test "fst180" "0" \
"Can we write to directories from PATH defined in /etc?" \
'for ep in $lse_exec_paths; do [ -d "$ep" ] && [ -w "$ep" ] && ls -ld "$ep"; done' \
"usr070"
#can we read backups
lse_test "fst190" "0" \
"Can we read any backup?" \
'find / $lse_find_opts -path /usr/lib -prune -o -path /usr/share -prune -o -regextype egrep -iregex ".*(backup|dump|cop(y|ies)|bak|bkp)[^/]*\.(sql|tgz|tar|zip)?\.?(gz|xz|bzip2|bz2|lz|7z)?" -readable -type f -exec ls -al {} \;'
#are there possible credentials in any shell history files
lse_test "fst200" "0" \
"Are there possible credentials in any shell history file?" \
'for h in .bash_history .history .histfile .zhistory; do [ -f "$lse_home/$h" ] && grep $lse_grep_opts -Ei "(user|username|login|pass|password|pw|credentials)[=: ][a-z0-9]+" "$lse_home/$h" | grep -v "systemctl"; done'
#nfs exports with no_root_squash
lse_test "fst210" "0" \
"Are there NFS exports with 'no_root_squash' option?" \
'grep $lse_grep_opts "no_root_squash" /etc/exports'
#nfs exports with no_all_squash
lse_test "fst220" "1" \
"Are there NFS exports with 'no_all_squash' option?" \
'grep $lse_grep_opts "no_all_squash" /etc/exports'
#files owned by user
lse_test "fst500" "2" \
"Files owned by user '$lse_user'" \
'find / $lse_find_opts -user $lse_user -type f -exec ls -al {} \;' \
"" "" "rootskip"
#check for SSH files anywhere
lse_test "fst510" "2" \
"SSH files anywhere" \
'find / $lse_find_opts \( -name "*id_dsa*" -o -name "*id_rsa*" -o -name "*id_ecdsa*" -o -name "*id_ed25519*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" \) -exec ls -la {} \;'
#dump hosts.equiv file
lse_test "fst520" "2" \
"Check hosts.equiv file and its contents" \
'find /etc -iname hosts.equiv -exec ls -la {} 2>/dev/null \; -exec cat {} \;'
#list nfs shares
lse_test "fst530" "2" \
"List NFS server shares" \
'ls -la /etc/exports 2>/dev/null && cat /etc/exports'
#dump fstab
lse_test "fst540" "2" \
"Dump fstab file" \
'cat /etc/fstab'
}
#)
#######################################################################( system
lse_run_tests_system() {
lse_header "sys" "system"
#who is logged in
lse_test "sys000" "2" \
"Who is logged in" \
'w'
#last logged in users
lse_test "sys010" "2" \
"Last logged in users" \
'last'
#check if /etc/passwd has the hashes (old system)
lse_test "sys020" "0" \
"Does the /etc/passwd have hashes?" \
'grep -v "^[^:]*:[x]" /etc/passwd'
#check if /etc/group has group password hashes (old system)
lse_test "sys022" "0" \
"Does the /etc/group have hashes?" \
'grep -v "^[^:]*:[x]" /etc/group'
#check if we can read any shadow file
lse_test "sys030" "0" \
"Can we read shadow files?" \
'for sf in "shadow" "shadow-" "shadow~" "gshadow" "gshadow-" "master.passwd"; do [ -r "/etc/$sf" ] && printf "%s\n---\n" "/etc/$sf" && cat "/etc/$sf" && printf "\n\n";done'
#check for superuser accounts
lse_test "sys040" "1" \
"Check for other superuser accounts" \
'for u in $(cut -d: -f1 /etc/passwd); do [ $(id -u $u) = 0 ] && echo $u; done | grep -v root'
#can root log in via SSH
lse_test "sys050" "1" \
"Can root user log in via SSH?" \
'grep -E "^[[:space:]]*PermitRootLogin " /etc/ssh/sshd_config | grep -E "(yes|without-password|prohibit-password)"'
#list available shells
lse_test "sys060" "2" \
"List available shells" \
'cat /etc/shells'
#system umask
lse_test "sys070" "2" \
"System umask in /etc/login.defs" \
'grep "^UMASK" /etc/login.defs'
#system password policies
lse_test "sys080" "2" \
"System password policies in /etc/login.defs" \
'grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs'
}
#)
#####################################################################( security
lse_run_tests_security() {
lse_header "sec" "security"
#check if selinux is present
lse_test "sec000" "1" \
"Is SELinux present?" \
'sestatus'
#get all binaries with capabilities
lse_test "sec010" "1" \
"List files with capabilities" \
'getcap -r /' \
"" \
"lse_cap_bin"
#check if we can write an a binary with capabilities
lse_test "sec020" "0" \
"Can we write to a binary with caps?" \
'for b in $(printf "$lse_cap_bin\n" | cut -d" " -f1); do [ -w "$b" ] && echo "$b"; done'
#check if we have all capabilities in any binary
lse_test "sec030" "0" \
"Do we have all caps in any binary?" \
'printf "$lse_cap_bin\n" | grep -v "cap_"'
#search /etc/security/capability.conf for users associated capapilies
lse_test "sec040" "1" \
"Users with associated capabilities" \
'grep -v "^#\|none\|^$" /etc/security/capability.conf' \
"" \
"lse_user_caps"
#does user have capabilities
lse_test "sec050" "0" \
"Does current user have capabilities?" \
'printf "$lse_user_caps\n" | grep "$lse_user"' \
"sec040"
#can user read the auditd log
lse_test "sec060" "0" \
"Can we read the auditd log?" \
'al=/var/log/audit/audit.log; test -r "$al" && echo "tail $al:" && echo && tail "$al"'
}
#)
##############################################################( recurrent tasks
lse_run_tests_recurrent_tasks() {
lse_header "ret" "recurrent tasks"
## CRON
#user crontab
lse_test "ret000" "1" \
"User crontab" \
'crontab -l | grep -Ev "^#"'
#cron tasks writable by user
lse_test "ret010" "0" \
"Cron tasks writable by user" \
'find -L /etc/cron* /etc/anacron /var/spool/cron -writable'
#list cron jobs
lse_test "ret020" "1" \
"Cron jobs" \
'grep -ERv "^(#|$)" /etc/crontab /etc/cron.d/ /etc/anacrontab'
#can we read other user crontabs?
lse_test "ret030" "1" \
"Can we read user crontabs" \
'ls -la /var/spool/cron/crontabs/*'
#can we list other user cron tasks? (you need privileges for this, so if you can something is fishy)
lse_test "ret040" "1" \
"Can we list other user cron tasks?" \
'for u in $(cut -d: -f 1 /etc/passwd); do [ "$u" != "$lse_user" ] && crontab -l -u "$u"; done'
#can we write to any paths present in cron tasks?
lse_test "ret050" "1" \
"Can we write to any paths present in cron jobs" \
'for p in `grep --color=never -hERoi "/[a-z0-9_/\.\-]+" /etc/cron* | grep -Ev "/dev/(null|zero|random|urandom)" | sort -u`; do [ -w "$p" ] && echo "$p"; done' \
"" \
"lse_user_writable_cron_paths"
#can we write to executable paths present in cron tasks?
lse_test "ret060" "0" \
"Can we write to executable paths present in cron jobs" \
'for uwcp in $lse_user_writable_cron_paths; do [ -w "$uwcp" ] && [ -x "$uwcp" ] && grep $lse_grep_opts -R "$uwcp" /etc/crontab /etc/cron.d/ /etc/anacrontab ; done' \
"ret050"
#list cron files
lse_test "ret400" "2" \
"Cron files" \
'ls -la /etc/cron*'
## Systemd Timers
#user timers
lse_test "ret500" "1" \
"User systemd timers" \
'systemctl --user list-timers --all | grep -iq "\.timer" && systemctl --user list-timers --all'
#can we write in any system timer?
lse_test "ret510" "0" \
"Can we write in any system timer?" \
'printf "$lse_user_writable\n" | grep -E "\.timer$"' \
"fst000"
#system timers
lse_test "ret900" "2" \
"Systemd timers" \
'systemctl list-timers --all'
}
#)
######################################################################( network
lse_run_tests_network() {
lse_header "net" "network"
#services listening only on localhost
lse_test "net000" "1" \
"Services listening only on localhost" \
'(ss -tunlp || netstat -tunlp)2>/dev/null | grep "127.0.0.1:"'
#can we execute tcpdump
lse_test "net010" "0" \
"Can we sniff traffic with tcpdump?" \
'(tcpdump -i lo -n 2>&1 & pid=$!;sleep 0.2;kill $pid)2>/dev/null | grep -i "listening on lo"'
#nic information
lse_test "net500" "2" \
"NIC and IP information" \
'ifconfig -a || ip a'
#routing table
lse_test "net510" "2" \
"Routing table" \
'route -n || ip r'
#arp table
lse_test "net520" "2" \
"ARP table" \
'arp -an || ip n'
#nameservers
lse_test "net530" "2" \
"Nameservers" \
'grep "nameserver" /etc/resolv.conf'
#systemd nameservers
lse_test "net540" "2" \
"Systemd Nameservers" \
'systemd-resolve --status || systemd-resolve --user --status'
#listening TCP
lse_test "net550" "2" \
"Listening TCP" \
'netstat -tnlp || ss -tnlp'
#listening UDP
lse_test "net560" "2" \
"Listening UDP" \
'netstat -unlp || ss -unlp'
}
#)
#####################################################################( services
lse_run_tests_services() {
lse_header "srv" "services"
## System-V
#check write permissions in init.d/* inetd.conf xinetd.conf
lse_test "srv000" "0" \
"Can we write in service files?" \
'printf "$lse_user_writable\n" | grep -E "^/etc/(init/|init\.d/|rc\.d/|rc[0-9S]\.d/|rc\.local|inetd\.conf|xinetd\.conf|xinetd\.d/)"' \
"fst000"
#check write permissions for binaries involved in services
lse_test "srv010" "0" \
"Can we write in binaries executed by services?" \
'for b in $(grep -ERvh "^#" /etc/inetd.conf /etc/xinetd.conf /etc/xinetd.d/ /etc/init.d/ /etc/rc* 2>/dev/null | tr -s "[[:space:]]" "\n" | grep -E "^/" | grep -Ev "^/(dev|run|sys|proc|tmp)/" | sort -u); do [ -x "$b" ] && [ -w "$b" ] && echo "$b" done'
#init.d files NOT belonging to root
lse_test "srv020" "1" \
"Files in /etc/init.d/ not belonging to root" \
'find /etc/init.d/ \! -uid 0 -type f | xargs -r ls -la'
#rc.d/init.d files NOT belonging to root!
lse_test "srv030" "1" \
"Files in /etc/rc.d/init.d not belonging to root" \
'find /etc/rc.d/init.d \! -uid 0 -type f | xargs -r ls -la'
# upstart scripts not belonging to root
lse_test "srv040" "1" \
"Upstart files not belonging to root" \
'find /etc/init \! -uid 0 -type f | xargs -r ls -la'
#/usr/local/etc/rc.d files NOT belonging to root!
lse_test "srv050" "1" \
"Files in /usr/local/etc/rc.d not belonging to root" \
'find /usr/local/etc/rc.d \! -uid 0 -type f | xargs -r ls -la'
#contents of inetd.conf
lse_test "srv400" "2" \
"Contents of /etc/inetd.conf" \
'cat /etc/inetd.conf'
#xinetd info
lse_test "srv410" "2" \
"Contents of /etc/xinetd.conf" \
'cat /etc/xinetd.conf'
#check xinetd.d and permissions
lse_test "srv420" "2" \
"List /etc/xinetd.d if used" \
'grep "/etc/xinetd.d" /etc/xinetd.conf ; ls -la /etc/xinetd.d'
#permissions of init.d scripts
lse_test "srv430" "2" \
"List /etc/init.d/ permissions" \
'ls -la /etc/init.d'
#rc.d/init.d permissions
lse_test "srv440" "2" \
"List /etc/rc.d/init.d permissions" \
'ls -la /etc/rc.d/init.d'
#usr/rc.d permissions
lse_test "srv450" "2" \
"List /usr/local/etc/rc.d permissions" \
'ls -la /usr/local/etc/rc.d'
# init permissions
lse_test "srv460" "2" \
"List /etc/init/ permissions" \
'ls -la /etc/init/'
## Systemd
#check write permissions in systemd services
lse_test "srv500" "0" \
"Can we write in systemd service files?" \
'printf "$lse_user_writable\n" | grep -E "^/(etc/systemd/|lib/systemd/).+\.service$"' \
"fst000"
#check write permissions for binaries involved in systemd services
lse_test "srv510" "0" \
"Can we write in binaries executed by systemd services?" \
'for b in $(grep -ERh "^Exec" /etc/systemd/ /lib/systemd/ 2>/dev/null | tr "=" "\n" | tr -s "[[:space:]]" "\n" | grep -E "^/" | grep -Ev "^/(dev|run|sys|proc|tmp)/" | sort -u); do [ -x "$b" ] && [ -w "$b" ] && echo "$b" done'
# systemd files not belonging to root
lse_test "srv520" "1" \
"Systemd files not belonging to root" \
'find /lib/systemd/ /etc/systemd \! -uid 0 -type f | xargs -r ls -la'
# systemd permissions
lse_test "srv900" "2" \
"Systemd config files permissions" \
'ls -lthR /lib/systemd/ /etc/systemd/'
}
#)
#####################################################################( software
lse_run_tests_software() {
lse_header "sof" "software"
#checks to see if root/root will get us a connection
lse_test "sof000" "0" \
"Can we connect to MySQL with root/root credentials?" \
'mysqladmin -uroot -proot version'
#checks to see if we can connect as root without password
lse_test "sof010" "0" \
"Can we connect to MySQL as root without password?" \
'mysqladmin -uroot version'
#check if there are credentials stored in .mysql-history
lse_test "sof015" "0" \
"Are there credentials in mysql_history file?" \
'grep -Ei "(pass|identified by|md5\()" "$lse_home/.mysql_history"'
#checks to see if we can connect to postgres templates without password
lse_test "sof020" "0" \
"Can we connect to PostgreSQL template0 as postgres and no pass?" \
'psql -U postgres template0 -c "select version()" | grep version'
lse_test "sof020" "0" \
"Can we connect to PostgreSQL template1 as postgres and no pass?" \
'psql -U postgres template1 -c "select version()" | grep version'
lse_test "sof020" "0" \
"Can we connect to PostgreSQL template0 as psql and no pass?" \
'psql -U pgsql template0 -c "select version()" | grep version'
lse_test "sof020" "0" \
"Can we connect to PostgreSQL template1 as psql and no pass?" \
'psql -U pgsql template1 -c "select version()" | grep version'
#installed apache modules
lse_test "sof030" "1" \
"Installed apache modules" \
'apache2ctl -M; httpd -M'
#find htpassword files
lse_test "sof040" "0" \
"Found any .htpasswd files?" \
'find / $lse_find_opts -name "*.htpasswd" -print -exec cat {} \;'
#check if there are ssh private keys in ssh-agent
lse_test "sof050" "0" \
"Are there private keys in ssh-agent?" \
'ssh-add -l | grep -iv "agent has no identities"'
#check if there are gpg keys in gpg-agent
lse_test "sof060" "0" \
"Are there gpg keys cached in gpg-agent?" \
'gpg-connect-agent "keyinfo --list" /bye | grep "D - - 1"'
#check if there is a writable ssh-agent socket
lse_test "sof070" "0" \
"Can we write to a ssh-agent socket?" \
'for f in $lse_user_writable; do test -S "$f" && printf "$f" | grep -Ea "ssh-[A-Za-z0-9]+/agent\.[0-9]+"; done' \
"fst000"
#check if there is a writable gpg-agent socket
lse_test "sof080" "0" \
"Can we write to a gpg-agent socket?" \
'for f in $lse_user_writable; do test -S "$f" && printf "$f" | grep -a "gpg-agent"; done' \
"fst000"
#find keepass database files
lse_test "sof090" "0" \
"Found any keepass database files?" \
'find / $lse_find_opts -regextype egrep -iregex ".*\.kdbx?" -readable -type f -print'
#find pass database files
lse_test "sof100" "0" \
"Found any 'pass' store directories?" \
'find / $lse_find_opts -name ".password-store" -readable -type d -print'
#check if any tmux session is active
lse_test "sof110" "0" \
"Are there any tmux sessions available?" \
'tmux list-sessions'
#check for all tmux sessions for other users
lse_test "sof120" "1" \
"Are there any tmux sessions from other users?" \
'find /tmp -type d -regex "/tmp/tmux-[0-9]+" ! -user $lse_user'
#check if we have write access to other users tmux sessions
lse_test "sof130" "0" \
"Can we write to tmux session sockets from other users?" \
'find /tmp -writable -type s -regex "/tmp/tmux-[0-9]+/.+" ! -user $lse_user -exec ls -l {} +'
#check if there is any active screen session
lse_test "sof140" "0" \
"Are any screen sessions available?" \
'screen -ls >/dev/null && screen -ls'
#find other users screen sessions
lse_test "sof150" "1" \
"Are there any screen sessions from other users?" \
'find /run/screen -type d -regex "/run/screen/S-.+" ! -user $lse_user'
#find writable screen session sockets from other users
lse_test "sof160" "0" \
"Can we write to screen session sockets from other users?" \
'find /run/screen -type s -writable -regex "/run/screen/S-.+/.+" ! -user $lse_user -exec ls -l {} +'
#check connection to mongoDB
lse_test "sof170" "1" \
"Can we access MongoDB databases without credentials?" \
'echo "show dbs" | mongo --quiet | grep -E "(admin|config|local)"'
#find kerberos credentials
lse_test "sof180" "0" \
"Can we access any Kerberos credentials?" \
'find / $lse_find_opts -name "*.so" -prune -o \( -name "krb5cc*" -o -name "*.ccache" -o -name "*.kirbi" -o -name "*.keytab" \) -type f -readable -exec ls -lh {} +'
#sudo version - check to see if there are any known vulnerabilities with this
lse_test "sof500" "2" \
"Sudo version" \
'sudo -V | grep "Sudo version"'
#mysql details - if installed
lse_test "sof510" "2" \
"MySQL version" \
'mysql --version'
#postgres details - if installed
lse_test "sof520" "2" \
"Postgres version" \
'psql -V'
#apache details - if installed
lse_test "sof530" "2" \
"Apache version" \
'apache2 -v; httpd -v'
#check tmux version
lse_test "sof540" "2" \
"Tmux version" \
'tmux -V'
#check screen version
lse_test "sof550" "2" \
"Screen version" \
'screen -v'
}
#)
###################################################################( containers
lse_run_tests_containers() {
lse_header "ctn" "containers"
#check to see if we are in a docker container
lse_test "ctn000" "1" \
"Are we in a docker container?" \
'grep -i docker /proc/self/cgroup; find / $lse_find_opts -name "*dockerenv*" -exec ls -la {} \;'
#check to see if current host is running docker services
lse_test "ctn010" "1" \
"Is docker available?" \
'docker --version; docker ps -a; docker images'
#is user a member of the docker group
lse_test "ctn020" "0" \
"Is the user a member of the 'docker' group?" \
'groups | grep -o docker'
#check to see if we are in an lxc container
lse_test "ctn200" "1" \
"Are we in a lxc container?" \
'grep -a container=lxc /proc/1/environ | tr -d "\0"'
#is user a member of any lxd/lxc group
lse_test "ctn210" "0" \
"Is the user a member of any lxc/lxd group?" \
'groups | grep $lse_grep_opts "lxc\|lxd"'
}
#)
####################################################################( processes
lse_run_tests_processes() {
lse_header "pro" "processes"
#wait for the process monitor to finish gathering data
lse_test "pro000" "2" \
"Waiting for the process monitor to finish" \
'while [ ! -s "$lse_procmon_data" ]; do sleep 1; done; cat "$lse_procmon_data"'\
"" \
"lse_procs"
#look for the paths of the process binaries
lse_test "pro001" "2" \
"Retrieving process binaries" \
'printf "%s" "$lse_procs" | cut -d" " -f5 | sort -u | xargs -r which' \
"pro000" \
'lse_proc_bin'
#look for the users running the
lse_test "pro002" "2" \
"Retrieving process users" \
'printf "%s" "$lse_procs" | cut -d" " -f4 | sort -u' \
"pro000" \
'lse_proc_users'
#check if we have write permissions in any process binary
lse_test "pro010" "0" \
"Can we write in any process binary?" \
'for b in $lse_proc_bin; do [ -w "$b" ] && echo $b; done'\
"pro001"
#list processes running as root
lse_test "pro020" "1" \
"Processes running with root permissions" \
'printf "%s" "$lse_procs" | grep -E "^[^ ]+ [^ ]+ [^ ]+ root" | lse_proc_print' \
"pro000"
#list processes running as users with shell
lse_test "pro030" "1" \
"Processes running by non-root users with shell" \
'for user in `printf "%s\n" "$lse_shell_users" | cut -d: -f1 | grep -v root`; do printf "%s" "$lse_proc_users" | grep -qE "(^| )$user( |\$)" && printf "\n\n------ $user ------\n\n\n" && printf "%s" "$lse_procs" | grep -E "^[^ ]+ [^ ]+ [^ ]+ $user" | lse_proc_print; done' \
"usr030 pro000 pro002"
#running processes
lse_test "pro500" "2" \
"Running processes" \
'printf "%s\n" "$lse_procs" | lse_proc_print' \
"pro000"
#list running process binaries and their permissions
lse_test "pro510" "2" \
"Running process binaries and permissions" \
'printf "%s\n" "$lse_proc_bin" | xargs ls -l' \
"pro001"
}
#)
#########################################################################( CVEs
lse_run_tests_cves() {
lse_header "cve" "CVEs"
if [ "${#lse_cve_list}" = 1 ]; then
if [ -z "$lse_selection" ] || printf "%s" "$lse_selection" | grep -iq 'cve'; then
printf "%s\n%s\n%s" \
" In order to test for CVEs, download lse.sh from the GitHub releases page." \
" Alternatively, build lse_cve.sh using tools/package_cvs_into_lse.sh from the" \
" repository."
fi
else
for lse_cve in $lse_cve_list; do
eval "$(printf '%s' "$lse_cve" | base64 -d | gunzip -c)"
lse_test "$lse_cve_id" "$lse_cve_level" \
"$lse_cve_description" \
"lse_cve_test"
done
fi
}
#)
#
##)
#( Main
main() {
while getopts "hcCil:e:p:s:S" option; do
case "${option}" in
c) lse_color=false; lse_grep_opts='--color=never';;
C) lse_alt_color=true;;
e) lse_exclude_paths "${OPTARG}";;
i) lse_interactive=false;;
l) lse_set_level "${OPTARG}";;
s) lse_selection="`printf \"%s\" \"${OPTARG}\"|sed 's/,/ /g'`";;
p) lse_proc_time="${OPTARG}";;
S) lse_serve; exit $?;;
h) lse_help; exit 0;;
*) lse_help; exit 1;;
esac
done
#trap to exec on SIGINT
trap "lse_exit 1" 2
# use alternative color scheme
$lse_alt_color && lse_recolor
lse_request_information
lse_show_info
PATH="$PATH:/sbin:/usr/sbin" #fix path just in case
lse_distro_codename=`lse_get_distro_codename`
lse_procmon &
(sleep "$lse_proc_time"; rm -f "$lse_procmon_lock") &
## NO WAR
lse_header "nowar" "humanity"
lse_test "nowar0" "0" \
'Should we question autocrats and their "military operations"?' \
'cecho " $black$b_blue NO $reset\n $black$b_yellow WAR $reset"'
lse_run_tests_users
lse_run_tests_sudo
lse_run_tests_filesystem
lse_run_tests_system
lse_run_tests_security
lse_run_tests_recurrent_tasks
lse_run_tests_network
lse_run_tests_services
lse_run_tests_software
lse_run_tests_containers
lse_run_tests_processes
lse_run_tests_cves
lse_exit 0
}
[ ! "$lse_NO_EXEC" ] && main "$@"
#)