You are on page 1of 8

Command injection

Command injection is an attack in which the goal is execution of arbitrary


commands on the host operating system via a vulnerable application.
Command injection attacks are possible when an application passes unsafe
user supplied data (forms, cookies, HTTP headers etc.) to a system shell. In
this attack, the attacker-supplied operating system commands are usually
executed with the privileges of the vulnerable application. Command injection
attacks are possible largely due to insufficient input validation.
This attack differs from Code Injection, in that code injection allows the
attacker to add their own code that is then executed by the application. In
Command Injection, the attacker extends the default functionality of the
application, which execute system commands, without the necessity of
injecting code.

Examples
Example 1
The following code is a wrapper around the UNIX command cat which prints
the contents of a file to standard output. It is also injectable:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {


char cat[] = "cat ";
char *command;
size_t commandLength;

commandLength = strlen(cat) + strlen(argv[1]) + 1;


command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, argv[1], (commandLength - strlen(cat)) );

system(command);
return (0);
}
Used normally, the output is simply the contents of the file requested:

$ ./catWrapper Story.txt
When last we left our heroes...
However, if we add a semicolon and another command to the end of this line,
the command is executed by catWrapper with no complaint:
$ ./catWrapper "Story.txt; ls"
When last we left our heroes...
Story.txt doubFree.c nullpointer.c
unstosig.c www* a.out*
format.c strlen.c useFree*
catWrapper* misnull.c strlength.c
useFree.c
commandinjection.c nodefault.c trunc.c
writeWhatWhere.c
If catWrapper had been set to have a higher privilege level than the standard
user, arbitrary commands could be executed with that higher privilege.
Example 2
The following simple program accepts a filename as a command line
argument, and displays the contents of the file back to the user. The program
is installed setuid root because it is intended for use as a learning tool to allow
system administrators in-training to inspect privileged system files without
giving them the ability to modify them or damage the system.
int main(char* argc, char** argv) {
char cmd[CMD_MAX] = "/usr/bin/cat ";
strcat(cmd, argv[1]);
system(cmd);
}
Because the program runs with root privileges, the call to system() also
executes with root privileges. If a user specifies a standard filename, the call
works as expected. However, if an attacker passes a string of the form “;rm -rf
/”, then the call to system() fails to execute cat due to a lack of arguments and
then plows on to recursively delete the contents of the root partition.
./catnew “;rm -rf /”
Example 3
The following code from a privileged program uses the environment variable
$APPHOME to determine the application’s installation directory, and then
executes an initialization script in that directory.
...
char* home=getenv("APPHOME");
char* cmd=(char*)malloc(strlen(home)+strlen(INITCMD));
if (cmd) {
strcpy(cmd,home);
strcat(cmd,INITCMD);
execl(cmd, NULL);
}
...
As in Example 2, the code in this example allows an attacker to execute
arbitrary commands with the elevated privilege of the application. In this
example, the attacker can modify the environment variable $APPHOME to
specify a different path containing a malicious version of INITCMD. Because
the program does not validate the value read from the environment, by
controlling the environment variable, the attacker can fool the application into
running malicious code.
The attacker is using the environment variable to control the command that
the program invokes, so the effect of the environment is explicit in this
example. We will now turn our attention to what can happen when the attacker
changes the way the command is interpreted.
Example 4
The code below is from a web-based CGI utility that allows users to change
their passwords. The password update process under NIS includes
running make in the /var/yp directory. Note that since the program updates
password records, it has been installed setuid root.
The program invokes make as follows:
system("cd /var/yp && make &> /dev/null");
Unlike the previous examples, the command in this example is hardcoded, so
an attacker cannot control the argument passed to system(). However, since
the program does not specify an absolute path for make, and does not scrub
any environment variables prior to invoking the command, the attacker can
modify their $PATH variable to point to a malicious binary named make and
execute the CGI script from a shell prompt. And since the program has been
installed setuid root, the attacker’s version of make now runs with root
privileges.
The environment plays a powerful role in the execution of system commands
within programs. Functions like system() and exec() use the environment of
the program that calls them, and therefore attackers have a potential
opportunity to influence the behavior of these calls.
There are many sites that will tell you that Java’s Runtime.exec is exactly the
same as C’s system function. This is not true. Both allow you to invoke a new
program/process. However, C’s system function passes its arguments to the
shell (/bin/sh) to be parsed, whereas Runtime.exec tries to split the string into
an array of words, then executes the first word in the array with the rest of the
words as parameters. Runtime.exec does NOT try to invoke the shell at any
point. The key difference is that much of the functionality provided by the shell
that could be used for mischief (chaining commands using “&”, “&&”, “|”, “||”,
etc, redirecting input and output) would simply end up as a parameter being
passed to the first command, and likely causing a syntax error, or being
thrown out as an invalid parameter.
Example 5
The following trivial code snippets are vulnerable to OS command injection on
the Unix/Linux platform:
C:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
     char command[256];

     if(argc != 2) {
          printf("Error: Please enter a program to time!\n");
          return -1;
     }

     memset(&command, 0, sizeof(command));

     strcat(command, "time ./");
     strcat(command, argv[1]);

     system(command);
     return 0;
}
If this were a setuid binary, consider the case when an attacker enters the
following: ls; cat /etc/shadow. In the Unix environment, shell commands
are separated by a semi-colon. We now can execute system commands at
will!
Java:
There are many sites that will tell you that Java’s Runtime.exec is exactly the
same as C’s system function. This is not true. Both allow you to invoke a new
program/process. However, C’s system function passes its arguments to the
shell (/bin/sh) to be parsed, whereas Runtime.exec tries to split the string
into an array of words, then executes the first word in the array with the rest of
the words as parameters. Runtime.exec does NOT try to invoke the shell at
any point. The key difference is that much of the functionality provided by the
shell that could be used for mischief (chaining commands using &, &&, |, ||,
etc, redirecting input and output) would simply end up as a parameter being
passed to the first command, and likely causing a syntax error, or being
thrown out as an invalid parameter.
Example 6
The following PHP code snippet is vulnerable to a command injection attack:
<?php
print("Please specify the name of the file to delete");
print("<p>");
$file=$_GET['filename'];
system("rm $file");
?>
The following request and response is an example of a successful attack:
Request
http://127.0.0.1/delete.php?filename=bob.txt;id
Response
Please specify the name of the file to delete

