Basic recursive search (case-insensitive, whole word, suppress errors)
grep -r password /path 2>/dev/null
Best practice: case-insensitive, line numbers, skip binaries, with color
grep -rnIi —color=auto ‘password’ /etc 2>/dev/null
Multiple patterns (OR logic)
grep -rnIi -E ‘password|api_key|secret|token’ /var/www 2>/dev/null
### Options and Flags
1. **-r** — Recursive search through directories
2. **-i** — Case-insensitive matching
3. **-n** — Show line numbers in output
4. **-I** — Skip binary files (prevents "Binary file matches" messages)
5. **-w** — Match whole word only (prevents false positives like "password_protected")
6. **-l** — List filenames only (no content; faster for large result sets)
7. **-H** — Always print filename with matches (default for multiple files)
8. **-o** — Print only matching part of line (useful for extracting values)
9. **-E** — Extended regex (enables `|` for OR, `+`, `?`)
10. **--color=auto** — Highlight matches (always use this)
11. **--include='*.ext'** — Search only specific file types
12. **--exclude-dir='dir'** — Skip directories (e.g., node_modules, .git)
13. **2>/dev/null** — Suppress permission denied errors
### Practical Examples
```bash
# Search all config files for password strings
grep -rnIi --include='*.conf' --include='*.config' --include='*.cnf' 'password' /etc 2>/dev/null
# Find database credentials in web apps
grep -rnIi -E 'DB_PASS|DATABASE_PASSWORD|dbpass' /var/www 2>/dev/null
# Extract values after "password=" pattern
grep -roIi 'password=' /opt | cut -d= -f2
# Search with multiple keywords across targeted directories
grep -rnIi -E 'pass=|pwd=|api_key=|secret=' /etc /opt /var/www /home 2>/dev/null | tee creds.txt
# Find SSH private keys
grep -rnI 'BEGIN.*PRIVATE KEY' /home /root 2>/dev/null
# Exclude irrelevant directories to reduce noise
grep -rnIi --exclude-dir={proc,sys,dev,run,boot} 'password' / 2>/dev/null
Output Interpretation
Format: filename:line_number:matching_line
Look for:
- Plaintext credentials
- Connection strings
- API keys
- Environment variable assignments
False positives: Documentation, comments, variable names without values
OPSEC and Detection Notes
- HIGH NOISE: Recursive grep from
/generates massive I/O and CPU load; detectable by performance monitoring - LOGGED: auditd file watches on
/etc/shadow,/etc/passwd,~/.ssh/*will log read attempts to/var/log/audit/audit.log - EDR DETECTION: Rapid sequential file reads across multiple sensitive directories trigger anomaly alerts
- MITIGATION: Use targeted directory searches (
/var/www,/opt,/home/user) instead of whole filesystem; use--exclude-dirliberally - Permission denied errors flood terminal without
2>/dev/null; also hides potential targets
Common Errors
Binary file (standard input) matches— File contains null bytes or UTF-16 encoding; use-Ito skip or-ato force text treatment- Hangs with no output — grep waiting for stdin when no file argument given; use Ctrl+D to exit
grep: memory exhausted— Pattern too complex or file too large; narrow search scope or use simpler regex- No matches found — Check case sensitivity (
-i), file permissions, SELinux denials (ls -Z,sestatus) - Shell glob expansion — Quote patterns with wildcards:
'pass*'notpass*
Version and Platform Notes
- GNU grep (Linux default): supports lazy matching,
-Pfor Perl regex - BSD grep (macOS default): limited regex features, no lazy matching
- GNU grep 3.0+ includes performance optimizations for large files
Phase 1: Fast Filename Enumeration
Purpose: Quickly locate files with password-related names before content searching
Prerequisites: Standard user access; locate database (updatedb) ideally current
Core Commands
# Fastest: locate database search (requires updated database)
locate -i password
locate -i 'pass'
locate -r '\.conf$'
# Filename-only find (case-insensitive)
find / -iname '*password*' 2>/dev/null
find / -iname '*pass*' -o -iname '*pwd*' -o -iname '*credential*' 2>/dev/null
Options and Flags
- locate -i — Case-insensitive filename search
- locate -r — Regex pattern matching
- find -iname — Case-insensitive name pattern
- -o — OR operator for multiple find conditions
- updatedb — Refresh locate database (requires root; runs daily via cron)
Practical Examples
# Search for password-related filenames (super fast)
locate -i password | grep -v 'lib\|share\|fonts\|doc'
locate -i pwd | grep -v 'lib\|share\|fonts\|doc'
# Find config files by name
locate '.conf' | grep -i 'password\|mysql\|db\|api'
# Find with name patterns
find /var/www /opt /home -type f \( -iname '*pass*' -o -iname '*secret*' -o -iname '*.pem' \) 2>/dev/null
# Find files modified in last 7 days
find /var/www /tmp -type f -mtime -7 -iname '*config*' 2>/dev/null
Output Interpretation
- Full file paths; manually inspect high-value targets (
.conf,.cnf,.sh,.env,.bak) - Prioritize:
/etc,/var/www,/opt,/home,/root/.ssh,/tmp
OPSEC and Detection Notes
- LOW NOISE: locate reads pre-built database (no filesystem traversal; very fast)
- MODERATE NOISE:
find /traverses filesystem; detectable via I/O monitoring - Target specific directories to minimize footprint:
find /var/www /opt /homenotfind /
Common Errors
locate: can not stat— Database stale; runupdatedb(requires root) or use findfind: permission denied— Normal for non-root user; redirect stderr with2>/dev/null
Version and Platform Notes
- locate database location varies:
/var/lib/mlocate/mlocate.db(Debian/Ubuntu),/var/db/locate.database(BSD) - updatedb runs daily via
/etc/cron.daily/mlocateon modern Linux
Phase 2: Targeted File Type Enumeration
Purpose: Enumerate high-value file types (configs, DBs, scripts, backups) before content search
Prerequisites: Standard user access; bash shell
Core Commands
# Find all config files
find /etc /opt /var/www -type f \( -name '*.conf' -o -name '*.config' -o -name '*.cnf' \) 2>/dev/null
# Find database files
find / -type f \( -name '*.sql' -o -name '*.db' -o -name '*.sqlite*' \) 2>/dev/null
# Find scripts and environment files
find /var/www /opt /home -type f \( -name '*.sh' -o -name '*.env' -o -name '.env' \) 2>/dev/null
Options and Flags
- find -type f — Regular files only (excludes directories, links)
- -name ‘pattern’ — Case-sensitive name matching
- -iname ‘pattern’ — Case-insensitive name matching
- -o — OR operator for multiple name conditions
- ( ) — Group multiple conditions
Practical Examples
# Configuration file loop (clean output)
for ext in conf config cnf; do
echo -e "\n=== Files with .$ext extension ===";
find /etc /opt /var/www -name "*.$ext" 2>/dev/null | grep -v 'lib\|fonts\|share\|doc';
done
# Database file loop with filtering
for ext in sql db sqlite sqlite3; do
echo -e "\n=== Files with .$ext extension ===";
find / -name "*.$ext" 2>/dev/null | grep -v 'lib\|share\|man\|doc';
done
# Backup and archive files (high-value targets)
find / -type f \( -name '*.bak' -o -name '*.backup' -o -name '*.old' -o -name '*~' \) 2>/dev/null | head -50
# SSH keys and certificates
find / -type f \( -name 'id_rsa' -o -name 'id_dsa' -o -name 'id_ed25519' -o -name '*.pem' -o -name '*.key' \) 2>/dev/null
# World-readable files (permission misconfiguration)
find / -type f -perm -004 -ls 2>/dev/null | grep -v 'proc\|sys\|usr/share'
# SUID/SGID binaries (potential privilege escalation)
find / -type f \( -perm -4000 -o -perm -2000 \) -ls 2>/dev/null
Output Interpretation
- Paths to files; next step is content search with grep
- Prioritize small files (
-size -100k) for faster manual inspection - Large
.sqlor.dbfiles may require strings or specialized tools
OPSEC and Detection Notes
- MODERATE NOISE: Filesystem traversal generates I/O; EDR may flag rapid enumeration
- Target specific directories first (
/var/www,/opt,/etc,/home) before whole filesystem - Exclude noisy system paths with
grep -vto reduce output volume
Common Errors
find: missing argument to '-name'— Quote patterns:-name '*.conf'not-name *.conf- Too many results — Add size filters (
-size -10M), time filters (-mtime -30), or path restrictions
Phase 3: Content Search in Targeted Files
Purpose: Search file contents for credential patterns after identifying target files
Prerequisites: List of target files (from Phase 2); standard user or root access
Core Commands
# Pipe find results to grep with xargs (handles spaces)
find /etc /opt /var/www -type f -name '*.conf' -print0 | xargs -0 grep -nIi 'password' 2>/dev/null
# Execute grep on each find result
find /var/www -type f \( -name '*.conf' -o -name '*.php' -o -name '*.env' \) -exec grep -HnIi 'password\|api_key' {} \; 2>/dev/null
Options and Flags
- find -print0 — Null-separated output (handles filenames with spaces)
- xargs -0 — Read null-separated input
- find -exec grep {} ; — Execute grep on each file individually
- grep -H — Always show filename (critical for multi-file searches)
Practical Examples
# Search config files for database credentials
find /etc /opt -name '*.conf' -exec grep -HnIi -E 'password|user|host|dbname' {} \; 2>/dev/null
# Search web app files for API keys
find /var/www -type f \( -name '*.php' -o -name '*.py' -o -name '*.js' -o -name '.env' \) -print0 | \
xargs -0 grep -nIi -E 'api[_-]?key|secret|token|auth' 2>/dev/null
# Search scripts for embedded credentials
find /home /opt -name '*.sh' -exec grep -HnIi -E 'export.*PASS|PASSWORD=' {} \; 2>/dev/null
# Combined file type + content search one-liner
find /etc /opt /var/www -type f \( -name '*.conf' -o -name '*.config' -o -name '*.cnf' \) \
-exec grep -Hn 'password\|pass=' {} \; 2>/dev/null | tee config-creds.txt
# Search only recently modified files (last 30 days)
find /var/www -type f -mtime -30 -name '*.conf' -print0 | \
xargs -0 grep -nIi 'password' 2>/dev/null
Output Interpretation
Format: filename:line_number:matching_line
- Extract values: pipe to
cut,awk, orsedfor parsing - Context: use
grep -A 2 -B 2to see surrounding lines
OPSEC and Detection Notes
- HIGH NOISE: Reading many files rapidly triggers I/O alerts and auditd logging
- Target smallest file set possible; use Phase 2 filtering aggressively
- Sensitive file access (e.g.,
/etc/shadow,~/.ssh/id_rsa) logged by auditd to/var/log/audit/audit.log
Common Errors
xargs: argument line too long— Large result sets exceed buffer; usefind -execinstead- Binary files slow search — Always use
-Iflag with grep to skip binaries - No output despite known credentials — Check file encoding (
file filename), SELinux contexts
Phase 4: History and Environment Inspection
Purpose: Check command history, environment variables, and process memory for credentials
Prerequisites: Standard user or root shell access
Core Commands
# Check command history files
cat ~/.bash_history ~/.zsh_history 2>/dev/null | grep -i 'pass\|user\|key\|secret'
# Check current environment variables
env | grep -i 'pass\|key\|secret\|token\|api'
# Check process command lines
ps auxww | grep -E 'mysql|psql|ssh|ftp' | grep -v grep
Practical Examples
# History files across all users (requires root)
find /home /root -type f \( -name '.bash_history' -o -name '.zsh_history' -o -name '.mysql_history' \) \
-exec grep -HnIi -E 'password|pass=|--password' {} \; 2>/dev/null
# Additional history files
cat ~/.lesshst ~/.viminfo ~/.python_history 2>/dev/null | grep -i 'pass'
# Environment variables from specific process
cat /proc/[PID]/environ | tr '\0' '\n' | grep -i 'pass\|key'
# All process environments (requires root)
for pid in $(ls /proc | grep '^[0-9]'); do
echo "=== PID $pid ===";
cat /proc/$pid/environ 2>/dev/null | tr '\0' '\n' | grep -iE 'pass|key|secret';
done
# Database connection strings in process memory (requires root)
ps aux | grep -E 'mysql|postgres' | awk '{print $2}' | \
xargs -I {} sh -c 'strings /proc/{}/environ 2>/dev/null | grep -i password'
# Check systemd service files for credentials
grep -rnIi 'Environment=' /etc/systemd/system /usr/lib/systemd/system 2>/dev/null | \
grep -iE 'pass|key|secret'
Output Interpretation
- History files may contain credentials passed as CLI arguments
- Environment variables often store DB passwords, API keys, tokens
- Process command lines expose credentials in
--password=valuestyle arguments /proc/[pid]/environcontains environment at process launch time
OPSEC and Detection Notes
- LOW NOISE: Reading history files and env variables minimal impact
- MODERATE NOISE: Iterating over all
/proc/[pid]/environmay trigger EDR alerts - auditd may log access to specific users’ history files if watched
Common Errors
/proc/[pid]/environaccess denied — Processes owned by other users unreadable without root- Empty output from
cat /proc/[pid]/environ— Process exited or no environment variables - History file not found — User using different shell or history disabled (
HISTFILE=)
Version and Platform Notes
/procfilesystem standard on Linux; not available on BSD/macOS (useps einstead)
Phase 5: Log File Analysis
Purpose: Search system and application logs for credentials, authentication events, and errors exposing secrets
Prerequisites: Read access to /var/log (many logs require root)
Core Commands
# Search all log files for password strings
grep -rnIi 'password' /var/log 2>/dev/null
# Search compressed logs with zgrep
zgrep -ai 'password\|credential\|secret' /var/log/*.gz 2>/dev/null
# Loop through logs for authentication events
for log in /var/log/*; do
grep -iE 'accepted|password|failure' "$log" 2>/dev/null && echo "=== $log ===";
done
Options and Flags
- zgrep — Search compressed files (
.gz,.bz2) - zgrep -a — Treat all files as text (avoids binary detection)
- Standard grep flags apply:
-i,-n,-E,-r
Practical Examples
# SSH authentication logs
grep -i 'accepted\|failed' /var/log/auth.log /var/log/secure 2>/dev/null | tail -50
# Application error logs (may expose DB connection strings)
grep -rnIi -E 'error.*password|exception.*credential' /var/log 2>/dev/null
# Web server logs for API keys in URLs (bad practice but happens)
grep -rE 'api_key=|token=' /var/log/apache2 /var/log/nginx 2>/dev/null | head -20
# Database logs
grep -rnIi 'password' /var/log/mysql /var/log/postgresql 2>/dev/null
# Search compressed logs (older rotated logs)
zgrep -aiE 'password=|api_key=|secret=' /var/log/*.gz /var/log/*/*.gz 2>/dev/null | less
# Conditional log search (only print logs with matches)
for logfile in $(ls /var/log/* 2>/dev/null); do
RESULT=$(grep -iE 'password|accepted|failure' "$logfile" 2>/dev/null);
if $RESULT ; then
echo -e "\n=== $logfile ===";
echo "$RESULT" | head -10;
fi;
done
Output Interpretation
- auth.log/secure: successful/failed login attempts with usernames
- Application logs: stack traces may expose credentials in connection strings
- Web logs: API keys or tokens in GET parameters (insecure but common)
- Look for: timestamps, usernames, source IPs, credential exposure patterns
OPSEC and Detection Notes
- HIGH ALERT: Access to
/var/log/auth.log,/var/log/secure,/var/log/audit/triggers high-priority alerts - auditd logs its own file watches to
/var/log/audit/audit.log— reading this creates recursive log entry - Legitimate sysadmins read logs frequently; timing and context matter for detection
Common Errors
grep: /var/log/[file]: Permission denied— Many logs require root; run as root or usesudozgrep: command not found— Install gzip utils:apt install gziporyum install gzip- Binary log formats — systemd journal uses binary format; use
journalctlinstead of grep
Version and Platform Notes
- Log paths vary:
/var/log/auth.log(Debian/Ubuntu),/var/log/secure(RHEL/CentOS) - systemd systems: use
journalctl -xe | grep -i passwordfor systemd journal
find File Discovery and Filtering
Purpose: Locate files by name, type, size, permissions, modification time before content search
Prerequisites: Standard user access; GNU findutils
Core Commands
# Basic recursive file search
find /path -type f -name 'pattern' 2>/dev/null
# Search with multiple name patterns (OR logic)
find / -type f \( -name '*.conf' -o -name '*.config' \) 2>/dev/null
# Permission-based search
find / -type f -perm -004 2>/dev/null
Options and Flags
- -type f — Regular files only
- -type d — Directories only
- -name ‘pattern’ — Case-sensitive name match (shell wildcards:
*,?) - -iname ‘pattern’ — Case-insensitive name match
- -perm -mode — Files with at least these permissions set
- -perm /mode — Files with any of these permissions set
- -user username — Files owned by user
- -group groupname — Files owned by group
- -size +100M — Files larger than 100MB (
+greater,-smaller, no prefix exact) - -mtime -7 — Modified in last 7 days (
-within,+older than) - -atime — Last access time
- -ctime — Last status change time
- ( ) — Group multiple expressions
- -o — OR operator
- ! or -not — Negation
Practical Examples
# World-writable files (security risk)
find / -type f -perm -002 2>/dev/null
# SUID binaries (privilege escalation vectors)
find / -type f -perm -4000 -ls 2>/dev/null
# Files owned by www-data user
find /var/www -user www-data -type f 2>/dev/null
# Large files (potential DB dumps)
find / -type f -size +50M -size -500M 2>/dev/null
# Recently modified config files (may contain fresh creds)
find /etc -type f -name '*.conf' -mtime -7 2>/dev/null
# SSH keys across all user home directories
find /home /root -type f \( -name 'id_rsa' -o -name 'id_dsa' -o -name 'id_ed25519' \) 2>/dev/null
# Writable directories (potential persistence locations)
find / -type d -perm -002 ! -path '/proc/*' ! -path '/sys/*' 2>/dev/null
# Files with no user ownership (orphaned files)
find / -nouser -ls 2>/dev/null
Output Interpretation
- Default: full path to matching files
- Use
-lsfor detailed output (permissions, size, owner, timestamp) - Pipe results to grep, xargs, or
-execfor further processing
OPSEC and Detection Notes
- MODERATE-HIGH NOISE: Full filesystem traversal from
/generates significant I/O - Target specific directories to reduce footprint
- SUID/permission enumeration is standard attacker behavior; may trigger alerts
Common Errors
find: missing argument to '-name'— Quote wildcards:-name '*.conf'find: invalid argument '-perm 777'— Use octal:-perm 0777or symbolic:-perm -u=rwx,g=rwx,o=rwx- Parentheses syntax error — Escape with backslash:
\(\)or quote:'(' ')' - Slow search — Exclude large directories:
! -path '/proc/*' ! -path '/sys/*'
Version and Platform Notes
- GNU find (Linux): supports
-printf,-regex, extended options - BSD find (macOS): limited features; use
-print0andxargs -0for portability
strings Binary File Extraction
Purpose: Extract printable ASCII strings from binary files (executables, compiled code, memory dumps)
Prerequisites: GNU binutils installed (standard on Linux)
Core Commands
# Extract printable strings from binary
strings /path/to/binary
# Set minimum string length (default 4)
strings -n 8 /path/to/binary
# Search extracted strings for patterns
strings /path/to/binary | grep -i 'password\|api\|key'
Options and Flags
- -n [num] — Minimum string length (default 4; increase to reduce noise)
- -a — Scan entire file (default scans only initialized/loaded sections)
- -t [format] — Print offset of each string (
ooctal,xhex,ddecimal) - -e [encoding] — Character encoding (
s7-bit,S8-bit,b16-bit big-endian,l16-bit little-endian)
Practical Examples
# Extract all strings and search for credentials
strings /usr/local/bin/app | grep -iE 'password|user|api_key|secret'
# Extract longer strings to reduce noise
strings -n 10 /bin/suspicious | less
# Extract strings with hex offsets
strings -t x /path/to/binary | grep -i 'config'
# Extract from memory dump or core dump
strings /proc/[PID]/mem 2>/dev/null | grep -i 'pass'
# Extract from all binaries in directory
find /usr/local/bin -type f -executable -exec sh -c 'echo "=== {} ==="; strings {} | grep -i password' \; 2>/dev/null
# Extract from libraries
strings /usr/lib/*.so | grep -iE 'password|api_key' | sort -u
Output Interpretation
- Raw printable strings; includes code, data, error messages, hardcoded credentials
- High noise-to-signal ratio; use grep filters and increase
-nvalue - Look for: connection strings, API endpoints, embedded credentials, license keys
OPSEC and Detection Notes
- LOW NOISE: strings reads files like cat; minimal detection footprint
- Extracting strings from
/proc/[pid]/memrequires same user or root; may log access
Common Errors
strings: [file]: file format not recognized— File truly not a binary; usefileto verify- Excessive output — Increase minimum length:
-n 8or-n 12 - Permission denied on
/proc/[pid]/mem— Requires root or process owner
Version and Platform Notes
- GNU strings (Linux standard): supports all encodings and formats
- BSD strings (macOS): limited encoding support
Parsing and Filtering Output (awk, sed, cut)
Purpose: Extract and format specific fields from grep/find results
Prerequisites: Standard Linux shell (bash/sh)
Core Commands
# awk: split by delimiter and print fields
grep 'password=' file.conf | awk -F= '{print $2}'
# cut: extract column by delimiter
grep 'user:' file | cut -d: -f2
# sed: regex extraction
sed -n 's/.*password=\([^&]*\).*/\1/p' file
Options and Flags
- awk -F[char] — Field separator (default whitespace)
- awk {print $N} — Print field N (1-indexed;
$0entire line) - cut -d[char] — Delimiter character
- cut -f[N] — Field number(s) to extract
- sed -n — Suppress default output (only print explicit
pcommands) - sed s/pattern/replacement/ — Substitute (regex)
Practical Examples
# Extract passwords from "password=value" format
grep -ri 'password=' /etc | awk -F= '{print $2}'
# Extract usernames from /etc/passwd (field 1, delimiter :)
cut -d: -f1 /etc/passwd
# Extract usernames and home directories
awk -F: '{print $1 " -> " $6}' /etc/passwd
# Extract database credentials from config
grep -E 'user|password|host' db.conf | awk -F= '{print $1 ": " $2}'
# Extract API keys from grep output (remove filename prefix)
grep -rh 'api_key=' /var/www | cut -d= -f2 | sort -u
# Extract values between quotes
sed -n 's/.*password="\([^"]*\)".*/\1/p' config.php
# Extract IP addresses from logs
grep 'Failed password' /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn
# Parse JSON-like output (basic)
grep -o '"password":"[^"]*"' config.json | cut -d'"' -f4
Output Interpretation
- Extracted fields only; ready for further processing or reporting
- Use
sort -uto deduplicate,sort | uniq -cto count occurrences
OPSEC and Detection Notes
ZERO IMPACT: awk/sed/cut operate on stdin/files; no network or unusual syscalls
Common Errors
- Wrong field number — Count fields carefully; awk is 1-indexed
- Delimiter not matched — Verify with
headfirst; ensure delimiter present - sed regex not matching — Test pattern with simpler examples; escape special chars
Version and Platform Notes
- POSIX-compliant awk/sed/cut work on all Linux/Unix
- GNU awk (gawk) supports advanced features (multi-char separators, arrays)
OPSEC and Detection Awareness
Purpose: Understand what defensive tools log when searching for credentials
Prerequisites: Awareness of target environment (auditd, EDR, SIEM presence)
Core Detection Mechanisms
- auditd — File access monitoring; logs to
/var/log/audit/audit.log - EDR agents — Behavioral detection; anomaly scoring for file enumeration patterns
- syslog — General system logging; may capture bash history or command execution
- Process accounting (psacct) — Logs executed commands
Key Indicators of Compromise (IOCs) Generated
- Recursive grep from
/— High I/O load, CPU spike, massive file read count - Access to
/etc/shadow,/etc/passwd,~/.ssh/id_rsa— High-priority alerts - Rapid sequential file reads across multiple directories — Anomaly detection trigger
- Large result sets piped to output files — Unusual data exfiltration patterns
Detection Check Commands
# Check if auditd is running
systemctl status auditd
ps aux | grep auditd
# Check existing audit watches (requires root)
auditctl -l
# Search audit logs for your own activity (requires root)
ausearch --file /etc/shadow --interpret
ausearch -k password-access -ts recent
# Check for file watches on sensitive files
auditctl -l | grep -E 'shadow|passwd|ssh'
# Generate audit summary report (requires root)
aureport -f | tail -50
aureport -u | tail -20
# Check if EDR/monitoring agent present
ps aux | grep -iE 'falcon|crowdstrike|carbon|defender|sentinel|tanium'
# Check SELinux status (may block file access)
sestatus
ls -Z /etc/shadow
Output Interpretation
- auditd file watches indicate monitored paths
- EDR processes indicate behavioral monitoring active
- SELinux enforcing mode may silently block reads
OPSEC Recommendations
- Target scope aggressively: Search
/var/www,/opt, specific user homes instead of/ - Exclude system directories: Use
--exclude-dir={proc,sys,dev,run,usr/share}with grep - Small result sets: Use
-l(filenames only) until target narrowed - Blend with normal activity: Sysadmins search logs frequently; timing and context matter
- Avoid high-value files initially: Test with lower-risk directories first
- Throttle I/O: Add
sleepbetween operations or usenice/ioniceto reduce resource impact
Common Detection Artifacts
/var/log/audit/audit.log— File access records:type=PATH msg=audit(...): item=0 name="/etc/shadow"- Bash history — Commands logged to
~/.bash_history(disable:unset HISTFILE) - Process command line — Visible in
ps auxwwoutput while running - Network anomaly — Large internal file reads may correlate with exfil attempts
Mitigation Against Detection
- Disable history temporarily:
unset HISTFILEorset +o history - Clear history:
history -c; rm ~/.bash_history(obvious indicator if monitored) - Use absolute paths: Avoid relative paths that expose working directory context
- Redirect output carefully: Large output files in
/tmpor home directory may trigger alerts
Version and Platform Notes
- auditd standard on RHEL/CentOS/Fedora; may not be enabled by default on Debian/Ubuntu
- systemd
journalctlalso logs command execution on systemd-based systems
References
- GNU grep Manual
- grep Man Page - Linux.die.net
- locate Man Page
- find Man Page
- Linux Privilege Escalation Using Misconfigured File Permissions - Hacking Articles
- xargs Man Page
- Linux find Command - Red Hat Sysadmin
- Linux /proc Filesystem Documentation
- ps Man Page
- Linux Log Files Location and Viewing Guide - nixCraft
- journalctl Man Page
- GNU find Manual
- strings Man Page
- awk Man Page
- GNU sed Manual
- Understanding Audit Log Files - Red Hat
- Configuring and Auditing Linux Systems with auditd
#Linux #PrivEsc #Enumeration #Credentials #grep #find #OPSEC #Logs #FileEnumeration #PasswordHunting