Skip to content

About

A platform built on open-source software to assist with the development and delivery of realistic cyber security tabletop exercises

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 

Repository files navigation

RIPPLE (Realistic Incident Platform for Practice, Learning and Exercises)

This repository contains the build instructions for creating a single standalone platform that is design to host websites and resources for conducting cyber security tabletop exercises.

0. Assumptions

  • You have a fresh Ubuntu Server 24.04 install with sudo access.
  • Static IP 192.168.1.100 (swap in your own throughout).
  • Hostname ripple.
  • A Wi-Fi access point / switch connected to the box, with the AP handing out this server's IP as the DNS server.

1. Installation

Below are a set of instructions to build the platform from scratch. As time permits, this repo will be expanded to include additional features and code to run on the platform itself.

2. Base packages

sudo apt install bind9 nginx apache2 mysql-server unzip

3. Docker installation

sudo su -

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt update
apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Test the install:

docker run hello-world

4. Reverse proxy split (Nginx in front of Apache)

sudo vi /etc/apache2/ports.conf

Change Listen 80 to an unused port (this example uses 8181):

Listen 8181

<IfModule ssl_module>
     Listen 443
</IfModule>

<IfModule mod_gnutls.c>
     Listen 443
</IfModule>
sudo vi /etc/apache2/sites-enabled/000-default.conf

Update the first line to match:

<VirtualHost *:8181>

Restart apache

sudo systemctl restart apache2

5. DNS (Bind9)

sudo mkdir /etc/bind/zones
sudo vi /etc/bind/zones/db.local

Zone contents (adjust hostname/IP to your own):

$TTL 3D
$ORIGIN local.
local. IN SOA ripple.local. hostmaster.local. (
    2026070201 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)
    NS ripple.local.
    MX 10 mail.local.
localhost A 127.0.0.1
ripple A 192.168.1.100
mail A 192.168.1.100
cyberchef A 192.168.1.100
ctf A 192.168.1.100
fakebook A 192.168.1.100
cert A 192.168.1.100
why A 192.168.1.100
things A 192.168.1.100

6. CyberChef (static site)

Visit https://gchq.github.io/CyberChef/ to obtain the latest version

sudo wget https://gchq.github.io/CyberChef/CyberChef_v10.19.4.zip
sha256sum CyberChef_v10.19.4.zip

Move files into the right folder for serving

cd /var/www/html/
sudo mkdir cyberchef.local
sudo cp ~/CyberChef_v10.19.4.zip ./cyberchef.local/
cd cyberchef.local
sudo unzip CyberChef_v10.19.4.zip
sudo rm CyberChef_v10.19.4.zip
sudo mv CyberChef_v10.19.4.html ./index.html

Nginx site config:

cd /etc/nginx/sites-available/
sudo vi cyberchef.local
server {
        listen 80;
        listen [::]:80;

        root /var/www/html/cyberchef.local;

        index index.html index.htm index.nginx-debian.html;

        server_name cyberchef.local;

        location / {
                  try_files $uri $uri/ =404;
        }
}

Enable the site:

cd ../sites-enabled/
sudo ln -s /etc/nginx/sites-available/cyberchef.local ./cyberchef.local

Test and restart:

sudo nginx -t
sudo systemctl restart nginx bind9

Visit http://cyberchef.local.

7. CTFd (Docker container)

cd ~
sudo git clone https://github.com/CTFd/CTFd.git
cd CTFd/
sudo head -c 64 /dev/urandom > .ctfd_secret_key

Edit the compose file:

sudo vi docker-compose.yml

Under the nginx service, change the port mapping from:

ports:
  - 80:80

to:

ports:
  - "8000:80"

Bring the stack up:

sudo docker compose up --detach

Reverse proxy for ctf.local:

sudo vi /etc/nginx/sites-available/ctf.local
server {
        listen 80;
        listen [::]:80;

        server_name ctf.local;

        location / {
                proxy_pass http://127.0.0.1:8000;
        }
}

Enable and restart:

sudo ln -s /etc/nginx/sites-available/ctf.local /etc/nginx/sites-enabled/ctf.local
sudo nginx -t
sudo systemctl restart nginx bind9

Visit http://ctf.local.

8. Email: Postfix

sudo apt install postfix

Choose Internet Site or Local only at the mail-config prompt (Local only is fine if you never need this box to talk to the outside world) and set the hostname (example: intramail.local - add this to DNS as covered in section 4).

sudo vi /etc/postfix/main.cf

Change:

inet_interfaces = all

Add:

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

smtpd_sasl_auth_enable = yes
smtpd_sasl_auth_type = dovecot
smtpd_sasl_path = private/auth

virtual_mailbox_domains = /etc/postfix/virtual_mailbox_domains
virtual_transport = lmtp:unix:private/dovecot/lmtp
virtual_mailbox_base = /var/mail/vhosts

Virtual domains:

sudo vi /etc/postfix/virtual_mailbox_domains
example1.local #example1.local
example2.local #example2.local
sudo postmap /etc/postfix/virtual_mailbox_domains

Re-run postmap any time this file changes.

Enable submission:

