top of page

Hunt AA26-281A: the SoftEther client named conhost.exe

Writer: Inception Security
Inception Security
11 minutes ago
9 min read
A SoftEther VPN client renamed conhost.exe blends in with legitimate Windows processes and reconnects at every boot.
A SoftEther VPN client renamed conhost.exe blends in with legitimate Windows processes and reconnects at every boot.

Picture an analyst closing an alert because it names conhost.exe, a process every Windows machine runs. This copy lives in a user profile, not System32, and reconnects to the same outside host at every boot. Meanwhile the mail server answers Exchange Web Services requests at 3 a.m.


On 8 October 2026, the FBI, CISA, NSA, and partner agencies in six countries published joint advisory AA26-281A. It describes "Chinese government-linked cyber threat actors, enabled by the Integrity Technology Group," who scan, spray, persist, and steal mail and Active Directory data. The analysis comes from multiple FBI investigations, and named target sectors include government, critical manufacturing, healthcare, and IT.


Why this one is different


Most of this chain is familiar: scanners, an XSS page, password spraying against Exchange. The persistence is what lasts. The actors install SoftEther, a legitimate VPN client, set it to reconnect on startup, and "often name the installers conhost.exe or dllhost.exe." The advisory adds that endpoint tools are "less likely to flag SoftEther because it is a legitimate VPN software."


Our reading: the SoftEther client named conhost.exe is the persistence that turns a sprayed mailbox into a long stay.


On attribution, the actors enabled by Integrity Tech "use TTPs consistent with" Flax Typhoon, Ethereal Panda, and Red Juliett, "among others," and "may also perform activity not associated with Integrity Tech." Vendor tracking "may not be a 1:1 correlation" with the US Government's view.


Carry two questions. Could you list every conhost.exe or dllhost.exe running outside System32 today? And would anyone notice one address failing against dozens of mailboxes over EWS and Autodiscover in an hour?


How Integrity Tech-enabled actors turn a scan into a stolen mailbox

Scanners and MicroScan

The actors run open-source scanners such as Fscan, masscan, NMAP, and dirsearch, mostly against ports 21, 22, 53, 80, 443, and 1080. Since at least 2017, they have used MicroScan, a Python web application with more than 1,300 scripts aimed at services including WebLogic, Jenkins, and Apache Struts.


Appendix B lists eight successfully exploited CVEs recovered from those scripts. The five it marks as new to CISA's Known Exploited Vulnerabilities catalog are the 8 October KEV adds, due 11 October for federal civilian agencies: CVE-2015-3306 (ProFTPD), CVE-2015-5477 (ISC BIND), CVE-2016-3081 (Apache Struts), CVE-2021-3199 (ONLYOFFICE DocumentServer), and CVE-2023-22894 (Strapi). The other three are CVE-2014-6278, CVE-2019-11510, and CVE-2021-22205.


XSS dropper to DiagTrack.exe


A recovered XSS payload paints username and password fields onto a vulnerable page, then offers a password-protected zip holding live700_v1.exe. It starts DiagTrack.exe, malware sharing a legitimate Windows name, which talks encrypted HTTP to dns.studiocloud[.]xyz, a domain the FBI attributes to Integrity Tech. The executable also holds mailbox query functions.


EBurst against Exchange and M365


EBurst, an open-source Python tool, sprays and guesses passwords for each target address. Citing the EBurst ReadMe, the advisory lists ECP, EWS, OAB, OWA, RPC, API, MAPI, PowerShell, Autodiscover, and Microsoft-Server-ActiveSync, and says to defend all of them.


SoftEther renamed conhost.exe or dllhost.exe


The actors pull SoftEther installers with PowerShell or other built-in binaries on Windows, and curl or wget on Linux. The client reaches SoftEther hubs on what the advisory calls victim domains and subdomains, such as 98aiblog[.]com, hmbcloud[.]com, javacheck.ooguy[.]com, and twimg.co[.]uk, or the server's IP address.


Our reading: system names running from user or temp paths make a short, high signal list.


Staging, Curlc4, DCSync, and office-cli


