Compare commits
5 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b0501ebe68 | ||
![]() |
5f7cd49e37 | ||
![]() |
674d3c6963 | ||
![]() |
9d93e52ac5 | ||
![]() |
ccc77a09e3 |
6 changed files with 121 additions and 64 deletions
|
@ -1 +1,5 @@
|
|||
# rust-remote
|
||||
# Remote Code Execution Program
|
||||
|
||||
I implemented this for my remote server.
|
||||
|
||||
Sometimes ssh can't be possible because of NAT. That's why I add a public remote server as a relay.
|
|
@ -66,10 +66,22 @@ async fn serve((ws_sender, mut ws_receiver): (WebSocketSender, WebSocketReceiver
|
|||
|
||||
async fn execute(payload: Payload, debug: bool) -> Option<Output> {
|
||||
if debug {
|
||||
println!("{:#?}", payload);
|
||||
payload.print();
|
||||
}
|
||||
match Command::new(payload.command)
|
||||
.args(payload.args)
|
||||
let command = if cfg!(target_os = "windows") {
|
||||
"cmd"
|
||||
} else {
|
||||
"sh"
|
||||
};
|
||||
|
||||
let first_arg = if cfg!(target_os = "windows") {
|
||||
"/C"
|
||||
} else {
|
||||
"-c"
|
||||
};
|
||||
match Command::new(command)
|
||||
.arg(first_arg)
|
||||
.arg(payload.args)
|
||||
.output()
|
||||
.await
|
||||
{
|
||||
|
@ -78,7 +90,7 @@ async fn execute(payload: Payload, debug: bool) -> Option<Output> {
|
|||
if debug {
|
||||
eprintln!("Error: Command Execution | {}", err_val);
|
||||
}
|
||||
return None;
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +145,10 @@ async fn send(
|
|||
},
|
||||
};
|
||||
|
||||
if debug {
|
||||
report.print();
|
||||
}
|
||||
|
||||
let report = serde_json::json!(report);
|
||||
let result = ws_sender.lock().await.send(report.to_string().into()).await;
|
||||
match result {
|
||||
|
|
61
src/lib.rs
61
src/lib.rs
|
@ -11,23 +11,56 @@ pub enum Runner {
|
|||
Server,
|
||||
Client,
|
||||
}
|
||||
|
||||
impl Runner {
|
||||
fn print(&self) {
|
||||
println!("-------");
|
||||
match self {
|
||||
Runner::Server => println!("Runner = Server"),
|
||||
Runner::Client => println!("Runner = Client"),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub enum RunnerMode {
|
||||
State(Runner, bool),
|
||||
}
|
||||
|
||||
impl RunnerMode {
|
||||
pub fn print(&self) {
|
||||
match self {
|
||||
RunnerMode::State(runner, debug) => {
|
||||
runner.print();
|
||||
println!("Debug = {}", debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
pub ip: IpAddr,
|
||||
pub port: u16,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn print(&self) {
|
||||
println!("-------");
|
||||
println!("IP = {}", self.ip);
|
||||
println!("Port = {}", self.port);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Payload {
|
||||
pub sudo: bool,
|
||||
pub user: String,
|
||||
pub command: String,
|
||||
pub args: Vec<String>,
|
||||
pub args: String,
|
||||
}
|
||||
|
||||
impl Payload {
|
||||
fn print(&self) {
|
||||
println!("-------");
|
||||
println!("args = {}", self.args);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -37,3 +70,23 @@ pub struct Report {
|
|||
pub stdout: String,
|
||||
pub stderr: String,
|
||||
}
|
||||
|
||||
impl Report {
|
||||
fn print(&self) {
|
||||
println!("-------");
|
||||
println!("Payload ↓");
|
||||
self.payload.print();
|
||||
println!("-------");
|
||||
if !self.status.is_empty() {
|
||||
println!("Status ↓ \n{}", self.status);
|
||||
println!("-------");
|
||||
}
|
||||
if !self.stdout.is_empty() {
|
||||
println!("Stdout ↓ \n{}", self.stdout);
|
||||
println!("-------");
|
||||
}
|
||||
if !self.stderr.is_empty() {
|
||||
println!("Stderr ↓ \n{}", self.stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -5,10 +5,13 @@ async fn main() {
|
|||
println!("Hello, world!");
|
||||
|
||||
let args = take_args();
|
||||
println!("{:#?}", args);
|
||||
|
||||
match args {
|
||||
Some((runner_mode, config)) => match runner_mode {
|
||||
Some((runner_mode, config)) => {
|
||||
runner_mode.print();
|
||||
config.print();
|
||||
|
||||
match runner_mode {
|
||||
RunnerMode::State(Runner::Server, false) => {
|
||||
rust_remote::server::start(config, false).await
|
||||
}
|
||||
|
@ -21,7 +24,8 @@ async fn main() {
|
|||
RunnerMode::State(Runner::Client, true) => {
|
||||
rust_remote::client::start(config, true).await
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
None => {
|
||||
eprintln!("Error: Take Args");
|
||||
return;
|
||||
|
|
|
@ -10,7 +10,7 @@ use tokio::{
|
|||
};
|
||||
use tokio_tungstenite::{accept_async, tungstenite::Message, WebSocketStream};
|
||||
|
||||
use crate::{Config, Payload};
|
||||
use crate::{Config, Payload, Report};
|
||||
type WebSocketSender = SplitSink<WebSocketStream<TcpStream>, Message>;
|
||||
type WebSocketReceiver = SplitStream<WebSocketStream<TcpStream>>;
|
||||
|
||||
|
@ -31,11 +31,22 @@ pub async fn start(config: Config, debug: bool) {
|
|||
match payload_from_input(debug).await {
|
||||
Some(payload) => {
|
||||
if !send(payload, ws_sender, debug).await {
|
||||
if debug {
|
||||
eprintln!("Error: Send");
|
||||
}
|
||||
break;
|
||||
}
|
||||
tokio::spawn(async move {
|
||||
let report = receive(ws_receiver, debug).await;
|
||||
println!("{:#?}", report);
|
||||
if let Some(report) = receive(ws_receiver, debug).await {
|
||||
match serde_json::from_str::<Report>(&report) {
|
||||
Ok(report) => report.print(),
|
||||
Err(err_val) => {
|
||||
if debug {
|
||||
eprintln!("Error: Deserialize | {}", err_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
None => continue,
|
||||
|
@ -82,38 +93,9 @@ async fn establish_connection(
|
|||
}
|
||||
|
||||
async fn payload_from_input(debug: bool) -> Option<Payload> {
|
||||
println!("User");
|
||||
// let user = match get_input() {
|
||||
// Some(input) => input,
|
||||
// None => return None,
|
||||
// };
|
||||
let user = "tahinli".to_string();
|
||||
println!("-------");
|
||||
println!("Command");
|
||||
match get_input(debug) {
|
||||
Some(input) => {
|
||||
let mut args: Vec<String> = input.split_ascii_whitespace().map(String::from).collect();
|
||||
if args.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut sudo = false;
|
||||
let mut command = args.remove(0);
|
||||
if command == "sudo" {
|
||||
if args.is_empty() {
|
||||
return None;
|
||||
}
|
||||
sudo = true;
|
||||
command = args.remove(0);
|
||||
}
|
||||
Some(Payload {
|
||||
sudo,
|
||||
user,
|
||||
command,
|
||||
args,
|
||||
})
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
get_input(debug).map(|args| Payload { args })
|
||||
}
|
||||
|
||||
fn get_input(debug: bool) -> Option<String> {
|
||||
|
|
12
src/utils.rs
12
src/utils.rs
|
@ -4,7 +4,7 @@ use crate::{Config, Runner, RunnerMode};
|
|||
|
||||
pub fn take_args() -> Option<(RunnerMode, Config)> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let mut runner = Runner::Server;
|
||||
let mut runner = Runner::Client;
|
||||
let mut debug = false;
|
||||
let mut ip = "127.0.0.1".to_string();
|
||||
let mut port = "3444".to_string();
|
||||
|
@ -13,8 +13,8 @@ pub fn take_args() -> Option<(RunnerMode, Config)> {
|
|||
"--server" | "-sv" => runner = Runner::Server,
|
||||
"--client" | "-cl" => runner = Runner::Client,
|
||||
"--debug" | "-d" => debug = true,
|
||||
"--ip" | "-i" => ip = args[i + 1].clone(),
|
||||
"--port" | "-p" => port = args[i + 1].clone(),
|
||||
"--ip" | "-i" => ip.clone_from(&args[i + 1]),
|
||||
"--port" | "-p" => port.clone_from(&args[i + 1]),
|
||||
"--help" | "-h" => {
|
||||
show_help();
|
||||
std::process::exit(0);
|
||||
|
@ -30,8 +30,6 @@ pub fn take_args() -> Option<(RunnerMode, Config)> {
|
|||
}
|
||||
};
|
||||
|
||||
println!("{:#?}", ip);
|
||||
|
||||
let port = match port.parse::<u16>() {
|
||||
Ok(port) => port,
|
||||
Err(err_val) => {
|
||||
|
@ -52,8 +50,8 @@ fn show_help() {
|
|||
println!("----------------------------------------------------------------------");
|
||||
println!(" -i -> --ip | Specifies IP Address | 127.0.0.1");
|
||||
println!(" -p -> --port | Specifies Port Address | 3444");
|
||||
println!(" -sv -> --server | Starts as a Server | True");
|
||||
println!(" -cl -> --client | Starts as a Client | False");
|
||||
println!(" -sv -> --server | Starts as a Server | False");
|
||||
println!(" -cl -> --client | Starts as a Client | True");
|
||||
println!(" -d -> --debug | Starts in Debug Mode | False");
|
||||
println!(" -h -> --help | Shows Help | False");
|
||||
println!("\n\n\n");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue