diff --git a/src/tree/SPEC.md b/PROTOCOL.md similarity index 100% rename from src/tree/SPEC.md rename to PROTOCOL.md diff --git a/README-old.md b/README-old.md deleted file mode 100644 index 7a68e4c..0000000 --- a/README-old.md +++ /dev/null @@ -1,2 +0,0 @@ -# unshell -The unified shell and exploitation framework diff --git a/README.md b/README.md new file mode 100644 index 0000000..d274036 --- /dev/null +++ b/README.md @@ -0,0 +1,218 @@ +# unshell + +A fully modular, pluggable framework for building cross-platform endpoint agents that integrate with existing toolsets. + +## Design Goals + +- **100% Modular** - Every component is replaceable at runtime. Nothing is hardcoded. +- **Tool Integration** - Drop in Metasploit payloads, Cobalt Strike beacons, or any external implant +- **Cross-Platform** - Full Rust cross-compilation support for Windows, Linux, macOS, and embedded targets +- **Minimal Footprint** - Compile-time obfuscation and size optimization for stealthy payloads + +## Philosophy + +Nothing is fixed. Every part of the system is a plugin: + +- **Transports** - TCP, HTTP, DNS, WebSocket, custom +- **Protocols** - Encryption, encoding, framing - all swappable +- **Payloads** - Metasploit, Cobalt Strike, custom - just load and run +- **Components** - Any Rust struct can be a module +- **Communication** - Tree-based routing with replaceable backends + +## Architecture + +``` +unshell/ +├── src/tree/ # Hierarchical message routing +│ ├── component.rs # Component trait (implement for any module) +│ ├── endpoint.rs # Endpoint manager +│ ├── protocols/ # Pluggable protocol stack +│ └── tcp/ # Example transport implementations +├── ush-obfuscate/ # Compile-time string obfuscation +└── ush-payload/ # Test harness +``` + +## Core Traits + +Everything plugs into these abstractions: + +### Component - Any Module + +```rust +use unshell::tree::Component; +use serde_json::Value; + +pub trait Component: Send + Sync { + fn name(&self) -> &str; + fn status(&self) -> Value; + fn init(&mut self, config: Value) -> Result<(), String>; + fn shutdown(&mut self) -> Result<(), String>; +} +``` + +### Protocol - Any Encoding Layer + +```rust +use unshell::tree::protocols::Protocol; + +pub trait Protocol: Send + Sync { + fn name(&self) -> &'static str; + fn encode(&self, data: &[u8]) -> Result, ProtocolError>; + fn decode(&self, data: &[u8]) -> Result, ProtocolError>; +} +``` + +### Transport - Any Connection + +```rust +// Transports connect to networks - TCP, HTTP, DNS, custom +// Implement send/recv and register with the transport registry +``` + +### Payload - Any External Implant + +```rust +// External payloads (Metasploit, Cobalt Strike, etc.) load as components +// They expose the same interface as native components +``` + +## Module System + +```rust +use unshell::{ModuleRuntime, Manager}; +use unshell::config::RuntimeConfig; + +// Define a module +pub struct MyModule; + +// Implement runtime lifecycle +impl ModuleRuntime for MyModule { + fn init(&mut self, manager: Arc>) -> Result<()>; + fn is_running(&self) -> bool; + fn kill(self: Box); +} + +// Export via FFI for dynamic loading +#[unsafe(no_mangle)] +pub fn get_components() -> Vec { + vec![NamedComponent { name: "mymodule", ... }] +} +``` + +Load compiled `.so`/`.dll` modules at runtime using `libloading` or in-memory via `memfd_create`. + +## Protocol Stacking + +Layer protocols arbitrarily: + +```rust +let mut stack = ProtocolStack::new(); +stack.push(&ProtocolConfig::Base64(Default::default())).unwrap(); +stack.push(&ProtocolConfig::Http(Default::default())).unwrap(); +stack.push(&ProtocolConfig::Tcp(Default::default())).unwrap(); +``` + +Order determines encoding: app → base64 → http → tcp → network + +## Integration Examples + +### Load a Metasploit Payload + +```rust +// Load precompiled Metasploit .so +let module = Module::new("meterpreter.so")?; +// Or load from raw bytes (in-memory execution) +let module = Module::new_bytes(&meterpreter_bytes)?; +``` + +### Use Cobalt Strike Beacon + +```rust +// Beacon loads as a component with standard interface +let beacon = CobaltBeacon::new(config); +component_registry.register(Box::new(beacon)).unwrap(); +// Communicate via tree messages - same as any other component +``` + +### Custom Transport + +```rust +// Implement Protocol trait +pub struct DnsTransport { ... } +impl Protocol for DnsTransport { + fn encode(&self, data: &[u8]) -> Result, ProtocolError> { + // Encode as DNS TXT records + } + fn decode(&self, data: &[u8]) -> Result, ProtocolError> { + // Decode DNS responses + } +} +// Register and use +stack.push(&ProtocolConfig::Custom { name: "dns", config: ... }); +``` + +## Cross-Compilation + +```bash +# Windows x64 +rustup target add x86_64-pc-windows-gnu +cargo build --target x86_64-pc-windows-gnu + +# ARM64 Linux +rustup target add aarch64-unknown-linux-gnu +cargo build --target aarch64-unknown-linux-gnu + +# macOS +rustup target add x86_64-apple-darwin +cargo build --target x86_64-apple-darwin +``` + +## Building + +```bash +# Standard build (~500KB) +cargo build + +# Size-optimized (~50KB) +cargo build --profile minimize + +# With obfuscation +cargo build --features obfuscate +``` + +## Testing + +```bash +cd ush-payload +cargo run +``` + +## Obfuscation + +Compile-time string obfuscation to evade static analysis: + +```rust +use ush_obfuscate::symbol; + +const API_KEY: &str = symbol!("SuperSecretKey123"); +const C2_URL: &str = symbol!("https://C2Server/endpoint"); +``` + +## Roadmap + +- [ ] Protocol registry for runtime registration +- [ ] Payload loader for common frameworks +- [ ] Transport abstraction layer +- [ ] Hot-swap components at runtime + +## Dependencies + +- `libloading` - Dynamic library loading +- `serde_json` - Serialization +- `crossbeam-channel` - Message passing +- `base64` - Encoding +- `thiserror` - Error handling + +## License + +MIT / Apache-2.0 diff --git a/THINGS.md b/THINGS.md deleted file mode 100644 index c44121b..0000000 --- a/THINGS.md +++ /dev/null @@ -1,42 +0,0 @@ -### Binary -- Obfustcation -- Randomly generated packed binaries -- Rust is already hard to decompile? -- Persistance - - Probably out of scope -- Build targets - - To achieve a minimal size, there should probably be a way to pack diffrent features with the actual result binary. - - There should also be a way to update one of the hosts with the new functionality. - -### Network -- Diffrent traffic obfuscators: - - ICMP - - HTTPS (Using actual webpages) - - OpenVPN (Hard to replicate in rust) -- "Hole Widening" - - Initial reverse shell is the final one - - Minimal presence on remote machine - - Instead of downloading binaries and then executing them, use the shell connection as a kind of remote storage server. -- Pivoting - - UI for sub-connections. - - A protocol that acts similar to routers and DHCP, registering known devices with the C2 server. Sub-devices will relay packets - - Packets must be encrypted, so that only the destination can decrypt. - - How? -- ### Encryption - - Diffrent "encryptors" such as PGP - - Everything must be self-implemented because of traffic monitors such as mitmproxy - - HTTPS could transmit over the actual TLS implemented by the system, and transfer data through things such as base64 images on webpages, which would itself be encrypted - -### UI -- Egui?? - - Usable both on web and on-device -- Network diagram creation tool - -### Tools -- These are the diffrent tools that can be transmitted, and then run on a machine -- Host discovery && port scanning -- File upload and download -- Screenshare -- Virtual browser and desktop -- meterpreter functionality? -- Scripting? diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 55d4c2a..0000000 --- a/TODO.md +++ /dev/null @@ -1,12 +0,0 @@ -### Functionality -- Add 'signals' interface between modules -- Write compilation helper CLI for building payload and breakout module -- Make CLI -- Make GUI - -### Topology -- Move server and client components into their own cargo projects - -### Obfuscation -- Implement custom ELF loading possibly using 'https://github.com/weizhiao/rust-dlopen' -- Macro-based automatic control flow obfuscation