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:
- Linux System Information
- Hostname
- Distribution and distribution release version
- Kernel version and architecture
- CPU information
- Disk information and mounted drives
- Installed packages and software
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:
- Users and Groups
- Current user and their groups
- Other users on the system
- Groups
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:
- Linux Network Information
- Current IP address and network adaptor
- Internal network addresses
- TCP / UDP services running and their respective ports
- Other hosts on the network
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:
-
- Running services and their process ids
- Cron jobs
- Hidden files
- Hidden directories
- Contents of temporary directories
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:
- Enumerating Credentials
- db_password
- db_passwd
- db_user
- db_username
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