# SSH (Secure Shell) Pentesting

SSH is a cryptographic network protocol for operating network services securely over an unsecured network. A default port is 22.

### Enumeration <a href="#enumeration" id="enumeration"></a>

```shellscript
nmap --script ssh-brute -p 22 <target-ip>
nmap --script ssh-auth-methods --script-args="ssh.user=username" -p 22 <target-ip>
nmap --script ssh-* -p 22 <target-ip>

# User enumeration
msfconsole
msf> use auxiliary/scanner/ssh/ssh_enumusers
```

#### Brute Force Credentials <a href="#brute-force-credentials" id="brute-force-credentials"></a>

```shellscript
# -t: tasks
hydra -l username -P passwords.txt <target-ip> ssh -t 4
hydra -L usernames.txt -p password <target-ip> ssh -t 4

# Specific ports
hydra -l username -P passwords.txt -s 2222 <target-ip> ssh -t 4
hydra -l username -P passwords.txt ssh://<target-ip>:2222 -t 4
```

If the target host opens port 80 or 443, you can generate wordlist from the contents of the website then use Hydra.

```shellscript
cewl http://<target-ip> > wordlist.txt
```

#### Crack SSH Private Key <a href="#crack-ssh-private-key" id="crack-ssh-private-key"></a>

First of all, you need to format the private key to make John to recognize it.

```shellscript
ssh2john private_key.txt > hash.txt
# or
python2 /usr/share/john/ssh2john.py private_key.txt > hash.txt
```

Crack the password of the private key using the formatted text.

```shellscript
john --wordlist=wordlist.txt hash.txt
```

### Investigation <a href="#investigation" id="investigation"></a>

#### Banner Grabbing <a href="#banner-grabbing" id="banner-grabbing"></a>

```
nc <target-ip> 22
```

