Let’s get something straight: most “holiday breaches” don’t start during the holidays – we already covered last week.
They continue during the holidays.
We didn’t exploit a 0day.
We didn’t phish anyone on December 29th.
We didn’t bruteforce a login.
We reused an identity that was already trusted, and that’s the part everyone keeps missing.
The myth: “no one is logged in”
Security teams love to say this at year-end:
“oh yeah, we have time! Most users are offline anyway.”
That sentence is meaningless.
Humans log out, but identities don’t. And people still think it’s gonna be alright just because they work in the “non-critical” field – what’s that, anyway?
Here’s what was still active when we started poking around:
- long-lived OAuth refresh tokens
- service accounts with static credentials
- CI/CD runners authenticated via IAM roles
- scheduled jobs using API keys
- background automations syncing data every night
No alarms. No MFA. No new sessions.
Just… access.
Have you heard about that big Italian company suffering a huuuge vuln and Smelly told ’em last year?
That’s a similar case.
What we actually abused (realistic chain)
This is a realistic, boring, extremely common setup.
A service account was created for a “temporary” (temporary as in “three years ago”) integration in March.
It authenticated using OAuth client credentials.
Here’s the relevant flow (RFC 6749, section 4.4, if you actually read it):
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=svc_integration_42&
client_secret=REDACTED&
scope=read write admin
That token was:
- non-user bound
- not protected by MFA (because “it’s a service, hey!”)
- used by an automation job
- never rotated
- never monitored behaviorally
We didn’t need to “steal” it during holidays, we just found it in:
- a CI config
- checked into a private repo
- last updated 9 months ago
Game over, baby.
“But tokens expire, right?”
Sure. In theory.
And when the question was delivered I only got this in my mind.

In practice, this is what we found:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"refresh_token": "r1.long.lived.and.never.rotated",
"scope": "read write admin"
}
That refresh token had no effective expiration.
So every hour, like clockwork, the automation refreshed itself.
No login events.
No alerts.
No human interaction.
Just identity persistence.
Lemme say it again: PERSISTENCE.
Automation is the perfect camouflage
Then, we replayed the token from a different environment.
Same scopes, same API calls, same cadence, and from the logs, this looked exactly like the legitimate job.
Because it actually was, and detection systems that rely on authentication anomalies, unusual IPs (no one cared about to check) and “new device” signals (no one cared to check, again), were totally blind.
This is why “monitor logins” is a useless metric here. But… there was no login.
Want something worse? Cron+IAM
Here’s another pattern we see constantly: a Linux host running a scheduled task:
0 2 * * * /usr/bin/python3 sync_data.py
Inside sync_data.py:
import boto3
sts = boto3.client("sts")
creds = sts.assume_role(
RoleArn="arn:aws:iam::123456789012:role/data-sync",
RoleSessionName="nightly-sync"
)
That role had:
s3:*rds:ReadReplicalogs:Describe*
No MFA and no IP restriction and no session tagging and no anomaly detection.
Now, ask why we didn’t need AWS creds but needed the machine that already had them.
Was that hard?
C’mon, holiday week = nobody notices new access patterns at 02:00!
This is why year-end attacks feel “magical”..
If you’re in a security team, you’ll look for:
- phishing emails
- new logins
- malware
While attackers will look for:
- identities that never log out
- automation that never questions
- access that outlives context
Different mental models, for the very same outcome.
If your defense strategy is just taking care of expired tokens, “hey, it’s just a service account” or “dude, that job has always run”, you’re betting your breach timeline on inertia. Add these to your identity resilience routine:
- check and kill long-lived refresh tokens
- check and rotate service credentials aggressively
- check and bind machine identities to behavior, not just to scope
- continuously monitor what identities do, not how they authenticate
- treat automation as hostile until proven otherwise
Yes, it’s annoying.
So is incident response in January, YKWIM.
Remember, attackers just show up while no one is watching, and every identity will welcome them in, because it had been trained to trust forever.
It’s an identity design problem.

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

