This post will explain to you, why it is that in Java most of the command line injection vulnerabilities in most common cases could not be exploited with:

  • && dir
  • ; ls

 

There are two options for running a command:

  1. Send the whole command to the OS shell (CMD or /bin/sh) and let Java parse & run it.
  2. Split the words of the command into an array, execute the first word, and pass the rest as parameters.

 

The difference is when, for example, the command is:

Notepad.exe a.txt && dir

The first method will run both commands (open  Notepad with the file a.txt and, if it will succeed, run the command dir). The second method will pass the ‘&&’ and ‘dir’ as  parameters to the notepad.exe program. Therefore, ‘&&’ and ‘dir’ will not run.

This is also the difference between the ‘system’ function in C language which works as the first method, and ‘Runtime.exec’ function in Java which works with the second method.

Therefore in Java, if our code is “CmdInjection.java”:

Runtime runtime = Runtime.getRuntime();

String command = “notepad ” + args[0];

System.out.println(“\nOur command is: ” + command + “\n”);

Process proc = runtime.exec(command);

You cannot use any of the following special characters to add or create effects to other files or commands: && || > <.

.

But… it is still vulnerable to command line injection. Even though you cannot run another program or command, you can manipulate the arguments. In this example, instead of opening a file, you can add the attribute /p to print it, or /pt and choose a driver.

Since we want pass to our code a few words as one word (we want to pass /p filename.txt but catch it with args[0]), we should just wrap it with quotes. I added a printLn(command) that shows that our whole command was caught. Now we’ll run:

java CmdInjection “/p a.txt”

.

Of course, it can happen that we’ll be able inject a shell’s special characters too, if the code is:

Runtime runtime = Runtime.getRuntime();

String command = “cmd.exe /c notepad ” + args[0];

System.out.println(“\nOur command is: ” + command + “\n”);

Process proc = runtime.exec(command);

In this case, Java calls the OS shell and give it the whole command to parse and run. In this case, it will parse special characters such as &&, so we’ll be able to inject:

java CmdInjection “a.txt && dir”

Because of the quotes, this whole string (a.txt && dir) is transferred to the CmdInjection file as one parameter, which passes it to the cmd.exe shell, which parses it as a regular shell command line.

Also note that during some exploitations, you may need to use double quoting: java CmdInjection “‘a.txt’ && dir”

.

References:

Share with your friends

appsec-labs-logo-007

No comments yet.

Leave a Reply

You must be logged in to post a comment.