Skip to content

Powerful Find Command Cheatsheet

Explore the versatility of the find command in Unix/Linux systems with this comprehensive cheatsheet. Discover various find commands to search for files based on modification time, access time, size, type, and more. Enhance your file searching skills and streamline your workflow efficiently.


Detecting Pipe-Based Command Execution in Shell Scripts

Explore methods to leverage find and xargs -P to pinpoint instances of command execution via pipes (|) in shell scripts, which may indicate potential vulnerabilities

Basic Parallel Scan

#!/usr/bin/env bash

TARGET_DIR="${1:-.}"
JOBS="${JOBS:-4}"

export LC_ALL=C

find "$TARGET_DIR" -type f \( -name "*.sh" -o -perm -111 \) -print0 \
| xargs -0 -P "$JOBS" -I{} bash -c '
    file="{}"
    grep -nE "\|[[:space:]]*[a-zA-Z0-9_./-]+" "$file" 2>/dev/null \
    | grep -vE "^[[:space:]]*#" \
    | while IFS= read -r line; do
        printf "[%s] %s\n" "$file" "$line"
      done
'

Parallelized full-filesystem string search with pruning and size limits

time find / -xdev \
  \( -path '/mnt/usb' -o -path '/mnt/usb/*' -o -path '/proc' -o -path '/sys' -o -path '/dev' -o -path '/run' -o -path '/tmp' \) -prune -o \
  -type f \( -name '*.sh' -o -name '*.conf' -o -name '*.db' -o -name '*.txt' \) \
  -size -2M -print0 2>/dev/null \
| xargs -0 -n 500 -P 4 grep -nH -I -F -- 'wuseman' 2>/dev/null

Excluding Common Safe Patterns

Filters out known safe constructs like || and |&.

find / -type f -name "*.sh" -print0 \
| xargs -0 -P 4 -I{} bash -c '
    grep -nE "\|[^|&]" "{}" 2>/dev/null \
    | grep -vE "^[[:space:]]*#" \
    | while read -r line; do
        printf "[%s] %s\n" "{}" "$line"
      done
'

Highlight Suspicious Dynamic Inputs

find / -type f -name "*.sh" -print0 \
| xargs -0 -P 4 -I{} bash -c '
    grep -nE "\|.*(\$|\`|\$\()" "{}" 2>/dev/null \
    | grep -vE "^[[:space:]]*#" \
    | while read -r line; do
        printf "[SUSPECT][%s] %s\n" "{}" "$line"
      done
'

Strict POSIX-Compatible Version

find / -type f -name "*.sh" -print0 \
| xargs -0 -P 4 grep -HnE "\|"

Dry-Run Mode (Preview Files Only)

find / -type f -name "*.sh" -print0 \
| xargs -0 -P 4 -I{} echo "Scanning {}"

Misc

Search for various urls in files

find / -type f -print0 | xargs -0 -P $(nproc) -I {} bash -c '
for file in "$@"; do
  strings "$file" | rg --pcre2 -o -i -e "(http|https|ftp|ftps|smtp|imap)://[a-zA-Z0-9./?=_-]+(?![a-zA-Z0-9./?=_-])" |
  while read -r url; do
    echo -e "Filename: $file \033[1;32m$url\033[0m"
  done
done' bash {}

Search All .sh files while excluding /dev, /proc, and /sys

find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o   -type f -name '*.sh' -print 2>/dev/null | xargs grep -nH -F '<string_to_search_for>' 2>/dev/null

Recursively search /etc for a string in selected file types

find /etc/ -type f  \( -name "*.sh" -o -name "*.conf" -o -name "*.db" -o -name "*.txt" \)  -print 2>/dev/null | xargs grep -nH -F '<string_to_search_for>' 2>/dev/nul    

Find the most recently changed files (recursively)

find / -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort    

Search entire filesystem for .sh files (skip virtual filesystems)

find / \( -path /proc -o -path /sys -o -path /dev \) -prune -o -type f \( -name "*.sh" \) -print

Search entire filesystem for .sh and .lua files

