Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!

TUCoPS :: Unix :: General :: unix4884.htm


29th Nov 2001 [SBWID-4884]



	 All versions of wu-ftpd including and up to 2.6.1 are vulnerable.

	 Version 2.7.0 snapshots are also vulnerable.

	 Solaris is NOT vulnerable to this problem.



	A previous bug was found, regarding glob() function and FTP daemon (see 

	This is another aspect of the same trouble.

	The bug was re-discovered independantly by  Luciano  Notarfrancesco  and
	Juan Pablo Martinez Kuhn from CORE  Security  Technologies.  Wu-ftpd  is
	vulnerable, remote  attacker  (with  a  valid  local  ftp  account)  can
	execute arbitrary code, with UID of the running ftp daemon (most of  the
	time : root)

	The problem is due to a combination of  bugs,  one  located  within  the
	function responsible for the globbing feature, which fails  to  properly
	signal an error  to  its  caller  under  certain  conditions.  The  glob
	function does not properly  handle  the  string  \"~{\"  as  an  illegal
	parameter. The other bug is at the caller, a  command  parser  function,
	that incorrectly handles the error status returned by the glob  function
	allowing the corruption of the process memory space.

	 Technical Description - Exploit/Concept Code:



	Tests were performed  using  wu-ftp  server  versions  2.6.1  and  2.7.0

	WU-FTPD server  features  globbing  capabilities,  allowing  a  user  to
	search pathnames matching patterns according to the rules  used  by  the
	shell. The feature does not use the glibc implementation of  the  glob()
	function, instead it implements its own in the the glob.c file

	This implementation fails to set  the  globerr  variable  under  certain
	circunstances, bypassing error checking after the call,  and  trying  to
	free an uninitialized memory address. This memory address is located  in
	the process heap and can be manipulated by the user, issuing  especially
	crafted commands beforehand to the server. This issue  was  found  twice
	in the source code.

	The handling of the globbing metacharacters is  done  by  the  ftpglob()
	function included in  the  glob.c  file.  The  function  is  called  for
	example  from  ftpcmd.y  line  1277  and  line  1303  while   processing
	pathnames for restricted  and  non-restricted  users  beggining  with  a
	\'/\' or a \'~\' character respectively.



	   if (restricted_user && logged_in && $1 && strncmp($1, \"/\", 1) == 0){


	 globlist = ftpglob(t);




	   else if (logged_in && $1 && strncmp($1, \"~\", 1) == 0) {

	        char **globlist;


	        globlist = ftpglob($1);





	After that, the variable globerr  is  checked  to  handle  any  possible
	error that could had happened during the globbing process, setting  this
	variable is responsability of the ftpglob() function.

	Under certain  circunstances  not  properly  handled  by  the  function,
	globerr is not set even though an error condition is present

	Being not initialized explicitly, globlist  contains  what  was  in  the
	heap before, which can be properly set with specially  crafted  requests
	to the server.

	As the globerr was not set properly, the function attempts to  free  the
	provided pointer in ftpcmd.y line 1282 and line 1288.



	                   if (globerr) {

	                        reply(550, globerr);

	                        $$ = NULL;

	                        if (globlist) {


	                            free((char *) globlist);



	                    else if (globlist) {

	                        $$ = *globlist;


	                        free((char *) globlist);





	As shown, during the processing  of  a  globbing  pattern,  the  Wu-Ftpd
	implementation creates a list of the files that match. The memory  where
	this data is stored is  on  the  heap,  allocated  using  malloc().  The
	globbing function simply returns a pointer to the list. It is up to  the
	calling functions to free the allocated memory.

	If an error occurs processing the pattern, memory will not be  allocated
	and a variable indicating this should  be  set.  The  calling  functions
	must check the value of this  variable  before  attempting  to  use  the
	globbed filenames (and later freeing the memory).

	Under certain circumstances, the globbing function  does  not  set  this
	variable when an error  occurs.  As  a  result  of  this,  Wu-Ftpd  will
	eventually attempt to free uninitialized memory.

	If this region of memory contained  user-controllable  data  before  the
	free  call,  it  is  possible  to  have  an  arbitrary  word  in  memory
	overwritten with an arbitrary value.  This  can  lead  to  execution  of
	arbitrary  code  if  function   pointers   or   return   addresses   are

	Details of hwo to exploit this  type  of  problems  are  in  the  public
	domain and can be found in Phrack Magazine #57 article 9:





	 Unsuccessful explotation of the problem does not lead to denial of service

	 attacks as the ftp server continues normal execution, only the thread

	 handling the request fails, helping the attacker to success.



	 The following excerpt is a sample verification of the existence of

	 the problem:



	ftp> open localhost

	Connected to localhost (

	220 sasha FTP server (Version wu-2.6.1-18) ready.

	Name (localhost:root): anonymous

	331 Guest login ok, send your complete e-mail address as password.


	230 Guest login ok, access restrictions apply.

	Remote system type is UNIX.

	Using binary mode to transfer files.

	ftp> ls ~{

	227 Entering Passive Mode (127,0,0,1,241,205)

	421 Service not available, remote server has closed connection


	 1405 ?        S      0:00 ftpd: accepting connections on port 21

	 7611 tty3     S      1:29 gdb /usr/sbin/wu.ftpd

	26256 ?        S      0:00 ftpd:


	26265 tty3     R      0:00 bash -c ps ax | grep ftpd

	(gdb) at 26256

	Attaching to program: /usr/sbin/wu.ftpd, process 26256

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/i686/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	Symbols already loaded for /lib/

	0x40165544 in __libc_read () from /lib/i686/

	(gdb) c



	Program received signal SIGSEGV, Segmentation fault.

	__libc_free (mem=0x61616161) at malloc.c:3136

	3136    in malloc.c



	Note that the segmentation fault is generated  because  the  program  is
	trying to free() a user provided  (and  in  this  case  invalid)  memory
	chunk referenced by  the  value  0x61616161  (or  its  ASCII  equivalent
	\'aaaa\', sent earlier in  the  session  as  the  user  password),  this
	should be enough hint on the existence and exploitability of the bug.






	To prevent exploitation of this bug it is advised to  disable  anonymous
	FTP access until patches are applied. Notice that legit users  with  FTP
	accounts can still exploit the  problem  even  if  anonymous  access  is
	disabled. If legit ftp  accoutn  posse  a  security  risk,  FTP  service
	should be disabled completly until fixed packages are deployed.




	Multiple vendors and  linux  distributions  released  patched  versions.
	check their web sites for further information.

	 Source Patch



	Mark Canter released a patch for wu-ftpd :


	--- glob.c.orig	Sat Jul  1 14:17:39 2000

	+++ glob.c	Wed Nov 28 00:43:38 2001

	@@ -298,7 +298,7 @@


	     for (lm = restbuf; *p != \'{\'; *lm++ = *p++)


	-    for (pe = ++p; *pe; pe++)

	+    for (pe = ++p; *pe; pe++) {

	 	switch (*pe) {


	 	case \'{\':

	@@ -314,11 +314,19 @@

	 	case \'[\':

	 	    for (pe++; *pe && *pe != \']\'; pe++)


	+	    if (!*pe) {

	+		globerr = \"Missing ]\";

	+		return (0);

	+	    }



	+    }


	-    brclev = 0;

	-    for (pl = pm = p; pm <= pe; pm++)

	+    if (brclev || !*pe) {

	+	globerr = \"Missing }\";

	+	return (0);

	+    }

	+    for (pl = pm = p; pm <= pe; pm++) {

	 	switch (*pm & (QUOTE | TRIM)) {


	 	case \'{\':

	@@ -352,19 +360,18 @@

	 		return (1);


	 	    pl = pm + 1;

	-	    if (brclev)

	-		return (0);



	 	case \'[\':

	 	    for (pm++; *pm && *pm != \']\'; pm++)


	-	    if (!*pm)

	-		pm--;

	+	    if (!*pm) {

	+		globerr = \"Missing ]\";

	+		return (0);

	+	    }



	-    if (brclev)

	-	goto doit;

	+    }

	     return (0);



	@@ -416,11 +423,10 @@

	 		else if (scc == (lc = cc))



	-	    if (cc == 0)

	-		if (ok)

	-		    p--;

	-		else

	-		    return 0;

	+	    if (cc == 0) {

	+		globerr = \"Missing ]\";

	+		return (0);

	+	    }



	 	case \'*\':



TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH