KingMiner non-deterministic indicators of compromise

See the story from SophosLabs Uncut on KingMiner: https://news.sophos.com/en-us/2020/06/09/kingminer-report/

The article is both educational and enlightening.  One of the aspects of KingMiner that is common with other attacks is that many of the indicators of compromise are non-deterministic.  The domain names and URLs they use are all auto generated.   I read through the article and crafted a query to check if you have experienced a Kingminer attack but because the indicators are not sufficient to convict with 100% accuracy I suspect we will have some false positive detections.  Even with the FP rate above 0 each of the detections requires a deeper investigation. See below for the query.

-------------------------------------- QUERY TEXT BELOW --------------------------------------------

/************************************************************\
| IOC Partial list for Kingminer from SophosLabs Uncut      |
\************************************************************/

/* Build the list of IOCs from the article */
WITH kingminer_IOCs(attribution, Conviction, method, ioc, notes) AS (
   VALUES
   /*****************************************************************************************\
   | These servers used domain names that were generated from the value of the current date |
   | and time. This method has the advantage that the downloaders don’t have to carry |
   | hardcoded server names, rather those server names are dynamically generated and keep |
   | changing with time. This way, if one of the download servers is shut down, the operators|
   | don’t have to release new versions of the downloader with the updated server names. |
   | Instead, they just register the next domain name, and when the time comes, the botnet |
   | will automatically switch to the new download servers. |
   | The generated domain names have the following structure: 3615.30713fdae.tk |
   | The fdae.tk part is the core of the domain name. In the observed cases it was either |
   | fdae.tk, fdae.com or fghh.com, but the strings found in the side-loading DLLs suggest |
   | that additionally the fdae.ga and fdae.cf domain cores could potentially be used, or |
   | were planned to be used at some point |
   \*****************************************************************************************/
   ('kingminer', 'NON-deterministic', 'domain_name', '%fdae.tk', 'Time-coded DGA - These servers used domain names that were generated from the value of the current date and time.'),
   ('kingminer', 'NON-deterministic', 'domain_name', '%fdae.com', 'Time-coded DGA - These servers used domain names that were generated from the value of the current date and time.'),
   ('kingminer', 'NON-deterministic', 'domain_name', '%fghh.com', 'Time-coded DGA - These servers used domain names that were generated from the value of the current date and time.'),
   ('kingminer', 'NON-deterministic', 'domain_name', '%fgae.ga', 'Time-coded DGA - These servers used domain names that were generated from the value of the current date and time.'),
   ('kingminer', 'NON-deterministic', 'domain_name', '%fghh.cf', 'Time-coded DGA - These servers used domain names that were generated from the value of the current date and time.'),
   ('kingminer', 'NON-deterministic', 'domain_name', '%a.qwerr.ga', 'Time-coded DGA - These servers used domain names that were generated from the value of the current date and time.'),
   ('kingminer', 'NON-deterministic', 'domain_name', '%lu4n.com', 'The lu4n.com site also hosted a few SQL brute forcing command injection tools'),
   ('kingminer', 'Deterministic', 'domain_name', '%ip.yototoo.com', 'encrypted backdoor connection'),

   /******************************************************************************************\
   | We have found over 20 Github user accounts that were used to deliver the contents of the |
   | Kingminer botnet over the time. |
   \******************************************************************************************/
   ('kingminer', 'NON-deterministic', 'URL', '%github%cvffdscccss%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%xieliang3%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%hansho23%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%paishi45276%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%oit847996%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%muzhuoyiyue%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%daonaoyef%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%leishi9%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%yut42929%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%shazhuangq%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%zaiya00387%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%gghhjjjj%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%gghhhhgh%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%haj08341%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%qipu872262484%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%jiaoyi7992%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%huitun237%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%zaiya00387%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%fff%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%chigutuiche%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%zhizi471%', 'Github repositories used to deliver contents of kingminer botnet'),
   ('kingminer', 'NON-deterministic', 'URL', '%github%jiaoshq %', 'Github repositories used to deliver contents of kingminer botnet'),

   /*****************************************************************************************\
   | Usually the first activity that we observed after a successful infection was the |
   | execution of a PowerShell script spawned from the sqlservr.exe process |
   | !!! TO_DO !!! Build detection method for this type of IOC |
   \*****************************************************************************************/
   /* ('kingminer', 'NON-deterministic', 'Powershell_Parent', '%sqlserver.exe%', 'successful infection was the execution of a PowerShell script spawned from the sqlservr.exe process'), */

   /*****************************************************************************************\
   | Copy of powershell.exe running under anothername |
   \*****************************************************************************************/
   ('kingminer', 'NON-deterministic', 'Powershell_renamed', '%powershell%', 'A powershell process runing under another name'),

   /*****************************************************************************************\
   | In one of the cases, we were able to observe the network traffic of an initial infection|
   | attempt, which helped us reconstruct the majority of the infection process. The attack |
   | in that case came from the IP address 185.234.216.223. |
   \*****************************************************************************************/
   ('kingminer', 'Non-Deterministic', 'IP', '185.234.216.223', 'this server is part of the Kingminer infrastructure'),
   ('kingminer', 'Non-Deterministic', 'IP', '9.9.9.9', 'The malicious loader contains the IP addresses of a few DNS servers'),
   ('kingminer', 'Non-Deterministic', 'IP', '1.1.1.1', 'The malicious loader contains the IP addresses of a few DNS servers'),
   ('kingminer', 'Non-Deterministic', 'IP', '119.29.29.29', 'The malicious loader contains the IP addresses of a few DNS servers'),
   ('kingminer', 'Non-Deterministic', 'IP', '8.8.4.4', 'The malicious loader contains the IP addresses of a few DNS servers'),

   /*****************************************************************************************\
   | this script is saved to a couple of locations, typically C:\Users\Public\Music\1.vbs. |
   \*****************************************************************************************/
   ('kingminer', 'Non-Deterministic', 'file_path', 'C:\Users\Public\Music\1.vbs', 'VBscript downloader'),
   ('kingminer', 'Non-Deterministic', 'file_path', 'C:\Users\Public\Music\2.vbs', 'VBscript downloader'),

   /*****************************************************************************************\
   | some cmd line options used |
   \*****************************************************************************************/
   ('kingminer', 'Non-Deterministic', 'cmdline', '%whoami%', 'luan_exec reference'),
   ('kingminer', 'Non-Deterministic', 'cmdline', '%vbscript:GetObject(%script:hxxp://ww.3113cfdae[.]com/r1.txt?', 'Kingminer executes this simple downloader command'),

   /*****************************************************************************************\
   | There were a handful of legit programs that were abused by Kingminer, coming from |
   | different software vendors |
   \*****************************************************************************************/
   ('kingminer', 'Non-Deterministic', 'processname', 'fix.exe', 'Clean executable may be used to trigger malware via side loading'),
   ('kingminer', 'Non-Deterministic', 'processname', 'alger.exe', 'Clean executable may be used to trigger malware via side loading'),
   ('kingminer', 'Non-Deterministic', 'processname', 'powered.exe', 'Clean executable may be used to trigger malware via side loading'),
   ('kingminer', 'Non-Deterministic', 'processname', 'repair.exe', 'Clean executable may be used to trigger malware via side loading'),
   ('kingminer', 'Non-Deterministic', 'processname', 'dwmer.exe', 'Clean executable may be used to trigger malware via side loading')
)
/**********************************************************************\
| The admin may want to search a large amount of data in the tables so |
| split time into 20 min chunks given the number hours specified |
\**********************************************************************/
, for(x) AS (
   VALUES ( ( SELECT CAST (strftime ('%s', 'now','-$$Hours to look back$$ hours') AS INT) ) )
   UNION ALL
   SELECT x+1200 FROM for WHERE x < (SELECT CAST (strftime ('%s', 'now') AS INT))
)

/****************************************************************************\
| Check for matching domain or URL info seen in the specified lookback period|
\****************************************************************************/
SELECT
   CAST( datetime(spa.time,'unixepoch') AS TEXT) DATE_TIME,
   km.attribution,
   km.Conviction,
   spa.subject,
   spa.SophosPID,
   CAST ( (select replace(spa.pathname, rtrim(spa.pathname, replace(spa.pathname, '\', '')), '')) AS TEXT) process_name,
   spa.action,
   spa.object,
   spa.url,
   km.method,
   km.ioc,
   km.notes
FROM for
   LEFT JOIN kingminer_IOCs km ON km.method IN('domain_name', 'url')
   LEFT JOIN sophos_process_activity spa ON spa.subject IN ('Http','Url','Network') AND spa.time >= for.x and spa.time <= for.x+1200
WHERE spa.url LIKE km.ioc

UNION ALL

/****************************************************************************\
| Check for matching IP info seen in the specified lookback period |
\****************************************************************************/
SELECT
   CAST( datetime(spa.time,'unixepoch') AS TEXT) DATE_TIME,
   km.attribution,
   km.Conviction,
   spa.subject,
   spa.SophosPID,
   CAST ( (select replace(spa.pathname, rtrim(spa.pathname, replace(spa.pathname, '\', '')), '')) AS TEXT) process_name,
   spa.action,
   spa.object,
   spa.url,
   km.method,
   km.ioc,
   km.notes
FROM for
   LEFT JOIN kingminer_IOCs km ON km.method IN('ip')
   LEFT JOIN sophos_process_activity spa ON spa.subject IN ('Http','Ip','Network') AND spa.time >= for.x and spa.time <= for.x+1200
WHERE spa.source LIKE km.ioc OR spa.destination LIKE km.ioc

UNION ALL

/***********************************************************************************\
| Check for matching cmdline or file_path info seen in the specified lookback period|
\***********************************************************************************/
SELECT
   CAST( datetime(spa.time,'unixepoch') AS TEXT) DATE_TIME,
   km.attribution,
   km.Conviction,
   spa.subject,
   spa.SophosPID,
   CAST ( (select replace(spa.pathname, rtrim(spa.pathname, replace(spa.pathname, '\', '')), '')) AS TEXT) process_name,
   spa.action,
   spa.object,
   spa.url,
   km.method,
   km.ioc,
   km.notes
FROM for
   LEFT JOIN kingminer_IOCs km ON km.method IN('cmdline','file_path')
   LEFT JOIN sophos_process_activity spa ON spa.subject IN ('FileBinaryChanges','FileBinaryReads','FileDataChanges','FileDataReads','FileOtherChanges','FileOtherReads', 'Image','Process') AND
spa.time >= for.x and spa.time <= for.x+1200
WHERE spa.pathname LIKE km.ioc OR spa.cmdline LIKE km.ioc

UNION ALL

/***********************************************************************************\
| Check for powershell rename events |
\***********************************************************************************/
SELECT
   CAST( datetime(spa.time,'unixepoch') AS TEXT) DATE_TIME,
   km.attribution,
   km.Conviction,
   spa.subject,
   spa.SophosPID,
   CAST ( (select replace(spa.pathname, rtrim(spa.pathname, replace(spa.pathname, '\', '')), '')) AS TEXT) process_name,
   'Powershell renamed',
   spa.object,
   spa.url,
   km.method,
   km.ioc,
   km.notes
FROM for
   LEFT JOIN kingminer_IOCs km ON km.method IN('Powershell_renamed')
   LEFT JOIN sophos_process_activity spa ON spa.subject IN ('FileBinaryChanges','FileOtherChanges') AND
spa.time >= for.x and spa.time <= for.x+1200
WHERE spa.pathname LIKE km.ioc

 

--------------------------------------- END SQL SCRIPT -------------------------------------