diff --git a/Introduccion-hacking-hack4u/tema_5_conceptos/LinEnum.sh b/Introduccion-hacking-hack4u/tema_5_conceptos/LinEnum.sh new file mode 100755 index 0000000..d8c69f2 --- /dev/null +++ b/Introduccion-hacking-hack4u/tema_5_conceptos/LinEnum.sh @@ -0,0 +1,1352 @@ +#!/bin/bash +#A script to enumerate local information from a Linux host +version="version 0.982" +#@rebootuser + +#help function +usage () +{ +echo -e "\n\e[00;31m#########################################################\e[00m" +echo -e "\e[00;31m#\e[00m" "\e[00;33mLocal Linux Enumeration & Privilege Escalation Script\e[00m" "\e[00;31m#\e[00m" +echo -e "\e[00;31m#########################################################\e[00m" +echo -e "\e[00;33m# www.rebootuser.com | @rebootuser \e[00m" +echo -e "\e[00;33m# $version\e[00m\n" +echo -e "\e[00;33m# Example: ./LinEnum.sh -k keyword -r report -e /tmp/ -t \e[00m\n" + + echo "OPTIONS:" + echo "-k Enter keyword" + echo "-e Enter export location" + echo "-s Supply user password for sudo checks (INSECURE)" + echo "-t Include thorough (lengthy) tests" + echo "-r Enter report name" + echo "-h Displays this help text" + echo -e "\n" + echo "Running with no options = limited scans/no output file" + +echo -e "\e[00;31m#########################################################\e[00m" +} +header() +{ +echo -e "\n\e[00;31m#########################################################\e[00m" +echo -e "\e[00;31m#\e[00m" "\e[00;33mLocal Linux Enumeration & Privilege Escalation Script\e[00m" "\e[00;31m#\e[00m" +echo -e "\e[00;31m#########################################################\e[00m" +echo -e "\e[00;33m# www.rebootuser.com\e[00m" +echo -e "\e[00;33m# $version\e[00m\n" + +} + +debug_info() +{ +echo "[-] Debug Info" + +if [ "$keyword" ]; then + echo "[+] Searching for the keyword $keyword in conf, php, ini and log files" +fi + +if [ "$report" ]; then + echo "[+] Report name = $report" +fi + +if [ "$export" ]; then + echo "[+] Export location = $export" +fi + +if [ "$thorough" ]; then + echo "[+] Thorough tests = Enabled" +else + echo -e "\e[00;33m[+] Thorough tests = Disabled\e[00m" +fi + +sleep 2 + +if [ "$export" ]; then + mkdir $export 2>/dev/null + format=$export/LinEnum-export-`date +"%d-%m-%y"` + mkdir $format 2>/dev/null +fi + +if [ "$sudopass" ]; then + echo -e "\e[00;35m[+] Please enter password - INSECURE - really only for CTF use!\e[00m" + read -s userpassword + echo +fi + +who=`whoami` 2>/dev/null +echo -e "\n" + +echo -e "\e[00;33mScan started at:"; date +echo -e "\e[00m\n" +} + +# useful binaries (thanks to https://gtfobins.github.io/) +binarylist='aria2c\|arp\|ash\|awk\|base64\|bash\|busybox\|cat\|chmod\|chown\|cp\|csh\|curl\|cut\|dash\|date\|dd\|diff\|dmsetup\|docker\|ed\|emacs\|env\|expand\|expect\|file\|find\|flock\|fmt\|fold\|ftp\|gawk\|gdb\|gimp\|git\|grep\|head\|ht\|iftop\|ionice\|ip$\|irb\|jjs\|jq\|jrunscript\|ksh\|ld.so\|ldconfig\|less\|logsave\|lua\|make\|man\|mawk\|more\|mv\|mysql\|nano\|nawk\|nc\|netcat\|nice\|nl\|nmap\|node\|od\|openssl\|perl\|pg\|php\|pic\|pico\|python\|readelf\|rlwrap\|rpm\|rpmquery\|rsync\|ruby\|run-parts\|rvim\|scp\|script\|sed\|setarch\|sftp\|sh\|shuf\|socat\|sort\|sqlite3\|ssh$\|start-stop-daemon\|stdbuf\|strace\|systemctl\|tail\|tar\|taskset\|tclsh\|tee\|telnet\|tftp\|time\|timeout\|ul\|unexpand\|uniq\|unshare\|vi\|vim\|watch\|wget\|wish\|xargs\|xxd\|zip\|zsh' + +system_info() +{ +echo -e "\e[00;33m### SYSTEM ##############################################\e[00m" + +#basic kernel info +unameinfo=`uname -a 2>/dev/null` +if [ "$unameinfo" ]; then + echo -e "\e[00;31m[-] Kernel information:\e[00m\n$unameinfo" + echo -e "\n" +fi + +procver=`cat /proc/version 2>/dev/null` +if [ "$procver" ]; then + echo -e "\e[00;31m[-] Kernel information (continued):\e[00m\n$procver" + echo -e "\n" +fi + +#search all *-release files for version info +release=`cat /etc/*-release 2>/dev/null` +if [ "$release" ]; then + echo -e "\e[00;31m[-] Specific release information:\e[00m\n$release" + echo -e "\n" +fi + +#target hostname info +hostnamed=`hostname 2>/dev/null` +if [ "$hostnamed" ]; then + echo -e "\e[00;31m[-] Hostname:\e[00m\n$hostnamed" + echo -e "\n" +fi +} + +user_info() +{ +echo -e "\e[00;33m### USER/GROUP ##########################################\e[00m" + +#current user details +currusr=`id 2>/dev/null` +if [ "$currusr" ]; then + echo -e "\e[00;31m[-] Current user/group info:\e[00m\n$currusr" + echo -e "\n" +fi + +#last logged on user information +lastlogedonusrs=`lastlog 2>/dev/null |grep -v "Never" 2>/dev/null` +if [ "$lastlogedonusrs" ]; then + echo -e "\e[00;31m[-] Users that have previously logged onto the system:\e[00m\n$lastlogedonusrs" + echo -e "\n" +fi + +#who else is logged on +loggedonusrs=`w 2>/dev/null` +if [ "$loggedonusrs" ]; then + echo -e "\e[00;31m[-] Who else is logged on:\e[00m\n$loggedonusrs" + echo -e "\n" +fi + +#lists all id's and respective group(s) +grpinfo=`for i in $(cut -d":" -f1 /etc/passwd 2>/dev/null);do id $i;done 2>/dev/null` +if [ "$grpinfo" ]; then + echo -e "\e[00;31m[-] Group memberships:\e[00m\n$grpinfo" + echo -e "\n" +fi + +#added by phackt - look for adm group (thanks patrick) +adm_users=$(echo -e "$grpinfo" | grep "(adm)") +if [[ ! -z $adm_users ]]; + then + echo -e "\e[00;31m[-] It looks like we have some admin users:\e[00m\n$adm_users" + echo -e "\n" +fi + +#checks to see if any hashes are stored in /etc/passwd (depreciated *nix storage method) +hashesinpasswd=`grep -v '^[^:]*:[x]' /etc/passwd 2>/dev/null` +if [ "$hashesinpasswd" ]; then + echo -e "\e[00;33m[+] It looks like we have password hashes in /etc/passwd!\e[00m\n$hashesinpasswd" + echo -e "\n" +fi + +#contents of /etc/passwd +readpasswd=`cat /etc/passwd 2>/dev/null` +if [ "$readpasswd" ]; then + echo -e "\e[00;31m[-] Contents of /etc/passwd:\e[00m\n$readpasswd" + echo -e "\n" +fi + +if [ "$export" ] && [ "$readpasswd" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/passwd $format/etc-export/passwd 2>/dev/null +fi + +#checks to see if the shadow file can be read +readshadow=`cat /etc/shadow 2>/dev/null` +if [ "$readshadow" ]; then + echo -e "\e[00;33m[+] We can read the shadow file!\e[00m\n$readshadow" + echo -e "\n" +fi + +if [ "$export" ] && [ "$readshadow" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/shadow $format/etc-export/shadow 2>/dev/null +fi + +#checks to see if /etc/master.passwd can be read - BSD 'shadow' variant +readmasterpasswd=`cat /etc/master.passwd 2>/dev/null` +if [ "$readmasterpasswd" ]; then + echo -e "\e[00;33m[+] We can read the master.passwd file!\e[00m\n$readmasterpasswd" + echo -e "\n" +fi + +if [ "$export" ] && [ "$readmasterpasswd" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/master.passwd $format/etc-export/master.passwd 2>/dev/null +fi + +#all root accounts (uid 0) +superman=`grep -v -E "^#" /etc/passwd 2>/dev/null| awk -F: '$3 == 0 { print $1}' 2>/dev/null` +if [ "$superman" ]; then + echo -e "\e[00;31m[-] Super user account(s):\e[00m\n$superman" + echo -e "\n" +fi + +#pull out vital sudoers info +sudoers=`grep -v -e '^$' /etc/sudoers 2>/dev/null |grep -v "#" 2>/dev/null` +if [ "$sudoers" ]; then + echo -e "\e[00;31m[-] Sudoers configuration (condensed):\e[00m$sudoers" + echo -e "\n" +fi + +if [ "$export" ] && [ "$sudoers" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/sudoers $format/etc-export/sudoers 2>/dev/null +fi + +#can we sudo without supplying a password +sudoperms=`echo '' | sudo -S -l -k 2>/dev/null` +if [ "$sudoperms" ]; then + echo -e "\e[00;33m[+] We can sudo without supplying a password!\e[00m\n$sudoperms" + echo -e "\n" +fi + +#check sudo perms - authenticated +if [ "$sudopass" ]; then + if [ "$sudoperms" ]; then + : + else + sudoauth=`echo $userpassword | sudo -S -l -k 2>/dev/null` + if [ "$sudoauth" ]; then + echo -e "\e[00;33m[+] We can sudo when supplying a password!\e[00m\n$sudoauth" + echo -e "\n" + fi + fi +fi + +##known 'good' breakout binaries (cleaned to parse /etc/sudoers for comma separated values) - authenticated +if [ "$sudopass" ]; then + if [ "$sudoperms" ]; then + : + else + sudopermscheck=`echo $userpassword | sudo -S -l -k 2>/dev/null | xargs -n 1 2>/dev/null|sed 's/,*$//g' 2>/dev/null | grep -w $binarylist 2>/dev/null` + if [ "$sudopermscheck" ]; then + echo -e "\e[00;33m[-] Possible sudo pwnage!\e[00m\n$sudopermscheck" + echo -e "\n" + fi + fi +fi + +#known 'good' breakout binaries (cleaned to parse /etc/sudoers for comma separated values) +sudopwnage=`echo '' | sudo -S -l -k 2>/dev/null | xargs -n 1 2>/dev/null | sed 's/,*$//g' 2>/dev/null | grep -w $binarylist 2>/dev/null` +if [ "$sudopwnage" ]; then + echo -e "\e[00;33m[+] Possible sudo pwnage!\e[00m\n$sudopwnage" + echo -e "\n" +fi + +#who has sudoed in the past +whohasbeensudo=`find /home -name .sudo_as_admin_successful 2>/dev/null` +if [ "$whohasbeensudo" ]; then + echo -e "\e[00;31m[-] Accounts that have recently used sudo:\e[00m\n$whohasbeensudo" + echo -e "\n" +fi + +#checks to see if roots home directory is accessible +rthmdir=`ls -ahl /root/ 2>/dev/null` +if [ "$rthmdir" ]; then + echo -e "\e[00;33m[+] We can read root's home directory!\e[00m\n$rthmdir" + echo -e "\n" +fi + +#displays /home directory permissions - check if any are lax +homedirperms=`ls -ahl /home/ 2>/dev/null` +if [ "$homedirperms" ]; then + echo -e "\e[00;31m[-] Are permissions on /home directories lax:\e[00m\n$homedirperms" + echo -e "\n" +fi + +#looks for files we can write to that don't belong to us +if [ "$thorough" = "1" ]; then + grfilesall=`find / -writable ! -user \`whoami\` -type f ! -path "/proc/*" ! -path "/sys/*" -exec ls -al {} \; 2>/dev/null` + if [ "$grfilesall" ]; then + echo -e "\e[00;31m[-] Files not owned by user but writable by group:\e[00m\n$grfilesall" + echo -e "\n" + fi +fi + +#looks for files that belong to us +if [ "$thorough" = "1" ]; then + ourfilesall=`find / -user \`whoami\` -type f ! -path "/proc/*" ! -path "/sys/*" -exec ls -al {} \; 2>/dev/null` + if [ "$ourfilesall" ]; then + echo -e "\e[00;31m[-] Files owned by our user:\e[00m\n$ourfilesall" + echo -e "\n" + fi +fi + +#looks for hidden files +if [ "$thorough" = "1" ]; then + hiddenfiles=`find / -name ".*" -type f ! -path "/proc/*" ! -path "/sys/*" -exec ls -al {} \; 2>/dev/null` + if [ "$hiddenfiles" ]; then + echo -e "\e[00;31m[-] Hidden files:\e[00m\n$hiddenfiles" + echo -e "\n" + fi +fi + +#looks for world-reabable files within /home - depending on number of /home dirs & files, this can take some time so is only 'activated' with thorough scanning switch +if [ "$thorough" = "1" ]; then +wrfileshm=`find /home/ -perm -4 -type f -exec ls -al {} \; 2>/dev/null` + if [ "$wrfileshm" ]; then + echo -e "\e[00;31m[-] World-readable files within /home:\e[00m\n$wrfileshm" + echo -e "\n" + fi +fi + +if [ "$thorough" = "1" ]; then + if [ "$export" ] && [ "$wrfileshm" ]; then + mkdir $format/wr-files/ 2>/dev/null + for i in $wrfileshm; do cp --parents $i $format/wr-files/ ; done 2>/dev/null + fi +fi + +#lists current user's home directory contents +if [ "$thorough" = "1" ]; then +homedircontents=`ls -ahl ~ 2>/dev/null` + if [ "$homedircontents" ] ; then + echo -e "\e[00;31m[-] Home directory contents:\e[00m\n$homedircontents" + echo -e "\n" + fi +fi + +#checks for if various ssh files are accessible - this can take some time so is only 'activated' with thorough scanning switch +if [ "$thorough" = "1" ]; then +sshfiles=`find / \( -name "id_dsa*" -o -name "id_rsa*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" \) -exec ls -la {} 2>/dev/null \;` + if [ "$sshfiles" ]; then + echo -e "\e[00;31m[-] SSH keys/host information found in the following locations:\e[00m\n$sshfiles" + echo -e "\n" + fi +fi + +if [ "$thorough" = "1" ]; then + if [ "$export" ] && [ "$sshfiles" ]; then + mkdir $format/ssh-files/ 2>/dev/null + for i in $sshfiles; do cp --parents $i $format/ssh-files/; done 2>/dev/null + fi +fi + +#is root permitted to login via ssh +sshrootlogin=`grep "PermitRootLogin " /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | awk '{print $2}'` +if [ "$sshrootlogin" = "yes" ]; then + echo -e "\e[00;31m[-] Root is allowed to login via SSH:\e[00m" ; grep "PermitRootLogin " /etc/ssh/sshd_config 2>/dev/null | grep -v "#" + echo -e "\n" +fi +} + +environmental_info() +{ +echo -e "\e[00;33m### ENVIRONMENTAL #######################################\e[00m" + +#env information +envinfo=`env 2>/dev/null | grep -v 'LS_COLORS' 2>/dev/null` +if [ "$envinfo" ]; then + echo -e "\e[00;31m[-] Environment information:\e[00m\n$envinfo" + echo -e "\n" +fi + +#check if selinux is enabled +sestatus=`sestatus 2>/dev/null` +if [ "$sestatus" ]; then + echo -e "\e[00;31m[-] SELinux seems to be present:\e[00m\n$sestatus" + echo -e "\n" +fi + +#phackt + +#current path configuration +pathinfo=`echo $PATH 2>/dev/null` +if [ "$pathinfo" ]; then + pathswriteable=`ls -ld $(echo $PATH | tr ":" " ")` + echo -e "\e[00;31m[-] Path information:\e[00m\n$pathinfo" + echo -e "$pathswriteable" + echo -e "\n" +fi + +#lists available shells +shellinfo=`cat /etc/shells 2>/dev/null` +if [ "$shellinfo" ]; then + echo -e "\e[00;31m[-] Available shells:\e[00m\n$shellinfo" + echo -e "\n" +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 "\e[00;31m[-] Current umask value:\e[00m\n$umaskvalue" + echo -e "\n" +fi + +#umask value as in /etc/login.defs +umaskdef=`grep -i "^UMASK" /etc/login.defs 2>/dev/null` +if [ "$umaskdef" ]; then + echo -e "\e[00;31m[-] umask value as specified in /etc/login.defs:\e[00m\n$umaskdef" + echo -e "\n" +fi + +#password policy information as stored in /etc/login.defs +logindefs=`grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs 2>/dev/null` +if [ "$logindefs" ]; then + echo -e "\e[00;31m[-] Password and storage information:\e[00m\n$logindefs" + echo -e "\n" +fi + +if [ "$export" ] && [ "$logindefs" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/login.defs $format/etc-export/login.defs 2>/dev/null +fi +} + +job_info() +{ +echo -e "\e[00;33m### JOBS/TASKS ##########################################\e[00m" + +#are there any cron jobs configured +cronjobs=`ls -la /etc/cron* 2>/dev/null` +if [ "$cronjobs" ]; then + echo -e "\e[00;31m[-] Cron jobs:\e[00m\n$cronjobs" + echo -e "\n" +fi + +#can we manipulate these jobs in any way +cronjobwwperms=`find /etc/cron* -perm -0002 -type f -exec ls -la {} \; -exec cat {} 2>/dev/null \;` +if [ "$cronjobwwperms" ]; then + echo -e "\e[00;33m[+] World-writable cron jobs and file contents:\e[00m\n$cronjobwwperms" + echo -e "\n" +fi + +#contab contents +crontabvalue=`cat /etc/crontab 2>/dev/null` +if [ "$crontabvalue" ]; then + echo -e "\e[00;31m[-] Crontab contents:\e[00m\n$crontabvalue" + echo -e "\n" +fi + +crontabvar=`ls -la /var/spool/cron/crontabs 2>/dev/null` +if [ "$crontabvar" ]; then + echo -e "\e[00;31m[-] Anything interesting in /var/spool/cron/crontabs:\e[00m\n$crontabvar" + echo -e "\n" +fi + +anacronjobs=`ls -la /etc/anacrontab 2>/dev/null; cat /etc/anacrontab 2>/dev/null` +if [ "$anacronjobs" ]; then + echo -e "\e[00;31m[-] Anacron jobs and associated file permissions:\e[00m\n$anacronjobs" + echo -e "\n" +fi + +anacrontab=`ls -la /var/spool/anacron 2>/dev/null` +if [ "$anacrontab" ]; then + echo -e "\e[00;31m[-] When were jobs last executed (/var/spool/anacron contents):\e[00m\n$anacrontab" + echo -e "\n" +fi + +#pull out account names from /etc/passwd and see if any users have associated cronjobs (priv command) +cronother=`cut -d ":" -f 1 /etc/passwd | xargs -n1 crontab -l -u 2>/dev/null` +if [ "$cronother" ]; then + echo -e "\e[00;31m[-] Jobs held by all users:\e[00m\n$cronother" + echo -e "\n" +fi + +# list systemd timers +if [ "$thorough" = "1" ]; then + # include inactive timers in thorough mode + systemdtimers="$(systemctl list-timers --all 2>/dev/null)" + info="" +else + systemdtimers="$(systemctl list-timers 2>/dev/null |head -n -1 2>/dev/null)" + # replace the info in the output with a hint towards thorough mode + info="\e[2mEnable thorough tests to see inactive timers\e[00m" +fi +if [ "$systemdtimers" ]; then + echo -e "\e[00;31m[-] Systemd timers:\e[00m\n$systemdtimers\n$info" + echo -e "\n" +fi + +} + +networking_info() +{ +echo -e "\e[00;33m### NETWORKING ##########################################\e[00m" + +#nic information +nicinfo=`/sbin/ifconfig -a 2>/dev/null` +if [ "$nicinfo" ]; then + echo -e "\e[00;31m[-] Network and IP info:\e[00m\n$nicinfo" + echo -e "\n" +fi + +#nic information (using ip) +nicinfoip=`/sbin/ip a 2>/dev/null` +if [ ! "$nicinfo" ] && [ "$nicinfoip" ]; then + echo -e "\e[00;31m[-] Network and IP info:\e[00m\n$nicinfoip" + echo -e "\n" +fi + +arpinfo=`arp -a 2>/dev/null` +if [ "$arpinfo" ]; then + echo -e "\e[00;31m[-] ARP history:\e[00m\n$arpinfo" + echo -e "\n" +fi + +arpinfoip=`ip n 2>/dev/null` +if [ ! "$arpinfo" ] && [ "$arpinfoip" ]; then + echo -e "\e[00;31m[-] ARP history:\e[00m\n$arpinfoip" + echo -e "\n" +fi + +#dns settings +nsinfo=`grep "nameserver" /etc/resolv.conf 2>/dev/null` +if [ "$nsinfo" ]; then + echo -e "\e[00;31m[-] Nameserver(s):\e[00m\n$nsinfo" + echo -e "\n" +fi + +nsinfosysd=`systemd-resolve --status 2>/dev/null` +if [ "$nsinfosysd" ]; then + echo -e "\e[00;31m[-] Nameserver(s):\e[00m\n$nsinfosysd" + echo -e "\n" +fi + +#default route configuration +defroute=`route 2>/dev/null | grep default` +if [ "$defroute" ]; then + echo -e "\e[00;31m[-] Default route:\e[00m\n$defroute" + echo -e "\n" +fi + +#default route configuration +defrouteip=`ip r 2>/dev/null | grep default` +if [ ! "$defroute" ] && [ "$defrouteip" ]; then + echo -e "\e[00;31m[-] Default route:\e[00m\n$defrouteip" + echo -e "\n" +fi + +#listening TCP +tcpservs=`netstat -ntpl 2>/dev/null` +if [ "$tcpservs" ]; then + echo -e "\e[00;31m[-] Listening TCP:\e[00m\n$tcpservs" + echo -e "\n" +fi + +tcpservsip=`ss -t -l -n 2>/dev/null` +if [ ! "$tcpservs" ] && [ "$tcpservsip" ]; then + echo -e "\e[00;31m[-] Listening TCP:\e[00m\n$tcpservsip" + echo -e "\n" +fi + +#listening UDP +udpservs=`netstat -nupl 2>/dev/null` +if [ "$udpservs" ]; then + echo -e "\e[00;31m[-] Listening UDP:\e[00m\n$udpservs" + echo -e "\n" +fi + +udpservsip=`ss -u -l -n 2>/dev/null` +if [ ! "$udpservs" ] && [ "$udpservsip" ]; then + echo -e "\e[00;31m[-] Listening UDP:\e[00m\n$udpservsip" + echo -e "\n" +fi +} + +services_info() +{ +echo -e "\e[00;33m### SERVICES #############################################\e[00m" + +#running processes +psaux=`ps aux 2>/dev/null` +if [ "$psaux" ]; then + echo -e "\e[00;31m[-] Running processes:\e[00m\n$psaux" + echo -e "\n" +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 "\e[00;31m[-] Process binaries and associated permissions (from above list):\e[00m\n$procperm" + echo -e "\n" +fi + +if [ "$export" ] && [ "$procperm" ]; then +procpermbase=`ps aux 2>/dev/null | awk '{print $11}' | xargs -r ls 2>/dev/null | awk '!x[$0]++' 2>/dev/null` + mkdir $format/ps-export/ 2>/dev/null + for i in $procpermbase; do cp --parents $i $format/ps-export/; done 2>/dev/null +fi + +#anything 'useful' in inetd.conf +inetdread=`cat /etc/inetd.conf 2>/dev/null` +if [ "$inetdread" ]; then + echo -e "\e[00;31m[-] Contents of /etc/inetd.conf:\e[00m\n$inetdread" + echo -e "\n" +fi + +if [ "$export" ] && [ "$inetdread" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/inetd.conf $format/etc-export/inetd.conf 2>/dev/null +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 "\e[00;31m[-] The related inetd binary permissions:\e[00m\n$inetdbinperms" + echo -e "\n" +fi + +xinetdread=`cat /etc/xinetd.conf 2>/dev/null` +if [ "$xinetdread" ]; then + echo -e "\e[00;31m[-] Contents of /etc/xinetd.conf:\e[00m\n$xinetdread" + echo -e "\n" +fi + +if [ "$export" ] && [ "$xinetdread" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/xinetd.conf $format/etc-export/xinetd.conf 2>/dev/null +fi + +xinetdincd=`grep "/etc/xinetd.d" /etc/xinetd.conf 2>/dev/null` +if [ "$xinetdincd" ]; then + echo -e "\e[00;31m[-] /etc/xinetd.d is included in /etc/xinetd.conf - associated binary permissions are listed below:\e[00m"; ls -la /etc/xinetd.d 2>/dev/null + echo -e "\n" +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 "\e[00;31m[-] The related xinetd binary permissions:\e[00m\n$xinetdbinperms" + echo -e "\n" +fi + +initdread=`ls -la /etc/init.d 2>/dev/null` +if [ "$initdread" ]; then + echo -e "\e[00;31m[-] /etc/init.d/ binary permissions:\e[00m\n$initdread" + echo -e "\n" +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 "\e[00;31m[-] /etc/init.d/ files not belonging to root:\e[00m\n$initdperms" + echo -e "\n" +fi + +rcdread=`ls -la /etc/rc.d/init.d 2>/dev/null` +if [ "$rcdread" ]; then + echo -e "\e[00;31m[-] /etc/rc.d/init.d binary permissions:\e[00m\n$rcdread" + echo -e "\n" +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 "\e[00;31m[-] /etc/rc.d/init.d files not belonging to root:\e[00m\n$rcdperms" + echo -e "\n" +fi + +usrrcdread=`ls -la /usr/local/etc/rc.d 2>/dev/null` +if [ "$usrrcdread" ]; then + echo -e "\e[00;31m[-] /usr/local/etc/rc.d binary permissions:\e[00m\n$usrrcdread" + echo -e "\n" +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 "\e[00;31m[-] /usr/local/etc/rc.d files not belonging to root:\e[00m\n$usrrcdperms" + echo -e "\n" +fi + +initread=`ls -la /etc/init/ 2>/dev/null` +if [ "$initread" ]; then + echo -e "\e[00;31m[-] /etc/init/ config file permissions:\e[00m\n$initread" + echo -e "\n" +fi + +# upstart scripts not belonging to root +initperms=`find /etc/init \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null` +if [ "$initperms" ]; then + echo -e "\e[00;31m[-] /etc/init/ config files not belonging to root:\e[00m\n$initperms" + echo -e "\n" +fi + +systemdread=`ls -lthR /lib/systemd/ 2>/dev/null` +if [ "$systemdread" ]; then + echo -e "\e[00;31m[-] /lib/systemd/* config file permissions:\e[00m\n$systemdread" + echo -e "\n" +fi + +# systemd files not belonging to root +systemdperms=`find /lib/systemd/ \! -uid 0 -type f 2>/dev/null |xargs -r ls -la 2>/dev/null` +if [ "$systemdperms" ]; then + echo -e "\e[00;33m[+] /lib/systemd/* config files not belonging to root:\e[00m\n$systemdperms" + echo -e "\n" +fi +} + +software_configs() +{ +echo -e "\e[00;33m### SOFTWARE #############################################\e[00m" + +#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 "\e[00;31m[-] Sudo version:\e[00m\n$sudover" + echo -e "\n" +fi + +#mysql details - if installed +mysqlver=`mysql --version 2>/dev/null` +if [ "$mysqlver" ]; then + echo -e "\e[00;31m[-] MYSQL version:\e[00m\n$mysqlver" + echo -e "\n" +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 "\e[00;33m[+] We can connect to the local MYSQL service with default root/root credentials!\e[00m\n$mysqlconnect" + echo -e "\n" +fi + +#mysql version details +mysqlconnectnopass=`mysqladmin -uroot version 2>/dev/null` +if [ "$mysqlconnectnopass" ]; then + echo -e "\e[00;33m[+] We can connect to the local MYSQL service as 'root' and without a password!\e[00m\n$mysqlconnectnopass" + echo -e "\n" +fi + +#postgres details - if installed +postgver=`psql -V 2>/dev/null` +if [ "$postgver" ]; then + echo -e "\e[00;31m[-] Postgres version:\e[00m\n$postgver" + echo -e "\n" +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 -w template0 -c 'select version()' 2>/dev/null | grep version` +if [ "$postcon1" ]; then + echo -e "\e[00;33m[+] We can connect to Postgres DB 'template0' as user 'postgres' with no password!:\e[00m\n$postcon1" + echo -e "\n" +fi + +postcon11=`psql -U postgres -w template1 -c 'select version()' 2>/dev/null | grep version` +if [ "$postcon11" ]; then + echo -e "\e[00;33m[+] We can connect to Postgres DB 'template1' as user 'postgres' with no password!:\e[00m\n$postcon11" + echo -e "\n" +fi + +postcon2=`psql -U pgsql -w template0 -c 'select version()' 2>/dev/null | grep version` +if [ "$postcon2" ]; then + echo -e "\e[00;33m[+] We can connect to Postgres DB 'template0' as user 'psql' with no password!:\e[00m\n$postcon2" + echo -e "\n" +fi + +postcon22=`psql -U pgsql -w template1 -c 'select version()' 2>/dev/null | grep version` +if [ "$postcon22" ]; then + echo -e "\e[00;33m[+] We can connect to Postgres DB 'template1' as user 'psql' with no password!:\e[00m\n$postcon22" + echo -e "\n" +fi + +#apache details - if installed +apachever=`apache2 -v 2>/dev/null; httpd -v 2>/dev/null` +if [ "$apachever" ]; then + echo -e "\e[00;31m[-] Apache version:\e[00m\n$apachever" + echo -e "\n" +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 "\e[00;31m[-] Apache user configuration:\e[00m\n$apacheusr" + echo -e "\n" +fi + +if [ "$export" ] && [ "$apacheusr" ]; then + mkdir --parents $format/etc-export/apache2/ 2>/dev/null + cp /etc/apache2/envvars $format/etc-export/apache2/envvars 2>/dev/null +fi + +#installed apache modules +apachemodules=`apache2ctl -M 2>/dev/null; httpd -M 2>/dev/null` +if [ "$apachemodules" ]; then + echo -e "\e[00;31m[-] Installed Apache modules:\e[00m\n$apachemodules" + echo -e "\n" +fi + +#htpasswd check +htpasswd=`find / -name .htpasswd -print -exec cat {} \; 2>/dev/null` +if [ "$htpasswd" ]; then + echo -e "\e[00;33m[-] htpasswd found - could contain passwords:\e[00m\n$htpasswd" + echo -e "\n" +fi + +#anything in the default http home dirs (a thorough only check as output can be large) +if [ "$thorough" = "1" ]; then + apachehomedirs=`ls -alhR /var/www/ 2>/dev/null; ls -alhR /srv/www/htdocs/ 2>/dev/null; ls -alhR /usr/local/www/apache2/data/ 2>/dev/null; ls -alhR /opt/lampp/htdocs/ 2>/dev/null` + if [ "$apachehomedirs" ]; then + echo -e "\e[00;31m[-] www home dir contents:\e[00m\n$apachehomedirs" + echo -e "\n" + fi +fi + +} + +interesting_files() +{ +echo -e "\e[00;33m### INTERESTING FILES ####################################\e[00m" + +#checks to see if various files are installed +echo -e "\e[00;31m[-] Useful file locations:\e[00m" ; 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 "\e[00;31m[-] Installed compilers:\e[00m\n$compiler" + echo -e "\n" +fi + +#manual check - lists out sensitive files, can we read/modify etc. +echo -e "\e[00;31m[-] Can we read/write sensitive files:\e[00m" ; 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" + +#search for suid files +allsuid=`find / -perm -4000 -type f 2>/dev/null` +findsuid=`find $allsuid -perm -4000 -type f -exec ls -la {} 2>/dev/null \;` +if [ "$findsuid" ]; then + echo -e "\e[00;31m[-] SUID files:\e[00m\n$findsuid" + echo -e "\n" +fi + +if [ "$export" ] && [ "$findsuid" ]; then + mkdir $format/suid-files/ 2>/dev/null + for i in $findsuid; do cp $i $format/suid-files/; done 2>/dev/null +fi + +#list of 'interesting' suid files - feel free to make additions +intsuid=`find $allsuid -perm -4000 -type f -exec ls -la {} \; 2>/dev/null | grep -w $binarylist 2>/dev/null` +if [ "$intsuid" ]; then + echo -e "\e[00;33m[+] Possibly interesting SUID files:\e[00m\n$intsuid" + echo -e "\n" +fi + +#lists world-writable suid files +wwsuid=`find $allsuid -perm -4002 -type f -exec ls -la {} 2>/dev/null \;` +if [ "$wwsuid" ]; then + echo -e "\e[00;33m[+] World-writable SUID files:\e[00m\n$wwsuid" + echo -e "\n" +fi + +#lists world-writable suid files owned by root +wwsuidrt=`find $allsuid -uid 0 -perm -4002 -type f -exec ls -la {} 2>/dev/null \;` +if [ "$wwsuidrt" ]; then + echo -e "\e[00;33m[+] World-writable SUID files owned by root:\e[00m\n$wwsuidrt" + echo -e "\n" +fi + +#search for sgid files +allsgid=`find / -perm -2000 -type f 2>/dev/null` +findsgid=`find $allsgid -perm -2000 -type f -exec ls -la {} 2>/dev/null \;` +if [ "$findsgid" ]; then + echo -e "\e[00;31m[-] SGID files:\e[00m\n$findsgid" + echo -e "\n" +fi + +if [ "$export" ] && [ "$findsgid" ]; then + mkdir $format/sgid-files/ 2>/dev/null + for i in $findsgid; do cp $i $format/sgid-files/; done 2>/dev/null +fi + +#list of 'interesting' sgid files +intsgid=`find $allsgid -perm -2000 -type f -exec ls -la {} \; 2>/dev/null | grep -w $binarylist 2>/dev/null` +if [ "$intsgid" ]; then + echo -e "\e[00;33m[+] Possibly interesting SGID files:\e[00m\n$intsgid" + echo -e "\n" +fi + +#lists world-writable sgid files +wwsgid=`find $allsgid -perm -2002 -type f -exec ls -la {} 2>/dev/null \;` +if [ "$wwsgid" ]; then + echo -e "\e[00;33m[+] World-writable SGID files:\e[00m\n$wwsgid" + echo -e "\n" +fi + +#lists world-writable sgid files owned by root +wwsgidrt=`find $allsgid -uid 0 -perm -2002 -type f -exec ls -la {} 2>/dev/null \;` +if [ "$wwsgidrt" ]; then + echo -e "\e[00;33m[+] World-writable SGID files owned by root:\e[00m\n$wwsgidrt" + echo -e "\n" +fi + +#list all files with POSIX capabilities set along with there capabilities +fileswithcaps=`getcap -r / 2>/dev/null || /sbin/getcap -r / 2>/dev/null` +if [ "$fileswithcaps" ]; then + echo -e "\e[00;31m[+] Files with POSIX capabilities set:\e[00m\n$fileswithcaps" + echo -e "\n" +fi + +if [ "$export" ] && [ "$fileswithcaps" ]; then + mkdir $format/files_with_capabilities/ 2>/dev/null + for i in $fileswithcaps; do cp $i $format/files_with_capabilities/; done 2>/dev/null +fi + +#searches /etc/security/capability.conf for users associated capapilies +userswithcaps=`grep -v '^#\|none\|^$' /etc/security/capability.conf 2>/dev/null` +if [ "$userswithcaps" ]; then + echo -e "\e[00;33m[+] Users with specific POSIX capabilities:\e[00m\n$userswithcaps" + echo -e "\n" +fi + +if [ "$userswithcaps" ] ; then +#matches the capabilities found associated with users with the current user +matchedcaps=`echo -e "$userswithcaps" | grep \`whoami\` | awk '{print $1}' 2>/dev/null` + if [ "$matchedcaps" ]; then + echo -e "\e[00;33m[+] Capabilities associated with the current user:\e[00m\n$matchedcaps" + echo -e "\n" + #matches the files with capapbilities with capabilities associated with the current user + matchedfiles=`echo -e "$matchedcaps" | while read -r cap ; do echo -e "$fileswithcaps" | grep "$cap" ; done 2>/dev/null` + if [ "$matchedfiles" ]; then + echo -e "\e[00;33m[+] Files with the same capabilities associated with the current user (You may want to try abusing those capabilties):\e[00m\n$matchedfiles" + echo -e "\n" + #lists the permissions of the files having the same capabilies associated with the current user + matchedfilesperms=`echo -e "$matchedfiles" | awk '{print $1}' | while read -r f; do ls -la $f ;done 2>/dev/null` + echo -e "\e[00;33m[+] Permissions of files with the same capabilities associated with the current user:\e[00m\n$matchedfilesperms" + echo -e "\n" + if [ "$matchedfilesperms" ]; then + #checks if any of the files with same capabilities associated with the current user is writable + writablematchedfiles=`echo -e "$matchedfiles" | awk '{print $1}' | while read -r f; do find $f -writable -exec ls -la {} + ;done 2>/dev/null` + if [ "$writablematchedfiles" ]; then + echo -e "\e[00;33m[+] User/Group writable files with the same capabilities associated with the current user:\e[00m\n$writablematchedfiles" + echo -e "\n" + fi + fi + fi + fi +fi + +#look for private keys - thanks djhohnstein +if [ "$thorough" = "1" ]; then +privatekeyfiles=`grep -rl "PRIVATE KEY-----" /home 2>/dev/null` + if [ "$privatekeyfiles" ]; then + echo -e "\e[00;33m[+] Private SSH keys found!:\e[00m\n$privatekeyfiles" + echo -e "\n" + fi +fi + +#look for AWS keys - thanks djhohnstein +if [ "$thorough" = "1" ]; then +awskeyfiles=`grep -rli "aws_secret_access_key" /home 2>/dev/null` + if [ "$awskeyfiles" ]; then + echo -e "\e[00;33m[+] AWS secret keys found!:\e[00m\n$awskeyfiles" + echo -e "\n" + fi +fi + +#look for git credential files - thanks djhohnstein +if [ "$thorough" = "1" ]; then +gitcredfiles=`find / -name ".git-credentials" 2>/dev/null` + if [ "$gitcredfiles" ]; then + echo -e "\e[00;33m[+] Git credentials saved on the machine!:\e[00m\n$gitcredfiles" + echo -e "\n" + fi +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 "\e[00;31m[-] World-writable files (excluding /proc and /sys):\e[00m\n$wwfiles" + echo -e "\n" + fi +fi + +if [ "$thorough" = "1" ]; then + if [ "$export" ] && [ "$wwfiles" ]; then + mkdir $format/ww-files/ 2>/dev/null + for i in $wwfiles; do cp --parents $i $format/ww-files/; done 2>/dev/null + fi +fi + +#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 "\e[00;31m[-] Plan file permissions and contents:\e[00m\n$usrplan" + echo -e "\n" +fi + +if [ "$export" ] && [ "$usrplan" ]; then + mkdir $format/plan_files/ 2>/dev/null + for i in $usrplan; do cp --parents $i $format/plan_files/; done 2>/dev/null +fi + +bsdusrplan=`find /usr/home -iname *.plan -exec ls -la {} \; -exec cat {} 2>/dev/null \;` +if [ "$bsdusrplan" ]; then + echo -e "\e[00;31m[-] Plan file permissions and contents:\e[00m\n$bsdusrplan" + echo -e "\n" +fi + +if [ "$export" ] && [ "$bsdusrplan" ]; then + mkdir $format/plan_files/ 2>/dev/null + for i in $bsdusrplan; do cp --parents $i $format/plan_files/; done 2>/dev/null +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 "\e[00;33m[+] rhost config file(s) and file contents:\e[00m\n$rhostsusr" + echo -e "\n" +fi + +if [ "$export" ] && [ "$rhostsusr" ]; then + mkdir $format/rhosts/ 2>/dev/null + for i in $rhostsusr; do cp --parents $i $format/rhosts/; done 2>/dev/null +fi + +bsdrhostsusr=`find /usr/home -iname *.rhosts -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;` +if [ "$bsdrhostsusr" ]; then + echo -e "\e[00;33m[+] rhost config file(s) and file contents:\e[00m\n$bsdrhostsusr" + echo -e "\n" +fi + +if [ "$export" ] && [ "$bsdrhostsusr" ]; then + mkdir $format/rhosts 2>/dev/null + for i in $bsdrhostsusr; do cp --parents $i $format/rhosts/; done 2>/dev/null +fi + +rhostssys=`find /etc -iname hosts.equiv -exec ls -la {} 2>/dev/null \; -exec cat {} 2>/dev/null \;` +if [ "$rhostssys" ]; then + echo -e "\e[00;33m[+] Hosts.equiv file and contents: \e[00m\n$rhostssys" + echo -e "\n" +fi + +if [ "$export" ] && [ "$rhostssys" ]; then + mkdir $format/rhosts/ 2>/dev/null + for i in $rhostssys; do cp --parents $i $format/rhosts/; done 2>/dev/null +fi + +#list nfs shares/permisisons etc. +nfsexports=`ls -la /etc/exports 2>/dev/null; cat /etc/exports 2>/dev/null` +if [ "$nfsexports" ]; then + echo -e "\e[00;31m[-] NFS config details: \e[00m\n$nfsexports" + echo -e "\n" +fi + +if [ "$export" ] && [ "$nfsexports" ]; then + mkdir $format/etc-export/ 2>/dev/null + cp /etc/exports $format/etc-export/exports 2>/dev/null +fi + +if [ "$thorough" = "1" ]; then + #phackt + #displaying /etc/fstab + fstab=`cat /etc/fstab 2>/dev/null` + if [ "$fstab" ]; then + echo -e "\e[00;31m[-] NFS displaying partitions and filesystems - you need to check if exotic filesystems\e[00m" + 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 "\e[00;33m[+] Looks like there are credentials in /etc/fstab!\e[00m\n$fstab" + echo -e "\n" +fi + +if [ "$export" ] && [ "$fstab" ]; then + mkdir $format/etc-exports/ 2>/dev/null + cp /etc/fstab $format/etc-exports/fstab done 2>/dev/null +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 "\e[00;33m[+] /etc/fstab contains a credentials file!\e[00m\n$fstabcred" + echo -e "\n" +fi + +if [ "$export" ] && [ "$fstabcred" ]; then + mkdir $format/etc-exports/ 2>/dev/null + cp /etc/fstab $format/etc-exports/fstab done 2>/dev/null +fi + +#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 "\e[00;31m[-] Find keyword ($keyword) in .conf files (recursive 4 levels - output format filepath:identified line number where keyword appears):\e[00m\n$confkey" + echo -e "\n" + else + echo -e "\e[00;31m[-] Find keyword ($keyword) in .conf files (recursive 4 levels):\e[00m" + echo -e "'$keyword' not found in any .conf files" + echo -e "\n" + fi +fi + +if [ "$keyword" = "" ]; then + : + else + if [ "$export" ] && [ "$confkey" ]; then + confkeyfile=`find / -maxdepth 4 -name *.conf -type f -exec grep -lHn $keyword {} \; 2>/dev/null` + mkdir --parents $format/keyword_file_matches/config_files/ 2>/dev/null + for i in $confkeyfile; do cp --parents $i $format/keyword_file_matches/config_files/ ; done 2>/dev/null + 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 "\e[00;31m[-] Find keyword ($keyword) in .php files (recursive 10 levels - output format filepath:identified line number where keyword appears):\e[00m\n$phpkey" + echo -e "\n" + else + echo -e "\e[00;31m[-] Find keyword ($keyword) in .php files (recursive 10 levels):\e[00m" + echo -e "'$keyword' not found in any .php files" + echo -e "\n" + fi +fi + +if [ "$keyword" = "" ]; then + : + else + if [ "$export" ] && [ "$phpkey" ]; then + phpkeyfile=`find / -maxdepth 10 -name *.php -type f -exec grep -lHn $keyword {} \; 2>/dev/null` + mkdir --parents $format/keyword_file_matches/php_files/ 2>/dev/null + for i in $phpkeyfile; do cp --parents $i $format/keyword_file_matches/php_files/ ; done 2>/dev/null + 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 "\e[00;31m[-] Find keyword ($keyword) in .log files (recursive 4 levels - output format filepath:identified line number where keyword appears):\e[00m\n$logkey" + echo -e "\n" + else + echo -e "\e[00;31m[-] Find keyword ($keyword) in .log files (recursive 4 levels):\e[00m" + echo -e "'$keyword' not found in any .log files" + echo -e "\n" + fi +fi + +if [ "$keyword" = "" ];then + : + else + if [ "$export" ] && [ "$logkey" ]; then + logkeyfile=`find / -maxdepth 4 -name *.log -type f -exec grep -lHn $keyword {} \; 2>/dev/null` + mkdir --parents $format/keyword_file_matches/log_files/ 2>/dev/null + for i in $logkeyfile; do cp --parents $i $format/keyword_file_matches/log_files/ ; done 2>/dev/null + 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 "\e[00;31m[-] Find keyword ($keyword) in .ini files (recursive 4 levels - output format filepath:identified line number where keyword appears):\e[00m\n$inikey" + echo -e "\n" + else + echo -e "\e[00;31m[-] Find keyword ($keyword) in .ini files (recursive 4 levels):\e[00m" + echo -e "'$keyword' not found in any .ini files" + echo -e "\n" + fi +fi + +if [ "$keyword" = "" ];then + : + else + if [ "$export" ] && [ "$inikey" ]; then + inikey=`find / -maxdepth 4 -name *.ini -type f -exec grep -lHn $keyword {} \; 2>/dev/null` + mkdir --parents $format/keyword_file_matches/ini_files/ 2>/dev/null + for i in $inikey; do cp --parents $i $format/keyword_file_matches/ini_files/ ; done 2>/dev/null + fi +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 "\e[00;31m[-] All *.conf files in /etc (recursive 1 level):\e[00m\n$allconf" + echo -e "\n" +fi + +if [ "$export" ] && [ "$allconf" ]; then + mkdir $format/conf-files/ 2>/dev/null + for i in $allconf; do cp --parents $i $format/conf-files/; done 2>/dev/null +fi + +#extract any user history files that are accessible +usrhist=`ls -la ~/.*_history 2>/dev/null` +if [ "$usrhist" ]; then + echo -e "\e[00;31m[-] Current user's history files:\e[00m\n$usrhist" + echo -e "\n" +fi + +if [ "$export" ] && [ "$usrhist" ]; then + mkdir $format/history_files/ 2>/dev/null + for i in $usrhist; do cp --parents $i $format/history_files/; done 2>/dev/null +fi + +#can we read roots *_history files - could be passwords stored etc. +roothist=`ls -la /root/.*_history 2>/dev/null` +if [ "$roothist" ]; then + echo -e "\e[00;33m[+] Root's history files are accessible!\e[00m\n$roothist" + echo -e "\n" +fi + +if [ "$export" ] && [ "$roothist" ]; then + mkdir $format/history_files/ 2>/dev/null + cp $roothist $format/history_files/ 2>/dev/null +fi + +#all accessible .bash_history files in /home +checkbashhist=`find /home -name .bash_history -print -exec cat {} 2>/dev/null \;` +if [ "$checkbashhist" ]; then + echo -e "\e[00;31m[-] Location and contents (if accessible) of .bash_history file(s):\e[00m\n$checkbashhist" + echo -e "\n" +fi + +#any .bak files that may be of interest +bakfiles=`find / -name *.bak -type f 2/dev/null` +if [ "$readmail" ]; then + echo -e "\e[00;31m[-] Any interesting mail in /var/mail:\e[00m\n$readmail" + echo -e "\n" +fi + +#can we read roots mail +readmailroot=`head /var/mail/root 2>/dev/null` +if [ "$readmailroot" ]; then + echo -e "\e[00;33m[+] We can read /var/mail/root! (snippet below)\e[00m\n$readmailroot" + echo -e "\n" +fi + +if [ "$export" ] && [ "$readmailroot" ]; then + mkdir $format/mail-from-root/ 2>/dev/null + cp $readmailroot $format/mail-from-root/ 2>/dev/null +fi +} + +docker_checks() +{ + +#specific checks - check to see if we're in a docker container +dockercontainer=` grep -i docker /proc/self/cgroup 2>/dev/null; find / -name "*dockerenv*" -exec ls -la {} \; 2>/dev/null` +if [ "$dockercontainer" ]; then + echo -e "\e[00;33m[+] Looks like we're in a Docker container:\e[00m\n$dockercontainer" + echo -e "\n" +fi + +#specific checks - check to see if we're a docker host +dockerhost=`docker --version 2>/dev/null; docker ps -a 2>/dev/null` +if [ "$dockerhost" ]; then + echo -e "\e[00;33m[+] Looks like we're hosting Docker:\e[00m\n$dockerhost" + echo -e "\n" +fi + +#specific checks - are we a member of the docker group +dockergrp=`id | grep -i docker 2>/dev/null` +if [ "$dockergrp" ]; then + echo -e "\e[00;33m[+] We're a member of the (docker) group - could possibly misuse these rights!\e[00m\n$dockergrp" + echo -e "\n" +fi + +#specific checks - are there any docker files present +dockerfiles=`find / -name Dockerfile -exec ls -l {} 2>/dev/null \;` +if [ "$dockerfiles" ]; then + echo -e "\e[00;31m[-] Anything juicy in the Dockerfile:\e[00m\n$dockerfiles" + echo -e "\n" +fi + +#specific checks - are there any docker files present +dockeryml=`find / -name docker-compose.yml -exec ls -l {} 2>/dev/null \;` +if [ "$dockeryml" ]; then + echo -e "\e[00;31m[-] Anything juicy in docker-compose.yml:\e[00m\n$dockeryml" + echo -e "\n" +fi +} + +lxc_container_checks() +{ + +#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 "\e[00;33m[+] Looks like we're in a lxc container:\e[00m\n$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 "\e[00;33m[+] We're a member of the (lxd) group - could possibly misuse these rights!\e[00m\n$lxdgroup" + echo -e "\n" +fi +} + +footer() +{ +echo -e "\e[00;33m### SCAN COMPLETE ####################################\e[00m" +} + +call_each() +{ + header + debug_info + system_info + user_info + environmental_info + job_info + networking_info + services_info + software_configs + interesting_files + docker_checks + lxc_container_checks + footer +} + +while getopts "h:k:r:e:st" option; do + case "${option}" in + k) keyword=${OPTARG};; + r) report=${OPTARG}"-"`date +"%d-%m-%y"`;; + e) export=${OPTARG};; + s) sudopass=1;; + t) thorough=1;; + h) usage; exit;; + *) usage; exit;; + esac +done + +call_each | tee -a $report 2> /dev/null +#EndOfScript diff --git a/Introduccion-hacking-hack4u/tema_5_conceptos/README.md b/Introduccion-hacking-hack4u/tema_5_conceptos/README.md index bf8b45c..2131081 100644 --- a/Introduccion-hacking-hack4u/tema_5_conceptos/README.md +++ b/Introduccion-hacking-hack4u/tema_5_conceptos/README.md @@ -181,12 +181,31 @@ Algunas de las herramientas que vemos en esta clase son: Asimismo, desarrollaremos un script en Bash ideal para detectar tareas y comandos que se ejecutan en el sistema a intervalos regulares de tiempo, abusando para ello del comando ‘ps -eo user,command‘ que nos chivará todo lo que necesitamos. -A continuación, se proporciona el enlace a estas herramientas: - - Herramienta LSE: https://github.com/diego-treitos/linux-smart-enumeration +- Herramienta LinEnum (Más viejita): - Herramienta PSPY: https://github.com/DominicBreuker/pspy +- script propio: [procmon.sh](procmon.sh) + + +- Para buscar binarios que se puedan ejecutar con permisos de root: https://gtfobins.github.io/ +- https://book.hacktricks.xyz/welcome/readme + + + ## 5.5 Introducción a BurpSuite +BurpSuite es una herramienta de prueba de penetración utilizada para encontrar vulnerabilidades de seguridad en aplicaciones web. Es una de las herramientas de prueba de penetración más populares y utilizadas en la industria de la seguridad informática. BurpSuite se compone de varias herramientas diferentes que se pueden utilizar juntas para identificar vulnerabilidades en una aplicación web. +Las principales herramientas que componen BurpSuite son las siguientes: + +- Proxy: Es la herramienta principal de BurpSuite y actúa como un intermediario entre el navegador web y el servidor web. Esto permite a los usuarios interceptar y modificar las solicitudes y respuestas HTTP y HTTPS enviadas entre el navegador y el servidor. El Proxy también es útil para la identificación de vulnerabilidades, ya que permite a los usuarios examinar el tráfico y analizar las solicitudes y respuestas. +- Scanner: Es una herramienta de prueba de vulnerabilidades automatizada que se utiliza para identificar vulnerabilidades en aplicaciones web. El Scanner utiliza técnicas de exploración avanzadas para detectar vulnerabilidades en la aplicación web, como inyecciones SQL, cross-site scripting (XSS), vulnerabilidades de seguridad de la capa de aplicación (OSWAP Top 10) y más. +- Repeater: Es una herramienta que permite a los usuarios reenviar y repetir solicitudes HTTP y HTTPS. Esto es útil para probar diferentes entradas y verificar la respuesta del servidor. También es útil para la identificación de vulnerabilidades, ya que permite a los usuarios probar diferentes valores y detectar respuestas inesperadas. +- Intruder: Es una herramienta que se utiliza para automatizar ataques de fuerza bruta. Los usuarios pueden definir diferentes payloads para diferentes partes de la solicitud, como la URL, el cuerpo de la solicitud y las cabeceras. Posteriormente, Intruder automatiza la ejecución de las solicitudes utilizando diferentes payloads y los usuarios pueden examinar las respuestas para identificar vulnerabilidades. +- Comparer: Es una herramienta que se utiliza para comparar dos solicitudes HTTP o HTTPS. Esto es útil para detectar diferencias entre las solicitudes y respuestas y analizar la seguridad de la aplicación. + +Se trata de una herramienta extremadamente potente, la cual puede ser utilizada para identificar una amplia variedad de vulnerabilidades de seguridad en aplicaciones web. Al utilizar las diferentes herramientas que componen BurpSuite, los usuarios pueden identificar vulnerabilidades de forma automatizada o manual, según sus necesidades. Esto permite a los usuarios encontrar vulnerabilidades y corregirlas antes de que sean explotadas por un atacante. + +https://portswigger.net/burp/communitydownload diff --git a/Introduccion-hacking-hack4u/tema_5_conceptos/lse.sh b/Introduccion-hacking-hack4u/tema_5_conceptos/lse.sh new file mode 100755 index 0000000..7a84aaf --- /dev/null +++ b/Introduccion-hacking-hack4u/tema_5_conceptos/lse.sh @@ -0,0 +1,1577 @@ +#!/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 +# 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%%/}" + lse_find_opts="$lse_find_opts -path ${p} -prune -o" + done +} #) +lse_set_level() { #( + case "$1" in + 0|1|2) + lse_level=$(($1)) + ;; + *) + lse_error "Invalid level." + exit 1 + ;; + esac +} #) +lse_help() { #( + echo "Use: $0 [options]" + echo + echo " OPTIONS" + echo " -c Disable color" + echo " -C Use alternative color scheme" + echo " -i Non interactive mode" + echo " -h This help" + echo " -l LEVEL Output verbosity level" + echo " 0: Show highly important results. (default)" + echo " 1: Show interesting results." + echo " 2: Show all gathered information." + echo " -s SELECTION Comma separated list of sections or tests to run. Available" + echo " sections:" + echo " usr: User related tests." + echo " sud: Sudo related tests." + echo " fst: File system related tests." + echo " sys: System related tests." + echo " sec: Security measures related tests." + echo " ret: Recurrent tasks (cron, timers) related tests." + echo " net: Network related tests." + echo " srv: Services related tests." + echo " pro: Processes related tests." + echo " sof: Software related tests." + echo " ctn: Container (docker, lxc) related tests." + echo " cve: CVE related tests." + echo " Specific tests can be used with their IDs (i.e.: usr020,sud)" + echo " -e PATHS Comma separated list of paths to exclude. This allows you" + echo " to do faster scans at the cost of completeness" + echo " -p SECONDS Time that the process monitor will spend watching for" + echo " processes. A value of 0 will disable any watch (default: 60)" + echo " -S Serve the lse.sh script in this host so it can be retrieved" + echo " from a remote host." +} #) +lse_ask() { #( + local question="$1" + # We use stderr to print the question + cecho "${white}${question}: ${reset}" >&2 + read -r answer + case "$answer" in + y|Y|yes|Yes|ok|Ok|true|True) + return 0 + ;; + *) + echo "$answer" + return 1 + ;; + esac +} #) +lse_request_information() { #( + if $lse_interactive; then + cecho "${grey}---\n" + [ -z "$lse_user" ] && lse_user=`lse_ask "Could not find current user name. Current user?"` + lse_pass=`lse_ask "If you know the current user password, write it here to check sudo privileges"` + cecho "${grey}---\n" + fi +} #) +lse_test_passed() { #( + # Checks if a test passed by ID + local id="$1" + for i in $lse_passed_tests; do + [ "$i" = "$id" ] && return 0 + done + return 1 +} #) +lse_test() { #( + # Test id + local id="$1" + # Minimum level required for this test to show its output + local level=$(($2)) + # Name of the current test + local name="$3" + # Output of the test + local cmd="$4" + # Dependencies + local deps="$5" + # Variable name where to store the output + local var="$6" + # Flags affecting the execution of certain tests + local flags="$7" + + # Define colors + local l="${lred}!" + local r="${lgreen}" + [ $level -eq 1 ] && l="${lyellow}*" && r="${cyan}" + [ $level -eq 2 ] && l="${lblue}i" && r="${blue}" + + # Filter selected tests + if [ "$lse_selection" ]; then + local sel_match=false + for s in $lse_selection; do + if [ "$s" = "$id" ] || [ "$s" = "`printf \"%s\" \"$id\" | cut -c1-3`" ]; then + sel_match=true + fi + done + $sel_match || return 0 + fi + + # DEBUG messages + $lse_DEBUG && cecho "${lmagenta}DEBUG: ${lgreen}Executing: ${reset}$cmd\n" + + # Print name and line + cecho "${white}[${l}${white}] ${grey}${id}${white} $name${grey}" + for i in $(seq $((${#id}+${#name}+10)) 79); do + printf "." + done + + # Check if test should be skipped when running as root + if [ "$lse_user_id" -eq 0 ] && [ "$flags" = "rootskip" ]; then + cecho " ${grey}skip\n" + return 1 + fi + + # Check dependencies + local non_met_deps="" + for d in $deps; do + lse_test_passed "$d" || non_met_deps="$non_met_deps $d" + done + if [ "$non_met_deps" ]; then + cecho " ${grey}skip\n" + # In "selection mode" we print the missed dependencies + if [ "$lse_selection" ]; then + cecho "${red}---\n" + cecho "Dependencies not met:$reset $non_met_deps\n" + cecho "${red}---$reset\n" + fi + return 1 + fi + + # If level is 2 and lse_level is less than 2, then we do not execute + # level 2 tests unless their output needs to be assigned to a variable + if [ $level -ge 2 ] && [ $lse_level -lt 2 ] && [ -z "$var" ]; then + cecho " ${grey}skip\n" + return 1 + else + if $lse_DEBUG; then + output="`eval "$cmd" 2>&1`" + else + # Execute command if this test's level is in scope + output="`eval "$cmd" 2>/dev/null`" + # Assign variable if available + fi + [ "$var" ] && [ "$output" ] && readonly "${var}=$output" + # Mark test as executed + lse_executed_tests="$lse_executed_tests $id" + fi + + if [ -z "$output" ]; then + cecho " ${grey}nope${reset}\n" + return 1 + else + lse_passed_tests="$lse_passed_tests $id" + cecho "${r} yes!${reset}\n" + if [ $lse_level -ge $level ]; then + cecho "${grey}---$reset\n" + echo "$output" + cecho "${grey}---$reset\n" + fi + return 0 + fi +} #) +lse_show_info() { #( + echo + cecho "${lcyan} LSE Version:${reset} $lse_version\n" + echo + cecho "${lblue} User:${reset} $lse_user\n" + cecho "${lblue} User ID:${reset} $lse_user_id\n" + cecho "${lblue} Password:${reset} " + if [ -z "$lse_pass" ]; then + cecho "${grey}none${reset}\n" + else + cecho "******\n" + fi + cecho "${lblue} Home:${reset} $lse_home\n" + cecho "${lblue} Path:${reset} $PATH\n" + cecho "${lblue} umask:${reset} `umask 2>/dev/null`\n" + + echo + cecho "${lblue} Hostname:${reset} $lse_hostname\n" + cecho "${lblue} Linux:${reset} $lse_linux\n" + if [ "$lse_distro" ]; then + cecho "${lblue}Distribution:${reset} $lse_distro\n" + fi + cecho "${lblue}Architecture:${reset} $lse_arch\n" + echo + cecho "${green}=====================(${yellow} Current Output Verbosity Level: ${cyan}$lse_level ${green})======================${reset}" + echo + if [ "$lse_user_id" -eq 0 ]; then + cecho "${green}============(${yellow} Already running as ${red}root${yellow}, some tests will be skipped! ${green})============${reset}" + echo + fi +} #) +lse_serve() { #( + # get port + which nc >/dev/null || lse_error "Could not find 'nc' netcat binary." + + local_ips="`ip a | grep -Eo "inet ([0-9]{1,3}\.){3}[0-9]{1,3}" | cut -d' ' -f2`" + + # Get a valid and non used port + port=`od -An -N2 -i /dev/random|grep -Eo '[0-9]+'` + port_valid=true + while true; do + for ip in $local_ips; do + nc -z "$ip" "$port" && port_valid=false + done + if [ $((port)) -lt 1024 ] || [ $((port)) -gt 65500 ]; then + port_valid=false + fi + $port_valid && break + port=`od -An -N2 -i /dev/random|grep -Eo '[0-9]+'` + done + + echo + cecho " Serving ${white}Linux Smart Enumeration${reset} on port ${blue}$port${reset}.\n" + echo + cecho " Depending on your IP and available tools, some of these commands should download it in a remote host:\n" + for ip in $local_ips; do + [ "$ip" = "127.0.0.1" ] && continue + echo + cecho "${reset} [${blue}$ip${reset}]\n" + cecho "${green} * ${white}nc ${reset} $ip $port > lse.sh /dev/tcp/${reset}$ip/$port;printf '\\\\n'>&3;cat<&3>lse.sh;exec 3<&-;chmod 755 lse.sh\n" + done + # try nc with '-N' (openbsd), then ncat and then use '-q0' (traditional) + nc -l -N -p "$port" < "$0" >/dev/null 2>/dev/null || nc -l --send-only -p "$port" < "$0" >/dev/null 2>/dev/null || nc -l -q0 -p "$port" < "$0" >/dev/null +} #) +lse_header() { #( + local id="$1" + shift + local title="$*" + local text="${magenta}" + + # Filter selected tests + if [ "$lse_selection" ]; then + local sel_match=false + for s in $lse_selection; do + if [ "`printf \"%s\" \"$s\"|cut -c1-3`" = "$id" ]; then + sel_match=true + break + fi + done + $sel_match || return 0 + fi + + for i in $(seq ${#title} 70); do + text="$text=" + done + text="$text(${green} $title ${magenta})=====" + cecho "$text${reset}\n" +} #) +lse_exit() { #( + local ec=1 + local text="\n${magenta}==================================" + [ "$1" ] && ec=$1 + text="$text(${green} FINISHED ${magenta})==================================" + cecho "$text${reset}\n" + rm -f "$lse_procmon_data" + rm -f "$lse_procmon_lock" + rm -f "$lse_cve_tmp" + exit "$ec" +} #) +lse_procmon() { #( + # monitor processes + #NOTE: The first number will be the number of occurrences of a process due to + # uniq -c + local ps_args + local ps_busybox + if ps -V 2>&1 | grep -iq busybox; then + ps_args='-o pid,user,args' + ps_busybox=true + else + ps_args="-ewwwo start_time,pid,user:50,args" + ps_busybox=false + fi + while [ -f "$lse_procmon_lock" ]; do + if $ps_busybox; then + ps $ps_args | sed 's/^\([0-9]*\)/? \1 /g' + else + ps $ps_args + fi + sleep 0.001 + done | grep -Ev "(pid,user|$lse_user *sed s/)" | sed 's/^ *//g' | tr -s '[:space:]' | grep -Ev "PID *USER *COMMAND" | grep -Ev '[^ ]+ [^ ]+ [^ ]+ \[' | sort -Mr | uniq -c | sed 's/^ *//g' > "$lse_procmon_data" +} #) +lse_proc_print() { #( + # Pretty prints output from lse_procmom received via stdin + if $lse_color; then + printf "${green}%s %8s %8s %s\n" "START" "PID" "USER" "COMMAND" + else + printf "%s %8s %8s %s\n" "START" "PID" "USER" "COMMAND" + fi + while read -r l; do + p_num=`echo "$l" | cut -d" " -f1` + p_time=`echo "$l" | cut -d" " -f2` + p_pid=`echo "$l" | cut -d" " -f3` + p_user=`echo "$l" | cut -d" " -f4` + p_args=`echo "$l" | cut -d" " -f5-` + + if $lse_color; then + if [ $((p_num)) -lt 20 ]; then # few times probably periodic + printf "${red}%s ${reset}%8s ${yellow}%8s ${red}%s\n" "$p_time" "$p_pid" "$p_user" "$p_args" + else + printf "${magenta}%s ${reset}%8s ${yellow}%8s ${reset}%s\n" "$p_time" "$p_pid" "$p_user" "$p_args" + fi + else + printf "%s %8s %8s %s\n" "$p_time" "$p_pid" "$p_user" "$p_args" + fi + done +} #) +lse_get_distro_codename() { #( + # Get the distribution name + # + # ubuntu, debian, centos, redhat, opsuse, fedora, rocky + local distro="${grey}unknown${reset}" + if type lsb_release >/dev/null 2>&1; then + distro=`lsb_release -is` + elif [ -f /etc/os-release ]; then + distro=`grep -E '^ID=' /etc/os-release | cut -f2 -d=` + echo "$distro" | grep -qi opensuse && distro=opsuse + echo "$distro" | grep -qi rhel && distro=redhat + elif [ -f /etc/redhat-release ]; then + grep -qi "centos" /etc/redhat-release && distro=centos + grep -qi "fedora" /etc/redhat-release && distro=fedora + grep -qi "red hat" /etc/redhat-release && distro=redhat + grep -qi "rocky" /etc/redhat-release && distro=rocky + fi + printf '%s' "$distro" | tr '[:upper:]' '[:lower:]' | tr -d \"\' +} #) +lse_is_version_bigger() { #( + # check if version v1 is bigger than v2 + local v1="$1"; local v2="$2" ; local vc + [ "$v1" = "$v2" ] && return 1 # equal is not bigger + vc="`printf "%s\n%s\n" "$v1" "$v2" | sort -rV | head -n1`" + [ "$v1" = "$vc" ] && return 0 + return 1 +} #) +lse_get_pkg_version() { #( + # get package version depending on distro + # returns 2 if distro is unknown + # returns 1 if package is not installed (or doesn't exist) + # returns 0 on success, and prints out the package version + pkg_name="$1" + case "$lse_distro_codename" in + debian|ubuntu) + pkg_version=`dpkg -l "$pkg_name" 2>/dev/null | grep -E '^[ih]i' | tr -s ' ' | cut -d' ' -f3` + ;; + centos|redhat|fedora|opsuse|rocky|amzn) + pkg_version=`rpm -q "$pkg_name" 2>/dev/null` + pkg_version="${pkg_version##"$pkg_name"-}" + pkg_version=`echo "$pkg_version" | sed -E 's/\.(aarch64|armv7hl|i686|noarch|ppc64le|s390x|x86_64)$//'` + ;; + *) + return 2 + ;; + esac + [ -z "$pkg_version" ] && return 1 + printf "%s" "$pkg_version" + return 0 +} #) +#) +#) + +########################################################################( TESTS +# +# A successful test will receive some output while a failed tests will receive +# an empty string. +# +########################################################################( users +lse_run_tests_users() { + lse_header "usr" "users" + + #user groups + lse_test "usr000" "2" \ + "Current user groups" \ + 'groups' \ + "" \ + "lse_user_groups" + + #user in an administrative group + lse_test "usr010" "1" \ + "Is current user in an administrative group?" \ + 'grep $lse_grep_opts -E "^(adm|admin|root|sudo|wheel)" /etc/group | grep $lse_grep_opts -E "(:|,)$lse_user"' + + #other users in an administrative group + lse_test "usr020" "1" \ + "Are there other users in administrative groups?" \ + 'grep $lse_grep_opts -E "^(adm|admin|root|sudo|wheel)" /etc/group | grep -Ev ":$|:$lse_user$" | grep $lse_grep_opts -Ei ":[,a-z_-]+\$"' + + #other users with shell + lse_test "usr030" "1" \ + "Other users with shell" \ + 'grep $lse_grep_opts -E ":/[a-z/]+sh\$" /etc/passwd' \ + "" \ + "lse_shell_users" + + #user env information + lse_test "usr040" "2" \ + "Environment information" \ + 'env | grep -v "LS_COLORS"' + + #dump user groups + lse_test "usr050" "2" \ + "Groups for other users" \ + 'cat /etc/group' + + #dump users + lse_test "usr060" "2" \ + "Other users" \ + 'cat /etc/passwd' + + #find defined PATHs + lse_test "usr070" "1" \ + "PATH variables defined inside /etc" \ + 'for p in `grep -ERh "^ *PATH=.*" /etc/ 2> /dev/null | tr -d \"\'"'"' | cut -d= -f2 | tr ":" "\n" | sort -u`; do [ -d "$p" ] && echo "$p";done' \ + "" \ + "lse_exec_paths" + + #check if . is in PATHs + lse_test "usr080" "0" \ + "Is '.' in a PATH variable defined inside /etc?" \ + 'for ep in $lse_exec_paths; do [ "$ep" = "." ] && grep -ER "^ *PATH=.*" /etc/ 2> /dev/null | tr -d \"\'"'"' | grep -E "[=:]\.([:[:space:]]|\$)";done' \ + "usr070" +} +#) + +#########################################################################( sudo +lse_run_tests_sudo() { + lse_header "sud" "sudo" + + #variables for sudo checks + lse_sudo=false + lse_sudo_commands="" + + #can we sudo without supplying a password + lse_test "sud000" "0" \ + "Can we sudo without a password?" \ + 'echo "" | sudo -nS id' && lse_sudo=true + + #can we list sudo commands without supplying a password + $lse_sudo || \ + lse_test "sud010" "0" \ + "Can we list sudo commands without a password?" \ + 'echo "" | sudo -nS -l' \ + "" \ + "lse_sudo_commands" + + if [ "$lse_pass" ]; then + #can we sudo supplying a password + $lse_sudo || \ + lse_test "sud020" "0" \ + "Can we sudo with a password?" \ + 'echo "$lse_pass" | sudo -S id' && lse_sudo=true + + #can we list sudo commands without supplying a password + if ! $lse_sudo && [ -z "$lse_sudo_commands" ]; then + lse_test "sud030" "0" \ + "Can we list sudo commands with a password?" \ + 'echo "$lse_pass" | sudo -S -l' \ + "" \ + "lse_sudo_commands" + fi + fi + + #check if we can read the sudoers file + lse_test "sud040" "1" \ + "Can we read sudoers files?" \ + 'grep -R "" /etc/sudoers*' + + #check users that sudoed in the past + lse_test "sud050" "1" \ + "Do we know if any other users used sudo?" \ + 'for uh in $(cut -d: -f1,6 /etc/passwd); do [ -f "${uh##*:}/.sudo_as_admin_successful" ] && echo "${uh%%:*}"; 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 "$@" +#) diff --git a/Introduccion-hacking-hack4u/tema_5_conceptos/procmon.sh b/Introduccion-hacking-hack4u/tema_5_conceptos/procmon.sh new file mode 100755 index 0000000..0803832 --- /dev/null +++ b/Introduccion-hacking-hack4u/tema_5_conceptos/procmon.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +function ctrl_c(){ + echo -e "\n\n[!] Saliendo...\n" + tput cnorm; exit 1 +} + +# Ctrl+C +trap ctrl_c SIGINT + +old_process=$(ps -eo user,command) + +tput civis # Ocultar cursor + +while true; do + new_process=$(ps -eo user,command) + diff <(echo "$old_process") <(echo "$new_process") | grep "[\>\<]" | grep -vE "command|kworker|procmon" + old_process=$new_process +done diff --git a/Introduccion-hacking-hack4u/tema_5_conceptos/pspy b/Introduccion-hacking-hack4u/tema_5_conceptos/pspy new file mode 100755 index 0000000..f11f6af Binary files /dev/null and b/Introduccion-hacking-hack4u/tema_5_conceptos/pspy differ