Bugtraq mailing list archives

Re: Source code to mstream, a DDoS tool


From: paul () MOQUIJO COM (Paul Cardon)
Date: Tue, 2 May 2000 01:58:17 -0400


Very nice writeup, especially the bits captured in the wild.  I had
almost completed an analysis based on the released source only.
Instead, I will add my comments to what is a already a strong piece of
work even though Dave needed to release it sooner than anticipated.  I
second the recommendation to review [12] for defense strategies.

-paul

Dave Dittrich wrote:

Communication
-------------

The handler expects commands to be contained entirely in the data
payload of a single TCP packet, not broken up character by character
in a stream.  This means that "telnet" cannot be used to control a
handler, but instead some other client program must be used to buffer
the command line before sending (e.g., a special command shell or port
redirector, netcat [19], etc. -- no special client was included in the
source posted on Security Focus [20]).

Actually, telnet can be used by switching it to line mode.  This mode is
used by telnet clients by default on some OSes.

Handler Commands
----------------

The handler command set is:

help

"commands" is an alias for "help"

servers
        List all currently known agents.

The agents may or may not be active.  This is the list of all agents
that have sent the "newserver" command to the handler at some point in
time.

stream <hostname> <seconds>
        Begin an attack against a single host, for the specified
        duration.  The handler resolves the hostname to an IP address
        and sends the command "mstream/arg1:arg1/arg2" to all agents,
        where "arg1" is the resolved hosts' IP address twice with a
        colon between (this simplifies argument parsing in the agent)
        and "arg2" is the duration in seconds.

The released source uses "mstream/arg1/arg2" without the colon and
repeated arg1.  Is the colon used only in the version in the wild?

quit
        Terminates the attacker's connection to the handler.

It also reports the termination to the connected users.

Agent Commands
--------------

stream/IP/seconds
        Starts streaming at IP address for specified duration in
        seconds.

This does not match the description of the corresponding handler command
above but it does match the released source.

Password protection
-------------------

(and can't simply hijack the TCP session, either, because of the command
buffering described in the Communication section.)

Hmmm.  I don't see why the session can't be hijacked.

Fingerprints
------------

Visible strings in the agent (in two truncated columns to save space)
are:

------------------------------------------------------------------------------
131.247.208.191                     _end
129.79.20.202                       htons@@GLIBC_2.0

Did you perhaps miss these when you were sanitizing?  The second one is
presumably the University of Indiana system mentioned in Appendix E.

Bugs in the source code for both handler and agent result in an
increasing number of raw sockets and UDP sockets in the agent (three
each are were witnessed on this agent), and an increasing number of
open file handles and UDP sockets in the handler (hundreds were shown
by Andrew Korty).

master.c neglects to do a close(fd) at the end of sendtoall and
send2server while server.c neglects to do the same at the end of
send2master.

The stream2.c attack floods the victim with TCP ACK packets, using
forged source addresses generated by random() (i.e., any or all
of the four octets will occasionally be zero) and incrementing source
port and sequence numbers, as seen in this code snippet:

By stream2.c, I assume that you mean the code sent to BUGTRAQ by Tim
Yardley that he later updated to set the ACK flag (also in [12]).

4.2.0.58.20000121112253.012a8f10 () students uiuc 
edu">http://www.securityfocus.com/templates/archive.pike?list=1&date=2000-01-15&msg=4.2.0.58.20000121112253.012a8f10 () 
students uiuc edu</A>

The released code server.c contains DoS code ripped almost verbatim out
of stream.c with the ACK flag fix and then modified to hit multiple
targets.  The only other major change is that stream.c gave the attacker
the option to select a specific destination port.  server.c always
randomizes the destination port on the victim host.

If you look at Yardley's analysis (also in [12])

4.2.0.58.20000125093641.0118b5e8 () students uiuc 
edu">http://www.securityfocus.com/templates/archive.pike?list=1&date=2000-01-22&msg=4.2.0.58.20000125093641.0118b5e8 () 
students uiuc edu</A>

then you can see that the attack could have potentially worse effect if
the destination port is selected to match an open port on the victim
host.

Weaknesses
----------

Control communication (attacker <-> handler and handler <-> agent)
is not encrypted, and is thus subject to session hijacking

This is a contradiction of the statement under Password Protection
above.

Other weaknesses:

The handler does not automatically clean up the file containing the list
of known agents.  The stream and mstream commands will blindly send
commands to agents that no longer exist but did at one time.

The code attempts to avoid adding an ip address multiple times to the
list of known agents.  However, a bug (common mistake with continue and
nearest loop) causes the check to fail in its purpose so the same agent
will have its ip address newly recorded in the agent list each time it
notifies the handler with "newserver".  As a result, the handler will
send ping, stream, and mstream commands to an agent however many times
its ip address is recorded in the agent list.

In server.c note the declaration:

  char *ipps[50]

and the code snippet:

  if ((tmpip = strtok(ips, ":")) == NULL) continue;
  ipps[0] = (char *) malloc(strlen(tmpip)+2);
  strncpy(ipps[0], tmpip, strlen(tmpip)+2);
  y = 1;
  while ((tmpip = strtok(NULL, ":")) != NULL) {
    ipps[y] = (char *)malloc(strlen(tmpip)+2);
    strncpy(ipps[y], tmpip, strlen(tmpip)+2);
    y++;
    }
  ipps[y] = NULL;

If an agent receives the mstream command containing a second argument
with greater than 50 colon-separated fields, it will merrily continue
mallocing memory and stuffing the addresses into ipps well past the
array bounds.  Could get interesting when the following code attempts to
free the malloced space:

  for (y = 0 ; ipps[y] != NULL ; y++) free(ipps[y]);

The list could continue but these are the major ones that affect visible
behavior.  Dave was kind when he described the code as more primitive
than other known DDoS tools.

The next logical evolutionary steps
-----------------------------------

It is not a stretch to assume that features from other published DDoS
tools will make their way into tools like mstream.  Briefly, some
likely enhancements to this code include:

7) Target destination port selection
8) Automated cleanup of known agent list

Appendix A - References
-----------------------

[12] BUGTRAQ threads on the stream.c DoS attack and its fallout
        http://staff.washington.edu/dittrich/misc/ddos/stream.txt


Current thread: