1080 lines
29 KiB
Bash
1080 lines
29 KiB
Bash
#!/bin/bash
|
|
# A script to enumerate local information from a Linux host
|
|
version="version 0.9.3"
|
|
|
|
# avoid to interrupt script if an error occurs
|
|
set +e
|
|
|
|
# option flags (enable[1]/disable[0])
|
|
perform_system_info=1
|
|
perform_user_info=1
|
|
perform_job_info=1
|
|
perform_networking_info=1
|
|
perform_services_info=1
|
|
perform_software_configs=1
|
|
#perform_docker_checks=1
|
|
perform_lxc_container_checks=1
|
|
perform_interesting_files_1=1
|
|
perform_interesting_files_2=1
|
|
|
|
# useful binaries (thanks to https://gtfobins.github.io/)
|
|
binarylist='nmap\|perl\|awk\|find\|bash\|sh\|man\|more\|less\|vi\|emacs\|vim\|nc\|netcat\|python\|ruby\|lua\|irb\|tar\|zip\|gdb\|pico\|scp\|git\|rvim\|script\|ash\|csh\|curl\|dash\|ed\|env\|expect\|ftp\|sftp\|node\|php\|rpm\|rpmquery\|socat\|strace\|taskset\|tclsh\|telnet\|tftp\|wget\|wish\|zsh\|ssh'
|
|
|
|
#help function
|
|
help() {
|
|
cat <<EOF
|
|
Usage: $(basename "${BASH_SOURCE[0]}") -r <report_name> -e <report_path> -k <keyword> [options]
|
|
|
|
A script to enumerate local information from a Linux host
|
|
|
|
Available options:
|
|
|
|
-k keyword: Searching for the keyword $keyword in conf, php, ini and log files
|
|
-r report: Report name = $report
|
|
-e export: Export folder location = $export\Export_Folder-DD-MM-YY
|
|
-t thorough: Thorough tests = Enabled (SUID/GUID file scanning will be perfomed)
|
|
-p performance: Avoid heavy scans to speed-up the script execution
|
|
This will exclude the following checks:
|
|
- search for suid/guid files (equivalent of '-t')
|
|
- list all world-writable files
|
|
- use supplied $keyword and search inside *.conf,*.php,*.log and *.ini file names for potential matches
|
|
-q quick: speed up the scan time significantly
|
|
This will exlude following checks:
|
|
- check to see if various software are installed (nc, netcat, wget, etc.)
|
|
- search for installed compilers
|
|
- list out sensitive files (if can read/modify, etc.)
|
|
- check for any *.plan files accessible in /home
|
|
- check if there are any .rhosts files accessible
|
|
- list of NFS displaying partitions and filesystems
|
|
- check for credentials in /etc/fstab
|
|
- extract *.conf files from /etc
|
|
- extract user history files that are accessible (.*_history)
|
|
-h help: Show this help page
|
|
EOF
|
|
exit
|
|
}
|
|
|
|
header()
|
|
{
|
|
echo -e "\n"
|
|
echo -e "Local Linux Enumeration Script"
|
|
echo -e "\n"
|
|
}
|
|
|
|
debug_info()
|
|
{
|
|
echo "[-] Debug Info"
|
|
|
|
if [ "$keyword" ]; then
|
|
echo "[+] Searching for keyword: '$keyword'"
|
|
else
|
|
:
|
|
fi
|
|
|
|
if [ "$report" ]; then
|
|
echo "[+] Report name = $report"
|
|
else
|
|
:
|
|
fi
|
|
|
|
if [ "$export" ]; then
|
|
echo "[+] Export location = $export"
|
|
else
|
|
:
|
|
fi
|
|
|
|
if [ "$thorough" ]; then
|
|
echo -e "[+] Thorough tests = \e[00;32mEnabled\e[00m"
|
|
else
|
|
echo -e "[+] Thorough tests = \e[00;33mDisabled (SUID/GUID checks will not be perfomed!)\e[00m"
|
|
fi
|
|
|
|
sleep 2
|
|
|
|
who=`whoami` 2>/dev/null
|
|
echo -e "\n"
|
|
|
|
echo -e "Scan started at:"; date
|
|
echo -e "\n"
|
|
}
|
|
|
|
system_info()
|
|
{
|
|
echo -e "Checking system..."
|
|
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### SYSTEM ###"
|
|
|
|
#basic kernel info
|
|
unameinfo=`uname -a 2>/dev/null`
|
|
if [ "$unameinfo" ]; then
|
|
echo -e "[-] Kernel information: $unameinfo"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
procver=`cat /proc/version 2>/dev/null`
|
|
if [ "$procver" ]; then
|
|
echo -e "[-] Kernel information (continued): $procver"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#search all *-release files for version info
|
|
release=`cat /etc/*-release 2>/dev/null`
|
|
if [ "$release" ]; then
|
|
echo -e "[-] Specific release information: $release"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#target hostname info
|
|
hostnamed=`hostname 2>/dev/null`
|
|
if [ "$hostnamed" ]; then
|
|
echo -e "[-] Hostname: $hostnamed"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
|
|
echo -e "\e[00;32mChecking system completed\e[00m"
|
|
}
|
|
|
|
user_info()
|
|
{
|
|
echo -e "Checking user/group..."
|
|
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### USER/GROUP ###"
|
|
|
|
#current user details
|
|
currusr=`id 2>/dev/null`
|
|
if [ "$currusr" ]; then
|
|
echo -e "[-] Current user/group info: $currusr"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#last logged on user information
|
|
lastlogedonusrs=`lastlog 2>/dev/null |grep -v "Never" 2>/dev/null`
|
|
if [ "$lastlogedonusrs" ]; then
|
|
echo -e "[-] Users that have previously logged onto the system: $lastlogedonusrs"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
|
|
#who else is logged on
|
|
loggedonusrs=`w 2>/dev/null`
|
|
if [ "$loggedonusrs" ]; then
|
|
echo -e "[-] Who else is logged on: $loggedonusrs"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#look for adm group
|
|
adm_users=$(echo -e "$grpinfo" | grep "(adm)")
|
|
if [[ ! -z $adm_users ]];
|
|
then
|
|
echo -e "[-] It looks like we have some admin users: $adm_users"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
#selinux
|
|
sestatus=`sestatus 2>/dev/null`
|
|
if [ "$sestatus" ]; then
|
|
echo -e "[-] SELinux seems to be present: $sestatus"
|
|
echo -e "\n"
|
|
fi
|
|
|
|
#current path configuration
|
|
pathinfo=`echo $PATH 2>/dev/null`
|
|
if [ "$pathinfo" ]; then
|
|
echo -e "[-] Path information: $pathinfo"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#lists available shells
|
|
shellinfo=`cat /etc/shells 2>/dev/null`
|
|
if [ "$shellinfo" ]; then
|
|
echo -e "[-] Available shells: $shellinfo"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#current umask value with both octal and symbolic output
|
|
umaskvalue=`umask -S 2>/dev/null & umask 2>/dev/null`
|
|
if [ "$umaskvalue" ]; then
|
|
echo -e "[-] Current umask value: $umaskvalue"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#umask value as in /etc/login.defs
|
|
umaskdef=`grep -i "^UMASK" /etc/login.defs 2>/dev/null`
|
|
if [ "$umaskdef" ]; then
|
|
echo -e "[-] umask value as specified in /etc/login.defs: $umaskdef"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking user/group completed\e[00m"
|
|
}
|
|
|
|
job_info()
|
|
{
|
|
echo -e "Checking jobs/tasks..."
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### JOBS/TASKS ###"
|
|
|
|
#crontab values
|
|
crontabvar=`ls -la /var/spool/cron/crontabs 2>/dev/null`
|
|
if [ "$crontabvar" ]; then
|
|
echo -e "[-] Anything interesting in /var/spool/cron/crontabs: $crontabvar"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
anacronjobs=`ls -la /etc/anacrontab 2>/dev/null; cat /etc/anacrontab 2>/dev/null`
|
|
if [ "$anacronjobs" ]; then
|
|
echo -e "[-] Anacron jobs and associated file permissions: $anacronjobs"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
anacrontab=`ls -la /var/spool/anacron 2>/dev/null`
|
|
if [ "$anacrontab" ]; then
|
|
echo -e "[-] When were jobs last executed (/var/spool/anacron contents): $anacrontab"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking jobs/tasks completed\e[00m"
|
|
}
|
|
|
|
networking_info()
|
|
{
|
|
echo -e "Checking networking..."
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### NETWORKING ###"
|
|
|
|
#nic information
|
|
nicinfo=`/sbin/ifconfig -a 2>/dev/null`
|
|
if [ "$nicinfo" ]; then
|
|
echo -e "[-] Network and IP info: $nicinfo"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#nic information (using ip)
|
|
nicinfoip=`/sbin/ip a 2>/dev/null`
|
|
if [ ! "$nicinfo" ] && [ "$nicinfoip" ]; then
|
|
echo -e "[-] Network and IP info: $nicinfoip"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
arpinfo=`arp -a 2>/dev/null`
|
|
if [ "$arpinfo" ]; then
|
|
echo -e "[-] ARP history: $arpinfo"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
arpinfoip=`ip n 2>/dev/null`
|
|
if [ ! "$arpinfo" ] && [ "$arpinfoip" ]; then
|
|
echo -e "[-] ARP history: $arpinfoip"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#dns settings
|
|
nsinfo=`grep "nameserver" /etc/resolv.conf 2>/dev/null`
|
|
if [ "$nsinfo" ]; then
|
|
echo -e "[-] Nameserver(s): $nsinfo"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
nsinfosysd=`systemd-resolve --status 2>/dev/null`
|
|
if [ "$nsinfosysd" ]; then
|
|
echo -e "[-] Nameserver(s): $nsinfosysd"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#default route configuration
|
|
defroute=`route 2>/dev/null | grep default`
|
|
if [ "$defroute" ]; then
|
|
echo -e "[-] Default route: $defroute"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#default route configuration
|
|
defrouteip=`ip r 2>/dev/null | grep default`
|
|
if [ ! "$defroute" ] && [ "$defrouteip" ]; then
|
|
echo -e "[-] Default route: $defrouteip"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#listening TCP
|
|
tcpservs=`netstat -antp 2>/dev/null`
|
|
if [ "$tcpservs" ]; then
|
|
echo -e "[-] Listening TCP: $tcpservs"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
tcpservsip=`ss -t 2>/dev/null`
|
|
if [ ! "$tcpservs" ] && [ "$tcpservsip" ]; then
|
|
echo -e "[-] Listening TCP: $tcpservsip"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
#listening UDP
|
|
udpservs=`netstat -anup 2>/dev/null`
|
|
if [ "$udpservs" ]; then
|
|
echo -e "[-] Listening UDP: $udpservs"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
udpservsip=`ip -u 2>/dev/null`
|
|
if [ ! "$udpservs" ] && [ "$udpservsip" ]; then
|
|
echo -e "[-] Listening UDP: $udpservsip"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking networking completed\e[00m"
|
|
}
|
|
|
|
services_info()
|
|
{
|
|
echo -e "Checking services..."
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### SERVICES ###"
|
|
|
|
#running processes
|
|
psaux=`ps aux 2>/dev/null`
|
|
if [ "$psaux" ]; then
|
|
echo -e "[-] Running processes: $psaux"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#lookup process binary path and permissisons
|
|
procperm=`ps aux 2>/dev/null | awk '{print $11}'|xargs -r ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null`
|
|
if [ "$procperm" ]; then
|
|
echo -e "[-] Process binaries and associated permissions (from above list): $procperm"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#anything 'useful' in inetd.conf
|
|
inetdread=`cat /etc/inetd.conf 2>/dev/null`
|
|
if [ "$inetdread" ]; then
|
|
echo -e "[-] Contents of /etc/inetd.conf: $inetdread"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#very 'rough' command to extract associated binaries from inetd.conf & show permisisons of each
|
|
inetdbinperms=`awk '{print $7}' /etc/inetd.conf 2>/dev/null |xargs -r ls -la 2>/dev/null`
|
|
if [ "$inetdbinperms" ]; then
|
|
echo -e "[-] The related inetd binary permissions: $inetdbinperms"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
xinetdread=`cat /etc/xinetd.conf 2>/dev/null`
|
|
if [ "$xinetdread" ]; then
|
|
echo -e "[-] Contents of /etc/xinetd.conf: $xinetdread"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
xinetdincd=`grep "/etc/xinetd.d" /etc/xinetd.conf 2>/dev/null`
|
|
if [ "$xinetdincd" ]; then
|
|
echo -e "[-] /etc/xinetd.d is included in /etc/xinetd.conf - associated binary permissions are listed below:"; ls -la /etc/xinetd.d 2>/dev/null
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#very 'rough' command to extract associated binaries from xinetd.conf & show permisisons of each
|
|
xinetdbinperms=`awk '{print $7}' /etc/xinetd.conf 2>/dev/null |xargs -r ls -la 2>/dev/null`
|
|
if [ "$xinetdbinperms" ]; then
|
|
echo -e "[-] The related xinetd binary permissions: $xinetdbinperms"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
initdread=`ls -la /etc/init.d 2>/dev/null`
|
|
if [ "$initdread" ]; then
|
|
echo -e "[-] /etc/init.d/ binary permissions: $initdread"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#init.d files NOT belonging to root!
|
|
initdperms=`find /etc/init.d/ \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null`
|
|
if [ "$initdperms" ]; then
|
|
echo -e "[-] /etc/init.d/ files not belonging to root: $initdperms"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
rcdread=`ls -la /etc/rc.d/init.d 2>/dev/null`
|
|
if [ "$rcdread" ]; then
|
|
echo -e "[-] /etc/rc.d/init.d binary permissions: $rcdread"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#init.d files NOT belonging to root!
|
|
rcdperms=`find /etc/rc.d/init.d \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null`
|
|
if [ "$rcdperms" ]; then
|
|
echo -e "[-] /etc/rc.d/init.d files not belonging to root: $rcdperms"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
usrrcdread=`ls -la /usr/local/etc/rc.d 2>/dev/null`
|
|
if [ "$usrrcdread" ]; then
|
|
echo -e "[-] /usr/local/etc/rc.d binary permissions: $usrrcdread"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#rc.d files NOT belonging to root!
|
|
usrrcdperms=`find /usr/local/etc/rc.d \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null`
|
|
if [ "$usrrcdperms" ]; then
|
|
echo -e "[-] /usr/local/etc/rc.d files not belonging to root: $usrrcdperms"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking services completed\e[00m"
|
|
}
|
|
|
|
software_configs()
|
|
{
|
|
echo -e "Checking software..."
|
|
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### SOFTWARE ###"
|
|
|
|
#sudo version - check to see if there are any known vulnerabilities with this
|
|
sudover=`sudo -V 2>/dev/null| grep "Sudo version" 2>/dev/null`
|
|
if [ "$sudover" ]; then
|
|
echo -e "[-] Sudo version: $sudover"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#mysql details - if installed
|
|
mysqlver=`mysql --version 2>/dev/null`
|
|
if [ "$mysqlver" ]; then
|
|
echo -e "[-] MYSQL version: $mysqlver"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#checks to see if root/root will get us a connection
|
|
mysqlconnect=`mysqladmin -uroot -proot version 2>/dev/null`
|
|
if [ "$mysqlconnect" ]; then
|
|
echo -e "[+] We can connect to the local MYSQL service with default root/root credentials!$mysqlconnect"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#mysql version details
|
|
mysqlconnectnopass=`mysqladmin -uroot version 2>/dev/null`
|
|
if [ "$mysqlconnectnopass" ]; then
|
|
echo -e "[+] We can connect to the local MYSQL service as 'root' and without a password!$mysqlconnectnopass"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#postgres details - if installed
|
|
postgver=`psql -V 2>/dev/null`
|
|
if [ "$postgver" ]; then
|
|
echo -e "[-] Postgres version:$postgver"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#checks to see if any postgres password exists and connects to DB 'template0' - following commands are a variant on this
|
|
postcon1=`psql -U postgres template0 -c 'select version()' 2>/dev/null | grep version`
|
|
if [ "$postcon1" ]; then
|
|
echo -e "[+] We can connect to Postgres DB 'template0' as user 'postgres' with no password!:$postcon1"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
postcon11=`psql -U postgres template1 -c 'select version()' 2>/dev/null | grep version`
|
|
if [ "$postcon11" ]; then
|
|
echo -e "[+] We can connect to Postgres DB 'template1' as user 'postgres' with no password!:$postcon11"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
postcon2=`psql -U pgsql template0 -c 'select version()' 2>/dev/null | grep version`
|
|
if [ "$postcon2" ]; then
|
|
echo -e "[+] We can connect to Postgres DB 'template0' as user 'psql' with no password!:$postcon2"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
postcon22=`psql -U pgsql template1 -c 'select version()' 2>/dev/null | grep version`
|
|
if [ "$postcon22" ]; then
|
|
echo -e "[+] We can connect to Postgres DB 'template1' as user 'psql' with no password!:$postcon22"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#apache details - if installed
|
|
apachever=`apache2 -v 2>/dev/null; httpd -v 2>/dev/null`
|
|
if [ "$apachever" ]; then
|
|
echo -e "[-] Apache version: $apachever"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#what account is apache running under
|
|
apacheusr=`grep -i 'user\|group' /etc/apache2/envvars 2>/dev/null |awk '{sub(/.*\export /,"")}1' 2>/dev/null`
|
|
if [ "$apacheusr" ]; then
|
|
echo -e "[-] Apache user configuration: $apacheusr"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#installed apache modules
|
|
apachemodules=`apache2ctl -M 2>/dev/null; httpd -M 2>/dev/null`
|
|
if [ "$apachemodules" ]; then
|
|
echo -e "[-] Installed Apache modules: $apachemodules"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking software completed\e[00m"
|
|
}
|
|
|
|
interesting_files_1()
|
|
{
|
|
echo -e "Checking interesting files (part 1)..."
|
|
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
|
|
echo -e "\n"
|
|
echo -e "### INTERESTING FILES ###"
|
|
|
|
#checks to see if various files are installed
|
|
echo -e "[-] Useful file locations:" ; which nc 2>/dev/null ; which netcat 2>/dev/null ; which wget 2>/dev/null ; which nmap 2>/dev/null ; which gcc 2>/dev/null; which curl 2>/dev/null
|
|
echo -e "\n"
|
|
|
|
#limited search for installed compilers
|
|
compiler=`dpkg --list 2>/dev/null| grep compiler |grep -v decompiler 2>/dev/null && yum list installed 'gcc*' 2>/dev/null| grep gcc 2>/dev/null`
|
|
if [ "$compiler" ]; then
|
|
echo -e "[-] Installed compilers: $compiler"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#manual check - lists out sensitive files, can we read/modify etc.
|
|
echo -e "[-] Can we read/write sensitive files:" ; ls -la /etc/passwd 2>/dev/null ; ls -la /etc/group 2>/dev/null ; ls -la /etc/profile 2>/dev/null; ls -la /etc/shadow 2>/dev/null ; ls -la /etc/master.passwd 2>/dev/null
|
|
echo -e "\n"
|
|
|
|
|
|
|
|
#are any .plan files accessible in /home (could contain useful information)
|
|
usrplan=`find /home -iname *.plan -exec ls -la {} \; -exec cat {} 2>/dev/null \;`
|
|
if [ "$usrplan" ]; then
|
|
echo -e "[-] Plan file permissions and contents: $usrplan"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
bsdusrplan=`find /usr/home -iname *.plan -exec ls -la {} \; -exec cat {} 2>/dev/null \;`
|
|
if [ "$bsdusrplan" ]; then
|
|
echo -e "[-] Plan file permissions and contents: $bsdusrplan"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#are there any .rhosts files accessible - these may allow us to login as another user etc.
|
|
rhostsusr=`find /home -iname *.rhosts -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;`
|
|
if [ "$rhostsusr" ]; then
|
|
echo -e "[+] rhost config file(s) and file contents: $rhostsusr"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
bsdrhostsusr=`find /usr/home -iname *.rhosts -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;`
|
|
if [ "$bsdrhostsusr" ]; then
|
|
echo -e "[+] rhost config file(s) and file contents: $bsdrhostsusr"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
rhostssys=`find /etc -iname hosts.equiv -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;`
|
|
if [ "$rhostssys" ]; then
|
|
echo -e "[+] Hosts.equiv file and contents: $rhostssys"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
if [ "$thorough" = "1" ]; then
|
|
#displaying /etc/fstab
|
|
fstab=`cat /etc/fstab 2>/dev/null`
|
|
if [ "$fstab" ]; then
|
|
echo -e "[-] NFS displaying partitions and filesystems - you need to check if exotic filesystems"
|
|
echo -e "$fstab"
|
|
echo -e "\n"
|
|
fi
|
|
fi
|
|
|
|
#looking for credentials in /etc/fstab
|
|
fstab=`grep username /etc/fstab 2>/dev/null |awk '{sub(/.*\username=/,"");sub(/\,.*/,"")}1' 2>/dev/null| xargs -r echo username: 2>/dev/null; grep password /etc/fstab 2>/dev/null |awk '{sub(/.*\password=/,"");sub(/\,.*/,"")}1' 2>/dev/null| xargs -r echo password: 2>/dev/null; grep domain /etc/fstab 2>/dev/null |awk '{sub(/.*\domain=/,"");sub(/\,.*/,"")}1' 2>/dev/null| xargs -r echo domain: 2>/dev/null`
|
|
if [ "$fstab" ]; then
|
|
echo -e "[+] Looks like there are credentials in /etc/fstab! $fstab"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
fstabcred=`grep cred /etc/fstab 2>/dev/null |awk '{sub(/.*\credentials=/,"");sub(/\,.*/,"")}1' 2>/dev/null | xargs -I{} sh -c 'ls -la {}; cat {}' 2>/dev/null`
|
|
if [ "$fstabcred" ]; then
|
|
echo -e "[+] /etc/fstab contains a credentials file! $fstabcred"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
|
|
|
|
#quick extract of .conf files from /etc - only 1 level
|
|
allconf=`find /etc/ -maxdepth 1 -name *.conf -type f -exec ls -la {} \; 2>/dev/null`
|
|
if [ "$allconf" ]; then
|
|
echo -e "[-] All *.conf files in /etc (recursive 1 level): $allconf"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
|
|
#extract any user history files that are accessible
|
|
usrhist=`ls -la ~/.*_history 2>/dev/null`
|
|
if [ "$usrhist" ]; then
|
|
echo -e "[-] Current user history files: $usrhist"
|
|
echo -e "\n"
|
|
else
|
|
:
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking interesting files (part 1) completed\e[00m"
|
|
}
|
|
|
|
interesting_files_2()
|
|
{
|
|
echo -e "Checking interesting files (part 2)..."
|
|
|
|
#search for suid files - this can take some time so is only 'activated' with thorough scanning switch (as are all suid scans below)
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
findsuid=`find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$findsuid" ]; then
|
|
echo -e "[-] SUID files:$findsuid" >> $report_path"_temp01"
|
|
echo -e "\n" >> $report_path"_temp01"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
#list of 'interesting' suid files - feel free to make additions
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
intsuid=`find / -perm -4000 -type f -exec ls -la {} \; 2>/dev/null | grep -w $binarylist 2>/dev/null`
|
|
if [ "$intsuid" ]; then
|
|
echo -e "[+] Possibly interesting SUID files:$intsuid" >> $report_path"_temp02"
|
|
echo -e "\n" >> $report_path"_temp02"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
#lists word-writable suid files
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
wwsuid=`find / -perm -4007 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$wwsuid" ]; then
|
|
echo -e "[+] World-writable SUID files:$wwsuid" >> $report_path"_temp03"
|
|
echo -e "\n" >> $report_path"_temp03"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
wait < <(jobs -p)
|
|
echo "Checking interesting files (part 2)... 3 of 13 tests completed"
|
|
|
|
#lists world-writable suid files owned by root
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
wwsuidrt=`find / -uid 0 -perm -4007 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$wwsuidrt" ]; then
|
|
echo -e "[+] World-writable SUID files owned by root:$wwsuidrt" >> $report_path"_temp04"
|
|
echo -e "\n" >> $report_path"_temp04"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
#search for guid files - this can take some time so is only 'activated' with thorough scanning switch (as are all guid scans below)
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
findguid=`find / -perm -2000 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$findguid" ]; then
|
|
echo -e "[-] GUID files:$findguid" >> $report_path"_temp05"
|
|
echo -e "\n" >> $report_path"_temp05"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
#list of 'interesting' guid files - feel free to make additions
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
intguid=`find / -perm -2000 -type f -exec ls -la {} \; 2>/dev/null | grep -w $binarylist 2>/dev/null`
|
|
if [ "$intguid" ]; then
|
|
echo -e "[+] Possibly interesting GUID files:$intguid" >> $report_path"_temp06"
|
|
echo -e "\n" >> $report_path"_temp06"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
wait < <(jobs -p)
|
|
echo "Checking interesting files (part 2)... 6 of 13 tests completed"
|
|
#lists world-writable guid files
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
wwguid=`find / -perm -2007 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$wwguid" ]; then
|
|
echo -e "[+] World-writable GUID files:$wwguid" >> $report_path"_temp07"
|
|
echo -e "\n" >> $report_path"_temp07"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
#lists world-writable guid files owned by root
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
wwguidrt=`find / -uid 0 -perm -2007 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$wwguidrt" ]; then
|
|
echo -e "[+] World-writable GUID files owned by root:$wwguidrt" >> $report_path"_temp08"
|
|
echo -e "\n" >> $report_path"_temp08"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
#list all world-writable files excluding /proc and /sys
|
|
{
|
|
if [ "$thorough" = "1" ]; then
|
|
wwfiles=`find / ! -path "*/proc/*" ! -path "/sys/*" -perm -2 -type f -exec ls -la {} 2>/dev/null \;`
|
|
if [ "$wwfiles" ]; then
|
|
echo -e "[-] World-writable files (excluding /proc and /sys):$wwfiles" >> $report_path"_temp09"
|
|
echo -e "\n" >> $report_path"_temp09"
|
|
else
|
|
:
|
|
fi
|
|
else
|
|
:
|
|
fi
|
|
} &
|
|
|
|
wait < <(jobs -p)
|
|
echo "Checking interesting files (part 2)... 9 of 13 tests completed"
|
|
|
|
#use supplied keyword and cat *.conf files for potential matches - output will show line number within relevant file path where a match has been located
|
|
{
|
|
if [ "$keyword" = "" ]; then
|
|
echo -e "[-] Can't search *.conf files as no keyword was entered\n"
|
|
else
|
|
confkey=`find / -maxdepth 4 -name *.conf -type f -exec grep -Hn $keyword {} \; 2>/dev/null`
|
|
if [ "$confkey" ]; then
|
|
echo -e "[-] Find keyword ($keyword) in .conf files (recursive 4 levels - output format filepath:identified line number where keyword appears):$confkey" >> $report_path"_temp10"
|
|
echo -e "\n" >> $report_path"_temp10"
|
|
else
|
|
echo -e "[-] Find keyword ($keyword) in .conf files (recursive 4 levels):" >> $report_path"_temp10"
|
|
echo -e "'$keyword' not found in any .conf files" >> $report_path"_temp10"
|
|
echo -e "\n" >> $report_path"_temp10"
|
|
fi
|
|
fi
|
|
} &
|
|
|
|
#use supplied keyword and cat *.php files for potential matches - output will show line number within relevant file path where a match has been located
|
|
{
|
|
if [ "$keyword" = "" ]; then
|
|
echo -e "[-] Can't search *.php files as no keyword was entered\n"
|
|
else
|
|
phpkey=`find / -maxdepth 10 -name *.php -type f -exec grep -Hn $keyword {} \; 2>/dev/null`
|
|
if [ "$phpkey" ]; then
|
|
echo -e "[-] Find keyword ($keyword) in .php files (recursive 10 levels - output format filepath:identified line number where keyword appears):$phpkey" >> $report_path"_temp11"
|
|
echo -e "\n" >> $report_path"_temp11"
|
|
else
|
|
echo -e "[-] Find keyword ($keyword) in .php files (recursive 10 levels):" >> $report_path"_temp11"
|
|
echo -e "'$keyword' not found in any .php files" >> $report_path"_temp11"
|
|
echo -e "\n" >> $report_path"_temp11"
|
|
fi
|
|
fi
|
|
} &
|
|
|
|
#use supplied keyword and cat *.log files for potential matches - output will show line number within relevant file path where a match has been located
|
|
{
|
|
if [ "$keyword" = "" ];then
|
|
echo -e "[-] Can't search *.log files as no keyword was entered\n"
|
|
else
|
|
logkey=`find / -maxdepth 4 -name *.log -type f -exec grep -Hn $keyword {} \; 2>/dev/null`
|
|
if [ "$logkey" ]; then
|
|
echo -e "[-] Find keyword ($keyword) in .log files (recursive 4 levels - output format filepath:identified line number where keyword appears):$logkey" >> $report_path"_temp12"
|
|
echo -e "\n" >> $report_path"_temp12"
|
|
else
|
|
echo -e "[-] Find keyword ($keyword) in .log files (recursive 4 levels):" >> $report_path"_temp12"
|
|
echo -e "'$keyword' not found in any .log files" >> $report_path"_temp12"
|
|
echo -e "\n" >> $report_path"_temp12"
|
|
fi
|
|
fi
|
|
} &
|
|
|
|
#use supplied keyword and cat *.ini files for potential matches - output will show line number within relevant file path where a match has been located
|
|
{
|
|
if [ "$keyword" = "" ];then
|
|
echo -e "[-] Can't search *.ini files as no keyword was entered\n"
|
|
else
|
|
inikey=`find / -maxdepth 4 -name *.ini -type f -exec grep -Hn $keyword {} \; 2>/dev/null`
|
|
if [ "$inikey" ]; then
|
|
echo -e "[-] Find keyword ($keyword) in .ini files (recursive 4 levels - output format filepath:identified line number where keyword appears):$inikey" >> $report_path"_temp13"
|
|
echo -e "\n" >> $report_path"_temp13"
|
|
else
|
|
echo -e "[-] Find keyword ($keyword) in .ini files (recursive 4 levels):" >> $report_path"_temp13"
|
|
echo -e "'$keyword' not found in any .ini files" >> $report_path"_temp13"
|
|
echo -e "\n" >> $report_path"_temp13"
|
|
fi
|
|
fi
|
|
} &
|
|
|
|
wait < <(jobs -p)
|
|
|
|
echo -e "\e[00;32mChecking interesting files (part 2) completed \e[00m"
|
|
}
|
|
|
|
|
|
lxc_container_checks()
|
|
{
|
|
echo -e "Checking lxd/lxc container..."
|
|
exec 4<&1
|
|
exec 1>>$report_path
|
|
#specific checks - are we in an lxd/lxc container
|
|
lxccontainer=`grep -qa container=lxc /proc/1/environ 2>/dev/null`
|
|
if [ "$lxccontainer" ]; then
|
|
echo -e "[+] Looks like we're in a lxc container:$lxccontainer"
|
|
echo -e "\n"
|
|
fi
|
|
|
|
#specific checks - are we a member of the lxd group
|
|
lxdgroup=`id | grep -i lxd 2>/dev/null`
|
|
if [ "$lxdgroup" ]; then
|
|
echo -e "[+] We're a member of the (lxd) group - could possibly misuse these rights!$lxdgroup"
|
|
echo -e "\n"
|
|
fi
|
|
exec 1<&4
|
|
echo -e "\e[00;32mChecking lxd/lxc container completed \e[00m"
|
|
}
|
|
|
|
footer()
|
|
{
|
|
echo -e "\e[01;32mScan completed.\e[00m"
|
|
}
|
|
|
|
call_each()
|
|
{
|
|
header
|
|
debug_info
|
|
if [ $perform_system_info -eq 1 ]; then
|
|
system_info
|
|
fi
|
|
if [ $perform_interesting_files_1 -eq 1 ]; then
|
|
interesting_files_1 &
|
|
fi
|
|
if [ $perform_interesting_files_2 -eq 1 ]; then
|
|
interesting_files_2 &
|
|
fi
|
|
if [ $perform_user_info -eq 1 ]; then
|
|
user_info
|
|
fi
|
|
if [ $perform_job_info -eq 1 ]; then
|
|
job_info
|
|
fi
|
|
if [ $perform_networking_info -eq 1 ]; then
|
|
networking_info
|
|
fi
|
|
if [ $perform_services_info -eq 1 ]; then
|
|
services_info
|
|
fi
|
|
if [ $perform_software_configs -eq 1 ]; then
|
|
software_configs
|
|
fi
|
|
# if [ $perform_docker_checks -eq 1 ]; then
|
|
# docker_checks
|
|
# fi
|
|
if [ $perform_lxc_container_checks -eq 1 ]; then
|
|
lxc_container_checks
|
|
fi
|
|
wait < <(jobs -p)
|
|
footer
|
|
}
|
|
|
|
while getopts "h:k:r:e:stpq" option; do
|
|
case "${option}" in
|
|
k) keyword=${OPTARG};;
|
|
r) report=${OPTARG}"-"`date +"%d-%m-%y"`;;
|
|
e) export=${OPTARG};;
|
|
t) thorough=1;;
|
|
p) perform_interesting_files_2=0;;
|
|
q) perform_interesting_files_1=0;;
|
|
h) help; exit;;
|
|
*) help; exit;;
|
|
esac
|
|
done
|
|
|
|
#if the specified export folder exist perform the test, else return an error
|
|
if [ -d $export ]; then
|
|
export=$export/"report-`date +"%d-%m-%y"`"
|
|
#if today someone already launched the script, it will create a new folder with also the time of the execution
|
|
if [ ! -d $export ]; then
|
|
mkdir $export
|
|
else
|
|
export=$export"`date +"_%H_%M"`"
|
|
if [ ! -d $export ]; then
|
|
mkdir $export
|
|
else
|
|
echo -e "\e[00;31m[*] Please don't launch consecutively the script, wait at least 1 min\e[00m"
|
|
exit
|
|
fi
|
|
fi
|
|
report_path=$export/$report
|
|
#if already exist the report, clear his content
|
|
if [ -f "$report_path" ]; then
|
|
true > $report_path
|
|
fi
|
|
call_each
|
|
cat $export/*_temp* >> $export/$report 2>/dev/null && rm -f $export/*_temp*
|
|
else
|
|
echo -e "\e[00;31m[*] The provided folder $export doen't exist.\n Please use an existing path\e[00m"
|
|
fi
|
|
#endScript |