|
|
96e81d |
From 043366ac3248a58662a6fbf47a1dd688a75d0e78 Mon Sep 17 00:00:00 2001
|
|
|
96e81d |
From: Darshit Shah <darnir@gmail.com>
|
|
|
96e81d |
Date: Mon, 8 Sep 2014 00:41:17 +0530
|
|
|
96e81d |
Subject: [PATCH 1/2] Fix R7-2014-15: Arbitrary Symlink Access
|
|
|
96e81d |
|
|
|
96e81d |
Wget was susceptible to a symlink attack which could create arbitrary
|
|
|
96e81d |
files, directories or symbolic links and set their permissions when
|
|
|
96e81d |
retrieving a directory recursively through FTP. This commit changes the
|
|
|
96e81d |
default settings in Wget such that Wget no longer creates local symbolic
|
|
|
96e81d |
links, but rather traverses them and retrieves the pointed-to file in
|
|
|
96e81d |
such a retrieval.
|
|
|
96e81d |
|
|
|
96e81d |
The old behaviour can be attained by passing the --retr-symlinks=no
|
|
|
96e81d |
option to the Wget invokation command.
|
|
|
96e81d |
---
|
|
|
96e81d |
doc/wget.texi | 23 ++++++++++++-----------
|
|
|
96e81d |
src/init.c | 16 ++++++++++++++++
|
|
|
96e81d |
2 files changed, 28 insertions(+), 11 deletions(-)
|
|
|
96e81d |
|
|
|
96e81d |
diff --git a/doc/wget.texi b/doc/wget.texi
|
|
|
96e81d |
index a31eb5e..f54e98d 100644
|
|
|
96e81d |
--- a/doc/wget.texi
|
|
|
96e81d |
+++ b/doc/wget.texi
|
|
|
96e81d |
@@ -1883,17 +1883,18 @@ Preserve remote file permissions instead of permissions set by umask.
|
|
|
96e81d |
|
|
|
96e81d |
@cindex symbolic links, retrieving
|
|
|
96e81d |
@item --retr-symlinks
|
|
|
96e81d |
-Usually, when retrieving @sc{ftp} directories recursively and a symbolic
|
|
|
96e81d |
-link is encountered, the linked-to file is not downloaded. Instead, a
|
|
|
96e81d |
-matching symbolic link is created on the local filesystem. The
|
|
|
96e81d |
-pointed-to file will not be downloaded unless this recursive retrieval
|
|
|
96e81d |
-would have encountered it separately and downloaded it anyway.
|
|
|
96e81d |
-
|
|
|
96e81d |
-When @samp{--retr-symlinks} is specified, however, symbolic links are
|
|
|
96e81d |
-traversed and the pointed-to files are retrieved. At this time, this
|
|
|
96e81d |
-option does not cause Wget to traverse symlinks to directories and
|
|
|
96e81d |
-recurse through them, but in the future it should be enhanced to do
|
|
|
96e81d |
-this.
|
|
|
96e81d |
+By default, when retrieving @sc{ftp} directories recursively and a symbolic link
|
|
|
96e81d |
+is encountered, the symbolic link is traversed and the pointed-to files are
|
|
|
96e81d |
+retrieved. Currently, Wget does not traverse symbolic links to directories to
|
|
|
96e81d |
+download them recursively, though this feature may be added in the future.
|
|
|
96e81d |
+
|
|
|
96e81d |
+When @samp{--retr-symlinks=no} is specified, the linked-to file is not
|
|
|
96e81d |
+downloaded. Instead, a matching symbolic link is created on the local
|
|
|
96e81d |
+filesystem. The pointed-to file will not be retrieved unless this recursive
|
|
|
96e81d |
+retrieval would have encountered it separately and downloaded it anyway. This
|
|
|
96e81d |
+option poses a security risk where a malicious FTP Server may cause Wget to
|
|
|
96e81d |
+write to files outside of the intended directories through a specially crafted
|
|
|
96e81d |
+@sc{.listing} file.
|
|
|
96e81d |
|
|
|
96e81d |
Note that when retrieving a file (not a directory) because it was
|
|
|
96e81d |
specified on the command-line, rather than because it was recursed to,
|
|
|
96e81d |
diff --git a/src/init.c b/src/init.c
|
|
|
96e81d |
index 93e95f8..94b6f8b 100644
|
|
|
96e81d |
--- a/src/init.c
|
|
|
96e81d |
+++ b/src/init.c
|
|
|
96e81d |
@@ -366,6 +366,22 @@ defaults (void)
|
|
|
96e81d |
|
|
|
96e81d |
opt.dns_cache = true;
|
|
|
96e81d |
opt.ftp_pasv = true;
|
|
|
96e81d |
+ /* 2014-09-07 Darshit Shah <darnir@gmail.com>
|
|
|
96e81d |
+ * opt.retr_symlinks is set to true by default. Creating symbolic links on the
|
|
|
96e81d |
+ * local filesystem pose a security threat by malicious FTP Servers that
|
|
|
96e81d |
+ * server a specially crafted .listing file akin to this:
|
|
|
96e81d |
+ *
|
|
|
96e81d |
+ * lrwxrwxrwx 1 root root 33 Dec 25 2012 JoCxl6d8rFU -> /
|
|
|
96e81d |
+ * drwxrwxr-x 15 1024 106 4096 Aug 28 02:02 JoCxl6d8rFU
|
|
|
96e81d |
+ *
|
|
|
96e81d |
+ * A .listing file in this fashion makes Wget susceptiple to a symlink attack
|
|
|
96e81d |
+ * wherein the attacker is able to create arbitrary files, directories and
|
|
|
96e81d |
+ * symbolic links on the target system and even set permissions.
|
|
|
96e81d |
+ *
|
|
|
96e81d |
+ * Hence, by default Wget attempts to retrieve the pointed-to files and does
|
|
|
96e81d |
+ * not create the symbolic links locally.
|
|
|
96e81d |
+ */
|
|
|
96e81d |
+ opt.retr_symlinks = true;
|
|
|
96e81d |
|
|
|
96e81d |
#ifdef HAVE_SSL
|
|
|
96e81d |
opt.check_cert = true;
|
|
|
96e81d |
--
|
|
|
96e81d |
2.1.0
|
|
|
96e81d |
|
|
|
96e81d |
From bfa8c9cc9937f686a4de110e49710061267f8d9e Mon Sep 17 00:00:00 2001
|
|
|
96e81d |
From: Darshit Shah <darnir@gmail.com>
|
|
|
96e81d |
Date: Mon, 8 Sep 2014 15:07:45 +0530
|
|
|
96e81d |
Subject: [PATCH 2/2] Add checks for valid listing file in FTP
|
|
|
96e81d |
|
|
|
96e81d |
When Wget retrieves a file through FTP, it first downloads a .listing
|
|
|
96e81d |
file and parses it for information about the files and other metadata.
|
|
|
96e81d |
Some servers may serve invalid .listing files. This patch checks for one
|
|
|
96e81d |
such known inconsistency wherein multiple lines in a listing file have
|
|
|
96e81d |
the same name. Such a filesystem is clearly not possible and hence we
|
|
|
96e81d |
eliminate duplicate entries here.
|
|
|
96e81d |
|
|
|
96e81d |
Signed-off-by: Darshit Shah <darnir@gmail.com>
|
|
|
96e81d |
---
|
|
|
96e81d |
src/ftp.c | 27 +++++++++++++++++++++++++--
|
|
|
96e81d |
1 file changed, 25 insertions(+), 2 deletions(-)
|
|
|
96e81d |
|
|
|
96e81d |
diff --git a/src/ftp.c b/src/ftp.c
|
|
|
96e81d |
index 2d54333..054cb61 100644
|
|
|
96e81d |
--- a/src/ftp.c
|
|
|
96e81d |
+++ b/src/ftp.c
|
|
|
96e81d |
@@ -2211,6 +2211,29 @@ has_insecure_name_p (const char *s)
|
|
|
96e81d |
return false;
|
|
|
96e81d |
}
|
|
|
96e81d |
|
|
|
96e81d |
+/* Test if the file node is invalid. This can occur due to malformed or
|
|
|
96e81d |
+ * maliciously crafted listing files being returned by the server.
|
|
|
96e81d |
+ *
|
|
|
96e81d |
+ * Currently, this function only tests if there are multiple entries in the
|
|
|
96e81d |
+ * listing file by the same name. However this function can be expanded as more
|
|
|
96e81d |
+ * such illegal listing formats are discovered. */
|
|
|
96e81d |
+static bool
|
|
|
96e81d |
+is_invalid_entry (struct fileinfo *f)
|
|
|
96e81d |
+{
|
|
|
96e81d |
+ struct fileinfo *cur;
|
|
|
96e81d |
+ cur = f;
|
|
|
96e81d |
+ char *f_name = f->name;
|
|
|
96e81d |
+ /* If the node we're currently checking has a duplicate later, we eliminate
|
|
|
96e81d |
+ * the current node and leave the next one intact. */
|
|
|
96e81d |
+ while (cur->next)
|
|
|
96e81d |
+ {
|
|
|
96e81d |
+ cur = cur->next;
|
|
|
96e81d |
+ if (strcmp(f_name, cur->name) == 0)
|
|
|
96e81d |
+ return true;
|
|
|
96e81d |
+ }
|
|
|
96e81d |
+ return false;
|
|
|
96e81d |
+}
|
|
|
96e81d |
+
|
|
|
96e81d |
/* A near-top-level function to retrieve the files in a directory.
|
|
|
96e81d |
The function calls ftp_get_listing, to get a linked list of files.
|
|
|
96e81d |
Then it weeds out the file names that do not match the pattern.
|
|
|
96e81d |
@@ -2248,11 +2271,11 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
|
|
|
96e81d |
f = f->next;
|
|
|
96e81d |
}
|
|
|
96e81d |
}
|
|
|
96e81d |
- /* Remove all files with possible harmful names */
|
|
|
96e81d |
+ /* Remove all files with possible harmful names or invalid entries. */
|
|
|
96e81d |
f = start;
|
|
|
96e81d |
while (f)
|
|
|
96e81d |
{
|
|
|
96e81d |
- if (has_insecure_name_p (f->name))
|
|
|
96e81d |
+ if (has_insecure_name_p (f->name) || is_invalid_entry (f))
|
|
|
96e81d |
{
|
|
|
96e81d |
logprintf (LOG_VERBOSE, _("Rejecting %s.\n"),
|
|
|
96e81d |
quote (f->name));
|
|
|
96e81d |
--
|
|
|
96e81d |
2.1.0
|
|
|
96e81d |
|