破解x-pack 6.7.2,并且更新许可证(License)

要使用elasticsearch的SQL功能,大概思路是这样的:

找到es中的x-pack-core-6.7.2.jar
解压x-pack-core-6.7.2
反编译x-pack-core-6.7.2
修改证书验证类LicenseVerifier和XPackBuild
然后重新编译
替换旧的x-pack-core-6.7.2
此时elasticsearch失去了验证功能,缺的只有是一个铂金证书
去官网申请一个basic证书
修改证书为为platinum证书(铂金版)
将证书上传到elasticsearch(服务已开启)

步骤一:破解x-pack-core-6.7.2

下载 elasticsearch 下载页面:https://www.elastic.co/downloads/elasticsearch

下载下来,解压压缩包,x-pack-core-6.7.2.jar 位于 elasticsearch-6.7.2/modules/x-pack-core 目录下面

使用luyten反编译x-pack-core-6.7.2.jar

下载 luyten
下载页面:https://github.com/deathmarine/Luyten/releases

软件下载下来,打开软件,把x-pack-core-6.7.2.jar 丢进去,就能看到我们jar包的源代码了。
我们需要把2个文件提取出来进行修改。
org.elasticsearch.license.LicenseVerifier 和 org.elasticsearch.xpack.core.XPackBuild

1、修改LicenseVerifier LicenseVerifier 中有两个静态方法,这就是验证授权文件是否有效的方法,我们把它修改为全部返回true.

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);
            return true;
        }
        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;
    }
}

2、修改XPackBuild XPackBuild 中最后一个静态代码块中 try的部分全部删除,这部分会验证jar包是否被修改.

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);
    }
}

编译修改后的java文件放在elasticsearch-6.7.2目录下
javac -cp “.:./modules/x-pack-core/x-pack-core-6.7.2.jar:./lib/” LicenseVerifier.java javac -cp “.:./modules/x-pack-core/x-pack-core-6.7.2.jar:./lib/” XPackBuild.java

需要注意的是,编译这两个文件的时候 需要指定依赖包的位置,注意修改。
将编译好的class文件重新压回x-pack-core-6.7.2.jar 解压x-pack-core-6.7.2.jar 会得到一个 x-pack-core-6.7.2目录,
按照其位置将编译好的2个class文件放到我们目录里面,替换老的。

可以采用7-zip更新即可
直接用命令也可以

[unjar] jar -xvf x-pack-core-6.7.2.jar
[jar] jar cf x-pack-core-6.7.2.jar *

导入授权文件
1、 先从官网申请basic授权文件 https://license.elastic.co/registration 注意邮箱要正确,地区写中国,保证能收到邮件,然后从邮箱里面的链接获取basic证书 2、 授权文件修改 原始证书:

{
"license": {
"uid": "9f9443d7-f48f-4141-a7df-551dd7868e0d",
"type": "basic",
"issue_date_in_millis": 1536105600000,
"expiry_date_in_millis": 1567727999999,
"max_nodes": 100,
"issued_to": "Li Si (MYHONE)",
"issuer": "Web Form",
"signature": "AAAAAwAAAA2OamcbwjbOtF7/y1QJAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxaktJRVl5MUYvUWh3bHZVUTllbXNPbzBUemtnbWpBbmlWRmRZb25KNFlBR2x0TXc2K2p1Y1VtMG1UQU9TRGZVSGRwaEJGUjE3bXd3LzRqZ05iLzRteWFNekdxRGpIYlFwYkJiNUs0U1hTVlJKNVlXekMrSlVUdFIvV0FNeWdOYnlESDc3MWhlY3hSQmdKSjJ2ZTcvYlBFOHhPQlV3ZHdDQ0tHcG5uOElCaDJ4K1hob29xSG85N0kvTWV3THhlQk9NL01VMFRjNDZpZEVXeUtUMXIyMlIveFpJUkk2WUdveEZaME9XWitGUi9WNTZVQW1FMG1XXXXlZ4NTltbU1CVE5lR09Bck93V2J1Y3c9PQAAAQBAXDSpRK5vJaJ4DduuK35/flhEXes5cCAKJ40rIkR0kDx9Nd5ZaiIxiEXQLbpT2ZG5H6znytn1/BITYvP9pOZsDgZBK7hL32UPC4j8Lar05A009NDIX8Tp0bhHT0iFB4dvYGmE3eZpgAoKD5FvRRsM9YuS3bUyMhVJwCdJqi2g6GfD2MTywEXSj+2CNMv5gUCMa2CM2x2Z+iIx+FbbpSpnsk4F3jqr+U83i1Fpkitv+ZSSSOD6yWc692MHFUBVGnTDW5vkxp+gMK6RK30kvZvmobOjqUvgaXbBPav7DEW1EGpfgXsdsMbZ6ZzvmF28tPUHpZxb4jUbHDjHRCggNXXB",
"start_date_in_millis": 1536105600000
}
}

时间戳、时间转换工具:https://tool.lu/timestamp
修改expiry_date_in_millis(到期日期,我写的2050年)后的证书:
platinum表示白金版,可以使用所有功能

{
"license": {
"uid": "9f9443d7-f48f-4141-a7df-551dd7868e0d",
"type": "platinum", # 修改授权为白金版本
"issue_date_in_millis": 1536105600000,
"expiry_date_in_millis": 2546011910000, # 修改到期时间
"start_date_in_millis": 1536105600000,
"max_nodes": 100,
"issued_to": "Li Si (MYHONE)",
"issuer": "Web Form",
"signature": "AAAAAwAAAA2OamcbwjbOtF7/y1QJAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxaktJRVl5MUYvUWh3bHZVUTllbXNPbzBUemtnbWpBbmlWRmRZb25KNFlBR2x0TXc2K2p1Y1VtMG1UQU9TRGZVSGRwaEJGUjE3bXd3LzRqZ05iLzRteWFNekdxRGpIYlFwYkJiNUs0U1hTVlJKNVlXekMrSlVUdFIvV0FNeWdOYnlESDc3MWhlY3hSQmdKSjJ2ZTcvYlBFOHhPQlV3ZHdDQ0tHcG5uOElCaDJ4K1hob29xSG85N0kvTWV3THhlQk9NL01VMFRjNDZpZEVXeUtUMXIyMlIveFpJUkk2WUdveEZaME9XWitGUi9WNTZVQW1FMG1XXXXlZ4NTltbU1CVE5lR09Bck93V2J1Y3c9PQAAAQBAXDSpRK5vJaJ4DduuK35/flhEXes5cCAKJ40rIkR0kDx9Nd5ZaiIxiEXQLbpT2ZG5H6znytn1/BITYvP9pOZsDgZBK7hL32UPC4j8Lar05A009NDIX8Tp0bhHT0iFB4dvYGmE3eZpgAoKD5FvRRsM9YuS3bUyMhVJwCdJqi2g6GfD2MTywEXSj+2CNMv5gUCMa2CM2x2Z+iIx+FbbpSpnsk4F3jqr+U83i1Fpkitv+ZSSSOD6yWc692MHFUBVGnTDW5vkxp+gMK6RK30kvZvmobOjqUvgaXbBPav7DEW1EGpfgXsdsMbZ6ZzvmF28tPUHpZxb4jUbHDjHRCggNXXB",
}
}

3.上传证书到elasticSearch
注意:这里你可能上传失败,碰到:Cannot install a [PLATINUM] license unless TLS is configured or security is disabled,
需要去修改elasticsearch.yml,在最后加上

xpack.security.enabled: false

记得在上传证书的过程之前保证开启elasticsearch服务可以通过API接口上传

curl -H "Content-Type: application/json" -XPUT "http://172.16.1.160:9200/_xpack/license?acknowledge=true" -d @license.json

4.查看证书状态

curl -H "Content-Type: application/json" -XGET "http://172.16.1.160:9200/_license"

这里是修改好的
http://gating.site/wp-content/uploads/2019/06/elasticsearch-6.7.2.zip

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在NoSQL分类目录。将固定链接加入收藏夹。