Movie Rating System 1.0 - Broken Access Control (Admin Account Creation)

Movie Rating System 1.0 - Broken Access Control (Admin Account Creation)

Exploit / Project Details

Python Tue Dec 21 2021

Zero-Day Discovery & Exploit Development: Movie Rating System Broken Access Control

Detailed Write-up

Introduction

In this report, I will detail the discovery and exploitation of a critical Broken Access Control vulnerability in the "Movie Rating System 1.0" application. This vulnerability allows an unauthenticated attacker to create a new user with administrator privileges.

Vulnerability Analysis

Unauthorized Access and User Creation

Upon examining the classes/Users.php file, which handles user management operations, I detected that the save_users function is executed without any authentication checks.

// Vulnerable Code in classes/Users.php
$action = !isset($_GET['f']) ? 'none' : strtolower($_GET['f']);
switch ($action) {
    case 'save':
        echo $users->save_users();
    break;
    // ...
}

As seen in the code snippet above, requests with the parameter f=save are directly routed to the save_users function. At this point, there is no check whether the user is logged in or has administrative privileges.

Looking into the save_users function, we see that data sent via POST request is directly saved to the database:

public function save_users(){
    // ...
    extract($_POST);
    // ...
    foreach($_POST as $k => $v){
        if(in_array($k,array('firstname','middlename','lastname','username','type'))){
            if(!empty($data)) $data .=" , ";
            $data .= " {$k} = '{$v}' ";
        }
    }
    // ...
    if(empty($id)){
        $qry = $this->conn->query("INSERT INTO users set {$data}");
        // ...
    }
    // ...
}

The most critical point here is that the type parameter can be manipulated externally. In the system, type=1 typically represents Administrator privileges. An attacker can send this parameter as 1 to make themselves an administrator.

Exploit Development

I developed a Python exploit (exploit.py) to leverage this vulnerability. The attack steps are as follows:

  1. Target Selection: The target URL is taken from the user.

  2. Admin Account Creation: A specially crafted multipart/form-data POST request is sent to classes/Users.php?f=save.

    • username: "tago"
    • password: "tagoletta"
    • type: "1" (Admin Privilege)
    • firstname, lastname: Random values.
  3. Login Check: After the account is created, a login request is sent to classes/Login.php?f=login with the created credentials to verify the success of the exploit.

If the server returns 200 OK and the login is successful, we now have a fully privileged administrator account on the system.

Remediation

To fix this vulnerability, access to the save_users function must be restricted to authorized administrators only.

Mitigation:
Add an authorization check to the switch structure in classes/Users.php or at the beginning of the save_users function.

Secure Implementation Example:

// classes/Users.php

// ...
switch ($action) {
    case 'save':
        // Add session check and authorization check
        if(!isset($_SESSION['userdata']) || $_SESSION['userdata']['type'] != 1){
            echo json_encode(['status' => 'failed', 'msg' => 'Unauthorized access.']);
            exit;
        }
        echo $users->save_users();
    break;
    // ...
}

This change will ensure that only logged-in users with a type value of 1 (Administrator) can call this function.

Source Code Explorer
/
Select a file
2024 © Tağmaç Han