Ben Cantrick (alias Macky Stingray)
1997-Mar-22 16:52 UTC
"Secure" tftpd source for Linux?
I''ve been poking around my system, and realized that having a tftp server would be handy. (I''m working with cisco routers, which have the capability to up and download configuration images via tftp.) However, I''m not content with the usual tftpd that comes with Linux. The whole "specify each directory you want" scheme is cock-eyed to me. I''d prefer a tftp server more like the ones I''ve seen on Sun and HPUX machines. That type chroot()''s to a "secure" (and I use the term loosely) directory just after it starts up. I''ve modified and started using a tftpd that starts up and then chroots to the directory specified by the first command line argument, or "/var/tftp". Then, it jettisons root privledges in favor of nobody/nogroup and goes on its way. It''s a cute little hack, and it seems to work. But I am convinced that someone must have seen the need and done this before. My extended forays into the web via several search engines have failed to turn up anything relevant. So I''m curious if anyone on the list knows of (or better, has) freely distributable source for a "secure" tftpd. If not, I''ll probably polish mine up a bit and then start asking people for evaluations of the code. If it passes, I''ll toss it up on my web page and give it away to anyone who wants it. -Ben -- =--------- ucsu.colorado.edu/~cantrick/home.html -------------*Ben Cantrick, diehard BGC otaku and Priss fan. ---> THE BGC DUBS SUCK! <---*
Alex Belits
1997-Mar-23 09:11 UTC
Re: [linux-security] tftpd bug (was: "Secure" tftpd source for Linux?)
[Mod: David Holland''s message added to the back, linux-alert added to the list of addresses -- alex] On Sat, 22 Mar 1997, Ben Cantrick wrote:> It''s a cute little hack, and it seems to work. But I am convinced that > someone must have seen the need and done this before. My extended forays > into the web via several search engines have failed to turn up anything > relevant. So I''m curious if anyone on the list knows of (or better, has) > freely distributable source for a "secure" tftpd.tftpd in FreeBSD distribution uses chroot() and sets its uid to nobody. I don''t think, it does anything reasonable with groups. But... I''ve looked at both Linux (NetKit 0.09) and FreeBSD (2.2-ALPHA) tftpd and found rather strange code in Linux tftpd''s validate_access() function: ---8<--- syslog(LOG_ERR, "tftpd: trying to get file: %s\n", filename); if (*filename != ''/'') { syslog(LOG_ERR, "tftpd: serving file from %s\n", dirs[0]); chdir(dirs[0]); } else { for (dirp = dirs; *dirp; dirp++) if (strncmp(filename, *dirp, strlen(*dirp)) == 0) break; if (*dirp==0 && dirp!=dirs) return (EACCESS); } /* * prevent tricksters from getting around the directory restrictions */ for (cp = filename + 1; *cp; cp++) if(*cp == ''.'' && strncmp(cp-1, "/../", 4) == 0) return(EACCESS); --->8--- ...it checks _only_ for "/../" and start _always_ from the second character in the filename (in other words, if filename is empty, it will "analyze" the memory after it where other piece of code places mode, so at least it won''t do anything destructive). But it also assumes all not starting from ''/'' filenames to be relative to some directory, and never checks them for "../" that FreeBSD one does. So (see code above for locations of calls to syslog()): ---8<--- Mar 23 06:55:08 phobos in.tftpd[9799]: connect from phobos.illtel.denver.co.us Mar 23 06:55:08 phobos tftpd[9800]: tftpd: trying to get file: ../etc/passwd Mar 23 06:55:08 phobos tftpd[9800]: tftpd: serving file from /tftpboot --->8--- ...and obviously it was /tftpboot/../etc/passwd aka /etc/passwd Not that it does any damage by itself, but it definitely wasn''t supposed to do that. FreeBSD tftpd disallows such things. According to copyright notices, both tftpd are derived from some old (1983) Berkeley code, and Linux one has some general clumsiness all over its code (and default /tftpboot directory didn''t exist until 0.09, 0.08 seems to require the list of directories, or it will just SIGSEGV on NULL pointer). FreeBSD tftpd compiles with command line: gcc -O -DLOG_FTP=LOG_DAEMON -o tftpd tftpd.c tftpsubs.c and works fine if -ls /tftpboot is added as options to its command line. Otherwise it only checks file permissions without even trying to become "nobody" and thus opens hole for non-executable directories (even if directory is non-executable for anyone but root, files in it will be accessible). Also it''s necessary to hardlink /dev/log under chroot directory to keep logging functional. -- Alex P.S. how such umm... not obviously secure code got into tftpd in the first place after that many revisions that definitely were done to increase security? After all, changes between NetKit revisions _do_ make sense. Return-Path: dholland@hcs.harvard.edu > [tftpd source mapped to /dev/null] > > Finally, it prevents ".." and "." in filename to be used to go up: He''s right; it doesn''t block leading ".." in the case where the filename doesn''t begin with "/". Someone already caught this and the fix is going to be in the next release; in the meantime here''s a patch. > > P.S. how such umm... not obviously secure code got into tftpd in the first > > place after that many revisions that definitely were done to increase > > security? After all, changes between NetKit revisions _do_ make sense. It needs an intensive rewrite. Don''t hold your breath... :( *** tftpd.c 1996/12/29 18:42:40 1.8 --- tftpd.c 1997/03/08 11:31:00 *************** *** 40,44 **** */ char rcsid[] ! "$Id: tftpd.c,v 1.8 1996/12/29 18:42:40 dholland Exp $"; /* --- 40,44 ---- */ char rcsid[] ! "$Id: tftpd.c,v 1.9 1997/03/08 11:30:30 dholland Exp $"; /* *************** *** 298,301 **** --- 298,303 ---- * prevent tricksters from getting around the directory restrictions */ + if (!strncmp(filename, "../", 3)) + return EACCESS; for (cp = filename + 1; *cp; cp++) if(*cp == ''.'' && strncmp(cp-1, "/../", 4) == 0) -- - David A. Holland | Number of words in the English language that dholland@eecs.harvard.edu | exist because of typos or misreadings: 381
On Sat, 22 Mar 1997, Ben Cantrick wrote:> I''ve been poking around my system, and realized that having a tftp server > would be handy. (I''m working with cisco routers, which have the capability to > up and download configuration images via tftp.) > > However, I''m not content with the usual tftpd that comes with Linux. The > whole "specify each directory you want" scheme is cock-eyed to me. I''d > prefer a tftp server more like the ones I''ve seen on Sun and HPUX machines. > That type chroot()''s to a "secure" (and I use the term loosely) directory > just after it starts up.I went through this almost 2 years ago when setting up a tftp server on a slackware 2.3 box. I found that the man page for slackware''s in.tftpd was wrong, or in.tftpd just didn''t work as advertised. I ended up hacking the inetd.conf to get the behaviour I wanted. tftp dgram udp wait root /usr/sbin/tcpd /usr/sbin/chroot /tftp /in.tftpd At the time I wasn''t as interested in hacking source as I might be now...I just wanted tftpd to work asap. This has the odd side affect that in hosts.allow, you have to specify chroot as the service. :) ------------------------------------------------------------------ Jon Lewis <jlewis@fdt.net> | Unsolicited commercial e-mail will Network Administrator | be proof-read for $199/hr. ________Finger jlewis@inorganic5.fdt.net for PGP public key_______