Introduction

Finding an unrecognized SSH public key in a user's ~/.ssh/authorized_keys file is a clear indicator of compromise. An attacker with access to the server (via another vector) may have added their own key to maintain persistent access, even after the original vulnerability is patched. This is a common post-exploitation technique because SSH key access survives password changes and is harder to detect than a modified password.

Symptoms

  • Unknown SSH public key found in ~/.ssh/authorized_keys
  • SSH login from an unfamiliar IP address in /var/log/auth.log
  • User reports they did not add the key
  • Key fingerprint does not match any known team member
  • Multiple servers have the same unauthorized key added

Common Causes

  • Server compromised via vulnerable web application
  • Stolen SSH private key from a developer's machine
  • Shared credentials allowing unauthorized access
  • Supply chain attack through compromised deployment pipeline
  • Insider threat adding a key for unauthorized access

Step-by-Step Fix

  1. 1.Document the unauthorized key before removing it:
  2. 2.```bash
  3. 3.# Record the key for forensic analysis
  4. 4.cat ~/.ssh/authorized_keys > /tmp/authorized_keys.evidence
  5. 5.# Get the fingerprint
  6. 6.ssh-keygen -lf /tmp/authorized_keys.evidence
  7. 7.# Note the timestamp of when the file was last modified
  8. 8.stat ~/.ssh/authorized_keys
  9. 9.`
  10. 10.Check authentication logs for access using the unauthorized key:
  11. 11.```bash
  12. 12.# Get the key fingerprint
  13. 13.FINGERPRINT=$(ssh-keygen -lf /tmp/unauthorized_key.pub | awk '{print $2}')
  14. 14.# Search auth logs for this fingerprint
  15. 15.sudo grep "$FINGERPRINT" /var/log/auth.log
  16. 16.sudo grep "$FINGERPRINT" /var/log/secure
  17. 17.# Check for SSH sessions from unfamiliar IPs
  18. 18.sudo grep "Accepted publickey" /var/log/auth.log | tail -20
  19. 19.`
  20. 20.Remove the unauthorized key immediately:
  21. 21.```bash
  22. 22.# Remove the specific key line from authorized_keys
  23. 23.# First identify which line it is
  24. 24.grep -n "unauthorized-key-comment" ~/.ssh/authorized_keys
  25. 25.# Remove it
  26. 26.sed -i '/unauthorized-key-comment/d' ~/.ssh/authorized_keys
  27. 27.`
  28. 28.Check all user accounts on the server for the same key:
  29. 29.```bash
  30. 30.for user in $(cut -d: -f1 /etc/passwd); do
  31. 31.homedir=$(eval echo ~$user)
  32. 32.if [ -f "$homedir/.ssh/authorized_keys" ]; then
  33. 33.match=$(grep -l "unauthorized-key-pattern" "$homedir/.ssh/authorized_keys" 2>/dev/null)
  34. 34.[ -n "$match" ] && echo "FOUND on $user: $match"
  35. 35.fi
  36. 36.done
  37. 37.`
  38. 38.Audit all recent SSH sessions and check for signs of lateral movement:
  39. 39.```bash
  40. 40.# List all SSH sessions in the last 7 days
  41. 41.sudo grep "session opened" /var/log/auth.log | grep sshd | tail -30
  42. 42.# Check for new user accounts created
  43. 43.sudo grep "useradd|adduser" /var/log/auth.log
  44. 44.# Check for sudo activity
  45. 45.sudo grep "sudo:" /var/log/auth.log | tail -20
  46. 46.# Check for cron jobs added
  47. 47.for user in $(cut -d: -f1 /etc/passwd); do
  48. 48.crontab -u $user -l 2>/dev/null
  49. 49.done
  50. 50.`
  51. 51.Harden SSH configuration to prevent recurrence:
  52. 52.```bash
  53. 53.sudo nano /etc/ssh/sshd_config
  54. 54.# Disable password authentication
  55. 55.PasswordAuthentication no
  56. 56.# Limit which users can SSH
  57. 57.AllowUsers admin deploy
  58. 58.# Disable root login
  59. 59.PermitRootLogin no
  60. 60.# Log all SSH access
  61. 61.LogLevel VERBOSE
  62. 62.sudo systemctl restart sshd
  63. 63.`

Prevention

  • Implement centralized SSH key management with automated auditing
  • Use SSH certificates instead of authorized_keys for better key lifecycle management
  • Monitor authorized_keys files with file integrity monitoring (AIDE, OSSEC)
  • Implement bastion hosts with session recording for all SSH access
  • Rotate SSH keys on a regular schedule and audit all active keys quarterly