SecurityTracker.com
Keep Track of the Latest Vulnerabilities
with SecurityTracker!
    Home    |    View Topics    |    Search    |    Contact Us    |   

SecurityTracker
Archives


 
Sign Up
Sign Up for Your FREE Weekly SecurityTracker E-mail Alert Summary
Instant Alerts
Buy our Premium Vulnerability Notification Service to receive customized, instant alerts
Affiliates
Put SecurityTracker Vulnerability Alerts on Your Web Site -- It's Free!
Partners
Become a Partner and License Our Database or Notification Service
Report a Bug
Report a vulnerability that you have found to SecurityTracker
bugs
@
securitytracker.com






Category:   Application (Generic)  >   FTE Vendors:   fte.sourceforge.net
FTE Command Line and Environment Variable Buffer Overflows May Let Local Users Gain Elevated Privileges
SecurityTracker Alert ID:  1009655
SecurityTracker URL:  http://securitytracker.com/id/1009655
CVE Reference:   CAN-2003-0648   (Links to External Site)
Date:  Apr 4 2004
Impact:   Execution of arbitrary code via local system, Root access via local system

Version(s): 0.49.13 and prior versions (also affects Debian's version 0.50.0-1 and prior)
Description:   Several vulnerabilities were reported in the FTE editor. A local user may be able to gain elevated privileges on the target system.

In August 2003, Steve Kemp reported that there are buffer overflows in the processing of command line arguments and environment variables, including the 'HOME' and 'TERM' variables. A local user may be able to execute arbitrary code with the privileges of FTE.

FTE is reportedly configured with set user id (setuid) root user privileges.

Impact:   A local user can execute arbitrary code with the privileges of FTE. On some distributions, FTE may be configured with setuid root user privileges.
Solution:   No upstream vendor solution was available at the time of this entry. The author of the report has provided a patch, available in the Source Message.

[Editor's note: The latest upstream version appears to be 0.49.13. A fix is available for Debian Linux -- see the Message History.]

Vendor URL:  fte.sourceforge.net/ (Links to External Site)
Cause:   Boundary error
Underlying OS:   Linux (Any), UNIX (Any)

Message History:   This archive entry has one or more follow-up message(s) listed below.
Apr 4 2004 (Debian Issues Fix) FTE Command Line and Environment Variable Buffer Overflows May Let Local Users Gain Elevated Privileges   (Matt Zimmerman <mdz@debian.org>)
Debian has released a fix.



 Source Message Contents

Date:  Sat, 02 Aug 2003 13:25:32 +0100
Subject:  fte-console allows local root compromise.


Package: fte-console
Version: 0.50.0-1
Severity: grave
Tags: security upstream patch
Justification: user security hole



Intro
-----

   fte is a text editor for programmers which comes in several
  flavours.

   ftp-console is a console based editor, whilst fte-terminal
  and fte-xwindow are for running in terminals and X Window system
  respectively.

   fte-console installs a binary setuid(0) on both Debian stable
  and Debian unstable:

skx@hell:~$ ls -l /usr/bin/vfte
-rwsr-xr-x    1 root     root       482808 Jul 10 18:50 /usr/bin/vfte


Overflow Problems
-----------------

   There are several overflow problems within vfte; the most obvious are
  the buffer overflows which are caused by a lack of adequate bounds
  checking upon the command line arguments.

   Additionally several environmental variables, including 'HOME'
  and 'TERM' are used insecurely.


    For example: g_qt.cpp:1962

	int GUI::RunProgram(char *Command) {
	    char Cmd[1024];

	    char* xterm = getenv("TERM");
	    if (NULL == xterm || 0 == *xterm)
	        xterm = "xterm";

	    strcpy(Cmd, xterm);
	...
         }


   These flaws present several possible avenues for attack by a local
  user.


Demonstration
-------------

   This is a simple example of how the code may be overflowed by
  a local user:

root@hell:~# ulimit -c 999999
root@hell:~# vfte -H`perl -e 'print "A"x6000'`
Segmentation fault (core dumped)
root@hell:~# gdb vfte core
Core was generated by `vfte 
-HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
#0  0x41414141 in ?? ()
(gdb) info register eip
eip            0x41414141       0x41414141


    -- showing that the instruction pointer EIP has been overwritten
  as a result of a return address being perverted upon the stack.



Exploit
-------

   Two exploits are available to cover the command line overflow
  and the TERM overflow.



Solution
--------

   The attached context diff should close these issues - it may
  be larger than that which Debian requires as I've tried to close
  issues which related to the non-Unix platforms also.

   Examination of the code is recommended.


Steve
---
www.steve.org.uk


-- System Information:
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux hell.my.flat 2.4.21 #1 Fri Jun 13 21:42:54 BST 2003 i686
Locale: LANG=C, LC_CTYPE=C

Versions of packages fte-console depends on:
ii  fte                       0.50.0-1       Text editor for programmers - base
ii  libc6                     2.3.1-17       GNU C Library: Shared libraries an
ii  libgcc1                   1:3.3.1-0rc2   GCC support library
ii  libgpmg1                  1.19.6-12.1    General Purpose Mouse Library [lib
ii  libncurses5               5.3.20030719-1 Shared libraries for terminal hand
ii  libstdc++5                1:3.3.1-0rc2   The GNU Standard C++ Library v3

-- no debconf information



--- e_unix.cpp-orig	2003-08-02 13:17:11.000000000 +0100
+++ e_unix.cpp	2003-08-02 13:17:32.000000000 +0100
@@ -35,8 +35,8 @@
          word = wordAsk;
      }

-    sprintf(file, "/tmp/fte%d-man-%s", getpid(), word);
-    sprintf(command, "%s %s %s >'%s' 2>&1", HelpCommand, options, word, file);
+    snprintf(file,sizeof(file)-1, "/tmp/fte%d-man-%s", getpid(), word);
+    snprintf(command,sizeof(command)-1, "%s %s %s >'%s' 2>&1", HelpCommand, options, 
word, file);

      /// !!! why is this needed ???
  #define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
--- fte.cpp-orig	2003-08-02 12:30:03.000000000 +0100
+++ fte.cpp	2003-08-02 12:36:17.000000000 +0100
@@ -120,11 +120,11 @@
          char *ph;
  #if defined(OS2)
          ph = getenv("HOME");
-        if (ph) strcpy(home, ph);
+        if (ph) strncpy(home, ph,sizeof(home)-1);
  #endif
  #if defined(NT)
          ph = getenv("HOMEDRIVE");
-        if (ph) strcpy(home, ph);
+        if (ph) strncpy(home, ph,sizeof(home)-1);
          ph = getenv("HOMEPATH");
          if (ph) strcat(home, ph);
  #endif
@@ -140,7 +140,7 @@
          }
  #endif

-        strcpy(ConfigFileName, CfgName);
+        strncpy(ConfigFileName, CfgName,sizeof(ConfigFileName)-1);
      }
      if (access(ConfigFileName, 0) == 0)
          return 1;
@@ -148,7 +148,7 @@
  #if defined(UNIX)
      for (unsigned int i = 0; i < sizeof(Unix_RCPaths)/sizeof(Unix_RCPaths[0]); i++) {
          if (access(Unix_RCPaths[i], 0) == 0) {
-            strcpy(ConfigFileName, Unix_RCPaths[i]);
+            strncpy(ConfigFileName, Unix_RCPaths[i], sizeof(ConfigFileName)-1);
              return 1;
          }
      }
@@ -246,7 +246,7 @@
  #endif
  #ifdef CONFIG_HISTORY
              } else if (argv[Arg][1] == 'H') {
-                strcpy(HistoryFileName, argv[Arg] + 2);
+                strncpy(HistoryFileName, argv[Arg] + 2,sizeof(HistoryFileName)-1);
                  if (HistoryFileName[0] == 0) {
                      KeepHistory = 0;
                  } else {
--- fte2.cpp-orig	2003-08-02 12:30:09.000000000 +0100
+++ fte2.cpp	2003-08-02 12:34:16.000000000 +0100
@@ -181,7 +181,7 @@
                  QuoteNext = 1;
              } else if (argv[Arg][1] == 'c') {
                  if (argv[Arg][2])
-                    strcpy(ConfigFileName, argv[Arg] + 2);
+                    strncpy(ConfigFileName, argv[Arg] + 2,sizeof(ConfigFileName)-1);
                  else
                      ign = 1;
              } else if (argv[Arg][1] == '?') {
@@ -214,7 +214,7 @@
                  QuoteNext = 1;
  #ifdef CONFIG_DESKTOP
              } else if (argv[Arg][1] == 'd') {
-                strcpy(DesktopFileName, argv[Arg] + 2);
+                strncpy(DesktopFileName, argv[Arg] + 2,sizeof(DesktopFileName)-1);
                  if (DesktopFileName[0] == 0) {
                      LoadDesktopOnEntry = 0;
                      SaveDesktopOnExit = 0;
@@ -224,7 +224,7 @@
  #endif
  #ifdef CONFIG_HISTORY
              } else if (argv[Arg][1] == 'h') {
-                strcpy(HistoryFileName, argv[Arg] + 2);
+                strncpy(HistoryFileName, argv[Arg] + 2,sizeof(HistoryFileName)-1);
                  if (HistoryFileName[0] == 0) {
                      KeepHistory = 0;
                  } else {
@@ -278,7 +278,7 @@
                     ModeOverride = 0;
                 } else {
                     ModeOverride = 1;
-                   strcpy(Mode, argv[Arg] + 2);
+                   strncpy(Mode, argv[Arg] + 2,sizeof(Mode)-1);
                 }
              } else if (argv[Arg][1] == 'T') {
                  TagsAdd(argv[Arg] + 2);
--- g_motif.cpp-orig	2003-08-02 13:14:47.000000000 +0100
+++ g_motif.cpp	2003-08-02 13:15:37.000000000 +0100
@@ -1803,17 +1803,16 @@
      if (NULL == xterm || 0 == *xterm)
          xterm = "xterm";

-    strcpy(Cmd, xterm);
-
      if (*Command == 0)  // empty string = shell
-        strcat(Cmd, " -ls &");
+      {
+	snprintf(Cmd, sizeof(Cmd)-1, "%s -ls &", xterm );
+      }
      else {
-        strcat(Cmd, " -e ");
-        // buffer overflow problem: -2 for possible async.
-	strncat(Cmd, Command, sizeof(Cmd) - strlen(Cmd) - 2);
-        Cmd[sizeof(Cmd) - 3] = 0;
-        if (mode == RUN_ASYNC)
-            strcat(Cmd, " &");
+      // Leave 2 characters spare for the optional ' &'
+      snprintf(Cmd, sizeof(Cmd)-3, "%s -e %s", xterm, Command );
+      if (mode == RUN_ASYNC)
+	strcat(Cmd, " &");
+
      }
      rc = system(Cmd);
      return rc;
--- g_qt.cpp-orig	2003-08-02 12:59:18.000000000 +0100
+++ g_qt.cpp	2003-08-02 13:01:14.000000000 +0100
@@ -1966,15 +1966,14 @@
      if (NULL == xterm || 0 == *xterm)
          xterm = "xterm";

-    strcpy(Cmd, xterm);

      if (*Command == 0)  // empty string = shell
-        strcat(Cmd, " -ls &");
+      {
+	snprintf(Cmd, sizeof(Cmd)-1, "%s -ls &", xterm );
+      }
      else {
-        strcat(Cmd, " -e ");
-        // buffer overflow problem: -2 for possible async.
-	strncat(Cmd, Command, sizeof(Cmd) - strlen(Cmd) - 2);
-        Cmd[sizeof(Cmd) - 3] = 0;
+        // Leave 2 characters spare for the optional ' &'
+        snprintf(Cmd, sizeof(Cmd)-3, "%s -e %s", xterm, Command );
          if (mode == RUN_ASYNC)
              strcat(Cmd, " &");
      }

 
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us

Copyright 2014, SecurityGlobal.net LLC