sudo vi /etc/postfix/master.cf

Uncomment:

submission inet n        -       y      -      -     smtpd

9. Email: Dovecot

sudo apt install dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd

Mail location:

sudo vi /etc/dovecot/conf.d/10-mail.conf

Change:

mail_location = mbox:~/mail:INBOX=/var/mail/%u

to:

mail_location = maildir:/var/mail/vhosts/%d/%n

Create vhost folders (repeat per domain) and the vmail user:

sudo mkdir -p /var/mail/vhosts/example.local
sudo groupadd -g 5000 vmail
sudo useradd -r -g vmail -u 5000 vmail -d /var/mail/vhosts -c "Virtual mail user"
sudo chown -R vmail:vmail /var/mail/vhosts/

Enable IMAP/POP3:

sudo vi /etc/dovecot/conf.d/10-master.conf
...
inet_listener imap {
    port = 143
}
...
inet_listener pop3 {
    port = 110
}
...

Enable LMTP - find:

...
service lmtp {
   unix_listener lmtp {
     #mode = 0666
   }
   #inet_listener lmtp {
     #address =
     #port =
   #}
}
...

Change to:

...
service lmtp {
   unix_listener /var/spool/postfix/private/dovecot-lmtp {
     mode = 0600
     user = postfix
     group = postfix
   }
}
...

Enable Postfix SMTP-AUTH - find:

...
#unix_listener /var/spool/postfix/private/auth {
#  mode = 0666
#}
...

Change to:

unix_listener /var/spool/postfix/private/auth {
  mode = 0666
  user = postfix
  group = postfix
}

Auth settings:

sudo vi /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = no
auth_mechanisms = plain login

Comment out:

#!include auth-system.conf.ext

Uncomment:

!include auth-passwdfile.conf.ext

Passdb/userdb config:

sudo vi /etc/dovecot/conf.d/auth-passwdfile.conf.ext
passdb {
  driver = passwd-file
  args = scheme=PLAIN username_format=%u /etc/dovecot/dovecot-users
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

User/password file:

sudo vi /etc/dovecot/dovecot-users
admin@example.local:{plain}password
info@example.local:{plain}password
admin@example2.local:{plain}password

Passwords are stored in plaintext here - acceptable only because this is an isolated, offline training box. Not recommended to use this in any sort of production environment.

10. Email: Roundcube webmail

sudo apt install -y php-mysql php-mbstring php-bcmath php-zip php-curl php-xml php-fpm
sudo apt install -y roundcube

During install, select Yes to configure a database, choose MySQL, and set/note a DB password.

DNS entry:

sudo vi /etc/bind/zones/db.local
intramail.local A 192.168.1.100

Nginx site:

sudo vi /etc/nginx/sites-available/intramail.local
server {
       listen 80;
       listen [::]:80;

       server_name intramail.local;

       root /var/lib/roundcube;
       index index.html index.htm index.php;

       location / {
                try_files $uri $uri/ =404;
       }

       location ~ \.php$ {
                 include snippets/fastcgi-php.conf;
                 fastcgi_pass unix:/run/php/php8.3-fpm.sock;
       }
}

Default host:

sudo vi /etc/roundcube/config.inc.php
$config['default_host'] = 'localhost';

Firewall + restart:

sudo ufw allow 25/tcp
sudo ufw allow 110/tcp
sudo ufw allow 143/tcp
sudo systemctl restart nginx apache2 bind9 dovecot postfix

Visit http://intramail.local.

11. WordPress site(s)

wget https://wordpress.org/latest.zip
sudo mkdir /var/www/html/example.local

DNS entry:

sudo vi /etc/bind/zones/db.local
example.local A 192.168.1.100

Nginx site:

sudo vi /etc/nginx/sites-available/example.local
server {
       listen 80;
       listen [::]:80;

        server_name example.local;

        root /var/www/html/example.local;
        index index.html index.htm index.php;

        location / {
                 try_files $uri $uri/ =404;
        }

        location ~ \.php$ {
                 include snippets/fastcgi-php.conf;
                 fastcgi_pass unix:/run/php/php8.3-fpm.sock;
       }
}

Deploy WordPress files:

cp ~/latest.zip /var/www/html/example.local/
cd /var/www/html/example.local/
unzip latest.zip
mv ./wordpress/* ./
rm -r ./wordpress
rm latest.zip

Database:

sudo mysql
CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE example_local;
GRANT ALL PRIVILEGES ON example_local.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

wp-config:

cp /var/www/html/example.local/wp-config-sample.php /var/www/html/example.local/wp-config.php
vi /var/www/html/example.local/wp-config.php
define( 'DB_NAME', 'example_local' );
define( 'DB_USER', 'example_user' );
define( 'DB_PASSWORD', 'password' );

Repeat this whole section for each team/site you need.

Finally, fix ownership across the web root:

sudo chown -R www-data:www-data /var/www/html

12. Summary

At the end of this, you should have a platform that is able to serve website content and a work email system that can be used between participants when running an exercise.

About

A platform built on open-source software to assist with the development and delivery of realistic cyber security tabletop exercises

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors