From 8ab7a2bec479ad2db5214d15a912b8ebefef2883 Mon Sep 17 00:00:00 2001 From: pyro Date: Wed, 19 Aug 2026 16:56:27 -0500 Subject: [PATCH] added a module to copy the command to run a portscan for the scope, and added the ability to add new configs to separate projects, like work vs personal. Also added a way to switch between these configs. --- Cargo.lock | 405 ++++++++------- Cargo.toml | 2 + .../cobalt_strike_portscan/config.conf | 5 + .../cobalt_strike_portscan/help.txt | 1 + .../cobalt_strike_portscan/script.rhai | 22 + src/funcs.rs | 65 ++- src/install.rs | 1 + src/lib.rs | 484 ++++++++++++++---- src/main.rs | 25 +- src/victim.rs | 40 ++ 10 files changed, 759 insertions(+), 291 deletions(-) create mode 100644 default-modules/cobalt_strike_portscan/config.conf create mode 100644 default-modules/cobalt_strike_portscan/help.txt create mode 100644 default-modules/cobalt_strike_portscan/script.rhai diff --git a/Cargo.lock b/Cargo.lock index d5e71bd..fdf9228 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aead" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" +dependencies = [ + "crypto-common 0.2.2", + "inout 0.2.2", +] + [[package]] name = "aes" version = "0.8.4" @@ -9,10 +19,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] +[[package]] +name = "aes" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8eb277bec05f56a0e0591f155a484cbd0f4f07ff2905051a48c72f004f7ed58" +dependencies = [ + "cipher 0.5.2", + "cpubits", + "cpufeatures 0.3.0", +] + +[[package]] +name = "aes-gcm" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf011db2e21ce0d575593d749db5554b47fed37aff429e4dc50bc91ac93a028" +dependencies = [ + "aead", + "aes 0.9.2", + "cipher 0.5.2", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.8.12" @@ -365,6 +400,12 @@ version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -374,6 +415,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -435,7 +485,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher", + "cipher 0.4.4", ] [[package]] @@ -479,8 +529,19 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", - "inout", + "crypto-common 0.1.7", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" +dependencies = [ + "block-buffer 0.12.1", + "crypto-common 0.2.2", + "inout 0.2.2", ] [[package]] @@ -523,6 +584,28 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "clipboard" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" +dependencies = [ + "clipboard-win", + "objc", + "objc-foundation", + "objc_id", + "x11-clipboard", +] + +[[package]] +name = "clipboard-win" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" +dependencies = [ + "winapi", +] + [[package]] name = "cmake" version = "0.1.58" @@ -532,6 +615,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "colorchoice" version = "1.0.5" @@ -606,6 +695,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -692,6 +787,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "getrandom 0.4.3", + "hybrid-array", + "rand_core 0.10.1", +] + [[package]] name = "csscolorparser" version = "0.6.2" @@ -702,6 +808,24 @@ dependencies = [ "phf", ] +[[package]] +name = "ctr" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" +dependencies = [ + "cipher 0.5.2", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "darling" version = "0.23.0" @@ -799,8 +923,8 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", "subtle", ] @@ -970,12 +1094,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foldhash" version = "0.2.0" @@ -1078,25 +1196,23 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", ] [[package]] -name = "hashbrown" -version = "0.15.5" +name = "ghash" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" dependencies = [ - "foldhash 0.1.5", + "polyval", ] [[package]] @@ -1107,7 +1223,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", - "foldhash 0.2.0", + "foldhash", ] [[package]] @@ -1153,10 +1269,13 @@ dependencies = [ ] [[package]] -name = "id-arena" -version = "2.3.0" +name = "hybrid-array" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "typenum", +] [[package]] name = "ident_case" @@ -1172,8 +1291,6 @@ checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", "hashbrown 0.17.1", - "serde", - "serde_core", ] [[package]] @@ -1195,6 +1312,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "hybrid-array", +] + [[package]] name = "instability" version = "0.3.12" @@ -1301,12 +1427,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" version = "0.2.186" @@ -1368,6 +1488,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.8.1" @@ -1546,6 +1675,26 @@ dependencies = [ "libc", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc2" version = "0.6.4" @@ -1603,6 +1752,15 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "oid-registry" version = "0.8.1" @@ -1817,6 +1975,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "polyval" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0fa31d631f2b2cb2a544d0aa321ce847a94764d701ca2becc411138b93d49cd" +dependencies = [ + "cpubits", + "cpufeatures 0.3.0", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -1829,16 +1998,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -1894,7 +2053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2227,7 +2386,7 @@ version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a62d7f86047af0077255a29494136b9aaaf697c76ff70b8e49cded4e2623c14" dependencies = [ - "aes", + "aes 0.8.4", "cbc", "futures-util", "generic-array", @@ -2531,7 +2690,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -2604,8 +2763,10 @@ dependencies = [ name = "tetanus" version = "0.1.0" dependencies = [ + "aes-gcm", "anyhow", "clap", + "clipboard", "crossterm", "fs_extra", "ipnet", @@ -2885,10 +3046,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] -name = "unicode-xid" -version = "0.2.6" +name = "universal-hash" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" +dependencies = [ + "crypto-common 0.2.2", + "ctutils", +] [[package]] name = "untrusted" @@ -2909,7 +3074,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" dependencies = [ "atomic", - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -2952,16 +3117,7 @@ version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] @@ -3009,40 +3165,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.12.1", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-time" version = "1.1.0" @@ -3370,15 +3492,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" @@ -3386,82 +3499,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] -name = "wit-bindgen-core" -version = "0.51.0" +name = "x11-clipboard" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.12.1", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", + "xcb", ] [[package]] @@ -3482,6 +3525,16 @@ dependencies = [ "time", ] +[[package]] +name = "xcb" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" +dependencies = [ + "libc", + "log", +] + [[package]] name = "yasna" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index 109838e..358a108 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,10 @@ version = "0.1.0" edition = "2024" [dependencies] +aes-gcm = "0.11.0" anyhow = "1.0.103" clap = { version = "4.6.1", features = ["derive"] } +clipboard = "0.5.0" crossterm = "0.29.0" fs_extra = "1.3.0" ipnet = "2.12.0" diff --git a/default-modules/cobalt_strike_portscan/config.conf b/default-modules/cobalt_strike_portscan/config.conf new file mode 100644 index 0000000..591f1e2 --- /dev/null +++ b/default-modules/cobalt_strike_portscan/config.conf @@ -0,0 +1,5 @@ +name: csps +output_type: String, +new_thread: false +args: project +calls: clipboard diff --git a/default-modules/cobalt_strike_portscan/help.txt b/default-modules/cobalt_strike_portscan/help.txt new file mode 100644 index 0000000..09e70ca --- /dev/null +++ b/default-modules/cobalt_strike_portscan/help.txt @@ -0,0 +1 @@ +Parse the scope file in your notes and print the cobalt strike portscan command to run. diff --git a/default-modules/cobalt_strike_portscan/script.rhai b/default-modules/cobalt_strike_portscan/script.rhai new file mode 100644 index 0000000..d01c927 --- /dev/null +++ b/default-modules/cobalt_strike_portscan/script.rhai @@ -0,0 +1,22 @@ +let ips = []; +let scope_path = find_file(project.notes, "scope"); +let scope_text = open_file(scope_path); +for line in scope_text.split("\n"){ + if line.contains("|") && !line.contains("//"){ + let cols = line.split("|"); + let data = cols[1]; + if data.len() > 0{ + for host in filter_ips(data){ + ips.push(host); + } + } + } +} + +let target_string = ""; +for ip in ips{ + target_string = target_string + "," + ip; +} + +let out_string = "portscan " + target_string + " 1-1024,1433,2222,3306,3389,5000-6000,8000,8080,8443 icmp 512"; +return out_string; diff --git a/src/funcs.rs b/src/funcs.rs index e24a567..65c394f 100644 --- a/src/funcs.rs +++ b/src/funcs.rs @@ -9,12 +9,12 @@ use ratatui::{ prelude::*, widgets::{Block, Borders, List, ListItem, ListState, Paragraph}, }; -use std::thread::sleep; use std::thread::spawn; +use std::thread::{JoinHandle, sleep}; use std::time::Duration; use std::{error::Error, time::Instant}; use std::{io::Write, usize}; -use sysinfo::{MemoryRefreshKind, System}; +use sysinfo::System; pub fn get_user_input(prompt: &str) -> Result> { println!("{}", prompt); @@ -23,9 +23,51 @@ pub fn get_user_input(prompt: &str) -> Result> { return Ok(response.trim().to_string()); } +pub fn startup( + mut state: AppState, + nested: bool, + handles: Arc>>>, +) -> Result<(), Box> { + let mut app = AppState::new(); + let (tx, rx) = channel(); + app.main_tx = tx.clone(); + if let Some(line) = state.config.get("alternate_configs") { + let mut selections = HashMap::new(); + line.split(",").into_iter().for_each(|line| { + if let Some((name, path)) = line.split_once("|") { + selections.insert(name.to_string(), path.to_string()); + println!("{} | {} ", name, path); + } + }); + selections.insert( + "default".to_string(), + state.config_file.display().to_string(), + ); + println!("default | {}", state.config_file.display()); + let response = get_user_input("which config would you like to load?")?; + if let Some(path) = selections.get(&response) { + app.load_config(PathBuf::from(path), true)?; + run_tui(app, rx, handles.clone())?; + } else { + eprintln!("error invalid selection! exiting..."); + return Err("invalid config selected.".into()); + } + } else { + app.load_config(state.config_file.clone(), true)?; + run_tui(app, rx, handles.clone())?; + } + if nested { + let (tx, rx) = channel(); + state.main_tx = tx; + run_tui(state, rx, handles.clone())?; + } + Ok(()) +} + pub fn run_tui( mut state: AppState, main_rx: Receiver, + main_handles: Arc>>>, ) -> Result<(), Box> { enable_raw_mode()?; let mut stdout = io::stdout(); @@ -43,6 +85,7 @@ pub fn run_tui( let mut system = System::new_all(); let system_timer = Duration::from_secs(1); let mut last_print = Instant::now(); + let mut switch_config = false; const BYTES_PER_GB: u64 = 1024 * 1024 * 1024; if !state.projects.is_empty() { project_list_state.select(Some(0)); @@ -87,6 +130,7 @@ pub fn run_tui( let mut history_index = state.history.len(); let mut handles = Vec::new(); loop { + if switch_config {} if Instant::now().duration_since(last_print) > system_timer { system.refresh_cpu_usage(); system.refresh_memory(); @@ -556,7 +600,10 @@ pub fn run_tui( .send(ToolMessage::Output((0, "\n".to_string()))); let prompt = state.prompt.clone(); if prompt.action.is_some() { - state.prompt.responses.push(trimmed.clone()); + state.prompt.responses.push(PromptResponse { + query: prompt.last_prompted.clone().unwrap(), + response: trimmed.clone(), + }); if state.prompt.responses.len() == state.prompt.num_responses { state.execute_command( prompt.execute_command.as_str(), @@ -604,6 +651,10 @@ pub fn run_tui( ); } } + "switch_config" => { + switch_config = true; + break; + } command_name => { if state.module_loader.commands.contains_key(command) { let _ = state.main_tx.send(ToolMessage::Output(( @@ -756,5 +807,13 @@ pub fn run_tui( for handle in handles { handle.join().unwrap(); } + if switch_config { + let handles_clone = main_handles.clone(); + if let Ok(mut lock) = main_handles.lock() { + lock.push(spawn(move || { + let _ = startup(state, true, handles_clone); + })); + } + } Ok(()) } diff --git a/src/install.rs b/src/install.rs index a467827..75e2998 100644 --- a/src/install.rs +++ b/src/install.rs @@ -97,6 +97,7 @@ pub fn client_install() -> Result<(), Box> { client_config_file.write(format!("template_box: {}\n", template_box).as_bytes())?; client_config_file.write(format!("term_cmd: {}\n", term_cmd).as_bytes())?; client_config_file.write(format!("tools: {}\n", tools_folder).as_bytes())?; + client_config_file.write("alternate_configs: \n".as_bytes())?; println!("\ndefault config files written!"); println!("downloading note templates, victim templates, and modules..."); create_dir_all("./temp")?; diff --git a/src/lib.rs b/src/lib.rs index e0179d8..d559766 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +use clipboard::ClipboardContext; +use clipboard::ClipboardProvider; use fs_extra::dir::{CopyOptions, copy}; use ipnet::IpNet; use keyring::Entry; @@ -5,6 +7,7 @@ use ratatui::crossterm::event; use rhai::{AST, Dynamic, Engine, Scope}; use rustls::{ClientConfig, ClientConnection, RootCertStore, StreamOwned, pki_types::ServerName}; use std::collections::HashMap; +use std::env; use std::error::Error; use std::fs::{self, File, create_dir_all, read_dir, read_to_string, remove_dir, remove_dir_all}; use std::io::{self, BufRead, BufReader, Read, Write}; @@ -94,48 +97,46 @@ pub struct AppState { } impl AppState { - pub fn new() -> (Self, Receiver) { - let (main_tx, main_rx) = channel(); - ( - Self { - projects: Vec::new(), - servers: Vec::new(), - config: HashMap::new(), - config_file: PathBuf::new(), - workers: rayon::ThreadPoolBuilder::new() - .num_threads(4) - .build() - .unwrap(), - worker_txes: Vec::new(), - main_tx, - history: Vec::new(), - log: Vec::new(), - output: Vec::new(), - selected_server: 0, - selected_project: 0, - curent_intput: String::new(), - module_loader: ModuleLoader::new(), - output_scroll: 0, - output_follow: true, - prompt: Prompt { - action: None, - responses: Vec::new(), - execute_command: String::new(), - num_responses: 0, - prompts: Vec::new(), - }, - info_scroll: 0, - server_broker_running: true, - app_state_running: true, - remoting: false, - help: Vec::new(), - name: String::new(), + pub fn new() -> Self { + let (main_tx, _) = channel(); + Self { + projects: Vec::new(), + servers: Vec::new(), + config: HashMap::new(), + config_file: PathBuf::new(), + workers: rayon::ThreadPoolBuilder::new() + .num_threads(4) + .build() + .unwrap(), + worker_txes: Vec::new(), + main_tx, + history: Vec::new(), + log: Vec::new(), + output: Vec::new(), + selected_server: 0, + selected_project: 0, + curent_intput: String::new(), + module_loader: ModuleLoader::new(), + output_scroll: 0, + output_follow: true, + prompt: Prompt { + action: None, + responses: Vec::new(), + execute_command: String::new(), + num_responses: 0, + prompts: Vec::new(), + last_prompted: None, }, - main_rx, - ) + info_scroll: 0, + server_broker_running: true, + app_state_running: true, + remoting: false, + help: Vec::new(), + name: String::new(), + } } - pub fn load_config(&mut self, file: PathBuf) -> Result<(), Box> { + pub fn load_config(&mut self, file: PathBuf, display: bool) -> Result<(), Box> { self.config_file = file.clone(); let config_contents = read_to_string(file)?; for line in config_contents.lines() { @@ -187,7 +188,7 @@ impl AppState { if conf_file.file_name().to_string_lossy() == "project.conf".to_string() { let mut new_project = Project::new(); new_project.config_folder(conf_file.path()); - new_project.load_config()?; + new_project.load_config(display)?; let template_box = self.config.get("template_box").unwrap(); let tools = self.config.get("tools").unwrap(); let db = DistroBox { @@ -242,6 +243,7 @@ impl AppState { ); self.help.push("parse_scope\nparse the projects general.md notes file for the scope copied from the workbook\n".to_string()); self.help.push("exit\nquit the tool\n".to_string()); + self.initialize_modules(); return Ok(()); } @@ -427,10 +429,12 @@ impl AppState { } } "remove_project_confirm" => { - self.prompt.action = None; - self.prompt.num_responses = 0; if self.prompt.responses.len() > 0 { - if self.prompt.responses[0] == "y".to_string() { + if self.prompt.responses[0] + .response + .to_lowercase() + .contains("y") + { let project = self.projects[self.selected_project].clone(); let mut config_file = project.config_folder.clone(); config_file.pop(); @@ -507,14 +511,17 @@ impl AppState { self.prompt.action = Some(ToolMessage::RemoveProject); self.prompt.num_responses = 1; self.prompt.execute_command = String::from("remove_project_confirm"); - let _ = self.main_tx.send(ToolMessage::Output(( - rid, - format!( - "{}, {} and all contents will be deleted. Continue? (y/N)", + self.prompt.prompts.push(PromptQuery { + id: 0, + query: format!( + "{}, {} and all contentes wil lbe deleted. Contineue? (y/N", project.files.display(), project.notes.display() ), - ))); + }); + let _ = self + .main_tx + .send(ToolMessage::Input((rid, "prompt".to_string()))); } "new_terminal" | "nt" => { let project = self.projects[self.selected_project].clone(); @@ -528,17 +535,30 @@ impl AppState { self.prompt.num_responses = 2; self.prompt.action = Some(ToolMessage::AddServer); self.prompt.execute_command = String::from("add_server"); - self.prompt.prompts = vec![ - "What is the IP for the server?".to_string(), - "What is the port for the server?".to_string(), - ]; + self.prompt.prompts.push(PromptQuery { + id: 0, + query: "What is the IP of the server?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 1, + query: "What is the port for the server?".to_string(), + }); let _ = self .main_tx .send(ToolMessage::Input((0, "prompt".to_string()))); } "add_server" => { + let mut ip = String::new(); + let mut port = String::new(); + self.prompt.responses.iter().for_each(|res| { + if res.query.id == 0 { + ip = res.response.clone(); + } else if res.query.id == 1 { + port = res.response.clone(); + } + }); let new_server = Server { - address: format!("{}:{}", self.prompt.responses[0], self.prompt.responses[1]), + address: format!("{}:{}", ip, port), connected: false, timer: Duration::from_secs(5), last_check: time::Instant::now(), @@ -565,12 +585,20 @@ impl AppState { .send(ToolMessage::Input((0, self.prompt.execute_command.clone()))); let _ = self.main_tx.send(ToolMessage::EndPrompt); } else { - let mut prompt_index = 0; - if self.prompt.responses.len() > 0 { - prompt_index = self.prompt.num_responses - self.prompt.responses.len(); + for query in &self.prompt.prompts { + if !self + .prompt + .responses + .iter() + .any(|res| res.query.id == query.id) + { + self.prompt.last_prompted = Some(query.clone()); + let _ = self + .main_tx + .send(ToolMessage::Output((rid, query.query.clone()))); + break; + } } - let query = self.prompt.prompts[prompt_index].clone(); - let _ = self.main_tx.send(ToolMessage::Output((rid, query))); } } "list_servers" => { @@ -614,7 +642,10 @@ impl AppState { "select_server" => { self.prompt.action = Some(ToolMessage::SelectServer); self.prompt.num_responses = 1; - self.prompt.prompts.push(String::from("Selection?")); + self.prompt.prompts.push(PromptQuery { + id: 0, + query: String::from("Selection?"), + }); self.prompt.execute_command = String::from("server_selected"); self.servers.iter().enumerate().for_each(|(id, servermut)| { if let Ok(server) = servermut.lock() { @@ -634,7 +665,7 @@ impl AppState { } "server_selected" => { if self.prompt.responses.len() == 1 { - if let Ok(id) = self.prompt.responses[0].parse::() { + if let Ok(id) = self.prompt.responses[0].response.parse::() { self.selected_server = id; if let Ok(server) = self.servers[id].lock() { let _ = self.main_tx.send(ToolMessage::Output(( @@ -855,6 +886,67 @@ impl AppState { } } } + "new_config" => { + self.prompt.num_responses = 8; + self.prompt.action = Some(ToolMessage::Input((0, "add_config".to_string()))); + self.prompt.execute_command = String::from("add_config"); + self.prompt.prompts.push(PromptQuery { + id: 0, + query: "name for the new config?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 1, + query: "Path to save the config folder?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 2, + query: "Path for upcoming project files (not notes)?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 3, + query: "Path for current project files (not notes)?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 4, + query: "Path for upcoming notes?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 5, + query: "Path for current notes?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 6, + query: "Path to tool directory?".to_string(), + }); + self.prompt.prompts.push(PromptQuery { + id: 7, + query: "Template box name?".to_string(), + }); + let _ = self + .main_tx + .send(ToolMessage::Input((0, "prompt".to_string()))); + } + "add_config" => { + self.prompt.responses.iter().for_each(|res| { + let _ = self.main_tx.send(ToolMessage::Output(( + rid, + format!("{} | {}", res.query.query, res.response), + ))); + }); + self.new_config()?; + self.save_config()?; + } + "list_configs" => { + if let Some(config_line) = self.config.get("alternate_configs") { + config_line.split(",").into_iter().for_each(|entry| { + if let Some((name, path)) = entry.split_once("|") { + let _ = self + .main_tx + .send(ToolMessage::Output((rid, format!("{}: {}", name, path)))); + } + }); + } + } "exit" => { self.save_all()?; let _ = self.main_tx.send(ToolMessage::AppStateExit); @@ -938,7 +1030,11 @@ impl AppState { let out_string = result .into_string() .unwrap_or_else(|_| "failed to parse string".into()); - if cmd_meta.calls != "none" { + if cmd_meta.calls == "clipboard" { + let mut ctx: ClipboardContext = + ClipboardProvider::new().unwrap(); + ctx.set_contents(out_string.clone()).unwrap(); + } else if cmd_meta.calls != "none" { let _ = worker_tx.send(ToolMessage::Input((0, out_string.clone()))); } @@ -1173,50 +1269,193 @@ impl AppState { return Ok(()); } - pub fn new_server(&mut self, rid: usize) -> Result<(), Box> { - let prompt = self.prompt.clone(); - if prompt.responses.len() == prompt.num_responses { - let new_server = Server { - address: format!( - "{}:{}", - self.prompt.responses[0].clone(), - self.prompt.responses[1].clone() - ), - connected: false, - timer: Duration::from_secs(60), - last_check: time::Instant::now(), - message_que: Vec::new(), - action_que: Vec::new(), - client_id: 0, - selected_client: 0, - config: None, - logged_in: false, - password: String::new(), - name: String::new(), - cert_text: String::new(), - }; - self.servers.push(Arc::new(Mutex::new(new_server))); - self.prompt.action = None; - self.prompt.responses.clear(); - self.prompt.num_responses = 0; - return Ok(()); - } else { - match prompt.responses.len() { - 0 => { - let _ = self.main_tx.send(ToolMessage::Output(( - rid, - String::from("What is the IP for the server?"), - ))); - } - 1 => { - let _ = self.main_tx.send(ToolMessage::Output(( - rid, - String::from("What is the port for the server?"), - ))); - } + pub fn new_server(&mut self) -> Result<(), Box> { + let mut ip = String::new(); + let mut port = String::new(); + self.prompt.responses.iter().for_each(|res| { + if res.query.id == 0 { + ip = res.response.clone(); + } else if res.query.id == 1 { + port = res.response.clone(); + } + }); + let new_server = Server { + address: format!("{}:{}", ip, port), + connected: false, + timer: Duration::from_secs(60), + last_check: time::Instant::now(), + message_que: Vec::new(), + action_que: Vec::new(), + client_id: 0, + selected_client: 0, + config: None, + logged_in: false, + password: String::new(), + name: String::new(), + cert_text: String::new(), + }; + self.servers.push(Arc::new(Mutex::new(new_server))); + self.prompt.reset(); + Ok(()) + } + + pub fn new_config(&mut self) -> Result<(), Box> { + let mut name = String::new(); + let mut config_path = PathBuf::new(); + let mut upcoming_files_path = PathBuf::new(); + let mut current_files_path = PathBuf::new(); + let mut upcoming_notes_path = PathBuf::new(); + let mut current_notes_path = PathBuf::new(); + let mut tools_folder = PathBuf::new(); + let mut template_box = String::new(); + let term_cmd = self.config.get("term_cmd").unwrap().clone(); + self.prompt + .responses + .iter() + .for_each(|res| match res.query.id { + 0 => name = res.response.clone(), + 1 => config_path = PathBuf::from(res.response.clone()), + 2 => upcoming_files_path = PathBuf::from(res.response.clone()), + 3 => current_files_path = PathBuf::from(res.response.clone()), + 4 => upcoming_notes_path = PathBuf::from(res.response.clone()), + 5 => current_notes_path = PathBuf::from(res.response.clone()), + 6 => tools_folder = PathBuf::from(res.response.clone()), + 7 => template_box = res.response.clone(), _ => {} + }); + let mut existing = false; + if let Some(line) = self.config.get("alternate_configs") { + line.split(",").into_iter().for_each(|line| { + if let Some((ename, _)) = line.split_once("|") { + if ename.trim().to_string() == name { + existing = true; + } + } + }); + } + if existing { + let _ = self.main_tx.send(ToolMessage::Output(( + 0, + format!("{} already exists!", name), + ))); + return Ok(()); + } + let root_config_folder_path = config_path.clone(); + let mut projects_path = config_path.clone(); + projects_path.push("projects"); + let mut module_path = config_path.clone(); + module_path.push("modules"); + let mut note_templates_path = config_path.clone(); + note_templates_path.push("note_templates"); + create_dir_all(&module_path)?; + config_path.push("client.conf"); + let client_conf_path = config_path.clone(); + projects_path.push("default"); + match create_dir_all(&projects_path) { + Ok(_) => { + let _ = self.main_tx.send(ToolMessage::Output(( + 0, + format!( + "[success] create projects path at {}", + projects_path.display() + ), + ))); + } + Err(e) => { + let _ = self.main_tx.send(ToolMessage::Output(( + 0, + format!( + "[error] couldn't create projects path at {}: {e}", + projects_path.display() + ), + ))); + return Ok(()); } } + projects_path.push("project.conf"); + let mut client_config_file = File::create(&config_path)?; + client_config_file.write(format!("projects: {}\n", projects_path.display()).as_bytes())?; + client_config_file.write("servers: 127.0.0.1:31337\n".as_bytes())?; + let mut default_project_file = File::create(projects_path)?; + config_path.pop(); + let mut server_path = config_path.clone(); + server_path.push("server"); + create_dir_all(&server_path)?; + server_path.push("server.conf"); + let mut server_config_file = File::create(&server_path)?; + server_config_file.write("address: 127.0.0.1:31337\n".as_bytes())?; + server_config_file.write("running: false\n".as_bytes())?; + default_project_file.write("org_name: default\n".as_bytes())?; + default_project_file.write("name: default\n".as_bytes())?; + default_project_file + .write(format!("notes: {}\n", current_files_path.display()).as_bytes())?; + default_project_file + .write(format!("files: {}\n", current_notes_path.display()).as_bytes())?; + default_project_file.write("stage: current".as_bytes())?; + client_config_file + .write(format!("current_files: {}\n", current_files_path.display()).as_bytes())?; + client_config_file + .write(format!("current_notes: {}\n", current_notes_path.display()).as_bytes())?; + client_config_file + .write(format!("upcoming_files: {}\n", upcoming_files_path.display()).as_bytes())?; + client_config_file + .write(format!("upcoming_notes: {}\n", upcoming_notes_path.display()).as_bytes())?; + client_config_file.write(format!("module_path: {}\n", module_path.display()).as_bytes())?; + client_config_file.write(format!("template_box: {}\n", template_box).as_bytes())?; + client_config_file.write(format!("term_cmd: {}\n", term_cmd).as_bytes())?; + client_config_file.write(format!("tools: {}\n", tools_folder.display()).as_bytes())?; + create_dir_all("./temp")?; + env::set_current_dir("./temp")?; + let git_clone_output = Command::new("git") + .arg("clone") + .arg("https://git.pyro.monster/pyro/tetanus.git") + .output()?; + let git_clone_status = git_clone_output.status.success(); + if git_clone_status { + let mut options = CopyOptions::new(); + options.overwrite = true; + options.copy_inside = true; + copy( + "./tetanus/note_templates", + root_config_folder_path.clone(), + &options, + )?; + copy( + "./tetanus/default-modules", + module_path.join("default"), + &options, + )?; + copy( + "./tetanus/victim_templates", + root_config_folder_path.join("victim"), + &options, + )?; + env::set_current_dir("../")?; + remove_dir_all("./temp")?; + let _ = self.main_tx.send(ToolMessage::Output(( + 0, + "New config structure created!".to_string(), + ))); + } + if let Some(original_value) = self.config.get("alternate_configs") { + let new_value = format!( + "{}|{},{}", + name, + client_conf_path.display().to_string(), + original_value, + ); + self.config + .insert("alternate_configs".to_string(), new_value); + } else { + self.config.insert( + "alternate_configs".to_string(), + format!("{}|{},", name, client_conf_path.display().to_string()), + ); + } + self.prompt.responses.clear(); + self.prompt.prompts.clear(); + self.prompt.action = None; + self.prompt.execute_command.clear(); Ok(()) } } @@ -1413,7 +1652,7 @@ impl Project { } } - pub fn load_config(&mut self) -> Result<(), Box> { + pub fn load_config(&mut self, display: bool) -> Result<(), Box> { let config_contents = read_to_string(&self.config_folder)?; for line in config_contents.lines() { let parts: Vec<&str> = line.split(": ").collect(); @@ -1438,8 +1677,10 @@ impl Project { } } } - println!("{} | {} config loaded!", self.org_name, self.name); - println!("loading hosts..."); + if display { + println!("{} | {} config loaded!", self.org_name, self.name); + println!("loading hosts..."); + } let mut hosts_folder = self.config_folder.clone(); let mut users_folder = self.config_folder.clone(); hosts_folder.pop(); @@ -1512,7 +1753,9 @@ impl Project { } } } - println!("{} | {} loaded!", self.org_name, self.name); + if display { + println!("{} | {} loaded!", self.org_name, self.name); + } return Ok(()); } @@ -1811,6 +2054,17 @@ impl ModuleLoader { } results }); + engine.register_fn("filter_ips", |s: &str| -> rhai::Array { + let mut results = rhai::Array::new(); + if let Ok(net) = s.trim().parse::() { + results.push(net.addr().to_string().trim().into()); + } else if let Ok(ip) = s.trim().parse::() { + results.push(ip.to_string().trim().into()); + } else if s.contains(".") { + results.push(s.to_string().trim().into()); + } + results + }); engine.register_fn("write_file", |path: &str, contents: &str| { std::fs::write(path, contents).is_ok() }); @@ -2133,10 +2387,11 @@ impl DistroBox { #[derive(Clone)] struct Prompt { action: Option, - responses: Vec, + responses: Vec, execute_command: String, num_responses: usize, - prompts: Vec, + prompts: Vec, + last_prompted: Option, } impl Prompt { @@ -2146,5 +2401,18 @@ impl Prompt { self.execute_command.clear(); self.num_responses = 0; self.prompts.clear(); + self.last_prompted = None; } } + +#[derive(Clone)] +struct PromptResponse { + query: PromptQuery, + response: String, +} + +#[derive(Clone)] +struct PromptQuery { + id: usize, + query: String, +} diff --git a/src/main.rs b/src/main.rs index 4094ac3..69eb179 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ use clap::Parser; use rand::RngExt; use rand::distr::Alphanumeric; +use std::sync::mpsc::channel; use std::sync::{Arc, Mutex}; +use std::thread::{sleep, spawn}; +use std::time::Duration; use std::{env, path::PathBuf, process::exit}; use sysinfo::*; use tetanus::funcs::*; @@ -138,8 +141,8 @@ async fn main() { ); exit(1); } - let (mut appstate, rx) = AppState::new(); - let config_load = appstate.load_config(client_config_path.clone()); + let (mut appstate) = AppState::new(); + let config_load = appstate.load_config(client_config_path.clone(), true); if config_load.is_err() { eprintln!("error loading config!"); exit(1); @@ -148,9 +151,23 @@ async fn main() { banner.lines().for_each(|line| { appstate.output.push(line.to_string()); }); - appstate.initialize_modules(); + let handles = Arc::new(Mutex::new(Vec::new())); + let handles_clone = handles.clone(); println!("entering tui..."); - let _res = run_tui(appstate, rx).unwrap(); + let primary_handle = spawn(move || { + let _ = startup(appstate, false, handles_clone); + }); + if let Ok(mut lock) = handles.lock() { + lock.push(primary_handle); + } + loop { + sleep(Duration::from_secs(3)); + if let Ok(lock) = handles.lock() { + if lock.iter().all(|handle| handle.is_finished()) { + break; + } + } + } } else if args.server { let mut address = "127.0.0.1:31337".to_string(); let mut certificate_path = config_path.clone(); diff --git a/src/victim.rs b/src/victim.rs index 7b22d86..81b5667 100644 --- a/src/victim.rs +++ b/src/victim.rs @@ -1,4 +1,6 @@ use crate::*; +use aes_gcm::{Aes256Gcm, Key, KeyInit, Nonce, aead::Aead}; +use rand::{self, Rng, TryRng}; use rayon::spawn; pub fn generate_code( @@ -46,6 +48,44 @@ pub fn generate_code( return Ok(()); } +/*fn generate_obfuscated_code( + address: String, + password: String, + config_file: PathBuf, + files: PathBuf, + target: String, + tx: Sender, + cert_text: String, +) -> Result<(), Box> { + let mut source_path = config_file.clone(); + source_path.pop(); + source_path.push("victim/src/main.rs"); + let mut source = read_to_string(&source_path)?; + source = source + .replace("|||SERVER|||", &address) + .replace("|||PASSWORD|||", &password) + .replace("|||CERT|||", &cert_text); + files_base.pop(); + files_base.pop(); + files_base.push("Cargo.toml"); + let cargo_string = read_to_string(source_path)?; + let mut files_base = files.clone(); + files_base.push("victim/src"); + create_dir_all(&files_base)?; + files_base.push("main.rs"); + let mut src_file = File::create(&files_base)?; + let mut key = [0u8; 32]; + rand::rng().fill_bytes(&mut key); + let mut iv = [0u8; 16]; + rand::rng().fill_bytes(&mut iv); + let cipher = Aes256Gcm::new_from_slice(&key)?; + let nonce = Nonce::try_from(&iv[..])?; + let mut ciphertext = cipher.encrypt(&nonce, source.as_bytes())?; + + + Ok(()) +}*/ + fn compile_victim(mut cargo_command: Command, tx: Sender) { let mut out = "Error compiling output!".to_string(); if let Ok(output) = cargo_command.output() {