find / -type f \( -name "*.sh" -o -name "*.lua" \)    

Search entire filesystem for .sh and .lua files (skip virtual filesystems)

find / \( -path /proc -o -path /sys -o -path /dev \) -prune -o -type f \( -name "*.sh" -o -name "*.lua" \) -print    

Find large log files

find /var/log -name "*.log" -size +100M

Find configuration files

find /etc -name "*.conf" | head -10    

Locate header files

find /usr/include -name "*.h" | grep pattern

Find all files and delete them all exempt win10ent64.z* files and autorun.inf

find / -type f ! -name 'win10ent64.z*' ! -name 'autorun.inf' -delete

Change permission for all directories in the current dir by parallelizing the task

find / -type d -print0 | xargs -0 -P$(($(nproc) + 1)) chmod 777

For a faster deletion when we have a lot of folders to delete

find / -type d -print0 | xargs -0 rm -rf

Delete folders when it replies directory is not empty

find / -name ".git" -type d -exec rm -rf {} +

Find files modified within the last 1 day

find / -mtime -1

Find files modified within the last 2 days

find / -mtime -2

Find files modified within the last 3 days

find / -mtime -3

Find files modified within the last 4 days

find / -mtime -4

Find files modified within the last 5 days

find / -mtime -5

Find files modified within the last 6 days

find / -mtime -6

Find files modified within the last 1 week

find / -mtime -7

Find files modified within the last 2 weeks

find / -mtime -14

Find files modified within the last 3 weeks

find / -mtime -21

Find files modified within the last 1 hour

find / -mmin -60

Find files modified within the last 30 minutes

find / -mmin -30

Find files modified within the last 10 minutes

find / -mmin -10

Find files accessed within the last 1 day

find / -amin -1440

Find files accessed within the last 2 days

find / -amin -2880

Find files accessed within the last 3 days

find / -amin -4320

Find files accessed within the last 1 hour

find / -amin -60

Find files accessed within the last 30 minutes

find / -amin -30

Find files accessed within the last 10 minutes

find / -amin -10

Find files that had their status changed within the last 1 day

find / -cmin -1440

Find files that had their status changed within the last 2 days

find / -cmin -2880

Find files that had their status changed within the last 3 days

find / -cmin -4320

Search for Files Only

find -type f

Search for Folders Only

find -type d

Search for Symlinks Only

find -type l

Search 3 Levels Deep

find -depth 2

Search for Files via Regex

find -regex PATTERN

Exactly 8 512-bit Blocks

find -size 8

Smaller Than 128 Bytes

find -size -128c

Exactly 1440KiB

find -size 1440k

Larger Than 10MiB

find -size +10M

Larger Than 2GiB

find -size +2G

Search for All Files Larger Than 500MB

find / -type f -size +500M

Search for All Executable Files

for i in $(find -type f); do [ -x "$i" ] && echo "$i is executable"; done

Search for Foo Text Inside All Files in Current Folder Using Parallel

find / -type f | parallel -k -j150% -n 1000 -m grep -H -n 'foo' {}

Find Broken Symlinks and Delete Them

find -L /path/to/check -type l -delete

Find All the Links to a File

find -L / -samefile /path/to/file -exec ls -ld {} +

Find the Most Recently Changed Files (Recursively)

find / -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

Remove 'Fucked' Dirnames from Microsoft Windows and Apple

ls -li | find / -inum 4063242 -delete

Find All Gz Files and Extract Them

find / -type f -iname "*.gz" -print0 | xargs -0 -I {} atool -x "{}" -delete

Last Accessed Between Now and 24 Hours Ago

find -atime 0

Accessed More Than 24 Hours Ago

find -atime +0

Find With Invert Match - E.g., Find Every File That Is Not Mp3

find / -name '*' -type f -not -iname '*.mp3'

Find Files/Directories Modified Within a Given Period

find / -type d -newermt "2019-01-01" ! -newermt "2019-02-01" -exec ls -ld {} \;

Store the Output of Find in an Array