Stolen mail is staged under quiet names such as 001.gif, Css.js, and M2k.js. Curlc4.txt, a PHP bot, pulls mail through the EWS API, compresses and sometimes encrypts it, uploads it to a remote server, and renames its child process crypto; its main C2 domain was natcloudservice[.]com. DC.exe binds over RPC to a domain controller and uses the Directory Replication Service to copy credentials, group memberships, and trusts. office-cli, a Linux binary, keeps reading Outlook 365 mailboxes with configuration files such as client_id, tenant_id, and secret. A custom web application lets third parties view the stolen mail.


What CISA published and what it did not


The advisory publishes the chain above, ATT&CK tables, and Appendix A indicators with hashes, also in STIX. It warns that "Several of the observed IOCs date back to as early as 2016" and recommends "investigating or vetting these IOCs before taking action, such as blocking." The hunts use a short pick-list: narrative hub and C2 domains, some last seen in 2020 to 2022, plus IPs active in 2024. Hashes stay in the STIX.


It does not name victim organizations, give a victim count, or size the botnets its summary mentions.


What to change this week


If a hunt hits, follow the advisory: isolate, scope, report (IC3, CISA, or your national center), evict with CISA's Eviction Strategies Tool, and harden. Either way, start with these picks from the agencies' list, in the advisory's order:


  1. Disable unused services and ports, and make banners reveal little.

  2. Sanitize web application input to stop XSS payload injection.

  3. Put ICAM policies in place, then require MFA for all services where possible, "particularly for webmail, VPNs, and accounts that access critical systems." Our reading: block legacy authentication wherever MFA cannot apply.

  4. Replace default passwords; limit and audit admin accounts.

  5. Turn on download and domain reputation screening and protective DNS.

  6. Monitor for unauthorized use of built-in tools and unexpected Active Directory replication.

  7. Monitor cloud accounts for connected applications that can read mail and files.

  8. Patch (our reading: start with Appendix B), and replace end-of-life products.


Four hunts to run


Each query is our field-name translation, so each is test first. Indicators come from that pick-list, refanged only inside queries; vet them before blocking. "Interpret before you escalate" says what is benign.


Hunt in Splunk: renamed SoftEther, named tools, and replication by user accounts

index=YOUR_WINDOWS_INDEX ((source="*Sysmon*" EventCode IN (1, 3, 22)) OR (EventCode=4662 "0x100" ("1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" OR "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" OR "89e95b76-444d-4c62-991a-0facbeda640c")))
| eval img=lower(Image), qn=lower(QueryName), actor=coalesce(SubjectUserName, User), pe=coalesce(Product,"")." ".coalesce(Description,"")." ".coalesce(Company,"")
| eval signals=mvappend(
    if(EventCode=1 AND match(img, "\\\\(conhost|dllhost)\\.exe$") AND NOT match(img, "^[a-z]:\\\\windows\\\\(system32|syswow64|winsxs)\\\\"), "system_name_outside_system32", null()),
    if(EventCode=1 AND match(pe, "(?i)softether"), "softether_binary", null()),
    if(EventCode=1 AND match(img, "[\\\\/](dc\\.exe|office-cli)$"), "advisory_tool_name", null()),
    if(EventCode=22 AND match(qn, "(^|\\.)(studiocloud\\.xyz|natcloudservice\\.com|98aiblog\\.com|hmbcloud\\.com|hmbcloud\\.net|hmbiplc-01\\.com|iepl\\.node\\.cm|javacheck\\.ooguy\\.com|javaupdate\\.giize\\.com|sexytube0\\.com|twimg\\.co\\.uk)$"), "pick_list_dns", null()),
    if(EventCode=3 AND in(DestinationIp, "149.28.132.137","149.28.132.161","45.32.61.246","64.176.38.35","66.42.40.189","66.42.60.242","103.179.45.203","108.61.181.104","138.199.62.148","139.84.174.129","141.164.55.227"), "pick_list_ip", null()),
    if(EventCode=4662 AND NOT match(actor, "\\$$"), "replication_by_non_machine_account", null()))
