To access material, start machines and answer questions login.
Privilege escalation is a journey. There are no silver bullets, and much depends on the specific configuration of the target system. The kernel version, installed applications, supported programming languages, and other users' passwords are a few key elements that will affect your road to the root shell. This room covers many privilege escalation techniques, and it's designed such that each technique is self-contained in its own task. You can study each task independently, but we recommend doing it in order.
What Does “Privilege Escalation” Mean?
At its core, privilege escalation usually involves going from a lower permission account to a higher permission one. More technically, it's the exploitation of a vulnerability, design flaw, or configuration oversight in an operating system or application to gain unauthorized access to resources that are usually restricted to users.
Why Is It Important?
It's rare when performing a real-world penetration test to be able to gain a foothold (initial access) that gives you direct administrative access. Generally, you'd first gain access to systems as a low-privileged user. Privilege escalation is crucial because it lets you gain system administrator levels of access, which allows you to perform actions such as:
- Resetting passwords
- Bypassing access controls to compromise protected data
- Editing software configurations
- Enabling
- Changing the privilege of existing (or new) users
- Execute any administrative command
This room is designed to cover the main privilege escalation vectors and give you a better understanding of the process. This new skill will be an essential part of your arsenal, whether you are participating in CTFs, taking certification exams, or working as a penetration tester.
Prerequisites
- Fundamentals module
Learning Objectives
- Understand the purpose and importance of enumeration in privilege escalation
- Identify key information using manual enumeration commands
- Find hidden files
- Enumerate users, groups, and permissions on a system
- Enumerate basic network information
- Discover potential privilege escalation vectors through manual enumeration
Ready for some enumeration!
To complete the of this room, you will need to start the target machine by clicking the button below, which will open the machine in split view. If you want to connect to the target from your own -connected machine, you can use the credentials provided below. In this room, you will have to use the attached to gather information about various properties.
Credentials
Only needed if you are using your own machine.
Enumeration is arguably the most critical phase when it comes to privilege escalation. Before you can exploit anything, you need to understand the environment you're working in; what's running, who's running it, and what misconfigurations might exist. This is where manual enumeration comes in. By gathering key information about the system, such as the kernel version, installed applications, user permissions, scheduled tasks, and network configuration, you can start to build a picture of potential attack vectors. Without thorough enumeration, you're essentially working blind, and any exploitation attempts would be guesswork at best. The more you understand about the target system, the more efficiently you can identify and exploit weaknesses to escalate your privileges.
This task will focus on various commands and techniques to enumerate operating system properties, like:
- hostname
- uname
- /proc/version
- /etc/issue
- ps
- cron
- dpkg
The hostname Command
The hostname command will return the hostname of the target machine. Although this value can easily be changed or have a relatively meaningless string (e.g., Ubuntu-3487340239), in some cases, it can provide information about the target system's role within the corporate network (e.g., SQL-PROD-01 for a production server).
The uname Command
The command uname -a will print system information, giving you additional details about the kernel used by the system. This is useful when searching for any potential kernel vulnerabilities that could lead to privilege escalation.
john@home:~$ uname -a
Linux home 6.8.0-41-generic
In the example above, the output is as follows:
- : Operating system
- home: Hostname
- 6.8.0-41-generic: Kernel version
The /proc/version File
The proc filesystem (procfs) provides information about the target system processes. You will find proc on many different Linux flavors, making it an essential tool to have in your arsenal. Looking at /proc/version may give you information on the kernel version or what compiler was used to create it.
john@home:~$ cat /proc/version
Linux version 6.8.0-41-generic (buildd@lcy02-amd64-077) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0, GNU ld (GNU Binutils for Ubuntu) 2.42)
In the example above, the output is as follows:
- 6.8.0-41-generic: Kernel version
- buildd@lcy02-amd64-077: Build machine that compiled the kernel
- x86_64--gnu-gcc-13: Compiler used to build the kernel
- Ubuntu 13.2.0-23ubuntu4: Ubuntu package version of the gcc compiler
- GNU ld (GNU Binutils for Ubuntu) 2.42: Linker used during the kernel build
The /etc/issue File
Systems can also be identified by looking at the /etc/issue file. This file usually contains some information about the operating system, but can easily be customized or changed. Also, any file containing system information can be customized or changed. For a clearer understanding of the system, it is always good to look at all of these.
john@linux-enumeration:~$ cat /etc/issue
Ubuntu 22.04.1 LTS \n \l
In the example above, Ubuntu 22.04.1 LTS represents the Ubuntu version running on the host.
The ps Command
The ps command is an effective way to see the running processes on a Linux system. Running ps in your terminal will show processes for the current shell.
The output of the ps (Process Status) will show the following;
- PID: The process ID (unique to the process)
- TTY: Terminal type used by the user
- Time: Amount of CPU time used by the process (this is NOT the time this process has been running for)
- CMD: The command or executable running (will NOT display any command line parameter)
The ps command provides a few useful options.
ps aux: Theauxoption will show processes for all usersa, display the user that launched the processu, and show processes that are not attached to a terminalx. Looking at theps auxcommand output, you can have a better understanding of the system and potential vulnerabilities.ps axjf: Theaxjfoption will show processes from all usersa, include processes that have no controlling terminalx, use jobs format outputj, and forest/tree viewf. An example of such tree can be seen below.
john@linux-enumeration:~$ ps axjf
1 1039 1039 1039 ? -1 Ss 0 0:00 /usr/sbin/sshd -D
1039 1854 1854 1854 ? -1 Ss 0 0:00 \_ sshd: karen [priv]
1854 1890 1854 1854 ? -1 S 1001 0:00 \_ sshd: karen@pts/0
1890 1891 1891 1891 pts/0 1975 Ss 1001 0:00 \_ -sh
1891 1975 1975 1891 pts/0 1975 R+ 1001 0:00 \_ ps axjf
The cron Service
Cron is a time-based job scheduler in Linux that allows users and the system to schedule commands or scripts to run automatically at specified intervals. You'll often find cron jobs being used for tasks like backups, log rotation, or running maintenance scripts. During enumeration, it's worth checking for cron jobs since they sometimes run as privileged users. If a cron job is running a script that you can modify, it could become a potential escalation vector.
You can start by examining /etc/crontab and listing the contents of /var/spool/cron/ or /etc/cron.d/ to see what's scheduled and, more importantly, who it's running as. You'll explore how to actually exploit misconfigured cron jobs later, but for now, it's important to include them in your enumeration checklist.
Below is an example of an /etc/crontab entry.
30 2 * * 1 root /home/ubuntu/clear-mail.sh
The output is as follows:
- The first field represents the minute when the script is supposed to be run (valid range: 0-59)
- The second field represents the hour when the script is supposed to be run (valid range: 0-23)
- The third field represents the day of the month when the script is supposed to be run (valid range: 1-31)
- The fourth field represents the month when the script is supposed to be run (valid range: 1-12)
- The fifth field represents the day of the week when the script is supposed to be run(valid range: 0-7, both 0 and 7 represent Sunday)
- The sixth field represents the user who will run the task
- The final field represents the task to be run, which can be any script or binary as long as it's executable
Putting this all together, the crontab above runs /home/ubuntu/clear-mail.sh every Monday at 2:30 AM as the root user.
The dpkg Command
The dpkg tool allows us to query all installed packages and their version. This is especially helpful in privilege escalation attempts when trying to find vulnerable binaries with known exploits.
The command to list all installed software is dpkg -l.
What is the hostname of the target host?
What is the Linux kernel version of the target host?
What version of Ubuntu is running on the host?
What is the full path of the script run by root every 5 minutes?
What is the full version of AppArmor?
This task will focus on obtaining information about local users through commands and files, such as:
- id
- env
- history
- sudo -l
- /etc/password
The id Command
The id command will provide a general overview of the user’s privilege level and group memberships. It is worth remembering that the id command can also be used to obtain the same information for another user, as seen below:
john@home:~$ id
uid=1001(john) gid=1001(john) groups=1001(john),100(users)
john@home:~$ id matt
uid=1002(matt) gid=1002(matt) groups=1002(matt),27(sudo),116(admin)
The env Command
The env command will show environmental variables.
john@home:~$ env
MAIL=/var/mail/john
USER=john
SSH_CLIENT=10.80.88.217 50500 22
HOME=/home/john
SSH_TTY=/dev/pts/0
QT_QPA_PLATFORMTHEME=appmenu-qt5
LOGNAME=john
TERM=linux
The PATH variable may have a compiler or a scripting language (e.g., Python) that could be used to run code on the target system or be leveraged for privilege escalation.
The history Command
Looking at earlier commands with the history command can give us some idea about the target system and, albeit rarely, store information such as passwords or usernames.
The sudo -l Command
The target system may be configured to allow users to run some (or all) commands with root privileges. The sudo -l command can be used to list all commands your user can run using sudo. Depending on the configuration, you may be required to input your current user's password when running the sudo command.
The /etc/passwd File
Reading the /etc/passwd file can be an easy way to discover users on the system.
john@home:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
While the output can be long and a bit intimidating, it can easily be cut and converted to a useful list for brute-force attacks.
john@home:~$ cat /etc/passwd | cut -d ":" -f 1
root
daemon
bin
sys
sync
games
man
lp
mail
news
uucp
proxy
www-data
backup
list
irc
gnats
nobody
libuuid
Remember that this will return all users, some of whom are system or service users that would not be very useful. Another approach could be to grep for “home” as real users will most likely have their folders under the “home” directory.
john@home:~$ cat /etc/passwd | grep /home
matt:x:1000:1000:matt,,,:/home/matt:/bin/bash
karen:x:1001:1001::/home/karen:
Print the environment variables. What is the value of LANG?
What is the flag in your history?
What is the full path of the command you are allowed to run with elevated privileges?
What is the username of the Mailing List Manager?
In this task, you will learn about ifconfig and netstat, and leverage them to gain information about network interfaces and listening ports.
The ifconfig Command
The target system may be a pivoting point to another network. The ifconfig command gives you information about the network interfaces of the system. In the snippet below, for example, you can see that there is a Docker interface, which suggests that Docker is probably running on the host.
john@home:~$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:2aff:feef:cb59 prefixlen 64 scopeid 0x20<link>
ether 02:42:2a:ef:cb:59 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 38 bytes 5128 (5.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9001
inet 10.80.96.65 netmask 255.255.192.0 broadcast 10.80.127.255
inet6 fe80::89f:a8ff:fed4:b8e9 prefixlen 64 scopeid 0x20<link>
ether 0a:9f:a8:d4:b8:e9 txqueuelen 1000 (Ethernet)
RX packets 14085 bytes 14572272 (14.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4151 bytes 7292416 (7.2 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
On modern Linux distributions, this command has been replaced by the ip command. The equivalent of ifconfig is ip addr. ifconfig still exists as part of the net-tools package.
The netstat Command
Following an initial check for existing interfaces and network routes, it is worth looking into existing communications. The netstat command can be used with several different options to gather information on existing connections.
netstat -a shows all listening ports and established connections.
netstat -at or netstat -au can also be used to list TCP or UDP protocols, respectively.
netstat -l lists ports in “listening” mode. These ports are open and ready to accept incoming connections. This can be used with the -t option to list only ports that are listening using the TCP protocol, as shown below:
john@home:~$ netstat -lt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:ldap 0.0.0.0:* LISTEN
tcp 0 0 localhost:postgresql 0.0.0.0:* LISTEN
tcp 0 0 localhost:5433 0.0.0.0:* LISTEN
netstat -s lists network usage statistics by protocol. This can also be used with the -t or -u options to limit the output to a specific protocol.
john@home:~$ netstat -s
Ip:
Forwarding: 1
66019 total packets received
5 with invalid addresses
0 forwarded
0 incoming packets discarded
66012 incoming packets delivered
60939 requests sent out
74 outgoing packets dropped
Icmp:
156 ICMP messages received
0 input ICMP message failed
ICMP input histogram:
destination unreachable: 156
156 ICMP messages sent
0 ICMP messages failed
ICMP output histogram:
destination unreachable: 156
netstat -tp lists connections with the service name and PID information.
john@home~$ netstat -tp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 10.80.96.65:55010 172.31.66.192:9092 TIME_WAIT -
tcp 0 0 localhost:5901 localhost:55988 ESTABLISHED
This can also be used with the -l option to list listening ports/services. The -n flag tells netstat to show numeric addresses and port numbers instead of resolving them.
john@home~$ netstat -tpln
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN
You can see the “/Program name” column is empty, as this process is owned by another user. Below is the same command run with root privileges, which reveals this information as 1144/slapd.
john@home~$ netstat -tpln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 1144/slapd
netstat -i shows interface statistics.
john@home~$ netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
docker0 1500 0 0 0 0 72 0 0 0 BMRU
ens5 9001 75667 0 0 0 54412 0 0 0 BMRU
The netstat usage you will probably see most often in blog posts, write-ups, and courses is netstat -ano which could be broken down as follows;
-a: Display all sockets-n: Do not resolve names-o: Display timers
john@home:~$ netstat -ano
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:5433 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:5901 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 0.0.0.0:6001 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
On modern Linux distributions, netstat has been replaced by the ss command. The core is mainly the same, with some subtle differences, like routing information being moved to IP, and some new functionality being added. As an example, ss -tpl is the equivalent of netstat -tpl. netstat still exists as part of the net-tools package.
What is the name of the network interface, other than loopback?
What port, other than 22, is listening on the host?
In this task, you will expand your already existing knowledge of ls and find to locate sensitive files on Linux systems.
The ls Command
One of the common commands used in is probably ls. While looking for potential privilege escalation vectors, remember to always use the ls command with the -la parameter. The example below shows how the “secret.txt” file can easily be missed using the ls or ls -l commands.
john@home:~$ ls
john@home:~$ ls -l
total 0
john@home~$ ls -la
total 24
drwxrwxrwt 4 root root 4096 Feb 16 04:36 .
drwxr-xr-x 23 root root 4096 Jun 18 2021 ..
drwxrwxrwt 2 root root 4096 Feb 16 04:25 .ICE-unix
-rw-rw-r-- 1 karen karen 23 Feb 16 04:36 .secret.txt
-r--r--r-- 1 root root 11 Feb 16 04:25 .X0-lock
drwxrwxrwt 2 root root 4096 Feb 16 04:25 .X11-unix
john@home:~$ cat .secret.txt
This is a secret file.
The find Command
Searching the target system for important information and potential privilege escalation vectors can be fruitful. The built-in find command is useful and worth keeping in your arsenal.
Below are some useful examples for the find command.
Find files:
find . -name flag1.txtfinds the file named “flag1.txt” in the current directory and subdirectories recursivelyfind /home -name flag1.txtfinds the file names “flag1.txt” in the /home directory and subdirectories recursivelyfind / -type d -name configfinds the directory named config under “/”find / -type f -perm 0777finds files with the 777 permissions (files readable, writable, and executable by all users)find / -perm -a=xfinds executable filesfind /home -user frankfinds all files for user “frank” under “/home”find / -mtime -10finds files that were modified in the last 10 daysfind / -atime -10finds files that were accessed in the last 10 daysfind / -cmin -60finds files changed within the last hour (60 minutes)find / -amin -60finds files accessed within the last hour (60 minutes)find / -size +50Mfinds files with at least 50 MB size
This command can also be used with (+) and (-) signs to specify a file that is larger or smaller than the given size.
john@home:~$ find / -size +100M
/john/.ZAP/plugin/ZAP_2.15.0_Linux.tar.gz
/john/.gradle/wrapper/dists/gradle-6.8-bin/1jblhjyydfkclfzx1agp92nyl/gradle-6.8-bin.zip
The example above returns files that are larger than 100 MB. It is important to note that the find command tends to generate errors, which sometimes makes the output hard to read. To address this, we can use 2>/dev/null, which sends errors to /dev/null, effectively ignoring them.
Folders and files that can be written to or executed from:
find / -writable -type d 2>/dev/nullfinds world-writeable folders.find / -perm -222 -type d 2>/dev/nullfinds world-writeable folders.find / -perm -o w -type d 2>/dev/nullfinds world-writeable folders.
The reason you see three different find commands that could potentially lead to the same result can be seen in the manual document. As you can see below, the perm parameter affects the way find works.
-perm mode
File's permission bits are exactly mode (octal or symbolic).
Since an exact match is required, if you want to use this form
for symbolic modes, you may have to specify a rather complex
mode string. For example `-perm g=w' will only match files
which have mode 0020 (that is, ones for which group write per\u2010
mission is the only permission set). It is more likely that you
will want to use the `/' or `-' forms, for example `-perm -g=w',
which matches any file with group write permission. See the EX\u2010
AMPLES section for some illustrative examples.
-perm -mode
All of the permission bits mode are set for the file. Symbolic
modes are accepted in this form, and this is usually the way in
which you would want to use them. You must specify `u', `g' or
`o' if you use a symbolic mode. See the EXAMPLES section for
some illustrative examples.
-perm /mode
Any of the permission bits mode are set for the file. Symbolic
modes are accepted in this form. You must specify `u', `g' or
`o' if you use a symbolic mode. See the EXAMPLES section for
some illustrative examples.
find / -perm -o x -type d 2>/dev/nullfinds world-executable folders
Find development tools and supported languages:
find / -name perl*find / -name python*find / -name gcc*
Wildcards can be used when you don't know the exact name of a file you are looking for. Say, for example, you want to find a text file containing passwords. You could use the following command.
find / -name pass*.txt
The command above will find file names such as pass.txt, password.txt, passwords.txt, etc.
Below is a short example used to find files that have the SUID bit set. The SUID bit allows the file to run with the privilege level of the account that owns it, rather than the account that runs it.
find / -perm -u=s -type f 2>/dev/nullfinds files with the SUID bit, which allows us to run the file with a higher privilege level than the current user.
What are the contents of the secret file in your home folder?
Find a file that has TryHackMe in its name. What is its content?
In this room, you've learned:
- How to find information about the system you are targeting
- How to enumerate local users
- How to leverage
ifconfigandnetstatto gain information on network connections - How to find interesting or hidden files on Linux systems
As you could see, there is a lot of information to be gained about a target system that doesn't necessarily give you a clear-cut escalation path, but does aid in your privilege escalation efforts. Please spend some time getting comfortable with commands such as find, locate, grep, cut, sort, etc.
Enumeration done.
Ready to learn Cyber Security?
TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.
Already have an account? Log in
