top of page

NIKKE Launcher Compromise: Hunt Workstation Exposure

Writer: Inception Security
Inception Security
3 hours ago
14 min read
Inceptor preserves launcher logs, hunts DNS, temp file and Chrome DLL leads, and pulls a per-user registry key loose while Glitch fades (NIKKE launcher compromise hunt comic)

What this means for your clients: a game on a work laptop could expose business accounts even after the game closes.


In the NIKKE launcher compromise, the game's official PC launcher loaded altered files through its own delivery infrastructure. Identify which work identities and secrets shared that computer, and preserve evidence to establish what happened.


How the launcher crossed into the workstation


Level Infinite's notice, mirrored by Nikke.gg, describes a hijacked open-source domain used by game services. MotherSphere describes four altered JavaScript files on the publisher's content delivery network. Embedded Chromium ran the loader; the launcher's JavaScript bridge fetched insight.bundle, LuaJIT bytecode for the K2F remote-access agent. This supply chain failure did not deliver the agent on every launch.


The timelines disagree. Level Infinite dates malicious distribution to October 30 at 03:52 UTC+9, October 29 at 11:52 AM MST. MotherSphere lists an earlier reported agent start, credited in its gist to a commenter, on October 23 at 16:40 GMT, October 23 at 9:40 AM MST. The publisher's domain-hijack explanation also does not establish how its hosted scripts were changed. Neither the intrusion route nor attacker identity is established.


The agent could read files, collect browser credentials and take screenshots while the launcher was open. Optional Chrome persistence used platform_experience_helper.dll and a per-user registry entry to survive launcher closure. BleepingComputer's November 6 update relays MotherSphere's reports of several players finding the DLL. Compromise counts and cryptocurrency theft remain unknown.


Who is exposed


Inventory Windows work and BYOD computers that ran the PC launcher, including the reported Google Play Games build. The publisher recommends checks after September 27 at 15:41 UTC+9, September 26 at 11:41 PM MST. Wine or Proton could expose files outside the prefix through normal home-directory permissions, including SSH keys and API tokens. Possible access warrants investigation, not a claim of theft.


Preserve evidence before cleanup


Isolate a suspected host using your incident-response procedure. Preserve volatile evidence where practicable before closing processes or rebooting. Before vendor scanning, relaunching or cleanup, preserve Launcher\intl_service\debug.log, Launcher\log\, every %APPDATA%\nikke_launcher*\tbs_cache, %TEMP%\k2f* files, the 64-hex DLL folder and an export of the per-user CLSID key, with hashes and timestamps; the updated client and antivirus cleanup can erase evidence. Then delete the working tbs_cache before any reopening, per MotherSphere's guidance, and follow the Nikke.gg mirror of the publisher's scan or manual guidance with browsers closed. A repaired delivery channel does not clean an already affected endpoint.


After preservation, block this defanged reference through approved controls: insightjs[.]com, analytics[.]insightjs[.]com, insightjs[.]org; agent delivery 89[.]127[.]233[.]127, and earlier victim-reported address 89[.]126[.]250[.]172. Replace [.] with . in controls. The fallback domain later became a third-party warning page, so historical hits need context. From a clean device, revoke sessions and replace exposed credentials, including business tokens. If agent execution is established, consider rebuilding from a trusted image. Do not remove Chrome's legitimate helper executable or the machine-wide parental-controls entry pointing to wpc.dll.


Hunts


These searches use Sysmon DNS and workstation events. Splunk and Elastic need that feed; CrowdStrike uses Falcon CQL over ingested Sysmon, not native Falcon telemetry, and Microsoft KQL targets Microsoft Sentinel's WindowsEvent table. Every block starts September 26 at 5:00 PM MST, September 27 at 00:00 UTC, and stops before November 6 at 3:27 PM MST. Match interface selectors to this start-inclusive, end-exclusive window; update every fixed cutoff for later investigations.


Results are untested investigative leads; no SIEM execution was performed. Elastic and CQL caps can truncate findings; partition the interval or export complete results.


The searches below cover Windows Sysmon telemetry. They do not test Wine or Proton hosts; a negative result cannot clear those computers.


Test the evidence before trusting a negative


Splunk


