diff --git a/modules/vulnerabilities/unix/http/raspap_rce/files/raspAP-webgui-2.8.7.tar.gz b/modules/vulnerabilities/unix/http/raspap_rce/files/raspAP-webgui-2.8.7.tar.gz
new file mode 100644
index 000000000..186e18be6
Binary files /dev/null and b/modules/vulnerabilities/unix/http/raspap_rce/files/raspAP-webgui-2.8.7.tar.gz differ
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/manifests/config.pp b/modules/vulnerabilities/unix/http/raspap_rce/manifests/config.pp
new file mode 100644
index 000000000..862160bce
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/manifests/config.pp
@@ -0,0 +1,90 @@
+# Class: raspap_rce::config
+# Configure RaspAP in its vulnerable state and set up the CTF challenge
+class raspap_rce::config {
+ Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ] }
+ $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file)
+ $port = $secgen_parameters['port'][0]
+ $strings_to_leak = $secgen_parameters['strings_to_leak']
+ $leaked_filenames = $secgen_parameters['leaked_filenames']
+ $strings_to_pre_leak = $secgen_parameters['strings_to_pre_leak']
+ $admin_password = $secgen_parameters['admin_password'][0]
+
+ $user = 'www-data'
+ $install_dir = '/var/www/raspap'
+
+ # Configure RaspAP - config.php must be in includes/ directory
+ # The vulnerable code does: require_once '../../includes/config.php'
+ file { "${install_dir}/includes/config.php":
+ ensure => file,
+ content => template('raspap_rce/config.php.erb'),
+ owner => $user,
+ group => $user,
+ mode => '0644',
+ require => Class['raspap_rce::install'],
+ }
+
+ # Create raspap.php in config directory (required by index.php)
+ file { "${install_dir}/config/raspap.php":
+ ensure => file,
+ content => template('raspap_rce/raspap.php.erb'),
+ owner => $user,
+ group => $user,
+ mode => '0644',
+ require => Class['raspap_rce::install'],
+ }
+
+ # Create raspap.auth file with bcrypt hashed admin password
+ # RaspAP expects: line 1 = username, line 2 = bcrypt hash
+ # htpasswd outputs username:hash format, so we extract and create separate lines
+ exec { 'create-raspap-auth':
+ command => "htpasswd -bcB /tmp/raspap_auth_temp admin '${admin_password}' && awk -F: '{print $1; print $2}' /tmp/raspap_auth_temp > ${install_dir}/config/raspap.auth && rm /tmp/raspap_auth_temp",
+ require => [Class['raspap_rce::install'], Package['apache2-utils']],
+ creates => "${install_dir}/config/raspap.auth",
+ }
+ -> file { "${install_dir}/config/raspap.auth":
+ owner => $user,
+ group => $user,
+ mode => '0644',
+ }
+
+ # Configure lighttpd
+ file { '/etc/lighttpd/lighttpd.conf':
+ ensure => file,
+ content => template('raspap_rce/lighttpd.conf.erb'),
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ notify => Service['lighttpd'],
+ }
+
+ # Create vulnerable OpenVPN configuration directory
+ exec { 'create-openvpn-dir':
+ command => 'mkdir -p /etc/openvpn/client',
+ creates => '/etc/openvpn/client',
+ }
+
+ # Create a dummy OpenVPN config for realism
+ file { '/etc/openvpn/client/example.ovpn':
+ ensure => file,
+ content => "# Dummy OpenVPN configuration for realism\n",
+ owner => 'root',
+ mode => '0644',
+ require => Exec['create-openvpn-dir'],
+ }
+
+ # Set log directory permissions
+ exec { 'set-log-perms':
+ command => 'chmod 755 /var/log/lighttpd',
+ require => Class['raspap_rce::install'],
+ }
+
+ # Leak flag files for students to find
+ ::secgen_functions::leak_files { 'raspap-file-leak':
+ storage_directory => '/var/www',
+ leaked_filenames => $leaked_filenames,
+ strings_to_leak => $strings_to_leak,
+ owner => $user,
+ mode => '0600',
+ leaked_from => 'raspap_rce',
+ }
+}
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/manifests/install.pp b/modules/vulnerabilities/unix/http/raspap_rce/manifests/install.pp
new file mode 100644
index 000000000..fc807cbda
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/manifests/install.pp
@@ -0,0 +1,79 @@
+# Class: raspap_rce::install
+# Install RaspAP v2.8.7 and all required dependencies
+# All packages are available in Debian 12 standard repositories
+class raspap_rce::install {
+ Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ] }
+ $user = 'www-data'
+ $install_dir = '/var/www/raspap'
+ $user_home = '/var/www'
+
+ # Install required packages (all available in Debian 12)
+ ensure_packages([
+ 'lighttpd',
+ 'php-cgi',
+ 'php-curl',
+ 'php-json',
+ 'php-mbstring',
+ 'php-xml',
+ 'php-sqlite3',
+ 'hostapd',
+ 'dnsmasq',
+ 'unzip',
+ 'apache2-utils' # for htpasswd (bcrypt password hashing)
+ ])
+
+ # Enable PHP in lighttpd
+ exec { 'enable-php-fastcgi':
+ command => 'lighttpd-enable-mod fastcgi-php',
+ require => Package['lighttpd', 'php-cgi'],
+ }
+
+ # Create installation directory
+ file { $install_dir:
+ ensure => directory,
+ owner => $user,
+ group => $user,
+ mode => '0755',
+ require => Package['lighttpd'],
+ }
+
+ # Copy RaspAP archive to the system
+ # Note: File is named with capital AP but is actually a ZIP archive
+ file { "${user_home}/raspAP-webgui-2.8.7.tar.gz":
+ source => 'puppet:///modules/raspap_rce/raspAP-webgui-2.8.7.tar.gz',
+ owner => $user,
+ mode => '0644',
+ require => Package['lighttpd'],
+ }
+
+ # Extract RaspAP archive (it's a ZIP file despite the .tar.gz extension)
+ # Note: GitHub archives extract to raspap-webgui-2.8.7 (with version number)
+ -> exec { 'extract-raspap':
+ cwd => $user_home,
+ command => 'unzip -o raspAP-webgui-2.8.7.tar.gz',
+ creates => "${user_home}/raspap-webgui-2.8.7",
+ require => Package['unzip'],
+ }
+
+ # Move RaspAP files to installation directory
+ -> exec { 'move-raspap':
+ cwd => $user_home,
+ command => "mv raspap-webgui-2.8.7/* ${install_dir}/",
+ creates => "${install_dir}/index.php",
+ }
+
+ # Set proper ownership
+ -> exec { 'set-raspap-permissions':
+ command => "chown -R ${user}:${user} ${install_dir}",
+ }
+
+ # Create necessary directories
+ -> exec { 'create-raspap-dirs':
+ command => "mkdir -p ${install_dir}/config ${install_dir}/tmp",
+ }
+
+ # Set permissions on config and tmp directories
+ -> exec { 'set-raspap-dir-permissions':
+ command => "chown ${user}:${user} ${install_dir}/config ${install_dir}/tmp",
+ }
+}
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/manifests/service.pp b/modules/vulnerabilities/unix/http/raspap_rce/manifests/service.pp
new file mode 100644
index 000000000..e27f5e154
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/manifests/service.pp
@@ -0,0 +1,12 @@
+# Class: raspap_rce::service
+# Start the lighttpd web server service
+class raspap_rce::service {
+ require raspap_rce::config
+ Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ] }
+
+ service { 'lighttpd':
+ ensure => running,
+ enable => true,
+ require => Class['raspap_rce::config'],
+ }
+}
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/raspap_rce.pp b/modules/vulnerabilities/unix/http/raspap_rce/raspap_rce.pp
new file mode 100644
index 000000000..897d16ffe
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/raspap_rce.pp
@@ -0,0 +1,3 @@
+include raspap_rce::install
+include raspap_rce::config
+include raspap_rce::service
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/secgen_metadata.xml b/modules/vulnerabilities/unix/http/raspap_rce/secgen_metadata.xml
new file mode 100644
index 000000000..316d583c4
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/secgen_metadata.xml
@@ -0,0 +1,85 @@
+
+
+
+ RaspAP Unauthenticated Command Injection
+ Rosie Fletcher
+ MIT
+
+ RaspAP versions 2.8.0 through 2.8.7 are vulnerable to unauthenticated
+ remote command execution via CVE-2022-39986. The vulnerability exists
+ in ajax/openvpn/del_ovpncfg.php due to insufficient input validation
+ on the cfg_id parameter, allowing attackers to inject arbitrary shell
+ commands. No authentication is required to exploit this vulnerability.
+
+ RaspAP is a web interface for managing wireless access points on
+ Raspberry Pi devices. This module installs RaspAP 2.8.7 in its
+ vulnerable configuration.
+
+
+ http
+ user_rwx
+ remote
+ linux
+ low
+
+ port
+ strings_to_leak
+ leaked_filenames
+ strings_to_pre_leak
+ admin_password
+
+
+ 80
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CVE-2022-39986
+ 9.8
+ https://nvd.nist.gov/vuln/detail/CVE-2022-39986
+ https://github.com/advisories/GHSA-7c28-wg7r-pg6f
+ https://github.com/tucommenceapousser/RaspAP-CVE-2022-39986-PoC
+ https://github.com/billz/raspap-webgui/
+
+ RaspAP Web GUI
+ GPL-3.0
+
+
+ update
+
+
+
+ server-side misconfiguration and vulnerable components
+ Command injection
+ Input validation
+
+
+ EXPLOITATION
+ EXPLOITATION FRAMEWORKS
+ Command Injection
+
+
+ CVEs and CWEs
+ CWE-78: OS Command Injection
+
+
+ PENETRATION TESTING - SOFTWARE TOOLS
+ PENETRATION TESTING - ACTIVE PENETRATION
+
+
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/templates/config.php.erb b/modules/vulnerabilities/unix/http/raspap_rce/templates/config.php.erb
new file mode 100644
index 000000000..f5290be6e
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/templates/config.php.erb
@@ -0,0 +1,56 @@
+
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/templates/lighttpd.conf.erb b/modules/vulnerabilities/unix/http/raspap_rce/templates/lighttpd.conf.erb
new file mode 100644
index 000000000..affda2cc3
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/templates/lighttpd.conf.erb
@@ -0,0 +1,67 @@
+# Lighttpd configuration for RaspAP
+# Configured for CVE-2022-39986 vulnerability module
+
+server.modules = (
+ "mod_access",
+ "mod_alias",
+ "mod_redirect",
+ "mod_rewrite",
+ "mod_fastcgi",
+ "mod_accesslog",
+)
+
+server.document-root = "/var/www/raspap"
+server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
+server.errorlog = "/var/log/lighttpd/error.log"
+server.pid-file = "/var/run/lighttpd.pid"
+server.username = "www-data"
+server.groupname = "www-data"
+server.port = <%= @port %>
+server.bind = "0.0.0.0"
+
+# PHP configuration
+fastcgi.server = (
+ ".php" => ((
+ "bin-path" => "/usr/bin/php-cgi",
+ "socket" => "/tmp/php.socket",
+ "max-procs" => 1,
+ "bin-environment" => (
+ "PHP_FCGI_CHILDREN" => "4",
+ "PHP_FCGI_MAX_REQUESTS" => "10000"
+ ),
+ "bin-copy-environment" => (
+ "PATH", "SHELL", "USER"
+ ),
+ "broken-scriptfilename" => "enable"
+ ))
+)
+
+# Static file caching
+static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
+
+# MIME types
+mimetype.assign = (
+ ".php" => "application/x-httpd-php",
+ ".html" => "text/html",
+ ".txt" => "text/plain",
+ ".jpg" => "image/jpeg",
+ ".png" => "image/png",
+ ".css" => "text/css",
+ ".js" => "application/javascript"
+)
+
+# Access log
+accesslog.filename = "/var/log/lighttpd/access.log"
+
+# Directory listing disabled
+dir-listing.activate = "disable"
+
+# Redirect root URL to index.php
+url.redirect = (
+ "^/$" => "/index.php"
+)
+
+# URL rewriting for RaspAP - exclude ajax endpoints to preserve vulnerability
+url.rewrite-if-not-file = (
+ "^/([^?]+)(\?.*)?$" => "/index.php?page=$1$2"
+)
diff --git a/modules/vulnerabilities/unix/http/raspap_rce/templates/raspap.php.erb b/modules/vulnerabilities/unix/http/raspap_rce/templates/raspap.php.erb
new file mode 100644
index 000000000..7e26b027f
--- /dev/null
+++ b/modules/vulnerabilities/unix/http/raspap_rce/templates/raspap.php.erb
@@ -0,0 +1,34 @@
+ 'admin',
+ 'admin_pass' => '' // Will be read from raspap.auth file
+ );
+
+ if (file_exists(RASPI_CONFIG . '/raspap.auth')) {
+ if ($auth_details = fopen(RASPI_CONFIG . '/raspap.auth', 'r')) {
+ $config['admin_user'] = trim(fgets($auth_details));
+ $config['admin_pass'] = trim(fgets($auth_details));
+ fclose($auth_details);
+ }
+ }
+ return $config;
+}
+
+// Theme setting
+define('RASPI_THEME', 'default');
+
+// Debug mode (disabled for CTF realism)
+define('RASPI_DEBUG', false);
+
+// Disable authentication for CTF (allows unauthenticated access to exploit CVE)
+define('RASPI_AUTH_ENABLED', false);
+?>
diff --git a/scenarios/ctf/easy_as_pi.xml b/scenarios/ctf/easy_as_pi.xml
new file mode 100644
index 000000000..46d208f10
--- /dev/null
+++ b/scenarios/ctf/easy_as_pi.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ Easy as Pi
+ Rosie Fletcher
+ Hack the RaspAP server from Kali. Exploit an unauthenticated command injection vulnerability to capture the flags.
+
+
+ ctf
+ attack-ctf
+ pwn-ctf
+ easy
+
+
+
+ server-side misconfiguration and vulnerable components
+ Command injection
+ Input validation
+
+
+ EXPLOITATION
+ EXPLOITATION FRAMEWORKS
+ Command Injection
+
+
+ CVEs and CWEs
+ CWE-78: OS Command Injection
+
+
+ PENETRATION TESTING - SOFTWARE TOOLS
+ PENETRATION TESTING - ACTIVE PENETRATION
+ PENETRATION TESTING - NETWORK MAPPING - RECONNAISSANCE
+
+
+ PENETRATION TESTING - NETWORK MAPPING - FINGERPRINTING
+ PENETRATION TESTING - NETWORK MAPPING - NMAP
+
+
+
+ kill chains
+
+
+ cyber kill chain
+
+
+
+ attack_vm
+
+
+
+
+ 172.16.0.2
+
+ 172.16.0.3
+
+
+
+
+ {"username":"kali","password":"kali","super_user":"true","strings_to_leak":[],"leaked_filenames":[]}
+
+
+
+
+
+ {"username":"kali","password":"kali","super_user":"true","strings_to_leak":[],"leaked_filenames":[]}
+
+
+ false
+
+
+
+
+
+
+
+
+ IP_addresses
+
+
+
+
+
+
+
+ spoiler_admin_pass
+
+
+
+
+
+ server
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IP_addresses
+
+
+
+
+ spoiler_admin_pass
+
+
+
+
+