| where isnotnull(signals)
| stats min(_time) as first_seen, max(_time) as last_seen, values(signals) as signals, values(Image) as images, values(QueryName) as queries, values(actor) as actors by host
| convert ctime(first_seen) ctime(last_seen)
| sort 0 first_seen

Field mapping: Sysmon via the Splunk add-on plus domain controller Security logs. Event 4662 needs Directory Service Access auditing plus a domain root SACL; the GUIDs are Microsoft's replication rights, our mapping of the advisory's DCSync. office-cli needs Linux process logs. Test first.

False positives: Entra Connect and other sync accounts replicate; dc.exe is a common name.


Empty result: confirm Sysmon DNS logging is on, and 4662 reaches the index.


Hunt in Kibana: the misplaced system binary, then the Exchange spray


Search 1: renamed SoftEther, named tools, and pick-list traffic

any where
  (process.name : ("conhost.exe", "dllhost.exe") and
     not process.executable : ("?:\\Windows\\System32\\*", "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\WinSxS\\*")) or
  ?process.pe.product : "*SoftEther*" or ?process.pe.company : "*SoftEther*" or
  process.name : ("dc.exe", "office-cli") or
  ?dns.question.name : ("studiocloud.xyz", "*.studiocloud.xyz", "natcloudservice.com", "*.natcloudservice.com", "98aiblog.com", "*.98aiblog.com", "hmbcloud.com", "*.hmbcloud.com", "hmbcloud.net", "*.hmbcloud.net", "hmbiplc-01.com", "*.hmbiplc-01.com", "iepl.node.cm", "*.iepl.node.cm", "javacheck.ooguy.com", "*.javacheck.ooguy.com", "javaupdate.giize.com", "*.javaupdate.giize.com", "sexytube0.com", "*.sexytube0.com", "twimg.co.uk", "*.twimg.co.uk") or
  cidrMatch(?destination.ip, "149.28.132.137/32", "149.28.132.161/32", "45.32.61.246/32", "64.176.38.35/32", "66.42.40.189/32", "66.42.60.242/32", "103.179.45.203/32", "108.61.181.104/32", "138.199.62.148/32", "139.84.174.129/32", "141.164.55.227/32")

Search 2: one address failing logons on the EBurst interfaces

FROM logs-iis.access-*
| WHERE http.response.status_code == 401 AND iis.access.win32_status IN (1326, 2148074252) AND TO_LOWER(url.path) RLIKE "/(ews|ecp|owa|oab|rpc|api|mapi|powershell|autodiscover|microsoft-server-activesync)(/.*)?"
| EVAL hour = DATE_TRUNC(1 hour, @timestamp)
| STATS failures = COUNT(*), users = COUNT_DISTINCT(user.name) BY source.ip, hour
| WHERE failures >= 50 OR users >= 15
| SORT failures DESC

Field mapping: EQL over Elastic Defend or Sysmon data, then ES|QL over Exchange IIS logs. NTLM handshakes also log 401s, so Search 2 keeps Windows logon failures; OWA and ECP form logons fail with a 302 instead. Test first.

False positives: a load balancer health check or a phone with a stale password.

Empty result: IIS often logs no user on a 401; lean on failure counts.


Hunt in Falcon CQL: system names in the wrong folder

