[email protected]
[Top] [All Lists]

Bug#304390: marked as forwarded (postfix-gld: Multiple remotely exploita

Subject: Bug#304390: marked as forwarded postfix-gld: Multiple remotely exploitable vulnerabilities
From: Debian Bug Tracking System
Date: Tue, 12 Apr 2005 17:33:20 -0700
Your message dated Wed, 13 Apr 2005 02:22:14 +0200 (CEST)
with message-id <[email protected]>
has caused the Debian Bug report #304390,
regarding postfix-gld: Multiple remotely exploitable vulnerabilities
to be marked as having been forwarded to the upstream software
author(s) Salim Gasmi <[email protected]>.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

---------------------------------------
Received: (at 304390-forwarded) by bugs.debian.org; 13 Apr 2005 00:22:17 +0000
>From [email protected] Tue Apr 12 17:22:17 2005
Return-path: <[email protected]>
Received: from pizarro.unex.es [158.49.8.2] (postfix)
        by spohr.debian.org with esmtp (Exim 3.35 1 (Debian))
        id 1DLVe4-0003Rc-00; Tue, 12 Apr 2005 17:22:16 -0700
Received: from localhost (almendralejo.unex.es [158.49.8.199])
        by pizarro.unex.es (Postfix/MJ-1.08) with ESMTP
        id 115A1A1C79; Wed, 13 Apr 2005 02:22:15 +0200 (CEST)
Received: from pizarro.unex.es ([158.49.8.2])
        by localhost (emilio [158.49.17.20]) (amavisd-new, port 10024)
        with ESMTP id 13415-08; Wed, 13 Apr 2005 02:23:15 +0200 (CEST)
Received: from guadiana.unex.es (guadiana.unex.es [158.49.17.23])
        by pizarro.unex.es (Postfix/MJ-1.08) with ESMTP
        id 49BC9A1C68; Wed, 13 Apr 2005 02:22:14 +0200 (CEST)
