Sign Up for Your FREE Weekly SecurityTracker E-mail Alert Summary
|
|
|
|
|
|
|
Put SecurityTracker Vulnerability Alerts on Your Web Site -- It's Free!
|
|
|
|
Become a Partner and License Our Database or Notification Service
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FTE Command Line and Environment Variable Buffer Overflows May Let Local Users Gain Elevated Privileges
|
|
SecurityTracker Alert 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)
|
Reported By: Steve Kemp <skx@debian.org>
|
Message History:
This archive entry has one or more follow-up message(s) listed below.
|
Source Message Contents
|
Date: Sat, 02 Aug 2003 13:25:32 +0100
From: Steve Kemp <skx@debian.org>
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, opti ons,
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
|