Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

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

+15 -55
+13 -53
src/Client.zig
··· 1 - const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '='); 2 - const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '='); 1 + const base64_enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '='); 2 + const base64_dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '='); 3 3 4 4 writer: *std.Io.Writer, 5 5 ··· 17 17 self.writer.flush() catch {}; 18 18 } 19 19 20 - /// Used for relay messages and connection handshake. 21 - /// Assumes Client .init has been called. 22 - fn broadcastInitialInterestMessage(self: *Self, msg_bytes: []u8) !void { 23 - const writer = self.writer; 20 + pub fn sendRelay(self: *Self, payload: []const u8, dest: [4]u8) !void { 21 + const payload_len = base64_enc.calcSize(payload.len); 24 22 25 23 // Ensure the writer is in a valid state 26 - std.debug.assert(writer.buffer.len - writer.end >= msg_bytes.len); 27 - 28 - // Saprus 29 - const msg_target_bytes = try writer.writableSlice(msg_bytes.len); 30 - @memcpy(msg_target_bytes, msg_bytes); 31 - var msg_target: *align(1) SaprusMessage = try .bytesAsValue(msg_target_bytes); 32 - try msg_target.networkFromNativeEndian(); 33 - try writer.flush(); 34 - } 35 - 36 - fn broadcastSaprusMessage(msg_bytes: []u8, udp_port: u16) !void { 37 - const msg: *align(1) SaprusMessage = try .bytesAsValue(msg_bytes); 38 - try msg.networkFromNativeEndian(); 39 - defer msg.nativeFromNetworkEndian() catch unreachable; 40 - 41 - var sock = try network.Socket.create(.ipv4, .udp); 42 - defer sock.close(); 43 - 44 - try sock.setBroadcast(true); 45 - 46 - // Bind to 0.0.0.0:0 47 - const bind_addr = network.EndPoint{ 48 - .address = network.Address{ .ipv4 = network.Address.IPv4.any }, 49 - .port = 0, 50 - }; 24 + std.debug.assert(self.writer.buffer.len - self.writer.end >= payload_len); 51 25 52 - const dest_addr = network.EndPoint{ 53 - .address = network.Address{ .ipv4 = network.Address.IPv4.broadcast }, 54 - .port = udp_port, 55 - }; 56 - 57 - try sock.bind(bind_addr); 58 - 59 - _ = try sock.sendTo(dest_addr, msg_bytes); 60 - } 61 - 62 - pub fn sendRelay(self: *Self, payload: []const u8, dest: [4]u8) !void { 63 - var buf: [max_message_size]u8 align(@alignOf(SaprusMessage)) = undefined; 64 - const msg_bytes = buf[0..try SaprusMessage.calcSize( 65 - .relay, 66 - base64Enc.calcSize(payload.len), 67 - )]; 68 - const msg: *align(1) SaprusMessage = .init(.relay, msg_bytes); 69 - 26 + const headers_buf = try self.writer.writableSlice(@sizeOf(SaprusMessage) + @sizeOf(SaprusMessage.Relay)); 27 + const msg: *align(1) SaprusMessage = .init(.relay, headers_buf); 28 + msg.length = @intCast(payload_len); 70 29 const relay = (try msg.getSaprusTypePayload()).relay; 71 30 relay.dest = dest; 72 - _ = base64Enc.encode(relay.getPayload(), payload); 73 31 74 - try self.broadcastInitialInterestMessage(msg_bytes); 32 + try base64_enc.encodeWriter(self.writer, payload); 33 + try msg.networkFromNativeEndian(); 34 + try self.writer.flush(); 75 35 } 76 36 77 37 // pub fn sendInitialConnection( ··· 83 43 // const dest_port = self.randomPort(); 84 44 // const msg_bytes = output_bytes[0..try SaprusMessage.calcSize( 85 45 // .connection, 86 - // base64Enc.calcSize(payload.len), 46 + // base64_enc.calcSize(payload.len), 87 47 // )]; 88 48 // const msg: *align(1) SaprusMessage = .init(.connection, msg_bytes); 89 49 90 50 // const connection = (try msg.getSaprusTypePayload()).connection; 91 51 // connection.src_port = initial_port; 92 52 // connection.dest_port = dest_port; 93 - // _ = base64Enc.encode(connection.getPayload(), payload); 53 + // _ = base64_enc.encode(connection.getPayload(), payload); 94 54 95 55 // try broadcastSaprusMessage(msg_bytes, 8888); 96 56
+2 -2
src/message.zig
··· 32 32 // &payload could be a void value that is treated as a pointer to a [*]u8 33 33 /// All Saprus messages 34 34 pub const Message = packed struct { 35 - const Relay = packed struct { 35 + pub const Relay = packed struct { 36 36 dest: @Vector(4, u8), 37 37 payload: void, 38 38 ··· 41 41 return @as([*]u8, @ptrCast(&self.payload))[0 .. len.* - @bitSizeOf(Relay) / 8]; 42 42 } 43 43 }; 44 - const Connection = packed struct { 44 + pub const Connection = packed struct { 45 45 src_port: u16, // random number > 1024 46 46 dest_port: u16, // random number > 1024 47 47 seq_num: u32 = 0,