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]