Date: Tue, 23 Feb 1999 14:59:14 -0400 From: Julien Nadeau To: PacketStorm@genocide2600.com Subject: NcFTPd remote buffer overflow Proof of Concept - Security Advisory 02/23/99 http://poc.csoft.net Released by poc@csoft.net sw3wn@poc.csoft.net --- Affected Program NcFTPd Description FTP server (commercial) Severity Theoretical root compromise, logs compromise Synopsis: NcFTPd is a commercial FTP (File Transfer Protocol) server, in the NcFTP product line. The source code is not publicly released. This was tested on Linux with libc5 (there's a glibc2 specific version available). Problem: NcFTPd's PORT parsing function has a stack buffer overflow problem, which would basically allow a user to remotely execute arbitrary code - the thing here is that the PORT parsing function seem to change characters, that are not in the range 0x30-0x39 (ASCII '0'-'9'), into 0x20 (ASCII space), hence making an exploit almost impossible (note that, if ascii 0x40 would be allowed that would be a different story =p). The program only parses for characters out of the 0-9 range in a specific area in memory (the one that contains return address heh) - the rest is kept unchanged, and you can't really go further in memory, input line size is restricted. Like with most buffer overflows there are probably work-arounds to exploit it - this could have been a particulary neat exploit, since it runs as a child and one could gain access transparently without crashing the parent. The current bug is not really a problem, it can crash the child process with a segfault, the parent process receives a signal 6 (abort) and the child process stay zombie for a few seconds and a brand new one is created. A few minor DoS attacks are possible but, who cares. Oh and this could be used to not get listed in the logs too. Example: -- evil:$ nc victim ftp 220 victim NcFTPd Server (unregistered copy) ready. user anonymous 331 Guest login ok, send your complete e-mail address as password. pass some@thing 230-You are user #1 of 50 simultaneous users allowed. 230- 230 Logged in anonymously. port 00000000000000000000000000000000000000000000 (...) 501 Syntax error in parameters. evil:$ -- Status: I contacted the authors, nice enough to send me back the piece of code that causes the problem - here goes: static int ftp_aton(const char *cp, struct sockaddr_in *sinaddr) { char buf[64]; char *dst; char *dstlim; int i, c; unsigned int octets[6], u; memset(sinaddr, 0, sizeof(struct sockaddr_in)); dst = buf; dstlim = dst + sizeof(buf); for ( ; ; ) { c = *cp++; if (c == '\0') break; if (! isdigit(c)) c = ' '; if (dst < dstlim) *dst++ = c; } *dst = '\0'; if (sscanf(buf, "%u%u%u%u%u%u", &octets[0], &octets[1], &octets[2], &octets[3], &octets[4], &octets[5] ) != 6) { return (-1); } for (i=0; i<6; i++) { if (octets[i] > 0xFF) return (-1); } sinaddr->sin_family = AF_INET; u = (octets[0] << 24) | (octets[1] << 16) | (octets[2] << 8) | (octets[3]); sinaddr->sin_addr.s_addr = htonl(u); u = (octets[4] << 8) | (octets[5]); sinaddr->sin_port = htons((unsigned short) u); return (0); } /* ftp_aton */ void Port(char *line) { if (gLoggedIn == 0) { NotLoggedIn(); return; } if (gAllowPORT == 0) { Reply("550 This site does not permit PORT. Please use PASV instead.\r\n"); return; } if (ftp_aton(line, &gRemoteDataAddr) < 0) { Reply("501 Syntax error in parameters.\r\n"); return; } /* ... */ } ------------------------------------------------------------------------- Date: Tue, 23 Feb 1999 21:42:06 -0600 From: Mike Gleason To: BUGTRAQ@netspace.org Subject: Comments on NcFTPd "theoretical root compromise" Summary:  Don't Panic!  Exactly one byte can be corrupted. There is an off-by-one bug which may cause one byte on the stack to be zeroed.  This can occur if an attacker uses 64 or more characters in the range of '0' to '9' in an FTP "PORT" command.  This can cause the child process handling the FTP connection to crash and respawn, but does not leave an attacker with root privileges.  Nevertheless, NcFTPd 2.4.1 is available which fixes this problem.  See the download page at http://www.ncftp.com/download/ or the mirror domain at http://www.ncftpd.com/download/ .  As usual, users of any version of NcFTPd can upgrade to version 2.4.1 free of charge. ObPlea:  I think we're making progress.  Rather than hearing about a bug second hand, I at least got an email at the same time a message goes out to Bugtraq.  However, I'd like an opportunity to verify that a bug actually exists, *AND* verify the severity of it.  A lot of people get thrown into a frenzy by the words "remote root compromise" even though it appears in the same sentence as "theoretical."  In the event of an actual emergency, I'd like to ask that in addition to verification, I request 5 working days to provide an official fix and time for users to upgrade prior to posting an "exploit".  That's not too much to ask.  (Didn't we just go over this whole shitbag in the HERT thread?) For reference, here is a snippet which illustrates the actual problem:  static int  ftp_aton(const char *cp, struct sockaddr_in *sinaddr)  {         char buf[64];         char *dst;         char *dstlim;         int i, c;         unsigned int octets[6], u;           memset(sinaddr, 0, sizeof(struct sockaddr_in));         dst = buf; -       dstlim = dst + sizeof(buf); +       dstlim = dst + sizeof(buf) - 1;           for ( ; ; ) {                 c = (int) *cp++;                 if (c == '\0')                         break;                 if (! isdigit(c))                         c = ' ';                 if (dst < dstlim)                         *dst++ = c;         }         *dst = '\0'; Mike Gleason NcFTP Software ------------------------------------------------------------------------- Date: Wed, 24 Feb 1999 22:07:25 -0400 From: Julien Nadeau To: PacketStorm@GENOCIDE2600.COM Subject: [Fwd: Comments on NcFTPd "theoretical root compromise"] Julien Nadeau wrote: > > Mike Gleason wrote: > > > > Summary: Don't Panic! Exactly one byte can be corrupted. > > > > There is an off-by-one bug which may cause one byte on the stack to be > > zeroed. This can occur if an attacker uses 64 or more characters in > > the range of '0' to '9' in an FTP "PORT" command. This can cause the > > child process handling the FTP connection to crash and respawn, but > > does not leave an attacker with root privileges. Nevertheless, NcFTPd > > 2.4.1 is available which fixes this problem. See the download page at > > http://www.ncftp.com/download/ or the mirror domain at > > http://www.ncftpd.com/download/ . As usual, users of any version of > > NcFTPd can upgrade to version 2.4.1 free of charge. > > Actually, more than one byte can be corrupted, but without modifying > anything > important, and only the buffer part [64 bytes] is checked for characters > out of > range 0x30-0x39, the rest is kept intact. The function's return address > in the > overflow (was 0x0806968c i think) can be changed. > > Still, you can get away without being listed in the logs =p. > > > ObPlea: I think we're making progress. Rather than hearing about a > > bug second hand, I at least got an email at the same time a message > > goes out to Bugtraq. However, I'd like an opportunity to verify that > > a bug actually exists, *AND* verify the severity of it. A lot of > > people get thrown into a frenzy by the words "remote root compromise" > > even though it appears in the same sentence as "theoretical." In the > > event of an actual emergency, I'd like to ask that in addition to > > verification, I request 5 working days to provide an official fix and > > time for users to upgrade prior to posting an "exploit". That's not > > too much to ask. (Didn't we just go over this whole shitbag in the > > HERT thread?) > > This is not an alert, just one funky buffer overflow that looked like > it could have led to arbitrary code execution > I thought there might be some work-around, that was before I could look > at the source code. > > Changing the subject here was my main concern. heh. > > > For reference, here is a snippet which illustrates the actual problem: > > > > static int > > ftp_aton(const char *cp, struct sockaddr_in *sinaddr) > > { > > char buf[64]; > > char *dst; > > char *dstlim; > > int i, c; > > unsigned int octets[6], u; > > > > memset(sinaddr, 0, sizeof(struct sockaddr_in)); > > dst = buf; > > - dstlim = dst + sizeof(buf); > > + dstlim = dst + sizeof(buf) - 1; > > > > for ( ; ; ) { > > c = (int) *cp++; > > if (c == '\0') > > break; > > if (! isdigit(c)) > > c = ' '; > > if (dst < dstlim) > > *dst++ = c; > > } > > *dst = '\0'; > > > > Mike Gleason > > NcFTP Software > > Date: Wed, 24 Feb 1999 08:50:35 -0400 From: Julien Nadeau To: Mike Gleason Subject: Re: Comments on NcFTPd "theoretical root compromise" Mike Gleason wrote: > > Summary: Don't Panic! Exactly one byte can be corrupted. > > There is an off-by-one bug which may cause one byte on the stack to be > zeroed. This can occur if an attacker uses 64 or more characters in > the range of '0' to '9' in an FTP "PORT" command. This can cause the > child process handling the FTP connection to crash and respawn, but > does not leave an attacker with root privileges. Nevertheless, NcFTPd > 2.4.1 is available which fixes this problem. See the download page at > http://www.ncftp.com/download/ or the mirror domain at > http://www.ncftpd.com/download/ . As usual, users of any version of > NcFTPd can upgrade to version 2.4.1 free of charge. Actually, more than one byte can be corrupted, but without modifying anything important, and only the buffer part [64 bytes] is checked for characters out of range 0x30-0x39, the rest is kept intact. The function's return address in the overflow (was 0x0806968c i think) can be changed. Still, you can get away without being listed in the logs =p. > ObPlea: I think we're making progress. Rather than hearing about a > bug second hand, I at least got an email at the same time a message > goes out to Bugtraq. However, I'd like an opportunity to verify that > a bug actually exists, *AND* verify the severity of it. A lot of > people get thrown into a frenzy by the words "remote root compromise" > even though it appears in the same sentence as "theoretical." In the > event of an actual emergency, I'd like to ask that in addition to > verification, I request 5 working days to provide an official fix and > time for users to upgrade prior to posting an "exploit". That's not > too much to ask. (Didn't we just go over this whole shitbag in the > HERT thread?) This is not an alert, just one funky buffer overflow that looked like it could have led to arbitrary code execution I thought there might be some work-around, that was before I could look at the source code. Changing the subject here was my main concern. heh. > For reference, here is a snippet which illustrates the actual problem: > > static int > ftp_aton(const char *cp, struct sockaddr_in *sinaddr) > { > char buf[64]; > char *dst; > char *dstlim; > int i, c; > unsigned int octets[6], u; > > memset(sinaddr, 0, sizeof(struct sockaddr_in)); > dst = buf; > - dstlim = dst + sizeof(buf); > + dstlim = dst + sizeof(buf) - 1; > > for ( ; ; ) { > c = (int) *cp++; > if (c == '\0') > break; > if (! isdigit(c)) > c = ' '; > if (dst < dstlim) > *dst++ = c; > } > *dst = '\0'; > > Mike Gleason > NcFTP Software > > At 12:37 PM 2/23/99 -0400, Julien Nadeau wrote: > >Proof of Concept - Security Advisory 02/23/99 > >http://poc.csoft.net Released by > >poc@csoft.net sw3wn@poc.csoft.net > > > >--- > > > >Affected Program NcFTPd > >Description FTP server (commercial) > >Severity Theoretical root compromise, logs compromise > > > > > >Synopsis: > > 05 MESSAGE TEXT Folder: INBOX Message 356 of 364 94% > >Synopsis: > > > >NcFTPd is a commercial FTP (File Transfer Protocol) server, in the > >NcFTP product line. The source code is not publicly released. This > >was tested on Linux with libc5 (there's a glibc2 specific version > >available). > > > >Problem: > > > >NcFTPd's PORT parsing function has a stack buffer overflow > >problem, which would basically allow a user to remotely execute > >arbitrary code - the thing here is that the PORT parsing function > >seem to change characters, that are not in the range 0x30-0x39 > >(ASCII '0'-'9'), into 0x20 (ASCII space), hence making an exploit > >almost impossible (note that, if ascii 0x40 would be allowed that > >would be a different story =p). > > > >The program only parses for characters out of the 0-9 range in a > >specific area in memory (the one that contains return address heh) > >- the rest is kept unchanged, and you can't really go further in > >memory, input line size is restricted. > > > >However, since NcFTPd does not come with source code, I'm not sure. > >Like with most buffer overflows there are probably work-arounds to > >exploit it - this could have been a particulary neat exploit, since > >it runs as a child and one could gain access transparently without > >crashing the parent. > > > >The current bug is not really a problem, it can crash the child > process > >with a segfault, the parent process receives a signal 6 (abort) and > the > >child process stay zombie for a few seconds and a brand new one is > >created. > >A few minor DoS attacks are possible but, who cares. Oh and this > could > >be > >used to not get listed in the logs too. > > > >Example: > > > >-- > >evil:$ nc victim ftp > >220 victim NcFTPd Server (unregistered copy) ready. > >user anonymous > >331 Guest login ok, send your complete e-mail address as password. > >pass some@thing > >230-You are user #1 of 50 simultaneous users allowed. > >230- > >230 Logged in anonymously. > >port 00000000000000000000000000000000000000000000 (...) > >501 Syntax error in parameters. > >evil:$ > >-- > > > >Status: > > > >I couldn't come up with a patch, since the source code doesn't > >come with NcFTPd. I contacted the authors about the bug.