Bug 78095 (CVE-2005-1127) - VUL-0: CVE-2005-1127: format string bug in perl-Net-Server
Summary: VUL-0: CVE-2005-1127: format string bug in perl-Net-Server
Status: RESOLVED FIXED
Alias: CVE-2005-1127
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents (show other bugs)
Version: unspecified
Hardware: Other All
: P5 - None : Normal
Target Milestone: ---
Assignee: Marcus Meissner
QA Contact: Security Team bot
URL:
Whiteboard: CVE-2005-1127: CVSS v2 Base Score: 5....
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-15 11:47 UTC by Ludwig Nussel
Modified: 2021-11-08 16:37 UTC (History)
2 users (show)

See Also:
Found By: Other
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ludwig Nussel 2005-04-15 11:47:36 UTC
We received the following report via full-disclosure.
The issue is public.

Note that format string bugs may be exploited for code execution.

Date: Fri, 15 Apr 2005 08:08:11 +0200
From: "Dr. Peter Bieringer" <pbieringer@aerasec.de>
To: Maillist full-disclosure <full-disclosure@lists.grok.org.uk>
Subject: [Full-disclosure] Use of function "log" in Perl module Net::Server
 can lead to format string vulnerability if syslog is used

Hi,

Module: Net::Server
Affected version: 0.87 and probably below
Latest available version: 0.87 from 14. Feb 2004
URL: <http://search.cpan.org/~bbb/Net-Server-0.87/> 

during investigating a remote DoS against postgrey <= 1.18 (1.21 is already
available now!) it was found with help of David Schweikert and Stefan
Schmidt that the "log" function in Net::Server Perl module is not safe
against format string vulnerability.

See also thread on postgrey mailing list:
 <http://lists.ee.ethz.ch/postgrey/msg00627.html>


Note that the "log" function itself isn't documentated at all in the
Server.pm, but at least used by "postgrey" (and probably by other software,
too).

The syslog call in function log is implemented like following:

  ### log only to syslog if setup to do syslog
  if( $prop->{log_file} eq 'Sys::Syslog' ){
    $level = $level!~/^\d+$/ ? $level : $Net::Server::syslog_map->{$level} ;
    Sys::Syslog::syslog($level,@_);   <---!!!!!!
    return;
  }


Sys::Syslog tells how to use function "syslog":

       syslog $priority, $format, @args
           If $priority permits, logs ($format, @args) printed as by
           "printf(3V)", with the addition that %m is replaced with "$!"
(the
           latest error message).


Unfortunately, the function "log" of Net::Server put now the first given
log argument into "syslog" function as format string, and the others as
arguments.

I do not believe this was the intention of the programmer(s) of
Net::Server, because during a quick code check I do not found any piece of
code like
          $self->log(0,$formatstring, $string)
at all, only
          $self->log(0,$string)


Also the "write_to_log_hook" (in case of file is used as log channel) do
not interpret first string token as format string at all (and uses btw only
one string argument for printing, not more).

