Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Burp extension persistence #19821

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open

Burp extension persistence #19821

wants to merge 11 commits into from

Conversation

h00die
Copy link
Contributor

@h00die h00die commented Jan 21, 2025

This PR creates a new persistence mechanism via Burp extension. Install the extension in burp and it gives you back a shell every burp start. Tested against windows and linux targets. You can either compile the java on your system (build action via gradle) or use the bytecode (precompiled). Instructions for creating the bytecode independently are included in the data/exploits/burp_extension folder.

#19592 persistence

Will need to be updated after #19815

Issues

Issue 1: Automating Install (not a blocker)

Currently installing the extension is manual due to several issues. As per my conversation with PortSwigger there are several candidates for automating the install which all fail:

  1. create a user config file that contains the extension listed and enabled. Loading it via "Load from configuration file" during GUI startup, however that doesn't seem to load the extension.
  2. create a user config file that contains the extension listed and enabled. apply it from the GUI after startup, this works but the user has to do it which defeats the purpose
  3. Run headless and load the user config file, which loads the extension, but doesn't apply it to the "Default" config so that it loads on the next start. Possibly due to using kill/pkill to stop the headless instance
  4. find some magical "default" config file and set the extension to load from there. I haven't been able to find this file.

PortSwigger said they haven't tested this, but will add it to their feature request list.

As a workaround, if the user specifies a user config file, it will be poisoned with our malicious burp extension.

Issue 2: Java Target

When attempting to use the Java target with a payload that seems right (payload/java/shell/reverse_tcp, payload/java/meterpreter/reverse_tcp) the following error is encountered:

[msf](Jobs:2 Agents:1) exploit(multi/local/burp_extension_persistence) > exploit
[-] Exploit failed: java/shell/reverse_tcp: All encoders failed to encode.
[*] Exploit completed, but no session was created.

No idea why. Either I can cut this target and shrink the java extension, or hopefully someone knows why this is happening

Verification

  • get a shell on linux/windows
  • use module
  • it will write the extension to the writableDir
  • load it manually via burp
  • get a shell back

],
'DefaultOptions' => {
# 25hrs, you know, just in case the user doesn't open Burp for a while
'WfsDelay' => 90_000,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 25*60*60 would be a tad clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can/will be addressed in the persistence PR

modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
Comment on lines +136 to +142
malicious_extension = {
'errors' => 'ui',
'extension_file' => extension_location,
'extension_type' => 'java',
'loaded' => true,
'name' => extension_name,
'output' => 'ui'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't the errors and the output be explicitly set to ignore/null/… to ensure that weird logs won't show up in Burp?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The options are "Output to system console", "Save to file", and "Show in UI". I selected "Show in UI" as I've added text to be displayed to the user to make it seem like all is well.
image

Right now if you use a Java payload it outputs more with XXX stuff, once we decide how to either fix the Java payload implementation, or remove it, I'll clean that up.

modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
@h00die h00die added docs and removed needs-docs labels Jan 21, 2025
@rapid7 rapid7 deleted a comment from github-actions bot Jan 21, 2025
@h00die h00die mentioned this pull request Jan 21, 2025
88 tasks
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved

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

whoami
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of implementing this to obtain the username, why not just expand the HOME environment variable for the specific platform? That would have a few advantages including not running whoami on linux, and allowing the rest of the code to work when the user running burp is a service account. IIRC Burp can be run in a headless mode as part of a CI/CD pipeline in which case the operating account may not be a normal user with their home directory under /home.

modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
modules/exploits/multi/local/burp_extension_persistence.rb Outdated Show resolved Hide resolved
Comment on lines +397 to +407
# 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

# 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 &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should look to configure this module to run passively in the background so it's not just sleeping for 25 hours.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is partially a chicken and egg problem. The past persistence modules I've written have all been:

        'Stance' => Msf::Exploit::Stance::Passive,
        'Passive' => true,

with 'WfsDelay' => 90_000,.

However, this will need to be synced with #19815 . Which will standardize a lot of this. Would prefer to leave it as is for consistence, then pick it up in the follow-up PR.

@dledda-r7 dledda-r7 self-assigned this Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waiting on Contributor
Development

Successfully merging this pull request may close these issues.

5 participants