Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Feb 1996 10:37:33 -0500
From:      "Garrett A. Wollman" <wollman@lcs.mit.edu>
To:        invalid opcode <coredump@nervosa.com>
Cc:        freebsd-security@freebsd.org, cert@cert.org
Subject:   Alert: UDP Port Denial-of-Service Attack (fwd)
Message-ID:  <9602231537.AA03433@halloran-eldar.lcs.mit.edu>
In-Reply-To: <Pine.BSF.3.91.960222181443.12862A-100000@nervosa.com>
References:  <Pine.BSF.3.91.960222181443.12862A-100000@nervosa.com>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Thu, 22 Feb 1996 18:14:53 -0800 (PST), invalid opcode <coredump@nervosa.com> said:

[Regarding CA-96.01]

> The CERT staff recommends disabling unneeded UDP services on each host, in
> particular the chargen and echo services, and filtering these services at the
> firewall or Internet gateway.

I have been aware of this problem for more than a year now, and a
former graduate student colleague of mine for much longer than that.
In late 1994, I took steps to ensure that FreeBSD is not vulnerable
to this problem to the same extent as other systems, as FreeBSD's
inetd will refuse to respond to requests for ``internal'' services
that appear to be coming from ports of other ``internal'' services
(those being in particular `echo', `daytime', `chargen', and
`discard').  Note in particular the following changes (being the
security fixes in inetd that I am aware of):

revision 1.11
date: 1996/02/07 17:15:01;  author: wollman;  state: Exp;  lines: +3 -1
Call setsockopt(SO_PRIVSTATE) to renounce SS_PRIV on all the sockets
we create.  (Nothing being called from inetd should use it anyway,
but you can never be too careful.)

Translate the man page back into -mdoc.
----------------------------
revision 1.4
date: 1994/12/21 19:08:45;  author: wollman;  state: Exp;  lines: +63 -17
Disable UDP service looping attack.
----------------------------

The second change is the relevant one to this case, and may be of
value to users in campus environments or other situations where
firewalling is impractical.

The following patch should apply to most 4.4BSD-derived inetd
programs:

===================================================================
RCS file: /home/ncvs/src/usr.sbin/inetd/inetd.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -c -r1.3 -r1.4
*** inetd.c     1994/09/11 11:16:32     1.3
--- inetd.c     1994/12/21 19:08:45     1.4
***************
*** 39,45 ****
  
  #ifndef lint
  /* from: @(#)inetd.c  8.4 (Berkeley) 4/13/94"; */
! static char RCSid[] = "$Id";
  #endif /* not lint */
  
  /*
--- 39,46 ----
  
  #ifndef lint
  /* from: @(#)inetd.c  8.4 (Berkeley) 4/13/94"; */
! static char inetd_c_rcsid[] = 
!       "$Id: inetd.c,v 1.4 1994/12/21 19:08:45 wollman Exp $";
  #endif /* not lint */
  
  /*
***************
*** 1084,1089 ****
--- 1085,1112 ----
        exit(0);
  }
  
+ int check_loop(sin, sep)
+       struct sockaddr_in *sin;
+       struct servtab *sep;
+ {
+       struct servtab *se2;
+ 
+       for (se2 = servtab; se2; se2 = se2->se_next) {
+               if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM)
+                       continue;
+ 
+               if (sin->sin_port == se2->se_ctrladdr.sin_port) {
+                       syslog(LOG_WARNING,
+                              "%s/%s:%s/%s loop request REFUSED from %s",
+                              sep->se_service, sep->se_proto, 
+                              se2->se_service, se2->se_proto,
+                              inet_ntoa(sin->sin_addr));
+                       return 1;
+               }
+       }
+       return 0;
+ }
+ 
  /* ARGSUSED */
  void
  echo_dg(s, sep)                       /* Echo service -- echo data back */
***************
*** 1092,1103 ****
  {
        char buffer[BUFSIZE];
        int i, size;
!       struct sockaddr sa;
  
!       size = sizeof(sa);
!       if ((i = recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size)) < 0)
                return;
!       (void) sendto(s, buffer, i, 0, &sa, sizeof(sa));
  }
  
  /* ARGSUSED */
--- 1115,1132 ----
  {
        char buffer[BUFSIZE];
        int i, size;
!       struct sockaddr_in sin;
  
!       size = sizeof(sin);
!       if ((i = recvfrom(s, buffer, sizeof(buffer), 0, 
!                         (struct sockaddr *)&sin, &size)) < 0)
                return;
! 
!       if (check_loop(&sin, sep))
!               return;
! 
!       (void) sendto(s, buffer, i, 0, (struct sockaddr *)&sin,
!                     sizeof(sin));
  }
  
  /* ARGSUSED */
***************
*** 1186,1192 ****
        int s;
        struct servtab *sep;
  {
!       struct sockaddr sa;
        static char *rs;
        int len, size;
        char text[LINESIZ+2];
--- 1215,1221 ----
        int s;
        struct servtab *sep;
  {
!       struct sockaddr_in sin;
        static char *rs;
        int len, size;
        char text[LINESIZ+2];
***************
*** 1196,1203 ****
                rs = ring;
        }
  
!       size = sizeof(sa);
!       if (recvfrom(s, text, sizeof(text), 0, &sa, &size) < 0)
                return;
  
        if ((len = endring - rs) >= LINESIZ)
--- 1225,1236 ----
                rs = ring;
        }
  
!       size = sizeof(sin);
!       if (recvfrom(s, text, sizeof(text), 0, 
!                    (struct sockaddr *)&sin, &size) < 0)
!               return;
! 
!       if (check_loop(&sin, sep))
                return;
  
        if ((len = endring - rs) >= LINESIZ)
***************
*** 1210,1216 ****
                rs = ring;
        text[LINESIZ] = '\r';
        text[LINESIZ + 1] = '\n';
!       (void) sendto(s, text, sizeof(text), 0, &sa, sizeof(sa));
  }
  
  /*
--- 1243,1250 ----
                rs = ring;
        text[LINESIZ] = '\r';
        text[LINESIZ + 1] = '\n';
!       (void) sendto(s, text, sizeof(text), 0, 
!                     (struct sockaddr *)&sin, sizeof(sin));
  }
  
  /*
***************
*** 1255,1268 ****
        struct servtab *sep;
  {
        long result;
!       struct sockaddr sa;
        int size;
  
!       size = sizeof(sa);
!       if (recvfrom(s, (char *)&result, sizeof(result), 0, &sa, &size) < 0)
                return;
        result = machtime();
!       (void) sendto(s, (char *) &result, sizeof(result), 0, &sa, sizeof(sa));
  }
  
  /* ARGSUSED */
--- 1289,1308 ----
        struct servtab *sep;
  {
        long result;
!       struct sockaddr_in sin;
        int size;
  
!       size = sizeof(sin);
!       if (recvfrom(s, (char *)&result, sizeof(result), 0, 
!                    (struct sockaddr *)&sin, &size) < 0)
!               return;
! 
!       if (check_loop(&sin, sep))
                return;
+ 
        result = machtime();
!       (void) sendto(s, (char *) &result, sizeof(result), 0, 
!                     (struct sockaddr *)&sin, sizeof(sin));
  }
  
  /* ARGSUSED */
***************
*** 1288,1303 ****
  {
        char buffer[256];
        time_t clock;
!       struct sockaddr sa;
        int size;
  
        clock = time((time_t *) 0);
  
!       size = sizeof(sa);
!       if (recvfrom(s, buffer, sizeof(buffer), 0, &sa, &size) < 0)
                return;
        (void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
!       (void) sendto(s, buffer, strlen(buffer), 0, &sa, sizeof(sa));
  }
  
  /*
--- 1328,1349 ----
  {
        char buffer[256];
        time_t clock;
!       struct sockaddr_in sin;
        int size;
  
        clock = time((time_t *) 0);
  
!       size = sizeof(sin);
!       if (recvfrom(s, buffer, sizeof(buffer), 0, 
!                    (struct sockaddr *)&sin, &size) < 0)
                return;
+ 
+       if (check_loop(&sin, sep))
+               return;
+ 
        (void) sprintf(buffer, "%.24s\r\n", ctime(&clock));
!       (void) sendto(s, buffer, strlen(buffer), 0, 
!                     (struct sockaddr *)&sin, sizeof(sin));
  }
  
  /*


-GAWollman

--
Garrett A. Wollman   | Shashish is simple, it's discreet, it's brief. ... 
wollman@lcs.mit.edu  | Shashish is the bonding of hearts in spite of distance.
Opinions not those of| It is a bond more powerful than absence.  We like people
MIT, LCS, ANA, or NSA| who like Shashish.  - Claude McKenzie + Florent Vollant



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9602231537.AA03433>