diff --git a/inventory_linux.sh b/inventory_linux.sh new file mode 100644 index 0000000..867fae9 --- /dev/null +++ b/inventory_linux.sh @@ -0,0 +1,1052 @@ +#!/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 () +{ + printf '%b\n' "$(cat ./usage.txt)" +} + +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 \ No newline at end of file