My Brand New CTF Environment

It has been awhile since my last post due to time commitments but I’m hoping to make time again in my schedule to do so once again. I had been preparing to make a post about a CTF challenge for a recent event. I thought instead since I have recently began changing my CTF playing environment, I would make a post about the new setup. Originally I was using VMware products and Virtual Machines (VM). I’m transitioning to a Vagrant, VirtualBox and Chef setup now.

Why make the transition?
Consistency and time, these are the reasons why I was looking for a environment to use while playing in wargames and CTF events. When I was required to rebuild my VM’s for any given reason, I found the consistency of the build wasn’t great because I would forget to include something. The time spent troubleshooting and setting up the VM was annoying as well. A very high level view of my process is the following.

  • build the virtual machines
  • Install  and configure required packages and software on the machine
  • And for redundancy I would create snapshots of the VM each step of the way (a fresh install, after first update, etc.)

With Vagrant, I download the instance and then use Chef Solo to configure the instance. This means that the time is spent setting up a cookbook and the recipes for Chef to use. The brilliant part about this is many instances can use the same cookbook with minor tweaks that might be needed. Further more the time investment is quite high initially but investment drops off quickly, compared to VMware which has a more constant medium to high investment.

For a little conclusion of my decision process, the VMware build had a very high time commitment because of the building time and the consistency is low. Vargant has a very high initial time requirement when developing and testing the cookbook, but that time commitment reduces to very low after the initial cookbook is configured. And the consistency is extremely high.

Setting up Vagrant with an instance and Chef
Note: I am installing vagrant on Ubuntu 14.04 Linux host.

The .deb packages of vagrant can be downloaded from the Vagrant website.

$ dpkg -i vagrant_1.7.2_x86_64.deb
Selecting previously unselected package vagrant.
(Reading database ... 164494 files and directories currently installed.)
Preparing to unpack vagrant_1.7.2_x86_64.deb ...
Unpacking vagrant (1:1.7.2) ...
Setting up vagrant (1:1.7.2) ...

To initialise the current location as the place you will be using vagrant from, we use the “vagrant init” command.

$ vagrant init
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`` for more information on using Vagrant.

This will have created the “Vagrantfile” file in the current directory, this file defines the configuration of the Vagrant instance. To describe how the file operates comments have been included. An outline of what how I would like to setup my Vagrant follows:

  • I want to use a Ubuntu 14.04 x86-64
  • Setup basic port forwarding
  • I want to use my CTF-cookbook I’m developing
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 # All Vagrant configuration is done here. The most common configuration
 # options are documented and commented below. For a complete reference,
 # please see the online documentation at

 # Every Vagrant virtual environment requires a box to build off of. = "ubuntu/trusty64"

 # The url from where the '' box will be fetched if it
 # doesn't already exist on the user's system.
 config.vm.box_url = ""

 # Create a forwarded port mapping which allows access to a specific port
 # within the machine from a port on the host machine. In the example below,
 # accessing "localhost:8080" will access port 80 on the guest machine. :forwarded_port, guest: 80, host: 8080

 # Create a private network, which allows host-only access to the machine
 # using a specific IP.
 # :private_network, ip: ""

 # Create a public network, which generally matched to bridged network.
 # Bridged networks make the machine appear as another physical device on
 # your network.
 # :public_network

 # If true, then any SSH connections made will enable agent forwarding.
 # Default value: false
 # config.ssh.forward_agent = true

 # Share an additional folder to the guest VM. The first argument is
 # the path on the host to the actual folder. The second argument is
 # the path on the guest to mount the folder. And the optional third
 # argument is a set of non-required options.
 # config.vm.synced_folder "../data", "/vagrant_data"

 # Provider-specific configuration so you can fine-tune various
 # backing providers for Vagrant. These expose provider-specific options.
 # Example for VirtualBox:
 # config.vm.provider :virtualbox do |vb|
 # # Don't boot with headless mode
 # vb.gui = true
 # # Use VBoxManage to customize the VM. For example to change memory:
 # vb.customize ["modifyvm", :id, "--memory", "1024"]
 # end
 # View the documentation for the provider you're using for more
 # information on available options.

 # Enable provisioning with chef solo, specifying a cookbooks path, roles
 # path, and data_bags path (all relative to this Vagrantfile), and adding
 # some recipes and/or roles.
 config.vm.provision :chef_solo do |chef|
  chef.cookbooks_path = "../../Chef/CTF-Cookbook"
  #chef.roles_path = "../../Chef/CTF-Cookbook/roles"
  #chef.data_bags_path = "../../Chef/CTF-Cookbook/data_bags"
  chef.add_recipe "default"
  #chef.add_role "web"

  # # You may also specify custom JSON attributes:
  # chef.json = { :mysql_password => "foo" }