index=YOUR_SYSMON_INDEX earliest=1790467200 latest=1794004020
| eval event_id=tonumber(coalesce(EventCode, EventID))
| where event_id IN (1,3,7,11,13,22)
| eval host_label_ok=if(isnotnull(host) AND len(mvjoin(host, ""))>0 AND mvjoin(host, "")!="-",1,0)
| eval stable_host_id_ok=if(isnotnull(DeviceId) AND len(mvjoin(DeviceId, ""))>0 AND mvjoin(DeviceId, "")!="-",1,0)
| eval user_ok=if(isnotnull(User) AND len(mvjoin(User, ""))>0 AND mvjoin(User, "")!="-",1,0)
| eval image_ok=if(isnotnull(Image) AND len(mvjoin(Image, ""))>0 AND mvjoin(Image, "")!="-",1,0)
| eval process_guid_ok=if(isnotnull(ProcessGuid) AND len(mvjoin(ProcessGuid, ""))>0 AND mvjoin(ProcessGuid, "")!="-",1,0)
| eval query_ok=if(isnotnull(QueryName) AND len(mvjoin(QueryName, ""))>0 AND mvjoin(QueryName, "")!="-",1,0)
| eval answers_ok=if(isnotnull(QueryResults) AND len(mvjoin(QueryResults, ""))>0 AND mvjoin(QueryResults, "")!="-",1,0)
| eval initiated_ok=if(isnotnull(Initiated) AND len(mvjoin(Initiated, ""))>0 AND mvjoin(Initiated, "")!="-",1,0)
| eval source_ip_ok=if(isnotnull(SourceIp) AND len(mvjoin(SourceIp, ""))>0 AND mvjoin(SourceIp, "")!="-",1,0)
| eval source_port_ok=if(isnotnull(SourcePort) AND len(mvjoin(SourcePort, ""))>0 AND mvjoin(SourcePort, "")!="-",1,0)
| eval destination_ip_ok=if(isnotnull(DestinationIp) AND len(mvjoin(DestinationIp, ""))>0 AND mvjoin(DestinationIp, "")!="-",1,0)
| eval destination_port_ok=if(isnotnull(DestinationPort) AND len(mvjoin(DestinationPort, ""))>0 AND mvjoin(DestinationPort, "")!="-",1,0)
| eval file_path_ok=if(isnotnull(TargetFilename) AND len(mvjoin(TargetFilename, ""))>0 AND mvjoin(TargetFilename, "")!="-",1,0)
| eval registry_target_ok=if(isnotnull(TargetObject) AND len(mvjoin(TargetObject, ""))>0 AND mvjoin(TargetObject, "")!="-",1,0)
| eval registry_value_ok=if(isnotnull(Details) AND len(mvjoin(Details, ""))>0 AND mvjoin(Details, "")!="-",1,0)
| eval parent_image_ok=if(isnotnull(ParentImage) AND len(mvjoin(ParentImage, ""))>0 AND mvjoin(ParentImage, "")!="-",1,0)
| eval command_line_ok=if(isnotnull(CommandLine) AND len(mvjoin(CommandLine, ""))>0 AND mvjoin(CommandLine, "")!="-",1,0)
| eval parent_guid_ok=if(isnotnull(ParentProcessGuid) AND len(mvjoin(ParentProcessGuid, ""))>0 AND mvjoin(ParentProcessGuid, "")!="-",1,0)
| eval image_loaded_ok=if(isnotnull(ImageLoaded) AND len(mvjoin(ImageLoaded, ""))>0 AND mvjoin(ImageLoaded, "")!="-",1,0)
| stats count as events min(_time) as first_seen max(_time) as last_seen sum(host_label_ok) as host_label_present sum(stable_host_id_ok) as stable_host_id_present sum(user_ok) as user_present sum(image_ok) as image_present sum(process_guid_ok) as process_guid_present sum(query_ok) as query_present sum(answers_ok) as answers_present sum(initiated_ok) as initiated_present sum(source_ip_ok) as source_ip_present sum(source_port_ok) as source_port_present sum(destination_ip_ok) as destination_ip_present sum(destination_port_ok) as destination_port_present sum(file_path_ok) as file_path_present sum(registry_target_ok) as registry_target_present sum(registry_value_ok) as registry_value_present sum(parent_image_ok) as parent_image_present sum(command_line_ok) as command_line_present sum(parent_guid_ok) as parent_guid_present sum(image_loaded_ok) as image_loaded_present by event_id
| eval host_label_missing=events-host_label_present, stable_host_id_missing=events-stable_host_id_present, user_missing=events-user_present, image_missing=events-image_present, process_guid_missing=events-process_guid_present, query_missing=events-query_present, answers_missing=events-answers_present, initiated_missing=events-initiated_present, source_ip_missing=events-source_ip_present, source_port_missing=events-source_port_present, destination_ip_missing=events-destination_ip_present, destination_port_missing=events-destination_port_present, file_path_missing=events-file_path_present, registry_target_missing=events-registry_target_present, registry_value_missing=events-registry_value_present, parent_image_missing=events-parent_image_present, command_line_missing=events-command_line_present, parent_guid_missing=events-parent_guid_present, image_loaded_missing=events-image_loaded_present
| convert ctime(first_seen) ctime(last_seen)

Elastic


