Each instruction sent over from the server is referred to as a 'task'. Implants receive tasks, interpret and execute them, and return the response.
During development, each task must be assigned a numeric opcode, to discourage the sending of text-based task names over the connection. As these opcodes are specified by the developer, an implant should have a built-in mechanism to efficiently route tasks to their controller. This will be referred to as 'task management'
Task manager
Here is a simple, single-threaded implementation of a task manager from Empress.
The router has various callback functions registered for each opcode received from the C2. This means that once a client receives a server request (transport.Request), it can simply call the handle function on the router, which will send the request to the appropriate handler and return the response.
// c is our HTTP(S) client in this casetaskResp := c.router.handle(taskReq)c.SetResponse(taskResp)// will loop and send response on the next connection (long polling)returnnil, nil
Now, whenever a new function is created, the developer simply needs to register the function with the client's internal router. Here is an example of integrating the function ls .