Post

OverTheWire Bandit: Level 21 to Level 22

OverTheWire Bandit: Level 21 to Level 22

The Goal

A program is running automatically at regular intervals via cron. Find what it does and use it to get the password for bandit22.

What is Cron

Cron is a time-based job scheduler built into Linux. It runs commands automatically at specified times without any user interaction. You define tasks in a crontab file and cron executes them in the background on schedule.

What I Did

Navigated to /etc/cron.d/ where cron job configurations are stored:

1
2
3
bandit21@bandit:~$ cd /etc/cron.d/
bandit21@bandit:/etc/cron.d$ ls
behemoth4_cleanup  clean_tmp  cronjob_bandit22  cronjob_bandit23  cronjob_bandit24  e2scrub_all  leviathan5_cleanup  manpage3_resetpw_job  otw-tmp-dir

Read the bandit22 cron job:

1
2
3
bandit21@bandit:/etc/cron.d$ cat cronjob_bandit22
@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null

Two entries for the same script — @reboot runs it once when the server boots, * * * * * runs it every minute. The &> /dev/null discards all output so nothing is printed to any terminal.

Read the script itself:

1
2
3
4
bandit21@bandit:/etc/cron.d$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

The script does two things every minute:

  1. Sets the permissions on a file in /tmp to 644 — world readable
  2. Writes bandit22’s password into that file

Since the file is world readable, anyone can read it including bandit21:

1
2
bandit21@bandit:/tmp$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
RYVux2rHEm9tiXHmLFzuR7Vhx6AZQMEz

Understanding the Crontab Format

The five fields before the username define the schedule:

1
2
3
4
5
6
7
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh
│ │ │ │ │
│ │ │ │ └── day of week (0-7, 0 and 7 = Sunday)
│ │ │ └──── month (1-12)
│ │ └────── day of month (1-31)
│ └──────── hour (0-23)
└────────── minute (0-59)

* means every value for that field. So * * * * * runs every minute of every hour of every day.

Some examples:

  • 0 * * * * — every hour at minute 0
  • 0 9 * * * — every day at 9am
  • 0 9 * * 1 — every Monday at 9am
  • 30 6 1 * * — 6:30am on the 1st of every month

@reboot is a special keyword that runs the job once when the system starts, regardless of time.

What I Tried That Didn’t Work

Tried to list and navigate /tmp directly — permission denied. The /tmp directory itself was restricted so you can’t browse it with ls or find. But you can still read a specific file inside it if you know the exact path and the file has read permissions. The script set chmod 644 on the file which made it readable by everyone, so cat /tmp/filename worked even though listing the directory didn’t.

What I Learned

Cron jobs run as a specific user. The username in the crontab entry (bandit22) determines whose privileges the script runs with. This script runs as bandit22, which is why it can read /etc/bandit_pass/bandit22.

/etc/cron.d/ contains system-wide cron jobs. Individual user cron jobs live in /var/spool/cron/crontabs/. The /etc/cron.d/ directory is readable by all users — useful for reconnaissance when you have access to a system.

Cron jobs writing to world-readable files is a misconfiguration. If a privileged cron job writes sensitive data to a location other users can read, that data is exposed. This is a real-world finding in penetration tests.

You don’t need to list a directory to read a file in it. If you know the exact filename and the file has read permission, cat /path/to/file works regardless of whether you can ls the directory.

Commands Used

CommandWhat it did
ls /etc/cron.d/Found the cron job configurations
cat cronjob_bandit22Read the schedule and script path
cat /usr/bin/cronjob_bandit22.shRead what the script actually does
cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgvRead the password written by the cron job
This post is licensed under CC BY 4.0 by the author.