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]