| Wiki Markup |
|---|
Many programs and libraries, including the shared library loader on both Unix and Windows systems, depend on environment variable settings. Because environment variables are inherited from the parent process when a program is executed, an attacker can easily sabotage variables, causing a program to behave in an unexpected and insecure manner \[[Viega 03|AA. C References#Viega 03]\]. |
| Wiki Markup |
|---|
Attackers can manipulate environmental variables to trick an executable into running a spoofed version of a shared library or executable. Most modern systems, for example, uses dynamic libraries and most executables are dynamically linked (that is, use dynamic libraries). If an attacker can run arbitary code with the privileges of a spoofed process by installing a spoofed version of a shared library and influencing the mechanism for dynamic linking by setting the {{LD_PRELOAD}} environmental variable (or another {{LD_\*}} environmental variable). An interesting example of this vulnerability involving the RFC 1408/RFC 1572 _Telnet Environment Option_ is documented in CERT Advisory CA-1995-14, "Telnetd Environment Vulnerability" \[[CA-1995-14|http://www.cert.org/advisories/CA-1995-14.html]\]. The Telnet Environment Option extension to telnet supports the transfer of environment variables from one system to another, allowing an attacker to transfer environment variables that influence the login program called by the telnet daemon and bypass the normal login and authentication scheme to become root on that system. |
...
| Wiki Markup |
|---|
Sanitize the environment by setting required variables to safe values and removing extraneous environment variables. Set {{IFS}} to its default of " \t\n" (the first character is a space character). Set the {{PATH}} environment variable to {{\_PATH_STDPATH}} defined in {{paths.h}}. Preserve the {{TZ}} environment variable (if present) which denotes the time zone (see the Open Group Base Specifications Issue 6 specifies for the format for this variable \[[Open Group 04|AA. C References#Open Group 04]\]. |
...
| Code Block | ||
|---|---|---|
| ||
uid_t uid;
struct passwd *pwd;
uid = getuid( );
if (!(pwd = getpwuid(uid))) {
endpwent();
return 1;
}
endpwent();
|
...
| Code Block | ||
|---|---|---|
| ||
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <paths.h> extern char **environ; /* These arrays are both NULLnull-terminated. */ static char *spc_restricted_environ[ ] = { "IFS= \t\n", "PATH=" _PATH_STDPATH, 0 }; static char *spc_preserve_environ[ ] = { "TZ", 0 }; void spc_sanitize_environment(int preservec, char **preservev) { int i; char **new_environ, *ptr, *value, *var; size_t arr_size = 1, arr_ptr = 0, len, new_size = 0; for (i = 0; (var = spc_restricted_environ[i]) != 0; i++) { new_size += strlen(var) + 1; arr_size++; } for (i = 0; (var = spc_preserve_environ[i]) != 0; i++) { if (!(value = getenv(var))) continue; new_size += strlen(var) + strlen(value) + 2; /* include the '=' */ arr_size++; } if (preservec && preservev) { for (i = 0; i < preservec && (var = preservev[i]) != 0; i++) { if (!(value = getenv(var))) continue; new_size += strlen(var) + strlen(value) + 2; /* include the '=' */ arr_size++; } } new_size += (arr_size * sizeof(char *)); if (!(new_environ = (char **)malloc(new_size))) abort( ); new_environ[arr_size - 1] = 0; ptr = (char *)new_environ + (arr_size * sizeof(char *)); for (i = 0; (var = spc_restricted_environ[i]) != 0; i++) { new_environ[arr_ptr++] = ptr; len = strlen(var); memcpy(ptr, var, len + 1); ptr += len + 1; } for (i = 0; (var = spc_preserve_environ[i]) != 0; i++) { if (!(value = getenv(var))) continue; new_environ[arr_ptr++] = ptr; len = strlen(var); memcpy(ptr, var, len); *(ptr + len + 1) = '='; memcpy(ptr + len + 2, value, strlen(value) + 1); ptr += len + strlen(value) + 2; /* include the '=' */ } if (preservec && preservev) { for (i = 0; i < preservec && (var = preservev[i]) != 0; i++) { if (!(value = getenv(var))) continue; new_environ[arr_ptr++] = ptr; len = strlen(var); memcpy(ptr, var, len); *(ptr + len + 1) = '='; memcpy(ptr + len + 2, value, strlen(value) + 1); ptr += len + strlen(value) + 2; /* include the '=' */ } } environ = new_environ; } |
Risk Assessment
...
| Wiki Markup |
|---|
\[[Dowd 06|AA. C References#Dowd 06]\] Chapter 10, "UNIX II: Processes"
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.4, "Communication with the environment"
\[[Open Group 04|AA. C References#Open Group 04]\] Chapter 8, "Environment Variables"
\[[Viega 03|AA. C References#Viega 03]\] Section 1.1, "Sanitizing the Environment"
\[[Wheeler 03|AA. C References#Wheeler 03]\] [Section 5.2, "Environment Variables"|http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html] |