Egress from ISPs and Proxy Services Reported in DPRK Worker Cases
Identity / cloudNetwork
IOC Hunt medium DPRK IT Worker FraudLaptop Farm
The addresses operators appear on when the VPN is not in the way: Russian TTK ranges around Khabarovsk, China Unicom, and the commercial proxy and hosting services named in recent casework.
What this hunt looks for
ReliaQuest's central observation is that operators slip: the same account authenticates through Astrill one day and from the Russian ISP TransTelekom the next. ReliaQuest publishes the TTK addresses seen in these campaigns, many in Khabarovsk, and China Unicom addresses found investigating North Korean incidents; Mandiant's table carries three of the same China Unicom addresses.
Huntress advises monitoring authentication through IPRoyal Proxy and infrastructure associated with WorkTitans B.V. in its 2026 casework. Where an employee's account has ever authenticated from any of these, that is a lead that does not depend on VPN attribution at all.
- Technique
- Session origin inconsistent with claimed residence, surfaced through proxy and hosting infrastructure (MITRE ATT&CK T1090, T1090.003) associated with fraudulently obtained employment (T1078).
- Data sources
- Identity provider sign-in logs, VPN/firewall logs, Proxy logs
- Last updated
- 2026-10-04
Indicators
The atomic values this hunt matches on, listed separately from the queries so they can be lifted into tooling that speaks none of the query languages below. Every value here is reported by one of the sources cited at the foot of this page.
| Type | Value | Note |
|---|---|---|
| IP | 80.237.84.12 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 80.237.87.21 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 83.234.227.33 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 83.234.227.34 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 83.234.227.35 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 83.234.227.36 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 83.234.227.37 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 83.234.227.38 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 188.43.33.252 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 188.43.136.41 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 188.43.136.115 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 188.43.253.77 |
TransTelekom (TTK), Russia; many geolocated in Khabarovsk. Published by ReliaQuest as associated with this campaign. |
| IP | 42.84.228.232 |
China Unicom, found by ReliaQuest while investigating North Korean incidents; 42.84.228.232, 60.20.1.234 and 113.227.237.46 also appear in Mandiant's table. |
| IP | 60.20.1.234 |
China Unicom, found by ReliaQuest while investigating North Korean incidents; 42.84.228.232, 60.20.1.234 and 113.227.237.46 also appear in Mandiant's table. |
| IP | 139.215.45.250 |
China Unicom, found by ReliaQuest while investigating North Korean incidents; 42.84.228.232, 60.20.1.234 and 113.227.237.46 also appear in Mandiant's table. |
| IP | 113.227.237.46 |
China Unicom, found by ReliaQuest while investigating North Korean incidents; 42.84.228.232, 60.20.1.234 and 113.227.237.46 also appear in Mandiant's table. |
| IP | 123.190.56.214 |
China Unicom, found by ReliaQuest while investigating North Korean incidents; 42.84.228.232, 60.20.1.234 and 113.227.237.46 also appear in Mandiant's table. |
| Service | IPRoyal Proxy |
Commercial proxy provider Huntress advises monitoring authentication through (2026-08-26). |
| Service | WorkTitans B.V. |
Hosting provider whose infrastructure Huntress advises monitoring (2026-08-26). |
| Certificate subject | hangro.net.kp |
North Korean ccTLD subject name found by ReliaQuest in a certificate tied to a Russian address. |
Logic
Every query below implements these steps, so the same hunt returns the same result in each product.
- Collect: Entra ID and Okta sign-ins; DNS and connection records from endpoints and proxies
- Match: sign-in source address is one of the 17 TTK or China Unicom addresses published by ReliaQuest and Mandiant
- Match: or a looked-up or contacted name contains iproyal, worktitans or hangro.net.kp (optionally any .kp name)
- Report: users and devices with the matched address or name, newest first
Queries
Defender / Sentinel KQL
Written for this site, from indicators reported by ReliaQuest, Mandiant, HuntressRows are users (sign-ins) or devices (lookups) that touched a reported address or name; these are ISP and proxy ranges with ordinary customers, so treat a hit as a lead.
// Hunt: egress from ISPs and proxy services reported in DPRK worker cases. ReliaQuest publishes 83.234.227.33-8 in compressed form; .33 to .38 is the reading used.
let ReportedAddresses = dynamic(["80.237.84.12", "80.237.87.21", "83.234.227.33", "83.234.227.34", "83.234.227.35", "83.234.227.36", "83.234.227.37", "83.234.227.38", "188.43.33.252", "188.43.136.41", "188.43.136.115", "188.43.253.77", "42.84.228.232", "60.20.1.234", "139.215.45.250", "113.227.237.46", "123.190.56.214"]);
union
( union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(90d)
| where IPAddress in (ReportedAddresses)
| project Timestamp = TimeGenerated, Subject = UserPrincipalName, Signal = "reported-signin-address", Evidence = strcat(IPAddress, " ", AppDisplayName) ),
( DeviceNetworkEvents
| where Timestamp > ago(90d)
| where RemoteUrl has_any ("iproyal", "worktitans") or RemoteUrl contains "hangro.net.kp"
// optional: any North Korean (.kp) name, not only the certificate subject ReliaQuest found
or RemoteUrl endswith ".kp"
| project Timestamp, Subject = DeviceName, Signal = "proxy-or-kp-name", Evidence = RemoteUrl )
| summarize Events = count(), Signals = make_set(Signal), Evidence = make_set(Evidence, 10), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by Subject
| sort by LastSeen desc
Lower-fidelity parts (1)
- the .kp suffix test — it widens the sourced certificate subject to every .kp name. Remove: delete the // optional: any North Korean line and the or RemoteUrl endswith line under it
Splunk SPL
Written for this site, from indicators reported by ReliaQuest, Mandiant, HuntressSign-in addresses and name lookups across identity, DNS and proxy data per user or source address.
```Placeholders: index=identity holds Okta, Entra ID or ms:aad:signin events with src_ip and user extracted; index=dns or index=proxy hold name lookups and web requests.```
(index=identity (sourcetype=okta OR sourcetype=azuread OR sourcetype="ms:aad:signin") src_ip IN ("80.237.84.12", "80.237.87.21", "83.234.227.33", "83.234.227.34", "83.234.227.35", "83.234.227.36", "83.234.227.37", "83.234.227.38", "188.43.33.252", "188.43.136.41", "188.43.136.115", "188.43.253.77", "42.84.228.232", "60.20.1.234", "139.215.45.250", "113.227.237.46", "123.190.56.214"))
OR ((index=dns OR index=proxy) ("iproyal" OR "worktitans" OR "hangro.net.kp"
```optional: any North Korean (.kp) name``` OR "*.kp"))
| eval signal=if(index="identity", "reported-signin-address", "proxy-or-kp-name"), subject=coalesce(user, src_ip)
| stats count AS events values(signal) AS signals values(src_ip) AS addresses min(_time) AS first_seen max(_time) AS last_seen BY subject
| convert ctime(first_seen) ctime(last_seen)
| sort - last_seen
Lower-fidelity parts (1)
- the *.kp term — it widens the sourced certificate subject to every .kp name. Remove: delete the ```optional comment and the OR "*.kp" term after it
CrowdStrike LogScale
Written for this site, from indicators reported by ReliaQuest, Mandiant, HuntressFree-text address match over ingested sign-in events plus DnsRequest name matches from Falcon.
// Hunt: egress from ISPs and proxy services reported in DPRK worker cases. Scope the query to the repository holding your sign-in events; the address is matched as a whole token, so no parser field name is assumed.
regex("(?:^|[^0-9.])(?<matchedIp>80[.]237[.]84[.]12|80[.]237[.]87[.]21|83[.]234[.]227[.]33|83[.]234[.]227[.]34|83[.]234[.]227[.]35|83[.]234[.]227[.]36|83[.]234[.]227[.]37|83[.]234[.]227[.]38|188[.]43[.]33[.]252|188[.]43[.]136[.]41|188[.]43[.]136[.]115|188[.]43[.]253[.]77|42[.]84[.]228[.]232|60[.]20[.]1[.]234|139[.]215[.]45[.]250|113[.]227[.]237[.]46|123[.]190[.]56[.]214)(?:[^0-9.]|$)", strict=false)
| regex("(?:userPrincipalName|alternateId)[^a-zA-Z0-9_]+(?<user>[^\"]+)", strict=false)
| case {
#event_simpleName=DnsRequest DomainName=/iproyal|worktitans|hangro[.]net[.]kp/i | signal := "proxy-or-kp-name";
// optional: any North Korean (.kp) name
#event_simpleName=DnsRequest DomainName=/[.]kp$/i | signal := "proxy-or-kp-name";
matchedIp=* | signal := "reported-signin-address";
* | signal := "";
}
| signal != ""
| groupBy([signal, matchedIp, user, ComputerName], function=[count(as=events), min(@timestamp, as=firstSeen), max(@timestamp, as=lastSeen)])
| sort(lastSeen, order=desc)
Lower-fidelity parts (1)
- the .kp suffix branch — it widens the sourced certificate subject to every .kp name. Remove: delete the // optional comment and the DomainName=/[.]kp$/i line under it
Elastic
Written for this site, from indicators reported by ReliaQuest, Mandiant, HuntressSign-ins from the reported addresses and DNS lookups of the named services, per subject.
FROM logs-azure.signinlogs-*, logs-okta*, logs-endpoint.events.network-*
| WHERE @timestamp > NOW() - 90 days
| EVAL src = TO_STRING(source.ip)
| EVAL name = TO_LOWER(COALESCE(dns.question.name, ""))
| EVAL signal = CASE(
src IN ("80.237.84.12", "80.237.87.21", "83.234.227.33", "83.234.227.34", "83.234.227.35", "83.234.227.36", "83.234.227.37", "83.234.227.38", "188.43.33.252", "188.43.136.41", "188.43.136.115", "188.43.253.77", "42.84.228.232", "60.20.1.234", "139.215.45.250", "113.227.237.46", "123.190.56.214"), "reported-signin-address",
name RLIKE ".*(iproyal|worktitans|hangro[.]net[.]kp).*", "proxy-or-kp-name",
"")
| EVAL signal = CASE(signal != "", signal, name RLIKE ".*[.]kp", "proxy-or-kp-name", "")
| WHERE signal != ""
| EVAL subject = COALESCE(azure.signinlogs.properties.user_principal_name, user.name, host.name)
| STATS events = COUNT(*), signals = VALUES(signal), first_seen = MIN(@timestamp), last_seen = MAX(@timestamp) BY subject
| SORT last_seen DESC
Lower-fidelity parts (1)
- the .kp EVAL line — it widens the sourced certificate subject to every .kp name. Remove: delete the second `| EVAL signal = CASE(signal != ""` line
Cortex XQL
Written for this site, from indicators reported by ReliaQuest, HuntressEndpoint lookups of the named proxy services and .kp names per host.
// Hunt: proxy-service and .kp names from endpoints. Sign-in addresses need your identity data, which xdr_data does not hold.
dataset = xdr_data
| filter event_type = ENUM.NETWORK and (dns_query_name ~= "(?i)iproyal|worktitans|hangro[.]net[.]kp"
or action_external_hostname ~= "(?i)iproyal|worktitans|hangro[.]net[.]kp"
// optional: any North Korean (.kp) name
or dns_query_name ~= "(?i)[.]kp$")
| comp count() as events, values(dns_query_name) as names, min(_time) as first_seen, max(_time) as last_seen by agent_hostname
| sort desc last_seen
Lower-fidelity parts (1)
- the .kp suffix test — it widens the sourced certificate subject to every .kp name. Remove: delete the // optional comment and the dns_query_name ~= line under it
False positives and tuning
These addresses are ISP and hosting infrastructure with ordinary customers and date from the reports that published them, so treat them as historical examples, not live indicators.
ReliaQuest publishes 83.234.227.33-8 in compressed form, expanded here as .33 through .38; verify that reading against the source before acting on the middle of the range.
IPRoyal and comparable proxy services carry much legitimate traffic, so a name hit is a lead; a sign-in from a reported address is a reason to look, not a finding.
Sources
- Threat Spotlight: Red Flags for Red Star Hackers: Hunting for North Korean Insiders — ReliaQuest, 2025-05-08
- Staying a Step Ahead: Mitigating the DPRK IT Worker Threat — Google Cloud (Mandiant), 2024-09-23
- Insights into Suspected DPRK Workers: Red Flags to Look Out For — Huntress, 2026-08-26