find-command.md (19558B)
1 --- 2 title: "Find Command" 3 description: "find /home -iname \"*.conf\" -type f" 4 category: linux-it 5 tags: ["linux-it", "privilege-escalation"] 6 tools: [] 7 difficulty: intermediate 8 updated: "2026-08-10" 9 source: "vault:Linux/Find Command.md" 10 --- 11 # Find files by name (case-insensitive) 12 find /home -iname "*.conf" -type f 13 ``` 14 15 > [!info]+ Command Breakdown 16 > 1. **-iname "*.conf"**: Case-insensitive pattern matching for files ending in `.conf` 17 > 2. **-type f**: Restricts results to regular files only 18 > 3. *Wildcard `*` matches any characters before `.conf` extension* 19 > 4. *Useful for locating configuration files across user directories* 20 21 ```bash 22 # Find files larger than 100MB 23 find / -type f -size +100M 2>/dev/null 24 ``` 25 26 > [!info]+ Command Breakdown 27 > 1. **-size +100M**: Files greater than 100 megabytes 28 > 2. **2>/dev/null**: Redirects permission-denied errors to avoid output clutter 29 > 3. *Starting from root `/` requires elevated privileges for complete results* 30 > 4. *Useful for identifying large files consuming disk space or potential data exfiltration* 31 32 ```bash 33 # Find files modified between two dates 34 find /data -newermt "2025-12-01" ! -newermt "2026-01-01" 35 ``` 36 37 > [!info]+ Command Breakdown 38 > 1. **-newermt "2025-12-01"**: Files modified after (newer than) December 1, 2025 39 > 2. **! -newermt "2026-01-01"**: `!` negates the test; files NOT newer than January 1, 2026 40 > 3. *Logical combination creates a date range: December 1-31, 2025* 41 > 4. *Critical for [incident response](https://www.sans.org/white-papers/33901/) timeline analysis* 42 43 ```bash 44 # Find and delete empty directories 45 find /tmp -type d -empty -delete 46 ``` 47 48 > [!warning]+ Command Breakdown 49 > 1. **-type d**: Targets directories only 50 > 2. **-empty**: Matches directories with no contents 51 > 3. **-delete**: Deletes matched items (implies `-depth` traversal) 52 > 4. *Use with extreme caution—deletion is immediate and irreversible* 53 > 5. *Test with `-print` before using `-delete` to verify targets* 54 55 --- 56 57 ## SUID/SGID and World-Writable File Discovery 58 59 Files with [SUID/SGID](https://www.redhat.com/sysadmin/suid-sgid-sticky-bit) bits or world-writable permissions are high-value targets for privilege escalation: 60 61 1. **SUID (Set User ID)**: Executes with file owner's privileges (typically root) 62 2. **SGID (Set Group ID)**: Executes with file group's privileges 63 3. **World-writable**: Any user can modify the file 64 4. Cross-reference SUID binaries with [GTFOBins](https://gtfobins.github.io/) for exploitation paths 65 5. World-writable config files in `/etc` are critical escalation vectors 66 67 ### SUID/SGID Discovery Commands 68 69 ```bash 70 # Find SUID files 71 find / -type f -perm -4000 2>/dev/null 72 ``` 73 74 > [!info]+ Command Breakdown 75 > 1. **-perm -4000**: Files with at least the SUID bit (octal 4000) set 76 > 2. **-type f**: Restricts to regular files (not directories) 77 > 3. *The `-` prefix means "at least these permission bits"—file may have additional permissions* 78 > 4. *Common legitimate SUID binaries: `/usr/bin/passwd`, `/usr/bin/sudo`, `/bin/ping`* 79 80 ```bash 81 # Find SGID files 82 find / -type f -perm -2000 2>/dev/null 83 ``` 84 85 **SGID characteristics:** 86 1. SGID on executables runs with group privileges 87 2. SGID on directories causes new files to inherit directory's group 88 3. Less common for privilege escalation than SUID but still valuable 89 4. Check output against system baseline for anomalies 90 91 ```bash 92 # Find SUID or SGID files 93 find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null 94 ``` 95 96 > [!info]+ Command Breakdown 97 > 1. **\( ... \)**: Parentheses create logical grouping (escaped for shell) 98 > 2. **-o**: Logical OR operator—matches either condition 99 > 3. *Comprehensive search for all elevated permission binaries* 100 > 4. *Output should be compared against baseline for anomaly detection* 101 102 ### World-Writable Discovery Commands 103 104 ```bash 105 # Find world-writable files 106 find / -type f -perm -0002 2>/dev/null 107 ``` 108 109 **Security implications:** 110 1. Extremely dangerous if file is executed or sourced by privileged processes 111 2. Check ownership—writable files owned by root are highest priority 112 3. Common in web directories due to misconfigurations 113 4. Potential for code injection or configuration tampering 114 115 ```bash 116 # Find world-writable directories (sticky bit often expected) 117 find / -type d -perm -0002 2>/dev/null 118 ``` 119 120 **Expected vs. dangerous:** 121 1. World-writable directories like `/tmp` typically have sticky bit (1000) set 122 2. Sticky bit prevents users from deleting others' files 123 3. Missing sticky bit on writable directory is a misconfiguration 124 4. Check `/var/www`, `/var/tmp`, `/dev/shm` for anomalies 125 126 ### Advanced Privilege Escalation Enumeration 127 128 ```bash 129 # SUID binaries owned by root (common priv-esc targets) 130 find / -type f -perm -4000 -user root 2>/dev/null 131 ``` 132 133 **Analysis approach:** 134 1. Root-owned SUID binaries execute with root privileges 135 2. Focus on non-standard binaries not in `/usr/bin` or `/bin` 136 3. Test discovered binaries against [GTFOBins](https://gtfobins.github.io/) for known exploits 137 4. Document custom SUID binaries for deeper analysis 138 139 ```bash 140 # SUID/SGID with detailed output 141 find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -la {} \; 2>/dev/null 142 ``` 143 144 > [!info]+ Command Breakdown 145 > 1. **-exec ls -la {} \;**: Executes `ls -la` on each matched file 146 > 2. **{}**: Placeholder replaced with found filename 147 > 3. **\;**: Required terminator for `-exec` (escaped for shell) 148 > 4. *Provides full permission string, owner, group, size, and modification date* 149 150 ```bash 151 # World-writable files excluding /proc and /sys 152 find / -path /proc -prune -o -path /sys -prune -o -type f -perm -0002 -print 2>/dev/null 153 ``` 154 155 > [!info]+ Command Breakdown 156 > 1. **-path /proc -prune**: Excludes `/proc` directory from traversal 157 > 2. **-o**: OR operator—chains pruning and search logic 158 > 3. **-prune**: Prevents descending into matched directory 159 > 4. *`/proc` and `/sys` are pseudo-filesystems with world-writable entries by design* 160 > 5. *Excluding them reduces noise and improves performance* 161 162 ```bash 163 # World-writable directories without sticky bit (dangerous) 164 find / -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null 165 ``` 166 167 > [!danger]+ Command Breakdown 168 > 1. **-a**: Logical AND operator—both conditions must be true 169 > 2. **! -perm -1000**: Negates sticky bit check (octal 1000) 170 > 3. *World-writable directory without sticky bit allows any user to delete any file* 171 > 4. *Severe misconfiguration—often found in poorly configured web directories* 172 173 **OPSEC considerations:** 174 1. Full system scans generate high I/O and may trigger file integrity monitoring ([AIDE](https://aide.github.io/), [OSSEC](https://www.ossec.net/)) 175 2. Redirect stderr (`2>/dev/null`) to avoid logging permission-denied paths in shell history 176 3. Consider running during high-activity periods to blend with baseline noise 177 4. Use `-maxdepth` to limit scope and reduce detection surface 178 5. Combine with `-xdev` to avoid traversing network mounts (reduces latency and external logs) 179 180 --- 181 182 ## Command Execution with `-exec` and `xargs` 183 184 Three primary methods exist for executing commands on found files, each with distinct performance and safety characteristics: 185 186 1. **-exec cmd {} \;**: Forks command once per file (slower, more visible) 187 2. **-exec cmd {} +**: Batches files into single command invocation (faster, less visible) 188 3. **find | xargs**: Batches via pipe, respects ARG_MAX, supports parallelism 189 190 ### Execution Method Comparison 191 192 | Method | Behaviour | Performance | Use Case | OPSEC Impact | 193 |:---|:---|:---|:---|:---| 194 | `-exec cmd {} \;` | Forks cmd once per file | Slow | Small sets, complex per-file logic | High (many processes) | 195 | `-exec cmd {} +` | Batches files into one cmd | Fast | Large sets, simple commands | Low (few processes) | 196 | `find \| xargs` | Batches via pipe | Fast | Very large sets, custom batching | Low (few processes) | 197 | `find -print0 \| xargs -0` | Null-delimited batching | Fast | Filenames with spaces/newlines | Low (safe handling) | 198 | `xargs -P N` | Parallel execution | Fastest | CPU-bound operations | Medium (multiple concurrent processes) | 199 200 ### `-exec` Examples 201 202 ```bash 203 # -exec with \; (one command per file – slower) 204 find . -type f -name "*.log" -exec rm {} \; 205 ``` 206 207 > [!info]+ Command Breakdown 208 > 1. **-exec rm {}**: Executes `rm` command with `{}` replaced by filename 209 > 2. **\;**: Terminator indicating end of command (backslash escapes semicolon from shell) 210 > 3. *Spawns one `rm` process per file—thousands of files = thousands of processes* 211 > 4. *High overhead but allows per-file command customization* 212 213 ```bash 214 # -exec with + (batched arguments – faster) 215 find . -type f -name "*.log" -exec rm {} + 216 ``` 217 218 **Batching behaviour:** 219 1. Combines multiple filenames into single command invocation 220 2. Example: `rm file1.log file2.log file3.log` instead of three separate `rm` calls 221 3. Respects system ARG_MAX limit—automatically splits into multiple batches if needed 222 4. Preferred method for large-scale operations 223 224 ```bash 225 # Grep for pattern in PHP files (batched) 226 find /var/www -type f -name "*.php" -exec grep -l "eval(" {} + 227 ``` 228 229 > [!info]+ Command Breakdown 230 > 1. **grep -l "eval("**: Lists filenames containing the string `eval(` (potential [web shell](https://www.acunetix.com/blog/articles/web-shells-101-using-php-introduction-web-shells-part-2/) indicator) 231 > 2. **-exec ... +**: Batches PHP files into single `grep` invocation for efficiency 232 > 3. *Useful for web application security audits and malware hunting* 233 > 4. *Consider escaping parentheses in grep pattern depending on shell context* 234 235 ```bash 236 # Change ownership in batches 237 find /data -type f -exec chown appuser:appgroup {} + 238 ``` 239 240 **Performance notes:** 241 1. Changes file owner to `appuser` and group to `appgroup` 242 2. Batching significantly reduces execution time on large directory trees 243 3. Common post-deployment task or privilege management operation 244 4. Requires appropriate permissions (typically root/sudo) 245 246 ### `xargs` Examples 247 248 ```bash 249 # Pipe to xargs (batched, handles large sets) 250 find . -type f -name "*.log" -print0 | xargs -0 rm 251 ``` 252 253 > [!info]+ Command Breakdown 254 > 1. **-print0**: Outputs null-delimited filenames (handles spaces, newlines, special characters) 255 > 2. **xargs -0**: Reads null-delimited input from stdin 256 > 3. *The `-0` pairing is **critical** for safe handling of unusual filenames* 257 > 4. *[xargs](https://man7.org/linux/man-pages/man1/xargs.1.html) automatically batches arguments respecting ARG_MAX* 258 259 ```bash 260 # xargs with parallelism 261 find . -type f -name "*.log" -print0 | xargs -0 -P 4 rm 262 ``` 263 264 **Parallelism considerations:** 265 1. **-P 4**: Runs up to 4 parallel `rm` processes simultaneously 266 2. Significantly faster for CPU-bound operations (compression, checksumming) 267 3. Use `-P 1` to force serial execution if parallelism causes detection 268 4. Monitor system load—excessive parallelism can overwhelm resources 269 270 ```bash 271 # Safe delete with confirmation (interactive) 272 find . -name "*.tmp" -print0 | xargs -0 -p rm 273 ``` 274 275 **Interactive mode:** 276 1. **-p**: Prompts user before executing each command 277 2. Safety mechanism for destructive operations 278 3. User must type `y` to confirm each deletion 279 4. Not suitable for automated scripts—use only for manual operations 280 281 ```bash 282 # Compress logs older than 30 days (parallel) 283 find /var/log -type f -mtime +30 -name "*.log" -print0 | xargs -0 -P 4 gzip 284 ``` 285 286 > [!info]+ Command Breakdown 287 > 1. **-mtime +30**: Files modified more than 30 days ago 288 > 2. **gzip**: Compresses each file (replaces original with `.gz` version) 289 > 3. **-P 4**: Compresses 4 files simultaneously 290 > 4. *Common log rotation cleanup task* 291 > 5. *Parallelism ideal for CPU-intensive compression workloads* 292 293 ### Additional `xargs` Options 294 295 | Flag | Description | Example Use | 296 |:---|:---|:---| 297 | `-n N` | Max N arguments per invocation | `xargs -n 1` processes one file at a time | 298 | `-r` | Don't run if input is empty | Prevents errors when find returns nothing | 299 | `-I {}` | Replace string placeholder | `xargs -I {} mv {} /backup/` | 300 | `-t` | Print command before executing | Debugging and logging | 301 | `--show-limits` | Display ARG_MAX and buffer sizes | System capability check | 302 303 > [!warning]+ Common Errors 304 > 1. **Missing `-0` with xargs when filenames contain spaces**: Command breaks or acts on wrong files—always use `-print0 | xargs -0` pairing 305 > 2. **Forgetting `\;` or `+` at end of `-exec`**: Syntax error—required terminator 306 > 3. **Using `-delete` before other predicates**: Evaluation order matters; `-delete` implies `-depth` traversal 307 > 4. **Forgetting `-r` with xargs when find returns nothing**: Unexpected command execution with no arguments 308 > 5. **Exceeding ARG_MAX with `-exec {} +`**: Rare on modern systems—xargs auto-splits, but find may fail on ancient systems 309 310 --- 311 312 ## Time-Based File Searches 313 314 [find](https://man7.org/linux/man-pages/man1/find.1.html) supports three timestamp types for file matching: 315 316 1. **mtime**: File modification time (content changed) 317 2. **atime**: File access time (content read) 318 3. **ctime**: Inode change time (metadata changed—permissions, ownership, name) 319 4. Each has day-based (`-mtime`) and minute-based (`-mmin`) variants 320 5. Critical for [incident response](https://www.sans.org/white-papers/33901/), forensic analysis, and log management 321 322 ### Time Predicate Syntax 323 324 | Predicate | Meaning | Measurement Unit | 325 |:---|:---|:---| 326 | `-mtime n` | Modified exactly n days ago | 24-hour periods | 327 | `-mtime +n` | Modified more than n days ago | 24-hour periods | 328 | `-mtime -n` | Modified within last n days | 24-hour periods | 329 | `-atime n/+n/-n` | Access time variants | 24-hour periods | 330 | `-ctime n/+n/-n` | Inode change time variants | 24-hour periods | 331 | `-mmin n/+n/-n` | Modification time | Minutes | 332 | `-amin n/+n/-n` | Access time | Minutes | 333 | `-cmin n/+n/-n` | Inode change time | Minutes | 334 | `-newermt "date"` | Modified after specified date | ISO 8601 format | 335 | `-newer reference` | Modified more recently than file | File comparison | 336 | `-daystart` | Measure from start of today | Changes reference point | 337 338 ### Time-Based Search Examples 339 340 ```bash 341 # Files modified in the last 24 hours 342 find /var/log -type f -mtime 0 343 ``` 344 345 **Interpretation:** 346 1. **-mtime 0**: Files modified between now and 24 hours ago 347 2. `0` represents the current 24-hour period from now 348 3. Useful for identifying recently changed logs during incident investigation 349 4. Does not mean "modified today"—use `-daystart -mtime 0` for that 350 351 ```bash 352 # Files modified more than 30 days ago 353 find /tmp -type f -mtime +30 354 ``` 355 356 **Interpretation:** 357 1. **-mtime +30**: Files with modification time older than 30 days 358 2. **+** prefix means "more than"—excludes files at exactly 30 days 359 3. Common cleanup pattern for temporary directories 360 4. Combine with `-delete` or `-exec rm` for automated maintenance 361 362 ```bash 363 # Files modified in the last 60 minutes 364 find /home -type f -mmin -60 365 ``` 366 367 **Interpretation:** 368 1. **-mmin -60**: Files modified within the last 60 minutes 369 2. **-** prefix means "less than"—within the specified timeframe 370 3. Higher resolution than day-based predicates 371 4. Essential for real-time security monitoring and breach detection 372 373 ```bash 374 # Files modified yesterday (using -daystart) 375 find /data -daystart -mtime 1 -type f 376 ``` 377 378 > [!info]+ Command Breakdown 379 > 1. **-daystart**: Changes reference point to midnight today (00:00) instead of current time 380 > 2. **-mtime 1**: Exactly 1 day ago from reference point 381 > 3. *Without `-daystart`, `1` means "24-48 hours ago from now"* 382 > 4. *Order matters: `-daystart` must appear **before** `-mtime` in expression* 383 384 ```bash 385 # Files modified between two dates 386 find /logs -newermt "2025-12-01" ! -newermt "2025-12-31" 387 ``` 388 389 > [!info]+ Command Breakdown 390 > 1. **-newermt "2025-12-01"**: Modified after (newer than) December 1, 2025 00:00:00 391 > 2. **! -newermt "2025-12-31"**: `!` negates—NOT newer than December 31, 2025 00:00:00 392 > 3. *Creates inclusive date range: December 1-30, 2025* 393 > 4. *Requires quotes around dates; supports ISO 8601 format with time: `"2025-12-01 14:30:00"`* 394 395 ```bash 396 # Files accessed more recently than a reference file 397 find /app -newer /app/deploy.timestamp 398 ``` 399 400 **Use cases:** 401 1. **-newer /app/deploy.timestamp**: Files modified more recently than reference file's mtime 402 2. Useful for identifying files changed since last deployment 403 3. Create timestamp files with `touch` to mark events 404 4. Variant: `-anewer` for atime comparison, `-cnewer` for ctime 405 406 ### Advanced Time-Based Queries 407 408 ```bash 409 # Files modified today (calendar day, not 24 hours) 410 find /var/log -type f -daystart -mtime 0 -printf "%T+ %p\n" 411 ``` 412 413 > [!info]+ Command Breakdown 414 > 1. **-daystart -mtime 0**: Files modified since midnight today 415 > 2. **-printf "%T+ %p\n"**: Custom format—`%T+` is ISO timestamp, `%p` is path 416 > 3. *Output format: `2026-01-18+09:30:15.0000000000 /var/log/auth.log`* 417 > 4. *Pipe to `sort` for chronological ordering* 418 419 ```bash 420 # Files NOT accessed in the last 90 days (candidates for archival) 421 find /archive -type f -atime +90 -ls 422 ``` 423 424 **Archival workflow:** 425 1. **-atime +90**: Access time older than 90 days 426 2. **-ls**: Long listing output with timestamps 427 3. Identifies stale files for archival or deletion 428 4. Warning: atime may be unreliable on filesystems with `noatime` or `relatime` mount options 429 430 **OPSEC and forensic considerations:** 431 1. **Access time queries may update atime on some filesystems**: Recursive find can modify the evidence you're searching for 432 2. **`noatime` or `relatime` mount options**: Access time may be stale or not updated—verify mount options with `mount | grep atime` 433 3. **Timestomping**: Adversaries can modify file timestamps—time-based queries less reliable if attacker has touched files 434 4. **Timezone considerations**: Timestamps in UTC vs local time—use `%T+` printf format for ISO 8601 with timezone 435 5. **Inode change time (ctime) cannot be modified by standard tools**: More forensically reliable than mtime/atime 436 437 > [!tip]+ Performance Optimization 438 > 1. Combine time predicates with `-type` early in expression for faster evaluation 439 > 2. Use `-maxdepth` to limit search scope when possible 440 > 3. Redirect stderr (`2>/dev/null`) to avoid permission-denied overhead 441 > 4. Consider `locate` database for name-based searches if time constraints allow 442 > 5. Use `-xdev` to avoid crossing mount points and network filesystems 443 444 --- 445 446 ## References 447 448 1. [GNU findutils Manual](https://www.gnu.org/software/findutils/manual/html_mono/find.html) 449 2. [Linux find Man Page](https://man7.org/linux/man-pages/man1/find.1.html) 450 3. [Red Hat: Linux find Command](https://www.redhat.com/en/blog/linux-find-command) 451 4. [Cyberciti: Finding Files by Date](https://www.cyberciti.biz/faq/howto-finding-files-by-date/) 452 5. [Red Hat: Audit Permissions with find](https://www.redhat.com/en/blog/audit-permissions-find) 453 6. [Baeldung: Find Modified Date](https://www.baeldung.com/linux/find-modified-date) 454 7. [Endpoint Dev: Efficiency of find -exec vs xargs](https://www.endpointdev.com/blog/2010/07/efficiency-of-find-exec-vs-find-xargs/) 455 8. [CaveOps: find -exec vs find | xargs](https://caveops.com/blog/post/name/find-exec-vs-find-xargs/) 456 9. [GTFOBins](https://gtfobins.github.io/) 457 10. [MITRE ATT&CK: File and Directory Discovery](https://attack.mitre.org/techniques/T1083/) 458 11. [HackTricks: Linux Privilege Escalation](https://book.hacktricks.xyz/linux-hardening/privilege-escalation) 459 12. [SANS: Incident Response Process](https://www.sans.org/white-papers/33901/) 460 461 --- 462 463 #Linux #FileSystemEnumeration #find #xargs #SUID #SGID #PrivilegeEscalation #IncidentResponse #Forensics #SystemAdministration #PenetrationTesting #Reconnaissance #GTFOBins