Most of what we know about the interval between credential theft and credential use is inferred. A stealer log shows up on a marketplace; a login shows up in an auth log weeks later; someone draws a line between them. The 48-hour infection-to-marketplace figure that circulates in vendor material is a reasonable estimate, but it is an estimate.

This is a measurement of a much smaller thing, done properly. I planted five synthetic credentials in a browser store on a VM at a known instant, detonated commodity infostealers against it, captured the exfiltration at the packet level, and stood up a listener that recorded any attempt to use those credentials. Both ends are protocol-confirmed from a single controlled endpoint. The link between them is a hash match, not an inference.

Two of the five credentials came back. The first return arrived 1 day, 13 hours, 55 minutes after plant, and 1 hour, 25 minutes after the closest confirmed exfiltration of that exact credential.

The setup

A Windows 11 VirtualBox guest, hostname DESKTOP-5HOUFLT, user dhoffman, clock set to US Central. Capture via VirtualBox nictrace — no in-guest tooling, nothing for the malware to notice.

The browser credential store held roughly 35 fictional consumer credentials — the sort of accumulated junk a real profile carries — with five synthetic corporate credentials buried among them, all five pointing at stratatechindustries.com, a domain that exists only for this purpose:

HostUsernamePassword
sslvpn.stratatechindustries.comDESKTOP-5HOUFLT\dhoffmanawoke#rehire3
auth.stratatechindustries.comadmin.dhoffman@stratatechindustries.comgLV!7dTmhAdSk0
admin-panel.stratatechindustries.comadmin.dhoffmanMonotypeLilly2019
myportal.stratatechindustries.comdhoffmanBottom2017?
rdp.stratatechindustries.comAdministratorrehire_exquisite825

All five resolve. All five serve a generic corporate login page. All five were written in a single operation at 2026-07-30 15:39:22.217 UTC — the instant the clock starts.

These password values were generated during a fresh server standup and had never existed anywhere before that moment. That matters more than it sounds like it does: it means anything that later submits one of them necessarily obtained it from this endpoint, on or after that timestamp, and there is no second path to explain.

The VM was restored from the same snapshot before each detonation, so every run saw an identical machine and an identical credential set.

What left the box

Six detonations produced protocol-confirmed successful exfiltration. One of them — a Remus run on 2026-07-18 — predates the plant by twelve days and carried an earlier bait set; it is out of scope and excluded from everything below. Five are in scope.

The clean one exfiltrated over cleartext FTP; Claude puts it in the Agent Tesla / Snake family. No TLS, no encryption, nothing to defeat. It wrote an HTML password report and uploaded it to a dropbox on Namecheap-hosted infrastructure:

226 File successfully transferred

Twice. PW_dhoffman-DESKTOP-5HOUFLT_2026_07_31_23_09_00.html and a second at ..._23_09_14.html. The filename stamp is the guest clock — US Central — so 2026-08-01 04:09:00 UTC.

The FTP control channel was never upgraded to TLS, so the operator's own credentials crossed the wire in the clear alongside the stolen ones. The dropbox account is cloudbackupbigsuccess@piovau.com. The password was trivially weak, and I am not printing it — the account may still be live, and it has no bearing on anything measured here. The credentials have been reported to the host. That account name, an FTP dropbox on shared hosting, and Agent Tesla make a combination that Claude flags as having well-established provenance.

Inside the uploaded report, buried among the consumer junk, all five synthetic credentials in full plaintext.

The remaining four in-scope detonations were Remus, riding cleartext HTTP with a ChaCha20-encrypted payload. Remus appends the key and nonce to the payload as a cleartext trailer, which means the key is on the wire and the payload is readable by anyone capturing it:

HTTP/1.1 201 Created

Twenty-four of those across three runs to one endpoint, plus a separate run to a second. Claude did the decryption and extraction. Decrypted, the archives total 910,764 bytes and contain the bait set. One thing needs stating precisely here, because it is easy to state badly: the bait appears fragmented in Claude's extraction, with partial literals like auth.stratatechindust[ries] and my[port]al.stratatechindustries. That is an artifact of reading LZ77 back-references out of the decrypted stream at that layer. The operator's panel decompresses the archive properly and gets exactly what the FTP operator got. Remus did not deliver a degraded copy; Claude read it badly.

