Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

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

IT'S RIGHT

+73 -70
+67 -68
src/NetWriter.zig
··· 5 5 wrapped: *Writer, 6 6 interface: Writer, 7 7 8 - pub fn init(w: *Writer) !NetWriter { 9 - std.debug.assert(w.buffer.len > @sizeOf(EthernetHeaders) + @sizeOf(IpHeaders) + @sizeOf(UdpHeaders)); 8 + pub fn init(w: *Writer, buffer: []u8) !NetWriter { 9 + std.debug.assert(buffer.len > @sizeOf(EthernetHeaders) + @sizeOf(IpHeaders) + @sizeOf(UdpHeaders)); 10 10 11 11 var prng = Random.DefaultPrng.init(blk: { 12 12 var seed: u64 = undefined; ··· 20 20 .interface = .{ 21 21 .vtable = &.{ 22 22 .drain = drain, 23 - .flush = flush, 23 + // .flush = flush, 24 24 }, 25 - .buffer = &.{}, 25 + .buffer = buffer, 26 26 }, 27 27 }; 28 28 } 29 29 30 30 fn drain(io_w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize { 31 31 const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w)); 32 - 33 - var res: usize = 0; 34 - 35 - if (io_w.end == 0) { 32 + const headers_byte_len = comptime (EthernetHeaders.byte_len + IpHeaders.byte_len + UdpHeaders.byte_len); 33 + const headers: [headers_byte_len]u8 = blk: { 36 34 const ether_headers: EthernetHeaders = .{ 37 35 .dest_mac = .{ 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff }, 38 - .src_mac = blk: { 36 + .src_mac = src_blk: { 39 37 var output_bytes: [6]u8 = undefined; 40 38 output_bytes[0] = 0xee; 41 39 w.rand.bytes(output_bytes[1..]); 42 - break :blk output_bytes; 40 + break :src_blk output_bytes; 43 41 }, 44 42 .ether_type = 0x0800, 45 43 }; 44 + 45 + const total_len = Writer.countSplat(data, splat) + w.interface.end; 46 46 47 47 const ip_headers: IpHeaders = .{ 48 - .total_length = @intCast(res - 92), 49 - .ttl = 0x64, 48 + // length of the packet minus eth header 49 + .total_length = @intCast(headers_byte_len + total_len - EthernetHeaders.byte_len), //@intCast(total_len), 50 + .ttl = 64, 50 51 .protocol = 0x11, 51 52 .src_ip = .{ 0xff, 0x02, 0x03, 0x04 }, 52 53 .dest_ip = .{ 0xff, 0xff, 0xff, 0xff }, ··· 55 56 const udp_headers: UdpHeaders = .{ 56 57 .src_port = 0xbbbb, 57 58 .dest_port = 8888, 58 - .length = @intCast(res), 59 + .length = @intCast(total_len + UdpHeaders.byte_len), 59 60 }; 60 61 61 - res += try ether_headers.write(w.wrapped); 62 - res += try ip_headers.write(w.wrapped); 63 - res += try udp_headers.write(w.wrapped); 64 - } 62 + var buf: [headers_byte_len]u8 = undefined; 63 + var buf_w = Writer.fixed(&buf); 65 64 66 - res += try w.wrapped.writeSplat(data, splat); 67 - return res; 68 - } 65 + _ = try ether_headers.write(&buf_w); 66 + _ = try ip_headers.write(&buf_w); 67 + std.debug.print("after ip: {x}\n", .{buf_w.buffered()}); 68 + _ = try udp_headers.write(&buf_w); 69 + std.debug.print("after udp: {x}\n", .{buf_w.buffered()}); 70 + 71 + break :blk buf; 72 + }; 73 + 74 + _ = try w.wrapped.write(&headers); 75 + const total_len = try w.wrapped.writeSplatHeader(w.interface.buffered(), data, splat); 69 76 70 - fn flush(io_w: *Writer) Writer.Error!void { 71 - const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w)); 77 + std.debug.print("total splat: {}\theaders.len: {}\tsplat: {}\n", .{ total_len, headers.len, splat }); 78 + 72 79 try w.wrapped.flush(); 80 + return total_len - w.interface.consumeAll(); 73 81 } 82 + 83 + // fn flush(io_w: *Writer) Writer.Error!void { 84 + // const w: *NetWriter = @alignCast(@fieldParentPtr("interface", io_w)); 85 + // try io_w.defaultFlush(); 86 + // } 74 87 75 88 const EthernetHeaders = struct { 76 89 dest_mac: @Vector(6, u8), ··· 80 93 ether_type: u16, 81 94 82 95 fn write(hdr: EthernetHeaders, writer: *std.Io.Writer) Writer.Error!usize { 83 - comptime var res: usize = 0; 84 - 85 - res += @sizeOf(u48); 86 96 try writer.writeInt(u48, @bitCast(hdr.dest_mac), .big); 87 - 88 - res += @sizeOf(u48); 89 97 try writer.writeInt(u48, @bitCast(hdr.src_mac), .big); 90 - 91 - res += @sizeOf(u16); 92 98 try writer.writeInt(u16, hdr.ether_type, .big); 93 - 94 - return res; 99 + return byte_len; 95 100 } 96 101 97 - const byte_len = @bitSizeOf(EthernetHeaders) / 8; 102 + const byte_len = blk: { 103 + var res: usize = 0; 104 + res += @bitSizeOf(u48) / 8; 105 + res += @bitSizeOf(u48) / 8; 106 + res += @bitSizeOf(u16) / 8; 107 + break :blk res; 108 + }; 98 109 99 110 fn bytes(hdr: EthernetHeaders) [byte_len]u8 { 100 111 var res: [byte_len]u8 = undefined; ··· 120 131 dest_ip: @Vector(4, u8), 121 132 122 133 fn write(hdr: @This(), writer: *std.Io.Writer) Writer.Error!usize { 123 - comptime var res: usize = 0; 124 - 125 - res += @sizeOf(u8); 126 134 try writer.writeInt(u8, 0x45, .big); // ip version and header length 127 - 128 - res += @sizeOf(u8); 129 135 try writer.writeByte(hdr.type_of_service); 130 - 131 - res += @sizeOf(u16); 132 136 try writer.writeInt(u16, hdr.total_length, .big); 133 - 134 - res += @sizeOf(u16); 135 137 try writer.writeInt(u16, hdr.identification, .big); 136 - 137 - res += @sizeOf(u16); 138 138 try writer.writeInt(u16, 0x00, .big); // ethernet flags and fragment offset 139 - 140 - res += @sizeOf(u8); 141 139 try writer.writeByte(hdr.ttl); 142 - 143 - res += @sizeOf(u8); 144 140 try writer.writeByte(hdr.protocol); 145 - 146 - res += @sizeOf(u16); 147 141 try writer.writeInt(u16, @bitCast(hdr.header_checksum), .big); 148 - 149 - res += @sizeOf(u32); 150 142 try writer.writeInt(u32, @bitCast(hdr.src_ip), .big); 151 - 152 - res += @sizeOf(u32); 153 143 try writer.writeInt(u32, @bitCast(hdr.dest_ip), .big); 154 - 155 - return res; 144 + return byte_len; 156 145 } 157 146 158 - const byte_len = @bitSizeOf(IpHeaders) / 8; 147 + const byte_len = blk: { 148 + var res: usize = 0; 149 + res += @sizeOf(u8); 150 + res += @sizeOf(u8); 151 + res += @sizeOf(u16); 152 + res += @sizeOf(u16); 153 + res += @sizeOf(u16); 154 + res += @sizeOf(u8); 155 + res += @sizeOf(u8); 156 + res += @sizeOf(u16); 157 + res += @sizeOf(u32); 158 + res += @sizeOf(u32); 159 + break :blk res; 160 + }; 159 161 160 162 fn bytes(hdr: IpHeaders) [byte_len]u8 { 161 163 var res: [byte_len]u8 = undefined; ··· 171 173 checksum: @Vector(2, u8) = .{ 0, 0 }, 172 174 173 175 fn write(hdr: @This(), writer: *std.Io.Writer) Writer.Error!usize { 174 - comptime var res: usize = 0; 175 - 176 - res += @sizeOf(u16); 177 176 try writer.writeInt(u16, hdr.src_port, .big); 178 - 179 - res += @sizeOf(u16); 180 177 try writer.writeInt(u16, hdr.dest_port, .big); 181 - 182 - res += @sizeOf(u16); 183 178 try writer.writeInt(u16, hdr.length, .big); 184 - 185 - res += @sizeOf(u16); 186 179 try writer.writeInt(u16, @bitCast(hdr.checksum), .big); 187 - 188 - return res; 180 + return byte_len; 189 181 } 190 182 191 - const byte_len = @bitSizeOf(UdpHeaders) / 8; 183 + const byte_len = blk: { 184 + var res: usize = 0; 185 + res += @sizeOf(u16); 186 + res += @sizeOf(u16); 187 + res += @sizeOf(u16); 188 + res += @sizeOf(u16); 189 + break :blk res; 190 + }; 192 191 193 192 fn bytes(hdr: UdpHeaders) [byte_len]u8 { 194 193 var res: [byte_len]u8 = undefined;
+3
src/RawSocketWriter.zig
··· 8 8 socket: gcat.nic.RawSocket, 9 9 10 10 fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) Writer.Error!usize { 11 + std.debug.print("in drain\n", .{}); 11 12 const w: *RawSocketWriter = @alignCast(@fieldParentPtr("interface", io_w)); 12 13 const rem_buf = io_w.unusedCapacitySlice(); 13 14 var rem_w = Writer.fixed(rem_buf); 14 15 const res = rem_w.writeSplat(data, splat) catch rem_buf.len; 15 16 io_w.advance(res); 16 17 const buffered = io_w.buffered(); 18 + std.debug.print("buffer: {x}\n", .{buffered}); 17 19 w.socket.linkLayer().send(buffered) catch return error.WriteFailed; 18 20 _ = io_w.consumeAll(); 19 21 ··· 21 23 } 22 24 23 25 pub fn init(interface_name: [:0]const u8, buffer: []u8) !RawSocketWriter { 26 + std.debug.assert(buffer.len > 0); 24 27 return .{ 25 28 .interface = .{ 26 29 .vtable = &.{ .drain = drain },
+3 -2
src/main.zig
··· 46 46 return clap.helpToFile(.stderr(), clap.Help, &params, .{}); 47 47 } 48 48 49 - var sock_buffer: [2048]u8 = undefined; 49 + var sock_buffer: [1500]u8 = undefined; 50 50 var raw_socket_writer: RawSocketWriter = try .init("enp7s0", &sock_buffer); // /proc/net/dev 51 - var net_writer: NetWriter = try .init(&raw_socket_writer.interface); 51 + var net_buffer: [1500]u8 = undefined; 52 + var net_writer: NetWriter = try .init(&raw_socket_writer.interface, &net_buffer); 52 53 var client = try SaprusClient.init(&net_writer.interface); 53 54 defer client.deinit(); 54 55