Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

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

Start adding connection message

+73 -30
+71 -28
src/main.zig
··· 90 90 std.debug.print("dest: {s}\n", .{flags.dest orelse "<null>"}); 91 91 std.debug.print("connect: {s}\n", .{flags.connect orelse "<null>"}); 92 92 93 - // const rand = blk: { 94 - // const io_source: std.Random.IoSource = .{ .io = init.io }; 95 - // break :blk io_source.interface(); 96 - // }; 93 + const rand = blk: { 94 + const io_source: std.Random.IoSource = .{ .io = init.io }; 95 + break :blk io_source.interface(); 96 + }; 97 97 98 98 // const net_interface: std.Io.net.Interface = .{ .index = 1 }; 99 99 // std.debug.print("Interface: {s}\n", .{(try net_interface.name(init.io)).toSlice()}); ··· 153 153 }; 154 154 155 155 var headers: EthIpUdp = .{ 156 - .src_mac = @splat(0x0e), 156 + .src_mac = undefined, // TODO: REAL MAC 157 157 .ip = .{ 158 158 .id = 0, 159 - .src_addr = 0, 159 + .src_addr = rand.int(u32), 160 160 .dst_addr = @bitCast([_]u8{ 255, 255, 255, 255 }), 161 161 .len = undefined, 162 162 }, 163 163 .udp = .{ 164 - .src_port = undefined, // TODO: change this? 164 + .src_port = rand.intRangeAtMost(u16, 1025, std.math.maxInt(u16)), 165 165 .dst_port = 8888, 166 166 .len = undefined, 167 167 }, 168 168 }; 169 169 std.debug.print("headers: {any}\n", .{&headers.toBytes()}); 170 170 171 - const relay: SaprusMessage = .{ 172 - .relay = .{ 173 - .dest = .fromBytes(&parseDest(flags.dest)), 174 - .payload = flags.relay.?, 175 - }, 176 - }; 171 + if (flags.relay != null) { 172 + const relay: SaprusMessage = .{ 173 + .relay = .{ 174 + .dest = .fromBytes(&parseDest(flags.dest)), 175 + .payload = flags.relay.?, 176 + }, 177 + }; 178 + 179 + var relay_buf: [2048]u8 = undefined; 180 + const relay_bytes = relay.toBytes(&relay_buf); 181 + std.debug.print("payload: {any}\n", .{relay_bytes}); 182 + headers.setPayloadLen(relay_bytes.len); 183 + 184 + const full_msg = blk: { 185 + var msg_buf: [2048]u8 = undefined; 186 + var msg_w: Writer = .fixed(&msg_buf); 187 + msg_w.writeAll(&headers.toBytes()) catch unreachable; 188 + msg_w.writeAll(relay_bytes) catch unreachable; 189 + break :blk msg_w.buffered(); 190 + }; 191 + 192 + std.debug.print("full message = {any}\n", .{full_msg}); 193 + 194 + var socket: RawSocket = try .init("enp7s0"); 195 + defer socket.deinit(); 196 + try socket.send(full_msg); 197 + return; 198 + } 199 + 200 + if (flags.connect != null) { 201 + const dest = rand.intRangeAtMost(u16, 1025, std.math.maxInt(u16)); 202 + const src = rand.intRangeAtMost(u16, 1025, std.math.maxInt(u16)); 203 + // udp dest port should not be 8888 after first 204 + const udp_dest_port = rand.intRangeAtMost(u16, 1025, std.math.maxInt(u16)); 205 + const connection: SaprusMessage = .{ 206 + .connection = .{ 207 + .src = src, 208 + .dest = dest, 209 + .seq = undefined, 210 + .id = undefined, 211 + .payload = flags.connect.?, 212 + }, 213 + }; 214 + 215 + _ = udp_dest_port; 216 + 217 + var connection_buf: [2048]u8 = undefined; 218 + const connection_bytes = connection.toBytes(&connection_buf); 219 + std.debug.print("connection: {any}\n", .{connection_bytes}); 220 + headers.setPayloadLen(connection_bytes.len); 177 221 178 - var relay_buf: [2048]u8 = undefined; 179 - const relay_bytes = relay.toBytes(&relay_buf); 180 - std.debug.print("payload: {any}\n", .{relay_bytes}); 181 - headers.setPayloadLen(relay_bytes.len); 222 + const full_msg = blk: { 223 + var msg_buf: [2048]u8 = undefined; 224 + var msg_w: Writer = .fixed(&msg_buf); 225 + msg_w.writeAll(&headers.toBytes()) catch unreachable; 226 + msg_w.writeAll(connection_bytes) catch unreachable; 227 + break :blk msg_w.buffered(); 228 + }; 182 229 183 - const full_msg = blk: { 184 - var msg_buf: [2048]u8 = undefined; 185 - var msg_w: Writer = .fixed(&msg_buf); 186 - msg_w.writeAll(&headers.toBytes()) catch unreachable; 187 - msg_w.writeAll(relay_bytes) catch unreachable; 188 - break :blk msg_w.buffered(); 189 - }; 230 + std.debug.print("full message = {any}\n", .{full_msg}); 190 231 191 - std.debug.print("full message = {any}\n", .{full_msg}); 232 + var socket: RawSocket = try .init("enp7s0"); 233 + defer socket.deinit(); 234 + try socket.send(full_msg); 235 + return; 236 + } 192 237 193 - var socket: RawSocket = try .init("enp7s0"); 194 - defer socket.deinit(); 195 - try socket.send(full_msg); 238 + unreachable; 196 239 } 197 240 198 241 fn parseDest(in: ?[]const u8) [4]u8 {
+2 -2
src/message.zig
··· 123 123 pub fn toBytes(self: Relay, buf: []u8) []u8 { 124 124 var out: Writer = .fixed(buf); 125 125 out.writeInt(u16, @intFromEnum(PacketType.relay), .big) catch unreachable; 126 - out.writeInt(u16, @intCast(self.payload.len), .big) catch unreachable; // Length field, but unread. Will switch to checksum 126 + out.writeInt(u16, @intCast(self.payload.len + 4), .big) catch unreachable; // Length field, but unread. Will switch to checksum 127 127 out.writeAll(&self.dest.bytes) catch unreachable; 128 128 out.writeAll(self.payload) catch unreachable; 129 129 return out.buffered(); ··· 177 177 pub fn toBytes(self: Connection, buf: []u8) []u8 { 178 178 var out: Writer = .fixed(buf); 179 179 out.writeInt(u16, @intFromEnum(PacketType.connection), .big) catch unreachable; 180 - out.writeInt(u16, undefined, .big) catch unreachable; // Saprus length field, unread. 180 + out.writeInt(u16, @intCast(self.payload.len + 14), .big) catch unreachable; // Saprus length field, unread. 181 181 out.writeInt(u16, self.src, .big) catch unreachable; 182 182 out.writeInt(u16, self.dest, .big) catch unreachable; 183 183 out.writeInt(u32, self.seq, .big) catch unreachable;