Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Use writer instead of RawSocket in Client

+57 -13
+7 -12
src/Client.zig
··· 2 2 const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '='); 3 3 4 4 rand: Random, 5 - socket: gcat.nic.RawSocket, 5 + writer: *std.Io.Writer, 6 6 7 7 const Self = @This(); 8 8 9 9 const max_message_size = 2048; 10 10 11 - pub fn init(interface_name: [:0]const u8) !Self { 11 + pub fn init(writer: *std.Io.Writer) !Self { 12 12 var prng = Random.DefaultPrng.init(blk: { 13 13 var seed: u64 = undefined; 14 14 try posix.getrandom(mem.asBytes(&seed)); ··· 16 16 }); 17 17 const rand = prng.random(); 18 18 19 - const socket: gcat.nic.RawSocket = try .init(interface_name); 20 - 21 19 return .{ 22 20 .rand = rand, 23 - .socket = socket, 21 + .writer = writer, 24 22 }; 25 23 } 26 24 27 25 pub fn deinit(self: *Self) void { 28 - self.socket.deinit(); 26 + self.writer.flush() catch {}; 29 27 } 30 28 31 29 /// Used for relay messages and connection handshake. ··· 70 68 const saprus_start_byte = 42; 71 69 @memcpy(packet_bytes[saprus_start_byte .. saprus_start_byte + msg_bytes.len], msg_bytes); 72 70 73 - try self.socket.linkLayer().send(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]); 71 + const writer = self.writer; 72 + _ = try writer.write(packet_bytes[0 .. saprus_start_byte + msg_bytes.len]); 73 + try writer.flush(); 74 74 } 75 75 76 76 // fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8) !void {} 77 77 78 78 fn broadcastSaprusMessage(msg_bytes: []align(@alignOf(SaprusMessage)) u8, udp_port: u16) !void { 79 - if (false) { 80 - var foo: gcat.nic.RawSocket = try .init("enp7s0"); // /proc/net/dev 81 - defer foo.deinit(); 82 - } 83 79 const msg: *SaprusMessage = try .bytesAsValue(msg_bytes); 84 80 try msg.networkFromNativeEndian(); 85 81 defer msg.nativeFromNetworkEndian() catch unreachable; ··· 194 190 const mem = std.mem; 195 191 196 192 const network = @import("network"); 197 - const gcat = @import("gatorcat");
+45
src/RawSocketWriter.zig
··· 1 + const std = @import("std"); 2 + const gcat = @import("gatorcat"); 3 + const Writer = @This(); 4 + const assert = std.debug.assert; 5 + 6 + interface: std.Io.Writer, 7 + socket: gcat.nic.RawSocket, 8 + alloc: std.mem.Allocator, 9 + 10 + fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize { 11 + const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w)); 12 + const buffered = io_w.buffered(); 13 + var res: usize = 0; 14 + if (buffered.len > 0) { 15 + w.socket.linkLayer().send(buffered) catch return error.WriteFailed; 16 + _ = io_w.consumeAll(); 17 + } 18 + 19 + for (data[0 .. data.len - 1]) |d| { 20 + w.socket.linkLayer().send(d) catch return error.WriteFailed; 21 + res += d.len; 22 + } 23 + 24 + if (splat > 0 and data[data.len - 1].len > 0) { 25 + var splatBuffer: std.ArrayList(u8) = .empty; 26 + defer splatBuffer.deinit(w.alloc); 27 + for (0..splat) |_| { 28 + splatBuffer.appendSlice(w.alloc, data[data.len - 1]) catch return error.WriteFailed; 29 + } 30 + w.socket.linkLayer().send(splatBuffer.items) catch return error.WriteFailed; 31 + } 32 + 33 + return res; 34 + } 35 + 36 + pub fn init(interface_name: [:0]const u8, buffer: []u8, alloc: std.mem.Allocator) !Writer { 37 + return .{ 38 + .interface = .{ 39 + .vtable = &.{ .drain = drain }, 40 + .buffer = buffer, 41 + }, 42 + .socket = try .init(interface_name), 43 + .alloc = alloc, 44 + }; 45 + }
+4 -1
src/main.zig
··· 46 46 return clap.helpToFile(.stderr(), clap.Help, &params, .{}); 47 47 } 48 48 49 - var client = try SaprusClient.init("enp7s0"); 49 + var sock_buffer: [2048]u8 = undefined; 50 + var rawSocketWriter: RawSocketWriter = try .init("enp7s0", &sock_buffer, gpa); // /proc/net/dev 51 + var client = try SaprusClient.init(&rawSocketWriter.interface); 50 52 defer client.deinit(); 51 53 52 54 if (res.args.relay) |r| { ··· 90 92 const zaprus = @import("zaprus"); 91 93 const SaprusClient = zaprus.Client; 92 94 const SaprusMessage = zaprus.Message; 95 + const RawSocketWriter = zaprus.RawSocketWriter; 93 96 94 97 const clap = @import("clap");
+1
src/root.zig
··· 1 1 pub const Client = @import("Client.zig"); 2 2 pub const Connection = @import("Connection.zig"); 3 + pub const RawSocketWriter = @import("RawSocketWriter.zig"); 3 4 4 5 const msg = @import("message.zig"); 5 6