VoIP · Chapter 14
The call factory
Comes from chapter 9 · The one who wanted me to pay for their calls
In chapter 9 someone tried to make my phone switch pay for their calls. I wrote it up and closed the incident, with one question left hanging: who was on the other end? This time I didn't just watch through the window. I gave the decoy a memory, followed the number's trail, and found out why they pick exactly those numbers.
Chapter 9 was a photograph: two hours, a handful of machines trying to make my decoy switch place calls to revenue-share numbers. Fraud caught live, told exactly as it arrived. But a photograph doesn't tell you who's behind the camera.
A week later the photograph had turned into a film: the same campaign kept hitting, harder, every single day. So this time I did something different. I stopped looking at each attack on its own and set out to map the operation — its shifts, its moving parts, where the money flows and, above all, why it does things the way it does.
01First, a memory
The decoy, the way I have it set up, has a problem for any long investigation: it forgets. My VPS isn't swimming in disk space, so I let events live for about a week and then be deleted; otherwise the disk fills up. A campaign that runs for months doesn't fit into seven days. So the first job was to build it a separate memory — a database that keeps every attempt, forever: who called, what number, with which tool, and when.
ingest → dedup by event_uuid (idempotent)
total events : 71,467
distinct IPs : 154
number cores : 904
window : 22 Aug → 28 Aug(That "core" is my normalised form of the destination number: I strip the dialling prefixes —00, 011, 900…— the attacker tries in front of it, to group all the variants that end at the same phone. The same destination shows up dialled a hundred different ways; the core is the real one.) seen
With this, every week I can add a fresh photograph without losing the earlier ones. It isn't an incident: it's a stakeout. And with six days of data already loaded, I started pulling the thread.
02The assembly line
The first thing the graph of who dials which number shows is that this isn't a clumsy swarm flailing about. It's a factory, with job stations.
172.110.223.207 → 14,265 REGISTER // enumerator: probes extensions
172.110.223.49 → 16,560 INVITE to 1 number // pumper: one target
149.50.107.48 → 1,752 INVITE to 1 number
149.50.107.53 → ~1,600 INVITE to 1 numberSome machines only do REGISTER: they probe extensions blindly —the internal lines of a phone switch, 200, 201…— looking for an open door (one with no password). Others only do INVITE: once there's a door, they pump calls. And here's the detail that gives away the industry: one number, one node. The pumper 172.110.223.49 dialled the same number more than sixteen thousand five hundred times. And it's not just an impression: of the machines that pump, grouping their destinations by normalised core, 64% attack a single destination, 85% one or two. That isn't chance — it's a production line, with every worker at their station. Even inside the same provider (ReliableSite, with the IPs geolocated in Hong Kong) an enumerator and a pumper live side by side: division of labour under one roof. seen
And there's another layer, one you don't see by looking at who calls what, but by measuring when. I timed each machine's pulse —the gap between one call and the next— and a pattern showed up that I wasn't expecting:
149.50.107.43 one call every 133 s regularity 0.98
149.50.107.47 one call every 114 s regularity 0.97
149.50.107.48 one call every 106 s regularity 0.99
149.50.107.49 one call every 118 s regularity 0.99
149.50.107.53 one call every 111 s regularity 0.99That's five machines from the same subnet —near-consecutive addresses at one Polish provider— and each fires a call roughly every two minutes, like a metronome: almost all of their intervals are identical (that regularity ~0.98, on a scale from 0 to 1 where 1 would be a perfectly periodic cadence). seen They don't dial when they feel like it; they follow a clock. Five clocks on the same shelf, all keeping the same time. Five patterns like that are hard to explain as anything independent: they look like a single piece of automation —a rented subnet running the same script.
And the same beat turns up on machines at other providers. At PebbleHost, one ticks every 53 seconds; at LeaseWeb —different company, different network— another ticks every 57, both just as metronomic (regularity 0.98). The same kind of clock in different rented houses. seen
I can't prove it's the same operator — I don't have their invoice or their name. But you tell me: how else do you explain machines on networks and providers that have nothing to do with each other each ticking with such an exact clock, and in such similar time? It doesn't look like a swarm of unconnected attackers: it looks more like a single hand winding up clocks in different houses. The factory doesn't just divide the work: it looks like it has a foreman keeping the beat. deduced
03The number has an owner
The destination numbers looked like they came out of a hat: London, York, Ontario, Milan, Bratislava… But they aren't anonymous. Numbering is allocated in blocks to carriers, and in many countries —the United Kingdom among them— that register is public: the regulators publish it themselves. You just have to go and look.
I downloaded the official British numbering list (Ofcom's codelist) and looked up who each block belongs to. The same name came back again and again:
020 3769 → DIDWW Ireland Limited
01904 911 → DIDWW Ireland Limited
01668 509 → DIDWW Ireland Limited
028 4024 → DIDWW Ireland Limited
… → DIDWW (6 of 6 UK blocks)DIDWW in all six British blocks. seen And across the Atlantic, three more names — Fibernetics, Onvoy/Inteliquent, Iristel. All of them the same class of company: numbering wholesalers, providers that resell phone numbers in bulk.
This does not mean DIDWW is behind the fraud. It means something more specific: that the numbers used by the campaign come from blocks whose regulatory allocation leads repeatedly back to the same wholesaler. Between the holder of the resource and whoever is using it there's a chain of intermediaries I haven't reconstructed yet.
And there's the mechanics of modern fraud, laid bare: it doesn't need to invent numbers; it works with real numbering. The known model is a resale chain —wholesaler → intermediary → end user— and, at the far end, the fraudster uses it to get paid for every call they manage to pump. read And one detail jumps out: they show up in clusters — 020 3996 ·70 ·74 ·96, three numbers from the same block. Used within the same campaign, they hardly look like a completely random selection. It's consistent with them coming from a batch allocated or sold together. I can't see the contract behind it, but it would be worth a look.
And the register says something else: these blocks aren't from yesterday. DIDWW has held them since 2014, 2016, 2019 and 2022 — none of them appears among the last year's new allocations. seen This isn't numbering freshly minted for the scam: it's a wholesaler's legitimate, well-aged inventory. When it jumped from there into the campaign, and through how many hands, no public register will tell you.
04Why these numbers, exactly?
Here's the question that kept nagging at me. Textbook IRSF calls exotic, expensive destinations — Pacific islands, satellite, ultra-high-tariff lines. But my attackers were dialling… York. Milan. A landline in Ontario. Western numbering, boring, cheap. Why give up the number that pays best?
The answer turns the intuition on its head. One half the anti-fraud industry documents —fraud no longer needs expensive numbers—; the other, the why, is mine: they pick them for stealth. deduced
And that explains my entire sample. They didn't pick York at random or out of clumsiness: they picked it because it looks legitimate. A York landline receiving calls doesn't trip any "risky destination" alarm; a Tuvalu number does. The sophistication isn't in the attack — it's in the camouflage. They choose the number that draws the least attention, so the till keeps ringing long after the noisy neighbour's has been switched off.
The GSMA confirms the first half of the intuition: today's IRSF no longer needs obviously fraudulent numbers — in 2023, 90.99% of the attacks in their sample went against valid numbering (and it isn't a recent fashion: back in 2020 it was already about the same, 91.13%). read What my data suggests is the next step, and this one is my own hypothesis: that among those valid destinations, the fraudster is hunting precisely for the ones that raise the fewest suspicions.
And the stealth shows up even in the rhythm. Measuring how long each number survives in my decoy, two tempos appear: the ones that last for days get pumped on a slow burn —around 40 calls an hour— and the ones that burn out within hours get milked hard —up to 170 an hour— until somebody cuts them off. The same logic, now in the cadence of the calls themselves: the one that goes slow, lasts. seen
05The factory runs on free tools
With the memory full, I could finally count what they hit with. And I expected to find some private kit, something custom-built. What's there is the opposite: public utilities anyone can download.
generic "VOIP" dialer 31,717 // 44%
SIPPTS (pplsip, by Pepelux) 17,713 // 25% · SIP auditing in Python
rotated carrier UAs 6,656 // 9% · fake Cisco/Avaya/AT&T…
SIPVicious (friendly-scanner) 94 // the 2007 classicClose to 80% of the traffic arrives wearing a non-malicious label —a generic dialer, an auditing tool, or a carrier's name— rather than as custom malware. seen But you have to be careful here, because that label gets faked — in fact, 9% are fake carrier User-Agents. That said: faking a scanner's name gains you nothing —it only gives you away and gets you blocked—, so when pplsip or friendly-scanner shows up, the most reasonable reading is that they're what they announce: SIPPTS (a SIP auditing suite, incidentally written by a Spanish researcher) and SIPVicious with its default configuration. With a name, and with reasonable confidence, that's what I can point at: SIPPTS, a quarter of everything. The 44% that announces itself as plain "VOIP" and the 9% that's faked aren't tools I can name. Confirming what's actually running takes looking at behaviour, not the label — another thread to pull. But the wider picture doesn't change: you don't need malware to explain this. Nothing to open in Ghidra; the whole operation is assembled from what a security student uses in class.
And there's the contrast that defines this story: the money side is remarkably sophisticated —numbering wholesalers, resale chains, the stealth strategy— and the attack side is bargain-basement. The clever part isn't the hacking; it's the plumbing. Whoever runs this isn't a coding genius: they're a manager who has understood the plumbing of the world's phone system and opens the tap with free tools.
06Whose machines are these
And the machines doing the dirty work? For the operating system I don't trust a single clue. I use the initial TTL of the packets they sent me —the value they left with, discounting the network hops along the way— plus a scan of the services and their versions. With that, the fleet points to a mix: around 24 Windows, around 13 Linux. That third of Linux tells a story. seen
They're old, unattended VPSs — an OpenSSH from years ago, unpatched, listening on the usual port. You don't need an exotic exploit to explain them: the simplest hypothesis is compromise via weak or reused SSH credentials, but I can't rule out other ways in. What I have lets me call a machine probably compromised, but not yet reconstruct how they got in. They're victims: somebody's servers, and that somebody has no idea their machine has spent days calling York in the small hours.
And the two that pump the most are hiding a second trade. They have thousands of open ports — 2,606 on one at ReliableSite, 708 on one at OVH. seen That isn't a phone switch: it fits a proxy exit node —a datacentre server that would resell its connection so other people's traffic can leave through it—, though the open ports, on their own, don't prove it. (I'm not calling it proxyjacking: that term is for other people's machines being hijacked, and these look like infrastructure rented or set up on purpose for that role.) The same machine that pumps fraudulent calls appears to be running that second function at the same time. One server, two dirty businesses stacked on top of each other. You pull one thread and three appear.
07Indicators (IOCs)
For anyone who wants the detail, the campaign's technical dossier — what anybody trying to recognise or cut it off would write down:
| Type | Value |
|---|---|
| Family | SIP toll fraud · traffic pumping (campaign) |
| Pumper #1 + proxy | 172.110.223.49 · ReliableSite (HK exit) · SIPPTS · 2,606 ports |
| Enumerator (REGISTER) | 172.110.223.207 · ReliableSite · Linux/nginx |
| Pumper + proxy | 51.75.106.116 · OVH · 708 ports · Scamalytics High Risk read |
| Pumper subnet | 149.50.107.0/24 · MEVSPACE (Poland) · 5 metronomic IPs (.43 .47 .48 .49 .53) · cadence ~106–133s · regularity ~0.98 |
| Timing signature (twins) | same kind of clock at different providers: PebbleHost 194.213.3.117 (~53s) ~ LeaseWeb 203.23.128.196 (~57s) · both regularity 0.98 |
| Tools (public) | SIPPTS (UA pplsip, 25%) · VOIP dialer (44%) · spoofed carrier UAs (9%) · SIPVicious (friendly-scanner, 0.1%) |
| Attack signature | dialling-prefix fuzzing (00/011/+/810/900…) over a normalised destination; one node per number |
| Victim recruitment | Windows/Linux mix · on the old Linux ones, probable SSH compromise |
| Wholesalers of the destinations | DIDWW Ireland (×6 UK) · Fibernetics · Onvoy/Inteliquent · Iristel |
| Destinations (DO NOT CALL) | legitimate low-risk geographic/mobile numbering · chosen for stealth · several numbers from the same block = probable batch |
08What this reveals
Who was on the other end? I still don't have a name —and I don't want one: that goal isn't mine to chase— but I do have a portrait: not a hooded coding genius, but somebody running a factory; "workers" that are in good part other people's compromised machines; and a till that, at the very end of it all, hangs off one very specific numbering wholesaler. That's what six days of memory show:
- The numbers aren't random: they have an owner, and the owner is in a public register. Tracing numbering is every bit as "OSINT" as tracing an IP — it's just that almost nobody looks there.
- They pick the number that draws the least attention, not the one that pays the most. The sophistication of the fraud isn't in the blow, it's in the camouflage: clean Western numbering that survives for weeks because nobody is watching it.
- The factory runs on free tools. Almost 80% of the traffic presents itself with non-malicious labels —dialer, auditing, carrier— rather than custom malware; and only 25% (SIPPTS) is an auditing utility I can name with confidence. The expensive, clever part is the money plumbing, not the code.
- The same rented infrastructure seems to serve several frauds at once. The nodes pumping calls look like they double as proxy exits. You pull one thread and three appear.
- It isn't a swarm, it's an orchestra. An entire subnet beats in the same time, and the pattern repeats at other providers. I can't prove it's a single hand — but the pattern suggests that behind those 154 IPs there are, probably, far fewer operations than it looks.
- The cut-off point isn't the machine, it's the number. You can take down a hundred VPSs and they'll rent a hundred more. But the number hangs off a specific wholesaler, and that wholesaler can suspend the reseller. That's where it hurts.
To be continued — the tracking machine is still running. This is photo 1 of N: in a few weeks I'll know who persists, which numbers have burned out and which are still cashing in. It wasn't an incident. It's a stakeout. 🍯
Comments