#event_simpleName=/^(ProcessRollup2|DnsRequest|NetworkConnectIP4)$/
| case {
    #event_simpleName=ProcessRollup2 ImageFileName=/\\(conhost|dllhost)\.exe$/i ImageFileName!=/\\Windows\\(System32|SysWOW64|WinSxS)\\/i | signal := "system_name_outside_system32" ;
    #event_simpleName=ProcessRollup2 ImageFileName=/[\\\/](dc\.exe|office-cli)$/i | signal := "advisory_tool_name" ;
    #event_simpleName=ProcessRollup2 ImageFileName=/\\(vpnclient|vpnbridge)(_x64)?\.exe$/i | signal := "softether_binary" ;
    #event_simpleName=ProcessRollup2 CommandLine=/(Invoke-WebRequest|iwr\s|DownloadFile|Start-BitsTransfer|bitsadmin|certutil|curl|wget).*(conhost|dllhost)\.exe/i | signal := "download_named_like_system_binary" ;
    #event_simpleName=DnsRequest DomainName=/(^|\.)(studiocloud\.xyz|natcloudservice\.com|98aiblog\.com|hmbcloud\.(com|net)|hmbiplc-01\.com|iepl\.node\.cm|javacheck\.ooguy\.com|javaupdate\.giize\.com|sexytube0\.com|twimg\.co\.uk)$/i | signal := "pick_list_dns" ;
    #event_simpleName=NetworkConnectIP4 in(field="RemoteAddressIP4", values=["149.28.132.137","149.28.132.161","45.32.61.246","64.176.38.35","66.42.40.189","66.42.60.242","103.179.45.203","108.61.181.104","138.199.62.148","139.84.174.129","141.164.55.227"]) | signal := "pick_list_ip" ;
    * | signal := "" ;
  }
| signal != ""
| default(field=ComputerName, value="-")
| groupBy([aid, ComputerName, signal], function=[min(@timestamp, as=first_seen), max(@timestamp, as=last_seen), collect([ImageFileName, CommandLine, DomainName, RemoteAddressIP4], limit=10), count()])
| sort(first_seen, order=asc)

Field mapping: Falcon sensor events in Next-Gen SIEM, matched on the ImageFileName path. Join aid to host details if ComputerName is empty. Test first.

False positives: portable apps bundling their own dllhost.exe; your own curl installs.

Empty result: confirm your sensors collect DNS events.


Hunt in KQL: endpoint and identity, then mail reads across mailboxes


Search 1: Defender XDR advanced hunting

let Lookback = 30d;
let PickDomains = dynamic(["studiocloud.xyz","natcloudservice.com","98aiblog.com","hmbcloud.com","hmbcloud.net","hmbiplc-01.com","iepl.node.cm","javacheck.ooguy.com","javaupdate.giize.com","sexytube0.com","twimg.co.uk"]);
let PickIps = dynamic(["149.28.132.137","149.28.132.161","45.32.61.246","64.176.38.35","66.42.40.189","66.42.60.242","103.179.45.203","108.61.181.104","138.199.62.148","139.84.174.129","141.164.55.227"]);
let DomainControllers = dynamic(["YOUR_DC_1_FQDN","YOUR_DC_2_FQDN"]);
let Renamed = DeviceProcessEvents
| where Timestamp > ago(Lookback)
| where (FileName in~ ("conhost.exe","dllhost.exe") and not(FolderPath matches regex @"(?i)^[a-z]:\\windows\\(system32|syswow64|winsxs)\\"))
    or ProcessVersionInfoProductName has "SoftEther" or ProcessVersionInfoCompanyName has "SoftEther"
    or FileName in~ ("dc.exe","office-cli")
| project Timestamp, DeviceName, Signal = "renamed_or_named_binary", Detail = strcat(FolderPath, " ", ProcessVersionInfoProductName), Account = AccountName;
let Net = DeviceNetworkEvents
| where Timestamp > ago(Lookback)
| where RemoteIP in (PickIps) or RemoteUrl has_any (PickDomains)
| project Timestamp, DeviceName, Signal = "pick_list_network", Detail = strcat(RemoteUrl, " ", RemoteIP), Account = InitiatingProcessAccountName;
let Dns = DeviceEvents
| where Timestamp > ago(Lookback)
| where ActionType == "DnsQueryResponse"
| extend Q = tostring(parse_json(AdditionalFields).DnsQueryString)
| where Q has_any (PickDomains)
| project Timestamp, DeviceName, Signal = "pick_list_dns", Detail = Q, Account = InitiatingProcessAccountName;
let Repl = IdentityDirectoryEvents
| where Timestamp > ago(Lookback)
| where ActionType == "Directory Services replication"
| where DeviceName !in~ (DomainControllers)
| project Timestamp, DeviceName, Signal = "replication_from_non_dc", Detail = tostring(AdditionalFields), Account = AccountName;
union Renamed, Net, Dns, Repl
| summarize FirstSeen = min(Timestamp), LastSeen = max(Timestamp), Signals = make_set(Signal), Details = make_set(Detail, 10), Accounts = make_set(Account, 10) by DeviceName
| order by FirstSeen asc

