2025-06-06 19:20:49 -06:00
|
|
|
use std::{
|
|
|
|
|
env,
|
|
|
|
|
error::Error,
|
|
|
|
|
net::{IpAddr, Ipv4Addr, SocketAddr},
|
|
|
|
|
str::FromStr,
|
|
|
|
|
};
|
2025-06-05 16:02:28 -06:00
|
|
|
|
|
|
|
|
use clap::{Parser, Subcommand};
|
2025-06-06 19:20:49 -06:00
|
|
|
use log::error;
|
2025-06-09 12:37:49 -06:00
|
|
|
use unshell_rs::Cli;
|
2025-06-10 06:12:18 -06:00
|
|
|
use unshell_rs_lib::{
|
|
|
|
|
connection::{ConnectionConfig, Node},
|
|
|
|
|
layers::LayerConfig,
|
|
|
|
|
};
|
2025-06-06 19:20:49 -06:00
|
|
|
|
|
|
|
|
pub static DEFAULT_CONFIG_FILEPATH: &'static str = "server_config.json";
|
2025-06-05 16:02:28 -06:00
|
|
|
|
2025-06-06 19:20:49 -06:00
|
|
|
// The default port that this program looks for
|
2025-06-05 16:02:28 -06:00
|
|
|
pub static DEFAULT_SERVICE_PORT: u16 = 13370;
|
2025-06-06 19:20:49 -06:00
|
|
|
// The default website port that this program looks for
|
2025-06-05 16:02:28 -06:00
|
|
|
pub static DEFAULT_WEB_PORT: u16 = 8082;
|
|
|
|
|
|
2025-06-06 19:20:49 -06:00
|
|
|
pub static LOCAL_SOCKET: SocketAddr =
|
|
|
|
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 12, 34, 56)), 13370);
|
|
|
|
|
|
2025-06-05 16:02:28 -06:00
|
|
|
#[derive(Debug, Parser)]
|
|
|
|
|
#[command(name = "unshell-rs")]
|
|
|
|
|
#[command(about = "Slick reverse shell tool in rust", long_about = None)]
|
|
|
|
|
struct Args {
|
|
|
|
|
#[command(subcommand)]
|
|
|
|
|
command: Commands,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Subcommand)]
|
|
|
|
|
enum Commands {
|
2025-06-10 06:12:18 -06:00
|
|
|
Start,
|
|
|
|
|
Middle,
|
|
|
|
|
End,
|
2025-06-05 16:02:28 -06:00
|
|
|
|
2025-06-10 06:12:18 -06:00
|
|
|
// Run as a service, and potentially hosting a website
|
|
|
|
|
// #[command(arg_required_else_help = true)]
|
|
|
|
|
// Relay {
|
|
|
|
|
// /// IPv4 to listen for clients on.
|
|
|
|
|
// host: String,
|
2025-06-06 19:20:49 -06:00
|
|
|
|
2025-06-10 06:12:18 -06:00
|
|
|
// /// Port listen to for command clients
|
|
|
|
|
// #[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
|
|
|
|
// port: u16,
|
|
|
|
|
|
|
|
|
|
// /// Json file to store config
|
|
|
|
|
// #[arg(short, long, default_value_t = DEFAULT_CONFIG_FILEPATH.to_string())]
|
|
|
|
|
// config_filepath: String,
|
|
|
|
|
// // /// Port to listen for website traffic (0 is disabled)
|
|
|
|
|
// // #[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
|
|
|
|
// // web_port: u16,
|
|
|
|
|
// },
|
2025-06-09 12:37:49 -06:00
|
|
|
/// Connect to remote server
|
|
|
|
|
Connect {
|
2025-06-06 19:20:49 -06:00
|
|
|
/// Remote server to connect to
|
|
|
|
|
host: String,
|
2025-06-05 16:02:28 -06:00
|
|
|
|
|
|
|
|
/// Port listen to for command clients
|
|
|
|
|
#[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
2025-06-06 19:20:49 -06:00
|
|
|
port: u16,
|
|
|
|
|
},
|
2025-06-05 16:02:28 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
2025-06-06 19:20:49 -06:00
|
|
|
if env::var("RUST_LOG").is_err() {
|
|
|
|
|
unsafe { env::set_var("RUST_LOG", "info") }
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-05 16:02:28 -06:00
|
|
|
pretty_env_logger::init();
|
|
|
|
|
let args = Args::parse();
|
|
|
|
|
|
2025-06-10 06:12:18 -06:00
|
|
|
if let Err(e) = match args.command {
|
|
|
|
|
// Commands::Relay { host, port, .. } => {
|
|
|
|
|
// let addr = SocketAddr::from_str(format!("{}:{}", host, port).as_str());
|
|
|
|
|
// if let Err(e) = Node::run() {
|
|
|
|
|
// error!("{}", e);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
Commands::Start {} => Node::run_master(
|
|
|
|
|
ConnectionConfig {
|
|
|
|
|
socket: SocketAddr::from_str("127.0.0.1:13370")?,
|
|
|
|
|
layers: vec![],
|
|
|
|
|
},
|
|
|
|
|
vec![ConnectionConfig {
|
|
|
|
|
socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
|
|
|
|
layers: vec![],
|
|
|
|
|
}],
|
|
|
|
|
),
|
|
|
|
|
Commands::Middle {} => Node::run_node(
|
|
|
|
|
ConnectionConfig {
|
|
|
|
|
socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
|
|
|
|
layers: vec![],
|
|
|
|
|
},
|
|
|
|
|
vec![ConnectionConfig {
|
|
|
|
|
socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
|
|
|
|
layers: vec![LayerConfig::Base64],
|
|
|
|
|
}],
|
|
|
|
|
),
|
|
|
|
|
Commands::End {} => Node::run_node(
|
|
|
|
|
ConnectionConfig {
|
|
|
|
|
socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
|
|
|
|
layers: vec![LayerConfig::Base64],
|
|
|
|
|
},
|
|
|
|
|
vec![],
|
|
|
|
|
),
|
|
|
|
|
|
2025-06-09 12:37:49 -06:00
|
|
|
Commands::Connect { host, port } => {
|
2025-06-06 19:20:49 -06:00
|
|
|
let addr = SocketAddr::from_str(format!("{}:{}", host, port).as_str());
|
2025-06-10 06:12:18 -06:00
|
|
|
Cli::connect(if let Ok(addr) = addr {
|
2025-06-09 12:37:49 -06:00
|
|
|
addr
|
2025-06-06 19:20:49 -06:00
|
|
|
} else {
|
|
|
|
|
error!("Could not parse address!");
|
|
|
|
|
return Ok(());
|
2025-06-10 06:12:18 -06:00
|
|
|
})
|
2025-06-06 19:20:49 -06:00
|
|
|
}
|
2025-06-10 06:12:18 -06:00
|
|
|
} {
|
|
|
|
|
error!("{}", e);
|
2025-06-06 19:20:49 -06:00
|
|
|
};
|
2025-06-05 16:02:28 -06:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|