PhishLabs IOC DRP

Retrieves Digital Risk cases Protection from PhishLabs.

Data Enrichment & Threat Intelligence · PhishLabs

Details

IDPhishLabs IOC DRP
ProviderFortra
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

This integration was integrated and tested with V1.0 of PhishLabs IOC DRP

Use Cases

  • Get cases by filters from PhishLabs DRP service
  • Get live incidents from PhishLabs DRP service

Detailed Description

PhishLabs Digital Risk Protection (DRP) is a solution that provides proactive detection and rapid mitigation of digital risks across:

  • email
  • domain
  • social media
  • mobile
  • dark
  • deep
  • open web vectors

Configure PhishLabs IOC DRP on Cortex XSOAR

  1. Navigate to Settings > Integrations  > Servers & Services.
  2. Search for PhishLabs IOC DRP.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Server URL (e.g. https://example.net)
    • User
    • Fetch incidents
    • Incident type
    • First fetch timestamp ( , e.g., 12 hours, 7 days) </strong></li>
    • Fetch by date field
    • Fetch limit (min 20)
    • Trust any certificate (not secure)
    • Use system proxy settings
    • </ul> </li>
    • Click Test to validate the new instance.
    • </ol>

      Fetch Incidents

      Fetch incidents done by the following configuration:

      • Limit - limit amount of incidents by fetch
      • Date field - Date field to fetch incidents by - created/modified/closed
      • Time to fetch - date for starting collecting incidents (1 days ago, 1 hours ago etc)
      • Incident type

      Incident data example:

        [
        {
          "name": "PhishLabs IOC - DRP: 12d329b7-13db-11ea-94e8-0ee0a3f3cb1c",
          "occurred": "2019-12-01T01:40:36Z",
          "rawJSON": {
            "caseId": "12d329b7-13db-11ea-94e8-0ee0a3f3cb1c",
            "title": "=? =?gb2312?Q?ted:_www.icloud.com.agona.cn?=",
            "description": "From: PhishLabs Security Operations <not@domain.com>\nSubject: =? =?gb2312?Q?ted:_www.icloud.com.agona.cn?=\n\n\r\n________________________________\r\nFrom: west263\r\nSent: Saturday, November 30, 2019 8:36:41 PM (UTC-05:00) Eastern Time (US & Canada)\r\nTo: PhishLabs Security Operations; not@domain.com; not@domain.com\r\nSubject: 回复:[PL-1405082] Malicious domain detected: www.icloud.com.agona.cn\r\n\r\n-- External email--\r\n\r\n\r\nThank you for allowing us an opportunity to assist you.\r\n\r\nWe have suspended our customer to use this domain. You can check it later.\r\n\r\nIf you have any questions, please do not hesitate to contact us. We look forward to assisting you.\r\n\r\nHave a wonderful day!\r\n\r\n\r\n\r\n------------------\r\n\r\nBest regards,\r\n\r\nLillian\r\n\r\n\r\n------------------ 原始邮件 ------------------\r\n\r\n发件人:  PhishLabs Security Operations<not@domain.com>;\r\n日  期:  2019-11-30 (星期六) 08:37:19\r\n收件人:  not@domain.com<not@domain.com>;not@domain.com<not@domain.com>;not@domain.com<not@domain.com>;\r\n主  题:  [PL-1405082] Malicious domain detected: www.icloud.com.agona.cn\r\n\r\n\r\nDuring an investigation of fraud, we discovered a domain(s) registered for the sole intent of malicious activity, which is being used to attack our client and their customers.\r\n\r\nWe have addressed this report to the responsible authoritative providers over this website who have the ability to disable the malicious content in question. This includes but is not limited to the hosting provider(s), nameserver, registrar and if applicable, the registry.  Based on your relationship to the content in question or services provided, please see our specific request below.\r\n\r\nThis threat has been active for at least 2.1 hours.\r\n\r\nhXXp www[.]icloud[.]com[.]agona[.]cn/ios/uy930glgr8yx54n4zkcw[.]asp?uy930glgr8yx54n4zkcw=\r\nhXXp www[.]icloud[.]com[.]agona[.]cn/ios/upvf7o4kon1kpt4vfy18[.]asp?upvf7o4kon1kpt4vfy18=\r\nhXXp www[.]icloud[.]com[.]agona[.]cn/ios/vweixhklbjw1t1ve3b4n[.]asp?vweixhklbjw1t1ve3b4n=\r\nhXXp www[.]icloud[.]com[.]agona[.]cn/an3n3abqqtkpuok9vw9c[.]asp?an3n3abqqtkpuok9vw9c\r\n\r\nFirst detection of malicious activity: 11-29-2019 22:26:17 UTC\r\nMost recent observation of malicious activity: 11-30-2019 00:35:06 UTC\r\nAssociated IP Addresses: 8.8.8.8\r\n\r\nEvidence of malicious content is provided below my signature.\r\n\r\n===   HOSTING  PROVIDER AND/OR WEBSITE OWNER    ===\r\nIf you agree that this is malicious, we kindly request that you take steps to have the content removed as soon as possible.  It is highly likely that the intruder who set up this phishing content has also left additional fraudulent material on this server such as illegitimate access points.\r\n\r\n===   REGISTRAR / REGISTRY   ===\r\nWe kindly request that this domain is placed on hold as soon as possible and all client related information sink holed. It is also very likely the registrant in question has registered various other domains through your service and it is suggested you investigate as you see fit.\r\n\r\n===   NAMESERVER, SOA   ===\r\nIf it is within your power, please consider disabling the routing to this domain to prevent further abuse to the public.\r\n\r\n===   CERT/CIRT, ETC.   ===\r\nIf you're able to assist in any means possible to see to the termination of this content, please do so.  Your local expertise and influence on this matter is critical to this effort.\r\n\r\nIf we have contacted you in error, or if there is a better way for us to report this incident, please let us know so that we may continue our investigation.\r\n\r\nWe are extremely grateful for your assistance.\r\n\r\nKind regards,\r\n\r\nYogender Chauhan\r\nPhishLabs Security Operations\r\n12023866001\r\nAvailable 24/7\r\n\r\n\r\nEvidence:\r\nPlease see attached screenshot.\r\n.\r\n\r\n[PL-1405082]\r\n\r\n\r\n ",
            "caseNumber": 1406220,
            "createdBy": {
              "id": "30c2e916-c72d-11e3-860e-002590387e36",
              "name": "soc.phishlabs",
              "displayName": "SOC PhishLabs"
            },
            "brand": "",
            "caseType": "Other",
            "resolutionStatus": "Accidental creation",
            "caseStatus": "Rejected",
            "dateCreated": "2019-12-01T01:37:02Z",
            "dateClosed": "2019-12-01T01:40:36Z",
            "dateModified": "2019-12-01T01:40:36Z",
            "customer": "PhishLabs",
            "attachments": [
              {
                "id": "12e5eeaa-13db-11ea-8247-0ad24386a0d6",
                "type": "Email",
                "description": "Source Email for case creation",
                "dateAdded": "2019-12-01T01:37:02Z",
                "fileName": "msg.oFAH.eml",
                "fileURL": "https://caseapi.phishlabs.com/v1/data/attachment/12e5eeaa-13db-11ea-8247-0ad24386a0d6"
              }
            ],
            "formReceiver": false,
            "brandAbuseFlag": false,
            "appDate": "0001-01-01T00:00:00Z",
            "primaryMarketplace": false
          }
        }
      ]
      

      Commands

      You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.

      1. Get cases by filters: phishlabs-ioc-drp-get-cases
      2. Get case by ID: phishlabs-ioc-drp-get-case-by-id
      3. Get open cases filters: phishlabs-ioc-drp-get-open-cases
      4. Get closed cases by filters: phishlabs-ioc-drp-get-closed-cases

      1. phishlabs-ioc-drp-get-cases


      Get cases by filters

      Base Command

      phishlabs-ioc-drp-get-cases

      Input
      </tr> </tbody> </table>
      Context Output
      Argument Name Description Required
      status Filter cases based on the case status Optional
      case_type Filter cases by case type Optional
      max_records Maximum number of cases to return, default is 20, maximum is 200 Optional
      offset Paginate results used in conjunction with maxRecords. Optional
      date_field Field to use to query using dateBegin and dateEnd parameters. Optional
      begin_date Date query beginning date Optional
      end_date Date query endining date Optional
      period timestamp ( , e.g., 12 hours, 7 days)</td> Optional
      Path Type Description
      PhishlabsIOC.DRP.CaseID String Case ID
      PhishlabsIOC.DRP.Title String Case title
      PhishlabsIOC.DRP.Description String Case description
      PhishlabsIOC.DRP.CaseNumber String Case number
      PhishlabsIOC.DRP.Resolution String Resolution
      PhishlabsIOC.DRP.ResolutionStatus String Resolution status
      PhishlabsIOC.DRP.CreatedBy.ID String Case creator ID
      PhishlabsIOC.DRP.CreatedBy.Name String Case creator name
      PhishlabsIOC.DRP.CreatedBy.DisplayName String Case creator display name
      PhishlabsIOC.DRP.Brand String Brand reported in case
      PhishlabsIOC.DRP.Email String Email of case creator
      PhishlabsIOC.DRP.CaseType String Type of the case
      PhishlabsIOC.DRP.CaseStatus String Status of the case
      PhishlabsIOC.DRP.DateCreated String Case creation date
      PhishlabsIOC.DRP.DateClosed String Case closing date
      PhishlabsIOC.DRP.DateModified String Case modification date
      PhishlabsIOC.DRP.Customer String Customer reporting the case
      PhishlabsIOC.DRP.AttackSources.URL String URL of the attack source
      PhishlabsIOC.DRP.AttackSources.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AttackSources.IP String IP of the attack source
      PhishlabsIOC.DRP.AttackSources.ISP String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.Country String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AttackSources.FQDN String FQDN of the attack source
      PhishlabsIOC.DRP.AttackSources.Domain String Domain of the attack source
      PhishlabsIOC.DRP.AttackSources.IsMaliciousDomain Boolean Detect if domain of attack source is malicious
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AttackSources.WhoIs.NameServers String Name servers of the URL
      PhishlabsIOC.DRP.Attachments.ID String ID of case attachment
      PhishlabsIOC.DRP.Attachments.Type String Type of case attachment
      PhishlabsIOC.DRP.Attachments.Description String Description of case attachment
      PhishlabsIOC.DRP.Attachments.DateAdded String Date adding of case attachment
      PhishlabsIOC.DRP.Attachments.FileName String File name of case attachment
      PhishlabsIOC.DRP.Attachments.FileURL String File URL of case attachment
      PhishlabsIOC.DRP.ApplicationName String Application reported in the case
      PhishlabsIOC.DRP.Platform String Platform reported in the case
      PhishlabsIOC.DRP.Severity String Sevirity of DRP
      PhishlabsIOC.DRP.Developer String Developer of the application reported
      PhishlabsIOC.DRP.DeveloperWebsite String Developer website of the application reported
      PhishlabsIOC.DRP.ApplicationDescription String Descripion of the application reported
      PhishlabsIOC.DRP.Language String Language of the application reported
      PhishlabsIOC.DRP.Phone String Phone number of case creator
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.AssociatedURLs.URL String URL of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.NameServers String Name servers of the URL

       

      Command Example

      !phishlabs-ioc-drp-get-cases max_records=2

      Context Example
      {
          "PhishLabsIOC": {
              "DRP": [
                  {
                      "Attachments": [
                          {
                              "DateAdded": "2019-12-09T07:56:02Z",
                              "Description": "Source Email for case creation",
                              "FileName": "msg.mFAH.eml",
                              "FileURL": "https://caseapi.phishlabs.com/v1/data/attachment/",
                              "ID": "581ba28d-1a59-11ea-8247-0ad24386a0d6",
                              "Type": "Email"
                          }
                      ],
                      "CaseID": "5808ec5a-1a59-11ea-94e8-0ee0a3f3cb1c",
                      "CaseNumber": 1417871,
                      "CaseStatus": "Rejected",
                      "CaseType": "Other",
                      "CreatedBy": {
                          "DisplayName": "SOC PhishLabs",
                          "ID": "30c2e916",
                          "Name": "soc.phishlabs"
                      },
                      "Customer": "PhishLabs",
                      "DateClosed": "2019-12-09T08:01:34Z",
                      "DateCreated": "2019-12-09T07:56:01Z",
                      "DateModified": "2019-12-09T08:01:34Z",
                      "Description": "From: ",
                      "ResolutionStatus": "Accidental creation",
                      "Title": "=?gb2312?B?"
                  },
                  {
                      "Attachments": [
                          {
                              "DateAdded": "2019-12-09T07:46:02Z",
                              "Description": "Source Email for case creation",
                              "FileName": "msg.fKAH.eml",
                              "FileURL": "https://caseapi.phishlabs.com/v1/data/",
                              "ID": "f24c36a6",
                              "Type": "Email"
                          }
                      ],
                      "CaseID": "f239fe62",
                      "CaseNumber": 1417866,
                      "CaseStatus": "Rejected",
                      "CaseType": "Other",
                      "CreatedBy": {
                          "DisplayName": "SOC PhishLabs",
                          "ID": "30c2e916",
                          "Name": "soc.phishlabs"
                      },
                      "Customer": "PhishLabs",
                      "DateClosed": "2019-12-09T07:49:11Z",
                      "DateCreated": "2019-12-09T07:46:01Z",
                      "DateModified": "2019-12-09T07:49:11Z",
                      "Description": "From: ",
                      "ResolutionStatus": "Accidental creation",
                      "Title": "=?gb231"
                  }
              ]
          }
      }
      
      Human Readable Output

      PhishLabs IOC - DRP - cases

      CaseID Title CaseStatus DateCreated ResolutionStatus CreatedBy
      5808ec5a-1a59-11ea-94e8-0ee0a3f3cb1c ?Q?idenform[.]top?= Rejected 2019-12-09T07:56:01Z Accidental creation ID: 30c2e916
      Name: soc.phishlabs
      DisplayName: SOC PhishLabs
      f239fe62-1a57-11ea-94e8-0ee0a3f3cb1c =?gb2312?B?R Rejected 2019-12-09T07:46:01Z Accidental creation ID: 30c2e916
      Name: soc.phishlabs
      DisplayName: SOC PhishLabs

      2. phishlabs-ioc-drp-get-case-by-id


      Get case by ID of Phishlabs DRP service

      Base Command

      phishlabs-ioc-drp-get-case-by-id

      Input
      Argument Name Description Required
      case_id ID of case, for expample ID from previous command Required

       

      Context Output
      Path Type Description
      PhishlabsIOC.DRP.CaseID String Case ID
      PhishlabsIOC.DRP.Title String Case title
      PhishlabsIOC.DRP.Description String Case description
      PhishlabsIOC.DRP.CaseNumber String Case number
      PhishlabsIOC.DRP.Resolution String Resolution
      PhishlabsIOC.DRP.ResolutionStatus String Resolution status
      PhishlabsIOC.DRP.CreatedBy.ID String Case creator ID
      PhishlabsIOC.DRP.CreatedBy.Name String Case creator name
      PhishlabsIOC.DRP.CreatedBy.DisplayName String Case creator display name
      PhishlabsIOC.DRP.Brand String Brand reported in case
      PhishlabsIOC.DRP.Email String Email of case creator
      PhishlabsIOC.DRP.CaseType String Type of the case
      PhishlabsIOC.DRP.CaseStatus String Status of the case
      PhishlabsIOC.DRP.DateCreated String Case creation date
      PhishlabsIOC.DRP.DateClosed String Case closing date
      PhishlabsIOC.DRP.DateModified String Case modification date
      PhishlabsIOC.DRP.Customer String Customer reporting the case
      PhishlabsIOC.DRP.AttackSources.URL String URL of the attack source
      PhishlabsIOC.DRP.AttackSources.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AttackSources.IP String IP of the attack source
      PhishlabsIOC.DRP.AttackSources.ISP String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.Country String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AttackSources.FQDN String FQDN of the attack source
      PhishlabsIOC.DRP.AttackSources.Domain String Domain of the attack source
      PhishlabsIOC.DRP.AttackSources.IsMaliciousDomain Boolean Detect if domain of attack source is malicious
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AttackSources.WhoIs.NameServers String Name servers of the URL
      PhishlabsIOC.DRP.Attachments.ID String ID of case attachment
      PhishlabsIOC.DRP.Attachments.Type String Type of case attachment
      PhishlabsIOC.DRP.Attachments.Description String Description of case attachment
      PhishlabsIOC.DRP.Attachments.DateAdded String Date adding of case attachment
      PhishlabsIOC.DRP.Attachments.FileName String File name of case attachment
      PhishlabsIOC.DRP.Attachments.FileURL String File URL of case attachment
      PhishlabsIOC.DRP.ApplicationName String Application reported in the case
      PhishlabsIOC.DRP.Platform String Platform reported in the case
      PhishlabsIOC.DRP.Severity String Sevirity of DRP
      PhishlabsIOC.DRP.Developer String Developer of the application reported
      PhishlabsIOC.DRP.DeveloperWebsite String Developer website of the application reported
      PhishlabsIOC.DRP.ApplicationDescription String Descripion of the application reported
      PhishlabsIOC.DRP.Language String Language of the application reported
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.Phone String Phone number of case creator
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.AssociatedURLs.URL String URL of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.NameServers String Name servers of the URL

       

      Command Example

      !phishlabs-ioc-drp-get-case-by-id case_id=08baa0d0-1a54-11ea-94e8-0ee0a3f3cb1c

      Context Example
      {
          "PhishLabsIOC": {
              "DRP": [
                  {
                      "Attachments": [
                          {
                              "DateAdded": "2019-12-09T07:18:01Z",
                              "Description": "Source Email for case creation",
                              "FileName": "msg.nFAH.eml",
                              "FileURL": "https://caseapi.phishlabs.com/v1/data/attachment/08d0611d",
                              "ID": "08d0611d",
                              "Type": "Email"
                          }
                      ],
                      "CaseID": "08baa0d0",
                      "CaseNumber": 1417854,
                      "CaseStatus": "Rejected",
                      "CaseType": "Other",
                      "CreatedBy": {
                          "DisplayName": "SOC PhishLabs",
                          "ID": "30c2e916",
                          "Name": "soc.phishlabs"
                      },
                      "Customer": "PhishLabs",
                      "DateClosed": "2019-12-09T07:18:46Z",
                      "DateCreated": "2019-12-09T07:18:01Z",
                      "DateModified": "2019-12-09T07:18:46Z",
                      "Description": "From: PhishLabs Security Operations <soc@phishlabs.com>",
                      "ResolutionStatus": "Accidental creation",
                      "Title": "=?gb2312?"
                  }
              ]
          }
      }
      
      Human Readable Output

      PhishLabs IOC - DRP - case ID None

      CaseID Title CaseStatus DateCreated ResolutionStatus CreatedBy
      08baa0d0-1a54-11ea-94e8-0ee0a3f3cb1c =?gb2312?B? Rejected 2019-12-09T07:18:01Z Accidental creation ID: 30c2e916
      Name: soc.phishlabs
      DisplayName: SOC PhishLabs

      3. phishlabs-ioc-drp-get-open-cases


      Get open cases of Phishlabs DRP service by filters

      Base Command

      phishlabs-ioc-drp-get-open-cases

      Input
      </tr> </tbody> </table>

       

      Context Output
      Argument Name Description Required
      case_type Filter cases by case type Optional
      max_records Maximum number of cases to return, default is 20, maximum is 200 Optional
      offset Paginate results used in conjunction with maxRecords, first 200 records maxRecords=200&offset=0 second 200 records maxRecords=200&offset=200 Optional
      date_field Field to use to query using dateBegin and dateEnd parameters. Optional
      begin_date Date query beginning date Optional
      end_date Date query beginning date Optional
      period timestamp ( , e.g., 12 hours, 7 days)</td> Optional
      Path Type Description
      PhishlabsIOC.DRP.CaseID String Case ID
      PhishlabsIOC.DRP.Title String Case title
      PhishlabsIOC.DRP.Description String Case description
      PhishlabsIOC.DRP.CaseNumber String Case number
      PhishlabsIOC.DRP.Resolution String Resolution
      PhishlabsIOC.DRP.ResolutionStatus String Resolution status
      PhishlabsIOC.DRP.CreatedBy.ID String Case creator ID
      PhishlabsIOC.DRP.CreatedBy.Name String Case creator name
      PhishlabsIOC.DRP.CreatedBy.DisplayName String Case creator display name
      PhishlabsIOC.DRP.Brand String Brand reported in case
      PhishlabsIOC.DRP.Email String Email of case creator
      PhishlabsIOC.DRP.CaseType String Type of the case
      PhishlabsIOC.DRP.CaseStatus String Status of the case
      PhishlabsIOC.DRP.DateCreated String Case creation date
      PhishlabsIOC.DRP.DateClosed String Case closing date
      PhishlabsIOC.DRP.DateModified String Case modification date
      PhishlabsIOC.DRP.Customer String Customer reporting the case
      PhishlabsIOC.DRP.AttackSources.URL String URL of the attack source
      PhishlabsIOC.DRP.AttackSources.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AttackSources.IP String IP of the attack source
      PhishlabsIOC.DRP.AttackSources.ISP String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.Country String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AttackSources.FQDN String FQDN of the attack source
      PhishlabsIOC.DRP.AttackSources.Domain String Domain of the attack source
      PhishlabsIOC.DRP.AttackSources.IsMaliciousDomain Boolean Detect if domain of attack source is malicious
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AttackSources.WhoIs.NameServers String Name servers of the URL
      PhishlabsIOC.DRP.Attachments.ID String ID of case attachment
      PhishlabsIOC.DRP.Attachments.Type String Type of case attachment
      PhishlabsIOC.DRP.Attachments.Description String Description of case attachment
      PhishlabsIOC.DRP.Attachments.DateAdded String Date adding of case attachment
      PhishlabsIOC.DRP.Attachments.FileName String File name of case attachment
      PhishlabsIOC.DRP.Attachments.FileURL String File URL of case attachment
      PhishlabsIOC.DRP.ApplicationName String Application reported in the case
      PhishlabsIOC.DRP.Platform String Platform reported in the case
      PhishlabsIOC.DRP.Severity String Sevirity of DRP
      PhishlabsIOC.DRP.Developer String Developer of the application reported
      PhishlabsIOC.DRP.DeveloperWebsite String Developer website of the application reported
      PhishlabsIOC.DRP.ApplicationDescription String Descripion of the application reported
      PhishlabsIOC.DRP.Language String Language of the application reported
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.Phone String Phone number of case creator
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.AssociatedURLs.URL String URL of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.NameServers String Name servers of the URL

       

      Command Example

      !phishlabs-ioc-drp-get-open-cases max_records=2

      Context Example
      {
          "PhishLabsIOC": {
              "DRP": [
                  {
                      "Attachments": [
                          {
                              "DateAdded": "2019-08-16T18:10:53Z",
                              "Description": "Proof CBS owns Maxpreps brand. Requesting take down of maxpreps.us",
                              "FileName": "CBS Maxpreps.png",
                              "FileURL": "https://caseapi.phishlabs.com/v1/data/attachment/2fca6455",
                              "ID": "2fca6455",
                              "Type": "Email"
                          }
                      ],
                      "CaseID": "7cc6d097",
                      "CaseNumber": 1254167,
                      "CaseStatus": "Assigned",
                      "CaseType": "Other",
                      "CreatedBy": {
                          "DisplayName": "Matt T.",
                          "ID": "1e59f06d",
                          "Name": "mtwitty"
                      },
                      "Customer": "PhishLabs",
                      "DateClosed": "0001-01-01T00:00:00Z",
                      "DateCreated": "2019-08-09T21:20:18Z",
                      "DateModified": "2019-11-01T18:13:21Z",
                      "Description": "Courtesy case for CBS ",
                      "Title": " Brand Abuse"
                  }
              ]
          }
      }
      
      Human Readable Output

      PhishLabs IOC - DRP - open cases

      CaseID Title CaseStatus DateCreated CreatedBy
      7cc6d097-baeb-11e9-94e8-0ee0a3f3cb1c Brand Abuse Assigned 2019-08-09T21:20:18Z ID: 1e59f06d-7b03-11e4-b9b0-0025902add30
      Name: mtwitty
      DisplayName: Matt T.

      4. phishlabs-ioc-drp-get-closed-cases


      Get closed cases of Phishlabs DRP service by filters

      Base Command

      phishlabs-ioc-drp-get-closed-cases

      Input
      </tr> </tbody> </table>

       

      Context Output
      Argument Name Description Required
      case_type Filter cases by case type Optional
      max_records maximum number of cases to return, default is 20, maximum is 200 Optional
      offset Paginate results used in conjunction with maxRecords, first 200 records maxRecords=200&offset=0 second 200 records maxRecords=200&offset=200 Optional
      Date_field Field to use to query using dateBegin and dateEnd parameters. Optional
      begin_date Date query beginning date Optional
      end_date Date query beginning date Optional
      period timestamp ( , e.g., 12 hours, 7 days)</td> Optional
      Path Type Description
      PhishlabsIOC.DRP.CaseID String Case ID
      PhishlabsIOC.DRP.Title String Case title
      PhishlabsIOC.DRP.Description String Case description
      PhishlabsIOC.DRP.CaseNumber String Case number
      PhishlabsIOC.DRP.Resolution String Resolution
      PhishlabsIOC.DRP.ResolutionStatus String Resolution status
      PhishlabsIOC.DRP.CreatedBy.ID String Case creator ID
      PhishlabsIOC.DRP.CreatedBy.Name String Case creator name
      PhishlabsIOC.DRP.CreatedBy.DisplayName String Case creator display name
      PhishlabsIOC.DRP.Brand String Brand reported in case
      PhishlabsIOC.DRP.Email String Email of case creator
      PhishlabsIOC.DRP.CaseType String Type of the case
      PhishlabsIOC.DRP.CaseStatus String Status of the case
      PhishlabsIOC.DRP.DateCreated String Case creation date
      PhishlabsIOC.DRP.DateClosed String Case closing date
      PhishlabsIOC.DRP.DateModified String Case modification date
      PhishlabsIOC.DRP.Customer String Customer reporting the case
      PhishlabsIOC.DRP.AttackSources.URL String URL of the attack source
      PhishlabsIOC.DRP.AttackSources.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AttackSources.IP String IP of the attack source
      PhishlabsIOC.DRP.AttackSources.ISP String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.Country String ISP of the attack source
      PhishlabsIOC.DRP.AttackSources.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AttackSources.FQDN String FQDN of the attack source
      PhishlabsIOC.DRP.AttackSources.Domain String Domain of the attack source
      PhishlabsIOC.DRP.AttackSources.IsMaliciousDomain Boolean Detect if domain of attack source is malicious
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AttackSources.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AttackSources.WhoIs.NameServers String Name servers of the URL
      PhishlabsIOC.DRP.Attachments.ID String ID of case attachment
      PhishlabsIOC.DRP.Attachments.Type String Type of case attachment
      PhishlabsIOC.DRP.Attachments.Description String Description of case attachment
      PhishlabsIOC.DRP.Attachments.DateAdded String Date adding of case attachment
      PhishlabsIOC.DRP.Attachments.FileName String File name of case attachment
      PhishlabsIOC.DRP.Attachments.FileURL String File URL of case attachment
      PhishlabsIOC.DRP.ApplicationName String Application reported in the case
      PhishlabsIOC.DRP.Platform String Platform reported in the case
      PhishlabsIOC.DRP.Severity String Sevirity of DRP
      PhishlabsIOC.DRP.Developer String Developer of the application reported
      PhishlabsIOC.DRP.DeveloperWebsite String Developer website of the application reported
      PhishlabsIOC.DRP.ApplicationDescription String Descripion of the application reported
      PhishlabsIOC.DRP.Language String Language of the application reported
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.Phone String Phone number of case creator
      PhishlabsIOC.DRP.Hardware String Hardware used by the application
      PhishlabsIOC.DRP.AssociatedURLs.URL String URL of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.UrlType String URL type of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.TargetedBrands String Target brands of the attack source
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registrant String URL of the registrant
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Created String Creation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Expires String Expiriation date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Updated String Update date of the registration
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.Registration.Registrar String Registrar of the URL
      PhishlabsIOC.DRP.AssociatedURLs.WhoIs.NameServers String Name servers of the URL

       

      Command Example

      !phishlabs-ioc-drp-get-closed-cases max_records=2

      Context Example
      {
          "PhishLabsIOC": {
              "DRP": [
                  {
                      "Attachments": [
                          {
                              "DateAdded": "2019-12-09T07:56:02Z",
                              "Description": "Source Email for case creation",
                              "FileName": "msg.mFAH.eml",
                              "FileURL": "https://caseapi.phishlabs.com/v1/data/attachment/581ba28d",
                              "ID": "581ba28d-1a59-11ea-8247-0ad24386a0d6",
                              "Type": "Email"
                          }
                      ],
                      "CaseID": "5808ec5a",
                      "CaseNumber": 1417871,
                      "CaseStatus": "Rejected",
                      "CaseType": "Other",
                      "CreatedBy": {
                          "DisplayName": "SOC PhishLabs",
                          "ID": "30c2e916",
                          "Name": "soc.phishlabs"
                      },
                      "Customer": "PhishLabs",
                      "DateClosed": "2019-12-09T08:01:34Z",
                      "DateCreated": "2019-12-09T07:56:01Z",
                      "DateModified": "2019-12-09T08:01:34Z",
                      "Description": "From: PhishLabs Security Operations <soc@phishlabs.com>\nSubject:",
                      "ResolutionStatus": "Accidental creation",
                      "Title": "=?gb2312?B?Rlc6I"
                  },
                  {
                      "Attachments": [
                          {
                              "DateAdded": "2019-12-09T07:46:02Z",
                              "Description": "Source Email for case creation",
                              "FileName": "msg.fKAH.eml",
                              "FileURL": "https://caseapi.phishlabs.com/v1/data/attachment/f24c36a3",
                              "ID": "f24c36a3",
                              "Type": "Email"
                          }
                      ],
                      "CaseID": "f239fe62",
                      "CaseNumber": 1417866,
                      "CaseStatus": "Rejected",
                      "CaseType": "Other",
                      "CreatedBy": {
                          "DisplayName": "SOC PhishLabs",
                          "ID": "30c2e916",
                          "Name": "soc.phishlabs"
                      },
                      "Customer": "PhishLabs",
                      "DateClosed": "2019-12-09T07:49:11Z",
                      "DateCreated": "2019-12-09T07:46:01Z",
                      "DateModified": "2019-12-09T07:49:11Z",
                      "Description": "From: PhishLabs Security ",
                      "ResolutionStatus": "Accidental creation",
                      "Title": "?="
                  }
              ]
          }
      }
      
      Human Readable Output

      PhishLabs IOC - DRP - Closed cases

      CaseID Title CaseStatus DateCreated ResolutionStatus CreatedBy
      5808ec5a ?= Rejected 2019-12-09T07:56:01Z Accidental creation ID: 30c2e916 SOC PhishLabs
      f239fe62c =1?= Rejected 2019-12-09T07:46:01Z Accidental creation ID: 30c2e916
      Name: soc.phishlabs
      DisplayName: SOC PhishLabs

Configuration parameters

  • url — Server URL (e.g. https://example.net) (required)
  • credentials — User (required)
  • isFetch — Fetch incidents
  • incidentType — Incident type
  • incidentFetchInterval — Incidents Fetch Interval
  • fetchTime — First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)
  • fetchByDate — Fetch by date field
  • fetchLimit — Fetch limit (minimum is 20)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (4)

  • phishlabs-ioc-drp-get-case-by-id

    Retrieves a case by the case ID.

  • phishlabs-ioc-drp-get-cases

    Retrieves cases by the specified filters.

  • phishlabs-ioc-drp-get-closed-cases

    Get closed cases by filters.

  • phishlabs-ioc-drp-get-open-cases

    Retrieves open cases by the specified filters.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

""" IMPORTS """
# Std imports
from datetime import datetime

# 3-rd party imports
from typing import Any, AnyStr

import urllib3

# Local imports
from CommonServerUserPython import *

"""GLOBALS/PARAMS

Attributes:
    INTEGRATION_NAME:
        Name of the integration as shown in the integration UI, for example: Microsoft Graph User.

    INTEGRATION_COMMAND_NAME:
        Command names should be written in all lower-case letters,
        and each word separated with a hyphen, for example: msgraph-user.

    INTEGRATION_CONTEXT_NAME:
        Context output names should be written in camel case, for example: MSGraphUser.
"""
INTEGRATION_NAME = "PhishLabs IOC - DRP"
INTEGRATION_COMMAND_NAME = "phishlabs-ioc-drp"
INTEGRATION_CONTEXT_NAME = "PhishLabsIOC"

# Disable insecure warnings
urllib3.disable_warnings()


class Client(BaseClient):
    def test_module(self) -> dict:
        """Performs basic GET request to check if the API is reachable and authentication is successful.

        Returns:
            Response json
        """
        return self.get_cases(max_records=2)

    def travel_to_end_date(
        self, cases_temp: list, params: dict, end_date: str | None, date_field: str, suffix: str
    ) -> tuple[list[Any], dict[Any, Any], int, datetime | None]:
        """Moving index to starting point, if neccery chage cases_temp (more get request)

        Args:
            cases_temp: case as starting point assuming list sorted by date
            params: query params
            end_date: end date of the query searched
            date_field: date field to apply end date filter
            suffix: suffix of url

        Returns:
            Tuple of (list of cases temp, modified params, index in cases, datetime object of last run in traveling)
        """
        format_time = "%Y-%m-%dT%H:%M:%SZ"
        last_time: datetime | None = None if not cases_temp else datetime.strptime(cases_temp[0].get(date_field), format_time)
        end_date_obj: datetime = datetime.strptime(end_date, format_time) if end_date else datetime.now()

        index = 0
        while end_date_obj and last_time:
            if end_date_obj < last_time:
                if len(cases_temp) == index + 1:
                    params["offset"] += len(cases_temp)
                    cases_temp = self._http_request("GET", url_suffix=suffix, params=assign_params(**params), timeout=20).get(
                        "data", []
                    )
                    index = 0
                    if not cases_temp:
                        break
                else:
                    index += 1
                last_time = datetime.strptime(cases_temp[index].get(date_field), format_time)
            else:
                break

        return cases_temp, params, index, last_time

    def travel_to_begin_date(
        self,
        cases_temp: list,
        index: int,
        params: dict,
        begin_date: str | None,
        last_time: datetime | None,
        date_field: str,
        max_records: str | int,
        suffix: str,
    ) -> list[dict[Any, Any]]:
        """

        Args:
            suffix: suffix of url
            cases_temp: case as starting point assuming list sorted by date
            index: current traveling point in travelling
            params: query params
            begin_date: begin date to move while traveling case
            last_time: last time of last case visited
            date_field: date field to apply end date filter
            max_records: max records to get in this query
            suffix: suffix of url

        Returns:
            List of cases filtered by date
        """
        format_time = "%Y-%m-%dT%H:%M:%SZ"
        begin_date_obj: datetime | None = datetime.strptime(begin_date, format_time) if begin_date else None
        cases: list = []

        while cases_temp and len(cases) < int(max_records) and last_time:
            if begin_date_obj:
                if last_time > begin_date_obj:
                    cases.append(cases_temp[index])
                else:
                    break
            else:
                cases.append(cases_temp[index])

            if len(cases) == max_records:
                break
            if len(cases_temp) == index + 1:
                params["offset"] += len(cases_temp)
                cases_temp = self._http_request("GET", url_suffix=suffix, params=assign_params(**params), timeout=20).get(
                    "data", []
                )
                index = 0
                if not cases_temp:
                    break
            else:
                index += 1
            last_time = datetime.strptime(cases_temp[index].get(date_field), format_time)
        return cases

    def get_cases(
        self,
        status: str | None = None,
        case_type: str | None = None,
        max_records: str | int = 20,
        offset: str | int = 0,
        date_field: str = "dateModified",
        begin_date: str | None = None,
        end_date: str | None = None,
        query_type: str = "",
        period: str | None = None,
    ) -> dict:
        """
        Query the specified kwargs with default parameters if not defined

        Args:
            status: Filter cases based on the case status
            case_type: Filter cases by case type
            max_records: Maximum number of cases to return, default is 20, maximum is 200
            offset: Paginate results used in conjunction with maxRecords
            date_field: Field to use to query using dateBegin and dateEnd parameters.
            begin_date: Date query beginning date
            end_date: Date query beginning date
            query_type: query type influence on suffix - all/open/closed
            period: timestamp (<number> <time unit>, e.g., 12 hours, 7 days)

        Returns:
            Response JSON as dictionary
        """
        if period:
            begin_date, end_date = parse_date_range(date_range=period, date_format="%Y-%m-%dT%H:%M:%SZ")
        suffix: str = f"/cases/{query_type}" if query_type else "/cases"
        params: dict = {"status": status, "type": case_type, "offset": int(offset), "maxRecords": int(max_records)}
        raw_response: dict = self._http_request("GET", url_suffix=suffix, params=assign_params(**params), timeout=20)
        cases_temp: list = raw_response.get("data", [])
        # About the drop some mean regex right now disable-secrets-detection-start
        cases_temp, params, index, last_time = self.travel_to_end_date(cases_temp, params, end_date, date_field, suffix)
        cases = self.travel_to_begin_date(cases_temp, index, params, begin_date, last_time, date_field, max_records, suffix)
        # Drops the mic disable-secrets-detection-end
        raw_response["header"]["returnResult"] = len(cases)
        raw_response["header"]["totalResult"] = len(cases)
        raw_response["header"]["queryParams"]["maxRecords"] = len(cases)
        raw_response["data"] = cases

        return raw_response

    def get_case_by_id(self, case_id: str) -> dict:
        """Query incident by ID

        Args:
            case_id: ID of the case

        Returns:
            Response JSON as dictionary
        """
        suffix = f"/cases/{case_id}"
        return self._http_request("GET", url_suffix=suffix)


""" HELPER FUNCTIONS """


@logger
def indicator_ec(indicator: dict, type_ec: AnyStr) -> dict:
    """indicator convert to ec format
    Get an indicator from raw response and concert to demisto entry context format

    Args:
        indicator: raw response dictionary
        type_ec: type of entry context

    Returns:
         indicator entry context
    """
    ec: dict = {}
    if type_ec == "AttackSources":
        ec = {
            "URL": indicator.get("url"),
            "UrlType": indicator.get("urlType"),
            "IP": indicator.get("ipAddress"),
            "ISP": indicator.get("isp"),
            "Country": indicator.get("country"),
            "TargetedBrands": indicator.get("targetedBrands"),
            "FQDN": indicator.get("fqdn"),
            "Domain": indicator.get("domain"),
            "IsMaliciousDomain": indicator.get("isMaliciousDomain"),
            "WhoIs": {
                "Registrant": indicator.get("whois", {}).get("registrant"),
                "Registration": {
                    "Created": indicator.get("whois", {}).get("registration", {}).get("created"),
                    "Expires": indicator.get("whois", {}).get("registration", {}).get("expires"),
                    "Updated": indicator.get("whois", {}).get("registration", {}).get("updated"),
                    "Registrar": indicator.get("whois", {}).get("registration", {}).get("registrar"),
                    "NameServers": indicator.get("whois", {}).get("name_servers"),
                },
            },
        }
    elif type_ec == "Attachments":
        ec = {
            "ID": indicator.get("id"),
            "Type": indicator.get("type"),
            "Description": indicator.get("description"),
            "DateAdded": indicator.get("dateAdded"),
            "FileName": indicator.get("fileName"),
            "FileURL": indicator.get("fileURL"),
        }
    elif type_ec == "AssociatedURLs":
        ec = {
            "URL": indicator.get("url"),
            "UrlType": indicator.get("urlType"),
            "TargetedBrands": indicator.get("targetedBrands"),
            "WhoIs": {
                "Registrant": indicator.get(""),
                "Registration": {
                    "Created": indicator.get("whois", {}).get("registration", {}).get("created"),
                    "Expires": indicator.get("whois", {}).get("registration", {}).get("expires"),
                    "Updated": indicator.get("whois", {}).get("registration", {}).get("updated"),
                    "Registrar": indicator.get("whois", {}).get("registration", {}).get("registrar"),
                    "NameServers": indicator.get("whois", {}).get("name_servers"),
                },
            },
        }

    return assign_params(**ec)


@logger
def indicators_to_list_ec(indicators: list, type_ec: AnyStr) -> tuple[list, list] | list:
    """Unpack list of incidents to demisto ec format
    Convert list of incidents from raw response to demisto entry context format lists

    Args:
        indicators: lit of indicators from raw response
        type_ec: type of indicators
    Returns:
         List of indicators entry context
    """
    ecs: list = []
    for indicator in indicators:
        ec = indicator_ec(indicator, type_ec)
        ecs.append(ec)
    return ecs


@logger
def raw_response_to_context(cases: list | Any) -> list:
    """
    Convert incidents list from raw response to demisto entry context list format
    Args:
        cases: Incidents list

    Returns:
        Entry contexts of phishLabs, emails, files, urls, dbotScores
    """
    phishlabs_ec: list = []
    for case in cases:
        # PhishLabs entry context
        phishlabs: dict = {
            "CaseID": case.get("caseId"),
            "Title": case.get("title"),
            "Description": case.get("description"),
            "CaseNumber": case.get("caseNumber"),
            "Resolution": case.get("resolution"),
            "ResolutionStatus": case.get("resolutionStatus"),
            "CreatedBy": {
                "ID": case.get("createdBy", {}).get("id"),
                "Name": case.get("createdBy", {}).get("name"),
                "DisplayName": case.get("createdBy", {}).get("displayName"),
            },
            "Brand": case.get("brand"),
            "Email": case.get("emailAddress"),
            "CaseType": case.get("caseType"),
            "CaseStatus": case.get("caseStatus"),
            "DateCreated": case.get("dateCreated"),
            "DateClosed": case.get("dateClosed"),
            "DateModified": case.get("dateModified"),
            "Customer": case.get("customer"),
            "AttackSources": indicators_to_list_ec(indicators=case.get("attackSources", []), type_ec="AttackSources"),
            "Attachments": indicators_to_list_ec(indicators=case.get("attachments", []), type_ec="Attachments"),
            "ApplicationName": case.get("applicationName"),
            "Platform": case.get("platform"),
            "Severity": case.get("severity"),
            "Developer": case.get("developer"),
            "DeveloperWebsite": case.get("developerWebsite"),
            "ApplicationDescription": case.get("applicationDescripion"),
            "Language": case.get("language"),
            "Hardware": case.get("hardware"),
            "Phone": case.get("phoneNumber"),
            "AssociatedURLs": indicators_to_list_ec(indicators=case.get("associatedURLs", []), type_ec="AssociatedURLs"),
        }
        phishlabs_ec.append(assign_params(**phishlabs))

    return phishlabs_ec


""" COMMANDS """


@logger
def test_module_command(client: Client, *_) -> tuple[None, None, str]:
    """Performs a basic GET request to check if the API is reachable and authentication is successful.

    Args:
        client: Client object with request
        *_: Usually demisto.args()

    Returns:
        'ok' if test successful.

    Raises:
        DemistoException: If test failed.
    """
    results = client.test_module()
    if "data" in results:
        return None, None, "ok"
    raise DemistoException(f"Test module failed, {results}")


@logger
def fetch_incidents_command(
    client: Client, fetch_time: str, max_records: str | int, date_field: str = "dateModified", last_run: str | None = None
) -> tuple[list[dict[str, Any]], dict]:
    """Uses to fetch incidents into Demisto
    Documentation: https://github.com/demisto/content/tree/master/docs/fetching_incidents

    Args:
        date_field: filter date is by dateCreated / dateClosed / dateModified
        client: Client object with request
        fetch_time: From when to fetch if first time, e.g. `3 days`
        max_records: limit of incidents in a fetch
        last_run: Last fetch object occurs.

    Returns:
        incidents, new last_run
    """
    occurred_format = "%Y-%m-%dT%H:%M:%SZ"
    if not last_run:
        datetime_new_last_run, _ = parse_date_range(date_range=fetch_time, date_format=occurred_format)
    else:
        datetime_new_last_run = last_run
    raw_response = client.get_cases(begin_date=datetime_new_last_run, date_field=date_field, max_records=max_records)
    cases_raw: list = raw_response.get("data", [])
    cases_report = []
    if cases_raw:
        datetime_new_last_run = cases_raw[0].get(date_field)
        for case in cases_raw:
            cases_report.append(
                {
                    "name": f"{INTEGRATION_NAME}: {case.get('caseId')}",
                    "occurred": case.get(date_field),
                    "rawJSON": json.dumps(case),
                }
            )

    return cases_report, datetime_new_last_run


@logger
def get_cases_command(client: Client, args: dict) -> tuple[object, dict, list | dict]:
    """Get all case by filters and return outputs in Demisto's context entry

    Args:
        client: Client object with request
        args: demisto.args() dictionary

    Returns:
        human readable (markdown format), entry context and raw response
    """
    raw_response: dict = client.get_cases(
        status=args.get("status"),
        case_type=args.get("case_type"),
        max_records=args.get("max_records", 20),
        offset=args.get("offset", 0),
        date_field=args.get("date_field", "dateModified"),
        begin_date=args.get("begin_date"),
        end_date=args.get("end_date"),
        period=args.get("period"),
    )
    if raw_response:
        title = f"{INTEGRATION_NAME} - cases"
        phishlabs_ec = raw_response_to_context(raw_response.get("data", []))
        context_entry: dict = {
            f"{INTEGRATION_CONTEXT_NAME}(val.DRP.CaseID && val.EIR.CaseID === obj.DRP.CaseID && "
            f"val.DRP.DateModified && val.DRP.DateModified === obj.DRP.DateModified)": {"DRP": phishlabs_ec}
        }
        human_readable = tableToMarkdown(
            name=title,
            t=phishlabs_ec,
            headers=["CaseID", "Title", "CaseStatus", "DateCreated", "Resolution", "ResolutionStatus", "CreatedBy"],
            removeNull=True,
        )

        return human_readable, context_entry, raw_response
    else:
        return f"{INTEGRATION_NAME} - Could not find any results for given query", {}, {}


@logger
def get_case_by_id_command(client: Client, args: dict) -> tuple[object, dict, list | dict]:
    """Get case by ID and return outputs in Demisto's context entry

    Args:
        client: Client object with request
        args: demisto.args() dictionary

    Returns:
        human readable (markdown format), entry context and raw response
    """
    case_id = args.get("case_id", "")
    raw_response: dict = client.get_case_by_id(case_id=case_id)
    if raw_response:
        title = f"{INTEGRATION_NAME} - case ID {case_id}"
        phishlabs_ec = raw_response_to_context(raw_response.get("data", []))
        context_entry: dict = {
            f"{INTEGRATION_CONTEXT_NAME}(val.DRP.CaseID && val.EIR.CaseID === obj.DRP.CaseID && "
            f"val.DRP.DateModified && val.DRP.DateModified === obj.DRP.DateModified)": {"DRP": phishlabs_ec}
        }
        human_readable = tableToMarkdown(
            name=title,
            t=phishlabs_ec,
            headers=["CaseID", "Title", "CaseStatus", "DateCreated", "Resolution", "ResolutionStatus", "CreatedBy"],
            removeNull=True,
        )

        return human_readable, context_entry, raw_response
    else:
        return f"{INTEGRATION_NAME} - Could not find any results for given query", {}, {}


@logger
def get_open_cases_command(client: Client, args: dict) -> tuple[object, dict, list | dict]:
    """Get all open case by filters and return outputs in Demisto's context entry

    Args:
        client: Client object with request
        args: demisto.args() dictionary

    Returns:
        human readable (markdown format), entry context and raw response
    """
    raw_response: dict = client.get_cases(
        status=args.get("status"),
        case_type=args.get("case_type"),
        max_records=args.get("max_records", 20),
        offset=args.get("offset", 0),
        date_field=args.get("date_field", "dateModified"),
        begin_date=args.get("begin_date"),
        end_date=args.get("end_date"),
        period=args.get("period"),
        query_type="open",
    )
    if raw_response:
        title = f"{INTEGRATION_NAME} - open cases"
        phishlabs_ec = raw_response_to_context(raw_response.get("data", []))
        context_entry: dict = {
            f"{INTEGRATION_CONTEXT_NAME}(val.DRP.CaseID && val.EIR.CaseID === obj.DRP.CaseID && "
            f"val.DRP.DateModified && val.DRP.DateModified === obj.DRP.DateModified)": {"DRP": phishlabs_ec}
        }
        human_readable = tableToMarkdown(
            name=title,
            t=phishlabs_ec,
            headers=["CaseID", "Title", "CaseStatus", "DateCreated", "Resolution", "ResolutionStatus", "CreatedBy"],
            removeNull=True,
        )

        return human_readable, context_entry, raw_response
    else:
        return f"{INTEGRATION_NAME} - Could not find any results for given query", {}, {}


@logger
def get_closed_cases_command(client: Client, args: dict) -> tuple[object, dict, list | dict]:
    """Get all closed case by filters and return outputs in Demisto's context entry

    Args:
        client: Client object with request
        args: demisto.args() dictionary

    Returns:
        human readable (markdown format), entry context and raw response
    """
    raw_response: dict = client.get_cases(
        status=args.get("status"),
        case_type=args.get("case_type"),
        max_records=args.get("max_records", 20),
        offset=args.get("offset", 0),
        date_field=args.get("date_field", "dateModified"),
        begin_date=args.get("begin_date"),
        end_date=args.get("end_date"),
        period=args.get("period"),
        query_type="closed",
    )
    if raw_response:
        title = f"{INTEGRATION_NAME} - Closed cases"
        phishlabs_ec = raw_response_to_context(raw_response.get("data", []))
        context_entry: dict = {
            f"{INTEGRATION_CONTEXT_NAME}(val.DRP.CaseID && val.EIR.CaseID === obj.DRP.CaseID && "
            f"val.DRP.DateModified && val.DRP.DateModified === obj.DRP.DateModified)": {"DRP": phishlabs_ec}
        }
        human_readable = tableToMarkdown(
            name=title,
            t=phishlabs_ec,
            headers=["CaseID", "Title", "CaseStatus", "DateCreated", "Resolution", "ResolutionStatus", "CreatedBy"],
            removeNull=True,
        )

        return human_readable, context_entry, raw_response
    else:
        return f"{INTEGRATION_NAME} - Could not find any results for given query", {}, {}


""" COMMANDS MANAGER / SWITCH PANEL """


def main():
    params = demisto.params()
    base_url = urljoin(params.get("url"), "/v1/data")
    verify_ssl = not params.get("insecure", False)
    proxy = params.get("proxy")
    client = Client(
        base_url=base_url,
        verify=verify_ssl,
        proxy=proxy,
        auth=(params.get("credentials", {}).get("identifier"), params.get("credentials", {}).get("password")),
    )
    command = demisto.command()
    demisto.debug(f"Command being called is {command}")
    commands = {
        "test-module": test_module_command,
        f"{INTEGRATION_COMMAND_NAME}-get-cases": get_cases_command,
        f"{INTEGRATION_COMMAND_NAME}-get-case-by-id": get_case_by_id_command,
        f"{INTEGRATION_COMMAND_NAME}-get-open-cases": get_open_cases_command,
        f"{INTEGRATION_COMMAND_NAME}-get-closed-cases": get_closed_cases_command,
    }
    try:
        if command == "fetch-incidents":
            incidents, new_last_run = fetch_incidents_command(
                client,
                fetch_time=params.get("fetchTime"),
                last_run=demisto.getLastRun().get("lastRun"),
                max_records=params.get("fetchLimit"),
                date_field=params.get("fetchByDate"),
            )
            demisto.incidents(incidents)
            demisto.setLastRun({"lastRun": new_last_run})
        else:
            readable_output, outputs, raw_response = commands[command](client=client, args=demisto.args())
            return_outputs(readable_output, outputs, raw_response)

    except Exception as e:
        err_msg = f"Error in {INTEGRATION_NAME} Integration [{e}]"
        return_error(err_msg, error=e)


if __name__ == "builtins":
    main()