F-Secure API for scanning

This post will be about API of F-Secure Radar. API become a crucial feature when you have to scan a range of thousands hosts and you can’t just add it in one Vulnerability Scanning task. As I mentioned earlier in “F-Secure Radar Vulnerability Management solution” Vulnerability Scanning in Radar is for known active IPs only, for ranges – Discovery Scans. Basically, in F-Secure Radar there is always one vulnerability scan for one host. Unusual concept, but it have some advantages. And it’s quite convenient when you work with Radar via API.

So, my plan for this post is to get active IPs from discovery scan report, create vulnerability scans, run them and get reports. All using API.

To use API you need to get API key at “F-Secure Radar -> Settings -> My profile”.

F-Secure Radar API key

To check that API is working we may send a request:

GET /v1/Scans/Types HTTP/1.1
Host: api.radar.f-secure.com
Content-Type: application/json; charset=utf-8
UserName: radar_user@corporation.com
APIKey: JDOBH9MV24ZOENMS94QCO8QP

curl -i -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/Scans/Types"

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Strict-Transport-Security: max-age=60000
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Date: Thu, 06 Oct 2016 14:29:48 GMT
Content-Length: 42

{"SystemScan":0,"WebScan":1,"Discovery":2}

We got code 200, that mean that all is fine.

All API methods are described here: https://api.radar.f-secure.com/ and https://api.radar.f-secure.com/wadl

Discovery Scan results

Let’s get active IPs of “Test Scan” discovery scan. All discovery scans:

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/DiscoveryScans/Get" | python -m json.tool

[
    {
        "AssignedTo": null,
        "ConfigTemplateId": "c1ccb71d-f420-463c-a04e-be34bd928ce3",
        "ConfigXML": null,
        "CreatedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "CreatedOn": "2016-09-13T14:37:16.023",
        "CurrentScanNodeId": "e6da9c59-df79-4157-89f5-c319ee23a214",
        "Exclude": "",
        "HostsWentOffline": 146,
        "HostsWentOnline": 145,
        "Id": "7d820e6c-dd32-4603-9925-5ac7b73b0928",
        "LastDiscoveryDate": "2016-10-06T11:34:48.98",
        "LastDiscoveryId": "fb51a068-df9d-4932-ad21-9ad904d3f4de",
        "LastSeen": "2016-10-06T11:34:48.98",
        "LiveHostsCount": 788,
        "ModifiedBy": null,
        "ModifiedOn": "2016-10-06T11:34:49.043",
        "Name": "Test Scan",
        "Range": "192.168.0.0/21",
        "RunState": 0,
        "ScanNodeId": "e6da9c59-df79-4157-89f5-c319ee23a214",
        "ScanProgress": null,
        "ScanStart": "2016-10-06T10:41:40.46",
        "ScheduleId": null
    }
]

So, we found the discovery scan, let’s get it in xml:

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/Reports/DiscoveryScan/SingleScanReports/ByDiscoveryScan/Get/7d820e6c-dd32-4603-9925-5ac7b73b0928/LatestReport" | python -m json.tool | grep -v "ReportXML"

{
    "CreatedBy": null,
    "CreatedOn": "2016-10-06T11:34:48.997",
    "HostsCount": 0,
    "HostsWentOffline": 146,
    "HostsWentOnline": 145,
    "Id": "fb51a068-df9d-4932-ad21-9ad904d3f4de",
    "NetworkId": "7d820e6c-dd32-4603-9925-5ac7b73b0928",
    "OpenPortsTCP": 0,
    "OpenPortsUDP": 0,
    "ReportXML": "...",
    "ScanEndDate": "2016-10-06T11:34:48.98",
    "Status": 0
}

XML parameter contains all scan data in XML:

    "ReportXML": "<?xml version=\"1.0\"?>
