The Tarpit

"MOST USEFUL APPLICATION OF 2001" - Jim Rapoza of eWEEK Labs
"LaBrea gives its users a tactical advantage over 'zombie' computers like those compromised by the Code Red worms. The computer security industry will find it a very intriguing utility." -- Rob Rosenberger, editor,
"We recommend that network administrators seriously consider implementing LaBrea, to finally relegate worms to the status their name implies. " -- eWeek

See the LaBrea@Home page here
Download the source code here
or here
For those of you running NT
You're about to become part of the solution, instead of part of the problem!
Download LaBreaNT
Download a white paper entitled
"Welcome To My Tarpit - The Tactical and Strategic Use of LaBrea"
by Tom Liston, author of LaBrea
LaBrea can also be used from a Trinux boot disk.
See the Trinux site for details.
If you're having trouble compiling or running LaBrea, please do the following things BEFORE asking for help:
  • Download, config, make and install libnet from
  • Download, config, make and install libpcap from
  • Run LaBrea in test mode (-T) and check that the output makes sense.
  • Under some newer kernels LaBrea has problems staying in promiscuous mode. Issue a 'ifconfig eth0 promisc', substituting for 'eth0' as necessary, to force the interface into promiscuous mode. Anyone able to explain WHY this is happening?
Thank you,
The Management

Current Version: 2.3
Please make sure you have the current version.

Added 11/20/2001:
Something that I've been looking into for a while:

Linux window probes are "different".
So far, LaBrea hasn't been recognizing them correctly. I've added "beta" support for correcting this issue (the new "-L" option).
Feedback is requested.

WARNING: Because they caused a GREAT DEAL of CONFUSION The message format has been changed and (hopefully!) clarified.

Added 10/2/2001:
I messed up.
In fixing something else, I broke logging... Sorry!

Added 10/2/2001:

    Added many new options
  • -T : Test mode - Prints diagnostic info and exits.
  • -d : Don't detach
  • -o : Output to stdout. Direct logging where YOU want it!
  • -R : "Soft restart" mode
  • -q : Do not log "Out of netblock" ARPs

Also... a number of small bug fixes (WHAT? I made mistakes???) and code improvements.

Added 9/6/2001: A new "-p" option to trap connection attempts using "persist" state. This essentially traps the connection attempt FOREVER. See the documentation below for full details.

Added 8/28/2001: Based on a suggestion by Anders Reed Mohn, I've added option "-a" to turn off LaBrea's default behavior of answering SYN/ACKs and PINGs.

Added 8/27/2001: I've re-introduced random ID and ACK numbers. One of Donald Smith's suggestions was that random number generation was computationally expensive and therefore was too slow (he's correct... it is), so in the original v1.1 I pulled them and used fixed IDs and ACKs. In v1.5, I pre-generate a list of random numbers and then cycle through the list.


  • SECTION 1 - What is it?

  • LaBrea is a program that creates a tarpit or, as some have called it, a "sticky honeypot". LaBrea takes over unused IP addresses on a network and creates "virtual machines" that answer to connection attempts. LaBrea answers those connection attempts in a way that causes the machine at the other end to get "stuck", sometimes for a very long time.

  • SECTION 2 - What prompted you to write it?

  • The original concept for LaBrea started in response to the CodeRed worm. Our IP block was being scanned non-stop. I began to wonder: "Is there anything that can be done to stop this worm?" Of course, many things came to mind, but most of them were illegal. Then, late one night, I thought, "Maybe I can't stop these machines from scanning, but I bet I can slow them down..."

    The following morning I posted to the INTRUSIONS list at

        "I'm pretty sure that most of you are using your allotted ip
        address space somewhat like I am.  At any given time I'm using
        only about 20-30% of the ip addresses that I have available.  What
        if I could put something on those other 80% of my ip addresses
        that would give "Code Red" something to play with that would slow
        it down to a crawl?  A sort of "DoS" back at the worm.
        Since those "extra" ip addresses aren't actually expecting any
        inbound traffic, anything fired at them can safely be assumed to
        be "bad" traffic.  If I wrote a little piece of software that sat
        on those ip's and listened on port 80, anything that it heard
        could safely be "played" with.
        My hypothetical program should be pretty simple:  you see an
        inbound packet at port 80 with SYN set, and you craft up a return
        packet with SYN/ACK set and perhaps an option to set the MSS to
        something small... say about 60 bytes.  What does that do?  Well,
        as far as the attacking worm is concerned, after replying with an
        ACK, it has completed a three-way handshake...  it's connected.
        It's also been told to send information back to you in small
        chunks (to keep traffic to a minimum), which it dutifully does.
        The only problem is, my program just answers SYN packets and
        ignores everything else.  So now the worm has to sit around while
        the whole TCP connection times out.  I'm not sure what the timeout
        NT is, but I think most stacks are pretty persistent about "good"
        connections, so it should hang it up for a good long time."
    A few days later, Mihnea Stoenescu sent a message back to the list:
        "Tom's concept works - I have a living proof.
        For a few hours I've been teergrubing CodeReds via three-way
        handshake on behalf of an entire C-block, by using only one host.
        At a rate of 6 hosts per minute hitting my block, I'm consuming
        circa 15 minutes of effective attack time every minute. A lot of
        hosts can be scanned in 15 minutes."

    Mihnea used a modified version of a program called Couic. But Couic was written to do a lot more, so I went though, hacked it apart, and put it back together to make "CodeRedneck."

    CodeRedneck did essentially what I described in my post, but it only worked on "real" connections that had some kind of firewalling that kept the underlying machines from responding. It did nothing for all of those "unused IPs".

    After CodeRedneck was done, I began trying to figure out how to deal with those unused IPs. Somehow I had to "create" machines, and my first thought was to use IP aliasing under Linux. Using the Trinux distribution I was able to put together a boot disk that, using a list of unused IPs, "created" new machines, then firewalled and "tarpitted" them. I called the new version "LaBrea".

    The day after I released LaBrea, someone asked if it would be able to handle a /16 network (65,535 hosts). Well, I didn't think my little program would handle it, and, well... it didn't. And so... I tried again.

    That's how this new version of LaBrea came into being...

  • SECTION 3 - Why should I run it?

  • If you're a network administrator, I don't REALLY need to explain this. They're out there, every day... 24/7/365. The scanners. They're out there and you get to sit and watch them beat on your network, doing reconnissance. Now you have a chance to make their life more difficult.

    Besides that... it's fun.

    And, as Mihnea so wonderfully put it, you can come into work in the morning, look at your logfiles and say "Wow - I'm *actually* saving the world"

    OK, maybe "saving the world" is a little much...

  • SECTION 4 - How does it work?

  • This new version works by watching ARP requests and replies. When it sees consecutive ARP requests spaced several seconds apart, without any intervening ARP reply, it assumes that the IP in question is unoccupied. It then "creates" an ARP reply with a bogus MAC address, and fires it back to the requester.

        An example (from a tcpdump of LaBrea running on my network):
        14:18:28.832187 ARP who-has xx.xx.xx.13 tell xx.xx.xx.1
        14:18:29.646402 ARP who-has xx.xx.xx.13 tell xx.xx.xx.1
        14:18:31.707295 ARP who-has xx.xx.xx.13 tell xx.xx.xx.1
        14:18:31.707574 ARP reply xx.xx.xx.13 is-at 0:0:f:ff:ff:ff

    There is no xx.xx.xx.13 machine on my network. In this case, the timeout was set to 3 seconds (it's a command line parameter), and when that final "who-has" came in, the "is-at" reply that you see was generated by LaBrea.

    There isn't a MAC address of 0:0:f:ff:ff:ff either. It doesn't exist.

    But now, the router (xx.xx.xx.1) believes that there is some machine at xx.xx.xx.13, and that it resides on the MAC address 0:0:f:ff:ff:ff, and so it dutifully sends packets on. In essence, we've created a "virtual machine" on that IP address.

    Now, LaBrea also watches for TCP traffic destined for the ether address 0:0:f:ff:ff:ff. When it sees an inbound TCP SYN packet, it replies with a SYN/ACK that "tarpits" that connection attempt. Everything else is ignored. (Well... sort of. This new version also tries to give its "virtual machines" some character... you can ping them, and they respond to a SYN/ACK with a RST...)

    There's more to it than that (obviously...) but you'll need to read the source code.

  • SECTION 4.1 - What is "persist mode" trapping?

  • Persist mode trapping is new in LaBrea version 2.0. It forces connections into a state called the "persist" state. While in persist state, you can literally hold a connection open for as long as you like.

    To do this, the LaBrea "server" software allows a normal three-way handshake in response to a connect attempt. During the handshake, the server sets a small (5 byte) TCP window. When the client sends its first 5 bytes of data, the server responds with a TCP window of 0 (wait). The client then shifts into the "persist" state, where it sends what are called "window probe" packets at intervals that increase to a maximum of 4 minutes for an NT stack. The LaBrea server answers these probes to hold the client in the persist state. At this point, a connection can be maintained with a throughput of approximately 1215 bytes per hour. All of this can be done without maintaining any "state" on the connections. This vastly simplifies LaBrea's code.

    Because you're holding connections open, and because there is a bandwidth "cost" associated with doing that, the "-p" option requires that you specify the maximum bandwidth (in bytes/second) that you want to allocate to doing this. You set the maximum bandwidth, fire it off, and LaBrea takes care of the rest. It keeps a 5 minute running window of bandwidth allocated to holding open connections, and does it's best to keep you at or near the maximum you allow. (FYI: 1 byte/second is roughly equal to 3 scanning threads).

    What happens to the threads you don't grab? LaBrea still tarpit's 'em... just like before.

  • SECTION 5 - How do I run it?

  • Glad you asked!

    Usage: LaBrea  
       -i interface : Set a non-default interface
       -t datasize  : Set connection throttling size in bytes (default 10)
       -r rate      : Set arp timeout rate in seconds (default 3)
       -s           : "Safe" operation in a switched environment
       -l           : Log activity to syslog (Note 8)
       -v           : Verbosely log activity to syslog (Note 8)
       -F filename  : Specify a BPF filter filename (Note 2)
       -h           : "Hard" capture IPs (Note 4)
       -x           : Disable IP capture
       -m           : User specified netmask (Note 1)
       -n           : User specified network number (Note 1)
       -V           : Print version information and exit
       -a           : Do not respond to SYN/ACKs and PINGs (Note 6)
       -q           : Do not report odd (out of netblock) ARPs
       -T           : Test mode - Prints out debug info but DOES NOT RUN
       -R           : Soft restart - Wait while recapturing active connects
       -p maxrate   : "Persist" state capture connect attempts (Note 7)
       -b           : Log bandwidth usage to syslog
       -d           : Do NOT detach process.
       -o           : Output to stdout instead of syslog (Note 9)
       -P           : Persist mode capture only.
       -L           : Beta "Linux" window probe capture code.
    Note 1:
     The network number and netmask are normally loaded from the interface.
     If you're using an interface that has no IP, you'll have to provide BOTH of
     these numbers.  These MUST be correct or BAD things may happen!
    Note 2:
     Connections specified by the BPF filter will also be tarpitted.  These
     connections MUST be firewalled to DROP inbound packets or this won't work!
    Note 3:
     /etc/LaBreaExclude contains a list of IPs (1/line) that you DON'T want LaBrea
     to capture. You don't need to specify "active" IPs.  LaBrea won't capture an
     IP with a machine on it. This is only for empty IPs that you DON'T want
     captured. Re-read on a SIGHUP.
    Note 4:
     /etc/LaBreaHardExclude should contain an IP list that you NEVER want LaBrea
     to hard capture.  Only necessary with the -h option.  Re-read on a SIGHUP.
    Note 5:
     IPs can be specified as either a single address (i.e.: "") or as a
     range of addresses (i.e.: " -")
    Note 6:
     By default, LaBrea "virtual machines" respond to an inbound SYN/ACK with a
     RST and are "pingable".  The -a option eliminates this behavior.
    Note 7:
     LaBrea will permanently capture connect attempts within the limit of the
     maximum data rate specified (in bytes/sec).
    Note 8:
     With version 2.1+ you can use 'kill -USR1 ' to toggle logging
      If logging was not enabled at start this sets the '-l' flag
      If logging (-l | -v) are set this saves the value and turns off logging
      If logging is presently toggled off it restores the saved level (-l | -v)
    Note 9:
     This sends log information to stdout rather than to syslog.  This option
     also implies and sets the -d option (Do NOT detach process).

  • SECTION 6 - What do all of those options do?

    -i devicename If your machine has more than one interface, and LaBrea choses the "wrong" one, you can use this option to direct it to the correct one. Use a device name ("eth0") as a parameter.
    -t number Since you're "inviting" the scanners in, you might as well place some restrictions on them. This option sets the TCP window advertisement to limit the amount of data sent by the scanner. The number of data bytes to allow per packet is passed as a parameter. (Default 10)
    -r number The number of seconds to wait between arp requests before deciding that an IP address is unused. The exact protocol is:
         On an IP by IP basis, we store a time and an originating
         IP address:
         1) When you see an ARP request, check the current time:
             a) If currently stored time is 0 or the arp comes from
                a different address than the one stored, store the
                current time and the requesting IP and return.
             b) If the stored time is less than "-r" seconds ago,
                ignore it and return.
             c) If currently stored time is more than a minute ago,
                store 0, return. (Max timeout)
             d) Otherwise, grab the IP!
         2) See an ARP reply, set stored time to 0.
    The default timeout is 3 seconds.
    -s Under a switched environment it is possible for LaBrea to see an ARP request, but not see the resulting ARP reply. LaBrea can still work under these conditions by sending out "mirror" ARP requests of its own. When it sees an inbound ARP request, LaBrea sends out an ARP request for the same IP, with itself as the target for the reply.
    -l Logs the IP addresses of machines that are "teergrubed" (tarpitted) to syslog
    -v Logs verbosely to syslog. It logs IPs "captured", IPs "teergrubed" and logs all activity from the "teergrubed" hosts.
    -F Designates the name of a file containing a BPF filter pointing to machines/ports to add to the tarpit. As with the command line BPF filter, these connections MUST be firewalled to DROP inbound traffic. For more on BPF filters, see the tcpdump(8) manpage.
    -h This instructs LaBrea that once it captures an IP address, it needn't wait for a "-r" timeout the next time around. IPs are "hard" captured.
    -x This instructs LaBrea NOT to capture IPs
    -m ipstring
    -n ipstring
    Sometimes you might run LaBrea on an unconfigured interface (one without an assigned IP address). Because LaBrea normally pulls information about your netblock from the IP information assigned to the interface, it is "missing" necessary information in this situation. You'll need to use these options to provide it. Pass the "netmask" and "network number" with these arguments. Note: KNOW WHAT YOU'RE DOING. You pass the numbers in standard form: i.e. ""
    -V Print out version information and then exit.
    -a By default, LaBrea's "virtual machines" will respond to a SYN/ACK packet with a RST. This is nice behavior, because it makes it difficult for people to use your empty IP addresses to "spoof". Also, it will respond to a ping, which acts as an invitation to anything that preceeds a scan with a ping to see if the target exists. Like say... NMap. If you DON'T want this behavior, use the "-a" option to disable it.
    -p maxbw This is UNBELIEVABLY COOL (if I do say so myself...) If you specify this flag and a maximum bandwidth, several things will happen. First of all, this forces data throttling to 5 bytes (see the "-t" option above). Then, when a connection is attempted, LaBrea will force the connection into what it known as "persist" state. In persist state, the connection will NEVER time out. You'll literally hang onto the scanning thread until you stop or they stop. Running unchecked, this could have a very BAD effect on your bandwidth, so LaBrea will make every effort to only allow this process to take up the maximum bandwidth that you specify (in bytes/second). If it can't capture a connection, LaBrea will still tarpit it. Note: It'll stay pretty NEAR your MAXBW number... YMMV.
    -b This will send an update on the current bandwidth being consumed by the -p option to syslog every minute. If you're interested... (Note: it'll only work if you have -p enabled. Duh...)
    -d Don't detach the LaBrea process. Some people wanted to run LaBrea under the supervision of other processes, so this will keep LaBrea from running in daemon mode.
    -o OK... So LaBrea can be a bit verbose... And some of you want a way to send its output to something to log and display what your tarpit is doing. Fire off LaBrea with this flag set. It won't detach, and all messages that would've gone to syslog will now print to stdout. Send this where YOU want it to go...
    -R "Soft restart" mode. If you need to restart LaBrea, and you do it quickly enough, you can continue to hang onto many of the connections you've captured. This flag will force LaBrea to wait for five minutes before capturing (-p) anything new. This allows you to continue to hold open any connections and get your bandwidth calculations running and acknowledging all of those "old" connections before adding anything new.
    -q Now why would anyone have traffic from mixed netblocks on the same network?? Well, I found out. Mia culpa. This lets you shut up LaBrea's crabbing about "IP address not in netblock". Forgive me...
    -P Persist mode capture only. This tries to cut down on the "standard" tarpitting. Because the same packet "conversation" leads to persist mode and tarpitting, it isn't really helpful. But someone asked...
    -L Linux (bless its little heart) uses a "different" format for window probes from Windows' TCP/IP stack. This one has been bugging be for a long time now, which is why I went ahead and worked on it, rather than all of the other things people have wanted to include. (Sorry!) This should (I believe!) get LaBrea to recognize and persist mode trap Linux connection attempts. It's BETA (just because I'm too much of a wimp to say "Yeah, it'll work... trust me...").

    If you keep getting a "you need to read the LaBrea.README file" message, you need to read SECTION 7 (Potential Issues) to find out what command line parameter you need to get past this.

    LaBrea also uses two files to control its operation:

    /etc/LaBreaExclude - contains a list of IPs (1/line) to exclude from LaBrea's attention. LaBrea won't do anything to these IPs.

    /etc/LaBreaHardExclude - contains a list of IPs that LaBrea won't hard capture. (Note: this only makes sense when using the -h option.)

    Note: IP address can be specified either as single addresses (i.e.: "") or they can be specified as a range of addresses: (i.e.: " -").

    Additional Note: LaBrea SHOULD never capture an IP that has an active machine sitting on it. These two files are used to give you control over "empty" IP addresses. That being said, it certainly doesn't hurt to "exclude" active IPs.

    Another additional note: Sending LaBrea a SIGHUP will cause it to re-read the "exclusion" files and report packet statistics to syslog.

  • SECTION 7 - Potential Issues

  • YOU MUST UNDERSTAND THIS: As a default, LaBrea captures IP addresses. That means that LaBrea creates a "virtual machine" that sits on any UNUSED IP address that it sees. If you decide you want to start using one of the IP addresses that LaBrea has laid claim to, THERE IS THE POTENTIAL FOR PROBLEMS. LaBrea has been written so that it does everything it can to move out of the way. If LaBrea notices a machine pop up on one of the IP addresses it is controling, it will even go so far as to re-route any traffic for that address that comes to its "bogus" MAC to the correct MAC, until everything gets straightened out. (Note to purists: LaBrea does not alter the "ttl" field of the forwarded packets when it does this.) Problems may arise because there are things beyond LaBrea's control. Switches and routers may feel compelled to tell you when you first attempt to use an IP address that it is already in use. If your switch or router does this, there is nothing that LaBrea can do about it. Judicious use of the "exclusion" files can minimize problems, as can reconfiguring the router or switch to "timeout" its cache more quickly, but DON'T BLAME ME! YOU HAVE BEEN WARNED!

    By the way, if your version of LaBrea has been compiled with USEZFLAG defined (the default), you'll need to pass it a command line parameter of "-z", in addition to any other flags, to get it to run.

    Sorry. But at least it got you to read the instructions...

  • SECTION 8 - How to compile

  • LaBrea requires both libnet and libpcap to compile. Other than that, it should simply "make" with the included Makefile. It has been tested under Linux. That's all. If you are successful at building it on another platform, please let me know!

  • SECTION 9 - I still don't get it...

  • Questions, comments, hate mail, and praise can be directed to

  • SECTION 10 - Legalese

  • This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

  • SECTION 11 - Acknowledgements

  • I couldn't have written this without the patience and help of a number of people.

    The beta testers who put up with my constant tinkering:
    Barton Bruce, Ben Curran, Andrew Daviel, Bill Dodd, Becky Pinkard, and Micropterus Salmoides.

    Tim Rushing who came to my rescue and offered to host the website when the downloads of the original LaBrea boot disk were too much for my connection to handle.

    Matt Franz for putting together the Trinux package.

    Mihnea Stoenescu for proving it would actually work.

    Anders Reed Mohn for suggesting the -a option, which, as I promised, was named after him.

    Many thanks to Rick Downes of Radsoft for all his help and encouragement. If you deal with any type of Windows environment and you haven't checked out Radsoft's Extreme Power Tools, you really, REALLY should.

    Thanks also to Rob Rosenberger of VMyths for his advice and assistance.

    Also a very special thanks to Donald Smith for putting up with LOTS of questions (and actually answering most of them) and for letting me bounce ideas off him.