One further exfiltration event — a webhook stealer posting to a Cloudflare Worker over HTTPS — is excluded entirely. The connection is confirmed; the content is not observable. You cannot assert delivery of data through TLS you did not break.

What came back

The listener recorded four validation attempts, all on 2026-08-01, from three distinct source networks:

#Time (UTC)Credential submittedSourceNetwork
105:34:25.140admin.dhoffman147.90.227.68Consumer VPN exit, Frankfurt (DE)
205:37:04.992Administrator147.90.227.68Same exit
314:01:20.084admin.dhoffman185.161.209.45DeltaHost VPS (NL-announced)
421:23:30.421Administrator105.112.178.204Airtel Networks Limited (NG)

Every one carried a complete browser header set — Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User, Accept-Language, Priority, Referer, Origin, Upgrade-Insecure-Requests — with an identical user agent (Chrome/150.0.0.0 ... Edg/150.0.0.0) across all three IPs. No automation signals fired. This is what hands-on-keyboard validation in a real browser looks like. It is also what a well-built headless harness looks like, and I did not capture header ordering, so I will not claim more than "consistent with manual."

None of these addresses is mine or related to me.

The part that makes it a measurement

The listener hashes the submitted password before doing any lookup. Two distinct hashes produced records:

ba8e25d9701afac10255ca1dbe21f85618e9ce6a5edbf4d09297019a987aeb3c
27c605d8bbb8f593e6cc9cd484baef0118bd012463eef3133cda9c9d205b37d9

Those are unsalted SHA-256 hashes of MonotypeLilly2019 and rehire_exquisite825 — the plaintexts Claude recovered from the FTP upload. Run them yourself:

$ printf 'MonotypeLilly2019' | sha256sum
ba8e25d9701afac10255ca1dbe21f85618e9ce6a5edbf4d09297019a987aeb3c
$ printf 'rehire_exquisite825' | sha256sum
27c605d8bbb8f593e6cc9cd484baef0118bd012463eef3133cda9c9d205b37d9

The value observed leaving the endpoint over cleartext FTP is byte-identical to the value submitted against the login form. That link is arithmetic. It does not depend on anyone's interpretation.

The timeline

All times UTC.

2026-07-30 15:39:22   Five credentials planted
                      │
                      │   ← Remus runs (×3) somewhere in this span; capture
                      │     frames are epoch-zeroed, exact times unrecovered
                      │
2026-08-01 04:09:00   Agent Tesla FTP upload accepted (226) ─┐
2026-08-01 04:09:14   Second upload accepted (226)           │ 1h 25m 25s
                      Remus HTTP POST accepted (201),        │
                      same detonation window                 │
                      │                                      │
2026-08-01 05:34:25   admin.dhoffman validated  ← Frankfurt ─┘
2026-08-01 05:37:04   Administrator validated   ← Frankfurt
                      │  (2m 40s apart — one operator, both creds)
                      │
2026-08-01 14:01:20   admin.dhoffman validated again ← Netherlands VPS
                      │
2026-08-01 21:23:30   Administrator validated again  ← Nigerian mobile

The headline intervals, computed by Claude from the timestamps above:

  • Plant → first validation: 1 d 13 h 55 m 03 s
  • Nearest confirmed exfiltration → first validation: 1 h 25 m 25 s
  • Both credentials tried by the first operator: 2 m 40 s apart
  • Same credential, second network: 8 h 27 m later
  • Same credential, third network: 15 h 46 m later
  • Full validation span: 15 h 49 m 05 s

Three of five were never touched

sslvpn, auth, and myportal all resolve. All three serve the same login page as the two that were validated. All three left the endpoint in the same plaintext FTP upload, in the same table, adjacent rows. Nobody ever tried them.

This is not a rate-limiting artifact, and Claude ruled that out explicitly: the forwarder rate-limits at burst 5 per source IP, so the Frankfurt operator could have submitted all five back-to-back and every one would have been recorded. They submitted two, 2 minutes 40 seconds apart, and stopped.

The two they chose were admin.dhoffman against an admin panel and Administrator against RDP — the two most privileged-looking entries in the set. With n=5 that is not enough to build a theory of operator triage on. But the operator did not spray. They read the log, picked two, and tested those.

What this does not show

I would rather list these than have them listed for me.

No detonation-to-validation attribution. Five detonations carried the same five credentials off the same endpoint from the same plant. The hash proves which credential travelled. It cannot prove which exfiltration event delivered it to the person who used it. My own instinct is that most of the validation traffic traces back to the Remus logs — Remus is commodity malware-as-a-service, logs get redistributed to multiple buyers, and three separate networks validating the same credential inside 16 hours fits that model better than it fits a single FTP dropbox. Claude reads it the other way, pointing at the identical user agent across all three IPs as evidence of one operator rotating egress. The data does not settle it and I am not going to pretend otherwise.

The 1 h 25 m figure is a nearest-confirmed-observation, not a proven causal interval. The true theft-to-use interval, as Claude bounds it, sits somewhere between roughly 1.5 hours and 1 day 14 hours. The Remus runs whose timestamps I lost could have delivered the credential earlier — or later.

No sample hashes. Family identification here is Claude's, and rests entirely on network signature: transport, C2 behaviour, payload format, report structure. I collected samples opportunistically without knowing which would detonate at all, and the samples cannot be mapped to these runs after the fact. Treat the family attributions as behavioural, not as hash-confirmed.

Two source captures are gone. A same-named capture file overwrote an earlier one. Claude extracted the Agent Tesla and one Remus run while the original was live; neither can be re-verified. That lands hardest on the headline figure: the 04:09:00 UTC anchor for the 1 h 25 m interval is read off the Agent Tesla upload's filename, so the most quotable number in this post rests on a reconstructed capture. The theft-to-use link does not — those plaintexts come from my own plant table rather than from that file, so the hash match stands on its own. I have flagged those fields in my own working notes as reconstructed. If you want to be strict, the fully re-verifiable set is smaller than the set I have described.

Endpoint metadata in the listener database is wrong. The endpoint record carries a placeholder hostname and OS user left over from an earlier test rig; it does not name DESKTOP-5HOUFLT. It did not affect anything here, because every identification in this post runs through the credential hash rather than the endpoint record — but it is a real defect in the setup and I am not going to quietly omit it.

Volume is a floor. Access logging was only enabled partway through, and rate-limited requests are dropped at the forwarder with no record. I can tell you how many attempts became detections. I cannot tell you how many requests hit the listener.

One endpoint, one plant, one observation window. n=1 machine, n=5 credentials, n=4 events, and the listener is now down. This is an existence proof with clean instrumentation. It is not a study.

Why it is worth writing up anyway

The closest published work Claude surfaced is Agari's 2021 Anatomy of a Compromised Account, which seeded thousands of accounts into live phishing sites and found that most credential pairs were verified within hours. That measures the same interval, on the phishing side, at real scale.

What is different here is the theft half. In a phishing-kit study, the moment of compromise is the moment you hand the credential over — it is known by construction. With infostealer malware, the moment of compromise is normally the thing nobody can see. It happens on an endpoint, often against a machine that never generates an alert, and by the time the credential surfaces anywhere observable the window has closed.

Here both halves are observable at the protocol level from one controlled endpoint. The theft is a packet capture of a credential leaving a machine in readable form. The use is a server-side record of the same credential's hash arriving from operator infrastructure. The two are bound together by a value that existed nowhere else in the world.

An hour and twenty-five minutes is the interesting part. Not because it generalises — it does not, from one machine — but because it is a lower bound on how fast this can move, established by observation rather than estimate. Detection strategies built around finding stolen credentials on marketplaces are working on a timescale of days. The operator in this run was typing into a login form before most organisations would have finished triaging the alert, assuming an alert fired at all.

For the three credentials nobody touched: they are still out there, in a log, somewhere. They were stolen just as thoroughly as the other two.

Reproducibility

Plaintexts and hashes are published above deliberately. The credentials are synthetic, the domain is mine, and the listener is down. Anyone can verify the central claim of this post with sha256sum and thirty seconds.