Cron Job Added From Interactive Session

high Single event T1053.003 Persistence

A session installs a cron job, either through crontab or by writing to /etc/cron* or /var/spool/cron, so the payload restarts after a reboot or after being killed.

Tested

Matches all 4 attack events in match.jsonl and none of the 4 look-alike events in nomatch.jsonl. See the test events.

False positives

Sigma

title: Cron Job Added From Interactive Session
id: 5577b658-fa17-4a11-96ed-dd7251823f3f
status: experimental
description: |
  A session installs a cron job, either through crontab or by writing to /etc/cron* or /var/spool/cron,
  so the payload restarts after a reboot or after being killed.
references:
  - https://attack.mitre.org/techniques/T1053/003/
author: Estul Lachin
date: 2026-11-08
tags:
  - attack.persistence
  - attack.t1053.003
logsource:
  product: cowrie
detection:
  crontab:
    eventid: cowrie.command.input
    input|re: '\|\s*crontab\b|\bcrontab\s+(-\s*($|[;&|])|\S+\.\w+)'
  files:
    eventid: cowrie.command.input
    input|re: '>>?\s*/(etc/cron|var/spool/cron)'
  condition: crontab or files
falsepositives:
  - Administrators scheduling jobs over SSH
level: high

rules/cron_persistence.yml

Splunk SPL

``` Cron Job Added From Interactive Session. Generated from rules/cron_persistence.yml by tools/build.py; do not edit. ```
index=honeypot sourcetype=cowrie:json
| rex field=input "(?<inputMatch>\\|\\s*crontab\\b|\\bcrontab\\s+(-\\s*($|[;&|])|\\S+\\.\\w+))"
| eval inputCondition=if(isnotnull(inputMatch), "true", "false")
| rex field=input "(?<inputMatch2>>>?\\s*/(etc/cron|var/spool/cron))"
| eval inputCondition2=if(isnotnull(inputMatch2), "true", "false")
| search (eventid="cowrie.command.input" inputCondition="true") OR (eventid="cowrie.command.input" inputCondition2="true")

Verified in Splunk against the test events. dist/spl/cron_persistence.spl

Microsoft Sentinel KQL

// Cron Job Added From Interactive Session. Generated from rules/cron_persistence.yml by tools/build.py; do not edit.
Cowrie_CL
| where (eventid =~ "cowrie.command.input" and input matches regex "\\|\\s*crontab\\b|\\bcrontab\\s+(-\\s*($|[;&|])|\\S+\\.\\w+)") or (eventid =~ "cowrie.command.input" and input matches regex ">>?\\s*/(etc/cron|var/spool/cron)")

For a custom table Cowrie_CL with Cowrie's field names. Converted, not yet run in Sentinel. dist/kql/cron_persistence.kql