Avoiding Code Injection With Find And Xargs

Code injection attacks take advantage of vulnerabilities in web applications to inject malicious code. This code gets executed by the application and allows the attacker to access resources or data that they should not have access to. Code injection can lead to data theft, corruption, or deletion. Some common examples include SQL injection, OS command injection, and LDAP injection.

The find and xargs commands in Linux can be vulnerable to injection attacks if used incorrectly. find searches for files matching specified criteria and xargs takes the results from find and passes them as arguments to a specified command. If arguments are not properly quoted or validated, an attacker could inject code that gets executed when xargs passes the arguments to the command.

Define what code injection is and why it’s dangerous

Code injection occurs when untrusted input is passed to an interpreter as part of a command or query. Attackers can craft the input in such a way that it changes how the command or query is interpreted, allowing them to execute arbitrary commands. This takes advantage of loose input validation on insecurely designed applications.

There are several types of code injection:

  • SQL injection: Inserting database commands into input fields for execution
  • OS command injection: Inserting shell commands into application parameters
  • LDAP injection: Manipulating LDAP queries to access unauthorized data

Dangers arising from code injection include:

  • Remote code execution on servers, potentially gaining admin access
  • Accessing sensitive data from databases, files, etc.
  • Manipulating or destroying data
  • Pivoting deeper into systems for lateral movement
  • Maintaining persistence on systems

Explain how find and xargs can lead to code injection if used improperly

The find command recursively searches file system directories for matching files. By itself, find is safe from code injection. However, the results can then be piped to xargs, which converts the results into an executable command.

If xargs is provided unsanitized input from find, like filenames or paths, it could then execute harmful commands by expanding those paths. For example, if find discovers a file named "; rm -rf /;", and directly pipes this to xargs without sanitizing, xargs may delete the root file system when executing the command. Delimiters like “;” can separate multiple commands for xargs to run multiple injections in a single execution.

Some ways attackers can exploit improper use of find and xargs:

  • Craft malicious filenames like "; malicious command;" to inject when run by xargs
  • Poison the paths searched by find to inject payloads into results
  • Use unquoted parameters for easy shell expansions

Following best practices is key to preventing code injection from untrusted input when using find and xargs in scripts or one-liners.

Quoting Arguments to find and xargs

Give examples of unquoted arguments allowing code injection

If xargs arguments are not properly quoted, attackers can inject arbitrary commands which will execute when passed to the system shell for expansion. For example:

find . -print | xargs grep pattern

Here the results from find are passed without quoting to xargs, which then passes them to the grep command. An attacker could inject code like so:

 
touch '/tmp/exploit; rm -rf /; echo exploit'
find . -print | xargs grep exploit 
# xargs now executes code injected by the attacker 

Likewise, improper quoting with find can expose it directly to shell expansion before execution:

find $INPUT -name "*.txt" -print

If $INPUT is user-supplied without sanitizing, they could enter:

; rm -rf /; 

Causing rm -rf / to execute when find runs the unsanitized input.

Demonstrate proper quoting of arguments to prevent expansions

To prevent code injection and malicious expansions, both find and xargs arguments should be properly quoted. Here is an example:

find . -name "*.txt" -print0 | xargs -0 -I {} grep pattern '{}'  

The -print0 flag to find outputs null delimited results that won’t be split or expanded by shells. Xargs -0 consumes the null delimited input safely. Argument {} is quoted to prevent shell interpretation.

Single and double quotes around arguments prevent unwanted expansions:

find '$INPUT' -name "*.txt" -print 

$INPUT is now quoted and will not expand. This helps sanitize find inputs safely.

Using find Safely with xargs

Explain dangers of piping find directly to xargs

Piping find directly to xargs can lead to code injection if filenames or paths contain malicious commands. For example:

find /home -name '*.png' -print | xargs rm

Here the found filenames matching *.png get passed unsanitized to xargs rm. An attacker could place a specially crafted filename like ';rm -rf /;# that executes arbitrary commands when xargs passes it to rm.

In addition, spaces in filenames can cause args to split in unexpected ways. Newlines and special characters can also affect scripts that don’t expect them.

Alternative delimiters should be used instead of unquoted arguments to xargs. Where possible, found names should be sanitized before reaching potentially dangerous system commands.

Show safer alternatives like -print0 and -0 for null delimiters

Instead of using unquoted find arguments, using null delimiters prevents splits, spaces, newlines and special characters from affecting downloads.

find . -name '*.png' -print0 | xargs -0 rm

find -print0 uses null characters to separate filenames before output instead of standard delimiters. xargs -0 consumes this null delimited input safely without spliiting or glob expansion.

Other options like -exec and -delete also invoke commands safely after checks:

find /home -name '*.png' -exec rm '{}' \;

Overall when piping find to xargs or other commands, proper delimiting and quoting is necessary to prevent expansion or splitting that could expose code injection vulnerabilities.

Validating Inputs and Sanitizing Data

Emphasize importance of data validation before piping to commands

Before passing user inputs and external data to find/xargs parameters, proper validation and sanitization should occur to prevent code injection:

  • Validate expected input formats – whitelist allowable characters
  • Sanitize with escapes or strips of bad characters
  • Encode interpreting dangerous characters like <, >, |, ; etc
  • Quote arguments to prevent glob and variable expansion

For robust solutions, defense in depth with multiple protections should be used. Higher level policies can enforce principle of least privilege regarding access and analysis of sensitive file repositories. Multi-factor authentication also prevents unauthorized access for uploading malicious payloads.

Give examples of sanitizing filenames and input to prevent code execution

User input with potential code injections:

$INPUT="/tmp/file; rm -rf /; echo" 

Strip executables with whitelist of allowable filenames:

SANITIZED=`echo "$INPUT" | sed -e 's/[;&|<>]/_/g;`  

Sanitized input:

 
$SANITIZED = "/tmp/file_rm-rf_/echo"

Likewise, found filenames can be sanitized before xargs:

find . -name \* -print0 | sed "s/['\';|&]//g" | xargs -0 rm

This strips bad characters from names before deleting with rm avoiding code injection. Similar methods should sanitize paths and parameters to inoculate against untrusted inputs expanding to harmful commands.

Employing Shell Parameter Expansion Carefully

Warn against uncontrolled parameter expansion

Bash shell allows variables to expand to commands if parameters reference environmental variables and special characters:

$FOO='*; rm -rf /'
echo $FOO
# Runs rm -rf / after expanding

Accessing environmental variables should be done safely:

ID="$UNTRUSTED_VAR"
grep pattern "$ID" 
# Potential code injection trigger

Unquoted expansions of untrusted variables can lead to arbitrary command execution. Use plain data references without touching the shell when possible.

Provide guidelines on quoting expansion like “$@” vs “$*”

Bash expands positional parameters like $1 differently depending on quoting:

"$@" - $1 to $N as separate quoted arguments
"$*" - Concatenates parameters as single quoted argument

This matters when passing unsanitized parameters or filenames:

find . -name \* -print0 | xargs -I '{}' echo "$@"
# Separates names - safer

find . -name \* -print0 | xargs -I '{}' echo "$*"  
# Concatenates - exposes injections

Always prefer “$@” form for passing unnamed positional parameters securely.

In general avoid unquoted expansion of names, paths and variables if sourced externally. Validate then quote or sanitize first.

Verifying Expected Behavior and Outputs

Highlight testing outputs before relying on scripts

Before deploying find/xargs scripts to production systems, thorough testing helps verify expected control flows to prevent logic flaws. Test with valid and invalid sample input data:

  • Echo outputs to check escaping/encoding
  • Dry run fake commands like : > /dev/null to prevent real impact
  • Start from non-privilege accounts first
  • Check exit codes and return values at each step

Monitor system resources during testing to detect abnormal activities from potentially malicious actions.

Check exit codes and return values at each stage

Tools like set can enforce exit codes and return values halting scripts if issues occur:

find /home \( -name '*.png' -o -name '*.jpg' \) -print0 | { 
    set -eo pipefail;  
    xargs -0 mv -t /images/ {};
}

-e exits immediately if any command fails
-o requires exit code 0 to proceed
pipefail catches errors in pipelines

These best practices help minimize reach of unintended behaviour before it impacts production systems. Auditing logs for errors provides visibility so scripts can be locked down further as needed.

Leave a Reply

Your email address will not be published. Required fields are marked *