Approved

Query for emerging threat - Check your Pulse

  REVIEWED by Sophos 

Yesterday I got one of those alerts that I suspect many of you also receive, another security advisory.  This one was for folks who have the Pulse Secure VPN and mentioned that even after applying the patch the adversary could be getting in if you have not changed any passwords they stole. AA20-107A: Continued Threat Actor Exploitation Post Pulse Secure VPN Patching

We don't have the Pulse VPN at Sophos, but I wanted to see how quickly I could get a query built that would scan my devices and check if the IOCs the advisory pointed to were present or not.   They provided a nice list of IOCs,  filename paths, IP Addresses and Cmdline details that would have been used by the attacker.  The nice thing about that list of IOC's is they are all things the Sophos Endpoint records, so I wanted to build a query to search through the historic record the endpoints keep and see if any of my devices had any matches.

It took about 45 min to get the query written and working. 

Some things I learned.

  • This query will require central to support larger queries.
    • We are going to extend the size of the query from 4K to 50K for general availability in June.
  • Pulling a list of IOC's and putting them into a query is fairly straight forward once you get the first one written, future work in this area will be a lot easier.
  • It may be nice to have a way to directly import a list of IOC's and just have some fancy query process the input.
    • We will be supporting variables for queries, so that will come soon)
  • I am continuously impressed by how flexible and powerful Live Discover is. 
    • When we started this project I knew it would be useful, I just did not realize how POWERFUL it actually is until I started trying to solve real problems with it.

Given the current issue with Central I decided to run the query directly from the endpoint. You can do that if you launch the SophosOSQuery from an admin CMD Shell.

Run CMD as admin
"C:\Program Files\Sophos\Live Query\SophosOsquery.exe" --allow_unsafe --socket \\.\pipe\sophososquery.sock
Run CMD as admin
"C:\Program Files\Sophos\Live Query\SophosOsqueryExtension.exe" --verbose --socket \\.\pipe\sophososquery.sock

If you want to test the query in central Just delete most of the IP IOC's to get the query under 4K and past it into the SQL box and run.

I would love your thoughts on this, and perhaps someone can craft the query to determine if they have the Pulse VPN deployed and if the version is in the list of versions that are vulnerable or not.  It's just some SQL and if anyone wants to give it a shot, id be happy to help. Just comment on this topic and we can get started.

Just so everyone is aware the Sophos Labs team monitors these advisories and about 40 other threat intel feeds as well as our own sources to build protection capabilities. When we find a deterministic indicator we add it to our protection technology either as a heuristic rule, Malicious traffic detection, IPS rule, updated ML model new anti-exploit technology ect.  But I figure if you are reading this far you want to get into the nuts and bolts of how to do some of that checking yourself. It may be you have other sources of threat indicators and you are being asked to confirm 'are we protected', with Live discover it is just a few hundred keystrokes away :), or perhaps a quick check of the Forum to see if someone has already published a query for that.

The SHORT QUERY you can run from Central. (Full version at bottom)

/* Pulse Secure VPN Appliance for CVE-2019-11510 */
/* Even if the Pulse Secure VPN is not deployed the IOC's may be valuable for other attacks from the same Threat Actor */
WITH IOC_HUNT_BY_TYPE AS (
   WITH IOC_LIST (Threat_Name, IOC_Type, Indicator) AS (
      VALUES 
      ('check-your-pulse','filepath','dana/html5acc/guacamole/../../'),
      ('check-your-pulse','filepath','../etc/passwd?'),
      ('check-your-pulse','filepath','../../data/runtime/lmdb-backup/data0/data.mdb?'),
      ('check-your-pulse','filepath','/data/runtime/mtmp/lmdb/dataa/data.mdb'),
      ('check-your-pulse','filepath','/dana-admin/diag/diag.cgi'),
      ('check-your-pulse','filepath','/dana-na/../dana/html5acc/guacamole/../../../../../../etc/passwd?/dana/html5acc/guacamole/'),
      ('check-your-pulse','filepath','/../../data/runtime/lmdb-backup'),
      ('check-your-pulse','cmdline','Mozilla\/5.0 \(Windows NT 6.1\; rv:60.0\) Gecko\/20100101 Firefox\/60.0'),
      ('check-your-pulse','cmdline','Mozilla\/5.0 \(Windows NT 10.0\; rv:68.0\) Gecko\/20100101 Firefox\/68.0'),
      ('check-your-pulse','cmdline','Mozilla\/5.0 \(Windows NT 6.1\; WOW64\) AppleWebKit\/537.36 \(KHTML, like Gecko\) Chrome\/55\[.\]0.2883.87 Safari\/537.36'),
      ('check-your-pulse','IP','51.255.45.144'),
      ('check-your-pulse','IP','54.39.22.213'),
      ('check-your-pulse','IP','62.102.148.68'),
      ('check-your-pulse','IP','62.210.37.15'),
      ('check-your-pulse','IP','77.247.181.162'),
      ('check-your-pulse','IP','5.199.135.107')
   )

/* CHECK Filename of historic Processes */
SELECT DISTINCT 
   CASE spj.pathname NOT NULL 
      WHEN 1 THEN 'DETECTED' || spj.pathname 
      ELSE 'INDICATOR NOT PRESENT' 
   END Result,
   Threat_Name, 
   IOC_type, 
   Indicator
FROM IOC_LIST ioc 
   LEFT JOIN sophos_process_journal spj ON spj.pathname LIKE "'%' || ioc.indicator || '%'" 
      AND spj.time > strftime('%s','now','-1 hours')
WHERE ioc.ioc_type = 'filepath'

UNION ALL

/* CHECK cmdline of historic Processes */
SELECT DISTINCT 
   CASE spj.cmdline NOT NULL  
      WHEN 1 THEN 'DETECTED' || spj.cmdline 
      ELSE 'INDICATOR NOT PRESENT' 
   END Result,
   Threat_Name, 
   IOC_type, 
   Indicator
FROM IOC_LIST ioc 
   LEFT JOIN sophos_process_journal spj ON spj.cmdline LIKE "'%' || ioc.indicator || '%'" 
      AND spj.time > strftime('%s','now','-1 hours')
WHERE ioc.ioc_type = 'cmdline'

UNION ALL

/* CHECK IP of process connection in last 1 day */
SELECT DISTINCT 
   CASE sij.SophosPID NOT NULL  
      WHEN 1 THEN 'DETECTED' || sij.SophosPID 
      ELSE 'INDICATOR NOT PRESENT' 
   END Result,
   Threat_Name, 
   IOC_type, 
   Indicator
FROM IOC_LIST ioc 
   LEFT JOIN sophos_ip_journal sij ON sij.destination LIKE ioc.indicator 
      AND sij.time > strftime('%s','now','-1 hours')
WHERE ioc.ioc_type = 'IP' 
)

SELECT * 
FROM IOC_HUNT_BY_TYPE
ORDER BY Result;

 

A FULL VERSION OF THE QUERY 

/* Pulse Secure VPN Appliance for CVE-2019-11510 */
/* Even if the Pulse Secure VPN is not deployed the IOC's may be valuable for other attacks from the same Threat Actor */
WITH IOC_HUNT_BY_TYPE AS (
   WITH IOC_LIST (Threat_Name, IOC_Type, Indicator) AS (
      VALUES
      ('check-your-pulse','filepath','dana/html5acc/guacamole/../../'),
      ('check-your-pulse','filepath','../etc/passwd?'),
      ('check-your-pulse','filepath','../../data/runtime/lmdb-backup/data0/data.mdb?'),
      ('check-your-pulse','filepath','/data/runtime/mtmp/lmdb/dataa/data.mdb'),
      ('check-your-pulse','filepath','/dana-admin/diag/diag.cgi'),
      ('check-your-pulse','filepath','/dana-na/../dana/html5acc/guacamole/../../../../../../etc/passwd?/dana/html5acc/guacamole/'),
      ('check-your-pulse','filepath','/../../data/runtime/lmdb-backup'),
      ('check-your-pulse','cmdline','Mozilla\/5.0 \(Windows NT 6.1\; rv:60.0\) Gecko\/20100101 Firefox\/60.0'),
      ('check-your-pulse','cmdline','Mozilla\/5.0 \(Windows NT 10.0\; rv:68.0\) Gecko\/20100101 Firefox\/68.0'),
      ('check-your-pulse','cmdline','Mozilla\/5.0 \(Windows NT 6.1\; WOW64\) AppleWebKit\/537.36 \(KHTML, like Gecko\) Chrome\/55\[.\]0.2883.87 Safari\/537.36'),
      ('check-your-pulse','IP','51.255.45.144'),
      ('check-your-pulse','IP','54.39.22.213'),
      ('check-your-pulse','IP','62.102.148.68'),
      ('check-your-pulse','IP','62.210.37.15'),
      ('check-your-pulse','IP','77.247.181.162'),
      ('check-your-pulse','IP','77.247.181.165'),
      ('check-your-pulse','IP','87.120.254.98'),
      ('check-your-pulse','IP','89.31.57.5'),
      ('check-your-pulse','IP','94.102.51.78'),
      ('check-your-pulse','IP','95.128.43.164'),
      ('check-your-pulse','IP','95.211.230.211'),
      ('check-your-pulse','IP','103.208.220.123'),
      ('check-your-pulse','IP','104.244.72.115'),
      ('check-your-pulse','IP','104.244.76.189'),
      ('check-your-pulse','IP','104.244.76.245'),
      ('check-your-pulse','IP','109.70.100.20'),
      ('check-your-pulse','IP','109.70.100.23'),
      ('check-your-pulse','IP','109.70.100.25'),
      ('check-your-pulse','IP','130.149.80.199'),
      ('check-your-pulse','IP','158.174.122.199'),
      ('check-your-pulse','IP','162.247.74.202'),
      ('check-your-pulse','IP','162.247.74.204'),
      ('check-your-pulse','IP','162.247.74.216'),
      ('check-your-pulse','IP','162.247.74.7'),
      ('check-your-pulse','IP','162.247.74.74'),
      ('check-your-pulse','IP','169.197.97.34'),
      ('check-your-pulse','IP','176.10.104.240'),
      ('check-your-pulse','IP','178.165.72.177'),
      ('check-your-pulse','IP','178.20.55.18'),
      ('check-your-pulse','IP','185.107.47.171'),
      ('check-your-pulse','IP','185.220.100.247'),
      ('check-your-pulse','IP','185.220.101.1'),
      ('check-your-pulse','IP','185.220.101.15'),
      ('check-your-pulse','IP','185.220.101.24'),
      ('check-your-pulse','IP','185.220.101.26'),
      ('check-your-pulse','IP','185.220.101.28'),
      ('check-your-pulse','IP','185.220.101.32'),
      ('check-your-pulse','IP','185.220.101.62'),
      ('check-your-pulse','IP','185.220.101.70'),
      ('check-your-pulse','IP','185.220.101.71'),
      ('check-your-pulse','IP','185.220.101.72'),
      ('check-your-pulse','IP','185.220.101.77'),
      ('check-your-pulse','IP','185.220.102.8'),
      ('check-your-pulse','IP','185.4.135.135'),
      ('check-your-pulse','IP','192.160.102.165'),
      ('check-your-pulse','IP','192.42.116.18'),
      ('check-your-pulse','IP','193.110.157.151'),
      ('check-your-pulse','IP','195.176.3.20'),
      ('check-your-pulse','IP','199.249.230.104'),
      ('check-your-pulse','IP','204.17.56.42'),
      ('check-your-pulse','IP','209.141.32.33'),
      ('check-your-pulse','IP','212.83.166.62'),
      ('check-your-pulse','IP','223.167.32.74'),
      ('check-your-pulse','IP','23.129.64.180'),
      ('check-your-pulse','IP','23.129.64.194'),
      ('check-your-pulse','IP','23.129.64.214'),
      ('check-your-pulse','IP','45.125.65.45'),
      ('check-your-pulse','IP','45.14.148.96'),
      ('check-your-pulse','IP','46.165.245.154'),
      ('check-your-pulse','IP','46.182.106.190'),
      ('check-your-pulse','IP','5.199.135.107')
   )

/* CHECK Filename of historic Processes */
SELECT DISTINCT
   CASE spj.pathname NOT NULL
      WHEN 1 THEN 'DETECTED' || spj.pathname
      ELSE 'INDICATOR NOT PRESENT'
   END Result,
   Threat_Name,
   IOC_type,
   Indicator
FROM IOC_LIST ioc
   LEFT JOIN sophos_process_journal spj ON spj.pathname LIKE "'%' || ioc.indicator || '%'"
      AND spj.time > strftime('%s','now','-1 hours')
WHERE ioc.ioc_type = 'filepath'

UNION ALL

/* CHECK cmdline of historic Processes */
SELECT DISTINCT
   CASE spj.cmdline NOT NULL  
      WHEN 1 THEN 'DETECTED' || spj.cmdline
      ELSE 'INDICATOR NOT PRESENT'
   END Result,
   Threat_Name,
   IOC_type,
   Indicator
FROM IOC_LIST ioc
   LEFT JOIN sophos_process_journal spj ON spj.cmdline LIKE "'%' || ioc.indicator || '%'"
      AND spj.time > strftime('%s','now','-1 hours')
WHERE ioc.ioc_type = 'cmdline'

UNION ALL

/* CHECK IP of process connection in last 1 day */
SELECT DISTINCT
   CASE sij.SophosPID NOT NULL  
      WHEN 1 THEN 'DETECTED' || sij.SophosPID
      ELSE 'INDICATOR NOT PRESENT'
   END Result,
   Threat_Name,
   IOC_type,
   Indicator
FROM IOC_LIST ioc
   LEFT JOIN sophos_ip_journal sij ON sij.destination LIKE ioc.indicator
      AND sij.time > strftime('%s','now','-1 hours')
WHERE ioc.ioc_type = 'IP'
)

SELECT *
FROM IOC_HUNT_BY_TYPE
ORDER BY Result;

------------------