Example #1
0
static int create_drivers(ll_t *drivers)
{
  int num_created = 0;
  make_driver_t *this_driver;

  while((this_driver = ll_remove_first(drivers)))
  {
    num_created++;
    switch(this_driver->type)
    {
      case DRIVER_TYPE_CONSOLE:
        printf("Creating a console session!\n");
        controller_add_session(session_create_console(group, "console"));
        break;

      case DRIVER_TYPE_EXEC:
        printf("Creating a exec('%s') session!\n", this_driver->options.exec.process);
        controller_add_session(session_create_exec(group, this_driver->options.exec.process, this_driver->options.exec.process));
        break;

      case DRIVER_TYPE_COMMAND:
        printf("Creating a command session!\n");
        controller_add_session(session_create_command(group, "command"));
        break;

      case DRIVER_TYPE_PING:
        printf("Creating a ping session!\n");
        controller_add_session(session_create_ping(group, "ping"));
        break;
    }
    safe_free(this_driver);
  }

  /* Default to creating a command session. */
  if(num_created == 0)
  {
    num_created++;
    controller_add_session(session_create_command(group, "command"));
  }

  return num_created;
}
Example #2
0
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);
  }
}
Example #3
0
int main(int argc, char *argv[])
{
  /* Define the options specific to the DNS protocol. */
  struct option long_options[] =
  {
    /* General options */
    {"help",    no_argument,       0, 0}, /* Help */
    {"h",       no_argument,       0, 0},
    {"version", no_argument,       0, 0}, /* Version */
#if 0
    {"name",    required_argument, 0, 0}, /* Name */
    {"n",       required_argument, 0, 0},
    {"download",required_argument, 0, 0}, /* Download */
    {"n",       required_argument, 0, 0},
    {"chunk",   required_argument, 0, 0}, /* Download chunk */
    {"isn",     required_argument, 0, 0}, /* Initial sequence number */
#endif

    {"delay",              required_argument, 0, 0}, /* Retransmit delay */
    {"steady",             no_argument,       0, 0}, /* Don't transmit immediately after getting a response. */
    {"max-retransmits",    required_argument, 0, 0}, /* Set the max retransmissions */
    {"retransmit-forever", no_argument,       0, 0}, /* Retransmit forever if needed */

    /* i/o options. */
    {"console", no_argument,       0, 0}, /* Enable console */
    {"exec",    required_argument, 0, 0}, /* Enable execute */
    {"e",       required_argument, 0, 0},
    {"command", no_argument,       0, 0}, /* Enable command (default) */
    {"ping",    no_argument,       0, 0}, /* Ping */

    /* Tunnel drivers */
    {"dns",     required_argument, 0, 0}, /* Enable DNS */
#if 0
    {"tcp",     optional_argument, 0, 0}, /* Enable TCP */
#endif

    /* Debug options */
    {"d",            no_argument, 0, 0}, /* More debug */
    {"q",            no_argument, 0, 0}, /* Less debug */
    {"packet-trace", no_argument, 0, 0}, /* Trace packets */

    /* Sentry */
    {0,              0,                 0, 0}  /* End */
  };

  char              c;
  int               option_index;
  const char       *option_name;

  NBBOOL            tunnel_driver_created = FALSE;
  NBBOOL            driver_created        = FALSE;


  log_level_t       min_log_level = LOG_LEVEL_WARNING;

  session_t        *session = NULL;

  group = select_group_create();
  system_dns = dns_get_system();

  /* Seed with the current time; not great, but it'll suit our purposes. */
  srand((unsigned int)time(NULL));

  /* This is required for win32 support. */
  winsock_initialize();

  /* Set the default log level */
  log_set_min_console_level(min_log_level);

  /* Parse the command line options. */
  opterr = 0;
  while((c = getopt_long_only(argc, argv, "", long_options, &option_index)) != EOF)
  {
    switch(c)
    {
      case 0:
        option_name = long_options[option_index].name;

        /* General options */
        if(!strcmp(option_name, "help") || !strcmp(option_name, "h"))
        {
          usage(argv[0], "--help requested");
        }
        if(!strcmp(option_name, "version"))
        {
          printf(NAME" v"VERSION" (client)\n");
          exit(0);
        }
        else if(!strcmp(option_name, "isn"))
        {
          uint16_t isn = (uint16_t) (atoi(optarg) & 0xFFFF);
          debug_set_isn(isn);
        }
        else if(!strcmp(option_name, "delay"))
        {
          int delay = (int) atoi(optarg);
          session_set_delay(delay);
          LOG_INFO("Setting delay between packets to %dms", delay);
        }
        else if(!strcmp(option_name, "steady"))
        {
          session_set_transmit_immediately(FALSE);
        }
        else if(!strcmp(option_name, "max-retransmits"))
        {
          controller_set_max_retransmits(atoi(optarg));
        }
        else if(!strcmp(option_name, "retransmit-forever"))
        {
          controller_set_max_retransmits(-1);
        }

        /* i/o drivers */
        else if(!strcmp(option_name, "console"))
        {
          driver_created = TRUE;

          session = session_create_console(group, "Console session");
          controller_add_session(session);
        }
        else if(!strcmp(option_name, "exec") || !strcmp(option_name, "e"))
        {
          driver_created = TRUE;

          session = session_create_exec(group, optarg, optarg);
          controller_add_session(session);
        }
        else if(!strcmp(option_name, "command"))
        {
          driver_created = TRUE;

          session = session_create_command(group, "Command session");
          controller_add_session(session);
        }
        else if(!strcmp(option_name, "ping"))
        {
          driver_created = TRUE;

          session = session_create_ping(group, "Ping session");
          controller_add_session(session);
        }

        /* Listener options. */
        else if(!strcmp(option_name, "listen") || !strcmp(option_name, "l"))
        {
          LOG_FATAL("--listen isn't implemented yet! :(\n");
          exit(1);
          /*listen_port = atoi(optarg);*/

          /*input_type = TYPE_LISTENER;*/
        }

        /* Tunnel driver options */
        else if(!strcmp(option_name, "dns"))
        {
          tunnel_driver_created = TRUE;
          tunnel_driver = create_dns_driver(group, optarg);
        }
        else if(!strcmp(option_name, "tcp"))
        {
          tunnel_driver_created = TRUE;
          create_tcp_driver(optarg);
        }

        /* Debug options */
        else if(!strcmp(option_name, "d"))
        {
          if(min_log_level > 0)
          {
            min_log_level--;
            log_set_min_console_level(min_log_level);
          }
        }
        else if(!strcmp(option_name, "q"))
        {
          min_log_level++;
          log_set_min_console_level(min_log_level);
        }
        else if(!strcmp(option_name, "packet-trace"))
        {
          session_enable_packet_trace();
        }
        else
        {
          usage(argv[0], "Unknown option");
        }
        break;

      case '?':
      default:
        usage(argv[0], "Unrecognized argument");
        break;
    }
  }

  /* If no output was set, use the domain, and use the last option as the
   * domain. */
  if(!tunnel_driver_created)
  {
    /* Make sure they gave a domain. */
    if(optind >= argc)
    {
      printf("Starting DNS driver without a domain! This will only work if you\n");
      printf("are directly connecting to the dnscat2 server.\n");
      printf("\n");
      printf("You'll need to use --dns server=<server> if you aren't.\n");
      tunnel_driver = create_dns_driver_internal(group, NULL, "0.0.0.0", 53, DEFAULT_TYPES, NULL);
    }
    else
    {
      tunnel_driver = create_dns_driver_internal(group, argv[optind], "0.0.0.0", 53, DEFAULT_TYPES, NULL);
    }
  }

  /* If no i/o was set, create a command session. */
  if(!driver_created)
  {
    session = session_create_command(group, "command (default)");
    controller_add_session(session);
  }

  /* Be sure we clean up at exit. */
  atexit(cleanup);

  /* Start the driver! */
  driver_dns_go(tunnel_driver);

  return 0;
}