念念不忘
必有回响

ElasticSearch 7.8.0 破解

在测试ES-SQL的过程中发现当前最新版`ES 7.8.0`的JDBC是收费的,不过都已经花了时间去搞那么还是需要小小的`测试`一下的。
其实,说ES破解也不太对,主要是ES的增强包`X-Pack`,这个增强包包含了JDBC、ODBC、安全、告警、机器学习等,所以这个工具的付费还是不错的,可惜目前还未得到能接受付费的回应,那就先`试`用一下吧。

根据目前我的场景,已经安装好ElasticSearch7.8.0和kibana7.8.0。

下载反编译工具

因为要修改期验证license的代码,所以我们需要通过反编译工具来查看代码,这里推荐`Luyten`,可以去[Releases · deathmarine/Luyten · GitHub]下载,官方提供了win的安装包已经可执行的jar,所以这里下载jar即可。

查看x-pack-core的源码

es我是通过rpm安装的,所以在其安装目录`/usr/share/elasticsearch/modules/x-pack-core`中下载`x-pack-core-7.8.0.jar`文件到本地,通过`Luyten`打开这个jar。

找到以下两个文件:

  • org.elasticsearch.license.LicenseVerifier
  • org.elasticsearch.xpack.core.XPackBuild

将这两个class文件中的所有内容拷贝到两个对应的java文件内
`LicenseVerifier.java`

package org.elasticsearch.license;

import java.nio.*;
import org.elasticsearch.common.bytes.*;
import java.security.*;
import java.util.*;
import org.elasticsearch.common.xcontent.*;
import org.apache.lucene.util.*;
import org.elasticsearch.core.internal.io.*;
import java.io.*;

public class LicenseVerifier
{
    public static boolean verifyLicense(final License license, final byte[] publicKeyData) {
        // byte[] signedContent = null;
        // byte[] publicKeyFingerprint = null;
        // try {
        //     final byte[] signatureBytes = Base64.getDecoder().decode(license.signature());
        //     final ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
        //     final int version = byteBuffer.getInt();
        //     final int magicLen = byteBuffer.getInt();
        //     final byte[] magic = new byte[magicLen];
        //     byteBuffer.get(magic);
        //     final int hashLen = byteBuffer.getInt();
        //     publicKeyFingerprint = new byte[hashLen];
        //     byteBuffer.get(publicKeyFingerprint);
        //     final int signedContentLen = byteBuffer.getInt();
        //     signedContent = new byte[signedContentLen];
        //     byteBuffer.get(signedContent);
        //     final XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
        //     license.toXContent(contentBuilder, (ToXContent.Params)new ToXContent.MapParams((Map)Collections.singletonMap("license_spec_view", "true")));
        //     final Signature rsa = Signature.getInstance("SHA512withRSA");
        //     rsa.initVerify(CryptUtils.readPublicKey(publicKeyData));
        //     final BytesRefIterator iterator = BytesReference.bytes(contentBuilder).iterator();
        //     BytesRef ref;
        //     while ((ref = iterator.next()) != null) {
        //         rsa.update(ref.bytes, ref.offset, ref.length);
        //     }
        //     return rsa.verify(signedContent);
        // }
        // catch (IOException ex) {}
        // catch (NoSuchAlgorithmException ex2) {}
        // catch (SignatureException ex3) {}
        // catch (InvalidKeyException e) {
        //     throw new IllegalStateException(e);
        // }
        // finally {
        //     if (signedContent != null) {
        //         Arrays.fill(signedContent, (byte)0);
        //     }
        // }
        return true;
    }
    
    public static boolean verifyLicense(final License license) {
    //     byte[] publicKeyBytes;
    //     try {
    //         final InputStream is = LicenseVerifier.class.getResourceAsStream("/public.key");
    //         try {
    //             final ByteArrayOutputStream out = new ByteArrayOutputStream();
    //             Streams.copy(is, (OutputStream)out);
    //             publicKeyBytes = out.toByteArray();
    //             if (is != null) {
    //                 is.close();
    //             }
    //         }
    //         catch (Throwable t) {
    //             if (is != null) {
    //                 try {
    //                     is.close();
    //                 }
    //                 catch (Throwable t2) {
    //                     t.addSuppressed(t2);
    //                 }
    //             }
    //             throw t;
    //         }
    //     }
    //     catch (IOException ex) {
    //         throw new IllegalStateException(ex);
    //     }
    //     return verifyLicense(license, publicKeyBytes);
        return true;
    }
}

将验证license的代码注释了,返回`true`。
XPackBuild.java

package org.elasticsearch.xpack.core;

import org.elasticsearch.common.io.*;
import java.net.*;
import org.elasticsearch.common.*;
import java.nio.file.*;
import java.io.*;
import java.util.jar.*;

public class XPackBuild
{
    public static final XPackBuild CURRENT;
    private String shortHash;
    private String date;
    
    @SuppressForbidden(reason = "looks up path of xpack.jar directly")
    static Path getElasticsearchCodebase() {
        final URL url = XPackBuild.class.getProtectionDomain().getCodeSource().getLocation();
        try {
            return PathUtils.get(url.toURI());
        }
        catch (URISyntaxException bogus) {
            throw new RuntimeException(bogus);
        }
    }
    
    XPackBuild(final String shortHash, final String date) {
        this.shortHash = shortHash;
        this.date = date;
    }
    
    public String shortHash() {
        return this.shortHash;
    }
    
    public String date() {
        return this.date;
    }
    
    static {
        final Path path = getElasticsearchCodebase();
        String shortHash = null;
        String date = null;
        Label_0109: {
            /*
            if (path.toString().endsWith(".jar")) {
                try {
                    final JarInputStream jar = new JarInputStream(Files.newInputStream(path, new OpenOption[0]));
                    try {
                        final Manifest manifest = jar.getManifest();
                        shortHash = manifest.getMainAttributes().getValue("Change");
                        date = manifest.getMainAttributes().getValue("Build-Date");
                        jar.close();
                    }
                    catch (Throwable t) {
                        try {
                            jar.close();
                        }
                        catch (Throwable t2) {
                            t.addSuppressed(t2);
                        }
                        throw t;
                    }
                    break Label_0109;
                }
                catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            */
            shortHash = "Unknown";
            date = "Unknown";
        }
        CURRENT = new XPackBuild(shortHash, date);
    }
}

将校验文件是否修改的逻辑注释了即可。
将这两个文件上传到安装了ES的服务器上,进行编译生成`class`字节码文件。

# 编译LicenseVerifier.java
javac -cp "/usr/share/elasticsearch/lib/elasticsearch-7.8.0.jar:/usr/share/elasticsearch/lib/lucene-core-8.0.0.jar:/usr/share/elasticsearch/modules/x-pack-core/x-pack-core-7.8.0.jar:/usr/share/elasticsearch/modules/x-pack-core/netty-common-4.1.32.Final.jar:/usr/share/elasticsearch/lib/elasticsearch-core-7.8.0.jar" /root/LicenseVerifier.java

# 编译XPackBuild.java
javac -cp "/usr/share/elasticsearch/lib/elasticsearch-7.8.0.jar:/usr/share/elasticsearch/lib/lucene-core-8.0.0.jar:/usr/share/elasticsearch/modules/x-pack-core/x-pack-core-7.8.0.jar:/usr/share/elasticsearch/modules/x-pack-core/netty-common-4.1.32.Final.jar:/usr/share/elasticsearch/lib/elasticsearch-core-7.8.0.jar" /root/XPackBuild.java

替换生成的class文件

将es安装包/usr/share/elasticsearch/modules/x-pack-core内的x-pack-core-7.8.0.jar拷贝到其他目录,按照如下步骤进行替换:

# 将其拷贝到其他目录
cp /usr/share/elasticsearch/modules/x-pack-core/x-pack-core-7.0.1.jar /root/es
# 进入/root
cd ~/es
# 解压
jar -xvf x-pack-core-7.8.0.jar

查看文件