FROM logs-windows.sysmon_operational-*
| WHERE @timestamp >= "2026-09-27T00:00:00Z" AND @timestamp < "2026-11-06T22:27:00Z"
| WHERE event.provider == "Microsoft-Windows-Sysmon" AND event.code IN ("1","3","7","11","13","22")
| EVAL host_label_ok = CASE(host.name IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(host.name), "")) > 0 AND MV_CONCAT(TO_STRING(host.name), "") != "-", 1, 0)
| EVAL stable_host_id_ok = CASE(host.id IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(host.id), "")) > 0 AND MV_CONCAT(TO_STRING(host.id), "") != "-", 1, 0)
| EVAL user_ok = CASE(user.name IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(user.name), "")) > 0 AND MV_CONCAT(TO_STRING(user.name), "") != "-", 1, 0)
| EVAL image_ok = CASE(process.executable IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(process.executable), "")) > 0 AND MV_CONCAT(TO_STRING(process.executable), "") != "-", 1, 0)
| EVAL process_guid_ok = CASE(process.entity_id IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(process.entity_id), "")) > 0 AND MV_CONCAT(TO_STRING(process.entity_id), "") != "-", 1, 0)
| EVAL query_ok = CASE(dns.question.name IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(dns.question.name), "")) > 0 AND MV_CONCAT(TO_STRING(dns.question.name), "") != "-", 1, 0)
| EVAL answers_ok = CASE(dns.answers.data IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(dns.answers.data), "")) > 0 AND MV_CONCAT(TO_STRING(dns.answers.data), "") != "-", 1, 0)
| EVAL initiated_ok = CASE(network.direction IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(network.direction), "")) > 0 AND MV_CONCAT(TO_STRING(network.direction), "") != "-", 1, 0)
| EVAL source_ip_ok = CASE(source.ip IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(source.ip), "")) > 0 AND MV_CONCAT(TO_STRING(source.ip), "") != "-", 1, 0)
| EVAL source_port_ok = CASE(source.port IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(source.port), "")) > 0 AND MV_CONCAT(TO_STRING(source.port), "") != "-", 1, 0)
| EVAL destination_ip_ok = CASE(destination.ip IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(destination.ip), "")) > 0 AND MV_CONCAT(TO_STRING(destination.ip), "") != "-", 1, 0)
| EVAL destination_port_ok = CASE(destination.port IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(destination.port), "")) > 0 AND MV_CONCAT(TO_STRING(destination.port), "") != "-", 1, 0)
| EVAL file_path_ok = CASE(file.path IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(file.path), "")) > 0 AND MV_CONCAT(TO_STRING(file.path), "") != "-", 1, 0)
| EVAL registry_target_ok = CASE(registry.path IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(registry.path), "")) > 0 AND MV_CONCAT(TO_STRING(registry.path), "") != "-", 1, 0)
| EVAL registry_value_ok = CASE(registry.data.strings IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(registry.data.strings), "")) > 0 AND MV_CONCAT(TO_STRING(registry.data.strings), "") != "-", 1, 0)
| EVAL parent_image_ok = CASE(process.parent.executable IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(process.parent.executable), "")) > 0 AND MV_CONCAT(TO_STRING(process.parent.executable), "") != "-", 1, 0)
| EVAL command_line_ok = CASE(process.command_line IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(process.command_line), "")) > 0 AND MV_CONCAT(TO_STRING(process.command_line), "") != "-", 1, 0)
| EVAL parent_guid_ok = CASE(process.parent.entity_id IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(process.parent.entity_id), "")) > 0 AND MV_CONCAT(TO_STRING(process.parent.entity_id), "") != "-", 1, 0)
| EVAL image_loaded_ok = CASE(file.path IS NOT NULL AND LENGTH(MV_CONCAT(TO_STRING(file.path), "")) > 0 AND MV_CONCAT(TO_STRING(file.path), "") != "-", 1, 0)
| STATS events = COUNT(*), first_seen = MIN(@timestamp), last_seen = MAX(@timestamp), host_label_present = SUM(host_label_ok), stable_host_id_present = SUM(stable_host_id_ok), user_present = SUM(user_ok), image_present = SUM(image_ok), process_guid_present = SUM(process_guid_ok), query_present = SUM(query_ok), answers_present = SUM(answers_ok), initiated_present = SUM(initiated_ok), source_ip_present = SUM(source_ip_ok), source_port_present = SUM(source_port_ok), destination_ip_present = SUM(destination_ip_ok), destination_port_present = SUM(destination_port_ok), file_path_present = SUM(file_path_ok), registry_target_present = SUM(registry_target_ok), registry_value_present = SUM(registry_value_ok), parent_image_present = SUM(parent_image_ok), command_line_present = SUM(command_line_ok), parent_guid_present = SUM(parent_guid_ok), image_loaded_present = SUM(image_loaded_ok) BY event.code
| EVAL host_label_missing = events - host_label_present, stable_host_id_missing = events - stable_host_id_present, user_missing = events - user_present, image_missing = events - image_present, process_guid_missing = events - process_guid_present, query_missing = events - query_present, answers_missing = events - answers_present, initiated_missing = events - initiated_present, source_ip_missing = events - source_ip_present, source_port_missing = events - source_port_present, destination_ip_missing = events - destination_ip_present, destination_port_missing = events - destination_port_present, file_path_missing = events - file_path_present, registry_target_missing = events - registry_target_present, registry_value_missing = events - registry_value_present, parent_image_missing = events - parent_image_present, command_line_missing = events - command_line_present, parent_guid_missing = events - parent_guid_present, image_loaded_missing = events - image_loaded_present
| LIMIT 10000

CrowdStrike


Channel="Microsoft-Windows-Sysmon/Operational"
| cutoff := 1790467200000
| test(@timestamp >= cutoff)
| test(@timestamp < 1794004020000)
// Set the selector from 2026-09-27T00:00:00Z to 2026-11-06T22:27:00Z (end exclusive).
| EventID=/^(1|3|7|11|13|22)$/
| case { Computer=* Computer!="" Computer!="-" | host_label_ok := 1; * | host_label_ok := 0; }
| case { DeviceId=* DeviceId!="" DeviceId!="-" | stable_host_id_ok := 1; * | stable_host_id_ok := 0; }
| case { User=* User!="" User!="-" | user_ok := 1; * | user_ok := 0; }
| case { Image=* Image!="" Image!="-" | image_ok := 1; * | image_ok := 0; }
| case { ProcessGuid=* ProcessGuid!="" ProcessGuid!="-" | process_guid_ok := 1; * | process_guid_ok := 0; }
| case { QueryName=* QueryName!="" QueryName!="-" | query_ok := 1; * | query_ok := 0; }
| case { QueryResults=* QueryResults!="" QueryResults!="-" | answers_ok := 1; * | answers_ok := 0; }
| case { Initiated=* Initiated!="" Initiated!="-" | initiated_ok := 1; * | initiated_ok := 0; }
| case { SourceIp=* SourceIp!="" SourceIp!="-" | source_ip_ok := 1; * | source_ip_ok := 0; }
| case { SourcePort=* SourcePort!="" SourcePort!="-" | source_port_ok := 1; * | source_port_ok := 0; }
| case { DestinationIp=* DestinationIp!="" DestinationIp!="-" | destination_ip_ok := 1; * | destination_ip_ok := 0; }
| case { DestinationPort=* DestinationPort!="" DestinationPort!="-" | destination_port_ok := 1; * | destination_port_ok := 0; }
| case { TargetFilename=* TargetFilename!="" TargetFilename!="-" | file_path_ok := 1; * | file_path_ok := 0; }
| case { TargetObject=* TargetObject!="" TargetObject!="-" | registry_target_ok := 1; * | registry_target_ok := 0; }
| case { Details=* Details!="" Details!="-" | registry_value_ok := 1; * | registry_value_ok := 0; }
| case { ParentImage=* ParentImage!="" ParentImage!="-" | parent_image_ok := 1; * | parent_image_ok := 0; }
| case { CommandLine=* CommandLine!="" CommandLine!="-" | command_line_ok := 1; * | command_line_ok := 0; }
| case { ParentProcessGuid=* ParentProcessGuid!="" ParentProcessGuid!="-" | parent_guid_ok := 1; * | parent_guid_ok := 0; }
| case { ImageLoaded=* ImageLoaded!="" ImageLoaded!="-" | image_loaded_ok := 1; * | image_loaded_ok := 0; }
| groupBy([EventID], function=[count(as=events), min(@timestamp, as=first_seen), max(@timestamp, as=last_seen), sum(host_label_ok, as=host_label_present), sum(stable_host_id_ok, as=stable_host_id_present), sum(user_ok, as=user_present), sum(image_ok, as=image_present), sum(process_guid_ok, as=process_guid_present), sum(query_ok, as=query_present), sum(answers_ok, as=answers_present), sum(initiated_ok, as=initiated_present), sum(source_ip_ok, as=source_ip_present), sum(source_port_ok, as=source_port_present), sum(destination_ip_ok, as=destination_ip_present), sum(destination_port_ok, as=destination_port_present), sum(file_path_ok, as=file_path_present), sum(registry_target_ok, as=registry_target_present), sum(registry_value_ok, as=registry_value_present), sum(parent_image_ok, as=parent_image_present), sum(command_line_ok, as=command_line_present), sum(parent_guid_ok, as=parent_guid_present), sum(image_loaded_ok, as=image_loaded_present)], limit=max)
| host_label_missing := events - host_label_present
| stable_host_id_missing := events - stable_host_id_present
| user_missing := events - user_present
| image_missing := events - image_present
| process_guid_missing := events - process_guid_present
| query_missing := events - query_present
| answers_missing := events - answers_present
| initiated_missing := events - initiated_present
| source_ip_missing := events - source_ip_present
| source_port_missing := events - source_port_present
| destination_ip_missing := events - destination_ip_present
| destination_port_missing := events - destination_port_present
| file_path_missing := events - file_path_present
| registry_target_missing := events - registry_target_present
| registry_value_missing := events - registry_value_present
| parent_image_missing := events - parent_image_present
| command_line_missing := events - command_line_present
| parent_guid_missing := events - parent_guid_present
| image_loaded_missing := events - image_loaded_present

Microsoft KQL


let Start = datetime(2026-09-27T00:00:00Z);
WindowsEvent
| where TimeGenerated >= Start and TimeGenerated < datetime(2026-11-06T22:27:00Z)
| where Provider == "Microsoft-Windows-Sysmon"
| where EventID in (1,3,7,11,13,22)
| summarize events=count(), first_seen=min(TimeGenerated), last_seen=max(TimeGenerated), host_label_present=countif(isnotempty(Computer) and Computer != "-"), stable_host_id_present=countif(isnotempty(tostring(EventData.DeviceId)) and tostring(EventData.DeviceId) != "-"), user_present=countif(isnotempty(tostring(EventData.User)) and tostring(EventData.User) != "-"), image_present=countif(isnotempty(tostring(EventData.Image)) and tostring(EventData.Image) != "-"), process_guid_present=countif(isnotempty(tostring(EventData.ProcessGuid)) and tostring(EventData.ProcessGuid) != "-"), query_present=countif(isnotempty(tostring(EventData.QueryName)) and tostring(EventData.QueryName) != "-"), answers_present=countif(isnotempty(tostring(EventData.QueryResults)) and tostring(EventData.QueryResults) != "-"), initiated_present=countif(isnotempty(tostring(EventData.Initiated)) and tostring(EventData.Initiated) != "-"), source_ip_present=countif(isnotempty(tostring(EventData.SourceIp)) and tostring(EventData.SourceIp) != "-"), source_port_present=countif(isnotempty(tostring(EventData.SourcePort)) and tostring(EventData.SourcePort) != "-"), destination_ip_present=countif(isnotempty(tostring(EventData.DestinationIp)) and tostring(EventData.DestinationIp) != "-"), destination_port_present=countif(isnotempty(tostring(EventData.DestinationPort)) and tostring(EventData.DestinationPort) != "-"), file_path_present=countif(isnotempty(tostring(EventData.TargetFilename)) and tostring(EventData.TargetFilename) != "-"), registry_target_present=countif(isnotempty(tostring(EventData.TargetObject)) and tostring(EventData.TargetObject) != "-"), registry_value_present=countif(isnotempty(tostring(EventData.Details)) and tostring(EventData.Details) != "-"), parent_image_present=countif(isnotempty(tostring(EventData.ParentImage)) and tostring(EventData.ParentImage) != "-"), command_line_present=countif(isnotempty(tostring(EventData.CommandLine)) and tostring(EventData.CommandLine) != "-"), parent_guid_present=countif(isnotempty(tostring(EventData.ParentProcessGuid)) and tostring(EventData.ParentProcessGuid) != "-"), image_loaded_present=countif(isnotempty(tostring(EventData.ImageLoaded)) and tostring(EventData.ImageLoaded) != "-") by EventID
| extend host_label_missing=events-host_label_present, stable_host_id_missing=events-stable_host_id_present, user_missing=events-user_present, image_missing=events-image_present, process_guid_missing=events-process_guid_present, query_missing=events-query_present, answers_missing=events-answers_present, initiated_missing=events-initiated_present, source_ip_missing=events-source_ip_present, source_port_missing=events-source_port_present, destination_ip_missing=events-destination_ip_present, destination_port_missing=events-destination_port_present, file_path_missing=events-file_path_present, registry_target_missing=events-registry_target_present, registry_value_missing=events-registry_value_present, parent_image_missing=events-parent_image_present, command_line_missing=events-command_line_present, parent_guid_missing=events-parent_guid_present, image_loaded_missing=events-image_loaded_present

Validate Splunk's EventCode or EventID, Elastic ECS fields, CQL's extracted Channel, Computer and EventID, and Sentinel's dynamic EventData against known Sysmon records. IDs 1, 3, 7, 11, 13 and 22 mean process, connection, image load, file creation, value set and DNS.


Presence counts exclude null, empty and -, not semantically invalid values. Compare required-field counts with events; investigate deficits. Event-family grouping retains missing host labels. DeviceId (Sentinel EventData.DeviceId) is deployment-specific enrichment, not native Sysmon; map it and Elastic host.id to one stable endpoint inventory. Zero or absent enrichment is a gap. Unmapped Elastic columns stop execution rather than yield a negative. Blank registry values may show cleanup. Inspect whitespace, placeholders, arrays, types and values on known records; confirm Sysmon-only Splunk input.


These searches query DNS events, not proxy logs. Reconcile expected hosts and retention with the telemetry owner; the oldest event cannot prove uninterrupted coverage. Missing classes require collection changes, not clearance.


Field expectations: all six event families need host_label, stable_host_id, user, image and process_guid. Additionally: event 1 needs parent_image, command_line, parent_guid; event 3 needs initiated, source_ip, source_port, destination_ip, destination_port; event 7 needs image_loaded; event 11 needs file_path; event 13 needs registry_target, with registry_value checked even if intentionally empty; event 22 needs query, with answers allowed empty on failed lookups. An absent family produces no row, never a pass; compare all six expected IDs and endpoint inventory separately. Counts aggregated across hosts cannot certify per-host coverage.


Hunt 1: Find the loader's domains


DNS contact is an exposure lead, not agent-execution proof; analyst visits to the later warning page can be benign.


Splunk


index=YOUR_SYSMON_INDEX earliest=1790467200 latest=1794004020
| eval event_id=tonumber(coalesce(EventCode, EventID))
| where event_id=22 AND match(lower(QueryName), "^([^.]+\\.)*insightjs\\.(com|org)\\.?$")
| table _time host User Image QueryName QueryResults ProcessGuid

Elastic


FROM logs-windows.sysmon_operational-*
| WHERE @timestamp >= "2026-09-27T00:00:00Z" AND @timestamp < "2026-11-06T22:27:00Z"
| WHERE event.code == "22" AND TO_LOWER(dns.question.name) RLIKE """([^.]+\.)*insightjs\.(com|org)\.?"""
| KEEP @timestamp, host.name, user.name, process.executable, dns.question.name, dns.answers.data, process.entity_id
| LIMIT 10000

CrowdStrike


Channel="Microsoft-Windows-Sysmon/Operational"
| cutoff := 1790467200000
| test(@timestamp >= cutoff)
| test(@timestamp < 1794004020000)
// Set the search time selector from 2026-09-27T00:00:00Z to 2026-11-06T22:27:00Z (end exclusive).
| EventID=22
| QueryName=/^([^.]+\.)*insightjs\.(com|org)\.?$/i
| table([@timestamp, Computer, User, Image, QueryName, QueryResults, ProcessGuid], limit=10000)

Microsoft KQL


let Start = datetime(2026-09-27T00:00:00Z);
WindowsEvent
| where TimeGenerated >= Start and TimeGenerated < datetime(2026-11-06T22:27:00Z)
| where Provider == "Microsoft-Windows-Sysmon"
| where EventID == 22
| where tolower(tostring(EventData.QueryName)) matches regex @"^([^.]+\.)*insightjs\.(com|org)\.?$"
| project TimeGenerated, Computer, user=tostring(EventData.User), image=tostring(EventData.Image), query=tostring(EventData.QueryName), answers=tostring(EventData.QueryResults), process_guid=tostring(EventData.ProcessGuid)

Map Sysmon QueryName to Elastic dns.question.name; other searches retain the original. Matches cover all subdomains, including analytics[.]insightjs[.]com, and trailing dots. MotherSphere dates insightjs[.]org's third-party warning page to November 3 at 10:55 AM MST. A later lookup from tbs_browser.exe or the launcher can be consistent with a stale modified script but does not establish execution; analyst browser checks are context.


Hunt 2: Follow the egress


Check each address's connection outcome and launcher context.


Splunk


index=YOUR_SYSMON_INDEX earliest=1790467200 latest=1794004020
| eval event_id=tonumber(coalesce(EventCode, EventID))
| where event_id=3 AND lower(Initiated)="true" AND DestinationIp IN ("89.127.233.127","89.126.250.172")
| table _time host User Image SourceIp SourcePort DestinationIp DestinationPort ProcessGuid

Elastic


FROM logs-windows.sysmon_operational-*
| WHERE @timestamp >= "2026-09-27T00:00:00Z" AND @timestamp < "2026-11-06T22:27:00Z"
| WHERE event.code == "3" AND network.direction == "egress" AND destination.ip IN ("89.127.233.127","89.126.250.172")
| KEEP @timestamp, host.name, user.name, process.executable, source.ip, source.port, destination.ip, destination.port, process.entity_id
| LIMIT 10000

CrowdStrike


Channel="Microsoft-Windows-Sysmon/Operational"
| cutoff := 1790467200000
| test(@timestamp >= cutoff)
| test(@timestamp < 1794004020000)
// Set the search time selector from 2026-09-27T00:00:00Z to 2026-11-06T22:27:00Z (end exclusive).
| EventID=3 Initiated=/^true$/i
| in(field=DestinationIp, values=["89.127.233.127", "89.126.250.172"])
| table([@timestamp, Computer, User, Image, SourceIp, SourcePort, DestinationIp, DestinationPort, ProcessGuid], limit=10000)

Microsoft KQL


let Start = datetime(2026-09-27T00:00:00Z);
WindowsEvent
| where TimeGenerated >= Start and TimeGenerated < datetime(2026-11-06T22:27:00Z)
| where Provider == "Microsoft-Windows-Sysmon"
| where EventID == 3 and tolower(tostring(EventData.Initiated)) == "true"
| where tostring(EventData.DestinationIp) in ("89.127.233.127","89.126.250.172")
| project TimeGenerated, Computer, user=tostring(EventData.User), image=tostring(EventData.Image), source_ip=tostring(EventData.SourceIp), source_port=tostring(EventData.SourcePort), destination_ip=tostring(EventData.DestinationIp), destination_port=tostring(EventData.DestinationPort), process_guid=tostring(EventData.ProcessGuid)

Elastic's Sysmon pipeline converts Initiated=true to network.direction egress, removes the raw field, and maps DestinationIp to destination.ip; CQL and Sentinel retain originals. MotherSphere identifies 89[.]127[.]233[.]127 as the agent server; 89[.]126[.]250[.]172 is only a victim-reported earlier insightjs[.]com address. Expect tbs_browser.exe for agent traffic; a blocked attempt cannot establish download.


Hunt 3: Check files and per-user persistence


The specific DLL path or per-user registry persistence merits investigation; the generic cleanup filename alone does not justify alerting.


Splunk


index=YOUR_SYSMON_INDEX earliest=1790467200 latest=1794004020
| eval event_id=tonumber(coalesce(EventCode, EventID))
| where (event_id=11 AND match(lower(TargetFilename), "^(.*\\\\google\\\\chrome\\\\(user data\\\\platformexperiencehelper\\\\[0-9a-f]{64}\\\\platform_experience_helper\\.dll|application\\\\([^\\\\]+\\\\)?platformexperiencehelper\\\\platform_experience_helper\\.dll)|.*\\\\service_util\\.dll|.*\\\\temp\\\\k2f-(bcreds|keyscan)-[^\\\\]+\\.db|.*\\\\temp\\\\k2f_screen_[0-9]+_[0-9]+\\.(jpg|png)|.*\\\\launcher\\\\log\\\\tinyget\\\\k2f\\.lua)$"))
    OR (event_id=13 AND match(lower(TargetObject), "^((hkcu|hkey_current_user)\\\\software\\\\classes\\\\|(hku|hkey_users)\\\\s-1-5-[0-9-]+(_classes\\\\|\\\\software\\\\classes\\\\))(wow6432node\\\\)?clsid\\\\\\{e77cc89b-7401-4c04-8ced-149db35add04\\}\\\\inprocserver32(\\\\.*)?$"))
| table _time host event_id User Image TargetFilename TargetObject Details ProcessGuid

Elastic


FROM logs-windows.sysmon_operational-*
| WHERE @timestamp >= "2026-09-27T00:00:00Z" AND @timestamp < "2026-11-06T22:27:00Z"
| WHERE (event.code == "11" AND TO_LOWER(file.path) RLIKE """(.*\\google\\chrome\\(user data\\platformexperiencehelper\\[0-9a-f]{64}\\platform_experience_helper\.dll|application\\([^\\]+\\)?platformexperiencehelper\\platform_experience_helper\.dll)|.*\\service_util\.dll|.*\\temp\\k2f-(bcreds|keyscan)-[^\\]+\.db|.*\\temp\\k2f_screen_[0-9]+_[0-9]+\.(jpg|png)|.*\\launcher\\log\\tinyget\\k2f\.lua)""")
    OR (event.code == "13" AND TO_LOWER(registry.path) RLIKE """((hkcu|hkey_current_user)\\software\\classes\\|(hku|hkey_users)\\s-1-5-[0-9-]+(_classes\\|\\software\\classes\\))(wow6432node\\)?clsid\\\{e77cc89b-7401-4c04-8ced-149db35add04\}\\inprocserver32(\\.*)?""")
| KEEP @timestamp, host.name, event.code, user.name, process.executable, file.path, registry.path, registry.data.strings, process.entity_id
| LIMIT 10000

CrowdStrike


Channel="Microsoft-Windows-Sysmon/Operational"
| cutoff := 1790467200000
| test(@timestamp >= cutoff)
| test(@timestamp < 1794004020000)
// Set the search time selector from 2026-09-27T00:00:00Z to 2026-11-06T22:27:00Z (end exclusive).
| ((EventID=11 TargetFilename=/^(.*\\google\\chrome\\(user data\\platformexperiencehelper\\[0-9a-f]{64}\\platform_experience_helper\.dll|application\\([^\\]+\\)?platformexperiencehelper\\platform_experience_helper\.dll)|.*\\service_util\.dll|.*\\temp\\k2f-(bcreds|keyscan)-[^\\]+\.db|.*\\temp\\k2f_screen_[0-9]+_[0-9]+\.(jpg|png)|.*\\launcher\\log\\tinyget\\k2f\.lua)$/i)
    or (EventID=13 TargetObject=/^((hkcu|hkey_current_user)\\software\\classes\\|(hku|hkey_users)\\s-1-5-[0-9-]+(_classes\\|\\software\\classes\\))(wow6432node\\)?clsid\\\{e77cc89b-7401-4c04-8ced-149db35add04\}\\inprocserver32(\\.*)?$/i))
| table([@timestamp, Computer, EventID, User, Image, TargetFilename, TargetObject, Details, ProcessGuid], limit=10000)

Microsoft KQL


let Start = datetime(2026-09-27T00:00:00Z);
WindowsEvent
| where TimeGenerated >= Start and TimeGenerated < datetime(2026-11-06T22:27:00Z)
| where Provider == "Microsoft-Windows-Sysmon"
| where (EventID == 11 and tolower(tostring(EventData.TargetFilename)) matches regex @"^(.*\\google\\chrome\\(user data\\platformexperiencehelper\\[0-9a-f]{64}\\platform_experience_helper\.dll|application\\([^\\]+\\)?platformexperiencehelper\\platform_experience_helper\.dll)|.*\\service_util\.dll|.*\\temp\\k2f-(bcreds|keyscan)-[^\\]+\.db|.*\\temp\\k2f_screen_[0-9]+_[0-9]+\.(jpg|png)|.*\\launcher\\log\\tinyget\\k2f\.lua)$")
    or (EventID == 13 and tolower(tostring(EventData.TargetObject)) matches regex @"^((hkcu|hkey_current_user)\\software\\classes\\|(hku|hkey_users)\\s-1-5-[0-9-]+(_classes\\|\\software\\classes\\))(wow6432node\\)?clsid\\\{e77cc89b-7401-4c04-8ced-149db35add04\}\\inprocserver32(\\.*)?$")
| project TimeGenerated, Computer, EventID, user=tostring(EventData.User), image=tostring(EventData.Image), file_path=tostring(EventData.TargetFilename), registry_path=tostring(EventData.TargetObject), value=tostring(EventData.Details), process_guid=tostring(EventData.ProcessGuid)

Map TargetFilename and TargetObject to Elastic file.path and registry.path, retaining original names elsewhere. Sysmon 11 records creation or overwrite, not every write. The file arm covers the 64-hex PlatformExperienceHelper subfolder; the Chrome Application path and less-specific service_util.dll that cleanup code names as probable earlier-version leftovers; and documented agent files: %TEMP% k2f-bcreds and k2f_screen copies, plus the Oct 23 build's reported k2f-keyscan copies and tinyget\k2f.lua. Temp copies are deleted right after use, and many Sysmon configurations filter %TEMP%, so absence is weak. The registry arm accepts HKCU and equivalent user-SID paths, including _Classes, but excludes HKLM. Review the value's destination; a generic filename alone is weak evidence.


Hunt 4: Inspect execution and loaded persistence


These independent branches find selected shell/transfer-tool children or Chrome loading the suspect DLL; missing children cannot rule out in-process collection.


Splunk


index=YOUR_SYSMON_INDEX earliest=1790467200 latest=1794004020
| eval event_id=tonumber(coalesce(EventCode, EventID))
| where (event_id=1 AND match(lower(ParentImage), "^.*\\\\(nikke_launcher(_google)?|tbs_browser)\\.exe$") AND match(lower(Image), "^.*\\\\(cmd|powershell|pwsh|curl|wget)\\.exe$"))
    OR (event_id=7 AND match(lower(Image), "^.*\\\\chrome\\.exe$") AND match(lower(ImageLoaded), "^.*\\\\google\\\\chrome\\\\user data\\\\platformexperiencehelper\\\\[0-9a-f]{64}\\\\platform_experience_helper\\.dll$"))
