Last weekend the Sebek-instrumented honeypot caught a careful attacker. The capture is detailed enough to write a useful case study around. As always, sanitised — source IP and specific exploit removed.
The compromise
The attacker exploited a known vulnerability in a service running on the honeypot. The exploit gave them root. The compromise itself was unremarkable; what they did next was instructive.
The first 30 seconds
From the Sebek capture, the attacker's first commands:
id
uname -a
cat /proc/version
ps -ef | head
w
last | head
Standard enumeration. The interesting thing is what they did not do — no ls /root, no cat /etc/shadow, no ls /home. They were not interested in the host's content. They were interested in establishing what the host was.
The next minute
ls /etc/cron.d/
cat /etc/syslog.conf
ls /var/log/
find /etc -newer /etc/passwd 2>/dev/null
They were checking for monitoring. Specifically: any custom syslog configuration, any unusual cron jobs, any recently-modified configuration files. This is the behaviour of someone who knows what to look for and is checking before they do anything irreversible.
The find /etc -newer /etc/passwd is particularly clever. It finds files in /etc modified more recently than /etc/passwd — which is normally relatively static. Recent changes in /etc are an indicator of active administration; an attacker doing this check is screening for hosts that are actively managed.
My honeypot's /etc was deliberately constructed to look unmanaged (recent changes only on certain files that look like routine updates). The attacker's check returned a small set of files; they apparently judged the host to be lightly-administered.
The next ten minutes
The attacker installed a small backdoor. The Sebek capture shows them typing the source code of the backdoor — a 30-line C program that listens on a high TCP port for a magic byte sequence and spawns a shell when matched.
The interesting thing: they did not fetch the source from anywhere. They typed it. This is the behaviour of someone who has the source memorised — presumably because they have used this same backdoor on many previous compromises.
The compilation:
gcc -O2 -static -o /tmp/.x backdoor.c
rm backdoor.c
The -static flag is interesting — it produces a binary with no library dependencies, so the binary works regardless of the host's library versions. The -O2 optimises for size. The output is in /tmp with a hidden filename (the leading dot makes it invisible to default ls).
The binary was started, the source removed. The attacker tested the backdoor by connecting to it from outside — the connection appears in the firewall log as an unusual outbound connection, which I would have flagged in a real environment but which my honeypot allows for capture purposes.
The exit
After the backdoor was tested:
history -c
rm ~/.bash_history
exit
The history was cleared; they exited cleanly. From an on-host inspection, the only artefact remaining was the /tmp/.x binary — and even that was hidden by the leading dot.
Without Sebek, the only visible signs of this compromise would have been the /tmp/.x binary and the open TCP port. With Sebek, I have the full sequence of commands, the source code of the backdoor, and the timing of every action.
What this teaches
Three things.
The skilled-attacker population, while small, is genuinely capable. This was an attacker who had presumably done this many times before. The economy of motion — no wasted commands, no obvious signature — was striking. The detection of this kind of attack from on-host artefacts alone is essentially impossible.
The off-host capture is the only reliable evidence. Everything the attacker did on-host was either ephemeral (their commands disappeared into history, which they then cleared) or carefully hidden (the binary in /tmp with a hidden name). The Sebek capture from outside the host has the complete record.
Specific behaviours are diagnostic. The find /etc -newer pattern, the gcc -static, the history -c/rm ~/.bash_history sequence, the leading-dot filename — these are diagnostic of the careful attacker style. Snort rules cannot easily detect these (they happen on the host, not the wire), but if you have on-host audit (syscall-level), the patterns can be alerted on.
For my own writing: more captures of this kind would be valuable, and I am going to make a habit of writing them up periodically. The careful-attacker population is small but high-impact; understanding their patterns is operationally useful.
More as captures accumulate.