# How to Use Cron Scheduling for Automated Red Team Operations in LazyOwn

> Automate red team operations with LazyOwn's built-in cron scheduler. Execute commands at specific times using `do_cron` for efficient, time-delayed operations.

- Repository: [Grisuno/lazyown](https://github.com/grisuno/lazyown)
- Tags: how-to-guide
- Published: 2026-03-02

---

**LazyOwn provides a built-in cron-style scheduler via the `do_cron` command in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py) that queues commands to execute at specific times using Python's `threading.Timer`, enabling time-delayed red team operations without touching the host's system crontab.**

The LazyOwn framework includes a native **cron scheduling for automated red team operations** capability that operates entirely within its interactive shell. This internal scheduler, implemented in the main [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py) file, allows operators to delay command execution using standard HH:MM syntax while maintaining session persistence. Unlike traditional system cron jobs that write to disk, LazyOwn's approach uses in-memory Python threading to trigger payloads, making it ideal for stealthy, time-delayed post-exploitation activities.

## Architecture of LazyOwn's Internal Cron Scheduler

### Core Implementation in lazyown.py

The scheduling logic resides in the `do_cron` method within [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py) (lines 18954-18997). This method parses the input format `cron HH:MM command [args]`, converts the time string using `datetime.strptime`, and calculates the delay interval until the target execution time. If the specified time has already passed, the system automatically adds one day using `timedelta(days=1)` to schedule the command for the next occurrence.

### Threading and cmd2 Integration

LazyOwn leverages the **cmd2** framework for its interactive shell infrastructure. The `do_cron` command is decorated with `@cmd2.with_category` to group it under miscellaneous commands, ensuring discoverability through the built-in help system. Execution relies on Python's `threading.Timer`, which fires the scheduled command in a background thread without blocking the interactive shell, allowing operators to continue their session while awaiting payload execution.

## Scheduling Red Team Operations with Cron Syntax

### Basic Time-Delayed Execution

To schedule a single red team operation, use the `cron` command followed by the 24-hour time format and the LazyOwn command you wish to execute. The system calculates the exact delay and confirms the scheduling.

```bash

# Schedule a PsExec lateral movement operation for 02:30 AM

cron 02:30 run_psexec target=10.0.0.5 payload=evil.exe

```

The shell responds with confirmation: `[+] Command scheduled for: 02:30`. If the current time is past 02:30, the operation automatically schedules for the next day's early morning.

### Chaining Multiple Scheduled Operations

Operators can queue sequential red team activities by issuing multiple `cron` commands with staggered timestamps. This enables automated attack chains where reconnaissance precedes exploitation.

```bash

# 01:00 AM - Network reconnaissance

cron 01:00 run_nmap -T4 -p- 10.0.0.0/24

# 02:00 AM - Credential harvesting

cron 02:00 run_mimikatzpy pass

```

Each command runs independently in its own thread, allowing overlapping operations if schedules coincide.

### Handling Complex Arguments and Quoting

When scheduling commands that require file paths or multiple arguments, the parser treats everything after the time specification as the complete command string. Use standard shell quoting for paths containing spaces or special characters.

```bash

# Schedule payload delivery with arguments

cron 23:45 run_psexec target=10.0.0.12 payload="C:\Temp\malicious.dll" args="-s"

```

The `do_cron` method passes this string directly to `self.onecmd`, ensuring exact command execution at the scheduled time.

## Enumerating Host-Level Cron Jobs

While LazyOwn's internal scheduler operates in memory, the framework also provides capabilities to inspect the target system's existing cron infrastructure. The **Venator** module ([`modules/venator.py`](https://github.com/grisuno/lazyown/blob/main/modules/venator.py), lines 474-483) includes functionality to enumerate user crontab entries, revealing persistence mechanisms or scheduled tasks established by other operators or system administrators.

```bash

# Enumerate existing system cron jobs

run_venator cron_jobs

```

This command parses the target's crontab files, providing visibility into scheduled operations without requiring you to write to disk yourself.

## Summary

- **LazyOwn's `do_cron` command** (lines 18954-18997 in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py)) provides native cron scheduling for automated red team operations using Python's `threading.Timer`.
- The scheduler accepts **HH:MM format** and automatically handles next-day scheduling if the specified time has passed, calculating delays with `datetime.strptime` and `timedelta`.
- Operations execute in **background threads** via `cmd2` framework integration, allowing the interactive shell to remain responsive while awaiting payload execution.
- The **Venator module** ([`modules/venator.py`](https://github.com/grisuno/lazyown/blob/main/modules/venator.py)) offers complementary host-level cron enumeration to inspect existing persistence mechanisms without disk writes.

## Frequently Asked Questions

### Does LazyOwn's cron scheduler persist after the shell exits?

No. The scheduler operates entirely in memory using Python's `threading.Timer`. If you exit the LazyOwn interactive shell, all pending scheduled commands are lost. For persistent scheduling, you would need to use the host's system cron or establish a persistence mechanism that restarts LazyOwn.

### Can I schedule multiple commands to run at the exact same time?

Yes. Each `cron` command creates an independent `threading.Timer` instance. You can queue multiple operations for the same HH:MM timestamp, and they will execute concurrently when the timer fires. The shell uses `self.onecmd` to dispatch each command, ensuring they run in parallel threads.

### What happens if the target time format is invalid?

The `do_cron` method validates the time format using `datetime.strptime` with the `%H:%M` pattern. If the input does not match the expected HH:MM format (e.g., missing colon, invalid hours/minutes), the parser raises a `ValueError`, and the shell prints an error message via `print_error` without scheduling the command.

### Is there a way to list or cancel scheduled cron jobs in LazyOwn?

Currently, the implementation in [`lazyown.py`](https://github.com/grisuno/lazyown/blob/main/lazyown.py) (lines 18954-18997) does not expose a command to list active timers or cancel pending jobs. Once a command is scheduled with `threading.Timer`, it runs autonomously unless the shell process terminates. Operators should track scheduled times manually or implement wrapper scripts that log pending operations to external files.