param ($file,$hash,$machineid) add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy $PTH = Get-Location $global:bearer_token=$null $SEPM = "IP/hostname/FQDN" function getBearerToken{ if(Test-Path $PTH\bearer.token) { $token = (gc $PTH\bearer.token) $global:bearer_token = @{Authorization='Bearer '+$token} } if($global:bearer_token -ne $null) { try { Write-Host "Checking if token ("$global:bearer_token.values.replace('Bearer ','')") is still valid" $bearer_working = Invoke-RestMethod -Uri ("https://"+$SEPM+":8446/sepm/api/v1/policies/summary/lu") -Headers $global:bearer_token } catch { #if($_.Exception.Response.StatusCode.Value__ -eq 401) { Write-Host "Token ("$global:bearer_token.values.replace('Bearer ','')") is expired / wrong (HTTP"$_.Exception.Response.StatusCode.Value__")" $global:bearer_token=$null #} } } if($global:bearer_token -eq $null) { Write-Host "No bearer token found, please authenticate against SEPM" $c = Get-Credential if($c -ne $null) { $cred = @{ username = $c.UserName password = (New-Object System.Management.Automation.PSCredential -ArgumentList $c.UserName, $c.Password).GetNetworkCredential().Password domain = "" } $auth = $cred | ConvertTo-Json try { Write-Host "Fetching new token from $SEPM" $token = (Invoke-RestMethod -Uri ("https://"+$SEPM+":8446/sepm/api/v1/identity/authenticate") -Method Post -Body $auth -ContentType 'application/json').token } catch { Write-Host "Failed to fetch new bearer token (HTTP"$_.Exception.Response.StatusCode.Value__")" } if($token -ne $null) { Write-Host "Successfully fetched new token ($token) from $SEPM" sc $PTH\bearer.token $token $global:bearer_token = @{Authorization='Bearer '+$token} } } } if($global:bearer_token -ne $null) { return $true } else { return $false } } function requestFile{ param([parameter(Mandatory=$true)][string]$filepath,[string]$filehash,[string]$computerID) if($filepath -match '.*\\\\.*') { $filepath = $filepath.replace("\\","\") } if($filehash.length -eq 64) { $hashtype = "sha256" } else { $hashtype = "md5" } $file_info = @{ file_path = $filepath computer_ids = $computerID $hashtype = $filehash } #$file_info try { Write-Host "Submitting file-request ($filepath / $filehash) command for $computerID to $SEPM" $command_id = (Invoke-RestMethod -Uri ("https://"+$SEPM+":8446/sepm/api/v1/command-queue/files") -Method Post -Headers $global:bearer_token -Body $file_info).commandID } catch { Write-Host "Error requesting $filepath from $computerID (HTTP"$_.Exception.Response.StatusCode.Value__")" $command_id = $null } return $command_id } function getFileID{ param([parameter(Mandatory=$true)][string]$commandid) Write-Host "Checking command status for command ID $commandid" $command_state = $null $command_state_id = -1 try { $command_state = (Invoke-RestMethod -Uri ("https://"+$SEPM+":8446/sepm/api/v1/command-queue/" + $commandid) -Method Get -Headers $global:bearer_token).content $command_state_id = $command_state.stateId # 0=not received | 1=received | 2=in progress | 3=completed | 4=rejected | 5=cancelled | 6=Error } catch {} while($command_state_id -lt 3) { switch($command_state_id) { 0 {Write-Host "SEPM: Client has yet to receive the command ($commandid)"} 1 {Write-Host "SEPM: Client has received the command ($commandid)"} 2 {Write-Host "SEPM: Client is processing the command ($commandid)"} default {Write-Host "SEPM: Command still to be initiated"} } try { $command_state = (Invoke-RestMethod -Uri ("https://"+$SEPM+":8446/sepm/api/v1/command-queue/" + $commandid) -Method Get -Headers $global:bearer_token).content $command_state_id = $command_state.stateId # 0=not received | 1=received | 2=in progress | 3=completed | 4=rejected | 5=cancelled | 6=Error } catch { Write-Host "Failed to check the command status of command ID $commandid (HTTP"$_.Exception.Response.StatusCode.Value__")" } if($command_state_id -eq -1) { break } elseif($command_state_id -lt 3) { Write-Host "Checking for status update in 1 minute" Start-Sleep -s 60 } } $stateDescription = $command_state.subStateDesc if($command_state_id -eq 3) { Write-Host "SEPM: Client has succesfully processed the command ($commandid / '$stateDescription')" return $command_state.binaryFileId } else { $errorCode = $command_state.subStateId switch($command_state_id) { 4 {Write-Host "SEPM: Client has rejected the command ($commandid / '$stateDescription')"} 5 {Write-Host "SEPM: The command ($commandid / '$stateDescription') got cancelled"} 6 { Write-Host "SEPM: Error while processing the command ($commandid / '$stateDescription')" switch($errorCode) { 31 {Write-Host "SEPM: Requested file not found"} default {Write-Host "SEPM: Undocumented/Unknown error"} } } default {Write-Host "SEPM: Unknown status code: $command_state_id"} } return $null } } function downloadFile{ param([parameter(Mandatory=$true)][string]$fileid,[string]$outputfile) if($outputfile -notmatch '[a-zA-Z]\:\\.*') { $outputfile = -join($PTH,"\",$outputfile) } if($outputfile -notmatch '.*\.[zZ][iI][pP]') { $outputfile = $outputfile + ".zip" } try { Write-Host "Downloading $fileid from $SEPM to $outputfile" Invoke-RestMethod -Uri ("https://"+$SEPM+":8446/sepm/api/v1/command-queue/file/" + $fileid +"/content") -Method Get -Headers $global:bearer_token -OutFile $outputfile return $outputfile } catch { Write-Host "Failed to download $fileid from $SEPM (HTTP"$_.Exception.Response.StatusCode.Value__")" return $null } } if($file -ne $null -and $hash -ne $null -and $machineid -ne $null) { Write-Host "" if(getBearerToken) { $request_id = requestFile -filepath $file -filehash $hash -computerID $machineid if($request_id -ne $null) { $file_id = getFileID -commandid $request_id if($file_id -ne $null) { $outfile = downloadFile -fileid $file_id -outputfile ($file_id + ".zip") if($outfile -ne $null) { if((Read-Host -Prompt ("Do you want to extract and un-XOR the archived file [y/n]")) -eq "Y") { $workingDir = $outfile.Substring(0, $outfile.LastIndexOf('\')) if((Test-path $workingDir\XOR) -eq $false){mkdir $workingDir\XOR} Expand-Archive -LiteralPath $outfile -DestinationPath $workingDir\XOR -Force $iFile = (Get-ChildItem $workingDir\XOR -exclude *.*).FullName $key = "0x80" $oFile = $iFile + ".unXORed" $bytes = [System.IO.File]::ReadAllBytes("$iFile") for($i=0; $i -lt $bytes.count ; $i++) { $bytes[$i] = $bytes[$i] -bxor $key } [System.IO.File]::WriteAllBytes("$oFile", $bytes) if(Test-Path $oFile) { Write-Host "File succesfully un-XOR-ed" } else { Write-Host "Failed to un-XOR the file" } } #} else { #Write-Host "File could not be downloaded" } #} else { #Write-Host "No file ID found" } #} else { #Write-Host "Request could not be submitted" } #} else { #Write-Host "No bearer token found" } Write-Host "" } else { Write-Host "" Write-Host "Missing required parameter(s):" Write-Host "" if($file -eq $null) { Write-Host "file (f.e. c:\windows\notepad.exe)" } if($hash -eq $null) { Write-Host "hash (f.e. E5D90BEEB6F13F4613C3153DABBD1466F4A062B7252D931F37210907A7F914F7 / 06E6C0482562459ADB462CA9008262F8)" } if($machineid -eq $null) { Write-Host "machineID (computerID from SEPM)" } Write-Host "" }