UMN-Qualys.psm1
### # Copyright 2017 University of Minnesota, Office of Information Technology # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with Foobar. If not, see <http://www.gnu.org/licenses/>. # Based off # https://community.qualys.com/community/developer # https://www.qualys.com/docs/qualys-api-quick-reference.pdf # https://www.qualys.com/docs/qualys-api-v2-user-guide.pdf # https://www.qualys.com/docs/qualys-asset-management-tagging-api-v2-user-guide.pdf #region Connect-Qualys function Connect-Qualys{ <# .Synopsis Connect to Qualys API and get back session $cookie for all other functions .DESCRIPTION Connect to Qualys API and get back session $cookie for all other functions .PARAMETER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo .PARAMETER header Use Get-QualysHeader to get the correctly formatted header for Qualys .PARAMETER qualysCred use Get-Credential to create a PSCredential with the username and password of an account that has access to Qualys .EXAMPLE $cookie = Connect-Qualys -uri 'https://qualysapi.qualys.com:443/api/2.0/fo/session/' -header (Get-QualysHeader) -qualysCred (Get-Credential) .Notes Author: Travis Sobeck, Kyle Weeks #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [string]$header, [Parameter(Mandatory=$true)] [System.Management.Automation.PSCredential]$qualysCred ) Begin{} Process { $qualysuser = $qualysCred.UserName $qualysPswd = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($qualysCred.Password)) ############# Log in ############# ## URL for Logging In/OUT ## Login/out $logInBody = @{ action = "login" username = $qualysuser password = $qualysPswd } ## Log in SessionVariable captures the cookie $uri += 'session/' $response = Invoke-RestMethod -Headers $headers -Uri $uri -Method Post -Body $logInBody -SessionVariable cookie return $cookie } End{} } #endregion #region Get-QualysAssetGrp function Get-QualysAssetGrp{ <# .Synopsis Get a list of AssetGroup IDs or the ID for a specific AssetGroup .DESCRIPTION Get a list of AssetGroup IDs or the ID for a specific AssetGroup .PARAMTER id Asset Group ID, use this to get a single Asset Group .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [string]$id, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { ## Create URL, see API docs for path ######################### $uri += "asset/group" $actionBody = @{action = "list"} if($id){$actionBody['ids'] = $id} [xml]$returnedXML = Invoke-RestMethod -Headers $header -Uri $uri -Method Get -Body $actionBody -WebSession $cookie $data = $returnedXML.ASSET_GROUP_LIST_OUTPUT.RESPONSE.ASSET_GROUP_LIST.ASSET_GROUP if($id){$data;$data.TITLE.'#cdata-section';$data.IP_SET} else{foreach ($n in 0..($data.Length -1)){"--------------";"Title: " +$data.Get($n).TITLE.'#cdata-section';$data.Get($n);$data.IP_SET}} } End{} } #endregion #region Get-QualysHeader function Get-QualysHeader{ <# .Synopsis Get header for subsequent calls .DESCRIPTION Place holder in the event future version require a different header. Future version may take version number as a param. .EXAMPLE $header = Get-QualysHeader .Notes Author: Travis Sobeck, Kyle Weeks #> [CmdletBinding()] [OutputType([System.Collections.Hashtable])] Param () Begin{} Process { return @{"X-Requested-With"="powershell"} } End{} } #endregion #region Get-QualysReport function Get-QualysReport{ <# .Synopsis Download Qualys Report .DESCRIPTION Download Qualys Report .PARAMTER id Report ID, use Get-QualysReportList to find the ID .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [string]$id, [Parameter(Mandatory=$true)] [string]$outFilePath, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { ### get the format type $format = (Get-QualysReportList -uri $uri -header $header -cookie $cookie -id $id).OUTPUT_FORMAT $outfile = "$outFilePath\qualysReport$ID.$format" ## Create URL, see API docs for path ######################### $uri += "report/" $actionBody = @{action = "fetch";id = "$id"} $null = Invoke-RestMethod -Headers $headers -Uri $uri -Method get -Body $actionBody -WebSession $cookie -OutFile $outfile } End{} } #endregion #region Get-QualysReportList function Get-QualysReportList{ <# .Synopsis Get list of Qualys Reports .DESCRIPTION Get list of Qualys Reports .PARAMTER id (Optional) Qualys Report ID, use this to get details on a specific ID .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [string]$id, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { ## Create URL, see API docs for path ######################### $uri += "report/" $actionBody = @{action = "list"} if($id){$actionBody['id'] = $id} [xml]$returnedXML = Invoke-RestMethod -Headers $header -Uri $uri -Method Get -Body $actionBody -WebSession $cookie $data = $returnedXML.REPORT_LIST_OUTPUT.RESPONSE.REPORT_LIST.REPORT if($id){$data;$data.TITLE.'#cdata-section'} else{foreach ($n in 0..($data.Length -1)){"--------------";"Title: " +$data.Get($n).TITLE.'#cdata-section';$data.Get($n)}} } End{} } #endregion #region Get-QualysSchedReportList function Get-QualysSchedReportList{ <# .Synopsis Get a list of Reports Scheduled .DESCRIPTION Get a list of Reports Scheduled .PARAMTER id (Optional) Report Schedule ID .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [string]$id, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { ## Create URL, see API docs for path ######################### $uri += "schedule/report" $actionBody = @{action = "list"} if($id){$actionBody['id'] = $id} [xml]$returnedXML = Invoke-RestMethod -Headers $header -Uri $uri -Method Get -Body $actionBody -WebSession $cookie $data = $returnedXML.SCHEDULE_REPORT_LIST_OUTPUT.RESPONSE.SCHEDULE_REPORT_LIST.REPORT if($id){$data;$data.TITLE.'#cdata-section';$data.TEMPLATE_TITLE.'#cdata-section';$data.SCHEDULE} else{foreach ($n in 0..($data.Length -1)){"--------------";"Title: " +$data.Get($n).TITLE.'#cdata-section';$data.Get($n);$data.Get($n).TEMPLATE_TITLE.'#cdata-section';$data.Get($n).SCHEDULE}} } End{} } #endregion #region Invoke-QualysBase function Invoke-QualysBase{ <# .Synopsis .DESCRIPTION .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [System.Collections.Hashtable]$body, [Parameter(Mandatory=$true)] [string]$method, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { return (Invoke-RestMethod -Headers $header -Uri $uri -Method $method -Body $body -WebSession $cookie) } End{} } #endregion #region New-QualysIP function New-QualysIP{ <# .Synopsis .DESCRIPTION .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [ValidatePattern("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")] [string]$ip, [Parameter(Mandatory=$true)] [string]$groupID, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { ## Create URL, see API docs for path ######################### $uri += 'asset/group/' ######################### $actionBody = @{ action = "list" ids = $groupID } ## Run your action, WebSession contains the cookie from login [xml]$returnedXML = Invoke-RestMethod -Headers $header -Uri $uri -Method Post -Body $actionBody -WebSession $cookie # Single IPs [System.Collections.ArrayList]$ips = $returnedXML.ASSET_GROUP_LIST_OUTPUT.RESPONSE.ASSET_GROUP_LIST.ASSET_GROUP.IP_SET.IP # IP Ranges, these will take more work to extrapolate [System.Collections.ArrayList]$ipRanges = $returnedXML.ASSET_GROUP_LIST_OUTPUT.RESPONSE.ASSET_GROUP_LIST.ASSET_GROUP.IP_SET.IP_RANGE ## break up the ip range strings, extract all the ips .. blah blah foreach ($ip in $ipRanges) { $a,$b = $ip -split "-" $a1,$a2,$a3,[int]$a4 = $a -split "\." $b1,$b2,$b3,[int]$b4 = $b -split "\." foreach ($i in $a4 .. $b4) { $newIP = $a1 + "." + $a2 + "." + $a3 + "." + [string]$i # add to the array of IPs, check for doubles if ($ips -notcontains $newIP){$junk = $ips.Add($newIP)} } } ########################### now we have a full list of IPs to check against ### check if IP to be added is is in the list if ($ips -notcontains $ip) { $actionBody = @{ action = "edit" id = $groupID add_ips = $ip } [xml]$response = Invoke-RestMethod -Headers $header -Uri $uri -Method Post -Body $actionBody -WebSession $cookie ## check that it worked $qualysError = $response.SIMPLE_RETURN.RESPONSE.TEXT if (-not ($response.SIMPLE_RETURN.RESPONSE.TEXT -eq $successResponse)){throw "Failed to add IP $ip -- $qualysError"} else{return $true} } else{return $true} } End { $returnedXML = $null } } #endregion #region Remove-QualysIP function Remove-QualysIP{ <# .Synopsis .DESCRIPTION .PARAMTER uri This will take the form https://<fqdn>:443/api/<apiversion>/fo see Qualys documentation for specifics .PARAMTER header Use Get-QualysHeader to get this .PARAMTER cookie Use Connect-Qualys to get session cookie .EXAMPLE .EXAMPLE #> [CmdletBinding()] Param ( [ValidatePattern("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")] [string]$ip, [Parameter(Mandatory=$true)] [string]$groupID, [Parameter(Mandatory=$true,HelpMessage="This will take the form https://<fqdn>:443/api/<apiversion>/fo/session")] [string]$uri, [Parameter(Mandatory=$true,HelpMessage="Use Get-QualysHeader")] [System.Collections.Hashtable]$header, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestSession]$cookie ) Begin{} Process { $uri += 'asset/group/' ## Remove IP from Asset Group ## Look at passinging in Asset Group (High or regular) and set IP ######################### $actionBody = @{ action = "edit" id = $groupID remove_ips = $ip } ## Run your action, WebSession contains the cookie from login [xml]$returnedXML = Invoke-RestMethod -Headers $header -Uri $uri -Method Post -Body $actionBody -WebSession $cookie if ($returnedXML.SIMPLE_RETURN.RESPONSE.TEXT -ne $successResponse){throw "$logInit Error - $ip - $returnedXML.SIMPLE_RETURN.RESPONSE.TEXT"} else{return $true} } End { $returnedXML = $null } } #endregion |