diff --git a/.gitignore b/.gitignore index 79668441e..8f2732f8c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ lib/resources/images/scenario rgloader .ruby-version vendor/** +plans/ diff --git a/modules/generators/content/maltrail_data/maltrail_data.pp b/modules/generators/content/maltrail_data/maltrail_data.pp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/content/maltrail_data/manifests/.no_puppet b/modules/generators/content/maltrail_data/manifests/.no_puppet new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/content/maltrail_data/secgen_local/local.rb b/modules/generators/content/maltrail_data/secgen_local/local.rb new file mode 100644 index 000000000..5fe7037fa --- /dev/null +++ b/modules/generators/content/maltrail_data/secgen_local/local.rb @@ -0,0 +1,282 @@ +#!/usr/bin/ruby +require_relative '../../../../../lib/objects/local_string_generator.rb' +require 'json' +require 'securerandom' + +class MalTrailDataGenerator < StringGenerator + attr_accessor :data_volume + attr_accessor :embedded_flag + + # TLDs for malicious-looking domains + TLDS = ['.com', '.net', '.xyz', '.ru', '.cn', '.info', '.pw', '.top', '.ml', '.tk'] + + # Prefixes that look suspicious + PREFIXES = ['update', 'cdn', 'api', 'mail', 'secure', 'auth', 'login', 'download', + 'verify', 'account', 'admin', 'panel', 'config', 'backup', 'db'] + + # Suffixes that suggest malicious intent + SUFFIXES = ['malware', 'bot', 'trojan', 'crypto', 'apt', 'c2', 'shell', 'payload', + ' exploit', 'hack', 'ransom', 'miner', 'phish', 'spam', 'ddos'] + + # Threat types with references + THREAT_TYPES = [ + { info: 'known_attacker', ref: 'abuseipdb' }, + { info: 'malware_c2', ref: '(static)' }, + { info: 'trojan', ref: 'malc0de' }, + { info: 'cryptominer', ref: 'minerchk' }, + { info: 'phishing', ref: 'openphish' }, + { info: 'apt', ref: '(static)' }, + { info: 'spam', ref: 'spamhaus' }, + { info: 'botnet', ref: 'zeustracker' }, + { info: 'ransomware', ref: '(static)' }, + { info: 'c2', ref: 'emergingthreats' } + ] + + # Common ports for different traffic types + PORTS = { + http: [80, 8080, 8000, 8888], + https: [443, 8443], + dns: [53], + ssh: [22], + ftp: [21], + smtp: [25, 587], + custom: [4444, 5555, 6666, 7777, 9999] + } + + def initialize + super + self.module_name = 'MalTrail Randomized Data Generator' + self.data_volume = 'medium' + self.embedded_flag = '' + end + + def get_options_array + super + [ + ['--data_volume', GetoptLong::REQUIRED_ARGUMENT], + ['--embedded_flag', GetoptLong::REQUIRED_ARGUMENT] + ] + end + + def process_options(opt, arg) + super + case opt + when '--data_volume' + self.data_volume = arg + when '--embedded_flag' + self.embedded_flag = arg + end + end + + def generate + # Validate and normalize data_volume + volume = normalize_volume(self.data_volume) + + # Determine event count based on volume + event_count = get_event_count(volume) + + # Generate events + events = [] + (1..event_count).each do + events << generate_random_event + end + + # Generate the flag event + flag_event = generate_flag_event if self.embedded_flag && !self.embedded_flag.empty? + + # Add flag event to events (inserted at a random position) + if flag_event + insert_position = rand(events.length) + events.insert(insert_position, flag_event) + end + + # Generate custom trails + custom_trails = generate_custom_trails(events, flag_event) + + # Build output structure + output = { + events: events, + custom_trails: custom_trails + } + + output[:flag_event] = flag_event if flag_event + + # Output as JSON + self.outputs << JSON.generate(output) + end + + private + + def normalize_volume(volume) + case volume.to_s.downcase + when 'low' + 'low' + when 'high' + 'high' + else + 'medium' + end + end + + def get_event_count(volume) + case volume + when 'low' + rand(10..20) + when 'high' + rand(500..1000) + else # medium + rand(50..100) + end + end + + def generate_random_event + threat = THREAT_TYPES.sample + src_ip = random_private_ip + dst_ip = random_public_ip + proto = ['TCP', 'UDP'].sample + port_type = proto == 'TCP' ? [:http, :https, :ssh, :custom].sample : [:dns, :custom].sample + dst_port = PORTS[port_type].sample + src_port = rand(1024..65535) + + # Determine trail type and trail value + trail_type = rand(0..2) == 0 ? 'URL' : (rand(0..1) == 0 ? 'IP' : 'DNS') + trail = case trail_type + when 'IP' + dst_ip + when 'DNS' + random_malicious_domain + when 'URL' + random_malicious_url(dst_ip) + end + + { + timestamp: generate_timestamp, + sensor: 'maltrail', + src_ip: src_ip, + src_port: src_port, + dst_ip: dst_ip, + dst_port: dst_port, + proto: proto, + trail_type: trail_type, + trail: trail, + trail_info: threat[:info], + reference: threat[:ref] + } + end + + def generate_flag_event + return nil if self.embedded_flag.empty? + + # Create a suspicious-looking domain that contains the flag + flag_domain = "update.flag.local" + + { + timestamp: generate_timestamp, + sensor: 'maltrail', + src_ip: random_private_ip, + src_port: rand(1024..65535), + dst_ip: '8.8.8.8', # Google DNS - makes it look like a DNS query + dst_port: 53, + proto: 'UDP', + trail_type: 'DNS', + trail: flag_domain, + trail_info: self.embedded_flag, + reference: 'flag' + } + end + + def generate_custom_trails(events, flag_event) + trails = [] + + # Add header comment + trails << '# Custom trails for training scenario' + trails << '# Malicious IPs' + + # Extract unique IPs from events + ip_trails = events.select { |e| e[:trail_type] == 'IP' } + .map { |e| "#{e[:trail]} #{e[:trail_info]} #{e[:reference]}" } + .uniq + .take(5) # Limit to 5 IP entries + trails.concat(ip_trails) + + trails << '# Malicious domains' + + # Extract unique domains from events + dns_trails = events.select { |e| e[:trail_type] == 'DNS' } + .map { |e| "#{e[:trail]} #{e[:trail_info]} #{e[:reference]}" } + .uniq + .take(5) # Limit to 5 domain entries + trails.concat(dns_trails) + + # Add flag trail if present + if flag_event + trails << '# CTF flag trail' + trails << "#{flag_event[:trail]} #{flag_event[:trail_info]} #{flag_event[:reference]}" + end + + trails << '# Malicious URLs' + + # Extract unique URLs from events + url_trails = events.select { |e| e[:trail_type] == 'URL' } + .map { |e| "#{e[:trail]} #{e[:trail_info]} #{e[:reference]}" } + .uniq + .take(3) # Limit to 3 URL entries + trails.concat(url_trails) + + trails + end + + def random_private_ip + case rand(3) + when 0 + "192.168.#{rand(1..254)}.#{rand(1..254)}" + when 1 + "10.#{rand(0..255)}.#{rand(0..255)}.#{rand(1..254)}" + else + "172.#{rand(16..31)}.#{rand(0..255)}.#{rand(1..254)}" + end + end + + def random_public_ip + loop do + first = rand(1..223) + # Skip private ranges + next if first == 10 + next if first == 127 # Loopback + next if first == 172 && rand(0..255) >= 16 && rand(0..255) <= 31 + next if first == 192 && rand(0..255) == 168 + + return "#{first}.#{rand(0..255)}.#{rand(0..255)}.#{rand(1..254)}" + end + end + + def random_malicious_domain + prefix = PREFIXES.sample + suffix = SUFFIXES.sample + tld = TLDS.sample + number = rand(100..999) + + "#{prefix}-#{suffix}#{number}#{tld}" + end + + def random_malicious_url(ip = nil) + domain = random_malicious_domain + paths = ['update.exe', 'download/payload.zip', 'install.msi', 'setup.bin', + 'config.jar', 'update.sh', 'backup.tar.gz'] + + if rand(2) == 0 && ip + "http://#{ip}/#{paths.sample}" + else + "http://#{domain}/#{paths.sample}" + end + end + + def generate_timestamp + # Generate a timestamp within the last 24 hours + now = Time.now + random_seconds = rand(0..86400) # Within last 24 hours + time = now - random_seconds + time.strftime('%Y-%m-%d %H:%M:%S.%6N') + end +end + +MalTrailDataGenerator.new.run \ No newline at end of file diff --git a/modules/generators/content/maltrail_data/secgen_metadata.xml b/modules/generators/content/maltrail_data/secgen_metadata.xml new file mode 100644 index 000000000..96496041e --- /dev/null +++ b/modules/generators/content/maltrail_data/secgen_metadata.xml @@ -0,0 +1,27 @@ + + + MalTrail Randomized Data Generator + Rosie Fletcher + MIT + Generates randomized MalTrail threat events and custom trails for security training scenarios. Creates synthetic IPs, domains, URLs, and malware indicators. Output includes a flag event that embeds a CTF flag within the threat data. + + maltrail_data + local_calculation + linux + + data_volume + embedded_flag + + + medium + + + + + + + generated_strings + + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/files/generate_custom_trails.rb b/modules/vulnerabilities/unix/http/maltrail_rce/files/generate_custom_trails.rb new file mode 100644 index 000000000..d38cafe7f --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/files/generate_custom_trails.rb @@ -0,0 +1,64 @@ +#!/usr/bin/env ruby +# Script to generate MalTrail custom trails file from JSON data +# Called by Puppet during provisioning +require 'json' + +# Read JSON input from command line argument +if ARGV.empty? + puts "Usage: #{$0} ''" + exit 1 +end + +begin + # Parse the JSON data + data = JSON.parse(ARGV[0]) + + # Generate custom trails content + trails = [] + + # Add header comment + trails << "# Custom trails for SecGen training scenario" + trails << "# Generated automatically by Puppet provisioning" + trails << "#" + trails << "# Malicious IPs" + + # Check for flag trail first + flag_trail = data['custom_trails'].find { |t| t.include?('update.flag.local') } + + # Add IP-based trails + data['custom_trails'].each do |trail_entry| + # Check if it's an IP (starts with a number) + if trail_entry =~ /^\d/ + trails << trail_entry + end + end + + trails << "#" + trails << "# Malicious domains" + + # Add domain-based trails + data['custom_trails'].each do |trail_entry| + # Check if it's a domain (starts with a letter) + if trail_entry =~ /^[a-z]/i && !trail_entry.include?('update.flag.local') + trails << trail_entry + end + end + + # Insert flag trail in the middle of the file if found + if flag_trail + insert_position = (trails.length / 2).to_i + trails.insert(insert_position, "#") + trails.insert(insert_position + 1, "# SUSPICIOUS DOMAIN") + trails.insert(insert_position + 2, flag_trail) + end + + # Output the trails content + puts trails.join("\n") + +rescue JSON::ParserError => e + STDERR.puts "Error parsing JSON: #{e.message}" + exit 1 +rescue => e + STDERR.puts "Error: #{e.message}" + exit 1 +end \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/files/generate_maltrail_log.rb b/modules/vulnerabilities/unix/http/maltrail_rce/files/generate_maltrail_log.rb new file mode 100644 index 000000000..0d7ddb874 --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/files/generate_maltrail_log.rb @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +# Script to generate MalTrail log entries from JSON data +# Called by Puppet during provisioning +require 'json' + +# Read JSON input from command line argument +if ARGV.empty? + puts "Usage: #{$0} ''" + exit 1 +end + +begin + # Parse the JSON data + data = JSON.parse(ARGV[0]) + + # Generate log entries + log_lines = [] + + data['events'].each do |event| + # Format: "timestamp" sensor src_ip src_port dst_ip dst_port proto trail_type trail trail_info reference + log_line = "\"#{event['timestamp']}\" #{event['sensor']} #{event['src_ip']} #{event['src_port']} #{event['dst_ip']} #{event['dst_port']} #{event['proto']} #{event['trail_type']} #{event['trail']} #{event['trail_info']} #{event['reference']}" + log_lines << log_line + end + + # Output the log content + puts log_lines.join("\n") + +rescue JSON::ParserError => e + STDERR.puts "Error parsing JSON: #{e.message}" + exit 1 +rescue => e + STDERR.puts "Error: #{e.message}" + exit 1 +end \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/files/maltrail-0.52.tar.gz b/modules/vulnerabilities/unix/http/maltrail_rce/files/maltrail-0.52.tar.gz new file mode 100644 index 000000000..65a6f577b Binary files /dev/null and b/modules/vulnerabilities/unix/http/maltrail_rce/files/maltrail-0.52.tar.gz differ diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/maltrail_rce.pp b/modules/vulnerabilities/unix/http/maltrail_rce/maltrail_rce.pp new file mode 100644 index 000000000..c6021731b --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/maltrail_rce.pp @@ -0,0 +1,5 @@ +# MalTrail <= 0.54 - Unauthenticated RCE (CVE-2025-34073) +# https://github.com/stamparm/maltrail/issues/19146 +include maltrail_rce::install +include maltrail_rce::config +include maltrail_rce::service diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/manifests/config.pp b/modules/vulnerabilities/unix/http/maltrail_rce/manifests/config.pp new file mode 100644 index 000000000..5307598cb --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/manifests/config.pp @@ -0,0 +1,87 @@ +class maltrail_rce::config { + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + $modulename = 'maltrail_rce' + $user = $secgen_parameters['unix_username'][0] + $leaked_filenames = $secgen_parameters['leaked_filenames'] + $strings_to_leak = $secgen_parameters['strings_to_leak'] + + # MalTrail data from generator (JSON format, base64 encoded) + $maltrail_data_json_array = $secgen_parameters['maltrail_data'] + $maltrail_data_json = $maltrail_data_json_array[0] + + Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ] } + + # Leak flag files to user's home directory for exploitation verification (Flag 1) + ::secgen_functions::leak_files { 'maltrail-flag-leak': + storage_directory => "/home/${user}", + leaked_filenames => $leaked_filenames, + strings_to_leak => $strings_to_leak, + owner => $user, + mode => '0600', + leaked_from => 'maltrail_rce', + } + + # Deploy Ruby helper scripts for generating MalTrail data + file { '/tmp/generate_maltrail_log.rb': + ensure => file, + source => "puppet:///modules/${modulename}/generate_maltrail_log.rb", + owner => 'root', + group => 'root', + mode => '0755', + } + + file { '/tmp/generate_custom_trails.rb': + ensure => file, + source => "puppet:///modules/${modulename}/generate_custom_trails.rb", + owner => 'root', + group => 'root', + mode => '0755', + } + + # Create MalTrail log directory + file { '/var/log/maltrail': + ensure => directory, + owner => $user, + group => $user, + mode => '0755', + require => User[$user], + } + + # Create custom trails directory + file { '/opt/maltrail/trails': + ensure => directory, + owner => $user, + group => $user, + mode => '0755', + } + + # Generate today's log file with synthetic events using Ruby script + # The script reads from maltrail_data_json and generates properly formatted log entries + exec { 'generate-maltrail-log': + command => "ruby /tmp/generate_maltrail_log.rb '${maltrail_data_json}' > /var/log/maltrail/$(date +%Y-%m-%d).log", + unless => "test -f /var/log/maltrail/$(date +%Y-%m-%d).log", + require => [File['/var/log/maltrail'], File['/tmp/generate_maltrail_log.rb']], + } + + # Set permissions on log file + exec { 'set-maltrail-log-permissions': + command => "chown ${user}:${user} /var/log/maltrail/*.log && chmod 644 /var/log/maltrail/*.log", + require => Exec['generate-maltrail-log'], + } + + # Generate custom trails file using Ruby script + exec { 'generate-custom-trails': + command => "ruby /tmp/generate_custom_trails.rb '${maltrail_data_json}' > /opt/maltrail/trails/custom.txt", + unless => 'test -f /opt/maltrail/trails/custom.txt', + require => [File['/opt/maltrail/trails'], File['/tmp/generate_custom_trails.rb']], + } + + # Set permissions on custom trails file + file { '/opt/maltrail/trails/custom.txt': + ensure => file, + owner => $user, + group => $user, + mode => '0644', + require => Exec['generate-custom-trails'], + } +} diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/manifests/install.pp b/modules/vulnerabilities/unix/http/maltrail_rce/manifests/install.pp new file mode 100644 index 000000000..5f49406b0 --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/manifests/install.pp @@ -0,0 +1,73 @@ +class maltrail_rce::install { + Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ] } + $modulename = 'maltrail_rce' + + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + $port = $secgen_parameters['port'][0] + $user = $secgen_parameters['unix_username'][0] + $user_home = "/home/${user}" + + # MalTrail tarball name (single file, no splitting needed) + $tarball = 'maltrail-0.52.tar.gz' + + # Create dedicated user for MalTrail service + user { $user: + ensure => present, + home => $user_home, + managehome => true, + shell => '/bin/bash', + } + + group { $user: + ensure => present, + } + + ensure_packages(['python3', 'python3-pip', 'python3-dev', 'libpcap-dev', 'build-essential', 'python3-pcapy']) + + # Create user home directory with proper permissions + file { $user_home: + ensure => directory, + owner => $user, + group => $user, + mode => '0750', + require => User[$user], + } + + # OFFLINE: Copy MalTrail tarball + file { "/tmp/${tarball}": + ensure => file, + source => "puppet:///modules/${modulename}/${tarball}", + } + + # Extract MalTrail tarball (maltrail-0.52 directory format) + exec { 'extract-maltrail': + cwd => '/tmp', + command => "tar -xzf ${tarball}", + creates => '/opt/maltrail', + require => File["/tmp/${tarball}"], + } + + # Move MalTrail to installation directory + exec { 'install-maltrail': + cwd => '/tmp', + command => 'mv maltrail-0.53 /opt/maltrail', + creates => '/opt/maltrail', + require => Exec['extract-maltrail'], + } + + # Set ownership + exec { 'chown-maltrail': + command => "chown -R ${user}:${user} /opt/maltrail", + require => Exec['install-maltrail'], + } + + # Copy custom configuration file from template + file { '/opt/maltrail/maltrail.conf': + ensure => file, + content => template("${modulename}/maltrail.conf.erb"), + owner => $user, + group => $user, + mode => '0644', + require => Exec['install-maltrail'], + } +} diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/manifests/service.pp b/modules/vulnerabilities/unix/http/maltrail_rce/manifests/service.pp new file mode 100644 index 000000000..43a9ca6f7 --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/manifests/service.pp @@ -0,0 +1,28 @@ +# Service management for MalTrail +class maltrail_rce::service { + require maltrail_rce::config + + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + $user = $secgen_parameters['unix_username'][0] + + Exec { path => [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ] } + + file { '/etc/systemd/system/maltrail.service': + content => template('maltrail_rce/maltrail.service.erb'), + owner => 'root', + group => 'root', + mode => '0644', + } + + exec { 'daemon-reload': + command => 'systemctl daemon-reload', + refreshonly => true, + subscribe => File['/etc/systemd/system/maltrail.service'], + } + + service { 'maltrail': + ensure => running, + enable => true, + require => [File['/etc/systemd/system/maltrail.service'], Exec['daemon-reload']], + } +} diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/secgen_metadata.xml b/modules/vulnerabilities/unix/http/maltrail_rce/secgen_metadata.xml new file mode 100644 index 000000000..054d619f5 --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/secgen_metadata.xml @@ -0,0 +1,85 @@ + + + + MalTrail RCE + Rosie Fletcher + MIT + MalTrail versions <= 0.52 contain an unauthenticated command injection vulnerability + in the login endpoint. A remote attacker can execute arbitrary operating system commands + via the 'username' parameter in a POST request to the /login endpoint. This occurs + due to unsafe handling of user-supplied input passed to subprocess.check_output() in + core/http.py, allowing injection of shell metacharacters. Exploitation does not require + authentication and commands are executed with the privileges of the MalTrail server process. + + This module creates a dual-flag CTF challenge: Flag 1 is found via RCE exploitation and + file system access, while Flag 2 is hidden within MalTrail's threat data and discovered + via web UI analysis. + + http + user_rwx + remote + linux + low + + port + strings_to_leak + leaked_filenames + unix_username + maltrail_data + + + + 8338 + + + + + + + + + + + + + + + + + medium + + + + + + + + + CVE-2025-34073 + 10 + AV:N/AC:L/Au:N/C:C/I:C/A:C + https://github.com/stamparm/maltrail + https://github.com/stamparm/maltrail/issues/19146 + https://nvd.nist.gov/vuln/detail/CVE-2025-34073 + https://vulncheck.com/advisories/stamparm-maltrail-rce + MalTrail + MIT + + + + server-side misconfiguration and vulnerable components + + + EXPLOITATION + EXPLOITATION FRAMEWORKS + + + CVEs and CWEs + + + Penetration Testing - Software Tools + Penetration Testing - Active Penetration + + \ No newline at end of file diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/templates/maltrail.conf.erb b/modules/vulnerabilities/unix/http/maltrail_rce/templates/maltrail.conf.erb new file mode 100644 index 000000000..5da09824e --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/templates/maltrail.conf.erb @@ -0,0 +1,12 @@ +# [Server] +HTTP_ADDRESS 0.0.0.0 +HTTP_PORT <%= @port %> +USE_SSL false +LOG_DIR /var/log/maltrail +UPDATE_PERIOD 24 +# USERS disabled for passwordless access to web UI + +# [Sensor] +MONITOR_INTERFACE any +CAPTURE_BUFFER 1GB +USE_MULTIPROCESSING false diff --git a/modules/vulnerabilities/unix/http/maltrail_rce/templates/maltrail.service.erb b/modules/vulnerabilities/unix/http/maltrail_rce/templates/maltrail.service.erb new file mode 100644 index 000000000..875a9de83 --- /dev/null +++ b/modules/vulnerabilities/unix/http/maltrail_rce/templates/maltrail.service.erb @@ -0,0 +1,15 @@ +[Unit] +Description=MalTrail Server v0.52 (Vulnerable to CVE-2025-34073) +After=network.target + +[Service] +Type=simple +User=<%= @user %> +Group=<%= @user %> +WorkingDirectory=/opt/maltrail +ExecStart=/usr/bin/python3 /opt/maltrail/server.py -c /opt/maltrail/maltrail.conf +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target diff --git a/scenarios/ctf/off_the_trail.xml b/scenarios/ctf/off_the_trail.xml new file mode 100644 index 000000000..639a58e70 --- /dev/null +++ b/scenarios/ctf/off_the_trail.xml @@ -0,0 +1,135 @@ + + + + + Off the trail + Rosie Fletcher + A multi-stage penetration testing exercise where students: + 1. Exploit CVE-2025-34073 (MalTrail RCE) for initial access + 2. Find the first flag via file system exploration + 3. Analyze MalTrail's web interface to discover a second hidden flag embedded in threat data + This lab teaches the full attack lifecycle from reconnaissance to root compromise. + + + ctf + attack-ctf + pwn-ctf + low + + + + EXPLOITATION + EXPLOITATION FRAMEWORKS + + + PENETRATION TESTING - SOFTWARE TOOLS + PENETRATION TESTING - ACTIVE PENETRATION + + + + + Elevated privileges + + + + + kill chains + + + cyber kill chain + + + + + Injection vulnerabilities + Command injection + + + + 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 + + + + + + + + + + + + + + + + + maltrail_flag + + + + + + + + + + + + + + IP_addresses + + + + + spoiler_admin_pass + + + + +