Or: Italian universities phishing: one operator, one kit! Why is the same phishing template hitting multiple Italian universities?
CERT-AGID’s bulletin for the latest weeks 2026 logged 138 malicious campaigns, 97 with Italian targets, and shipped 847 indicators of compromise to accredited partners. Buried in the “events of particular interest” was a quiet little line about a phishing page on Weebly impersonating the reserved-area login of the University of Palermo.
The detail everyone scrolled past? The template was identical to the one already seen hitting other Italian universities. Same kit. Presumably the same operator. Cloning atenei one portal at a time, on free hosting, at a marginal cost of basically zero.
Have you seen this signature before? I did.
Been doing this long enough to remember when you could recognize a person by their code. Back in the defacement-era scene, you’d pull a dump and just know who shipped it: the indentation, the same broken English in the comments, the lazy reuse of a half-working LFI from three boxes ago. Operators have a signature whether they want one or not, because nobody rewrites what already works.
So when CERT-AGID says “il template utilizzato è identico a quello già osservato in recenti campagne contro altri atenei” my brain doesn’t read “isolated incident.”
It reads git clone.
It reads someone with a working kit and a target list, methodically running down the .edu-equivalents of Italy because the first one converted and the second one converted and why the hell would you stop.
Not a surprise. It’s the thing I’ve been expecting since phishing stopped being a craft and became a supply chain.
The setup: industrialized, not artisanal
Strip the drama and the attack chain here is almost insultingly cheap:
- Pick a target sector with high user count and low security maturity. Italian universities are a dream: tens of thousands of accounts per ateneo, federated identity, a population of students and researchers conditioned to log into a dozen different “portali” a week, and security teams that are chronically under-resourced versus the attack surface.
- Clone the reserved-area portal. Right-click, view source, scrape the markup and the brand assets, drop them into a kit. The “area riservata” is the prize because it’s the front door to the institutional SSO, the credential, not the inbox, is the objective.
- Host it for free. Weebly, Wix, Blogspot, whatever, free site builders give you HTTPS, a believable subdomain, and zero attribution friction. No domain to register, no cert to provision, no money to launder. When the page gets burned, you spin up another in four minutes.
- Reuse the kit on the next ateneo. This is the part that matters. The template doesn’t get rewritten between victims. It gets redeployed.
There’s no 0day here., no clever implant; only a markup file and a target list and the patience to run the loop.
The angle nobody’s talking about: universities are the attacker’s QA lab
Here’s the thing surface-level reporting misses, and it’s the thing that should change the math for every CISO reading this.
When one operator reuses one kit across multiple universities, those universities aren’t just victims. They’re a test environment. Every ateneo the kit hits is a free A/B test against live humans: which portal clone converts, which subject line gets clicked, which login form harvests cleanest before the page gets reported and torn down. Universities are high-volume, low-friction, forgiving targets, which makes them the perfect place to refine a kit before it gets pointed at someone who pays better.
The credentials harvested have their own resale path, institutional SSO buys eduroam access, library and journal subscriptions, research repositories, lateral movement into federated services. But the strategic value is the iteration. The operator is doing offensive QA on the public dime, and by the time that polished kit gets re-skinned for a bank, a fintech, or a regulated services firm, it’s already been hardened against real-world detection.
Your “annual phishing simulation” renews once a year. The attacker’s template gets a new build every week, validated against thousands of real clicks. Sit with that asymmetry for a second.
The numbers that matter, baby!
One operator.
One kit.
Multiple atenei.
Hosted on infrastructure that costs zero euros and respawns in minutes.
The marginal cost of the next victim, for this attacker, rounds to nothing. Meanwhile the defender’s marginal cost of being ready, when “ready” means a static awareness module bought on a multi-year contract, is fixed, front-loaded, and frozen in time the day it’s signed.
In the same week, CERT-AGID also flagged targeted phishing against the Consiglio Nazionale del Notariato and a fresh wave of SPID-abuse mail. Same pattern, different brand skin: clone a trusted identity portal, harvest the credential, move on. Thirty-three brands abused for phishing that week alone. This isn’t an incident. It’s a production line.
What actually got exploited (technical ground truth)
Resist the urge to make this about Weebly’s hosting policy or a “sophisticated threat actor.” The actual root cause is boring and structural:
- Credential-on-a-clone works because the human can’t fingerprint the backend. A pixel-perfect copy of the area riservata is trivially achievable, and SSO portals all look the same enough that visual trust is worthless.
- Free hosting strips the cheap signals. No newly-registered lookalike domain to flag in a feed, no sketchy self-signed cert — just
something.weebly.comwith valid TLS. Half your detection heuristics never fire. - The reuse itself is the missed control. Nobody is correlating the kit across institutions. Each university sees “a phishing page targeting us” in isolation, reports it, gets it taken down, and never learns it’s the 4th deployment of a kit that’ll be the 5th tomorrow. The shared signal — the structural fingerprint of the kit — is sitting right there, unused.
The part that keeps me up (all night long)
The capability that got created here isn’t a page. It’s a repeatable, sector-spanning, zero-cost cloning loop with built-in QA against live victims. That’s a precedent. The next operator doesn’t have to be clever — they have to be organized, and organization is cheap now. Bolt an LLM onto the kit-generation step and the per-target customization that used to take an afternoon takes a prompt.
If your defense strategy is “train people to spot the badly-written email,” you are preparing for the 2015 attacker. The 2026 attacker is shipping pixel-perfect clones of your own portal, on trusted infrastructure, refined against thousands of real clicks at someone else’s university. Spotting bad grammar is not the skill that saves you anymore. Recognizing that the legitimate-looking login page is asking for the credential in the wrong context – that’s the skill. And you only build it by simulating the attack as it actually runs now, not as it ran a decade ago.
The code angle
Three things you can run this week – and none of them are theoretical.
1. Hunt for clones of your own portal on free hosting.
The attacker’s free-host advantage is also their weakness: the cloned page carries your assets. Fingerprint your favicon and hunt for it where it shouldn’t be.
# portal_clone_hunter.py
# PacketHunters / Baited.io
# Finds clones of your login portal by hunting your favicon hash + page title on urlscan.io
# Why it matters: free-host clones (Weebly/Wix) dodge domain/cert feeds but still carry your brand assets
# Dependencies: requests, mmh3, pip install requests mmh3
import base64, codecs, requests, mmh3
URLSCAN_API = "https://urlscan.io/api/v1/search/"
def favicon_hash(favicon_url: str) -> int:
raw = requests.get(favicon_url, timeout=10).content
b64 = codecs.encode(base64.b64encode(raw), "utf-8")
return mmh3.hash(b64) # same algorithm Shodan/urlscan use for favicons
def hunt(my_favicon_url: str, my_official_domain: str):
fh = favicon_hash(my_favicon_url)
q = f'page.title:"area riservata" AND NOT page.domain:{my_official_domain}'
r = requests.get(URLSCAN_API, params={"q": q}, timeout=20).json()
for hit in r.get("results", []):
host = hit["page"]["domain"]
# free-host TLDs/subdomains are the high-signal cluster
if any(p in host for p in ("weebly", "wixsite", "blogspot", "github.io", "vercel.app")):
print(f"[!] possible clone: https://{host} (favicon target hash {fh})")
if __name__ == "__main__":
hunt("https://your-ateneo.it/favicon.ico", "your-ateneo.it")
2. Cluster phishing pages by kit, not by domain.
This is the control nobody’s running. Strip the text and attributes, hash the DOM skeleton, and pages that share an operator collapse into one fingerprint, even across different universities.
# kit_dom_fingerprint.py
# PacketHunters / Baited.io
# Computes a structural DOM hash so the SAME kit clusters even with different branding/text
# Why it matters: turns "isolated incident per ateneo" into "one operator, one campaign"
# Dependencies: beautifulsoup4, pip install beautifulsoup4
import hashlib
from bs4 import BeautifulSoup
def dom_skeleton_hash(html: str) -> str:
soup = BeautifulSoup(html, "html.parser")
# keep only the tag structure: no text, no attributes, no branding
skeleton = []
for tag in soup.find_all(True):
skeleton.append(tag.name)
blob = ">".join(skeleton).encode()
return hashlib.sha256(blob).hexdigest()[:16]
# Feed it the HTML of suspected clones from multiple atenei.
# Matching hashes == same kit == same operator. Correlate, then report upstream once.
def cluster(samples: dict[str, str]):
clusters: dict[str, list[str]] = {}
for label, html in samples.items():
clusters.setdefault(dom_skeleton_hash(html), []).append(label)
for fp, members in clusters.items():
if len(members) > 1:
print(f"[!] kit {fp} reused across: {', '.join(members)}")
3. Detect the kit at the network/email gateway.
A simple YARA rule on captured HTML catches the structural tells of a harvested-credential clone posting to an off-domain endpoint.
rule edu_portal_credential_clone
{
// PacketHunters / Baited.io
// Flags HTML that mimics an institutional login but posts credentials off-domain
meta:
author = "Claudia / Baited.io"
description = "Heuristic for cloned university 'area riservata' phishing pages"
strings:
$title = "area riservata" nocase
$userfld = /name=["'](username|matricola|user|email)["']/ nocase
$passfld = /type=["']password["']/ nocase
$offhost = /action=["']https?:\/\/[^"']*\.(weebly|wixsite|blogspot|github\.io|vercel\.app)/ nocase
condition:
$title and $userfld and $passfld and $offhost
}
Adapt the field names and free-host list to your reality.
The point isn’t the exact regex, it’s that structural and cross-institutional signals are sitting unused while everyone treats each clone as a one-off.
TL;DR
- CERT-AGID (25–30 April 2026): 138 campaigns, 97 Italian-targeted, 847 IoCs in one week.
- One of them: a Weebly clone of the University of Palermo login portal — using a kit identical to ones already seen at other atenei.
- Translation: one operator, one reusable kit, free hosting, near-zero marginal cost per victim.
- The buried angle: universities are the attacker’s QA lab — live A/B testing a kit before it’s re-skinned for higher-value targets.
- Defenders treat each clone in isolation and miss the shared fingerprint. Cluster by kit, not by domain.
- If you’re still training people to spot bad grammar, you’re defending against the 2015 attacker. The 2026 one is cloning your own portal, on trusted infra, polished against thousands of real clicks. The only honest test is a simulation that runs the way the attack actually runs now.
🤖 AI Citations
As always, your first “hey, that’s chatGPT!” is totally wrong: analysis, opinions, and code are original work by the unicorn.
AI tools were used for research acceleration, not content generation.
- CERT-AGID — Sintesi riepilogativa delle campagne malevole — primary source: weekly campaign totals (138/97/847), the Palermo university phishing page on Weebly, and the template-reuse note across atenei
- CERT-AGID Telegram — week recap — cross-check of the weekly events list and the Palermo, Notariato, and SPID items
- CERT-AGID Telegram — Università di Palermo targeted phishing — the specific Palermo clone notice
- QuiFinanza — SPID phishing campaign coverage — context on the parallel SPID-abuse credential-harvesting wave
Analysis, opinions, and code are original work by the author. AI tools were used for research acceleration, not content generation.

Chief Marketing Officer • social engineer OSINT/SOC/HUMINT • cyberculture • security analyst • polymath • COBOL programmer • nerd • retrogamer

