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 + + + + +