ls
ilm-history-ilm-policy.json  monitoring-alerts-7.json  monitoring-logstash.json        security-tokens-index-template-7.json  watches.json                   watch-history-no-ilm-10.json
ilm-history.json             monitoring-beats.json     org                             slm-history-ilm-policy.json            watch-history-10.json          watch-history-no-ilm.json
logstash-management.json     monitoring-es.json        public.key                      slm-history.json                       watch-history-ilm-policy.json  x-pack-core-7.8.0.jar
META-INF                     monitoring-kibana.json    security-index-template-7.json  triggered-watches.json                 watch-history.json

替换文件

cp /root/XPackBuild.class org/elasticsearch/xpack/core/
cp /root/LicenseVerifier.class org/elasticsearch/license/

替换完成后,重新将其打包,在刚才操作的目录`/root/es`,执行如下命令:

重新打包

# 先删除刚才解压的文件
rm -rf x-pack-core-7.8.0.jar
# 重新生成,注意后面的点,代表当前目录
jar cvf x-pack-core-7.8.0.jar .

替换x-pack-core-7.8.0.jar

# 将x-pack-core-7.8.0.jar拷贝到该目录
cp ~/es/x-pack-core-7.8.0.jar /usr/share/elasticsearch/modules/x-pack-core

替换完成后重启ElasticSearch

申请免费的ElasticSearch License

打开[Register | Elastic](https://license.elastic.co/registration)申请一个一年的免费license,申请完成后会发送文件到你的邮箱中,打开后:
elasticsearch
点击Download the license for Elasticsearch 5.x/6.x,下载后打开这个文件,修改两个地方,将typebasic修改为platinum(白金),将expiry_date_in_millis修改为2524579200999(2050年)。

{
  "license": {
    "uid": "c3f3df93-4636-45af-aafa-65d982dcabcd",
    "type": "platinum", //修改这里
    "issue_date_in_millis": 1594598400000,
    "expiry_date_in_millis": 2524579200999, //修改这里
    "max_nodes": 100,
    "issued_to": "Yun Ma (alibaba)",
    "issuer": "Web Form",
    "signature": "AAAAAwAAAA2OlDvwgEit+SgvmIMdAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxaktJRVl5MUYvUWh3bHZVUTllbXNPbzBUemtnbWpBbmlWRmRZb25KNFlBR2x0TXc2K2p1Y1VtMG1UQU9TRGZVSGRwaEJGUjE3bXd3LzRqZ05iLzRteWFNekdxRGpIYlFwYkJdadadvcvTVlJKNVlXekMrSlVUdFIvV0FNeWdOYnlESDc3MWhlY3hSQmdKSjJ2ZTcvYlBFOHhPQlV3ZHdDQ0tHcG5uOElCaDJ4K1hob29xSG85N0kvTWV3THhlQk9NL01VMFRjNDZpZEVXeUtUMXIyMlIveFpJUkk2WUdveEZaME9XWitGUi9WNTZVQW1FMG1DenhZU0ZmeXlZakVEMjZFT2NvOWxpZGlqVmlHNC8rWVVUYzMwRGVySHpIdURzKzFiRDl4TmM1TUp2VTBOUlJZUlAyV0ZVL2kvVk10L0NsbXNFYVZwT3NSU082dFNNa2prQ0ZsclZ4NTltbU1CVE5lR09Bck93V2J1Y3c9PQAAAQAiHgOdr6bXoO1mENpZuipAKKjoMyW2cAT0DD8FQ2fotYibJO2rK4JX4e4Ce4yO/g5lv6/DgNt95qN2m9c2NpZlv3Qu0wg3lovrnAzstX3IddpnIvoDOIOTDULFLBNL5+jENUVZ+OtKewXUqldPKQWA4v2a4UjQ8TKV6dwxYNMz55Ml8y0XU9mK/DoRCsXUwDFsOdR+bUHOZsTMA1EUgosIykxo5L8E7bYgMIuW8IirRB50DmtzUxCe5eX+SoarOIHVKQica/YHXETD0dzGRhHR7AOm3AMoHnXcg652dNvKVbyiaSXLaTwy2NuHKxmRR9L/fcPgA/xf2+pCXzTMfgjm",
    "start_date_in_millis": 1594598400000
  }
}

修改完成后将这个文件通过`kibana`上传上去即可。
elasticsearch

赞(0) 打赏
未经允许不得转载:码农志 » ElasticSearch 7.8.0 破解

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