core/modules/monkeyhttpwebrequest/public/Invoke-MonkeyWebRequest.ps1
# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Function Invoke-MonkeyWebRequest{ <# .SYNOPSIS .DESCRIPTION .INPUTS .OUTPUTS .EXAMPLE .NOTES Author : Juan Garrido Twitter : @tr1ana File Name : Invoke-HttpWebRequest Version : 1.0 .LINK https://github.com/silverhack/monkey365 #> [CmdletBinding()] Param ( [Parameter(Mandatory=$True, position=0)] [System.Uri]$Url, [Parameter(Mandatory = $false, HelpMessage='HttpClient')] [System.Net.Http.HttpClient]$Client, [parameter(Mandatory=$False, HelpMessage='Request method')] [ValidateSet("GET","POST","PUT","HEAD")] [String]$Method = "GET", [parameter(Mandatory=$False, HelpMessage='Accept')] [Object[]]$Accept, [parameter(Mandatory=$False, HelpMessage='Content Type')] [String]$ContentType, [parameter(Mandatory=$False, HelpMessage='Referer')] [String]$Referer, [Parameter(Mandatory = $false, HelpMessage='Timeout threshold for request operations in timespan format')] [int32]$TimeOut = 120, [parameter(Mandatory=$False, HelpMessage='cookies')] [Object[]]$Cookies, [parameter(Mandatory=$False, HelpMessage='Cookie container')] [System.Net.CookieContainer]$CookieContainer, [parameter(Mandatory=$False, HelpMessage='user agent')] [String]$UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0", [parameter(Mandatory=$False, HelpMessage='Headers as hashtable')] [System.Collections.Hashtable]$Headers, [parameter(Mandatory=$False, HelpMessage='POST PUT data')] [String]$Data, [parameter(Mandatory=$False, HelpMessage='Allows autoredirect')] [int32]$MaxRedirections, [parameter(Mandatory=$False, HelpMessage='return RAW response')] [switch]$RawResponse, [parameter(Mandatory=$False, HelpMessage='Show response headers')] [switch]$ShowResponseHeaders, [parameter(Mandatory=$False, HelpMessage='Get bytes')] [switch]$GetBytes, [parameter(Mandatory=$False, HelpMessage='Disable SSL Verification')] [switch]$DisableSSLVerification, [parameter(Mandatory=$False, HelpMessage='Control redirects')] [bool]$AllowAutoRedirect = $True ) Begin{ $response = $null $Verbose = $False; $Debug = $False; $InformationAction = 'SilentlyContinue' if($PSBoundParameters.ContainsKey('Verbose') -and $PSBoundParameters.Verbose){ $Verbose = $True } if($PSBoundParameters.ContainsKey('Debug') -and $PSBoundParameters.Debug){ $DebugPreference = 'Continue' $Debug = $True } if($PSBoundParameters.ContainsKey('InformationAction')){ $InformationAction = $PSBoundParameters['InformationAction'] } if(!$PSBoundParameters.ContainsKey('Timeout')){ $_timeout = 120; } else{ $_timeout = $PSBoundParameters['Timeout'] } #Get command metadata $HttpClientMetaData = New-Object -TypeName "System.Management.Automation.CommandMetaData" (Get-Command -Name "New-HttpClient") $StringContentMetaData = New-Object -TypeName "System.Management.Automation.CommandMetaData" (Get-Command -Name "New-StringContent") $RequestMessageMetaData = New-Object -TypeName "System.Management.Automation.CommandMetaData" (Get-Command -Name "New-HttpRequestMessage") #Set new dict $newPsboundParams = [ordered]@{} } Process{ if($PSBoundParameters.ContainsKey('Client') -and $PSBoundParameters['Client']){ $httpClient = $PSBoundParameters['Client'] } else{ if($null -ne $HttpClientMetaData){ $param = $HttpClientMetaData.Parameters.Keys foreach($p in $param.GetEnumerator()){ if($PSBoundParameters.ContainsKey($p)){ $newPsboundParams.Add($p,$PSBoundParameters[$p]) } } #Add verbose, debug, etc.. [void]$newPsboundParams.Add('InformationAction',$InformationAction) [void]$newPsboundParams.Add('Verbose',$Verbose) [void]$newPsboundParams.Add('Debug',$Debug) } #get new http client $httpClient = New-HttpClient @newPsboundParams } #clear dict [void]$newPsboundParams.Clear() if($null -ne $StringContentMetaData){ $param = $StringContentMetaData.Parameters.Keys foreach($p in $param.GetEnumerator()){ if($PSBoundParameters.ContainsKey($p)){ $newPsboundParams.Add($p,$PSBoundParameters[$p]) } } #Add verbose, debug, etc.. [void]$newPsboundParams.Add('InformationAction',$InformationAction) [void]$newPsboundParams.Add('Verbose',$Verbose) [void]$newPsboundParams.Add('Debug',$Debug) } #Get string content $body = New-StringContent @newPsboundParams #clear dict [void]$newPsboundParams.Clear() if($null -ne $RequestMessageMetaData){ $param = $RequestMessageMetaData.Parameters.Keys foreach($p in $param.GetEnumerator()){ if($PSBoundParameters.ContainsKey($p)){ $newPsboundParams.Add($p,$PSBoundParameters[$p]) } } #Add verbose, debug, etc.. [void]$newPsboundParams.Add('InformationAction',$InformationAction) #[void]$newPsboundParams.Add('Verbose',$Verbose) [void]$newPsboundParams.Add('Debug',$Debug) } #Get string content $request = New-HttpRequestMessage @newPsboundParams #Execute request If($null -ne $httpClient -and $null -ne $request -and $null -ne $body){ $p = @{ Client = $httpClient; Method = $Method; Body = $body; Request = $request; TimeOut = $_timeout; RawResponse = $RawResponse; InformationAction = $InformationAction; Verbose = $Verbose; Debug = $Debug; } $response = Invoke-ClientRequest @p } } End{ if($null -ne $response){ if($PSBoundParameters.ContainsKey('GetBytes') -and $PSBoundParameters['GetBytes'].IsPresent -and $response -is [System.Net.Http.HttpContent]){ try{ [byte[]]$bytes = $response.ReadAsByteArrayAsync().GetAwaiter().GetResult() return $bytes } catch{ Write-Error $_ } } ElseIf($PSBoundParameters.ContainsKey('RawResponse') -and $PSBoundParameters['RawResponse'].IsPresent -and $response -is [System.Net.Http.HttpResponseMessage]){ return $response } else{ #Get response stream try{ $rawData = $response.ReadAsStringAsync().GetAwaiter().GetResult(); $obj = Convert-RawData -RawObject $rawData -ContentType $response.Headers.ContentType #Dispose object [void]$response.Dispose(); if($null -ne (Get-Variable -Name ErrorObj -Scope Script -ErrorAction Ignore)){ $p = @{ Message = ($messages.UnableToConvertRawData -f $PSBoundParameters['Url'], $response.Headers.ContentType); Verbose = $Verbose; } Write-Verbose @p Remove-Variable -Name ErrorObj -Scope Script -Force } #return obj return $obj } catch{ Write-Error $_ } } } } } |