mapfile -d $'\0' arr < <(find /path/to -print0)

Find All Log Files Modified 24 Hours Ago and Zip Them

find / -type f -mtime +1 -name "*.log" -exec zip -m {}.zip {} \; >/dev/null

Search for AT Atention commands

find / -type f -name "*.apk" -print0 | xargs -0 strings | grep -E 'AT[\+\*][A-Z]{2,10}([^A-Z]|$)'

Search for a pattern inside multiple tar.gz archives

find / -name '*.tar.gz' -print0 | xargs -0 -P $(nproc --all) -I {} tar -tzf {} | grep 'pattern'

Question

Quote

Can we modify the find and xargs -P approach to identify dynamic code execution vulnerabilities, such as those arising from the use of system, exec, or shell_exec, lua, shell, modals, nginx, openwrt, android enviroments functions with user-controlled input?How can we adapt the find and xargs -P combination to detect function call injections within PHP files, where attackers manipulate function calls to execute arbitrary code?"

PHP: Direct OS command execution sinks (variable or superglobal)

  • Catches both $var and direct \(_GET/\)_POST style usage
  • Uses b boundaries
  • (?i) makes the match case-insensitive
find / -type f -name '*.php' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'(?i)\b(system|exec|shell_exec|passthru|popen|proc_open)\s*\(\s*(\$|@?\$_(GET|POST|REQUEST|COOKIE)\b)'

PHP: Variable function call injection ($func(…))

  • Detects dynamic function invocation where function name is variable-controlled
