Friday, October 7, 2011

Freepbx Exploit

Wow, what a week.  You move data centres and then find of an exploit that you weren't aware of.  Big thanks to freepbx for this one.  Not really sure why this little gem isn't documented in many places, but it's a good one.
When you use database authentication in freepbx the Database user and pass gets admin access to the system.  That sounds a little strange, but what it means is that if you have installed a clean install of freepbx, despite the fact that you have set a root password etc. access to the database asterisk is granted to the default user of:
freepbx - fpbx
Now, if you login to your web administration using those credentials it will grant you full admin access.  thus completely opening your system.  To modify the details you need to edit /etc/amportal.conf and change the following  option... once you have changed that don't forget to give that user/pass the mysql access to get into the asterisk database an example is shown on the second line
AMPDBPASS=SOMENEWPASS
 mysql> grant all on asterisk.* to freepbx@localhost identified by 'SOMENEWPASS'
Please bear in mind that you will still be able to get into the system using freepbx and SOMENEWPASS, so make it secure!!
 

Wednesday, August 31, 2011

Click to Call from Public Website

It's been a while since we posted, so we are going to get straight into it.

What we want to do here is provide some code that we can use on our public website which will call the person in the office and then call the number they entered. To make it easy on the public web developer what we are going to do is just hand them a small piece of javascript which they can use to put on there website where they want the picture to appear. The rest of the work is done on the asterisk side. It's all from a perspective where you are in control of the asterisk box, but nothing else. Whether it be a trixbox, elastix, pbx in a flash or asterisk, the setup explained here should work. It was designed for elastix and may need changes to the asterisk manager on other systems We are going to make a few assumptions.


  • You have some basic understanding of PHP/Asterisk/Javascript

  • You know your way around the freepbx layout.

  • What we need to do on the Asterisk side is login to web admin section and create a new queue.


With that queue leave all the static agents blank, or else the image will display constantly even when you don't want to take calls.

Then create a directory in web(apache/httpd) directory which we will use for access from the public website. in that directory we are going to have a few files:

  • index.php ( the php script to do the calling )

  • callingscript.js ( the main chunk of javascript )

  • callback.png ( the image to display )


We are only using 1 image, i.e. an online image the code is very easy to change to include an offline image if you want. In this example everything will reference http://call.pracapps.com.au/callback and will live in /var/www/html/callback

First lets start out with index.php

<?
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, GET");
$queue = '7';// change this to the queue you have created on your system
$asterisk_location = '/usr/sbin/asterisk';
$command = "$asterisk_location -rx 'queue show $queue'";
if( !empty($_REQUEST['callback_number']) ) // this is the do the call part
{
require_once('/var/lib/asterisk/agi-bin/phpagi-asmanager.php');
$ami = new AGI_AsteriskManager();
$ami->connect();
$ami->originate("Local/$queue@from-internal", $_REQUEST['callback_number'], "from-internal", "1");
die('Your Call has been placed and your phone should be ringing shortly.');
} else { // display the javascript
exec($command, $output);
if(trim($output[1]) == 'Members:')
{
echo file_get_contents('http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js');
echo file_get_contents('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js');
include('callingscript.js');
}
}
?>


In the index.php file you will need to edit line 4:
$queue = '7'; // change this to the queue you have created on your system
Then we have the callingscript.js, and just change line 1

base_url = 'http://call.pracapps.com.au/callback';
$('#callback').append(
$('<div></div>')
.append(
$('<img></img>')
.attr( { src: base_url + '/callback.png' } )
.click(function() { $('#callback-details').dialog('open'); } )
)
.append(
$('<div></div>')
.attr( { id: 'callback-details', title: 'Call Me Now' } )
.append(
$('<span>Please enter your number</span><br>')
)
.append(
$('<input></input>')
.attr( { name : 'callback_number', size : '20', id: 'callback_number' } )
)
)
);
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/themes/base/jquery-ui.css';
document.head.appendChild(link);

$(function() {
$('#callback-details').dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
" Call Me ": function() {
$.ajax({
url: base_url+'/index.php',
data:{ callback_number: $('#callback_number').val() },
dataType: "text",
success: function(data){
$('#callback-details').dialog('close');
$('#callback').append(
$('<div>'+data+'</div>')
.attr( { id: 'callback-response', title: 'Your Call Status' } )
);
$('#callback-response').dialog({
height: 300,
width: 350,
});
}
});
$(this).dialog('close');
},
" Cancel ": function() {
$(this).dialog('close');
}
}
});
});

Then all we need to is log into queue from an extension to make it activate it. in the above example on a standard freepbx system it would be 7* and then 7** when their shift is finished.



**Elastix Specific**

Elastix always redirects to https, which caused issues, so the work around is this, need to create a file /etc/http/conf.d/callback.conf with the following details

<Directory /var/www/html/callback>
RewriteEngine Off
Order deny,allow
allow from all
</Directory>

** end Elastix **

We now just have to insert the code into the public website:

<div id='callback'></div>
<script type='text/javascript' src='http://call.pracapps.com.au/callback'></script>