<?xml-stylesheet type=\"text/xsl\" href=\"https://karhu2.nsense.net/mmc/reports/transformations/html/discovery/psng.xsl\"?>
<report scanner=\"psng\" duration=\"0 days, 0 hours, 52 minutes, 53 seconds\" args=\"-scanId '7d820e6c-dd32-4603-9925-5ac7b73b0928' -c C:\\Program Files (x86)\\F-Secure\
\RadarScanAgent\\dsscans\\a5484cd6-2d73-4f9e-ad49-8f00915c93c8\\2diz9\\2016_10_06\\10_40_47\\7d820e6c-dd32-4603-9925-5ac7b73b0928.xml -oX report.xml 192.168.0.0/21\">
  <host>
    <address addr=\"192.168.0.0\" addrtype=\"ipv4\" />
    <hostnames />
    <status state=\"down\">Completed in 0 h, 0 m, 7 s.</status>
    <ports />
  </host>
  <host>
    <address addr=\"192.168.0.1\" addrtype=\"ipv4\" />
    <hostnames>
      <hostname name=\"corporation.com\" type=\"PTR\" />
    </hostnames>
    <status state=\"down\">Completed in 0 h, 0 m, 3 s.</status>
    <ports />
  </host>
    ...
</report>",

We can easily get active (up) IP-addresses here. Sorry for some dirty bash example:

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/Reports/DiscoveryScan/SingleScanReports/ByDiscoveryScan/Get/7d820e6c-dd32-4603-9925-5ac7b73b0928/LatestReport" | python -m json.tool | grep "ReportXML" | sed 's/<\/host>/\n/g' | egrep "state=..up.." | egrep -o "address addr=..[^\"]*" | sed 's/\\//g' | awk -F"\"" '{print $2}' | head -n 10

192.168.0.11
192.168.0.12
192.168.0.13
192.168.0.14
192.168.0.15
192.168.0.16
192.168.0.17
192.168.0.19
192.168.0.20
192.168.0.21

Now, let’s create a new Vulnerability Scans for this IPs.  Scan should be created in some group and we needs it’s id.

Scan Groups

I search a group by it’s name “Scan Group 1

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/ScanGroups/Find/Scan%20Group%201" | python -m json.tool

[
    {
        "AssignedTo": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "CleanupRule": null,
        "CreatedBy": "422126b8-2423-4ede-9fda-17a3d3e7825d",
        "CreatedOn": "2011-06-07T00:57:01.877",
        "Description": "",
        "DiscoveryConfigTemplate": null,
        "DynamicScope": false,
        "GroupedScansCount": 0,
        "Id": "7458f6eb-04bf-45d0-93e8-71f69e051f54",
        "MaxSSSimultaneousScans": 5,
        "MaxWSSimultaneousScans": 3,
        "ModifiedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "ModifiedOn": "2016-10-07T17:14:35.737",
        "Name": "Scan Group 1",
        "Privileges": 0,
        "SSConfigTemplate": "acfa7cab-386e-46d6-a452-102897ab6748",
        "SSScanNodeId": "d80ce706-01ff-4fea-8fac-100396a8946b",
        "ScansCount": 4,
        "ScheduleId": null,
        "Show": false,
        "VScanList": [
            ...
        ],
        "WSConfigTemplate": "93bb84e0-87be-4a2d-a9aa-9c143c33fa04",
        "WSScanNodeId": "a0955bd7-6c81-4975-804a-402fdb92046c",
        "WSScheduleId": null
    }
]

Vulnerability Scans

Ok, now when we have group id, we can create vulnerability scans in it:

curl -X POST -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" -d "{ \"GroupId\": \"7458f6eb-04bf-45d0-93e8-71f69e051f54\", \"TargetScans\": [ { \"ScanTarget\": \"192.168.0.11\", \"FriendlyName\": \"192.168.0.11\" }, { \"ScanTarget\": \"192.168.0.12\", \"FriendlyName\": \"192.168.0.12\" } ]}" "https://api.radar.f-secure.com/v1/SystemScans/Create" | python -m json.tool

[
    {
        "AssignedTo": null,
        "Change": null,
        "ConfigXML": null,
        "CreatedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "CreatedOn": "2016-10-07T17:50:38.307",
        "GroupId": "7458f6eb-04bf-45d0-93e8-71f69e051f54",
        "GroupName": "Scan Group 1",
        "Host": "192.168.0.11",
        "HostFriendlyName": "192.168.0.11 (192.168.0.11)",
        "Id": "9a48f8f0-fd34-4ac5-84b0-b984692efab9",
        "LastReportId": null,
        "ModifiedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "ModifiedOn": "2016-10-07T17:50:38.307",
        "ParentScanId": null,
        "ScanEnd": null,
        "ScanLastCompleted": null,
        "ScanName": "192.168.0.11",
        "ScanProgress": null,
        "ScanRunState": 0,
        "ScanStart": null,
        "ScanType": 0,
        "ScanningMode": 0,
        "ScheduleId": null
    },
    {
        "AssignedTo": null,
        "Change": null,
        "ConfigXML": null,
        "CreatedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "CreatedOn": "2016-10-07T17:50:38.32",
        "GroupId": "7458f6eb-04bf-45d0-93e8-71f69e051f54",
        "GroupName": "Scan Group 1",
        "Host": "192.168.0.12",
        "HostFriendlyName": "192.168.0.12 (192.168.0.12)",
        "Id": "7717a168-719e-4613-ae2f-8072978d0fc3",
        "LastReportId": null,
        "ModifiedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
        "ModifiedOn": "2016-10-07T17:50:38.32",
        "ParentScanId": null,
        "ScanEnd": null,
        "ScanLastCompleted": null,
        "ScanName": "192.168.0.12",
        "ScanProgress": null,
        "ScanRunState": 0,
        "ScanStart": null,
        "ScanType": 0,
        "ScanningMode": 0,
        "ScheduleId": null
    }
]

Ok, how can we start a scan? By Scan Id:

curl -X PUT -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" -d "" "https://api.radar.f-secure.com/v1/VulnerabilityScans/9a48f8f0-fd34-4ac5-84b0-b984692efab9/Start" | python -m json.tool

{
    "AssignedTo": null,
    "Change": null,
    "ConfigXML": null,
    "CreatedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
    "CreatedOn": "2016-10-07T17:50:38.307",
    "GroupId": "7458f6eb-04bf-45d0-93e8-71f69e051f54",
    "GroupName": "Scan Group 1",
    "Host": "192.168.0.11",
    "HostFriendlyName": "192.168.0.11 (192.168.0.11)",
    "Id": "9a48f8f0-fd34-4ac5-84b0-b984692efab9",
    "LastReportId": null,
    "ModifiedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
    "ModifiedOn": "2016-10-07T17:50:38.307",
    "ParentScanId": null,
    "ScanEnd": null,
    "ScanLastCompleted": null,
    "ScanName": "192.168.0.11",
    "ScanProgress": 0,
    "ScanRunState": 6,
    "ScanStart": null,
    "ScanType": 0,
    "ScanningMode": 0,
    "ScheduleId": null
}

We can delete it in similar way: DELETE request to v1/VulnerabilityScans/Remove/{scanId}

How to check scan status in F-Secure Radar?

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/VulnerabilityScans/Get/9a48f8f0-fd34-4ac5-84b0-b984692efab9" | python -m json.tool

{
    "AssignedTo": null,
    "Change": null,
    "ConfigXML": null,
    "CreatedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
    "CreatedOn": "2016-10-07T17:50:38.307",
    "GroupId": "7458f6eb-04bf-45d0-93e8-71f69e051f54",
    "GroupName": "Scan Group 1",
    "Host": "192.168.0.11",
    "HostFriendlyName": "192.168.0.11 (192.168.0.11)",
    "Id": "9a48f8f0-fd34-4ac5-84b0-b984692efab9",
    "LastReportId": null,
    "ModifiedBy": null,
    "ModifiedOn": "2016-10-07T18:08:42.51",
    "ParentScanId": null,
    "ScanEnd": null,
    "ScanLastCompleted": null,
    "ScanName": "192.168.0.11",
    "ScanProgress": 0,
    "ScanRunState": 1,
    "ScanStart": "2016-10-07T18:07:42.417",
    "ScanType": 0,
    "ScanningMode": 0,
    "ScheduleId": null
}

And how the scan will look like after it will be finished:

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/VulnerabilityScans/Get/062e9934-9553-43da-912e-cs2d34364e4c" | python -m json.tool | sed 's/"ConfigXML": .*/"ConfigXML": "..."/'

{
    "AssignedTo": null,
    "Change": null,
    "Compliant": 0,
    "CompliantType": 0,
    "CreatedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
    "CreatedOn": "2016-09-21T10:45:12.887",
    "GroupId": "7458f6eb-04bf-45d0-93e8-71f69e051f54",
    "GroupedScanCount": 0,
    "Host": "192.168.56.101",
    "Id": "062e9934-9553-43da-912e-cs2d34364e4c",
    "IndexId": 0,
    "LastReportId": "0e0f6724-2bc4-4db9-9954-644efbba7161",
    "ModifiedBy": "2f0bbff7-6502-4e55-a670-fsdl7b209ce5",
    "ModifiedOn": "2016-10-07T18:39:21.077",
    "NumberOfRecords": 0,
    "Os": "CentOS Linux 7 (Core)",
    "ParentScanId": null,
    "ScanEnd": "2016-10-05T15:39:58",
    "ScanLastCompleted": "2016-09-23T15:49:59",
    "ScanName": "192.168.56.101",
    "ScanProgress": null,
    "ScanRunState": 0,
    "ScanStart": "2016-10-05T15:37:17.287",
    "ScanType": 0,
    "ScanningMode": 0,
    "ScheduleId": null
}

After scan will be finished we will be able to get report xml as we did for discovery scan:

curl -s -H "Content-Type: application/json; charset=utf-8" -H "UserName: radar_user@corporation.com" -H "APIKey: JDOBH9MV24ZOENMS94QCO8QP" "https://api.radar.f-secure.com/v1/Reports/VulnerabilityScan/SingleScanReports/SystemScans/062e9934-9553-43da-912e-cs2d34364e4c/LatestReport" | python -m json.tool

{
    "VulnerabilityDefinitions": [
        {
            "CVSSBaseScore": 6.8,
            "CVSSBaseScoreRefVector": 6.8,
            "CVSSVector": "(AV:N/AC:M/Au:N/C:P/I:P/A:P)",
            "Category": "Linux",
            "CreatedBy": null,
            "CreatedOn": "2016-09-23T15:50:30.587",
            "Description": "The glibc packages provide the standard C libraries (libc), ...",
            "IsDos": false,
            "ManualId": null,
            "ModifiedBy": null,
            "ModifiedOn": "2016-09-23T15:50:30.587",
            "Name": "CESA-2016:0176: glibc security and bug fix update",
            "PluginId": 1017790,
            "ScanType": 0,
            "SectionName": null,
            "Solution": "Run 'yum update' to install latest security updates.",
            "Summary": "Checks for missing security patches.",
            "Synopsis": "The remote host is missing security patches.",
            "TagCollection": [
                {
                    "Component": null,
                    "FriendlyName": "Authenticated Check",
                    "Source": "SystemScan",
                    "TechnicalName": "authcheck",
                    "Type": "dynamic"
                },
                {
                    "Component": null,
                    "FriendlyName": "CentOS Authenticated Check",
                    "Source": "SystemScan",
                    "TechnicalName": "centosauthcheck",
                    "Type": "dynamic"
                },
                {
                    "Component": null,
                    "FriendlyName": "Linux",
                    "Source": "SystemScan",
                    "TechnicalName": "linux",
                    "Type": "dynamic"
                }
            ],
            "Tags": null,
            "TrustLevel": 100,
            "Version": "2016-06-10T06:02:43",
            "description": "The glibc packages provide the standard C libraries (libc), ..."
        },
...

One thought on “F-Secure API for scanning

  1. Pingback: F-Secure Radar Vulnerability Management solution | Alexander V. Leonov

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.