Integrate Code42 with Sumo Logic

Overview

Sumo Logic is a security information and event management (SIEM) tool that helps you detect and respond to threats. This tutorial explains how to collect and automatically import file exfiltration event data from Code42 into Sumo Logic. 

Watch the short video below to learn how Incydr integrates with Sumo Logic. For more videos, visit the Code42 University.

Considerations

  • Python version 3.5 or later is required. For instructions on downloading and installing Python, see the Python documentation
  • Your orchestration server must be able to connect via SSL (ports 80 and 443) to your Code42 console address. 

Before you begin

Create an API client

In the Code42 console, create an API client to provide permissions in the CLI for the integration with Sumo Logic:

Install and configure the Code42 CLI

To integrate with Sumo Logic, you must first install the Code42 CLI and create a profile following the instructions in https://clidocs.code42.com.

Step 1: Collect file exfiltration event data

Collect file exfiltration event data from Code42 using either a cron job or automated task, or using the Sumo Logic Script Source collection method. 

Create a cron job or automated task

After you've completed the steps of creating a user and setting up the Code42 CLI, create an automated task or cron job for running a query on a scheduled basis

Linux cron job

Windows automated task

Use a Sumo Logic Script Source

You can also use a Sumo Logic Script Source to collect file exfiltration event data from Code42. For instructions on setting up and using a Script Source, see the Sumo Logic documentation

Step 2: Configure log collection into Sumo Logic 

Download, install, and configure the Sumo Logic collector either on the orchestration server you are using for the Code42 CLI or on another system. 

  1. Sign in to the Sumo Logic console. 
  2. Click Manage Data > Collection from the left navigation bar.
  3. Click Add Collector.  
    Add collector
    The Select Collector Type dialog opens. 
    Select collector type
  4. Select either Installed Collector or Hosted Collector
    The Add Installed Collector or Add Hosted Collector dialog opens. 
    Add installed collector
  5. Click the link for the platform on which you want to install the collector. 
    The installer package downloads. 
  6. Follow the installation instructions for the platform you chose: 
  7. Once installed, the collector appears on the Collection tab. 

Step 3: Configure the Code42 source for collection by the agent

The following directions describe how to add a collector as a source from the Sumo Logic UI.

Sumo Logic Script Source
If you're using the the Sumo Logic Script Source collection method, configure the source following the Sumo Logic instructions.  
  1. Click Manage Data > Collection from the left navigation bar.
  2. Locate the collector you added in the previous steps. 
  3. Click Add > Add Source
    Add source
    The File Sources window opens. 
    File Sources
  4. Select a source.
    The configuration options appear (for Syslog in this example). 
    Configure syslog source
  5. Enter a Name for the source. 
  6. Select your Protocol and Port
  7. For the Timestamp Format, select Specify a format
    1. Enter the following Formatyyyy-MM-dd'T'HH:mm:ss.SSS'Z' 
    2. In the Timestamp locator field, enter a regular expression to locate the timestamp in your log line, for example: 
      \"eventTimestamp\":\s\"(.*?)\" 
      If no regex is provided, Sumo Logic automatically locates the timestamp.
      Timestamp format
    3. Click Add
  8. Click Save
    The source is configured and logs now flow from the orchestration server to your Sumo Logic environment. 

Log types

The available log types are as follows: 

  • Code42 Exposure Events
  • Code42 Non-Exposure Events 

Sample log message

{"eventId": "0_c4b5e830-824a-40a3-a6d9-345664cfbb33_941983451917189059_971295845574006661_193", 
"eventType": "READ_BY_APP", "eventTimestamp": "2020-09-09T20:55:47.087Z", 
"insertionTimestamp": "2020-09-09T20:57:22.179901Z", "fieldErrors": [], 
"filePath": "C:/Users/first.last/Documents/", "fileName": "filename.png", 
"fileType": "FILE", "fileCategory": "IMAGE", "fileCategoryByBytes": "Image", 
"fileCategoryByExtension": "Image", "fileSize": 4052619, "fileOwner": 
"first.last", "md5Checksum": "4d43da7448e03de913622559d35d84af", 
"sha256Checksum": "f25e1fb2665a6fa3edd505f4c4ffb8b5bd84a5f3e5373c0db8b76ebea678bedd", 
"createTimestamp": "2020-02-10T04:38:42Z", "modifyTimestamp": 
"2020-02-10T04:38:42Z", "deviceUserName": "vistor.welch@example.com", 
"osHostName": "FIRSTL-WIN10", "domainName": " FIRSTL-WIN10.example.com", 
"publicIpAddress": "XXX.XXX.XX.XXX", "privateIpAddresses": ["XXX.XXX.XX.XXX 
", "fe80:0:0:0:1d77:dcdf:c593:1143%eth4", "0:0:0:0:0:0:0:1", "127.0.0.1"], 
"deviceUid": "941983451917189059", "userUid": "902428473202283166", "actor": 
null, "directoryId": [], "source": "Endpoint", "url": null, "shared": null, 
"sharedWith": [], "sharingTypeAdded": [], "cloudDriveId": null, 
"detectionSourceAlias": null, "fileId": null, "exposure": 
["ApplicationRead"], "processOwner": "first.last", "processName": "\\Device\
\HarddiskVolume2\\Program Files (x86)\\Google\\Chrome\\Application\
\chrome.exe", "windowTitle": ["Files - OneDrive - Google Chrome"], "tabUrl": 
"https://my.sharepoint.com/personal/first_last_onmicrosoft_com/_layouts/15/
onedrive.aspx", "removableMediaVendor": null, "removableMediaName": null, 
"removableMediaSerialNumber": null, "removableMediaCapacity": null, 
"removableMediaBusType": null, "removableMediaMediaName": null, 
"removableMediaVolumeName": [], "removableMediaPartitionId": [], 
"syncDestination": null, "syncDestinationUsername": [], 
"emailDlpPolicyNames": null, "emailSubject": null, "emailSender": null, 
"emailFrom": null, "emailRecipients": null, "outsideActiveHours": false, 
"mimeTypeByBytes": "image/png", "mimeTypeByExtension": "image/png", 
"mimeTypeMismatch": false, "printJobName": null, "printerName": null, 
"printedFilesBackupPath": null, "remoteActivity": "TRUE", "trusted": true, 
"operatingSystemUser": "first.last"}

Step 4: Configure the Code42 dashboard 

The Code42 Incydr app for Sumo Logic gives you the ability to detect and respond to insider threats while providing data protection for the collaborative and remote enterprise with simplicity, signal, and speed.
 
Use this dashboard to:

  • Detect and respond to data leakage and theft from corporate cloud, email and computer systems
  • Visualize file sharing activity in Slack, OneDrive, Google Drive, Box, Zoom, and more
  • Display file telemetry data based on file name, user, or endpoint association
Update query URLs as needed
If you sign in to the Code42 console at https://console.us.code42.com, all dashboard panels work by default. If you sign in to the Code42 console using a different URL, you must update the queries for the following dashboards to use your Code42 console URL instead:
  • Top 10 exposed files
  • Malicious MD5s
  • Top 10 endpoint users by exposure type
  • Top 10 cloud users by exposure type

Install the Code42 Incydr app for Sumo Logic

To install the Code42 Incydr app: 

  1. Sign in to the Sumo Logic console. 
  2. Click App Catalog
  3. Search for and select the Code42 Incydr app. 
  4. Select the version of the service you're using.
  5. Click Add to Library

Incydr dashboard

Filter the dashboard

Click the filter icon in the top-left corner of the dashboard to display a list of filters you can apply across the entire dashboard. Use the filters to drill down and examine the data on a more granular level.

Main dashboard filter

Click the filter icon in the top-left corner of the panel to view a list of filters for that specific panel. 

Cloud exposures panel

Query samples 

You can use the following queries to create or modify your dashboard. As noted above, you may need to update the Code42 console URLs in these queries.

Cloud exposures

_sourceCategory="Your Code42 Source Here"
| json "source" AS SourceType | json "actor" AS User
| json "exposure[0]" as ExposureType 
| json auto keys "eventType","fileOwner","fileType","fileName","sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum","processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid"
| where !(SourceType="Endpoint")
| count as SourceCount by SourceType | sort by SourceCount

Endpoint exposures

_sourceCategory="Your Code42 Source Here"
| json "osHostName" AS Endpoint | json "source" AS SourceType | json "deviceUserName" AS User
| json "exposure[0]" as ExposureType | json "privateIpAddresses[0]" as IPAddress
| json auto keys "eventType","fileOwner","fileType","fileName","publicIpAddress", "sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum", "actor", "processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid"
| where SourceType="Endpoint"
| count as ExposureCount by ExposureType | sort by ExposureCount

Removable media exposure by user

_sourceCategory="Your Code42 Source Here"
| json field=_raw "osHostName" AS Endpoint | json “source" AS SourceType | json "deviceUserName" AS User
| json "exposure[0]" as ExposureType | json "privateIpAddresses[0]" as IPAddress
| json auto keys "eventType","fileOwner","fileType","fileName","publicIpAddress", "sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum", "actor", "processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid"
| parse field=User "*@*" as User, UserDomain 
| timeslice 1d
|where ExposureType matches "RemovableMedia"
|count by _timeslice, User | transpose row _timeslice column User

Exposure by location (map)

_sourceCategory="Your Code42 Source Here"
| json "osHostName" AS User_endpoint | json "source" AS source_type | json "deviceUserName" AS UserName
| json "exposure[0]" as exposure_type | json "privateIpAddresses[0]" 
| json auto keys "eventType","fileOwner","fileType","fileName","publicIpAddress", "sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum", "actor", "processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid"
| lookup latitude, longitude from geo://location on ip= publicIpAddress
| json field=_raw "filePath" | if(filePath matches "*:/*", substring(filePath,0,1),"") as driveletter
| count(exposure_type) as _count by latitude, longitude
| sort by _count

Top 10 files exposed

This dashboard includes links to the Code42 console for more details. 

_sourceCategory="Your Code42 Source Here"
| json "fileName" AS File
| json "md5Checksum" AS MD5
| if (isNull(MD5), "NA", MD5) as MD5
| urlencode (File) as URLName
| tourl(concat("https://console.us.code42.com/app/#/forensic-search/search/?t0=fileName&q0=IS&v0=", URLName, "&t1=eventTimestamp&q1=WITHIN_THE_LAST&v1=P30D"), File) as File
| tourl(concat("https://console.us.code42.com/app/#/forensic-search/search/?t0=md5Checksum&q0=IS&v0=", MD5, "&t1=eventTimestamp&q1=WITHIN_THE_LAST&v1=P30D"), MD5) as MD5
| count as FileCount by File, MD5 | sort by File
| top 10 File, MD5 by FileCount

Top 25 exposed files

_sourceCategory="Your Code42 Source Here"
| json "osHostName" AS Endpoint | json "source" AS SourceType | json "deviceUserName" AS User | json "fileName" AS File
| json "exposure[0]" as exposure_type | json "privateIpAddresses[0]" 
| json auto keys "eventType","fileOwner","fileType", "publicIpAddress", "sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum", "actor", "processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid"
| count as FileCount by File | sort by FileCount
| top 25 File by FileCount

Top 10 endpoint users by exposure type

This dashboard includes links to the Code42 console for more details. 

_sourceCategory="Your Code42 Source Here"
| json "osHostName" AS Endpoint | json "source" AS SourceType | json "deviceUserName" AS User
| json "exposure[0]" as ExposureType | json "privateIpAddresses[0]" as IPAddress
| json auto keys "eventType","fileOwner","fileType","fileName","publicIpAddress", "sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum", "actor", "processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid" 
| urlencode (User) as URLName
| tourl(concat("https://console.us.code42.com/app/#/forensic-search/search/?t0=deviceUserName&q0=IS&v0=", URLName, "&t1=exposureType&q1=IS_EITHER&v1%5B0%5D=RemovableMedia&v1%5B1%5D=ApplicationRead&v1%5B2%5D=CloudStorage&v1%5B3%5D=OutsideTrustedDomains&v1%5B4%5D=SharedToDomain&v1%5B5%5D=SharedViaLink&v1%5B6%5D=IsPublic&t2=eventTimestamp&q2=WITHIN_THE_LAST&v2=P30D"), User) as User
| count as ExposureCount by ExposureType, User | sort by ExposureType
| top 10 User, ExposureType by ExposureCount

Top 10 cloud users by exposure type

This dashboard includes links to the Code42 console for more details.

_sourceCategory="Your Code42 Source Here"
| json "source" AS SourceType | json "actor" AS User
| json "exposure[0]" as ExposureType 
| json auto keys "eventType","fileOwner","fileType","fileName","sha256Checksum", "filePath", "fileSize","fileCategory","md5Checksum", "actor", "processName", "processOwner" , "removableMediaSerialNumber", "removableMediaName", "removableMediaVendor", "syncDestination", "url", "userUid"
| urlencode (User) as URLName
| tourl(concat("https://console.us.code42.com/app/#/forensic-search/search/?t0=actor&q0=IS&v0=", URLName, "&t1=exposureType&q1=EXISTS&v1%5B0%5D=IsPublic&v1%5B1%5D=SharedViaLink&v1%5B2%5D=SharedToDomain&v1%5B3%5D=OutsideTrustedDomains&v1%5B4%5D=RemovableMedia&v1%5B5%5D=ApplicationRead&v1%5B6%5D=CloudStorage&t2=eventTimestamp&q2=WITHIN_THE_LAST&v2=P30D"), User) as User
| where !(source_type="Endpoint")
| count as ExposureCount by ExposureType, User | sort by ExposureType
| top 10 User, ExposureType by ExposureCount

Malicious MD5s

This dashboard compares MD5 hashes that exist on your Code42 devices to Crowdstrike's Indicators of Compromise (IOC) list, and only shows results if a match is found. It also includes links to the Code42 console for more details. For more information, see the Sumo Logic documentation

_sourceCategory="Your Code42 Source Here"
| json "md5Checksum" as MD5
| if (isNull(md5), "NA", MD5) as MD5
| lookup type, actor, raw, threatlevel as malicious_confidence from sumo://threat/cs on threat=MD5
| tourl(concat("https://console.us.code42.com/app/#/forensic-search/search/?t0=md5Checksum&q0=IS&v0=", md5, "&t1=eventTimestamp&q1=WITHIN_THE_LAST&v1=P30D"), MD5) as MD5
| where type= "hash_md5" and malicious_confidence = "high"
| count as MD5Count by MD5