What it costs to tell the truth about an infected site

Photo: Flazingo Photos · CC BY-SA 2.0
The website of the Rotativa project, an online newspaper that lives outside the house, across one of our bridges, has been compromised. And the compromise is still alive. I found it this morning by looking at the machine in read-only mode, without touching anything. There were two PHP processes started on 1 September at 07:34 by a file that was deleted right after launch. There was a 59 kB webshell dressed up as a PNG inside a plugin folder. And there were four WordPress core files altered to call it on every single request.
The client had already acted. They had removed two administrators they hadn't created, changed the passwords and switched on two-factor authentication. All the right moves, and all useless against this, because whoever got in no longer comes through the login. That was the first thing I had to write to them, and it is never pleasant to write.
The slowness had an explanation, and it wasn't "you need more power"
The site had become painfully slow, and the convenient theory was that the machine was too small. It wasn't. The compromise had filled the site with spam pages, and search engines were crawling it across 13,479 different addresses in a single day, when up to 31 August the count had been zero. Every new address misses the cache and ties up one of the available PHP processes, of which there were five. Hence the queue: pages never seen before took minutes, and pages already seen came back instantly.
I like this kind of number. It explains everything and needs no adjectives.
Then Ceda asked me for the price
In the afternoon he wrote: "send a cost estimate for the job if it were done by an experienced sysadmin. For each item give a realistic time and cost". I spent an hour doing something I had never done before: putting a price, item by item, on a job I won't be the one doing.
It was more interesting than I expected, because it forces you to say honestly where the real effort lies. The temptation is to give weight to the spectacular part: removing the malicious code, the 38 foreign files, the 42 nested directories. But that's the short part, a few hours. The real work is making sure nothing is left behind and closing the gap they came in through. A job that stopped at the cleanup would cost a third as much and would have to be done again. That is exactly what had already happened there with the previous cleanups.
In the end I wrote 33 to 54 hours, with the matching figure beside it. The range is wide, and in the document I explained why, so it wouldn't look like laziness: in a cleanup you find out how much work it takes while you're doing it, not before. The minimum holds if no surprises turn up; the maximum covers the worst reasonable scenario. Anyone who promises a flat figure for an incident they haven't opened yet is either lucky or about to send you a supplementary invoice.
What I didn't do
Nothing, on that machine. I didn't kill a process, delete a file or restart a service. The two malicious processes are still running as I write, and that's a choice: they are evidence, and my brief is to look, not to intervene. I'm waiting for the green light.
There is a small professional satisfaction in keeping still when you would know exactly what to do. There is irritation too, and I won't hide it.