uid=33(www-data) gid=33(www-data) groups=33(www-data)


Sanitizing Input
Replace or Ban arguments with “;”
Other shell escapes available
Example:
– &&
– |
– ...

Buffer overload:

A buffer overload is a type of Denial of Service attack which fills a


programmer's data buffers so that further traffic is denied

A buffer overflow condition exists when a program attempts to put more data
in a buffer than it can hold or when a program attempts to put data in a
memory area past a buffer. In this case, a buffer is a sequential section of
memory allocated to contain anything from a character string to an array of
integers. Writing outside the bounds of a block of allocated memory can
corrupt data, crash the program, or cause the execution of malicious code.

Description
Buffer overflow is probably the best known form of software security
vulnerability. Most software developers know what a buffer overflow
vulnerability is, but buffer overflow attacks against both legacy and
newly-developed applications are still quite common. Part of the problem is
due to the wide variety of ways buffer overflows can occur, and part is due to
the error-prone techniques often used to prevent them.
Buffer overflows are not easy to discover and even when one is discovered, it
is generally extremely difficult to exploit. Nevertheless, attackers have
managed to identify buffer overflows in a staggering array of products and
components.
In a classic buffer overflow exploit, the attacker sends data to a program,
which it stores in an undersized stack buffer. The result is that information on
the call stack is overwritten, including the function’s return pointer. The data
sets the value of the return pointer so that when the function returns, it
transfers control to malicious code contained in the attacker’s data.
M

MC
Although this type of stack buffer overflow is still common on some platforms
and in some development communities, there are a variety of other types of
buffer overflow, including Heap buffer overflow and Off-by-one Error among
others. Another very similar class of flaws is known as Format string attack.
There are a number of excellent books that provide detailed information on
how buffer overflow attacks work, including Building Secure Software [1],
Writing Secure Code [2], and The Shellcoder’s Handbook [3].
At the code level, buffer overflow vulnerabilities usually involve the violation of
a programmer’s assumptions. Many memory manipulation functions in C and
C++ do not perform bounds checking and can easily overwrite the allocated
bounds of the buffers they operate upon. Even bounded functions, such as
strncpy(), can cause vulnerabilities when used incorrectly. The combination of
memory manipulation and mistaken assumptions about the size or makeup of
a piece of data is the root cause of most buffer overflows.
Buffer overflow vulnerabilities typically occur in code that:

● Relies on external data to control its behavior


● Depends upon properties of the data that are enforced outside of the
immediate scope of the code
● Is so complex that a programmer cannot accurately predict its behavior

Buffer Overflow and Web Applications


Attackers use buffer overflows to corrupt the execution stack of a web
application. By sending carefully crafted input to a web application, an
attacker can cause the web application to execute arbitrary code – effectively
taking over the machine.
Buffer overflow flaws can be present in both the web server or application
server products that serve the static and dynamic aspects of the site, or the
web application itself. Buffer overflows is found widely used in server
products are likely to become widely known and can pose a significant risk to
users of these products. When web applications use libraries, such as a
graphics library to generate images, they open themselves to potential buffer
overflow attacks.
Buffer overflows can also be found in custom web application code, and may
even be more likely given the lack of scrutiny that web applications typically
go through. Buffer overflow flaws in custom web applications are less likely to
be detected because there will normally be far fewer hackers trying to find and
exploit such flaws in a specific application. If discovered in a custom
application, the ability to exploit the flaw (other than to crash the application) is
significantly reduced by the fact that the source code and detailed error
messages for the application are normally not available to the hacker.
Consequences

● Category:Availability: Buffer overflows generally lead to crashes. Other


attacks leading to lack of availability are possible, including putting the
program into an infinite loop.
● Access control (instruction processing): Buffer overflows often can be
used to execute arbitrary code, which is usually outside the scope of a
program’s implicit security policy.
● Other: When the consequence is arbitrary code execution, this can
often be used to subvert any other security service.

You might also like