Example #1
0
uint16_t packet_peek_session_id(uint8_t *data, size_t length)
{
  buffer_t *buffer = NULL;
  uint16_t session_id = -1;

  /* Create a buffer of the first 5 bytes. */
  if(length < 5)
  {
    LOG_FATAL("Packet is too short!\n");
    return -1;
  }

  /* Create a buffer with the first 5 bytes of data. */
  buffer = buffer_create_with_data(BO_BIG_ENDIAN, data, 5);

  /* Discard packet_id. */
  buffer_consume(buffer, 2);

  /* Discard packet_type. */
  buffer_consume(buffer, 1);

  /* Finally, get the session_id. */
  session_id = buffer_read_next_int16(buffer);

  /* Kill the buffer. */
  buffer_destroy(buffer);

  /* Done! */
  return session_id;
}
Example #2
0
SELECT_RESPONSE_t incoming(void *group, int s, uint8_t *data, size_t length, char *addr, uint16_t port, void *param)
{
	buffer_t *buffer;

	switch(state)
	{
		case RECV_STATE_HEADER:
		{
			/* Sanity check -- this should never happen with select_group. */
			if(length != 4)
				DIE("Received incorrect number of bytes for NetBIOS header (likely a problem with select_group).");

			/* The header is 24-bytes in network byte order. */
			buffer = buffer_create_with_data(BO_NETWORK, data, 4);
			current_length = (buffer_read_next_int32(buffer) & 0x00FFFFFF);
			buffer_destroy(buffer);
			/* Enter body-receiving mode. */
			select_group_wait_for_bytes((select_group_t*)group, s, current_length);
			state = RECV_STATE_BODY;

			break;
		}
		case RECV_STATE_BODY:
		{
			SMB_t *smb;

			/* Sanity check -- this should never happen with select_group. */
			if(length != current_length)
				DIE("Received incorrect number of bytes for SMB (likely a problem with select_group).");

			smb = smb_create_from_data(data, length, -1, NULL); /* TODO: Fix. */

			switch(smb->header.command)
			{
				case SMB_COM_NEGOTIATE:
					parse_SMB_COM_NEGOTIATE(s, smb);
					break;
				case SMB_COM_SESSION_SETUP_ANDX:
					break;
				default:
					fprintf(stderr, "Don't know how to handle 0x%02x yet!\n", smb->header.command);
			}

			smb_destroy(smb);

			/* Return to header state. */
			select_group_wait_for_bytes((select_group_t*)group, s, 4);
			state = RECV_STATE_HEADER;

			break;
		}
		default:
			DIE("Entered an unknown state.");
	}

	return SELECT_OK;
}
Example #3
0
packet_t *packet_parse(uint8_t *data, size_t length, options_t options)
{
  packet_t *packet = (packet_t*) safe_malloc(sizeof(packet_t));
  buffer_t *buffer = buffer_create_with_data(BO_BIG_ENDIAN, data, length);

  /* Validate the size */
  if(buffer_get_length(buffer) > MAX_PACKET_SIZE)
  {
    LOG_FATAL("Packet is too long: %zu bytes\n", buffer_get_length(buffer));
    exit(1);
  }

  packet->packet_id    = buffer_read_next_int16(buffer);
  packet->packet_type  = (packet_type_t) buffer_read_next_int8(buffer);
  packet->session_id   = buffer_read_next_int16(buffer);

  switch(packet->packet_type)
  {
    case PACKET_TYPE_SYN:
      packet->body.syn.seq     = buffer_read_next_int16(buffer);
      packet->body.syn.options = buffer_read_next_int16(buffer);
      break;

    case PACKET_TYPE_MSG:
      if(options & OPT_CHUNKED_DOWNLOAD)
      {
        packet->body.msg.options.chunked.chunk = buffer_read_next_int32(buffer);
      }
      else
      {
        packet->body.msg.options.normal.seq     = buffer_read_next_int16(buffer);
        packet->body.msg.options.normal.ack     = buffer_read_next_int16(buffer);
      }
      packet->body.msg.data    = buffer_read_remaining_bytes(buffer, &packet->body.msg.data_length, -1, FALSE);
      break;

    case PACKET_TYPE_FIN:
      packet->body.fin.reason = buffer_alloc_next_ntstring(buffer);

      break;

    case PACKET_TYPE_PING:
      packet->body.ping.data = buffer_alloc_next_ntstring(buffer);

      break;

    default:
      LOG_FATAL("Error: unknown message type (0x%02x)\n", packet->packet_type);
      exit(0);
  }

  buffer_destroy(buffer);

  return packet;
}
Example #4
0
/* Parse a packet from a byte stream. */
static command_packet_t *command_packet_parse(uint8_t *data, uint32_t length)
{
  command_packet_t *p         = safe_malloc(sizeof(command_packet_t));
  buffer_t         *buffer    = buffer_create_with_data(BO_BIG_ENDIAN, data, length);
  uint16_t          packed_id = buffer_read_next_int16(buffer);

  /* The first bit of the request_id represents a response */
  p->request_id = (packed_id & 0x7FFF);
  p->is_request = (packed_id & 0x8000) ? FALSE : TRUE;

  p->command_id = (command_packet_type_t) buffer_read_next_int16(buffer);

  switch(p->command_id)
  {
    case COMMAND_PING:
      if(p->is_request)
        p->r.request.body.ping.data = buffer_alloc_next_ntstring(buffer);
      else
        p->r.response.body.ping.data = buffer_alloc_next_ntstring(buffer);
      break;

    case COMMAND_SHELL:
      if(p->is_request)
        p->r.request.body.shell.name = buffer_alloc_next_ntstring(buffer);
      else
        p->r.response.body.shell.session_id = buffer_read_next_int16(buffer);
      break;

    case COMMAND_EXEC:
      if(p->is_request)
      {
        p->r.request.body.exec.name    = buffer_alloc_next_ntstring(buffer);
        p->r.request.body.exec.command = buffer_alloc_next_ntstring(buffer);
      }
      else
      {
        p->r.response.body.exec.session_id = buffer_read_next_int16(buffer);
      }
      break;

    case COMMAND_DOWNLOAD:
      if(p->is_request)
      {
        p->r.request.body.download.filename = buffer_alloc_next_ntstring(buffer);
      }
      else
      {
        p->r.response.body.download.data = (uint8_t*)buffer_read_remaining_bytes(buffer, (size_t*)&p->r.response.body.download.length, -1, TRUE);
      }

      break;

    case COMMAND_UPLOAD:
      if(p->is_request)
      {
        p->r.request.body.upload.filename = buffer_alloc_next_ntstring(buffer);
        p->r.request.body.upload.data = buffer_read_remaining_bytes(buffer, (size_t*)&p->r.request.body.upload.length, -1, TRUE);
      }
      else
      {
      }
      break;

    case COMMAND_SHUTDOWN:
      break;

    case TUNNEL_CONNECT:
      if(p->is_request)
      {
        p->r.request.body.tunnel_connect.options = buffer_read_next_int32(buffer);
        p->r.request.body.tunnel_connect.host    = buffer_alloc_next_ntstring(buffer);
        p->r.request.body.tunnel_connect.port    = buffer_read_next_int16(buffer);
      }
      else
      {
        p->r.response.body.tunnel_connect.tunnel_id = buffer_read_next_int32(buffer);
      }
      break;

    case TUNNEL_DATA:
      if(p->is_request)
      {
        p->r.request.body.tunnel_data.tunnel_id = buffer_read_next_int32(buffer);
        p->r.request.body.tunnel_data.data = buffer_read_remaining_bytes(buffer, (size_t*)&p->r.request.body.tunnel_data.length, -1, TRUE);
      }
      else
      {
        /* n/a */
      }
      break;

    case TUNNEL_CLOSE:
      if(p->is_request)
      {
        p->r.request.body.tunnel_close.tunnel_id = buffer_read_next_int32(buffer);
        p->r.request.body.tunnel_close.reason    = buffer_alloc_next_ntstring(buffer);
      }
      else
      {
        /* n/a */
      }
      break;

    case COMMAND_ERROR:
      if(p->is_request)
      {
        p->r.request.body.error.status = buffer_read_next_int16(buffer);
        p->r.request.body.error.reason = buffer_alloc_next_ntstring(buffer);
      }
      else
      {
        p->r.request.body.error.status = buffer_read_next_int16(buffer);
        p->r.request.body.error.reason = buffer_alloc_next_ntstring(buffer);
      }
      break;

    default:
      LOG_FATAL("Unknown command_id: 0x%04x", p->command_id);
      exit(1);
  }

  return p;
}