TL;DR:

~/.ssh/authorized_keys

command="/usr/local/bin/honeykey kulinacs@honeypot",restrict ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDhOeMjLnm/G+HEwAkF5QVeqtu53NjtdUINrUtkjg2xOfycK7vo5fS3Uk46UjaY3JzRnXAsIhAUM4FRSA6TUY+1FqpEI5NXFtFF0jwaPre9P7Elx4d0QOliUaHcixrQhzGwIfhiyyVqQSWZ2i0LR2bB07hClr6buj0UH60bg0VeNIs7ZnardkFXQ53PUa64m15SxJgh0GcM5LFGYT2eCPT+7FYT4h6lUdxYfHHM0TIFY+Cp/d3pHeev8ieC1/xtVSgGYbj0DkI78w/e9wzO1Hc6HLM9WSlxxWaivrjokGtrKSmQfcaJtETExTWY9aLxKy4Nafqc71bVX7URVrB6iakD kulinacs@honeypot

/usr/local/bin/honeykey

#!/bin/sh logger "Honey key used - ${1}"

Motivation

Honeypots and canaries have been on the rise over the last year or so, at least in the InfoSec media I consume. I have some experience with the Cowrie Honeypot (https://github.com/kulinacs/cowrie-attack) mapping honeypot activity to ATT&CK Techniques and during the live run I noticed a relatively large drawback to dedicated honeypots.

For dedicated honeypots, you have to run a dedicated honeypot.

Any attacker looking through user history, SSH known_hosts, outgoing connections, etc., will likely see no activity between legitimate users and the honeypot. With this, I wanted to find low investment "honey" opportunities that could alert on attacker activities on legitimate infrastructure.

SSH Keys

SSH keys serve as a cryptographic form of authentication for the user and are regularly touted as the "more secure" way to authenticate. If SSH Keys are new to you, the Arch wiki provides fairly comprehensive documentation.

The thought behind honey keys is similar to Honeywords, a concept published a while ago to help identify attempts to use data collected in breaches to gain unauthorized access to a user account. In our case, the attacker attempts to authenticate with the honey key, the action is logged (or another action chosen by the defender) and an alarm is sounded for use of the key.

Fortunately, the authorized_keys format permits an rarely used options field that aids greatly in this attempt.

Honey Keys

Honey keys can be implemented incredibly easily. All a defender needs to do is add an additional key to the authorized key file containing the command option pointing to the desired "alarm" and the restrict option.

~/.ssh/authorized_keys

command="/usr/local/bin/honeykey kulinacs@honeypot",restrict ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDhOeMjLnm/G+HEwAkF5QVeqtu53NjtdUINrUtkjg2xOfycK7vo5fS3Uk46UjaY3JzRnXAsIhAUM4FRSA6TUY+1FqpEI5NXFtFF0jwaPre9P7Elx4d0QOliUaHcixrQhzGwIfhiyyVqQSWZ2i0LR2bB07hClr6buj0UH60bg0VeNIs7ZnardkFXQ53PUa64m15SxJgh0GcM5LFGYT2eCPT+7FYT4h6lUdxYfHHM0TIFY+Cp/d3pHeev8ieC1/xtVSgGYbj0DkI78w/e9wzO1Hc6HLM9WSlxxWaivrjokGtrKSmQfcaJtETExTWY9aLxKy4Nafqc71bVX7URVrB6iakD kulinacs@honeypot

The restrict option is a future proof (according to the documentation) method to disable additional features like port forwarding, pty allocation, etc., stopping any attackers from using the key for pivoting or any other malicious activity. The command option forces the command given to be run when this key is used, stopping an attacker from gaining command execution on the machine. This coupled with a logging script could be fed in to Elasticsearch with ElastAlert querying for a log message to detect the attack.

/usr/local/bin/honeykey

#!/bin/sh logger "Honey key used - ${1}"

Domain Integration

Many corporations centrally manage user keys, to avoid needing to copy the same authorized_keys file to every machine. This is well supported through the AuthorizedKeysCommand directive, which in the case of FreeIPA, uses sss_ssh_authorizedkeys to look up the keys stored in FreeIPA.

Fortunately, this command follows the same format as the authorized_keys file, and honey keys can be implemented identically

Closing Thoughts

I'm not sure how practical this is in production. Keys could be scattered randomly in users home directories fairly easily, multiple keys would be incredibly easy to manage in solutions like FreeIPA (or even more grassroots solutions like keys directly in LDAP), and detection can be done easily via integration with existing logging solutions like Splunk or Elasticsearch.

That being said, I'm always wary of a solution that seems too good to be true. Searching the internet for a similar solution hasn't turned up anything and it makes me wonder why no one else is doing it. Perhaps it hasn't proved useful or this solution has some inherent flaw that I haven't identified. In either case, I think its a neat idea and I'd love to get some other's opinions on it.

Addendum

Addressing comments from external sources.

How is this useful? It doesn't seem to fit any threat model.

That's a really fair point and likely fairly specific to the environment being deployed to. In my mind, I could see unencrypted honey private keys scattered throughout user home directories, potentially with a name that suggests authority across a security boundary, like id_jumphost . In environments where a jumphost is used to restrict access to another network, this might be tantalizing enough for an attacker to attempt the key. In the more general case, I see this more as a trap for pivoting attackers more than anything else.

Can we get an ssh -vvv to see what's going on?

Sure: https://gist.github.com/kulinacs/3264e36e0a7680b49668d1f8ef129bda

I don't think command+restrict is really meant for security auditing/logging...

I don't disagree that this isn't for security auditing/logging, but I'm not sure as much skepticism is warranted (queue openssh developer telling me I'm wrong). The sshd(8) man page gives examples like

restrict,command="uptime" ssh-rsa AAAA1C8...32Tv== user@example.net

that to me speaks to this being considered a security feature. Any owner of the key can run uptime, but nothing else. Granted, examples from man pages on rarely used features shouldn't be taken as confirmation of security, but I think it leans towards this not being a TERRIBLE idea. Still, more testing needs to be done.

It seems like this breaks the AAA chain, while the attacker is only authorized to use the log script, they are still authenticated which has security implications.

Unfortunately true. If there was a way to fail auth for specific keys but still log, that would be really great. Suggests taking a look at the expiry-time and from options, see if they fail silently or with some intelligent log message.

This turns 'You have no access to this system' into 'You have access to this system but you can only run this logging script' which to me seems like the basis of every infiltration trick ever.

Also agreed, however, AFAIK, the user has no ability to input to the script. This greatly reduces attack surface. The command they send is substituted, environment variables are ignored, and no additional forwarding can be set. Not even a pty is allocated. With some more rigorous testing, that seems fairly safe in my mind.