• CENTRE D’URGENCE | 24/7
  • Vous êtes victime d’une cyberattaque ?
  • Contactez notre centre d’urgence cyber :
  • +33 (0)1 83 07 00 06

A2Billing <= 1.9.4 Multiple vulnerabilities

Cross-Site Scripting (XSS) vulnerabilities were identified within A2Billing version 1.9.4 . A simple and non-permanent XSS
Security 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&section=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&section=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