Public/Get-UrlScanioScan.ps1

function Get-UrlScanioScan {
<#
.SYNOPSIS
Get urlscan.io scan results.
 
.DESCRIPTION
Get urlscan.io scan results for the provided id. Returns results as an object by default or -DataType can be used to access subsets of data.
 
.PARAMETER id
Guid of scan to get details on.
 
.PARAMETER DataType
Data type to return. Provides quick access to specific subsets of data for interrogation.
 
.PARAMETER IncludeTaskDetails
Includes details of scan along with data type specified.
 
.PARAMETER SimilarDomains
List structurally similar domains.
 
.EXAMPLE
Get-UrlScanioScan -uuid b14db0aa-013c-4aa9-ad5a-ec947a2278c7
Get urlscan.io report for the scan with uuid b14db0aa-013c-4aa9-ad5a-ec947a2278c7
 
.INPUTS
System.String. UUID's of scans can be piped to Get-UrlScanioScan.
System.Object. Objects containing a property of a scans UUID can be piped to Get-UrlScanioScan.
 
.OUTPUTS
System.String. Data can be returned as a json string.
System.Object. Data can be returned as an Object.
 
.NOTES
 
.LINK
#>

    [CmdletBinding(DefaultParameterSetName = 'All')]
    param (
        [Parameter(Mandatory = $true,
        Position = 0,
        ValueFromPipelineByPropertyName,
        ValueFromPipeline)]
        [ValidatePattern('[\d\w]{8}-[\d\w]{4}-[\d\w]{4}-[\d\w]{4}-[\d\w]{12}')]
        [Alias('uuid', '_id')]
        [string[]]$id,

        [Parameter(ParameterSetName = 'data')]
        [ValidateSet('Links','Hashes','Cookies','Certificates','Verdict','Technologies', 'iocs')]
        [string]$DataType,
        [Parameter(ParameterSetName = 'data')]
        [switch]$IncludeTaskDetails,

        [Parameter(ParameterSetName = 'similar')]
        [switch]$SimilarDomains
    )

    process {
        $request = Invoke-RestMethod -Uri "https://urlscan.io/api/v1/result/$id" -ErrorAction:SilentlyContinue

        if ($PSBoundParameters.DataType) {
            # output basic task deets
            $props = [ordered]@{}
            if ($PSBoundParameters.IncludeTaskDetails) {
                $task = $request.task | select uuid, time, url, reportURL

                $props.Property +=  @{n="id";e={$task.uuid}},
                                            @{n="time";e={$task.time}},
                                            @{n="taskUrl";e={$task.url}}
            }

            switch ($DataType) {
                Links {
                    $props.Property += 'href','text'

                    $out = $request.data.links | select @props

                    if ($out.count -eq 0) {
                        Write-Error "No links found for task $($task.uuid)"
                    }
                }
                Hashes {
                    $hashes = $request.data.requests.response.Where({$_.hash})

                    $props.Property +=  @{n="type";e={$_.type}},
                                        @{n="size";e={$_.size}},
                                        @{n="hash";e={$_.hash}},
                                        @{n="url";e={$_.response.url}}

                    $out = $hashes | select @props
                }
                Cookies {
                    [datetime]$origin = '1970-01-01 00:00:00'
                    $props.Property +=  'name',
                                        'value',
                                        'domain',
                                        'path',
                                        @{n='expires';e={$origin.AddSeconds($_.expires)}},
                                        'size',
                                        'httpOnly',
                                        'secure',
                                        'session'

                    $out = $request.data.cookies | select @props

                    if ($out.count -eq 0) {
                        Write-Error "No cookies found for task $($task.uuid)"
                    }
                }
                Certificates {
                    [datetime]$origin = '1970-01-01 00:00:00'
                    $props.Property +=  'subjectName',
                                        'issuer',
                                        @{n='validFrom';e={$origin.AddSeconds($_.validFrom)}},
                                        @{n='validTo';e={$origin.AddSeconds($_.validTo)}}

                    $out = $request.lists.certificates | select @props
                }
                Verdict {
                    $vo = $request.verdicts.overall
                    $ve = $request.verdicts.engines
                    $out = New-Object psobject

                    if ($task) {
                        $out | Add-Member NoteProperty 'id' $task.uuid
                        $out | Add-Member NoteProperty 'time' $task.time
                        $out | Add-Member NoteProperty 'time' $task.time
                        $out | Add-Member NoteProperty 'taskUrl' $task.url
                    }

                    $out | Add-Member NoteProperty 'malicious' $vo.malicious
                    $out | Add-Member NoteProperty 'overallScore' $vo.score
                    $out | Add-Member NoteProperty 'tags' ((@($vo.tags + $ve.verdicts.categories) | select -Unique) -join ', ')
                    $out | Add-Member NoteProperty 'brands' ($vo.brands -join ', ')
                    $out | Add-Member NoteProperty 'engineHits' ($ve.malicious -join ', ')
                }
                Technologies {
                    $wappa = $request.meta.processors.wappa.data

                    $props.Property +=  @{n="App";e={$_.app}},
                                        @{n="Website";e={$_.website}},
                                        @{n="Category";e={$_.categories.name}}

                    $out = $wappa | select @props
                }
                iocs {
                    $req = Invoke-WebRequest "https://urlscan.io/result/$id/#iocs" -UseBasicParsing
                    $iocsRaw = [regex]::match($req.content, '<h3>Indicators of compromise \(IoCs\)<\/h3>(.|\n)*<footer class="footer navbar-default">').Value

                    $iocsParsed = $iocsRaw.Split("`n").Trim() | % {
                        $l = $_

                        if ($l -match 'a href') {
                            $m = [regex]::Matches($l, '<a href=.*?>(.*)<\/a>')
                            $m.Groups[1].Value
                        }
                    }

                    $out = $iocsParsed
                }
            }
        } else {
            $out = $request
        }

        if ($PSCmdlet.ParameterSetName -eq 'similar') {
            $out = Get-SimilarDomains -id $id
        }

        return $out
    }
}