daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

linux-find.md (12106B)


      1 ---
      2 title: "Linux find Command"
      3 description: "find recipes: by name/type/time/perm/size, SUID hunting, exec actions and pruning noisy paths."
      4 category: linux-it
      5 tags: [linux, cli, search]
      6 tools: [find]
      7 difficulty: intermediate
      8 updated: "2026-08-09"
      9 source: "vault:Linux/Find Command.md"
     10 ---
     11 
     12 # Linux find Command
     13 
     14 ## Overview
     15 
     16 `find` recursively searches directory trees for files and directories matching specified criteria (name, type, size, time, permissions, ownership) and optionally executes actions on results. Part of GNU findutils, it's essential for system enumeration, privilege escalation reconnaissance, and incident response.
     17 
     18 **Key capabilities:**
     19 1. Pattern-based file and directory matching
     20 2. Time-based searches (modification, access, inode change)
     21 3. Permission-based filtering (SUID/SGID, world-writable)
     22 4. Command execution on matched files via `-exec` or pipe to `xargs`
     23 5. Minimal overhead with powerful filtering capabilities
     24 
     25 > **Prerequisites**
     26 > 1. GNU findutils installed (standard on all major Linux distributions).
     27 > 2. Read permission on target directories; root/sudo required for full system scans.
     28 > 3. Current stable version: GNU findutils 4.10.0 (4.9.x widely deployed).
     29 > 4. Understand Linux permission octal notation: SUID=4000, SGID=2000, world-writable=0002.
     30 > 5. Timestamps depend on filesystem and mount options (`noatime`, `relatime`).
     31 
     32 ---
     33 
     34 ## General File Search
     35 
     36 ### Basic Syntax
     37 
     38 ```bash
     39 find [starting-point...] [expression]
     40 ```
     41 
     42 - **starting-point**: Directory path(s) to begin search (default: current directory)
     43 - **expression**: Combination of tests, actions, and operators (evaluated left-to-right with implicit AND)
     44 
     45 ### Search Criteria Options
     46 
     47 | Flag | Description | Example |
     48 |:---|:---|:---|
     49 | `-name "pattern"` | Match filename (case-sensitive, wildcards `*`, `?`) | `find . -name "*.conf"` |
     50 | `-iname "pattern"` | Case-insensitive `-name` | `find . -iname "*.PHP"` |
     51 | `-type f/d/l/s/p` | File type: `f`=file, `d`=dir, `l`=symlink, `s`=socket, `p`=named pipe | `find / -type f` |
     52 | `-size [+/-]n[cwbkMG]` | File size; `+`=greater, `-`=less; units `c`/`k`/`M`/`G` | `find / -size +100M` |
     53 | `-user / -group` | Owner / group name or UID/GID | `find /home -user john` |
     54 | `-perm mode` | Exact permissions match | `find . -perm 0644` |
     55 | `-perm -mode` | All permission bits set | `find / -perm -4000` |
     56 | `-perm /mode` | Any permission bit set | `find / -perm /6000` |
     57 | `-maxdepth n` | Limit traversal depth | `find /etc -maxdepth 2` |
     58 | `-mindepth n` | Start traversal at depth n | `find / -mindepth 2` |
     59 | `-xdev` | Stay on same filesystem (do not descend into other mounts) | `find / -xdev` |
     60 | `-empty` | Empty files or directories | `find /tmp -empty` |
     61 
     62 ### Output Control Options
     63 
     64 | Flag | Description | Use Case |
     65 |:---|:---|:---|
     66 | `-print` | Print full path (default) | Standard output |
     67 | `-print0` | Null-delimit output | Safe piping to `xargs -0` |
     68 | `-printf "format"` | Custom output format | `%M` mode, `%u` user, `%T+` timestamp |
     69 | `-ls` | Long listing format | Permissions, owner, size, date |
     70 
     71 ### Basic Search Examples
     72 
     73 ```bash
     74 # Find files by name (case-insensitive)
     75 find /home -iname "*.conf" -type f
     76 
     77 # Find files larger than 100MB
     78 find / -type f -size +100M 2>/dev/null
     79 
     80 # Find files modified between two dates
     81 find /data -newermt "2025-12-01" ! -newermt "2026-01-01"
     82 
     83 # Find and delete empty directories
     84 find /tmp -type d -empty -delete
     85 ```
     86 
     87 > **Warning —** `-delete` is immediate and irreversible. Test with `-print` before using `-delete` to verify targets. `-delete` implies `-depth` traversal.
     88 
     89 ---
     90 
     91 ## SUID/SGID and World-Writable File Discovery
     92 
     93 Files with SUID/SGID bits or world-writable permissions are high-value targets for privilege escalation:
     94 
     95 1. **SUID (Set User ID)**: Executes with file owner's privileges (typically root)
     96 2. **SGID (Set Group ID)**: Executes with file group's privileges
     97 3. **World-writable**: Any user can modify the file
     98 4. Cross-reference SUID binaries with GTFOBins (https://gtfobins.github.io/) for exploitation paths
     99 5. World-writable config files in `/etc` are critical escalation vectors
    100 
    101 ### SUID/SGID Discovery Commands
    102 
    103 ```bash
    104 # Find SUID files (at least the SUID bit set)
    105 find / -type f -perm -4000 2>/dev/null
    106 
    107 # Find SGID files
    108 find / -type f -perm -2000 2>/dev/null
    109 
    110 # Find SUID or SGID files
    111 find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null
    112 
    113 # SUID binaries owned by root (common priv-esc targets)
    114 find / -type f -perm -4000 -user root 2>/dev/null
    115 
    116 # SUID/SGID with detailed output
    117 find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -la {} \; 2>/dev/null
    118 ```
    119 
    120 > **Note —** The `-` prefix on `-perm` means "at least these bits" — the file may have additional permissions. Common legitimate SUID binaries: `/usr/bin/passwd`, `/usr/bin/sudo`, `/bin/ping`. Compare output against a baseline for anomaly detection.
    121 
    122 ### World-Writable Discovery Commands
    123 
    124 ```bash
    125 # Find world-writable files
    126 find / -type f -perm -0002 2>/dev/null
    127 
    128 # Find world-writable directories (sticky bit often expected)
    129 find / -type d -perm -0002 2>/dev/null
    130 
    131 # World-writable files excluding /proc and /sys
    132 find / -path /proc -prune -o -path /sys -prune -o -type f -perm -0002 -print 2>/dev/null
    133 
    134 # World-writable directories without sticky bit (dangerous)
    135 find / -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null
    136 ```
    137 
    138 > **Danger —** A world-writable directory without the sticky bit (octal 1000) allows any user to delete any file. Writable files owned by root, and writable configs sourced by privileged processes, are the highest priority. World-writable dirs like `/tmp` normally carry the sticky bit.
    139 
    140 > **OPSEC considerations**
    141 > 1. Full system scans generate high I/O and may trigger file-integrity monitoring (AIDE, OSSEC).
    142 > 2. Redirect stderr (`2>/dev/null`) to avoid permission-denied noise.
    143 > 3. Use `-maxdepth` to limit scope and reduce detection surface.
    144 > 4. Combine with `-xdev` to avoid traversing network mounts.
    145 
    146 ---
    147 
    148 ## Command Execution with `-exec` and `xargs`
    149 
    150 Three primary methods for executing commands on found files:
    151 
    152 1. **-exec cmd {} \;**: Forks command once per file (slower, more visible)
    153 2. **-exec cmd {} +**: Batches files into single command invocation (faster, less visible)
    154 3. **find | xargs**: Batches via pipe, respects ARG_MAX, supports parallelism
    155 
    156 ### Execution Method Comparison
    157 
    158 | Method | Behaviour | Performance | Use Case | OPSEC Impact |
    159 |:---|:---|:---|:---|:---|
    160 | `-exec cmd {} \;` | Forks cmd once per file | Slow | Small sets, complex per-file logic | High (many processes) |
    161 | `-exec cmd {} +` | Batches files into one cmd | Fast | Large sets, simple commands | Low (few processes) |
    162 | `find \| xargs` | Batches via pipe | Fast | Very large sets, custom batching | Low (few processes) |
    163 | `find -print0 \| xargs -0` | Null-delimited batching | Fast | Filenames with spaces/newlines | Low (safe handling) |
    164 | `xargs -P N` | Parallel execution | Fastest | CPU-bound operations | Medium (concurrent processes) |
    165 
    166 ### `-exec` Examples
    167 
    168 ```bash
    169 # -exec with \; (one command per file – slower)
    170 find . -type f -name "*.log" -exec rm {} \;
    171 
    172 # -exec with + (batched arguments – faster)
    173 find . -type f -name "*.log" -exec rm {} +
    174 
    175 # Grep for pattern in PHP files (batched) – potential webshell indicator
    176 find /var/www -type f -name "*.php" -exec grep -l "eval(" {} +
    177 
    178 # Change ownership in batches
    179 find /data -type f -exec chown appuser:appgroup {} +
    180 ```
    181 
    182 ### `xargs` Examples
    183 
    184 ```bash
    185 # Pipe to xargs (batched, handles large sets)
    186 find . -type f -name "*.log" -print0 | xargs -0 rm
    187 
    188 # xargs with parallelism (up to 4 concurrent processes)
    189 find . -type f -name "*.log" -print0 | xargs -0 -P 4 rm
    190 
    191 # Safe delete with confirmation (interactive)
    192 find . -name "*.tmp" -print0 | xargs -0 -p rm
    193 
    194 # Compress logs older than 30 days (parallel)
    195 find /var/log -type f -mtime +30 -name "*.log" -print0 | xargs -0 -P 4 gzip
    196 ```
    197 
    198 > **Note —** The `-print0 | xargs -0` pairing is critical for safe handling of filenames with spaces, newlines, or special characters.
    199 
    200 ### Additional `xargs` Options
    201 
    202 | Flag | Description | Example Use |
    203 |:---|:---|:---|
    204 | `-n N` | Max N arguments per invocation | `xargs -n 1` processes one file at a time |
    205 | `-r` | Don't run if input is empty | Prevents errors when find returns nothing |
    206 | `-I {}` | Replace string placeholder | `xargs -I {} mv {} /backup/` |
    207 | `-t` | Print command before executing | Debugging and logging |
    208 | `--show-limits` | Display ARG_MAX and buffer sizes | System capability check |
    209 
    210 > **Common errors**
    211 > 1. Missing `-0` with xargs when filenames contain spaces — always use the `-print0 | xargs -0` pairing.
    212 > 2. Forgetting `\;` or `+` at the end of `-exec` — required terminator.
    213 > 3. Using `-delete` before other predicates — evaluation order matters; `-delete` implies `-depth`.
    214 > 4. Forgetting `-r` with xargs when find returns nothing.
    215 
    216 ---
    217 
    218 ## Time-Based File Searches
    219 
    220 `find` supports three timestamp types for file matching:
    221 
    222 1. **mtime**: File modification time (content changed)
    223 2. **atime**: File access time (content read)
    224 3. **ctime**: Inode change time (metadata changed — permissions, ownership, name)
    225 4. Each has day-based (`-mtime`) and minute-based (`-mmin`) variants.
    226 
    227 ### Time Predicate Syntax
    228 
    229 | Predicate | Meaning | Measurement Unit |
    230 |:---|:---|:---|
    231 | `-mtime n` | Modified exactly n days ago | 24-hour periods |
    232 | `-mtime +n` | Modified more than n days ago | 24-hour periods |
    233 | `-mtime -n` | Modified within last n days | 24-hour periods |
    234 | `-atime n/+n/-n` | Access time variants | 24-hour periods |
    235 | `-ctime n/+n/-n` | Inode change time variants | 24-hour periods |
    236 | `-mmin n/+n/-n` | Modification time | Minutes |
    237 | `-amin n/+n/-n` | Access time | Minutes |
    238 | `-cmin n/+n/-n` | Inode change time | Minutes |
    239 | `-newermt "date"` | Modified after specified date | ISO 8601 format |
    240 | `-newer reference` | Modified more recently than file | File comparison |
    241 | `-daystart` | Measure from start of today | Changes reference point |
    242 
    243 ### Time-Based Search Examples
    244 
    245 ```bash
    246 # Files modified in the last 24 hours (rolling window from now)
    247 find /var/log -type f -mtime 0
    248 
    249 # Files modified more than 30 days ago
    250 find /tmp -type f -mtime +30
    251 
    252 # Files modified in the last 60 minutes
    253 find /home -type f -mmin -60
    254 
    255 # Files modified yesterday (calendar day, using -daystart)
    256 find /data -daystart -mtime 1 -type f
    257 
    258 # Files modified between two dates
    259 find /logs -newermt "2025-12-01" ! -newermt "2025-12-31"
    260 
    261 # Files modified more recently than a reference file
    262 find /app -newer /app/deploy.timestamp
    263 ```
    264 
    265 > **Note —** `-mtime 0` is a rolling 24-hour window, not "today". For calendar-day semantics use `-daystart -mtime 0`, and `-daystart` must appear before `-mtime` in the expression. Variants: `-anewer` (atime), `-cnewer` (ctime).
    266 
    267 ### Advanced Time-Based Queries
    268 
    269 ```bash
    270 # Files modified today (calendar day) with ISO timestamp output
    271 find /var/log -type f -daystart -mtime 0 -printf "%T+ %p\n"
    272 
    273 # Files NOT accessed in the last 90 days (candidates for archival)
    274 find /archive -type f -atime +90 -ls
    275 ```
    276 
    277 > **Forensic considerations**
    278 > 1. Recursive `find` on atime can update atime and modify the evidence you're searching.
    279 > 2. `noatime` / `relatime` mounts make atime stale — verify with `mount | grep atime`.
    280 > 3. Timestomping: adversaries modify timestamps, so mtime/atime are less reliable.
    281 > 4. ctime cannot be modified by standard tools — more forensically reliable than mtime/atime.
    282 
    283 > **Performance tips**
    284 > 1. Combine time predicates with `-type` early in the expression for faster evaluation.
    285 > 2. Use `-maxdepth` to limit search scope.
    286 > 3. Redirect stderr (`2>/dev/null`) to avoid permission-denied overhead.
    287 > 4. Use `-xdev` to avoid crossing mount points and network filesystems.
    288 
    289 ---
    290 
    291 ## References
    292 
    293 1. GNU findutils Manual — https://www.gnu.org/software/findutils/manual/html_mono/find.html
    294 2. Linux find Man Page — https://man7.org/linux/man-pages/man1/find.1.html
    295 3. GTFOBins — https://gtfobins.github.io/
    296 4. MITRE ATT&CK: File and Directory Discovery (T1083)
    297 5. HackTricks: Linux Privilege Escalation