nox.sh

Matt's ramblings

For about five weeks, my UDM Pro kept generating the same alert from one iPhone on my network:

ET SCAN Potential SSH Scan OUTBOUND
source:      [iPhone on local VLAN]
destination: [redacted cloud host]:22/tcp

I had 140 of these. No other device on the network generated one.

My setup is nothing unusual: a UDM Pro at the edge, with Pi-hole and Unbound handling DNS.

I took the alert name literally. One phone appeared to be opening SSH connections to cloud servers around the world, sometimes at 3am. I checked for unknown profiles, certificates, VPNs and linked devices. I found nothing and got close to recommending a wipe.

A controlled packet capture eventually tied the traffic to opening WhatsApp.

What the IDS actually recorded

Source one iPhone
Observation window about five weeks
Alerts 140
Other devices with the same alert 0
Total traffic involved under 1 MB

The destinations were ordinary rented servers spread across several cloud providers. Most connection attempts failed. A few completed enough of a handshake to confirm that this was real traffic and not a reporting bug.

Before doing anything else, I should have read the rule:

flow:to_server; flags:S,12;
threshold: type threshold, track by_src, count 5, seconds 120;

It fires after five matching SYNs from one source within two minutes. So an alert is a threshold crossing, not a record of one connection. I had been treating the IDS output as a complete connection log when it was only showing me the events that crossed the threshold.

Port 22 was misleading too. The packet capture later showed the same behavior across several ports. Port 22 stood out because this particular rule watches it.

Where I wasted time

The phone queried a domain under .invalid, a suffix that is guaranteed not to resolve. That looked like a DNS-integrity probe: ask for something that cannot exist and see whether the resolver lies. I thought it was important until I searched the other devices and found the same probe on two more Apple devices, including my own phone. It was normal OS behavior. I had only searched the logs of the phone I already suspected.

I also calculated that 83% of the destinations appeared only once and started building a theory around a constantly changing server fleet. That number came from the sampled IDS alerts, not from all the traffic, so the calculation did not mean what I thought it meant.

The timestamps sent me in another bad direction. Alerts appeared at almost every hour of the day, which made persistent background networking seem likely. I left the phone idle for ten minutes and got no traffic at all. The owner simply uses the phone at odd hours.

There was also a burst of strange-looking hostnames around some alerts. What looked like a signature turned out to be my DNS server logging each step in an ordinary CNAME chain as a separate row.

Testing the apps

I finally stopped reading old logs and ran a passive capture on the phone’s VLAN. I didn’t send traffic to the phone or interfere with any connections.

PHONE_IP=192.0.2.10   # replace with the device IP
CAPTURE_IF=br0        # replace with the VLAN interface

sudo tcpdump -ni "$CAPTURE_IF" -s 96 \
  "host $PHONE_IP" -w iphone-test.pcap

The short snap length limits how much application payload is stored while keeping the packet headers the analysis needs. It is not a guarantee of metadata only, since 96 bytes can still include the start of a payload. Captures can hold sensitive data either way, so I ran it only during the controlled tests and deleted it afterwards.

I tested one condition at a time:

Test Result
Phone idle and untouched, ten minutes no connections
Telegram force-quit and relaunched no connections
Safari force-quit and relaunched no connections
WhatsApp force-quit and relaunched immediate burst, three launches in a row

That was the useful result. The phone was quiet while idle, the two unrelated apps were quiet, and WhatsApp produced the burst three times out of three.

The capture also showed the normal Meta connection succeeding while the alternate connections were still in flight, and the alternates being abandoned together shortly after.

What the capture showed

Each test launch produced two groups of connections:

WhatsApp launches
├── normal connection to Meta ─── succeeds
└── 10 to 24 other connections ───── abandoned together

The other connections went to rented servers across several cloud providers. They presented as ordinary remote-access sessions, but not consistently, and they were attempted across multiple ports. Once the normal Meta connection succeeded, the other connections were dropped nearly together.

This looks like a connection race: try the normal route and a set of possible alternate routes in parallel, then keep whichever works. On this network the normal route works, so the alternate attempts lose every time I tested it. The IDS had been reporting part of those failed attempts.

Calling those servers circumvention relays is still an inference. I could observe the timing and connection behavior, but I could not see inside the encrypted portion of the sessions.

Why the Russian number matters

In February 2026 Russia moved to fully block WhatsApp, reportedly removing its domains from the national DNS. WhatsApp had more than 100 million users in Russia at the time. Weeks later it began showing Russian users instructions for connecting through a VPN or proxy.

The WhatsApp account on this phone is registered to a Russian number. The phone itself is in the US on a residential connection where WhatsApp is not blocked.

My theory is that the account region enables some kind of ready-to-use circumvention path. The timing, server pattern and parallel connection race all fit. I didn’t test the same procedure with an actively used non-Russian account, so I can’t show that the phone number is the trigger.

WhatsApp documents a user-configured proxy for people who cannot connect directly. This didn’t look like that feature. No proxy was configured on the phone, and the alternate connections ran even while the normal connection was succeeding.

What is observed, and what is inferred

Claim Status
Launching WhatsApp triggers the burst observed, three controlled launches
Normal and alternate connections overlap observed in the capture
The alternate connections are for censorship circumvention strong inference
A Russian phone number enables the behavior my theory, untested
Meta wrote the component unknown
The phone is compromised or exfiltrating data no evidence found

The feature could be universal, tied to some other account property, or supplied by a third-party component inside the app. The traffic alone can’t answer that.

What I did with the result

I checked certificate trust, device-management profiles, enterprise trust, VPN and messaging proxy settings, and linked accounts. I found nothing unexpected.

I didn’t find evidence of compromise or data theft. The traffic volume was tiny, the device checks were clean, and the behavior occurred when one specific app was launched rather than while the phone sat idle. Because the session contents were encrypted, that is not proof that nothing left the phone. “No evidence of compromise” is as far as I can go.

I didn’t wipe the phone. I also wouldn’t block outbound port 22 just to stop the alert. The same behavior used other ports, so that would hide one symptom without stopping it.

The part I still don’t like

I understand why a circumvention feature would work this way. If the normal path is being censored, alternate routes need to be hard to identify and ready before the user has to troubleshoot anything.

I don’t love an app contacting a large set of unrelated-looking servers, on infrastructure its developer doesn’t own, without any notice or visible control. It may be useful for people behind censorship. From a normal home network it looks awful.

Packet inspection did not prove that the traffic was benign. What changed my assessment was the controlled test: an idle baseline, two unrelated apps that produced nothing, and WhatsApp reproducing the behavior three times.

My order next time:

  1. Check what the detection rule actually measures.
  2. Look for the same behavior on every device, not just the suspect.
  3. Establish an idle baseline.
  4. Run one positive test and at least one negative control.
  5. Capture the traffic before building theories on sampled logs.

The IDS accurately reported traffic that matched its rule. My mistake was treating the name of that rule as an explanation of what the software was doing.


I removed the server addresses, probe domains, full port list and handshake fingerprints. Those details could be turned into a blocklist or detection signature. This makes the article harder to reproduce from the public evidence, but I think that tradeoff is worth it.