3

I was reviewing code of an application that uses the following piece of Java code and wanted to know if the the use of exec() was susceptible to command injection.

public class FindFileInDir {
  public static void main(String[] args){
   try {
        Runtime rt = Runtime.getRuntime();
        String[] cmdArr = { "bash", "checkfileindirectory.sh", "<directory_to_search>", "<file_to_find>" };
        Process p = rt.exec(cmdArr);
      } catch (Exception e) {
         e.printStackTrace(System.out);
    }
  }
}

To provide some context, the shell script is just a wrapper for the find command that searches for a file in a directory. It takes two arguments directory_to_search and file_to_find. The directory_to_search argument to the script is fixed but the user contains the file_to_find argument. Is there are payload that can be used to chain multiple bash commands in this scenario?

Mike Ounsworth
  • 57,707
  • 21
  • 150
  • 207
JohnnyHunter
  • 233
  • 1
  • 7

1 Answers1

3

I ran your program, linked to a checkfileindirectory.sh that looks like this:

#!/bin/bash

echo $1 > param1.txt
echo $2 > param2.txt

As a test, I changed "<file_to_find>" to "<file_to_find>;touch MikeWasHere.txt"

String[] cmdArr = { "bash", "checkfileindirectory.sh", "<directory_to_search>", "<file_to_find>;touch MikeWasHere.txt" };

And I get this output:

➜  /tmp javac FindFileInDir.java
➜  /tmp java FindFileInDir 
➜  /tmp cat param1.txt 
<directory_to_search>
➜  /tmp cat param2.txt 
<file_to_find>;touch MikeWasHere.txt
➜  /tmp ls MikeWasHere.txt
ls: cannot access 'MikeWasHere.txt': No such file or directory

So it looks like java's rt.exec() is injection-safe.


OWASP's page on command injection has a paragraph about java's exec (emphasis mine):

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

That seems consistent with our experiment that java's rt.exec() is injection-safe.

Mike Ounsworth
  • 57,707
  • 21
  • 150
  • 207