So I think this is more a mistake that a feature...a time bomb as we see
now :((


I do not have the time to investigate which network related programs uses
the "log" function of Net::Server (at least "postgrey" does). But I think
it would be important to look for them and check them.

As a workaround, programs using "log" of Net::Server can replace a single
"%" by "%%", but only in case of syslog is used...

Probably (untested) solution would be to fix the syslog calling code in
Net::Server from
    Sys::Syslog::syslog($level,@_);
to e.g.
    Sys::Syslog::syslog($level,"%s", $_[0]);
  (hopefully I'm right...it's untested)


Possible impact of such fix: programs which call "log" of Net::Server with
format string in first log argument will break. But this would already
break logging into a file if I understand the "write_to_log_hook" code.

Hope this helps,

        Dr. Peter Bieringer
-- 
Dr. Peter Bieringer                             Phone: +49-8102-895190
AERAsec Network Services and Security GmbH        Fax: +49-8102-895199
Wagenberger Straße 1                           Mobile: +49-174-9015046
D-85662 Hohenbrunn                       E-Mail: pbieringer@aerasec.de
Germany                                Internet: http://www.aerasec.de



_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/
Comment 2 Stefan Fent 2005-04-18 14:36:31 UTC
I created a patch:
--- Net-Server-0.87/lib/Net/Server.pm.ORG       2005-04-18 15:22:18.002797897 +0200
+++ Net-Server-0.87/lib/Net/Server.pm   2005-04-18 15:22:25.153319236 +0200
@@ -1046,7 +1046,9 @@
   ### log only to syslog if setup to do syslog
   if( $prop->{log_file} eq 'Sys::Syslog' ){
     $level = $level!~/^\d+$/ ? $level : $Net::Server::syslog_map->{$level} ;
-    Sys::Syslog::syslog($level,@_);
+    ### check for formatstring, if none take only the first string
+    my $fstring = sprintf shift @_, @_;
+    Sys::Syslog::syslog($level, $fstring);
     return;
   }

that checks for a formatstring and uses this, otherwise takes the first string

submitted for

9.0,9.1.9.2, 9.3
Comment 3 Marcus Meissner 2005-04-18 14:58:04 UTC
this is not the correct way, you actually open a new hole. 
 
Note that the problem is that the first element of @_ is evaluated 
as format string and can be chosen by an attacker. 
 
Your fix just lets it evaluate by sprintf ... this might be 
implemented in perl and not as dangerous as before. 
 
However you then pass the string to syslog again unprotected, 
so an attacker just needed %% to a get a % and then could proceed 
as before. 
 
Please use: 
 
-    Sys::Syslog::syslog($level,@_); 
+    Sys::Syslog::syslog($level, "%s", @_); 
 
as a better approach. Reading the source does not show any call passing 
more than 1 argument to the function. 
Comment 4 Stefan Fent 2005-04-18 15:33:10 UTC
So this would be what keeps all arguments, in case there is a formatstring in @_
and make sure it is not misinterpreted as formatstring:

-    Sys::Syslog::syslog($level,@_);
+    ### check for formatstring, if none take only the first string
+    my $fstring = sprintf shift @_, @_;
+    Sys::Syslog::syslog($level, "%s", $fstring);
     return;
   }

right?
(Just to make sure to not have an impact as described in the comment#1)
Comment 5 Marcus Meissner 2005-04-18 15:37:34 UTC
partially. 
 
sprintf is still evaluating the % xpressions in the first 
array element. 
 
check this code: 
#!/usr/bin/perl 
 
sub foo { 
 
        my $str = sprintf shift @_, @_; 
 
        print STDERR "$str" . "\n"; 
} 
 
 
foo('hallohallo','bar'); 
foo('hallo%shallo','bar'); 
foo('%s'); 
foo('hallo%%shallo','bar'); 
foo('%n'); 
 
 
$ perl xx.pl 
hallohallo 
hallobarhallo 
 
hallo%shallo 
Modification of a read-only value attempted at xx.pl line 5. 
$  
 
the string gets evaluated.  
 
i think we should skip the sprintf step and just allow one argument which is 
printed verbatim (my suggeste4d patch) 
Comment 6 Stefan Fent 2005-04-20 12:41:23 UTC
Ok, after some discussion, I changed the patch accordingly.

submitted for 8.2 9.0 9.1 9.2 9.3 STABLE
Comment 7 Marcus Meissner 2005-04-20 14:59:21 UTC
swampid: 969  
Comment 8 Marcus Meissner 2005-04-20 15:05:34 UTC
pinfos submitted. 
Comment 9 Michael Schröder 2005-04-22 16:55:09 UTC
I don't see how this is exploitable as SyS::Syslog::syslog() uses Perl's 
sprintf and I don't see how this can be exploited. This isn't C, you know... 
 
I'm not sure if it is wise to cripple the log() function. If there any 
feedback from the author of Net-Server? 
Comment 10 Marcus Meissner 2005-04-25 12:58:50 UTC
i agree, it only seem to be passed to perl sprintf. 
 
However, the whole module just uses ->log(level,string); and does 
not use format strings as far as I can see. 
 
Also, there is one log() call in perl-Net-Server where it feeds userdata 
directly from the user input and must be fixed. (this is the original cause of 
problem) 
 
$self->log(5,$_); # very verbose log 
should be: 
$self->log(5,"%s",$_); # very verbose log 
Comment 11 Michael Schröder 2005-04-25 13:03:27 UTC
Yeah, but it's just a DoS, you can't get root with it. I don't mind changing 
the log function when the author of Net-Server says it's ok, otherwise we 
should change the call to log(). 
Comment 12 Marcus Meissner 2005-04-27 16:03:15 UTC
contacted author on what is he best fix. 
Comment 13 Thomas Biege 2005-05-24 15:44:21 UTC
Marcus,
does he respond?
Comment 14 Marcus Meissner 2005-05-31 14:23:57 UTC
not until now, no. 
 
I think we should be treating this as a security bug, but as a "bug bug" only. 
Comment 15 Marcus Meissner 2005-06-10 12:15:24 UTC
CAN-2005-1127 
Comment 16 Marcus Meissner 2005-06-23 07:29:21 UTC
no feedback received yet. 
 
I think we should proceed with our fix as-is. 
 
mls, please checkin patchinfos... 
Comment 17 Michael Schröder 2005-06-23 10:01:22 UTC
Please fix the patchinfo files. This cannot be used to execute code, it is 
just a DoS. 
Comment 18 Marcus Meissner 2005-06-23 10:12:16 UTC
done 
Comment 19 Marcus Meissner 2005-06-27 11:34:41 UTC
packages approved 
Comment 20 Thomas Biege 2009-10-13 21:17:06 UTC
CVE-2005-1127: CVSS v2 Base Score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)