Vibe Hacking: Finding Auth Bypass and RCE in Open Game Panel
You've heard of vibe coding, but have you considered vibe hacking? I tried thinking less to find an authentication bypass and RCE in OpenGamePanel.

Vibe coding is more popular than ever, and I get it. But what if we took that same energy and applied it to cybersecurity?
Anyone who knows me well knows I'm a big fan of using my brain as little as possible for the given task at hand. So naturally I started thinking: can we vibe our way through security research too?
Enter vibe hacking featuring Open Game Panel, a popular game server control panel.
VUL-01: Type Juggling Authentication Bypass
Taking a look at the login flow I immediately spotted our first vulnerability. I didn't get a chance to fire up the vibes.
The login and API key generation process uses a MD5 loose comparison ==
instead of a strict comparison ===
resulting in classic PHP type juggling issue.
0e
followed by numbers (like 0e12345
), PHP would treat it like zero.An attacker could then log in with a different password that also hashed to a
0e...
value, even if it wasn’t the user's actual password. These are known as magic hashes.Affected Lines of Code
$userInfo = $db->getUser($_POST['ulogin']);
// If result matched $myusername and $mypassword, table row must be 1 row
if( isset($userInfo['users_passwd']) && md5($_POST['upassword']) == $userInfo['users_passwd'])
{
--- SNIP ---
// User is authenticated successfully.
Login code in index.php
if($request[0] == "create")
{
$user = isset($request[1])?urldecode($request[1]):$_POST['user'];
$password = isset($request[2])?urldecode($request[2]):$_POST['password'];
$userInfo = $db->getUser($user);
if(isset($userInfo['users_passwd']) && md5($password) == $userInfo['users_passwd'])
{
$token = bin2hex(openssl_random_pseudo_bytes(32));
--- SNIP ---
// New token is generated for the user
API key generation in ogp_api.php
For example, if we set our password to "240610708", we can login and generate an API token for our account with a completely different password like "QNKCDZO".


If a user has a password that hashes to a magic hash, all an attacker needs to guess is the user's username to take over that account.
Unfortunately, I used my brain to find this issue.
So let's try to lean harder into the vibe rather than looking at anything myself.
VUL-02: Authenticated Local File Inclusion
What if I just fed the output of a SAST tool like Semgrep straight into Cursor and asked it to help me craft a request to exploit it?

With some addition of a few more ../
's we have a working POC.

That's better!
Escalating it to Authenticated RCE
Taking a look closer at what we (Semgrep + Cursor) found, the code uses include
which means if we can point the LFI payload to a file that contains user controlled data we can actually leverage this for RCE.
$file = urldecode($_GET['file']);
if(file_exists(__dir__ . "/" . $file)){
include(__dir__ . "/" . $file);
As it turns out you can create game configuration files which are stored on the file system.

Lets create a game config with arbitrary some PHP.

Now we can use our vibey LFI to include it and execute the PHP file.

And of course we can convert this to a simple web shell for easier usage.

No amount of prompting and saying 'please' worked for me.
I'm not fully replaceable yet!
VUL-03: More Authenticated Local File Inclusion
Normally, when there’s one vulnerability of a certain class, there’s more in the same code base.
I asked Cursor to look for similar LFI patterns elsewhere in the codebase and unsurprisingly it pointed out a few more suspicious spots.
Number 3 looked particularly interesting.

Cursor struggled to craft a valid request that would actually reach the vulnerable code. But it didn’t take long to spot the relevant button in the UI myself.
After modifying the request and swapping out the dwfile
parameter with a simple LFI payload, we had another confirmed LFI vulnerability.

Taking a closer look at the actual code, this time the file is read using fopen and echo'd to the user in the response.
$path = getcwd()."/".$_GET['randir']."/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['dwfile'];
if ($fd = fopen ($fullPath, "r")) {
header("Content-Disposition: attachment; filename=\"".$_GET['dwfile']."\"");
header("Content-length: ".filesize($fullPath));
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
fclose($fd);
}
backupdwl.php
Although this type of LFI can’t be used to achieve RCE like our last example, it does let you read PHP files that would normally be interpreted by the server.
That means we can craft an alternate payload to download site configuration files that may contain passwords.

Disclosure Timeline
- 29/04/25 - Research started.
- 29/04/25 - Type juggling vulnerability disclosed.
- 30/04/25 - LFI vulnerabilities disclosed.
- 30/04/25 - Type juggling issue resolved, LFI issues marked as won't fix as admin permissions are required to access both functions.
- 30/04/25 - Public disclosure and CVEs requested.
Conclusion
Ultimately, what I found from this mini project is that full blown vibe based security research isn't quite there yet.
The vulnerabilities we uncovered were pretty straightforward, but it still took some interpretation and manual digging to turn ideas into working exploits.
What I am convinced of though is that even today, tools like Cursor are great for exploring large and unfamiliar codebases.
Try it out on your next research project!