So a collegue approached us about using Ansible to quickly build a CTF (Capture-The-Flag) virtual machine. They had heard about Ansible from their DevOps Team, but their Internal Security Team wanted to setup their own boxes (without DevOps) for the purpose of having a small inter-company CTF challenge where none of the players necessarily helped build the CTF infrastructure.

There were a few requirements, but to keep things simple we will give one example challenge from the provided scope.

Challenge Scope

  • Linux VM
  • Graphic X login or RDP varient
  • Local privilege escalation

Ansible Solution

Now we did not want to make it too easy for the Sysadmins/DevOps Team, so we thought about some of the lesser known protocols.

  • Classic sudo privilege escalation

Our solution:


Vagrant.configure(2) do |config|

base_network = "172.16.31"

  config.vm.define :secretservice do |secretservice|
    config.vm.provider "virtualbox" do |v| = "secretservice"
      v.gui = true
      v.memory = 1024
    end = "ubuntu/trusty64" :private_network, ip: "#{base_network}.103"
    secretservice.vm.provision "ansible" do |ansible|
      ansible.playbook = "Secretservice.yml"


Remember: Generate your own root hash (or randomly generate one!)

- hosts: secretservice
  remote_user: vagrant
  become: yes
      - enter / randomise your password hashes here 
      password: "$6$3sADYmmQeBo.rYjt$r60iT54qwCTYKIQfiF108DekgwrqvG4YXi2y2gcE7/uaQv449t9GEJh0thDj1WX6nHXWYuQoLTg1XnlF8I/3W."
      password2: "$6$AUiE****UctlKjCZWfl6QbEcm."

    - name: Set hostname
      hostname: name=secretservice

    - name: test basic user account creation
      user: name=secretservice password={{ password }}

    - name: change root account
      user: name=root password={{ password2 }}

    - name: Fix sudo
      become: yes
      shell: echo "%secretservice ALL=(ALL) /usr/sbin/mini-httpd" >> /etc/sudoers

    - name: Update cache and install gdm
          - gdm
        state: present
        update_cache: yes

    - name: Update cache and install destkop
          - ubuntu-desktop
          - apache2
          - mini-httpd
          - gnome-terminal
        state: present

    - name: Create autologin script
      template: src=lightdm.conf dest=/etc/lightdm/lightdm.conf

    - name: Start GDM
      service: name=lightdm state=restarted

    - name: Start httpd
      service: name=apache2 state=restarted



Using the Solution

Our Proof-Of-Concept is using Vagrant and Virtualbox, but it is trivial to adapt to ESXi.

To install Virtualbox and Vagrant, use your native package manager, or look at the links below:

Once you have copied the files to a local folder, starting the machine is as simple as

vagrant up

It only takes a few minutes, and you can watch the challenge build steps in the commandline.

Once you’ve finished with the machine, to remove the virtual machine from your inventory and disk, issue the following command:

vagrant destroy


Ansible (and Vagrant) are useful tools in the DevOps world. With security teams having to act dynamically in cloud environments, whether setting up test boxes, or medium-large red-team infrastructures, Ansible is an excellent tool to help speed up and replicate common Operating System builds.

It is also useful to store Infrastructure-as-Code, no longer are we eating up bandwidth transporting large usb drives/drives containing large VM images, the size of the challenge falls into a few KB (of course this is larger on disk when the vm is running), but it makes transfer and storage costs far cheaper.

Also if we want to make new challenges, using the above code as a template we can easily adapt. We can create new challeges in minutes.

Share on: