Home Get Started Step 02

Clone the playbooks and build a target

All playbooks are in one GitHub repo. Clone the repo. Run the base setup on the VM from Step 01. Make a snapshot with the name clean-base. Then pick a CVE and run one command. Ansible changes the machine into the vulnerable target. When you finish, restore the snapshot. Then pick another CVE.

Time
~25 min
Difficulty
Easy
Runs on
Host machine
Ends with
A running target
01

Clone the repository

One repo has everything. It has the base setup and all CVE playbooks. Clone it on the host.

Terminal · host
git clone https://github.com/askarlabs/TheHackingMachine.git
cd TheHackingMachine
02

What's in the repo

Look at the layout before you change anything. You must know five things.

Repository layout
ansible/
├── ansible.cfg            # sets the default inventory
├── inventory/
│   └── hosts.ini          # the only file you edit by hand
├── base/
│   ├── bootstrap.yml      # shared setup for the base image
│   └── verify.yml         # confirms the base image is healthy
├── cve/
│   ├── cve-2021-41773.yml # one playbook per CVE
│   ├── cve-2025-32023.yml
│   ├── ...
│   └── files/             # service files and configs used by the playbooks
└── templates/             # writeup template for new CVEs
  • inventory/hosts.ini: tells Ansible where your machine is. You set it in the next section.
  • base/: has the shared setup and the check for the base image. You use both in the steps below.
  • cve/: has one file for each CVE. The file name is the CVE ID.
  • cve/files/: has the static files that a playbook copies to the machine. Do not change them unless you add a new playbook.
  • ansible.cfg: sets the default inventory. This is why you can leave out -i when you run a playbook.
03

Point the inventory at the machine

The inventory file (inventory/hosts.ini) tells Ansible where the machine is. It is the only file you edit by hand. It uses the address and the SSH key from Step 01.

Change the IP address. 10.0.0.7 below is only an example. Replace it with the host-only address you wrote down in Step 01. If it is wrong, Ansible cannot connect.

inventory/hosts.ini
[machine]
thehackingmachine ansible_host=10.0.0.7

[machine:vars]
ansible_user=lab
ansible_password=lab
ansible_become_password=lab
ansible_ssh_private_key_file=~/.ssh/thehackingmachine
ansible_python_interpreter=/usr/bin/python3
04

Run the base provisioning playbook

One playbook installs the tools that all targets share. These are build tools, Python, and a local package mirror.

Terminal · host
ansible-playbook base/bootstrap.yml

The first run takes 8 to 12 minutes. Most of the time is for package downloads. If the playbook fails, run it again. It continues from the point of failure.

05

Snapshot it as clean-base

The snapshot lets you do each lab again from the same state. First, shut down the machine correctly. A snapshot of a running machine also saves the memory. It then restores more slowly.

Terminal · host
VBoxManage controlvm thehackingmachine acpipowerbutton
sleep 20
VBoxManage snapshot thehackingmachine take clean-base --description "Ubuntu 22.04.1 + base toolchain"

The name is important. Each reset command and playbook note uses the name clean-base.

06

Verify the base image

Do one check. It shows that the image is ready for a CVE playbook.

Terminal · host
VBoxManage snapshot thehackingmachine list | grep clean-base
VBoxManage startvm thehackingmachine
ansible-playbook base/verify.yml

You must see base image OK. Then you must see a snapshot list with clean-base. If you see both, the base image is complete. You do not need the installer again.

07

Pick a playbook

Each playbook installs one vulnerable product. It uses the exact version that the CVE affects. Show the list of playbooks. Or search for a product name. The library page has the same list. It also has tags for search.

Terminal · host
ls cve/
grep -ril "apache" cve/

This guide uses CVE-2021-41773. It affects Apache 2.4.49. The playbook is small. It builds in less than one minute. It is easy to check.

08

Run your first playbook

Make sure that the machine started from clean-base. If it did not, read Step 03. Then run the playbook that you picked.

Terminal · host
ansible-playbook cve/cve-2021-41773.yml

A good run ends with a recap that shows failed=0. Task names and numbers are different for each playbook. The steps are always the same. The playbook installs the vulnerable version. It sets the configuration. It starts the service.

Example output
PLAY [Build CVE-2021-41773 (Apache 2.4.49 path traversal) lab] 

TASK [Gathering Facts]
ok: [thehackingmachine]

TASK [Install build dependencies]
changed: [thehackingmachine]

TASK [Download vulnerable Apache httpd source]
changed: [thehackingmachine]

TASK [Extract Apache httpd source]
changed: [thehackingmachine]

TASK [Configure, build and install Apache httpd]
changed: [thehackingmachine] => (item=./configure --enable-cgi)
changed: [thehackingmachine] => (item=make -j2)
changed: [thehackingmachine] => (item=make install)

TASK [Set ServerName so apachectl doesn't warn/fail]
changed: [thehackingmachine]

TASK [Loosen the root Directory ACL (deliberately vulnerable setting)] 
changed: [thehackingmachine]

TASK [Install systemd unit for the vulnerable Apache instance]
changed: [thehackingmachine]

TASK [Flush handlers so systemd sees the new unit before starting it]

RUNNING HANDLER [reload systemd]
ok: [thehackingmachine]

TASK [Start and enable the vulnerable Apache service]
changed: [thehackingmachine]

TASK [Restart Apache so any config changes from this run are live]
changed: [thehackingmachine]

PLAY RECAP 
thehackingmachine: ok=11   changed=9    unreachable=0    failed=0    skipped=0    ignored=0 

Use one CVE at a time. Playbooks need a clean base. A second playbook on top of the first can leave packages with conflicting versions. Reset the machine between targets. Do not run playbooks one after the other.

09

Verify the target

Check from the host that the service is up. Do this before you use the target. Each playbook has a verify tag. The tag checks that the service is listening. It also checks that the service has the correct version. This is the same type of check as for the base image.

Terminal · host
curl -sI http://10.0.0.7/ | head -3
ansible-playbook cve/cve-2021-41773.yml --tags verify

The first command must show HTTP/1.1 200 OK. The second command must show target OK. If you see both, the machine is live at 10.0.0.7. It runs the version that the playbook needs.

Your lab machine is ready for your hacking practice. The target is up. Go ahead and start practicing. When you are done, Step 03 shows how to reset the machine for the next CVE.