Technical Deep Dive: Analyzing Starkiller's Reverse Proxy Architecture & MFA Relay
Just saw the Krebs report on the 'Starkiller' PhaaS offering, and it’s a textbook example of Adversary-in-the-Middle (AitM) sophistication moving mainstream. Unlike static kits that get flagged by hash-based filters instantly, Starkiller proxies the legitimate site in real-time. This means the SSL certificate is valid, the page content is dynamic, and standard URL reputation engines often fail because the traffic is technically hitting the real login endpoint after the initial hop.
The core danger here is the automated MFA relay. The attacker sits between the victim and the bank/O365, forwarding credentials and the second factor (TOTP codes, SMS, etc.) immediately. Since there isn't a specific CVE for the service itself—this is an abuse of protocol architecture—we have to rely on behavioral analysis.
I've been looking at how to detect the initial proxy hop versus direct access. One indicator is the TLS fingerprint. Reverse proxy tools often use custom TLS stacks (like Go's standard library) that produce distinct JA3/JA4 signatures compared to standard browsers.
Here is a basic KQL query to help spot potential AitM attempts by correlating high-risk sign-ins with unusual TLS fingerprints or fast user-agent switches:
SigninLogs
| where Result == "success"
| where ConditionalAccessStatus == "failure" or RiskLevelDuringSignIn == "high"
| extend DeviceDetail = parse_(DeviceDetail)
| project Timestamp, UserPrincipalName, AppDisplayName,
DeviceDetail.browser, DeviceDetail.os,
RiskDetail, AuthenticationRequirement
| join kind=inner (
AADSignInRiskEvents
| project RiskEventTime, RiskEventType, RiskState
) on $left.UserPrincipalName == $right.UserPrincipalName
| where RiskEventType == "anomalousLocation" or RiskEventType contains "tokenIssuance"
| summarize Count=count() by UserPrincipalName, RiskEventType, bin(Timestamp, 1h)
We are pushing for FIDO2/WebAuthn hardware keys across the board since they bind the session to the specific origin, rendering the relay useless. However, legacy support is a real blocker.
How are you all handling the detection gap for AitM attacks when you still have users on SMS/VOICE MFA? Are you relying purely on device compliance or looking at network telemetry?
We've seen a similar rise in reverse proxy attacks using Evilginx2 templates. The JA3 fingerprinting route is solid, but we've found a lot of false positives with mobile browsers.
We shifted focus to 'impossible travel' combined with device compliance. If a user logs in from a compliant device in the US, and 5 minutes later from a new device in a high-risk region (even with correct creds/MFA), we trigger a hard block.
Also, enabling 'Number Matching' in MS Authenticator has helped stop some automated relays, though it doesn't fix the core proxy issue.
From a Red Team perspective, these services are scary effective because the URL looks legitimate (typosquatting the main domain or using a lookalike, e.g., account-security-verify.com). The victim enters creds, the tool hits the real API, returns the 2FA prompt, victim enters code, tool logs them in.
Detection-wise, check the referrer headers if you have access to the web server logs. You might see the phishing site as the referrer before the redirect. Just be careful not to rely on it entirely—proxies can strip headers.
We started implementing Conditional Access policies that require trusted locations or compliant devices for sensitive admin actions. If you aren't on a domain-joined machine or managed mobile device, you don't get access to the console, period.
It's a heavy-handed approach, but it mitigates the risk of credentials+MFA being phished from a personal device. We also use a script to audit for legacy authentication protocols which PhaaS often tries to exploit:
Get-MsolUser -All | Where-Object {$_.StrongAuthenticationRequirements.Count -eq 0 -and $_.LastPasswordChangeTimestamp -lt (Get-Date).AddDays(-90)} | Select-Object UserPrincipalName
Building on Rachel’s point, try monitoring server-side JA3S fingerprints. Since Starkiller terminates the connection, its TLS handshake often differs from the legitimate infrastructure. We track known proxy fingerprints—often Go-based—to flag AitM attempts. You can use Zeek to spot these deviations:
zeek event ssl_established(c: connection) { if (c$ssl$server_hello$ja3s in //) { print fmt("Potential AitM detected: %s", c$id$orig_h); } }
This complements Conditional Access by catching the transport layer deception early.
While technical detection like JA3S is vital, the ultimate control against AitM is phishing-resistant MFA. FIDO2/WebAuthn keys bind the authentication to the specific domain, effectively negating the relay capability. We’ve made it a mandate for all privileged access management (PAM) workflows. It not only stops Starkiller but also aligns perfectly with regulatory frameworks requiring stronger authentication assurances. Has anyone successfully enforced hardware keys for Tier 0 users without significant pushback?
Verified Access Required
To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.
Request Access