コード例 #1
0
ファイル: nbsniff.c プロジェクト: ACGT/nbtool
static void register_send(settings_t *settings)
{
    dns_t      *dns;
    uint8_t    *packet;
    uint32_t    packet_length;

	/* Create the DNS object. */
    dns = dns_create();
	dns->flags = FLAGS_R_REQUEST | FLAGS_NM_RD | FLAGS_NM_B;

	if(settings->query_type == TYPE_REGISTER)
	    dns->flags  = FLAGS_OPCODE_NAME_REGISTRATION;
	else if(settings->query_type == TYPE_REFRESH)
	    dns->flags  = FLAGS_OPCODE_NAME_REFRESH;
	else if(settings->query_type == TYPE_RELEASE)
	    dns->flags  = FLAGS_OPCODE_NAME_RELEASE;
	else
		fprintf(stderr, "Unknown query type made it into register_send() -- %d\n", settings->query_type);

	dns->trn_id = 0x1337;

	/* Add the question/additional. */
    dns_add_netbios_question(dns, settings->name, settings->name_type, NULL, DNS_TYPE_NB, 0x0001);
	dns_add_additional_NB(dns, settings->name, settings->name_type, NULL, 0x0001, 0, 0x0000, settings->source);

	/* Convert the DNS object to a packet. */
    packet = dns_to_packet(dns, &packet_length);
    dns_destroy(dns);

	/* Put it on the wire. */
	fprintf(stderr, "Sending query.\n");
    udp_send(settings->socket, settings->target, settings->port, packet, packet_length);
    safe_free(packet);
}
コード例 #2
0
ファイル: nbsniff.c プロジェクト: ACGT/nbtool
static void send_conflict_response(settings_t *settings, int socket, char *addr, uint16_t port, char *name, uint8_t name_type, uint16_t trn_id)
{
	dns_t *response = dns_create();
	uint8_t *packet;
	uint32_t packet_length;

	fprintf(stderr, "Replying to registration request for '%s<%02x>' with a conflict (%s)\n", name, name_type, settings->source);

	response->trn_id = trn_id;
	response->flags = FLAGS_R_RESPONSE | FLAGS_OPCODE_NAME_REGISTRATION | FLAGS_NM_AA | FLAGS_NM_RD | FLAGS_NM_RA | FLAGS_RCODE_ACT_ERR;

	dns_add_answer_NB(response, name, name_type, NULL, 1, 0, 0x0000, settings->source ? settings->source : "0.0.0.0");

	packet = dns_to_packet(response, &packet_length);
	dns_destroy(response);

	udp_send(socket, addr, port, packet, packet_length);
	safe_free(packet);
}
コード例 #3
0
ファイル: nbsniff.c プロジェクト: ACGT/nbtool
static void send_poison_response(settings_t *settings, int socket, char *addr, uint16_t port, char *name, uint8_t name_type, uint16_t trn_id)
{
	dns_t *response = dns_create();
	uint8_t *packet;
	uint32_t packet_length;

	fprintf(stderr, "Replying to request for '%s<%02x>' with %s\n", name, name_type, settings->source);

	response->trn_id = trn_id;
	response->flags  = FLAGS_R_RESPONSE | FLAGS_OPCODE_QUERY | FLAGS_NM_AA | FLAGS_NM_RD;

	dns_add_answer_NB(response, name, name_type, NULL, 1, 0, 0x0000, settings->source);

	packet = dns_to_packet(response, &packet_length);
	dns_destroy(response);

	udp_send(socket, addr, port, packet, packet_length);
	safe_free(packet);
}
コード例 #4
0
ファイル: nbsniff.c プロジェクト: ACGT/nbtool
static SELECT_RESPONSE_t nb_recv_callback(void *group, int s, uint8_t *data, size_t length, char *addr, uint16_t port, void *param)
{
	settings_t *settings = (settings_t*) param;
	uint16_t i;

	dns_t *dns = dns_create_from_packet(data, length);
	printf("Received a query from %s:%d:\n", addr, port);

	for(i = 0; i < dns->question_count; i++)
	{
		if(dns->questions[i].type == DNS_TYPE_NB)
		{
			char    decoded_name[16];
			uint8_t type;

			NB_print_question(dns->questions[i], dns->flags);
			NB_decode_name(dns->questions[i].name, decoded_name, &type);

			if(should_poison(settings, dns->flags, decoded_name, addr))
				send_poison_response(settings, s, addr, port, decoded_name, type, dns->trn_id);

			if(should_conflict(settings, dns->flags, decoded_name, addr))
				send_conflict_response(settings, s, addr, port, decoded_name, type, dns->trn_id);
		}
		else if(dns->questions[i].type == DNS_TYPE_NBSTAT)
		{
			NBSTAT_print_question(dns->questions[i], dns->flags);
		}
		else
		{
			fprintf(stderr, "Unknown NetBIOS question: 0x%04x\n", dns->questions[i].type);
		}
	}
	printf("\n");

	dns_destroy(dns);

	return SELECT_OK;
}
コード例 #5
0
ファイル: nbsniff.c プロジェクト: ACGT/nbtool
static void query_send(settings_t *settings)
{
    dns_t      *dns;
    uint8_t    *packet;
    uint32_t    packet_length;

	/* Create the DNS object. */
    dns = dns_create();
    dns->flags  = FLAGS_R_REQUEST | FLAGS_OPCODE_QUERY | FLAGS_NM_B;
	dns->trn_id = 0x1337;

	/* Add the question. */
    dns_add_netbios_question(dns, settings->name, settings->name_type, NULL, settings->query_type == TYPE_QUERY_NB ? DNS_TYPE_NB : DNS_TYPE_NBSTAT, 0x0001);

	/* Convert the DNS object to a packet. */
    packet = dns_to_packet(dns, &packet_length);
    dns_destroy(dns);

	/* Put it on the wire. */
	fprintf(stderr, "Sending query.\n");
    udp_send(settings->socket, settings->target, settings->port, packet, packet_length);
    safe_free(packet);
}
コード例 #6
0
ファイル: dnslogger.c プロジェクト: ACGT/nbtool
static SELECT_RESPONSE_t dns_callback(void *group, int socket, uint8_t *packet, size_t packet_length, char *addr, uint16_t port, void *s)
{
	settings_t *settings = (settings_t*) s;
	dns_t      *response;
	uint8_t    *response_packet;
	uint32_t    response_packet_length;

	/* Parse the DNS packet. */
	dns_t *request  = dns_create_from_packet(packet, packet_length);

	/* Create the response packet. */
	response = dns_create();
	response->trn_id = request->trn_id;
	response->flags = 0x8000;

	if(request->question_count > 0)
	{
		int i;

		/* Display the questions. */
		for(i = 0; i < request->question_count; i++)
		{
			/* Grab the question and display it. */
			question_t this_question = request->questions[i];
			fprintf(stderr, "Question %d: %s (0x%04x 0x%04x)\n", i, this_question.name, this_question.type, this_question.class);

			/* Add an answer, if appropriate. */
			dns_add_question(response, this_question.name, this_question.type, this_question.class);
			if(settings->A && (this_question.type == DNS_TYPE_A || this_question.type == DNS_TYPE_ANY))
			{
				fprintf(stderr, "(Responding with %s)\n", settings->A);
				dns_add_answer_A(response, this_question.name, 0x0001, settings->TTL, settings->A);
			}
#ifndef WIN32
			else if(settings->AAAA && this_question.type == DNS_TYPE_AAAA)
			{
				fprintf(stderr, "(Responding with %s)\n", settings->AAAA);
				dns_add_answer_AAAA(response, this_question.name, 0x0001, settings->TTL, settings->AAAA);
			}
#endif

		}

		/* If we have any answers, send back our packet. */
		if(response->answer_count > 0)
		{
			/* Send the packet. */
			response_packet = dns_to_packet(response, &response_packet_length);
			udp_send(socket, addr, port, response_packet, response_packet_length);
		}
		else
		{
			/* Send back an error. */
			response_packet = dns_create_error_string(request->trn_id, request->questions[0], &response_packet_length);
			udp_send(socket, addr, port, response_packet, response_packet_length);
		}

		/* Delete the response. */
		safe_free(response_packet);
		dns_destroy(response);

		/* Delete the request. */
		dns_destroy(request);
	}
コード例 #7
0
ファイル: driver_dns.c プロジェクト: atimorin/dnscat2
/* This function expects to receive the proper length of data. */
static void handle_packet_out(driver_dns_t *driver, uint8_t *data, size_t length)
{
  size_t        i;
  dns_t        *dns;
  buffer_t     *buffer;
  uint8_t      *encoded_bytes;
  size_t        encoded_length;
  uint8_t      *dns_bytes;
  size_t        dns_length;
  size_t        section_length;

  assert(driver->s != -1); /* Make sure we have a valid socket. */
  assert(data); /* Make sure they aren't trying to send NULL. */
  assert(length > 0); /* Make sure they aren't trying to send 0 bytes. */
  assert(length <= MAX_DNSCAT_LENGTH(driver->domain));

  buffer = buffer_create(BO_BIG_ENDIAN);

  /* If no domain is set, add the wildcard prefix at the start. */
  if(!driver->domain)
  {
    buffer_add_bytes(buffer, (uint8_t*)WILDCARD_PREFIX, strlen(WILDCARD_PREFIX));
    buffer_add_int8(buffer, '.');
  }

  section_length = 0;
  /* TODO: I don't much care for this loop... */
  for(i = 0; i < length; i++)
  {
    char hex_buf[3];

#ifdef WIN32
    sprintf_s(hex_buf, 3, "%02x", data[i]);
#else
    sprintf(hex_buf, "%02x", data[i]);
#endif
    buffer_add_bytes(buffer, hex_buf, 2);

    /* Add periods when we need them. */
    section_length += 2;
    if(i + 1 != length && section_length + 2 >= MAX_FIELD_LENGTH)
    {
      section_length = 0;
      buffer_add_int8(buffer, '.');
    }
  }

  /* If a domain is set, instead of the wildcard prefix, add the domain to the end. */
  if(driver->domain)
  {
    buffer_add_int8(buffer, '.');
    buffer_add_bytes(buffer, driver->domain, strlen(driver->domain));
  }
  buffer_add_int8(buffer, '\0');

  /* Get the result out. */
  encoded_bytes = buffer_create_string_and_destroy(buffer, &encoded_length);

  /* Double-check we didn't mess up the length. */
  assert(encoded_length <= MAX_DNS_LENGTH);

  dns = dns_create(_DNS_OPCODE_QUERY, _DNS_FLAG_RD, _DNS_RCODE_SUCCESS);
  dns_add_question(dns, (char*)encoded_bytes, driver->type, _DNS_CLASS_IN);
  dns_bytes = dns_to_packet(dns, &dns_length);

  LOG_INFO("Sending DNS query for: %s to %s:%d", encoded_bytes, driver->dns_host, driver->dns_port);
  udp_send(driver->s, driver->dns_host, driver->dns_port, dns_bytes, dns_length);

  safe_free(dns_bytes);
  safe_free(encoded_bytes);
  dns_destroy(dns);
}
コード例 #8
0
ファイル: driver_dns.c プロジェクト: atimorin/dnscat2
static SELECT_RESPONSE_t recv_socket_callback(void *group, int s, uint8_t *data, size_t length, char *addr, uint16_t port, void *param)
{
  /*driver_dns_t *driver_dns = param;*/
  dns_t        *dns    = dns_create_from_packet(data, length);
  driver_dns_t *driver = (driver_dns_t*) param;

  LOG_INFO("DNS response received (%d bytes)", length);

  /* TODO */
  if(dns->rcode != _DNS_RCODE_SUCCESS)
  {
    /* TODO: Handle errors more gracefully */
    switch(dns->rcode)
    {
      case _DNS_RCODE_FORMAT_ERROR:
        LOG_ERROR("DNS: RCODE_FORMAT_ERROR");
        break;
      case _DNS_RCODE_SERVER_FAILURE:
        LOG_ERROR("DNS: RCODE_SERVER_FAILURE");
        break;
      case _DNS_RCODE_NAME_ERROR:
        LOG_ERROR("DNS: RCODE_NAME_ERROR");
        break;
      case _DNS_RCODE_NOT_IMPLEMENTED:
        LOG_ERROR("DNS: RCODE_NOT_IMPLEMENTED");
        break;
      case _DNS_RCODE_REFUSED:
        LOG_ERROR("DNS: RCODE_REFUSED");
        break;
      default:
        LOG_ERROR("DNS: Unknown error code (0x%04x)", dns->rcode);
        break;
    }
  }
  else if(dns->question_count != 1)
  {
    LOG_ERROR("DNS returned the wrong number of response fields (question_count should be 1, was instead %d).", dns->question_count);
    LOG_ERROR("This is probably due to a DNS error");
  }
  else if(dns->answer_count < 1)
  {
    LOG_ERROR("DNS didn't return an answer");
    LOG_ERROR("This is probably due to a DNS error");
  }
  else
  {
    size_t    i;

    uint8_t   *answer = NULL;
    size_t     answer_length = 0;
    dns_type_t type = dns->answers[0].type;

    if(type == _DNS_TYPE_TEXT)
    {
      /* Get the answer. */
      answer        = dns->answers[0].answer->TEXT.text;
      answer_length = dns->answers[0].answer->TEXT.length;
      LOG_INFO("Received a TXT response (%zu bytes)", answer_length);

      /* Decode it. */
      answer = buffer_decode_hex(answer, &answer_length);
    }
    else if(type == _DNS_TYPE_CNAME)
    {
      /* Get the answer. */
      answer = remove_domain((char*)dns->answers[0].answer->CNAME.name, driver->domain);
      answer_length = strlen((char*)answer);
      LOG_INFO("Received a CNAME response (%zu bytes)", answer_length);

      /* Decode it. */
      answer = buffer_decode_hex(answer, &answer_length);
    }
    else if(type == _DNS_TYPE_MX)
    {
      /* Get the answer. */
      answer = remove_domain((char*)dns->answers[0].answer->MX.name, driver->domain);
      answer_length = strlen((char*)answer);
      LOG_INFO("Received a MX response (%zu bytes)", answer_length);

      /* Decode it. */
      answer = buffer_decode_hex(answer, &answer_length);
    }
    else if(type == _DNS_TYPE_A)
    {
      buffer_t *buf = buffer_create(BO_BIG_ENDIAN);

      qsort(dns->answers, dns->answer_count, sizeof(answer_t), cmpfunc_a);

      for(i = 0; i < dns->answer_count; i++)
        buffer_add_bytes(buf, dns->answers[i].answer->A.bytes + 1, 3);

      answer_length = buffer_read_next_int8(buf);
      LOG_INFO("Received an A response (%zu bytes)", answer_length);

      answer = safe_malloc(answer_length);
      buffer_read_bytes_at(buf, 1, answer, answer_length);
    }
#ifndef WIN32
    else if(type == _DNS_TYPE_AAAA)
    {
      buffer_t *buf = buffer_create(BO_BIG_ENDIAN);

      qsort(dns->answers, dns->answer_count, sizeof(answer_t), cmpfunc_aaaa);

      for(i = 0; i < dns->answer_count; i++)
        buffer_add_bytes(buf, dns->answers[i].answer->AAAA.bytes + 1, 15);

      answer_length = buffer_read_next_int8(buf);
      LOG_INFO("Received an AAAA response (%zu bytes)", answer_length);

      answer = safe_malloc(answer_length);
      buffer_read_bytes_at(buf, 1, answer, answer_length);
    }
#endif
    else
    {
      LOG_ERROR("Unknown DNS type returned: %d", type);
      answer = NULL;
    }

    if(answer)
    {
      /*LOG_WARNING("Received a %zu-byte DNS response: %s [0x%04x]", answer_length, answer, type);*/

      /* Pass the buffer to the caller */
      if(answer_length > 0)
      {
        /* Pass the data elsewhere. */
        message_post_packet_in(answer, answer_length);
      }

      safe_free(answer);
    }
  }

  dns_destroy(dns);

  return SELECT_OK;
}
コード例 #9
0
ファイル: dns.c プロジェクト: SpComb/nwprog
int main (int argc, char **argv)
{
    int opt;
    enum log_level log_level = LOG_LEVEL;
    int err = 0;

    struct event_main *event_main;
    struct options options = {
        .resolver   = "localhost",
    };

    while ((opt = getopt_long(argc, argv, "hqvdR:", long_options, NULL)) >= 0) {
        switch (opt) {
            case 'h':
                help(argv[0]);
                return 0;

            case 'q':
                log_level = LOG_ERROR;
                break;

            case 'v':
                log_level = LOG_INFO;
                break;

            case 'd':
                log_level = LOG_DEBUG;
                break;

            case 'R':
                options.resolver = optarg;
                break;

            default:
                help(argv[0]);
                return 1;
        }
    }

    // apply
    log_set_level(log_level);

    if ((err = event_main_create(&event_main))) {
        log_fatal("event_main_create");
        goto error;
    }

    if ((err = dns_create(event_main, &options.dns, options.resolver))) {
        log_fatal("dns_create: %s", options.resolver);
        goto error;
    }

    while (optind < argc && !err) {
        struct dns_task task = {
            .options    = &options,
            .arg        = argv[optind++],
        };

        // start async task
        if ((err = event_start(event_main, dns, &task))) {
            log_fatal("event_start: %s", task.arg);
        }
    }

    // mainloop
    if ((err = event_main_run(event_main))) {
        log_fatal("event_main");
    }

error:
    if (options.dns)
        dns_destroy(options.dns);

    return err;
}