コード例 #1
0
ファイル: session.c プロジェクト: EricSB/dnscat2
session_t *session_create_exec(select_group_t *group, char *name, char *process)
{
  session_t *session = session_create(name);

  session->driver = driver_create(DRIVER_TYPE_EXEC, driver_exec_create(group, process));

  return session;
}
コード例 #2
0
ファイル: driver_command.c プロジェクト: atimorin/dnscat2
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);
    }
  }
}
コード例 #3
0
ファイル: dnscat.c プロジェクト: 52piaoyu/dnscat2
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},
    {"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 */
    {"ping",    no_argument,       0, 0}, /* Ping */

    /* Console options. */
    {"console", no_argument,       0, 0}, /* Enable console (default) */

    /* Execute-specific options. */
    {"exec",    required_argument, 0, 0}, /* Enable execute */
    {"e",       required_argument, 0, 0},

    /* Listener options */
    {"listen",  required_argument, 0, 0}, /* Enable listener */
    {"l",       required_argument, 0, 0},

    /* DNS-specific options */
    {"dns",        required_argument, 0, 0}, /* Enable DNS (default) */
    {"dnshost",    required_argument, 0, 0}, /* DNS server */
    {"host",       required_argument, 0, 0}, /* (alias) */
    {"dnsport",    required_argument, 0, 0}, /* DNS port */
    {"port",       required_argument, 0, 0}, /* (alias) */

    /* Debug options */
    {"d",       no_argument,       0, 0}, /* More debug */
    {"q",       no_argument,       0, 0}, /* Less debug */
    {0,         0,                 0, 0}  /* End */
  };

  /* Define DNS options so we can set them later. */
  struct {
    char     *host;
    uint16_t  port;
  } dns_options = { DEFAULT_DNS_HOST, DEFAULT_DNS_PORT };

  char              c;
  int               option_index;
  const char       *option_name;

  NBBOOL            output_set = FALSE;

  char             *name     = NULL;
  char             *download = NULL;
  uint32_t          chunk    = -1;

  log_level_t       min_log_level = LOG_LEVEL_WARNING;

  drivers_t input_type = TYPE_NOT_SET;

  char *exec_process = NULL;

  int listen_port = 0;

  /* Initialize the modules that need initialization. */
  log_init();
  sessions_init();

  group = select_group_create();

  /* 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");
        }
        else if(!strcmp(option_name, "name") || !strcmp(option_name, "n"))
        {
          name = optarg;
        }
        else if(!strcmp(option_name, "download"))
        {
          download = optarg;
        }
        else if(!strcmp(option_name, "chunk"))
        {
          chunk = atoi(optarg);
        }
        else if(!strcmp(option_name, "ping"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          input_type = TYPE_PING;

          /* Turn off logging, since this is a simple ping. */
          min_log_level++;
          log_set_min_console_level(min_log_level);
        }

        /* Console-specific options. */
        else if(!strcmp(option_name, "console"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          input_type = TYPE_CONSOLE;
        }

        /* Execute options. */
        else if(!strcmp(option_name, "exec") || !strcmp(option_name, "e"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          exec_process = optarg;
          input_type = TYPE_EXEC;
        }

        /* Listener options. */
        else if(!strcmp(option_name, "listen") || !strcmp(option_name, "l"))
        {
          if(input_type != TYPE_NOT_SET)
            too_many_inputs(argv[0]);

          listen_port = atoi(optarg);

          input_type = TYPE_LISTENER;
        }

        /* DNS-specific options */
        else if(!strcmp(option_name, "dns"))
        {
          output_set = TRUE;
          driver_dns = driver_dns_create(group, optarg);
        }
        else if(!strcmp(option_name, "dnshost") || !strcmp(option_name, "host"))
        {
          dns_options.host = optarg;
        }
        else if(!strcmp(option_name, "dnsport") || !strcmp(option_name, "port"))
        {
          dns_options.port = atoi(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"))
        {
          log_set_min_console_level(min_log_level);
        }
        else
        {
          usage(argv[0], "Unknown option");
        }
        break;

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

  if(chunk != -1 && !download)
  {
    LOG_FATAL("--chunk can only be used with --download");
    exit(1);
  }

  /* If no input was created, default to command. */
  if(input_type == TYPE_NOT_SET)
    input_type = TYPE_COMMAND;

  switch(input_type)
  {
    case TYPE_CONSOLE:
      LOG_WARNING("INPUT: Console");
      driver_console_create(group, name, download, chunk);
      break;

    case TYPE_COMMAND:
      LOG_WARNING("INPUT: Command");
      driver_command_create(group, name);
      break;

    case TYPE_EXEC:
      LOG_WARNING("INPUT: Executing %s", exec_process);

      if(exec_process == NULL)
        usage(argv[0], "--exec set without a process!");

      driver_exec_create(group, exec_process, name);
      break;

    case TYPE_LISTENER:
      LOG_WARNING("INPUT: Listening on port %d", driver_listener->port);
      if(listen_port == 0)
        usage(argv[0], "--listen set without a port!");

      driver_listener = driver_listener_create(group, "0.0.0.0", listen_port, name);
      break;

    case TYPE_PING:
      LOG_WARNING("INPUT: ping");
      driver_ping = driver_ping_create(group);
      break;

    case TYPE_NOT_SET:
      usage(argv[0], "You have to pick an input type!");
      break;

    default:
      usage(argv[0], "Unknown type?");
  }

  /* If no output was set, use the domain, and use the last option as the
   * domain. */
  if(!output_set)
  {
    /* Make sure they gave a domain. */
    if(optind >= argc)
    {
      LOG_WARNING("Starting DNS driver without a domain! You'll probably need to use --host to specify a direct connection to your server.");
      driver_dns = driver_dns_create(group, NULL);
    }
    else
    {
      driver_dns = driver_dns_create(group, argv[optind]);
    }
  }

  if(driver_dns)
  {
    if(dns_options.host == DEFAULT_DNS_HOST)
      driver_dns->dns_host = dns_get_system();
    else
      driver_dns->dns_host = safe_strdup(dns_options.host);

    if(!driver_dns->dns_host)
    {
      LOG_FATAL("Couldn't determine the system DNS server! Please use --host to set one.");
      LOG_FATAL("You can also create a proper /etc/resolv.conf file to fix this");
      exit(1);
    }

    driver_dns->dns_port = dns_options.port;
    if(driver_dns->domain)
      LOG_WARNING("OUTPUT: DNS tunnel to %s via %s:%d", driver_dns->domain, driver_dns->dns_host, driver_dns->dns_port);
    else
      LOG_WARNING("OUTPUT: DNS tunnel to %s:%d (no domain set! This probably needs to be the exact server where the dnscat2 server is running!)", driver_dns->dns_host, driver_dns->dns_port);
  }
  else
  {
    LOG_FATAL("OUTPUT: Ended up with an unknown output driver!");
    exit(1);
  }

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

  /* Add the timeout function */
  select_set_timeout(group, timeout, NULL);
  while(TRUE)
    select_group_do_select(group, 1000);

  return 0;
}