A2Billing <= 1.9.4 Multiple vulnerabilities
Cross-Site Scripting (XSS) vulnerabilities were identified within A2Billing version 1.9.4 . A simple and non-permanent XSSSecurity Advisory
=================
Overview
--------
* Program : A2Billing 1.9.4 and prior
* Vendor : http://www.star2billing.com/
* Homepage : * http://www.star2billing.com/solutions/voip-billing/
* Discovery : 2012/07/04
* Author Contacted : 2012/10/11
* Found by : Romain E SILVA
* This Advisory : Romain E SILVA
Application description
-----------------------
A2Billing is an opensource VoIP billing system.
Cross-Site Scripting vulnerabilities
------------------------------------
Cross-Site Scripting (XSS) vulnerabilities were identified within A2Billing version 1.9.4
### Proof of Concept
http://a2billing.localhost/customer/checkout_payment.php?payment_error=plugnpay&error=%3Cscript%3Ealert%28%27xss%27%29;%3C/script%3EThe+payment+couldnt+be+proceed+correctly!
### Description of the vulnerability
A simple and non-permanent XSS
### Location of the vulnerability
Located at: customer/checkout_payment.php line 182
### Fix
In: customer/checkout_payment.php line 182
Replace:
<td class="main" valign="top" width="100%"><?php echo tep_output_string($error['error']); ??></td>
By:
<td class="main" valign="top" width="100%"><?php echo tep_output_string_protected($error['error']); ??></td>
Cross-Site Request Forgery vulnerability
----------------------------------------
### Proof of Concept
http://a2billing.localhost/customer/A2B_entity_card.php?form_action=ask-edit
### Description
All forms are vulnerable. For example, you can change the email of an account with this CSRF and ask for a new password
### Fix
In: common/lib/Form/Class.FormHandler.inc.php
Add at line 515 :
// CSRF TOKEN
var $FG_CSRF_STATUS = true;
var $FG_CSRF_TOKEN_SALT = 'YOUR_SALT';
var $FG_CSRF_TOKEN_KEY = null;
var $FG_CSRF_TOKEN = null;
var $FG_CSRF_FIELD = 'csrf_token';
var $FG_FORM_UNIQID_FIELD = 'form_id';
Edit the var $FG_CSRF_TOKEN_SALT in order to add your salt for more security
Add at line 539 :
// If anti CSRF protection is enabled
if ($this->FG_CSRF_STATUS == true) {
// Initializing anti csrf token (Generate a key, concat it with salt and hash it)
$this -> FG_CSRF_TOKEN_KEY = $this->genCsrfTokenKey();
$this -> FG_CSRF_TOKEN = $this->FG_CSRF_TOKEN_SALT.$this->FG_CSRF_TOKEN_KEY;
$this -> FG_CSRF_TOKEN = hash('SHA256', $this->FG_CSRF_TOKEN);
$this->FG_FORM_UNIQID = uniqid();
$this->FG_FORM_RECEIVED_UNIQID = $_POST[$this->FG_FORM_UNIQID_FIELD];
$this->FG_CSRF_RECEIVED_TOKEN = $_SESSION[$this->FG_FORM_RECEIVED_UNIQID]['CSRF_TOKEN'];
$_SESSION['CSRF_TOKEN'][$this->FG_FORM_RECEIVED_UNIQID] = $this->FG_CSRF_TOKEN;
if ($this->FG_DEBUG) {
echo 'CSRF NEW TOKEN : '.$this->FG_CSRF_TOKEN.'<br></br>';
echo 'CSRF RECEIVED TOKEN : '.$this->FG_CSRF_RECEIVED_TOKEN.'<br></br>';
}
}
Add after line 1170 :
/* Add CSRF protection */
if ($this->FG_CSRF_STATUS == true) {
switch ($form_action) {
case 'add':
case 'edit':
case 'delete':
if ($this->_processed[$this->FG_CSRF_RECEIVED_FIELD] != $this->FG_CSRF_RECEIVED_TOKEN) {
Header ("Location: ". $_SERVER['PHP_SELF']);
die();
}
break;
}
}
In: common/lib/Form/Class.FormHandler.AddForm.inc.php
Add after line 13 :
<?php if ($this-?>FG_CSRF_STATUS == true) {
?>
<input name="<?php echo $this->FG_FORM_UNIQID_FIELD ?>" type="hidden" value="<?php echo $this->FG_FORM_UNIQID; ?>"></input><input name="<?php echo $this->FG_CSRF_FIELD ?>" type="hidden" value="<?php echo $this->FG_CSRF_TOKEN; ?>"></input><?php }
??>
In: common/lib/Form/Class.FormHandler.DelForm.inc.php
Add after line 40 :
<?php if ($this-?>FG_CSRF_STATUS == true) {
?>
<input name="<?php echo $this->FG_FORM_UNIQID_FIELD ?>" type="hidden" value="<?php echo $this->FG_FORM_UNIQID; ?>"></input><input name="<?php echo $this->FG_CSRF_FIELD ?>" type="hidden" value="<?php echo $this->FG_CSRF_TOKEN; ?>"></input><?php }
??>
In: common/lib/Form/Class.FormHandler.EditForm.inc.php
Add after line 43 :
<?php if ($this-?>FG_CSRF_STATUS == true) {
?>
<input name="<?php echo $this->FG_FORM_UNIQID_FIELD ?>" type="hidden" value="<?php echo $this->FG_FORM_UNIQID; ?>"></input><input name="<?php echo $this->FG_CSRF_FIELD ?>" type="hidden" value="<?php echo $this->FG_CSRF_TOKEN; ?>"></input><?php }
??>
You may also patch custom forms.
Design weaknesses
-----------------
### HTML POST parameter tampering
http://a2billing.localhost/customer/
#### Description
This vuln let you set the price(with POST parameters) you want to paid your postpaid invoice with paypal it's a normal way to use paypal api, but when paypal contact the server with the callback url the amount of the transaction isn't verified.
#### Fix:
In: customer/checkout_process.php
Check if the price submitted by paypal is the same as the amount item
### Arbitrary file download
http://a2billing.localhost/customer/call_history.php?donwload=file&file=Li4vLi4vLi4vLi4vZXRjL2EyYmlsbGluZy5jb25m
#### Description
One may download any file apache can access on the server. On some page, if download variable is set to "file" the server will encrypt "file" variable with base64_decode and send the content of the file.
#### Fix
In: admin/Public/call_dnid.php, admin/Public/call_log_customers.php, customer/call_history.php
Check if the file is in the correct directory before sending it to the client.
SQL code injections
-------------------
### Proof of Concept
http://a2billing.localhost/customer/A2B_entity_did.php?assign=1&new_did_page=2&confirm_buy_did=0&action_release=&choose_did_rate=10CUR10.55%2B1000&destination=347894999&voip_call=0&choose_country=73&confirm_buy_did=1
http://a2billing.localhost/agent/Public/export_csv.php?var_export=menu_section&var_export_type=type_xml§ion=SELECT * FROM `cc_ui_authen`
### Description
One may add some credits to an existing account or get a complete export of the results corresponding to an arbitrary SQL query.
This second vulnerability is exploited in two steps, the export_csv module gets a sql query from session variable wich the user can set in "var_export" GET Variable, and then inject some data in session in order to execute a specifically crafted sql query. This can be done by adding "section" in url with any sql query, the script will set $_SESSION['menu_section'] with the content of $_GET['section'] variable, and eventually run export_csv and send the result.
### Fix
In: customer/A2B_entity_did.php
Get the amount from database instead of form data
- http://a2billing.localhost/agent/Public/export_csv.php?var_export=menu_section&var_export_type=type_xml§ion=SELECT * FROM `cc_ui_authen`
In: agent/export_csv.php and admin/export_csv.php
Set the sql query in FormHandler (with a new attribute) and force integer in $section
Vulnerability Timeline
-----------------------
2012-10-11 - Reported to vendor
2012-10-11 - Reply from vendor
2012-10-12 - Fix pushed by Vendor
2012-10-22 - Suggestion in paypal correction by Sysdream
2012-10-26 - New vulnerability repported
2012-11-05 - Fixes pushed by Vendor
2012-11-12 - A2Billing 2.0 released with patch
2013-01-15 - Advisory released
Credits
-------
http://www.sysdream.com
r.esilva at sysdream dot com