Received: from sanvila (helo=localhost)
        by guadiana.unex.es with local-esmtp (Exim 3.35 #1 (Debian))
        id 1DLVe2-0004Eb-00; Wed, 13 Apr 2005 02:22:14 +0200
Date: Wed, 13 Apr 2005 02:22:14 +0200 (CEST)
From: Santiago Vila <[email protected]>
To: Salim Gasmi <[email protected]>
Cc: [email protected],
        Moritz Muehlenhoff <[email protected]>
Subject: Bug#304390: postfix-gld: Multiple remotely exploitable vulnerabilities
 (fwd)
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at unex.es
Delivered-To: [email protected]
X-Spam-Checker-Version: SpamAssassin 2.60-bugs.debian.org_2005_01_02 
        (1.212-2003-09-23-exp) on spohr.debian.org
X-Spam-Status: No, hits=-10.0 required=4.0 tests=BAYES_01,HAS_BUG_NUMBER,
        HAS_PACKAGE autolearn=ham version=2.60-bugs.debian.org_2005_01_02
X-Spam-Level: 

Hello.

I received this from the Debian bug system:

---------- Forwarded message ----------
From: Moritz Muehlenhoff <[email protected]>
To: Debian Bug Tracking System <[email protected]>
Date: Tue, 12 Apr 2005 22:22:21 +0200
Subject: Bug#304390: postfix-gld: Multiple remotely exploitable
    vulnerabilities

Package: postfix-gld
Severity: grave
Tags: security
Justification: user security hole

dong-hun you <[email protected]> posted a report about several
remotely exploitable security issues to the vuln-watch mailing list.
As I couldn't find a proper WWW reference I'm posting the advisory
verbose.

Cheers,

        Moritz

        ========================================
        INetCop Security Advisory #2005-0x82-026
        ========================================


 Title: GLD (Greylisting daemon for Postfix) multiple vulnerabilities.


 0x01. Description

 About:
 Gld is a standalone greylisting server for Postfix.

 Greylisting is a new weapon to use against spam. For more information on
 this technique, see http://www.greylisting.org.

 This implementation listens on a TCP port and uses MySQL for storing data.
 The server supports whitelists based on sender, sender domain and client IP.
 It also supports light greylisting.

 URL: http://www.gasmi.net/gld.html
 Reference URL: http://www.gasmi.net/down/gld-readme

 It's using in FreeBSD port and gentoo, debian.

 Reference URL: http://wyae.de/docs/greylisting_on_debian.php
 Reference URL: http://www.freebsd.org/cgi/cvsweb.cgi/ports/mail/gld/
 Reference URL: http://gentoo-portage.com/mail-filter/gld
 Reference URL: http://directory.fsf.org/email/spam/gld.html

 The program has plenty of remote vulnerabilities.
 These vulnerabilities can be used remote user to gain root privilege.


 #1) Multi-oveflow vulnerability


 This problem happens because of abuse of strcpy() and sprintf() functions

 `/gid-1.4/server.c':
    --
        ...
   195  int HandleChild(int s,config *cnf)
   196  {
   197  char buff[BLEN];
   198  char request[BLEN];
   199  char sender[BLEN];
   200  char recipient[BLEN];
   201  char ip[BLEN];
        ...
   301  if(strcmp(request,REQ)!=0 || recipient[0]==0 || ip[0]==0)
   302          {
   303          sprintf(buff,"Received invalid data req=(%s) sender=(%s) 
recipient=(%s) ip=(%s)",request,sender,recipient,ip); // here
   304          if(cnf->syslog==1) ErrorLog(cnf,buff);
   305          if(cnf->debug==1) printf("%d: %s\n",pid,buff);
   306          return(-2);
   307          }
        ...
    --

 Remote overflow exploit can be happened by sprintf() and it allows attacker to 
gain root privilege.


 #2) remote format string -


 These vulnerabilities are very easy to be exploited.
 gld.conf is supporting syslog() function basically.
 Thereby, with problem in next code, it's possible to gain root privilege.


 `/gld-1.4/cnf.c':
    --
        ...
   117  void ErrorLog(config *conf,char *msg)
   118  {
   119  #ifdef HAVE_SYSLOG_H
   120  openlog("gld",0,conf->facility);
   121  syslog(LOG_ALERT,msg); // here
   122  closelog();
   123  #endif
   124  }
        ...
    --

 It happens by illegal use of syslog() function.

 --
 bash-2.04# cat *.c |grep ErrorLog |grep -v void
 if(conf.syslog==1) ErrorLog(&conf,"gld started, up and running");
                 if(cid < 0 && conf.syslog==1) ErrorLog(&conf,"Fork returned 
error code, no child");
                 ErrorLog(cnf,buff);
                 if(cnf->syslog==1) ErrorLog(cnf,"Read Network error");
         if(cnf->syslog==1) ErrorLog(cnf,buff);
         if(cnf->syslog==1) ErrorLog(cnf,"MySQL error");
 bash-2.04#
 --


 It can be exploited pretty easily.
 And there are alot more sprintf(), strcpy() function overflow vulnerabilities 
which are not mentioned.


 0x02. Vulnerable Packages


 Vendor site: http://www.gasmi.net/gld.html

 GLD all version (exploitable)
 -gld-1.4.tgz
 -gld.1.3.tgz


 0x03. Exploit

 I made this exploit in RedHat Linux 7.x and 9.x by Proof of Concept code.
 There is no plan to develop other platform code.


 #1) remote buffer overflow exploit:


 bash-2.04$ ./0x82-meOw_linuxer_forever -t 3 -h x0x

  #
  # 0x82-meOw_linuxer_forever - Greylisting daemon for Postfix remote exploit
  # szoahc(at)hotmail(dot)com
  #

  #
  # target host: x0x:2525
  # type: Red Hat Linux release 9 (Shrike) gld 1.4 (buffer overflow exploit)
  # method: jmp *%esp exploit: 254 byte
  # send code size: 2200 byte
  #
  # Waiting rootshell, Trying x0x:36864 ...
  # connected to x0x:36864 !
  #

  #
  # Kill two bird with one stone!
  # OK, It's Rootshell
  #

 Linux x0x 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux
 uid=0(root) gid=0(root) 
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
 bash: no job control in this shell
 stty: standard input: Invalid argument
 [[email protected] /]# w


 #2) remote format string exploit:


 bash-2.04$ ./0x82-meOw_linuxer_forever -t 0 -h x0x

  #
  # 0x82-meOw_linuxer_forever - Greylisting daemon for Postfix remote exploit
  # szoahc(at)hotmail(dot)com
  #

  #
  # target host: x0x:2525
  # type: Red Hat Linux release 9 (Shrike) gld 1.4 (format string exploit)
  # Make format string, .dtors: 0x804d14c
  #
  # shellcode addr: 0x805506e, size: 320 byte
  # send code size: 394 byte
  #
  # Waiting rootshell, Trying x0x:36864 ...
  # connected to x0x:36864 !
  #

  #
  # Kill two bird with one stone!
  # OK, It's Rootshell
  #

 Linux x0x 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux
 uid=0(root) gid=0(root) 
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
 bash: no job control in this shell
 stty: standard input: Invalid argument
 [[email protected] /]#


 0x04. Patch


 GLD 1.4 patch:

 === gld-1.4.patch ===
--- cnf.c       2004-08-18 23:44:22.000000000 +0900
+++ patch/cnf.c 2005-03-06 17:36:04.000000000 +0900
@@ -118,7 +118,7 @@
 {
 #ifdef HAVE_SYSLOG_H
 openlog("gld",0,conf->facility);
-syslog(LOG_ALERT,msg);
+syslog(LOG_ALERT,"%s",msg);
 closelog();
 #endif
 }
--- greylist.c  2004-08-18 04:12:38.000000000 +0900
+++ patch/greylist.c    2005-03-06 17:39:59.000000000 +0900
@@ -20,9 +20,9 @@
 pid=getpid();

 ts=time(0);
-strcpy(oip,ip);
-strcpy(osender,sender);
-strcpy(orecipient,recipient);
+strncpy(oip,ip,sizeof(oip)-1);
+strncpy(osender,sender,sizeof(osender)-1);
+strncpy(orecipient,recipient,sizeof(orecipient)-1);

 if(conf->debug==1) printf("%d: Starting the greylist algo\n",pid);

@@ -52,17 +52,17 @@
         if(conf->debug==1) printf("%d: lightgrey on domain is on, let's keep 
the domain only on recipient and sender\n",pid);

         domain=(char *)strstr(osender,"@");
-        if(domain!=NULL) strcpy(sender,domain);
+        if(domain!=NULL) strncpy(sender,domain,BLEN-1);

         domain=(char *)strstr(orecipient,"@");
-        if(domain!=NULL) strcpy(recipient,domain);
+        if(domain!=NULL) strncpy(recipient,domain,BLEN-1);
         }

 //
 // Do we have this entry in our database ?
 //

-sprintf(query,"select first from greylist where ip='%s' and sender='%s' and 
recipient='%s'",ip,sender,recipient);
+snprintf(query,sizeof(query)-1,"select first from greylist where ip='%s' and 
sender='%s' and recipient='%s'",ip,sender,recipient);
 n=SQLQuery(query);

 if(conf->debug==1) printf("%d: Query=(%s) result=%ld\n",pid,query,n);
@@ -78,7 +78,7 @@
 //
 if(conf->lightd==1 && n==0)
         {
-        sprintf(query,"select first from greylist where ip='%s' and 
sender='%s' and recipient='%s'",ip,osender,orecipient);
+        snprintf(query,sizeof(query)-1,"select first from greylist where 
ip='%s' and sender='%s' and recipient='%s'",ip,osender,orecipient);
         n=SQLQuery(query);
         if(n<0) return(-1);
         if(n==0) fneither=1; else fnotdomain=1;
@@ -101,7 +101,7 @@
                domain=(char *)strstr(osender,"@");
                if(domain==NULL) domain=osender;

-               strcpy(netw,oip);
+               strncpy(netw,oip,sizeof(netw)-1);
                l=strlen(netw);
                for(i=l-1;i>=0;i--)
                        if(netw[i]=='.')
@@ -111,7 +111,7 @@
                                }


-        sprintf(query,"select count(mail) from whitelist where mail in 
('%s','%s','%s','%s')",osender,domain,oip,netw);
+        snprintf(query,sizeof(query)-1,"select count(mail) from whitelist 
where mail in ('%s','%s','%s','%s')",osender,domain,oip,netw);
        n=SQLQuery(query);
        if(conf->debug==1) printf("%d: Query=(%s) result=%ld\n",pid,query,n);
        if(n>0)
@@ -130,7 +130,7 @@
                x=sscanf(oip,"%d.%d.%d.%d",&a,&b,&c,&d);
                if(x==4)
                        {
-                       sprintf(query,"%d.%d.%d.%d.%s",d,c,b,a,conf->dnswl);
+                       
snprintf(query,sizeof(query)-1,"%d.%d.%d.%d.%s",d,c,b,a,conf->dnswl);
                        n=DnsIp(query,NULL);
                        if(conf->debug==1) printf("%d: DNSQuery=(%s) 
result=%ld\n",pid,query,n);
                        if(n==0)
@@ -146,9 +146,9 @@
        // was not whitelisted and thus we have to insert it
        //
        if(conf->lightd==1 && fneither==1)
-                sprintf(query,"insert into greylist 
values('%s','%s','%s',%d,%d,1)",ip,osender,orecipient,ts,ts);
+                snprintf(query,sizeof(query)-1,"insert into greylist 
values('%s','%s','%s',%d,%d,1)",ip,osender,orecipient,ts,ts);

-       else sprintf(query,"insert into greylist 
values('%s','%s','%s',%d,%d,1)",ip,sender,recipient,ts,ts);
+       else snprintf(query,sizeof(query)-1,"insert into greylist 
values('%s','%s','%s',%d,%d,1)",ip,sender,recipient,ts,ts);

        SQLQuery(query);
        if(conf->debug==1) printf("%d: Query=(%s)\n",pid,query);
@@ -165,9 +165,9 @@
        if(conf->update==1)
                {
                if(conf->lightd==1 && fnotdomain==1)
-                       sprintf(query,"update greylist set last=%d,n=n+1 where 
ip='%s' and sender='%s' and recipient='%s'",ts,ip,osender,orecipient);
+                       snprintf(query,sizeof(query)-1,"update greylist set 
last=%d,n=n+1 where ip='%s' and sender='%s' and 
recipient='%s'",ts,ip,osender,orecipient);

-               else sprintf(query,"update greylist set last=%d,n=n+1 where 
ip='%s' and sender='%s' and recipient='%s'",ts,ip,sender,recipient);
+               else snprintf(query,sizeof(query)-1,"update greylist set 
last=%d,n=n+1 where ip='%s' and sender='%s' and 
recipient='%s'",ts,ip,sender,recipient);

                SQLQuery(query);
                if(conf->debug==1) printf("%d: Query=(%s)\n",pid,query);
@@ -180,7 +180,7 @@

        if(ts-n>conf->mini && conf->lightd==1 && fnotdomain==1)
                {
-               sprintf(query,"insert into greylist 
values('%s','%s','%s',%d,%d,1)",ip,sender,recipient,ts,ts);
+               snprintf(query,sizeof(query)-1,"insert into greylist 
values('%s','%s','%s',%d,%d,1)",ip,sender,recipient,ts,ts);
                if(conf->debug==1) printf("Add the domain triplet for next 
time.\n");
                SQLQuery(query);
                }
--- server.c    2004-08-19 07:57:03.000000000 +0900
+++ patch/server.c      2005-03-06 17:41:52.000000000 +0900
@@ -215,7 +215,7 @@
        if(cnf->debug==1) printf("%d: Rejected New incoming connexion from %s 
(%s)\n",pid,buff,ip);
        if(cnf->syslog==1)
                {
-               sprintf(buff,"Rejected New incoming connexion from %s 
(%s)\n",buff,ip);
+               snprintf(buff,sizeof(buff)-1,"Rejected New incoming connexion 
from %s (%s)\n",buff,ip);
                ErrorLog(cnf,buff);
                }

@@ -262,16 +262,16 @@
        if(strcmp(buff,"")==0) break;

        if(strncmp(buff,"request=",8)==0)
-               strcpy(request,buff+8);
+               strncpy(request,buff+8,sizeof(request)-1);

        if(strncmp(buff,"sender=",7)==0)
-               strcpy(sender,buff+7);
+               strncpy(sender,buff+7,sizeof(sender)-1);

        if(strncmp(buff,"recipient=",10)==0)
-               strcpy(recipient,buff+10);
+               strncpy(recipient,buff+10,sizeof(recipient)-1);

        if(strncmp(buff,"client_address=",15)==0)
-               strcpy(ip,buff+15);
+               strncpy(ip,buff+15,sizeof(ip)-1);

        }

@@ -300,7 +300,7 @@

 if(strcmp(request,REQ)!=0 || recipient[0]==0 || ip[0]==0)
        {
-       sprintf(buff,"Received invalid data req=(%s) sender=(%s) recipient=(%s) 
ip=(%s)",request,sender,recipient,ip);
+       snprintf(buff,sizeof(buff)-1,"Received invalid data req=(%s) 
sender=(%s) recipient=(%s) ip=(%s)",request,sender,recipient,ip);
        if(cnf->syslog==1) ErrorLog(cnf,buff);
        if(cnf->debug==1) printf("%d: %s\n",pid,buff);
        return(-2);
@@ -322,7 +322,7 @@

 if(n==0)
        {
-       sprintf(buff,"action=defer_if_permit %s\n\n",cnf->message);
+       snprintf(buff,sizeof(buff)-1,"action=defer_if_permit 
%s\n\n",cnf->message);
         WriteSocket(s,buff,strlen(buff),TOUT);
         if(cnf->syslog==1) Log(cnf,recipient,sender,ip,MSGGREYLIST);
        if(cnf->debug==1) printf("%d: Decision is to greylist\n",pid);

 === eof ===

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.11
Locale: LANG=C, [email protected] (charmap=ISO-8859-15)



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

<Prev in Thread] Current Thread [Next in Thread>
  • Bug#304390: marked as forwarded (postfix-gld: Multiple remotely exploitable vulnerabilities), Debian Bug Tracking System <=