Thursday, November 18, 2010

Binding SpyEye (1.0.x) with BSQL Injection

This is true that "vulnerabilities die hard". Recently during the process of testing, it has been detected that some of the released versions of SpyEye starting from 1.0.x has shown an interesting weakness in the "frm_cards_edit.php" module. This PHP module is present in the main admin panel and used to manage the credentials. The "id" parameter is used with "GET" request to fetch credit card details thereby updating the database after-wards.This module is vulnerable to blind SQL injection.


$data= '"id" : "1 AND [Union SQL Poisoning Code]));-- /*"'
$encode_data= apply encoding module on $data
$http_request("GET", path + "frm_cards_edit.php?" + $encode_data )

Some of the traces of the vulnerable PHP module is presented below.

<?php
require_once 'mod_dbase.php';
require_once 'mod_time.php';
require_once 'mod_crypt.php';
require_once 'mod_file.php';
$id_card = $_GET['id']; if (!@$id_card) exit;
$dbase = db_open();if (!$dbase) exit;

$sql = ' SELECT cards.num, cards.csc, cards.exp_date, cards.name, cards.surname, cards.address, cards.city, cards.state, cards.post_code, country_t.name_country, cards.phone_num, email_t.value_email '
. ' FROM cards, country_t, email_t'
. ' WHERE cards.fk_email = email_t.id_email'
. ' AND cards.fk_country = country_t.id_country'
. " AND cards.id_card = $id_card"
. ' LIMIT 0, 1';
$res = mysqli_query ($dbase, $sql);
if ((!(@($res))) || !mysqli_num_rows($res)) {
writelog ("error.log", $sql);
db_close($dbase);
exit();
}

$res = mysqli_fetch_row($res);
list($num_card, $csc, $exp_date, $name, $surname, $address, $city, $state, $post_code, $country, $phone_num, $email) = $res;

db_close($dbase);

list($year, $month) = split('[\/.-]', $exp_date);
$res[2] = $exp_date = gmdate("m/y", gmmktime(0, 0, 0, $month, 1, $year));
$res[0] = $num = encode(base64_decode($num_card), $csc);

// labels & names
$reslb['num'] = 'Card number';
$reslb['csc'] = 'CSC';
$reslb['exp_date'] = 'Exp. date';
$reslb['name'] = 'Name';
$reslb['surname'] = 'Surname';
$reslb['address'] = 'Address';
$reslb['city'] = 'City';
$reslb['state'] = 'State';
$reslb['post_code'] = 'ZIP';
$reslb['country'] = 'Country';
$reslb['phone'] = 'Phone';
$reslb['email'] = 'E-Mail';

// lengths
$lnexp = 7;
$resln[0] = $numln = strlen($num) + $lnexp;
$resln[1] = $cscln = strlen($csc) + $lnexp;
$resln[2] = $exp_dateln = strlen($exp_date) + $lnexp;
$resln[3] = $nameln = strlen($name) + $lnexp;
$resln[4] = $surnameln = strlen($surname) + $lnexp;
$resln[5] = $addressln = strlen($address) + $lnexp;
$resln[6] = $cityln = strlen($city) + $lnexp;
$resln[7] = $stateln = strlen($state) + $lnexp;
$resln[8] = $post_codeln = strlen($post_code) + $lnexp;
$resln[9] = $countryln = strlen($country) + $lnexp;
$resln[10] = $phone_numln = strlen($phone_num) + $lnexp;
$resln[11] = $emailln = strlen($email) + $lnexp;
?>

It works efficiently in number of cases. Thanks to my team.