find / -type f -name '*.php' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\$[A-Za-z_][A-Za-z0-9_]*\s*\(\s*(\$|@?\$_(GET|POST|REQUEST|COOKIE)\b)'

PHP: call_user_func / call_user_func_array with user-controlled input

  • Flags indirect execution via call_user_func*
find / -type f -name '*.php' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\bcall_user_func(_array)?\s*\(\s*(\$|@?\$_(GET|POST|REQUEST|COOKIE)\b)'

PHP: eval / assert dynamic execution

  • assert() behavior varies by configuration in modern PHP
find / -type f -name '*.php' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(eval|assert)\s*\(\s*(\$|@?\$_(GET|POST|REQUEST|COOKIE)\b)'

PHP: Backtick shell execution with variables

  • Detects inline shell execution using backticks
find / -type f -name '*.php' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'`[^`]*\$[^`]*`'

PHP: include/require with user-controlled input

find / -type f -name '*.php' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(include|require)(_once)?\s*\(.*\$_(GET|POST|REQUEST|COOKIE)\b'

Shell Script Injection Detection (Improved Patterns)

Shell: eval with user-controlled data

  • Focuses on real execution sink: eval
  • Matches positional parameters and variable expansions
find / -type f \( -name '*.sh' -o -name '*.bash' \) -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'^[^#]*\beval\b.*(\$[0-9@*]|\$\{[^}]+\}|"\$[^"]+")'

Shell: Command substitution containing variables

  • Detects $() and backtick substitutions with variables
  • Common injection surface
find / -type f \( -name '*.sh' -o -name '*.bash' \) -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'(\$\([^)]*\$[^)]*\)|`[^`]*\$[^`]*`)'

Shell: Dynamic command variable execution ($cmd, ${cmd})

  • Noisy by design
  • Detects execution of dynamically constructed command strings
find / -type f \( -name '*.sh' -o -name '*.bash' \) -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'^[^#]*\$\{?[A-Za-z_][A-Za-z0-9_]*\}?(\s+|$)'

Shell: Unquoted positional parameters (execution-context heuristic)

  • More execution-context oriented than simple $(1|2|@|*)
  • Still requires manual review
find / -type f \( -name '*.sh' -o -name '*.bash' \) -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'^[^#]*\s(?:\S+\s+)*\$(?:[0-9]+|@|\*)\b'

OpenWrt / BusyBox system helpers with variable usage

  • Useful for embedded/OpenWrt audit triage
  • Flags command helpers combined with variable input
find / -type f -name '*.sh' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'^[^#]*\b(uci|ubus|fw3|iptables|nft|service|procd|iw|ifconfig|ip)\b.*\$(\{)?[A-Za-z_0-9@*]'

Lua Script Injection Detection (Improved Patterns - nproc is used if supported)

Heuristic Grep Only

These patterns are regex-based triage checks.
They do not perform taint/data-flow tracking, so expect false positives/negatives.

Lua: Direct OS command execution sinks (os.execute / io.popen / posix.system)

  • posix.system appears when luaposix is used.
  • os.spawn exists in some Lua environments/frameworks (less common on OpenWrt, but worth flagging).
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(os\.execute|io\.popen|posix\.system|os\.spawn)\s*\('

Lua: Shell command creation via string concat before execution (common injection pattern)

  • Flags os.execute("cmd " .. user) and string.format("cmd %s", user) style command building.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(os\.execute|io\.popen|posix\.system)\s*\(\s*[^)]*(\.\.|string\.format)\b'

Lua: BusyBox/OpenWrt luci.sys.exec / luci.util.exec (LuCI command execution)

  • Very relevant on OpenWrt/LuCI.
  • luci.sys.call() returns exit code but still executes the shell command.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(luci\.sys\.exec|luci\.util\.exec|luci\.sys\.call)\s*\('

Lua: OpenWrt nixio.exec / nixio.spawn (process exec without shell, still dangerous)

  • nixio.exec() is not “shell injection” per se, but argument injection / unsafe param passing can still be critical.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(nixio\.(exec|spawn|fork|popen))\s*\('

Lua: load / loadstring / dofile / require with variable input (code/loader injection)

  • Flags dynamic loading where the argument isn’t a literal string.
  • On OpenWrt, loadstring may be absent depending on Lua version/build, but still worth scanning.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(loadstring|load|dofile|loadfile|require)\s*\(\s*[^)]*\$?\w+'

Lua: Web/LuCI request input usage near execution sinks (controller input → exec)

  • This is a broad net: it helps you find files that both read request input and execute commands.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(http\.formvalue|luci\.http\.formvalue|luci\.http\.getenv|luci\.http\.content)\b|\b(os\.execute|io\.popen|luci\.(sys|util)\.exec|luci\.sys\.call|nixio\.(exec|spawn|popen))\b'

Lua: UCI/ubus interaction with variables (router config surfaces)

  • Not “command injection” directly, but tainted config writes often become RCE later via hooks/scripts.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(uci\.set|uci\.commit|ubus\.call|luci\.model\.uci|luci\.ubus)\b.*(\.\.|\$\{|\$[A-Za-z_])'

Lua: Dangerous patterns — piping, redirection, and chaining in executed command strings

  • Flags commands with shell metacharacters inside string literals.
  • Great for quickly spotting obviously dangerous exec usage.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -P \
'\b(os\.execute|io\.popen|luci\.(sys|util)\.exec|luci\.sys\.call)\s*\(\s*["'\''][^"'\'']*(\||;|&&|\|\||>|<)[^"'\'']*["'\'']'

BusyBox-friendly alternative (no -P / no -P regex)

  • If you ever run this on-router where grep -P isn’t available, add a note like:
  • Use grep -E and simpler patterns, or install ripgrep (rg) if possible.
find / -type f -name '*.lua' -print0 |
xargs -0 -P"$(nproc)" grep -nH -E \
'(os\.execute|io\.popen|luci\.sys\.exec|luci\.util\.exec|luci\.sys\.call|nixio\.(exec|spawn|popen))'

Lua Script Injection Detection (Improved Patterns - no nproc is used if not supported)

  • Minimal BusyBox Version (Safe & Works Everywhere)

Lua: Detect direct OS execution sinks (BusyBox compatible)

  • Works with BusyBox
  • No parallel required
  • No PCRE required
find / -type f -name '*.lua' -print0 | \
xargs -0 -r grep -nH -E \
'(os\.execute|io\.popen|posix\.system|os\.spawn)'

Lua: Detect LuCI command execution (OpenWrt specific)

  • This one is especially important on OpenWrt.

find / -type f -name '*.lua' -print0 |
xargs -0 -r grep -nH -E
'(luci.sys.exec|luci.util.exec|luci.sys.call)'

Lua: Detect nixio execution primitives

  • Slightly More Targeted (BusyBox regex only)
  • Since BusyBox grep lacks b, we approximate word boundaries:
find / -type f -name '*.lua' -print0 | \
xargs -0 -r grep -nH -E \
'nixio\.(exec|spawn|popen)'

Lua: Detect execution sinks combined with string concatenation

  • Detects: os.execute("ping " .. user)
find / -type f -name '*.lua' -print0 | \
xargs -0 -r grep -nH -E \
'(os\.execute|io\.popen|luci\.sys\.exec|luci\.sys\.call).*\.{2}'

Lua: Detect web input usage (LuCI controllers)

Now manually check files that contain BOTH:

  • input functions
  • execution sinks
find / -type f -name '*.lua' -print0 | \
xargs -0 -r grep -nH -E \
'(http\.formvalue|luci\.http\.formvalue|luci\.http\.getenv)'

Explore methods to leverage find and xargs -P to pinpoint instances of command execution via pipes (|) in shell scripts, which may indicate potential vulnerabilities

Parallel scan for pipe usage in shell scripts (basic)

find . -type f \( -name "*.sh" -o -perm -111 \) -print0 \
  | xargs -0 -P "$(nproc)" -I{} grep -nH --color=never '|' "{}"

Exclude commented lines

find . -type f -name "*.sh" -print0 \
  | xargs -0 -P "$(nproc)" -I{} awk '
    /^[[:space:]]*#/ { next }
    /\|/ { printf "%s:%d:%s\n", FILENAME, NR, $0 }
  ' {}

Detect suspicious pipe-to-shell patterns

find . -type f -name "*.sh" -print0 \
  | xargs -0 -P "$(nproc)" -I{} grep -nH -E '\|\s*(sh|bash|dash|ksh|zsh)\b' "{}"

Detect curl/wget piped to shell

find . -type f -name "*.sh" -print0 \
  | xargs -0 -P "$(nproc)" -I{} grep -nH -E '(curl|wget)[^|]*\|\s*(sh|bash)' "{}"

Ignore vendor/git directories

find . -type d \( -name .git -o -name vendor -o -name node_modules \) -prune -false \
  -o -type f -name "*.sh" -print0 \
  | xargs -0 -P "$(nproc)" -I{} grep -nH -E '\|' "{}"

And for OpewWRT minimal shell how to explore methods to leverage find to pinpoint instances of command execution via pipes (|) in shell scripts, which may indicate potential vulnerabilities without using xargs -P and nproc since we dont have it

Basic recursive search for pipe usage in .sh files

find . -type f -name "*.sh" -exec grep -nH '|' {} \;

Exclude commented lines (simple heuristic)

find . -type f -name "*.sh" -exec awk '
  /^[[:space:]]*#/ { next }
  /\|/ { printf "%s:%d:%s\n", FILENAME, NR, $0 }
' {} \;

Detect pipe-to-shell patterns (possible RCE indicators)

find . -type f -name "*.sh" -exec grep -nH -E '\|\s*(sh|ash|bash)\b' {} \;

Detect curl/wget piped into shell

find . -type f -name "*.sh" -exec grep -nH -E '(curl|wget)[^|]*\|\s*(sh|ash|bash)' {} \;

Scan entire filesystem but skip pseudo/volatile dirs (OpenWRT safe scope)

find / -type d \( -path /proc -o -path /sys -o -path /dev \) -prune -o \
  -type f -name "*.sh" -exec grep -nH '|' {} \;If

Basic scan for pipe usage in .sh and .lua

find . -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH '|' {} \;

Detect pipe-to-shell patterns (RCE indicators)

find . -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '\|\s*(sh|ash|bash)\b' {} \;

Detect curl/wget piped into shell

find . -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '(curl|wget)[^|]*\|\s*(sh|ash|bash)' {} \;

Detect os.execute/io.popen usage in Lua

find . -type f -name "*.lua" \
  -exec grep -nH -E 'os\.execute|io\.popen' {} \;

Detect backticks and $() command substitution (sh + lua)

find . -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '`.*`|\$\(' {} \;

Detect eval usage in shell

find . -type f -name "*.sh" \
  -exec grep -nH -E '\beval\b' {} \;

Detect Dynamic Code Execution in Shell and Lua (loadstring, dofile, loadlib)

find . -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '\b(loadstring|load|dofile|package\.loadlib)\b' {} \;

Identify Suspicious Relative Module Loading in Lua (require ..)

find . -type f -name "*.lua" \
  -exec grep -nH -E 'require\s*\(.*\.\.' {} \;

Detect Unquoted Variable Expansions in Shell Scripts

find . -type f -name "*.sh" \
  -exec grep -nH -E '\$\{?[A-Za-z_][A-Za-z0-9_]*\}?[^"]' {} \;

Find Overly Permissive chmod Usage (777 / a+rw)

find . -type f -name "*.sh" \
  -exec grep -nH -E '\b(chmod\s+777|chmod\s+a\+rw)\b' {} \;

Locate Temporary Directory Usage (/tmp /var/tmp)

find . -type f -name "*.sh" \
  -exec grep -nH -E '(/tmp/|/var/tmp/)[A-Za-z0-9._-]+' {} \;

Detect Environment Variable Manipulation (PATH, LD_PRELOAD, LD_LIBRARY_PATH)

find . -type f -name "*.sh" \
  -exec grep -nH -E '\b(PATH|LD_PRELOAD|LD_LIBRARY_PATH)\s*=' {} \;

Identify Privilege Manipulation (setuid, setgid, chown root)

find . -type f -name "*.sh" \
  -exec grep -nH -E '\b(setuid|setgid|chown\s+root)\b' {} \;

Search for Embedded Networking Utilities (nc, telnetd, dropbear, socat)

find . -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '(nc|netcat|telnetd|dropbear|socat)\b' {} \;

Detect Base64 Decode Piped to Shell (RCE Indicator)

find . -type f -name "*.sh" \
  -exec grep -nH -E 'base64\s+-d.*\|\s*(sh|ash|bash)' {} \;

Identify Dangerous eval Usage with Variable Expansion

find . -type f -name "*.sh" \
  -exec grep -nH -E '\b(eval\s*"\$|eval\s*\$\()' {} \;

Detect IFS Manipulation (Input Field Separator Abuse)

find . -type f -name "*.sh" \
  -exec grep -nH -E '\bIFS=' {} \;

Detect Lua os.execute Concatenation (Command Injection Risk)

find . -type f -name "*.lua" \
  -exec grep -nH -E 'os\.execute\s*\(.*\.\.' {} \;

Locate External Input Handling in Lua (CGI, Environment, Form Values)

find . -type f -name "*.lua" \
  -exec grep -nH -E '(cgi|os\.getenv|luci\.http\.formvalue)' {} \;

Find Indirect Shell Execution (xargs -I, sh -c)

find . -type f -name "*.sh" \
  -exec grep -nH -E '\b(xargs\s+-I|sh\s+-c)\b' {} \;

Full Filesystem Triage (Pruned /proc, /sys, /dev) for High-Risk Patterns

find / -type d \( -path /proc -o -path /sys -o -path /dev \) -prune -o \
  -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '(loadstring|package\.loadlib|base64\s+-d|nc\s|telnetd|chmod\s+777|LD_PRELOAD|eval\s*"\$)' {} \;

Skip volatile dirs (recommended on OpenWRT)

find / -type d \( -path /proc -o -path /sys -o -path /dev \) -prune -o \
  -type f \( -name "*.sh" -o -name "*.lua" \) \
  -exec grep -nH -E '(\||os\.execute|io\.popen|`|\$\(|\beval\b)' {} \;

How can I search for all .sh and lua files for command injections risks

Find all .sh and .lua files

find /path/to/project -type f \( -name "*.sh" -o -name "*.lua" \)

Grep for high-risk command execution patterns (shell + lua)

grep -RInE \
'(eval|exec|system|popen|io\.popen|os\.execute|`.+`|\$\(.+\)|bash -c|sh -c|source |\.\s)' \
/ --include="*.sh" --include="*.lua"

Detect variable expansion inside dangerous calls (possible injection)

grep -RInE \
'(eval|system|popen|os\.execute).*\$[{(]?[A-Za-z_]' \
/ --include="*.sh" --include="*.lua"

Find unquoted variables in shell scripts (common injection source)

grep -RInE '\$[A-Za-z_][A-Za-z0-9_]*' / --include="*.sh" \
| grep -vE '"\$[A-Za-z_][A-Za-z0-9_]*"'

Look for user input sources piped into commands

grep -RInE \
'(read |readarray|cat |curl |wget |nc |telnet ).*\|.*(sh|bash)' \
/ --include="*.sh"

Basic Lua taint-style pattern (input → command)

grep -RInE \
'(io\.read|arg\[|ngx\.var|socket:receive).*(os\.execute|io\.popen)' \
/ --include="*.lua"

Locate all .sh files containing eval (high-risk primitive)

grep -RIl --include="*.sh" '\beval\b' /path/to/project

eval combined with variable expansion (very high risk)

grep -RIn --include="*.sh" -E 'eval\s+.*\$[{(]?[A-Za-z_]' /path/to/project

Dangerous backticks (command substitution legacy form)

grep -RIn --include="*.sh" -E '`[^`]+`' /path/to/project

Backticks combined with variables (injection-prone)

grep -RIn --include="*.sh" -E '`[^`]*\$[^`]*`' /path/to/project

Modern command substitution with variables

grep -RIn --include="*.sh" -E '\$\([^)]*\$[^)]*\)' /path/to/project

Direct shell execution patterns (sh -c / bash -c)

grep -RIn --include="*.sh" -E '(sh|bash)\s+-c\s+.*\$' /path/to/project

Unquoted variable usage (common injection vector)

grep -RIn --include="*.sh" -E '(^|[^"])\$[A-Za-z_][A-Za-z0-9_]*([^"]|$)' /path/to/project \
| grep -vE '"\$[A-Za-z_][A-Za-z0-9_]*"'

User input flowing into execution

grep -RIn --include="*.sh" -E '(read|readarray).*\n?.*(eval|sh|bash|`|\$\()' /path/to/project

Look for networking tools combined with shell execution

grep -RIn --include="*.sh" -E '(nc|netcat|telnet|curl|wget).*(sh|bash|`|\$\()' /path/to/project

Find files containing multiple high-risk primitives

grep -RIl --include="*.sh" -E '(eval|`|\$\(|sh -c|bash -c)' /path/to/project \
| xargs -r grep -lE '(nc|netcat|telnet|curl|wget)'

Rank .sh files by number of risky patterns

grep -RIn --include="*.sh" -E '(eval|`|\$\(|sh -c|bash -c)' /path/to/project \
| cut -d: -f1 | sort | uniq -c | sort -nr

Use awk to flag lines where eval contains unquoted input

grep -RIn --include="*.sh" '\beval\b' /path/to/project \
| awk -F: '$0 ~ /\$/ && $0 !~ /"\$/ {print}'

Advanced: combine ripgrep (rg) for better performance

rg -n --glob "*.sh" '(eval\s+.*\$|`[^`]*\$[^`]*`|\$\([^)]*\$[^)]*\)|sh -c\s+.*\$|bash -c\s+.*\$)' /path/to/project

If You Want Faster On-Router Scanning

Simpler BusyBox-only variant (no xargs)

  • Instead of xargs, BusyBox find supports -exec:
find / -type f -name '*.lua' -exec \
grep -nH -E '(os\.execute|io\.popen|luci\.sys\.exec|luci\.sys\.call|nixio\.(exec|spawn|popen))' {} +