VaultSpace

Summary

We’ll use the app’s own public “function dispatcher” to call a state-changing helper that writes directly into $_SESSION. One request sets $_SESSION['admin']=true for our cookie, and then /dashboard.php shows the flag. No shell, no SQL, just an authorization check that trusts what the client can modify.

Start

The challenge ships a classic PHP stack with these relevant files:

  • api_handler.php — generic POST API gateway

  • functions.php — the functions that the gateway can call

  • dashboard.php — admin-only page that renders the flag

Two observations frame the whole exploit:

  1. A public dispatcher invokes server functions by name.

  2. One exported function writes session auth based on caller input.

Dispatcher (Entry point)

  • No authentication sits in front of this entrypoint. Any POST is forwarded to safe_call_function.

  • Whatever we put in $action determines which server function runs. That’s huge power.

The “safety” check that isn’t authorization

  • The only gate is a regex on the name. That’s not a permission model.

  • If a sensitive routine starts with set_, it passes and becomes remotely callable.

  • call_user_func_array($fn, $params) uses our params to build the function’s arguments, so we control both which function runs and what it receives.

Where the privilege flip actually happens

  • Whatever we put in user_data['admin'] becomes the session’s admin bit.

  • No DB lookup, no signature, no role verification, just trust.

The admin check elsewhere simply reads that bit:

And the dashboard gates by it and renders the flag:

So if we can call set_user_session through the dispatcher and keep the same cookie, we’re in.

Steps for Exploitation

Open any page to establish a PHP session (keep the same cookie for the next requests).

2-Flip your session to admin via the dispatcher

Send a form-encoded POST that calls set_user_session with a single array argument. This shape makes PHP build params[0] as the $user_data array for call_user_func_array.

Under the hood:

  • The regex allows set_user_session.

  • call_user_func_array('set_user_session', [ {id, username, admin:1} ]) runs.

  • (bool)1 becomes true$_SESSION['admin']=true for your current cookie.

Then visit /dashboard and you should see the flag

Last updated