| table _time host event_id User ParentImage Image CommandLine ImageLoaded ProcessGuid ParentProcessGuid

Elastic


FROM logs-windows.sysmon_operational-*
| WHERE @timestamp >= "2026-09-27T00:00:00Z" AND @timestamp < "2026-11-06T22:27:00Z"
| WHERE (event.code == "1" AND TO_LOWER(process.parent.executable) RLIKE """.*\\(nikke_launcher(_google)?|tbs_browser)\.exe""" AND TO_LOWER(process.executable) RLIKE """.*\\(cmd|powershell|pwsh|curl|wget)\.exe""")
    OR (event.code == "7" AND TO_LOWER(process.executable) RLIKE """.*\\chrome\.exe""" AND TO_LOWER(file.path) RLIKE """.*\\google\\chrome\\user data\\platformexperiencehelper\\[0-9a-f]{64}\\platform_experience_helper\.dll""")
| KEEP @timestamp, host.name, event.code, user.name, process.parent.executable, process.executable, process.command_line, file.path, process.entity_id, process.parent.entity_id
| LIMIT 10000

CrowdStrike


Channel="Microsoft-Windows-Sysmon/Operational"
| cutoff := 1790467200000
| test(@timestamp >= cutoff)
| test(@timestamp < 1794004020000)
// Set the search time selector from 2026-09-27T00:00:00Z to 2026-11-06T22:27:00Z (end exclusive).
| ((EventID=1 ParentImage=/^.*\\(nikke_launcher(_google)?|tbs_browser)\.exe$/i Image=/^.*\\(cmd|powershell|pwsh|curl|wget)\.exe$/i)
    or (EventID=7 Image=/^.*\\chrome\.exe$/i ImageLoaded=/^.*\\google\\chrome\\user data\\platformexperiencehelper\\[0-9a-f]{64}\\platform_experience_helper\.dll$/i))
| table([@timestamp, Computer, EventID, User, ParentImage, Image, CommandLine, ImageLoaded, ProcessGuid, ParentProcessGuid], limit=10000)

Microsoft KQL


let Start = datetime(2026-09-27T00:00:00Z);
WindowsEvent
| where TimeGenerated >= Start and TimeGenerated < datetime(2026-11-06T22:27:00Z)
| where Provider == "Microsoft-Windows-Sysmon"
| where (EventID == 1 and tolower(tostring(EventData.ParentImage)) matches regex @"^.*\\(nikke_launcher(_google)?|tbs_browser)\.exe$" and tolower(tostring(EventData.Image)) matches regex @"^.*\\(cmd|powershell|pwsh|curl|wget)\.exe$")
    or (EventID == 7 and tolower(tostring(EventData.Image)) matches regex @"^.*\\chrome\.exe$" and tolower(tostring(EventData.ImageLoaded)) matches regex @"^.*\\google\\chrome\\user data\\platformexperiencehelper\\[0-9a-f]{64}\\platform_experience_helper\.dll$")
| project TimeGenerated, Computer, EventID, user=tostring(EventData.User), parent=tostring(EventData.ParentImage), image=tostring(EventData.Image), command_line=tostring(EventData.CommandLine), module=tostring(EventData.ImageLoaded), process_guid=tostring(EventData.ProcessGuid), parent_guid=tostring(EventData.ParentProcessGuid)

Map Sysmon ParentImage, Image and ImageLoaded to Elastic process.parent.executable, process.executable and file.path; CQL and Sentinel retain originals. Neither arm requires the other. Enable image-load logging; in-process file and browser collection need not create children.


Read the host artifacts too


Inspect preserved logs for k2f_chan registered, agent started as and lua downloaded to log\tinyget\; inspect Local Storage for k2f.agent.state. MotherSphere's read-only checker is optional triage, not a tool whose safety or effectiveness we have validated.


Interpret before you escalate


Finding

What to establish next

Domain lookup

Which process made it, when, and whether it was a later security check

Outbound connection

Whether it succeeded and aligns with a launcher run

Generic DLL name

Full path, writer and nearby agent evidence

Per-user CLSID value

Its target, writer and whether it points at the suspicious DLL

k2f temp file or tinyget\k2f.lua

Supports agent activity; preserve it and identify the writing process

Launcher child process

Check command line, expected local launcher behavior and preserved artifacts before escalation; a child alone is not proof

Chrome loading the 64-hex-path DLL

Preserve the file and expand credential investigation

No results

Collection coverage, retention and whether cleanup already removed traces


What to alert on


Prioritize per-user persistence, Chrome DLL loads and k2f files; investigate other hits with context. Do not alert solely on Chrome's legitimate helper folder.


What This Means for Your Team


Connect the employee, endpoint and work accounts. A game update does not establish that business credentials are safe.


Sources



Inception Protection


Inception Protection is our managed detection and response service, with analysts reviewing endpoint, identity, email and cloud alerts around the clock.


Inception Foresight


The free Inception Foresight M365 Assessment reviews Microsoft 365 identity, email, sharing, device and audit settings and returns a prioritized remediation plan. It does not examine game files or certify malware removal. Request the M365 Assessment.


bg-map-white.png

INCEPTION SECURITY™

A cybersecurity company with in depth knowledge of the threat landscape and security controls.

NAVIGATION

GET IN TOUCH

© 2025 All Rights Reserved by INCEPTION SECURITY™ .

bottom of page