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

Add a base64 ARCH_CMD encoder #18807

Closed

Conversation

zeroSteiner
Copy link
Contributor

This adds a new encoder module that leverages base64 encoding to escape bad characters in ARCH_CMD payloads for the Linux and UNIX platforms. It aims to consolidate the way in which modules have been doing it by automatically identifying the decoding binary, or allowing the user to specify it themselves.

Testing

  • Use an ARCH_CMD payload module in msfconsole
  • Generate the payload with one or more bad characters that will trigger the encoding
  • See that the encoder works and the payload executes

modules/encoders/cmd/base64.rb Outdated Show resolved Hide resolved
if (state.badchars.bytes & '>()/|-&'.bytes).empty?
base64_decoder = '(which base64 >/dev/null && base64 -d || which openssl >/dev/null && openssl enc -base64 -d)'
else
base64_decoder = 'base64 -d'
Copy link
Contributor

Choose a reason for hiding this comment

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

If we want to support OSX, --decode would be a safer fallback default flag.

Copy link
Contributor

Choose a reason for hiding this comment

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

Apparently BusyBox base64 is the opposite: -d is supported but --decode is not.

https://boxmatrix.info/wiki/Property:base64_(bbcmd)

Copy link
Contributor

Choose a reason for hiding this comment

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

For busybox, busybox base64 -d can be used to tell it apart from coreutils' busybox.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a few additional platforms including OSX. Now when base64 is selected the (|) characters need to be allowed so it can automatically use either -d or --decode, otherwise it'll fail with an EncodignError. The encoder doesn't know the payload platform, so it can't be determined based on that. Informing the encoder of the payload platform could be useful, but seems out of scope for this.

I also added base64-long and base64-short as options for using -d and --decode respectively. That should cover all of the bases, so long as the user knows what they're targeting.

lib/msf/core/encoder.rb Outdated Show resolved Hide resolved
@cdelafuente-r7 cdelafuente-r7 self-assigned this Feb 9, 2024
@zeroSteiner zeroSteiner force-pushed the feat/mod/encoder/cmd-base64 branch from 2b07436 to e24ebf6 Compare February 9, 2024 22:04
modules/encoders/cmd/base64.rb Outdated Show resolved Hide resolved
if (state.badchars.bytes & '>()/|-&'.bytes).empty?
base64_decoder = '(which base64 >/dev/null && base64 -d || which openssl >/dev/null && openssl enc -base64 -d)'
else
base64_decoder = 'base64 -d'
Copy link
Contributor

Choose a reason for hiding this comment

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

For busybox, busybox base64 -d can be used to tell it apart from coreutils' busybox.

modules/encoders/cmd/base64.rb Outdated Show resolved Hide resolved
base64_decoder = 'openssl enc -base64 -d'
else
# find a decoder at runtime if we can use the necessary characters
if (state.badchars.bytes & '>()/|-&'.bytes).empty?
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't something like this be more clear/maintainable:

base64_decoder = '(which base64 >/dev/null && base64 -d || which openssl >/dev/null && openssl enc -base64 -d)'
if (state.badchars.bytes & base64_decode.to_a.uniq.to_s.bytes).empty?
  base64_decoder = 'base64 -d'
end

modules/encoders/cmd/base64.rb Outdated Show resolved Hide resolved
@cdelafuente-r7
Copy link
Contributor

Thanks @zeroSteiner ! It looks good to me. I tested every generated payloads on Linux (Debian) and Mac OS X and it works as expected. I'll go ahead and land it.

@cdelafuente-r7 cdelafuente-r7 added the rn-modules release notes for new or majorly enhanced modules label Feb 13, 2024
cdelafuente-r7 added a commit that referenced this pull request Feb 13, 2024
@cdelafuente-r7
Copy link
Contributor

Release Notes

This adds a new encoder module that leverages base64 encoding to escape bad characters in ARCH_CMD payloads for the Linux and UNIX platforms.

@zeroSteiner zeroSteiner force-pushed the feat/mod/encoder/cmd-base64 branch from be1b7ba to 1cd5b70 Compare February 13, 2024 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module rn-modules release notes for new or majorly enhanced modules
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants