See the story from Sophos Labs 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 experianced 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 warrents a deeper investigation. See below for the query.
-------------------------------------- QUERY TEXT BELOW --------------------------------------------
/************************************************************\
| IOC Partial list for Kingminer from Sophos Naked Security Article |
\************************************************************/
/* 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: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 -------------------------------------