The lines in the configuration that are our focus and a brief explanation.

  • = “ubuntu/trusty64” – This tells Vagrant what instance we want to use.
  • config.vm.box_url = “” – If the instance we want to use isn’t found on the system, it will be downloaded from the URL provided.
  • :forwarded_port, guest: 80, host: 8080 – Port forwards TCP port 80 from the Vagrant instance to TCP port 8080 on the host system.
  • chef.cookbooks_path = “../../Chef/” – Tells Vagrant where to find the cookbook to use.
  • chef.add_recipe “CTF-Cookbook” – From the cookbook being used, tells Vagrant what recipe to use.

Setting up Creating a cookbook and a recipe

It’s time to create the cookbook that will be used by the Vagrant instance. This requires, the Chef package to be installed which can be installed by using most software packages in Linux.

$ apt-get install chef

Once installed the knife command can be used to create cookbooks.

$ knife cookbook create CTF-Cookbook
WARNING: No knife configuration file found
** Creating cookbook CTF-Cookbook
** Creating README for cookbook: CTF-Cookbook
** Creating CHANGELOG for cookbook: CTF-Cookbook
** Creating metadata for cookbook: CTF-Cookbook
$ sudo ls -lh /var/chef/cookbooks/
total 4K
drwxr-xr-x 10 root root 4.0K Feb 23 02:24 CTF-Cookbook

The cookbook comes with a bunch of directories and files, but what do they all mean?

tree ../../Chef/CTF-Cookbook/
├── attributes
│   └── default.rb
├── definitions
├── files
│   └── default
│   └──
├── libraries
├── metadata.rb
├── providers
├── recipes
│   └── default.rb
├── resources
└── templates
 └── default
  • Attributes – Attributes define the settings for Chef.
  • Files – The files directory within the cookbook contains any static files that are needed by the cookbook e.g. software packages, etc.
  • Templates – Templates are similar to files, but they are not static. This is where the attributes are commonly used. Template files end with the .erb extension because they contain Ruby.
  • Metadata.rb – This is to manage metadata about a package, such as the package, a description, etc.
  • Recipes – The recipe directory is the main focus of a cookbook. A cookbook can contain more than one recipe or reference outside recipes.
  • The other directories (definitions, libraries, providers and resources) are not necessary for general usage.

Below is a real basic recipe to demonstrate the cookbook is correctly working with Vagrant. The default recipe will place the BASH script into the /tmp directory but only if the file does not already exist.

cookbook_file "" do
path "/tmp/"
mode "0711"
action :create_if_missing

Finally to turn the instance on, gain access to the instance and verify that the recipe has worked correctly.

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'ubuntu/trusty64'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Fixed port collision for 22 => 2222. Now on port 2200.
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2200 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Mounting shared folders...
[default] -- /vagrant
[default] -- /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[default] Running provisioner: chef_solo...
Generating chef JSON and uploading...
Running chef-solo...
stdin: is not a tty
[2015-04-04T03:53:30+00:00] INFO: Forking chef instance to converge...
[2015-04-04T03:53:30+00:00] INFO: *** Chef 11.8.2 ***
[2015-04-04T03:53:30+00:00] INFO: Chef-client pid: 1549
[2015-04-04T03:53:30+00:00] INFO: Setting the run_list to ["recipe[CTF-Cookbook]"] from JSON
[2015-04-04T03:53:30+00:00] INFO: Run List is 
] [2015-04-04T03:53:30+00:00] INFO: Run List expands to [CTF-Cookbook] [2015-04-04T03:53:30+00:00] INFO: Starting Chef Run for vagrant-ubuntu-trusty-64 [2015-04-04T03:53:30+00:00] INFO: Running start handlers [2015-04-04T03:53:30+00:00] INFO: Start handlers complete. [2015-04-04T03:53:30+00:00] INFO: cookbook_file[] created file /tmp/ [2015-04-04T03:53:30+00:00] INFO: cookbook_file[] updated file contents /tmp/ [2015-04-04T03:53:30+00:00] INFO: Chef Run complete in 0.031937375 seconds [2015-04-04T03:53:30+00:00] INFO: Running report handlers [2015-04-04T03:53:30+00:00] INFO: Report handlers complete [2015-04-04T03:53:30+00:00] INFO: Forking chef instance to converge... $ vagrant ssh Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-43-generic x86_64) * Documentation: System information as of Sat Apr 4 03:53:42 UTC 2015 System load: 0.37 Processes: 88 Usage of /: 2.8% of 39.34GB Users logged in: 0 Memory usage: 19% IP address for eth0: Swap usage: 0% Graph this data and manage this system at: Get cloud support with Ubuntu Advantage Cloud Guest: 0 packages can be updated. 0 updates are security updates. vagrant@vagrant-ubuntu-trusty-64:~$ ls -lh /tmp/ total 32K -rwx--x--x 1 root root 27K Apr 4 04:05 drwxr-xr-x 3 vagrant root 4.0K Apr 4 03:53 vagrant-chef-1

As show from the above output, the Vagrant instance was successfully provisioned and access is gained. And finally the cookbook was verified that it was executed successfully as well.

The CTF-Cookbook can be found here on my GitHub:

The project is an ongoing and will continue be updated.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s