Initial Enumeration

We can have a look for the installed shells using cat /etc/shells and we can gain an interactive session if we do not already have one using /bin/bash -i We can look for exploits which target out of date shells - we will need to know the versions of the shells which are installed on the system.

We can try to upgrade our shell using python. We will want to enumerate the python version using python --version If python is installed on the victim machine, we can try using python -c 'import pty;pty.spawn("/bin/bash");' to upgrade our shell.

If we cannot find python, we can try using perl. We can check to see if perl is installed on the compromised machine using perl --help and assuming it is we can try to upgrade our shell using perl -e 'exec "/bin/bash";'

We can take a look at the environment variables using env and if the PATH variable is missing we can set it using export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin and if the TERM variable is not set we can set it using export TERM=xterm We could also set the shell using export SHELL=bash

We can try to find files which the current user has write permissions for using: find / -path /proc -prune -o -type f -perm -o+w 2>/dev/null If we find that /etc/passwd is writeable, we can add a new user entry and give them a uid of 0 and a gid of 0 along with a password hash which we create and therefore control.

We can look for a quick priv esc win by checking the current user's sudo configuration with sudo -l

It is also worthwhile to check the version of sudo installed as older versions can be vulnerable to exploits: sudo -V

System Information

When we land on a linux machine, we will need to enumerate information relating to the system itself. We will want to know more about:

We can use: hostname to find the name of the compromised host. We can find out more about the host using: uname -a This will also show us the linux kernel version. If we want to focus only on the kernel version, we can use: uname -r We can also look at cat /proc/version

We can look for the distribution with: cat /etc/issue We can find more information relating to the distribution using: cat /etc/*release The command: cat /proc/version also shows us information about the kernel and distribution.

Once we know the os and version, we need to have a look at the release cycles for it to see if it is out of date or still being maintained. If we are working on a ubuntu machine, we can check here Wikipedia also has good information regarding os release cycles.

We can see the environment variables for the compromised user (including the path environment variable) using: env We might find something sensitive such as a password in the environment variables.

We can find out more about the cpu using: lscpu This will show us the architecture of the cpu.

We can use: df -h to see the file systems mounted on the compromised machine. We can use: lsblk to look at devices.

We need to also look for unmounted file systems as we might be able to mount them and find sensitive data on them. We can look for unmounted file systems using: cat /etc/fstab | grep -v "#" | column -t In order to mount them, we will need to be acting under root privileges.

To list the installed packages on the compromised machine, we can use: dpkg -l This will return lots of results. We can make it faster to look through them by using: dpkg -l | more

We can create a file which contains all installed packages on the system. This can be useful as we can then use grep to search for specific packages such as apparmor or snort

apt list --installed | tr "/" " " | cut -d" " -f1,3 | sed 's/[0-9]://g' | tee -a installed_pkgs.list

Once we have a list of installed binaries, we can compare them to gtfobins to see if any are vulnerable:

for i in $(curl -s https://gtfobins.github.io/ | html2text | cut -d" " -f1 | sed '/^[[:space:]]*$/d');do if grep -q "$i" installed_pkgs.list;then echo "Check GTFO for: $i";fi;done

We can make a similar list of binaries which have the suid bit set when we are looking for priv esc opportunities. This can be cross referenced with ... as on a regular linux system there may well be lots of binaries returned and we will want to quickly focus in on those which might have priv esc vulns we can use.

find / -perm -4000 -type f 2>/dev/null | tr "/" " " | rev | cut -d" " -f1 | sed 's/[0-9]://g' | rev | tee -a suid_bins.txt

Linux Users and Groups

We are looking for:

To find out more about the current user, we can use: id and whoami We can check which groups they belong to we can use: groups bob If we see that they are members of the root or sudo groups then we know they have higher privileges. If the user is in the sudo group, we can try sudo -l to see which commands they can run.

To find other users on the compromised machine, we can use: cat /etc/passwd This will show us user and service accounts. User accounts will have the specification for which shell they use - this is at the end of the displayed data - for example /bin/bash Service accounts are set up to manage services rather than to allow users to log into the machine, so they do not have shells set up - they will typically have /usr/sbin/nologin listed at the end of their data. An example of this is the www-data user which is set up to manage apache2. Knowing this, we can search for other user accounts which are not services using: cat /etc/passwd | grep -v /nologin

If we want to only see the usernames, we can use: cat /etc/passwd | cut -d : -f 1

We can also check the /home directory to see if there are any other usernames in there.

We can add a new user using: useradd bob -s /bin/bash and we can then add the user to the root group using: usermod -aG root bob though this is not recommended practise. If we want the new user to have a home directory, we need to include the -m flag with the useradd command.

We can look for groups using: cat /etc/group If we find interesting groups, we can check which users belong to it using getent group sudo

We can check for logged in users using: w or who if those binaries are installed on the compromised system. We can use: last to look for the latest logons.

The lastlog command will show us the users and when they last logged in. We can use this to see if a user has used ssh to log onto the system.

We can have a look at recently used shell commands using: cat /home/bob/.bash_history or just the history command.

When it comes to looking for history files, it is worthwhile looking for special history files which are created by scripts or programs - these might be monitoring the system and activities of its users: find / -type f \( -name *_hist -o -name *_history \) -exec ls -l {} \; 2>/dev/null

Linux Network Information

We are looking for:

We can use ifconfig to find the IP address and network adapter information. If this command does not work, we can try ip a or ip a s We could also try looking at cat /etc/networks

We can have a look at cat /etc/hosts if we are trying to find internal domains to access as it is configured locally. We can find the dns configuration by looking at cat /etc/resolv.conf

We can look for other hosts using arp -a If the arp command is not installed and we have access to a meterpreter session, we can use arp from within the meterpreter session. We can also look for other hosts using ip neigh

We can look at routing information using route and ip route The command netstat -r will also show us routing information. If we want to add a new route via a specified gateway, we can use: ip route add 192.168.222.0/24 via 10.52.14.1

The netstat -ano command will show us active connections to other hosts which might only be on the internal network. The ss -at command will also do this.

The top command will show us running processes dynamically.

We can perform a ping sweep of a network using: for i in {1..254} ;do (ping -c 1 172.16.5.$i | grep "bytes from" &) ;done A ping sweep will need to be tried several times and it might not work even then as often icmp traffic is dropped by networks.

Linux Processes, Cron Jobs and Hidden / Temporary Resources

We are looking for:

To find running processes, we can use ps or ps aux if we want more information regarding them.

We can use top to look at the running processes - this is a dynamic command.

We will want to know more about cron jobs which have been scheduled as they can potentially provide us with privilege escalation opportunities. We can have a look at the cron jobs for the current user using: crontab -l The crontab process executes at boot and manages the scheduled cron jobs.

We can use different commands to enumerate the cron table. One way is to use cat /etc/crontab Another is ls -al /etc/cron* and another is systemctl list-timers -all

We can look for hidden files using: find / -type f -name ".*" -exec ls -l {} \; 2>/dev/null | grep billybob

We can look for hidden directories using: find / -type d -name ".*" -ls 2>/dev/null

The directories on linux systems which store data on a temporary basis are worth looking into as there might be interesting log files or other data in them. The /tmp directory stores data for ten days whereas the /var/tmp directory stores it for thirty days. Furthermore, the data in the /tmp directory is deleted at every reboot whereas the data in /var/tmp is not so it is used for data which needs to survive reboots. The /dev/shm directory is also used to store data on a temporary basis.

We can look for temporary data using: ls -l /tmp /var/tmp /dev/shm

Password Hunting

The /var directory is a good place to start looking for credentials. This is because it usually contains the web root. Credntials and database credentials are typically found in the web root.

A common example of database credentials being found in the web root is mysql creds in wordpress configuration files: cat wp-config.php | grep 'DB_USER\|DB_PASSWORD'

The spool or mail directories may also contain credentials.

We can look for passwords using various commands. To find files which contain the string password we can use locate password | more

We can look for the string password and colour it using: grep --color=auto -rnw '/' -ie "PASSWORD" --color=always 2>/dev/null

We can check the current directory and its child directories for the string password using: find . -type f -exec grep -i -I "PASSWORD" {} /dev/null \;

We can do the same thing as the above command but also colour the string password using: find . -type f -exec grep --color=auto -ie "PASSWORD" --color=always {} /dev/null \;

The strings username and password can give lots of results, so we can try to be more specific first of all with strings such as:

It is also worth looking for files which end .conf or .config as they might contain usernames, passwords or other sensitive data.

find / -type f \( -name *.conf -o -name *.config \) -exec ls -l {} \; 2>/dev/null

find / ! -path "*/proc/*" -iname "*config*" -type f 2>/dev/null

It is worthwhile looking at .sh files (shell scripts) as well as they can reveal interesting data: find / -type f -name "*.sh" 2>/dev/null | grep -v "src\|snap\|share"

We can also check .xml files, .bak files and even .txt files.

If we do find passwords, it is worth trying them with all the user accounts which we have discovered as password reuse is common.

If we want to try to find the public ssh keys of users who have access to the compromised machine, we can use: find / -name authorized_keys 2>/dev/null

We can look for private ssh keys on the compromised machine using: find / -name id_rsa 2>/dev/null If we find a private ssh key, we can try to gain access to other machines on the network or even the compromised machine itself using ssh along with the looted private key. We will need to copy the private key to our attacking machine first of all and change its permissions using chmod 600 id_rsa as ssh will not accept a private key which has lax permissions.

It might be that users are using their ssh keys to ssh into machines which are on other subnets which they can access - it makes sense therefore to try any discovered private keys from the compromised machine on any hosts which we have found on other subnets or in the arp cache. We can check the known_hosts file to look for target machines when we find ssh keys on a system.

Automating Linux Enumeration

We can use meterpreter post exploitation modules to automate some enumeration of a linux machine. We can use run post/linux/gather/enum_configs to find info in common configuration files. We can use run post/linux/gather/enum_network to find out more about the networks. The command run post/linux/gather/enum_system gives us lots of information about the system, users and processes along with cronjobs. We can use run post/linux/gather/checkvm to check if the victim machine is a virtual machine.

We can use LinEnum's shell script. We need to transfer it to the victim machine first. We can run it using ./linenum.sh We can save the output with a name for the report using ./linenum.sh -r report -e /tmp/ We can add the -t switch to use thorough tests which are slower than the default ones.

We can also use linpeas.sh after we have transfered it to the victim machine. We can run it using ./lp.sh

We need to make sure we can execute the above shell scripts - to do this we can use chmod +x linenum.sh