Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * handlers can be one of these types.
- */
- typedef enum {
- NONE, // blind command, no I/O, only exit value returned.
- RAW, // RAW I/O, executa a command and redirect stdin and stdout to Java
- NMAP, // nmap executable
- ETTERCAP, // ettercap...
- HYDRA, // ...
- HTTP_SNIFFER // ...
- } handler_type;
- /**
- * commands sent from client to server and viceversa
- */
- typedef enum {
- START_CMD,
- STOP_CMD,
- CMD_STARTED,
- CMD_END,
- // others like restart server, stop server...
- } action;
- /**
- * internal struct for manage
- * handler data and functions.
- *
- * @id handler id
- * @tid thread id associated to this handler
- * @output_parser the process stdout parser function
- * @input_parser the process stdin parser function
- */
- typedef struct {
- unsigned char id;
- unsigned char tid;
- const char *(* output_parser)(char *line);
- const char *(* input_parser)(char *line);
- } handler_t;
- /**
- * this is the header of a message
- * @handler_id id of the handler that generate this message
- * @bytes_count the number of following bytes to read
- */
- typedef struct {
- unsigned char handler_id;
- unsigned char bytes_count;
- } message_header;
- /**
- * request for a new program execution.
- * this is followed by the argv for the program.
- * @type type of the new program
- */
- typedef struct {
- handler_type type;
- } new_process_request;
- /**
- * this info is sent to Java when a new
- * process is created.
- *
- * @id the id of the new handler
- * @type type of running handler
- */
- typedef struct {
- unsigned char id;
- handler_type type;
- } new_process_info;
- /**
- * this info is sent to Java when a
- * process ends.
- *
- * @id the id of the handler
- * @exit_code the code returned by the sub process
- */
- typedef struct {
- unsigned char id;
- int exit_code
- } end_process_info;
- #define JAVA_HANDLER_ID 0
- int main(int argc, char **argv) {
- static unsigned long uid = 1;
- // lot of things here
- // on new command
- handler_t h = malloc(sizeof(handler_t));
- new_process_info info;
- if(!h)
- //OOM
- h.id = uid++;
- switch(new_process_type) {
- case NMAP:
- h.output_parser = &nmap_output_parser;
- h.input_parser = &nmap_input_parser;
- break;
- case ETTERCAP:
- h.output_parser = &ettercap_output_parser;
- h.input_parser = &ettercap_input_parser;
- break;
- // others...
- default:
- h.output_parser = NULL;
- h.input_parser = NULL;
- }
- info.id = h.id;
- info.type = new_process_type;
- send_to_Java(JAVA_HANDLER_ID,(void *) &info, sizeof(info));
- }
- //this function run inside a thread
- void process_handler(void *arg) {
- char cancel = 0;
- char *output_buffer;
- char *input_buffer;
- char *old;
- int outfd, infd;
- pid_t pid;
- handler_t h;
- unsigned long tid;
- unsigned long count;
- char c;
- end_process_info einfo;
- h = *((handler_t *)arg);
- tid = h.tid;
- pthread_mutex_lock(&(tpool[tid].lock));
- cancel = tpool[tid].cancel;
- outfd = tpool[tid].stdout_fd;
- infd = tpool[tid].stdin_fd;
- pid = tpool[tid].pid;
- tpool[tid].started = 1;
- pthread_mutex_unlock(&(tpool[tid].lock));
- output_size = 1;
- input_size = 0;
- read_size = (h.output_parser != NULL ? 1 : BUFFER_SIZE);
- write_size = (h.input_parser != NULL ? 1 : BUFFER_SIZE);
- output_buffer = malloc(read_size);
- input_buffer = malloc(write_size);
- while(!cancel) {
- // non blocking file descriptor
- if((read_count = read(outfd, output_buffer, read_size)) > 0) {
- // use output buffer only if we have to parse
- if(h.output_parser != NULL) {
- output_buffer = realloc(output_buffer, ++output_size);
- output_buffer[output_size-1] = c;
- if(c=='\n') {
- parsed_output = h.output_parser(output_buffer);
- if(parsed_output) {
- send_to_Java(h.id, parsed_output, strlen(parsed_output));
- }
- output_size = 1;
- output_buffer = realloc(output_buffer,1);
- }
- } else {
- // send everything to java
- send_to_Java(h.id, (void *) output_buffer, read_count);
- }
- } else if(read_count < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
- // error...
- }
- pthread_mutex_lock(&(tpool[tid].input_lock));
- if(tpool[tid].input_bytes_count > 0) {
- if(h.input_parser) {
- for(count=0;count<tpool[tid].input_bytes_count;count++) {
- input_buffer = realloc(input_buffer, ++input_size);
- input_buffer[input_size -1] = *ptr;
- if(*ptr == '\n') {
- parsed_input = h.input_parser(input_buffer);
- if(parsed_input) {
- send_to_Java(h.id, parsed_input, strlen(parsed_input));
- }
- input_size = 1;
- output_buffer = realloc(input_buffer, 1);
- }
- }
- } else {
- do {
- res = write(infd, tpool[tid].input_buffer, tpool[tid].input_bytes_count);
- pthread_mutex_lock(tpool[id].lock);
- cancel = tpool[id].cancel;
- pthread_mutex_unlock(tpool[id].lock);
- } while(!cancel && (res > 0 || errno == EAGAIN));
- }
- }
- pthread_mutex_unlock(tpool[id].input_lock);
- waitpid(pid, &status, WNOHANG);
- if(WIFEXITED(status)) {
- einfo.id = h.id;
- einfo.exit_code = WEXITSTATUS(status);
- send_to_Java(JAVA_HANDLER_ID, (void *)&einfo, sizeof(einfo));
- return; // TODO: free()
- }
- pthread_mutex_lock(tpool[id].lock);
- cancel = tpool[id].cancel;
- pthread_mutex_unlock(tpool[id].lock);
- }
- }
- void send_to_Java(unsigned long id, void *data, unsigned long data_length) {
- message_header header;
- header.id = id;
- header.bytes_count = data_length;
- // write into IPC header + data
- }
- void send_action_to_Java(
- /**
- * PROTOCOL SUMMARY
- * ================
- *
- * a message is composed as follow
- *
- * +----+-----+----------------------+
- * | id | len | data |
- * +----+-----+----------------------+
- *
- * where
- * - @id: is the id of the receiver
- * - @len: is the length of the data section
- * - @data: is the data to trasfer to the receiver
- *
- * NOTE: if @id is 0 the receiver is the dSploitd server or the Java main thread.
- * if @id is 0, the first byte of @ðata is an action that describe what comes next.
- * if @len is 0, the handler must close the stream.
- * LIMITS: maximum 254 handlers can run in parallel ( @id is an 8 bit char )
- * maximum len of data is 255 chars
- * these limits can be expanded using `unsigned int` or `unsigned long` instead of `unsigned char`.
- *
- *
- * EXAMPLES
- * ========
- *
- * execute a blind command
- * -----------------------
- *
- * Java:
- * "\x00\x35\x00\x00rm -rf /data/data/it.evilsocket.dsploit/files/fifos"
- *
- * @id = \x00
- * @len = \x35 = 53
- * @data = \x00\x00rm -rf /data/data/it.evilsocket.dsploit/files/fifos
- * = START_CMD + NONE + "rm -rf /data/data/it.evilsocket.dsploit/files/fifos"
- *
- * C:
- * "\x00\x03\x02\x01\x01"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x02\x01\x00 = CMD_STARTED + new_process_info =
- * = CMD_STARTED + handler_id + NONE
- *
- * C:
- * "\x00\x03\x03\x01\x00"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x03\x01\x00 = CMD_END + end_process_info = CMD_END + handler_id + exit_code
- *
- *
- * execute a RAW command
- * ---------------------
- *
- * Java:
- * "\x00\x06\x00\x01date"
- *
- * @id = \x00
- * @len = \x06
- * @data = \x00\x01date = START_CMD + RAW + argv = START_CMD + RAW + "date"
- *
- * C:
- * "\x00\x03\x02\x01\x01"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x02\x01\x01 = CMD_STARTED + new_process_info =
- * = CMD_STARTED + handler_id + RAW
- *
- * C:
- * "\x01\x1Fven 18 apr 2014, 02.17.41, CEST"
- *
- * @id = \x01 // handler_id
- * @len = \x1F
- * @data = "ven 18 apr 2014, 02.17.41, CEST"
- *
- * C:
- * "\x00\x03\x03\x01\x00"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x03\x01\x00 = CMD_END + end_process_info = CMD_END + handler_id + exit_code
- *
- *
- * execute a RAW command and write to it's stdin
- * ---------------------------------------------
- *
- * Java:
- * "\x00\x0C\x00\x01tar\x00-xf\x00-\x00"
- *
- * @id = \x00
- * @len = \x0C
- * @data = \x00\x01tar\x00-xf\x00-\x00 = START_CMD + RAW + argv =
- * = START_CMD + RAW + "tar" + "-xf" + "-"
- *
- * C:
- * "\x00\x03\x02\x02\x01"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x02\x02\x01 = CMD_STARTED + new_process_info =
- * = CMD_STARTED + handler_id + RAW
- *
- * Java:
- * "\x02\xFFtar archive here..."
- *
- * @id = \x02
- * @len = \xFF
- * @data = "tar archive here..."
- *
- *
- * // close stdin
- *
- * Java:
- * "\x02\x00"
- *
- * @id = \x02
- * @len = \x00
- *
- * C:
- * "\x00\x03\x03\x02\x00"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x03\x02\x00 = CMD_END + end_process_info = CMD_END + handler_id + exit_code
- *
- *
- * execute nmap
- * ------------
- *
- * Java:
- * "\x00\x22\x00\x02-sV\x00-T4\x00-F\x00-O\x00192.168.0.100\x00"
- *
- * @id = \x00
- * @len = \x22
- * @data = \x00\x02-sV\x00-T4\x00-F\x00-O\x00192.168.0.100\x00 =
- * = START_CMD + NMAP + argv =
- * = START_CMD + NMAP + "-sV" + "-T4" + "-F" + "-O" + "192.168.0.100"
- *
- * C:
- * "\x00\x03\x02\x02\x01"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x02\x03\x02 = CMD_STARTED + new_process_info =
- * = CMD_STARTED + handler_id + NMAP
- *
- * C:
- * "\x03\x27starting synScan for host 192.168.0.100"
- *
- * @id = \x03
- * @len = \x27
- * @data = "starting synScan for host 192.168.0.100"
- *
- * C:
- * "\x03\x14TCP\x0022\x00OpenSSH\x005.9p1"
- *
- * @id = \x03
- * @len = \x14
- * @data = "TCP\x0022\x00OpenSSH\x005.9p1" =
- * = protocol + number + service + version
- *
- * C:
- * "\x00\x03\x03\x03\x00"
- *
- * @id = \x00
- * @len = \x03
- * @data = \x03\x03\x00 = CMD_END + end_process_info = CMD_END + handler_id + exit_code
- *
- */
Advertisement
Add Comment
Please, Sign In to add comment