Also, [**ssh-audit**](https://github.com/jtesta/ssh-audit) is an useful tool for SSH server and client auditing.

```shellscript
ssh-audit <target-ip>
```

### Configuration Files <a href="#configuration-files" id="configuration-files"></a>

```shellscript
# SSH client
cat /etc/ssh/ssh_config
# SSH server
cat /etc/ssh/sshd_config
```

### Connect <a href="#connect" id="connect"></a>

If you know a target credential, you can connect a remote server over SSH using the credential.

```shellscript
ssh username@<target-ip>
ssh username@<target-ip> -p 22

# Using private key
ssh -i id_rsa username@<target-ip>

# Without username
ssh 10.0.0.1
```

#### Additional Options <a href="#additional-options" id="additional-options"></a>

If we got the error message **"no matching host key type found. Their offer: ssh-rsa..."**, add the following flag.

```shellscript
ssh -o HostKeyAlgorithms=+ssh-rsa user@10.0.0.1
```

If we got error **"no matching key exchange method found. Their offer: diffie-hellman-..."**, add the **"KexAlgorithms"** flag as below.

```shellscript
ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 user@10.0.0.1
```

#### Execute Commands after Connecting <a href="#execute-commands-after-connecting" id="execute-commands-after-connecting"></a>

```shellscript
ssh username@<target-ip> 'ls -l'
```

#### Test Connection <a href="#test-connection" id="test-connection"></a>

```shellscript
ssh -T username@10.0.0.1
ssh -T username@10.0.0.1 -vvv
```

#### Connect to Windows via Active Directory <a href="#connect-to-windows-via-active-directory" id="connect-to-windows-via-active-directory"></a>

```shellscript
ssh domain-name\\username@domain-controller
```

#### Connect using an Existing Private Key <a href="#connect-using-an-existing-private-key" id="connect-using-an-existing-private-key"></a>

1. **Copy the Content of id\_rsa (Private Key)**

   In remote machine,

   ```shellscript
   cat /home/<victim-user>/.ssh/id_rsa
   ```
2. **Create New Private Key in Local Machine**

   ```
   echo 'copied content of id_rsa' > private_key.txt
   ```

   Don't forget to change permission this file. Otherwise, you cannot connect remote server.

   ```shellscript
   chmod 600 private_key.txt
   ```
3. **Connect using Private Key**

   ```shellscript
   ssh -i private_key.txt victim-user@<remote-ip>
   ```

   If the error “error in libcrypto” occured, edit the format of the RSA private key.\
   The correct format is below:

   ```shellscript
   -----BEGIN RSA PRIVATE KEY-----
   Proc-Type:4,ENCRYPTED
   DEK-Info:AES-128-CBC,D137279D69A43E71BB7FCB87FC61D25E

   jqDJP+blUr+xMlASYB9t4gFyMl9VugHQJAylGZE6J/b1nG57eGYOM8wdZvVMGrfN
   bNJVZXj6VluZMr9uEX8Y4vC2bt2KCBiFg224B61z4XJoiWQ35G/bXs1ZGxXoNIMU
   ...
   ...
   ...
   7mxN/N5LlosTefJnlhdIhIDTDMsEwjACA+q686+bREd+drajgk6R9eKgSME7geVD
   -----END RSA PRIVATE KEY-----
   ```

### Transfer Files <a href="#transfer-files" id="transfer-files"></a>

#### Send a File/Directory to Another Machine <a href="#send-a-filedirectory-to-another-machine" id="send-a-filedirectory-to-another-machine"></a>

```shellscript
# Send a file
scp ./example.txt user@<ip>:./example.txt

# Send a directory
scp -r ./example user@<ip>:/home/<ip>/
```

#### Download a File/Directory from Another Machine <a href="#download-a-filedirectory-from-another-machine" id="download-a-filedirectory-from-another-machine"></a>

```shellscript
# Download a file
scp user@<ip>:/home/<user>/path/to/file.txt .

# Download a directory
scp -r user@<ip>:/home/<user>/path/to/file.txt .
```

If you get error **“connection refused”**, the SSH server is not running in another machine. So you need to start the SSH server.

### Create SSH Keys <a href="#create-ssh-keys" id="create-ssh-keys"></a>

#### Generate Keys <a href="#generate-keys" id="generate-keys"></a>

```shellscript
ssh-keygen

# Specify the output file
ssh-keygen -f key
# Specify Ed25519
ssy-keygen -t ed25519
```

#### Install SSH Key <a href="#install-ssh-key" id="install-ssh-key"></a>

In target machine,

```shellscript
ssh-copy-id username@<target-ip>
```

### Generate SSH Keys and Set Up Public Key to Connect Remote Machine <a href="#generate-ssh-keys-and-set-up-public-key-to-connect-remote-machine" id="generate-ssh-keys-and-set-up-public-key-to-connect-remote-machine"></a>

#### 1. Check if authorized\_keys Exists in Remote Machine <a href="#id-1-check-if-authorized_keys-exists-in-remote-machine" id="id-1-check-if-authorized_keys-exists-in-remote-machine"></a>

```shellscript
ls /home/<remote-user>/.ssh/authorized_keys
```

If it exists, you may be able to connect SSH with your keys as victim user.

#### 2. Generate SSH Keys in Local Machine <a href="#id-2-generate-ssh-keys-in-local-machine" id="id-2-generate-ssh-keys-in-local-machine"></a>

```shellscript
ssh-keygen -f key

# Copy the content of publick key
cat ./key.pub
```

Then copy the content of public key you generated.

#### 3. Add the Content of Publick Key to authorized\_keys <a href="#id-3-add-the-content-of-publick-key-to-authorized_keys" id="id-3-add-the-content-of-publick-key-to-authorized_keys"></a>

In remote machine,

```shellscript
echo '<content of id_rsa.pub' >> /home/<victim-user>/.ssh/authorized_keys
```

#### 4. Login with Private Key <a href="#id-4-login-with-private-key" id="id-4-login-with-private-key"></a>

In local machine, we have a SSH private key in local machine so we can login the target SSH server with it.

```
# Change permission of the private key ('key', here)
chmod 600 key
# Login with it
ssh victim@<target-ip> -i key
```

### SSH Server <a href="#ssh-server" id="ssh-server"></a>

#### Start/Stop/Restart <a href="#startstoprestart" id="startstoprestart"></a>

* **Start**

  ```
  sudo systemctl start ssh
  ```
* **Stop**

  ```
  sudo systemctl stop ssh
  ```
* **Restart**

  ```
  sudo systemctl restart ssh
  ```

#### Status <a href="#status" id="status"></a>

```
sudo systemctl status ssh

ps -e | grep ssh
```

#### Configuration <a href="#configuration" id="configuration"></a>

```
vim /etc/ssh/sshd_config
```

#### Check for any Established Connection <a href="#check-for-any-established-connection" id="check-for-any-established-connection"></a>

To get the “pts/# terminal”, run the following command. The pts stands for pseudo terminal slave.

```
who | grep <username>
```

To kill any connections, run the following commands.

```
# -f: full process name to match
sudo pkill -f pts/#
```

#### Logs <a href="#logs" id="logs"></a>

```
# Authentication logs
grep 'sshd' /var/log/auth.log
```

### SSH Proxy Server <a href="#ssh-proxy-server" id="ssh-proxy-server"></a>

#### Sshuttle <a href="#sshuttle" id="sshuttle"></a>

[**sshuttle**](https://github.com/sshuttle/sshuttle) is transparent proxy server that works as a poor man's VPN. Forwards over ssh.

```
sshuttle -r username@<remote-ip> <remote-ip>/24

# Automatically determine subnet
sshuttle -r username@<remote-ip> -N

# Using private key
sshuttle -r username@<remote-ip> --ssh-cmd "ssh -i private_key" <remote-ip>/24

# Exclude the specific ip (-x)
sshuttle -r username@<remote-ip> <remote-ip>/24 -x <remote-ip>
```

Then you can access to other networks.

* **Troubleshooting**

  If you get the error "Failed to flush caches: Unit dbus-org.freedesktop.resolve1.service not found...", you need to flush DNS cache.

  ```
  sudo systemctl enable systemd-resolved.service
  sudo resolvectl flush-caches
  ```

  Run sshuttle again.

### SSH-MITM for Stealing Credentials <a href="#ssh-mitm-for-stealing-credentials" id="ssh-mitm-for-stealing-credentials"></a>

If the target system user try to connect arbitrary host using SSH, we might be able to steal credentials by listening via the SSH man-in-the-middle server.\
Run the following command in local machine.

```
# If not have the ssh-mitm, install first.
pip3 install ssh-mitm --upgrade

# --enable-trivial-auth: The "trivial authentication" phishing attack
# --remote-host: Specify the target ip/domain
# --listen-port: Specify the ip address to listen in local machine
ssh-mitm server --enable-trivial-auth --remote-host example.com --listen-port 2222
```

### 2FA Bypass <a href="#id-2fa-bypass" id="id-2fa-bypass"></a>

When logging in to SSH with 2FA enabled, we will be asked for a **Verification Code**.

#### Google Authenticator <a href="#google-authenticator" id="google-authenticator"></a>

If the Google Authenticator is used, the secret key of TOTP can be stored in `$HOME/.google_authenticator` according to [the repo](https://github.com/google/google-authenticator-libpam).

After getting the secret key, now access to [Online one-time password generator](https://totp.app/) and input the secret key, then get TOTP.\
Now login SSH with `ssh` command and input the TOTP for verification code.

### References <a href="#references" id="references"></a>

* [Exploit DB](https://www.exploit-db.com/docs/english/44592-linux-restricted-shell-bypass-guide.pdf)
