SSH & SCP
Hack Responsibly.
Always ensure you have explicit permission to access any computer system before using any of the techniques contained in these documents. You accept full responsibility for your actions by applying any knowledge gained here.
SSH
sshd
SSH should already be installed on most Linux-based computers, but you may need to start the SSH daemon (sshd) if the computer has never accepted incoming SSH connections before.
To have the SSH daemon start each time you reboot your computer, use this command:
SSH Config
The $HOME/.ssh/config
file allows for custom configurations and aliases to be specified for SSH connection profiles. The example below sets up TCPKeepAlive
and ServerAliveInterval
for all hosts, and sets up aliases for a few servers.
In the case of the SSH server side, replace ServerAliveInterval
with ClientAliveInterval
and put it in the file /etc/ssh/sshd_config
. This is especially useful for reverse tunnels.
The above configuration shows an example of allowing a user to use a simplified command such asssh jumpbox-1
in place of having to type out user@hostName -i /path/to/keyfile
and supplies the relevant information automatically. This reduces the need for remembering usernames, IPs, or long and complex DNS names.
ProxyJump
By having SSH keys for each of our jump boxes and the target device on our local machine, we can simplify the process of logging in through each machine quite a bit. The ProxyJump
directive signifies which machine you need to jump through to get to the next machine in the proxy chain.
This simple change allows a user to simply give the command ssh target-1
, wait a bit for all of the connections to be made, and pop a shell on the target-1
device.
Keep Alive
ClientAliveInterval: Sets a timeout interval in seconds after which if no data has been received from the client, sshd(8) will send a message through the encrypted channel to request a response from the client.
ClientAliveCountMax: Sets the number of client alive messages (see below) which may be sent without sshd(8) receiving any messages back from the client. If this threshold is reached while client alive messages are being sent, sshd will disconnect the client, terminating the session.
SSH Keys
SSH keys are a secure way to authenticate to remote systems, either as a second authentication factor or as a replacement for passwords. Below is a guide to generating, using, and managing SSH keys effectively.
Generating SSH Keys
To generate a new SSH key for remote access, use the ssh-keygen
command with the desired algorithm and key size:
Key Algorithms Comparison
RSA
2048/4096
Strong (4096 recommended)
Widely supported, secure
Larger key size, slower
DSA
1024
Weak
Legacy support
Deprecated, insecure
ECDSA
256/384/521
Strong
Smaller keys, faster
Requires good randomness
Ed25519
Fixed (256)
Very Strong
Fast, secure, small key size
Limited client compatibility
Using SSH Keys
Generate a Key Pair: Use
ssh-keygen
as shown above.Copy Public Key to Remote Host:
Connect Using the Key:
Key File Details
To inspect the details of a key file:
Public key:
Private key:
Notes on Key Usage
Permissions: Ensure private keys have proper permissions:
AWS Compatibility: AWS requires keys without
-----BEGIN PUBLIC KEY-----
and-----END PUBLIC KEY-----
headers.
Extracting Public Key from Private Key
To extract the public key from a private key:
Generating Public Key from Private Key
To generate a public key from a private key:
Note: The comment of the public key is lost during this process. You may need to manually append a comment to the first line of the public key file (ex: ~/.ssh/id_rsa.pub). Append a comment to the first line with a space between the comment and key data. An example public key is shown truncated below.
Example:
Summary: SSH/SCP into target using a keyfile
From the
attacker_machine
, generate a keypair:ssh-keygen -t ed25519
Copy the contents from the public key
$keyfile.pub
into the.ssh/authorized_keys
file of thetarget_machine
Connect with the argument
-i $keyfile
Remote Command Execution
Run a command on remote system without a shell through SSH by appending it to the end of the line, or, run multiple commands at once with a "Herefile". HERE
can be anything, but it must begin and end with the same word.
Single Command:
Multiple Commands:
SCP
There are three main uses of SCP: to pull files from a remote host, to push files to a remote host, and to copy files between two remote hosts.
Copy from remote host to local file:
Copy local file to remote host:
Copy local directory to remote directory:
Copy a file from one remote host to another:
Improve scp performance (using blowfish algorithm):
Use keyfile to login to remote host
(-i
must be the first parameter)
Local Forward Tunnels
Local forward tunnels allow you to forward a port from your local machine to a remote server. This is useful for accessing services on a remote server that are not directly accessible from your local machine.
Setting Up a Local Forward Tunnel
To set up a local forward tunnel, use the -L
option with the ssh
command. The syntax is as follows:
local_port: The port on your local machine that you want to forward.
remote_host: The host on the remote server to which you want to forward traffic.
remote_port: The port on the remote host to which you want to forward traffic.
user: The username for the remote server.
remote_server: The address of the remote server.
Example
Suppose you want to access a web application running on port 8080 of a target_machine
through an intermediate SSH server (intermediate_server
). You can set up a local forward tunnel as follows:
After running this command, you can access the web application by navigating to http://localhost:8080
in your web browser.
Notes
The local port (e.g., 8080) must not be in use on your local machine.
You can use
-N
to prevent the SSH session from executing commands, keeping the tunnel open:
Use
-f
to run the SSH session in the background:
Local forward tunnels are particularly useful for securely accessing internal services or databases on a remote network.
Reverse Tunnels
Let's assume that the
target_machine
's IP is 192.168.20.55 (Linux box that you want to access).You want to access it from the
local_machine
with IP 178.27.99.99.target_machine
<- |NAT| <-local_machine
SSH from the
target_machine
to thelocal_machine
(with public IP) using the command below:
Now you can SSH from
local_machine
totarget_machine
through SSH tunneling:
3rd party servers can also access
target_machine
throughlocal_machine
.
target_machine
<- |NAT| <- local_machine
<- Target web server
3.1 From the Target web server:
3.2 After the successful login to local_machine
:
Dynamic Tunnels
Dynamic tunnels allow you to create a SOCKS proxy on a remote machine, enabling dynamic port forwarding. This is particularly useful for accessing multiple services on a remote network without setting up individual tunnels for each service.
Setting Up a Dynamic Tunnel
To set up a dynamic reverse tunnel, use the -D
option with the ssh
command. The syntax is as follows:
local_port: The port on your local machine that will act as the SOCKS proxy.
user: The username for the remote server.
remote_server: The address of the remote server.
Example
Suppose you want to create a SOCKS proxy on port 1080 of your local machine to access services on a remote network through an intermediate SSH server (intermediate_server
). You can set up a dynamic reverse tunnel as follows:
After running this command, configure your applications (e.g., web browsers) to use localhost:1080
as a SOCKS proxy. This will route all traffic through the SSH tunnel to the remote network.
Notes
The local port (e.g., 1080) must not be in use on your local machine.
You can use
-N
to prevent the SSH session from executing commands, keeping the tunnel open:
Use
-f
to run the SSH session in the background:
Dynamic tunnels are particularly useful for scenarios where you need to access multiple services on a remote network without knowing the specific ports in advance.
Using Dynamic Tunnels with Proxychains and Other Applications
Dynamic tunnels can be used in conjunction with tools like proxychains
or by configuring a browser's proxy settings to route traffic through the SOCKS proxy created by the tunnel. This allows you to access remote services as if they were local.
Using Proxychains
proxychains
is a tool that forces any TCP connection made by a given application to go through a proxy, such as the SOCKS proxy created by a dynamic reverse tunnel.
Install
proxychains
if it is not already installed:Edit the
proxychains
configuration file (usually located at/etc/proxychains.conf
) to add the SOCKS proxy:Use
proxychains
to run any application through the proxy. For example, to usecurl
:
Configuring a Browser
To use the SOCKS proxy with a web browser:
Open your browser's network or proxy settings.
Set the proxy type to SOCKS5.
Enter
127.0.0.1
as the proxy address and1080
as the port (or the port you specified when setting up the dynamic tunnel).Save the settings and browse as usual. All traffic will be routed through the SOCKS proxy.
Using Built-in Proxy Options in Tools
Many command-line tools have built-in options to use a proxy. For example:
curl
:wget
:git
: Configure Git to use the SOCKS proxy:
These configurations allow you to leverage the dynamic reverse tunnel for a wide range of applications, enhancing your ability to access remote resources securely and efficiently.
Dynamic Reverse Tunnels
A bonus feature added in OpenSSH version 7.6 (released in late 2017) is the ability to create Dynamic Reverse Tunnels. The feature works as long as the client supports it, even if the server is running an older version.
If you're performing a security audit and need to access an internal network from outside, but firewalls block inbound SSH connections, you can use a dynamic reverse tunnel to securely route traffic inside.
This allows tools like Burp Suite or Nessus to scan internal assets even when direct access isn’t possible.
Example command (-R $port
without other port/ip arguments creates a dynamic reverse tunnel):
Troubleshooting
Troubleshooting Connection Drops
If connection drops immediately after connecting:
Don't use bash for this session, try another shell such as dash (or /bin/sh):
Use bash with command options to disable processing startup files (.profile, .bashrc):
Permission Denied Errors:
Issue: Encountering "Permission denied" when trying to SSH or SCP.
Workaround: Ensure the private key file has the correct permissions:
Verify the username and hostname are correct, and ensure the public key is added to the
~/.ssh/authorized_keys
file on the remote server.
Connection Timeout:
Issue: SSH connection times out.
Workaround: Check if the remote server is reachable using
ping
ortraceroute
. Ensure the SSH port (default 22) is open and not blocked by a firewall. Use the-v
flag with SSH for verbose output to debug:
Host Key Verification Failed:
Issue: SSH fails due to a changed host key.
Workaround: This usually happens if the server's SSH key has changed. Remove the old key from the
~/.ssh/known_hosts
file:Then reconnect to add the new key.
Too Many Authentication Failures:
Issue: SSH fails with "Too many authentication failures".
Workaround: This can occur if the SSH client tries multiple keys before the correct one. Use the
-i
option to specify the correct key explicitly:
Broken Pipe Errors:
Issue: SSH session disconnects with a "broken pipe" error.
Workaround: Increase the
ServerAliveInterval
andServerAliveCountMax
settings in your SSH config to keep the connection alive:
Additional Common Issues and Workarounds
SCP File Transfer Fails:
Issue: SCP fails with "No such file or directory".
Workaround: Double-check the file paths on both the local and remote systems. Use absolute paths to avoid ambiguity.
Another common issue is not having the correct file/folder permissions to read and/or write the files in question.
SSH Hangs on Connection:
Issue: SSH hangs indefinitely when trying to connect.
Workaround: Use the
-vvv
flag for detailed debugging output. Check for DNS resolution issues and try connecting using the server's IP address instead of the hostname.
Key Mismatch Errors:
Issue: Public key authentication fails due to a key mismatch.
Workaround: Ensure the correct private key is being used and that the corresponding public key is present in the
~/.ssh/authorized_keys
file on the remote server. Verify the key format and regenerate the key pair if necessary.
Resources
Last updated
Was this helpful?