Skip to content

Latest commit

 

History

History
125 lines (105 loc) · 5.09 KB

slims9_bulian-9.6.1-SQLI-loan_rules.md

File metadata and controls

125 lines (105 loc) · 5.09 KB

The issue

My machine learning model that are in progress for vulnerable code detection in php recently found the issues below Issue Reference: https://github.com/slims/slims9_bulian/issues/205

The explanation

it is straight forward that there is unsafe parsing from input to user at the code below

/* RECORD OPERATION */
if (isset($_POST['saveData'])) {
    $data['member_type_id'] = $_POST['memberTypeID'];
    $data['coll_type_id'] = $_POST['collTypeID'];
    $data['gmd_id'] = $_POST['gmdID'];
    $data['loan_limit'] = trim($_POST['loanLimit']);
    $data['loan_periode'] = trim($_POST['loanPeriode']);
    $data['reborrow_limit'] = trim($_POST['reborrowLimit']);
    $data['fine_each_day'] = trim($_POST['fineEachDay']);
    $data['grace_periode'] = trim($_POST['gracePeriode']);
    $data['input_date'] = date('Y-m-d');
    $data['last_update'] = date('Y-m-d');
    // create sql op object
    $sql_op = new simbio_dbop($dbs);
    if (isset($_POST['updateRecordID'])) {
        /* UPDATE RECORD MODE */
        // remove input date
        unset($data['input_date']);
        // filter update record ID
        $updateRecordID = (integer)$_POST['updateRecordID'];
        // update the data
        $update = $sql_op->update('mst_loan_rules', $data, 'loan_rules_id='.$updateRecordID);
        if ($update) {
            toastr(__('Loan Rules Successfully Updated'))->success();
            echo '<script language="Javascript">parent.jQuery(\'#mainContent\').simbioAJAX(parent.jQuery.ajaxHistory[0].url);</script>';
        } else { toastr(__('Loan Rules FAILED to Updated. Please Contact System Administrator')."\nDEBUG : ".$sql_op->error)->error(); }
        exit();
    } else {
        /* INSERT RECORD MODE */
        $insert = $sql_op->insert('mst_loan_rules', $data); // HERE
        if ($insert) {
            toastr(__('New Loan Rules Successfully Saved'))->success();
            echo '<script language="Javascript">parent.jQuery(\'#mainContent\').simbioAJAX(\''.$_SERVER['PHP_SELF'].'\');</script>';
        } else { toastr(__('Loan Rules FAILED to Save. Please Contact System Administrator')."\n".$sql_op->error)->error(); }
        exit();
    }
    exit();
}

which then passes to simbio2/simbio_DB/simbio_dbop.inc.php function insert()

   public function insert($str_table, $array_data)
    {
        if (!is_array($array_data) OR count($array_data) == 0) {
            return false;
        }

        // parse the array first
        $_str_columns = '';
        $_str_value = '';
        foreach ($array_data as $column => $value) {
            // concatenating column name
            $_str_columns .= ", `$column`";
            // concatenating value
            if ($value === 'NULL' OR $value === null) {
                // if the value is NULL or string NULL
                $_str_value .= ', NULL';
            } else if (is_string($value)) {
                if (preg_match("/^literal{.+}/i", $value)) {
                    $value = preg_replace("/literal{|}/i", '', $value);
                    $_str_value .= ", $value";
                } else {
                    // concatenating column value
                    $_str_value .= ", '$value'";
                }
            } else {
                // if the value is an integer or unknown data type
                $_str_value .= ", $value";
            }
        }

        // strip the first comma  of string
        $_str_columns = substr_replace($_str_columns, '', 0, 1);
        $_str_value = substr_replace($_str_value, '', 0, 1);

        try {
            // the insert query
            $this->sql_string = "INSERT INTO `$str_table` ($_str_columns) "
                ."VALUES ($_str_value)";
            $_insert = $this->obj_db->query($this->sql_string);
            
            // get last inserted record ID
            $this->insert_id = $this->obj_db->insert_id;
            $this->affected_rows = $this->obj_db->affected_rows;
        } catch (Exception $e) {
            // if an error occur
            $this->error = isDev() ? $e->getMessage() . ' : ' . $this->sql_string : ''; 
            return false; 
        }

        return true;
    }

from here we can see that the input from the http request goes into an array and then when is being inserted it calls the insert where the insert function we can see that it passes to this part of the code below:

  $this->sql_string = "INSERT INTO `$str_table` ($_str_columns) "
                ."VALUES ($_str_value)";
            $_insert = $this->obj_db->query($this->sql_string);

in order to launch the attack to exploit the bugs, all we need is a user or account with privilege to access circulation, then either capture a request or make a custom post request mentioned in the issue to admin/modules/circulation/loan_rules.php to get the request, then use sqlmap to dump the database or perform any other various attacks to the database

The CVE ID

This vulnerability was assigned as CVE-2023-40970

notes

fix the issue reference. last edit at 18 August 2023 21.37 GMT+7