Search 2: Sentinel, EBurst-shaped failures and EWS or REST reads across many mailboxes

let Lookback = 30d;
let MailClients = dynamic(["Exchange Web Services","Exchange ActiveSync","Autodiscover","Exchange Online PowerShell","MAPI Over HTTP","Offline Address Book","Outlook Anywhere (RPC over HTTP)","Other clients"]);
let Spray = union isfuzzy=true SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(Lookback)
| where ResultType in ("50126","50053")
| where ClientAppUsed in (MailClients) or (ClientAppUsed == "Browser" and ResourceDisplayName == "Office 365 Exchange Online")
| summarize Users = dcount(UserPrincipalName), Events = count(), Codes = make_set(ResultType), Clients = make_set(ClientAppUsed, 10) by Source = IPAddress, Hour = bin(TimeGenerated, 1h)
| where Users >= 15
| extend Signal = "eburst_shaped_spray";
let Bulk = OfficeActivity
| where TimeGenerated > ago(Lookback)
| where Operation == "MailItemsAccessed"
| extend ClientInfo = tostring(column_ifexists("ClientInfoString", "")), App = tostring(column_ifexists("AppId", ""))
| where ClientInfo startswith "Client=WebServices" or ClientInfo startswith "Client=REST"
| summarize Users = dcount(MailboxOwnerUPN), Events = count(), Clients = make_set(ClientInfo, 5) by Source = coalesce(ClientIP, Client_IPAddress), App, Hour = bin(TimeGenerated, 1h)
| where Users >= 5
| extend Signal = "ews_or_rest_reads_across_mailboxes";
union Spray, Bulk
| order by Hour asc

Field mapping: Search 1 needs Defender for Endpoint, plus Defender for Identity for replication. Search 2 sees cloud sign-ins only; 50053 can also mean a blocked IP, and one MailItemsAccessed record can bundle many reads. Test first.

False positives: backup and eDiscovery apps; shared NAT addresses.

Empty result: confirm MailItemsAccessed is audited and sign-in logs are connected.


Interpret before you escalate

Finding

Benign read

Escalate when

conhost.exe or dllhost.exe outside System32

Bundled portable software

Product or description says SoftEther, or it starts at boot and holds an outbound session

Download named conhost.exe or dllhost.exe

Software deployment tooling

PowerShell, curl, or wget pulls it from an unknown host

DNS or traffic to a pick-list domain or IP

Address reassigned since 2024

Any process other than a browser, or repeat beacons

dc.exe or office-cli on a host

Unrelated tool with the same name

Running from a user path, or near replication or mail activity

Replication from a non-DC or user account

Entra Connect or approved sync

Account or host has no documented replication role

One address failing across EBurst interfaces

Stale password on a phone

Many distinct mailboxes in an hour, then a success

EWS or REST reads across many mailboxes

Backup or eDiscovery app

Unknown app, new secret, or reads spanning many mailboxes

Empty results

Nothing matched

Sysmon DNS, 4662, IIS, or mail audit logs are missing, so fix coverage first

Sources

What This Means for Your Team


Treat a Windows system name in the wrong folder as a lead, not noise. Put MFA in front of every EBurst interface that supports it, block legacy authentication on the rest, list who may replicate your directory, and review which apps can read mail. Then run the four hunts. A SoftEther client named conhost.exe is the seam to chase.


Inception Protection


Inception Protection is our managed detection and response service, and it works with the Microsoft licenses you already have. This chain runs from Exchange sign-ins through an endpoint into Active Directory, so we read Entra sign-in, Defender, Defender for Identity, and mailbox audit signals as one story and move on accounts and hosts fast. You keep the decisions.


Inception Foresight


If you want to see how well your Microsoft environment would surface activity like this, the free Inception Foresight M365 Assessment is a good place to start: https://www.inceptionsecurity.com/m365assessment. You can also follow Inception Security on LinkedIn and @inceptionsec on X.

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