User/Get-HawkUserHiddenRule.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
# Looks for hidden inbox rules in the mailbox
Function Get-HawkUserHiddenRule {
    param
    (
        [Parameter(Mandatory = $true)]
        [array]$UserPrincipalName,
        $EWSCredential
    
    )
    
    Test-EXOConnection

    # Verify our UPN input
    [array]$UserArray = Test-UserObject -ToTest $UserPrincipalName
    
    # Process thru each object recieved
    foreach ($Object in $UserArray) 
    {

        # Push the UPN into $user for ease of use
        $user = $object.UserPrincipalName

        # Determine if the email address is null or empty
        # If it is write a warning and skip the rest of the script
        [string]$EmailAddress = (get-mailbox $user).primarysmtpaddress
        if ([string]::IsNullOrEmpty($EmailAddress))
        { 
            Write-Warning "No SMTP Address found Skipping"
            Return $null
        }

        # If we don't have a credential object then ask for creds and push them into the global scope
        if ($null -eq $EWSCredential)
        {
            Out-LogFile "Please provide credentials that have impersonation rights to the mailbox you are looking to check"
            $EWSCredential =  Get-Credential
        }

        # Import the EWS Managed API
        if (Test-Path 'C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll')
        {
            Out-LogFile "Ews Managed API Found"
        }
        else 
        { 
            Write-Error "Please install EWS Managed API 2.2 `nhttp://www.microsoft.com/en-us/download/details.aspx?id=42951" -ErrorAction Stop
        }
        
        # Import the EWS managed API dll
        Import-Module 'C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll'

        # Set up the EWS Connection
        Write-Host ("Setting up connection for " + $emailaddress) -ForegroundColor Green
        $exchService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_Sp1)
        $exchService.Credentials = New-Object  Microsoft.Exchange.WebServices.Data.WebCredentials($EWSCredential.username,$EWSCredential.GetNetworkCredential().password);

        # If we have the global URL for EWS then we just use it since it should all be the same in this case
        # Otherwise we need to get it via autodiscover
        if ($null -eq $EWSUrl){
            $exchService.AutodiscoverUrl($emailAddress,{$true})
            $exchService.url | Set-Variable -name EWSUrl -Scope Global
        }
        else {
            $exchService.url = $EWSUrl
        }

        # Set the connection up for impersonation so that we log into the mailbox we want not the one we have creds for
        $exchService.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$emailAddress);

        # Add the Anchor mailbox to the http header
        $exchService.HttpHeaders.Add("X-AnchorMailbox",[string]$EmailAddress)

        # Using the exchService object connect and retrieve all inbox rules
        # This DID NOT work since it didn't pull back the hidden rule
        # $rules = $exchService.GetInboxRules($EmailAddress)

        # Bind to the inbox folder
        try 
        {
            $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)    
        }
        catch 
        {
            # If we don't have rights to impersonate throw in the log file and provide a better error
            if ($_.Exception.innerexception -like "*permission to impersonate*")
            {
                Out-LogFile ("[ERROR] - Account does not have Impersonation Rights on Mailbox: " + $EmailAddress)
                Out-LogFile "https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-configure-impersonation:"
                Write-Error $_ -ErrorAction Stop
            }
            # If it isn't an impersonation error throw it and stop
            else 
            {
                Write-Error $_ -ErrorAction Stop
            }
        }        

        # Setup the search
        $SearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, "IPM.Rule.Version2.Message")
        $Itemview = new-object Microsoft.Exchange.WebServices.Data.ItemView(500)
        $ItemView.Traversal = [Microsoft.Exchange.Webservices.Data.ItemTraversal]::Associated

        # Create our property set to view
        $PR_RULE_MSG_NAME = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EC,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String) 
        $PR_RULE_MSG_PROVIDER = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EB,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
        $PR_PRIORITY = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x0026,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer)
        $psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IDOnly,$PR_RULE_MSG_NAME,$PR_RULE_MSG_PROVIDER,$PR_PRIORITY)

        # Add the property set to the item view
        $ItemView.PropertySet = $psPropset

        # Do the search and return the items
        $ruleResults = $inbox.finditems($SearchFilter,$Itemview)

        # Null our return arry and populate it
        [array]$ruleArray = $null
        $ruleResults | ForEach-Object {[array]$ruleArray += $_}

        # Set our found flag to false
        $FoundHidden = $false

        # Check each rule
        Foreach ($rule in $ruleArray)
        {
            
            # If either Rule Name or Rule Provider are null then we need to flag it and return the priority of the rule
            if ([string]::IsNullOrEmpty($rule.ExtendedProperties[0].value) -or [string]::IsNullOrEmpty($rule.ExtendedProperties[1].value))
            {
                $priority = ($rule.ExtendedProperties | Where-Object {$_.propertydefinition.tag -eq 38}).value
                Out-LogFile ("Possible Hidden Rule found in mailbox: " + $EmailAddress + " -- Rule Priority: " + $priority) -notice
                $rule | Out-MultipleFileType -FilePrefix "EWS_Inbox_rule" -csv -user $user -append
                $FoundHidden = $true
            }
            
        }
        
        # If the flag wasn't set then we need to log that we didn't find any hidden rules for th euser
        if ($FoundHidden -eq $false)
        {
            Out-LogFile ("No Hidden rules found for mailbox: " + $EmailAddress)
        }

        # return $ruleArray
    }
    
    <#
  
 .SYNOPSIS
 Pulls inbox rules for the specified user using EWS.
 
 .DESCRIPTION
 Pulls inbox rules for the specified user using EWS.
 Searches the resulting rules looking for "hidden" rules.
 
 .PARAMETER UserPrincipalName
 Single UPN of a user, commans seperated list of UPNs, or array of objects that contain UPNs.
 
 .PARAMETER EWSCredential
 Credentials of a user that can impersonate the target user/users.
 Gather using (get-credential)
 Does NOT work with MFA protected accounts at this time.
 
 .OUTPUTS
  
 File: _Investigate.txt
 Path: \
 Description: Adds any hidden rules found here to be investigated
 
 File: EWS_Inbox_rule.csv
 Path: \<User>
 Description: Inbox rules that were found with EWS
  
 .EXAMPLE
 
 Get-HawkUserHiddenRules -UserPrincipalName user@contoso.com -EWSCredential (get-credential)
 
 Searches user@contoso.com looking for hidden inbox rules using the provided credentials
 
 .EXAMPLE
 
 Get-HawkUserHiddenRules -UserPrincipalName (get-mailbox -Filter {Customattribute1 -eq "C-level"})
 
 Looks for hidding inbox rules for all users who have "C-Level" set in CustomAttribute1
 
  
 #>



}