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:
- User role: As a user with the Insider Risk Admin role, create an API client solely to be used by the integration with Sumo Logic.
- Permissions: Set the necessary API permissions in the API client to the minimal permissions needed by the integration. (After granting access in the CLI with the API client ID and secret, test to confirm that the necessary data is accessible in 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.
- Sign in to the Sumo Logic console.
- Click Manage Data > Collection from the left navigation bar.
- Click Add Collector.
The Select Collector Type dialog opens.
- Select either Installed Collector or Hosted Collector.
The Add Installed Collector or Add Hosted Collector dialog opens.
- Click the link for the platform on which you want to install the collector.
The installer package downloads. - Follow the installation instructions for the platform you chose:
- 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.
If you're using the the Sumo Logic Script Source collection method, configure the source following the Sumo Logic instructions.
- Click Manage Data > Collection from the left navigation bar.
- Locate the collector you added in the previous steps.
- Click Add > Add Source.
The File Sources window opens.
- Select a source.
The configuration options appear (for Syslog in this example).
- Enter a Name for the source.
- Select your Protocol and Port.
- For the Timestamp Format, select Specify a format.
- Enter the following Format:
yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
- 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.
- Click Add.
- Enter the following Format:
- 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
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:
- Sign in to the Sumo Logic console.
- Click App Catalog.
- Search for and select the Code42 Incydr app.
- Select the version of the service you're using.
- Click Add to Library.
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.
Click the filter icon in the top-left corner of the panel to view a list of filters for that specific 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