Strategic Security Intelligence
Fred Cohen
&Associates
Responder Manual

Responder Manual
Copyright (c) 2001-3 Fred Cohen & Associates - ALL RIGHTS RESERVED
Help Card
Responder Applications

The Basics:

Who: Responder was written by Fred Cohen with assistance from Don Cohen. It uses a modified version of the raw socket package for CLISP, CLISP, C, and Linux - which means that it rests on the shoulders of giants. It is intended to be used by those who would defend their networks through active defensive measures. In order to use Responder at the level of setting up simple responses for simple cases, the operator is expected to have basic network knowledge, including details of IP addresses, gateways, and something of an understan ding of packets and how and why they operate. Responder can also be programmed at increasing levels of sophistication by increasingly sophisticated operators - without any top end in sight. It helps to know Lisp and a great deal about the details of packets and protocols, and it also helps to know your enemy and their tools.

What: Responder listens to packets on interfaces, manipulates them, stores information about them if desired, and sends, possibly altered or augmented, packets back out. It has a number of built-in manipulation functions designed to selectively create cognitive clarity or dissonance based on what comes in and the operator-provided specification of how to deal with it. For example, the operator may specify that certain computers are bad, based on IP addresses, and indicate that they should be 'dazzled', 'mirrored', 'forged', 'ignored', 'slowed', 'attacked', and so forth, in select ways. Similarly, 'good' computers might have some of their packets 'posed' as packets for another network.

Where: Responder was developed in my living room in Hudson, Ohio then in my garage in Livermore, CA, and now in the distributed and ever-expanding network of small shops and boutiques that form the global network of my associates. Responder can be situated at different points in your network depending on its purpose. Since it has multiple interface capabilities, it can be situated at control points between LANs or anywhere else a router or gateway computer might be placed. In this sort of location it can act as a sort of firewall, router, address translator, and general purpose security and communication facilitation device. You can also place Responder on one or more LANs and have it act to defend those LANs against illicit use on the same LAN segment. The more you know about networks and how they work, the more clever things you will likely find to do with Responder. I even know people that use it so they don't have to worry about setting up gateway addresses or other such things on their internal networks.

Why: Responder exists because the stoic defenses of old were designed to take abuse, but not to inhibit further abuse. They did not make things more difficult for the attacker than it absolutely had to be in order for the defense to operate. Responder is a mechanism intended to increase the difficulty to the attacker by making their tools and techniques less effective than they would otherwise be. It also provides the same sorts of stoic defense capabilities as previous defenses, but it enhances them with the ability to confuse attackers while having no noticeable negative side effect on the normal user.

When: Responder was developed starting in late 1995 and its initial development continued into 1996. Deception ToolKit was in its line of ascension and one of the side effects of its seemingly eternal development was a series of experiments and papers on deception written in 2001. It undergoes development even as I write and will likely continue its development for the foreseeable future. As long as attackers continue to develop, defenders will continue to find ways to respond to them. Responder can be used at any time when power and networks are available, but it is most enjoyable to use it when you have the chance to watch the attackers as they writhe in frustration.

How: The computer that Responder runs on is typically dedicated to this purpose and does not appear to exist from a standpoint of network traffic, except of course that it makes the network appear to operate quite differently than it otherwise would. It does not need or want an IP address - please don't feed it one. It observes packets using the 'Promiscuous' mode of Ethernet cards and makes those Ethernet packets available to a program written in C and Lisp. This program examines and manipulates packets based on the operator's specification. The program is extensible in the sense that the advanced operator may add to or alter the program to do precisely what they desire, and of course this is how we develop custom response mechanisms for customers who want a little bit more or different here or there than what you can purchase over the counter. Responder also has several operator 'languages', special purpose specifications, designed to allow some of the more common things to be done with a minimum of knowledge.


Getting Started:

Responder exists in both hardware and software incantations.

Step 1:

Hardware: Plug it in, turn it on.

Software: Boot from the Responder CD-ROM in the PC you are dedicating to this task. You may have to change the BIOS to boot from a CDROM instead of your hard drive or floppy. Check with your equipment manufacturer for details.

Step 2: Software Only: Get CD-ROM to work

Software Only: Identify which interface card is associate with which device names in your computer. Device names are shown during the bootup process - typically as 'eth0', 'eth1', and so forth. As each interface comes up , it should light its LEDs at the interface point (assuming each interface is connected to a network). Note which is first, second, third, etc. and label the interfaces on your computer. The first one to turn on is 'eth0', the second one is 'eth1' and so forth. Some of your interfaces may not work with the Responder CD. Most do, but there is no guarantee. Our hardware version is designed to eliminate these problems...

Step 3: Configure it (and save the configuration files)

The easy way to run whatever configuration came with responder:

A GUI for responder is under development. Programming Responder is described throughout the rest of this manual.

Step 4: Operate it

The simplest way to operate it, once configured, is to just leave it alone. It pretty much takes care of itself.

Step 5: Maintain it

If you change things in your network that you were asked about in installation, you might have to change the installation. To do that, do step 3 again.

If Responder is configured to produce audit trails, you need to periodically examine them - or they won't be of any use. Older audit trails may be automatically deleted to save disk space (if it starts running low), so track your system and figure out how often you will need to check log files.

Step 6: Enhance it

Now the fun begins. For details, read all about it below...


At factory install

At factory install, Responder ignores all traffic, has no IP address, and no external services. This is a good thing, because it makes the system practically invincible from network attack and assures that it has no negative impacts on your network, but it is also a bad thing because it does nothing at all to protect your network.

In order to get Responder to start to protect your network, you need to configure it to do something. Before you do that, here's a little note.

I hope this is clear. Responder operates under the Linux operating system. Linux, like other operating systems, can do many things. Some of those things are safe, while others are less safe. In order to operate Responder, you do not need to have any IP address assigned to the computer Responder runs on. Not having an IP address makes Responder far safer from network attack than it might otherwise be because there is no way to explicitly direct packets toward it and there are no external 'services' that it provides which might be exploited to the attacker's benefit. Responder's internal operation is such that no external packets will likely overflow buffers or otherwise induce misoperation UNLESS YOU CHANGE THE WAY IT WORKS. So don't.


Operating modes

Responder is general purpose in that it can do any transform on packets or packet sequences that you can get a computer implement. That means that it could - literally - replace a whole computer network - or act as if it were the whole Internet... if it had enough storage and was fast enough. But it's doesn't and it's not. So, since replacing the whole Internet is not a likely option, let's focus on some of the things it was built to do. These are the current standard operating modes:

Responder implements modes by translating all other modes into Programmed mode programs which are compiled and run in the Responder. Because other modes compile their specifications into Programmed mode, you can start with a program in any other mode, translate it into Programmed mode, and modify it from there. This is a very convenient way to get started.

Router mode

The format for router mode is similar to the format of many routers. If you are clever (or if you are clever enough to hire us to do it) you (or we) can program Responder to use the identical syntax to one of your routers. the normal syntax for Router mode goes like this:

Here are some examples of valid rules:

eth0 *	*.*.*.*:1024-65535:0:0:23:23:54:56 	*.*.*.*:80  		-	F eth1	; Forward everything indicated from eth0 to eth1
eth1 AT *.*.*.*:1024-65535      1.2.3.45-90:0-1023      SafU    Z       ; Dazzle selected ARPs and TCP SYN/URGs (no ack/fin)on eth1
eth1 U	*.*.*.* 		*.*.*.*			C	M	; Mirror all UDP packets on eth1 and continue
eth1 IT	*.*.*.* 		1.2.*.*      		-	F eth0	; Forward selected ICMP and TCP on eth1 to eth0
eth2 *	12.23.45.67 		90.43.32.234 		-	G I 50	; Garble (Itch) eth2 packets from 12.23.45.67 to 90.43.32.234
eth2 T	10.0.128-255.* 		*.*.*.* 		F	S 30	; Slow eth2 TCP traffic for fin packets
eth1 * *.*.*.*:1024-65535	1.2.3.45-90:0-1023	-	W	; Weird mode for other eth1 service attempts
eth4 T	*.*.*.*			12.23.34.*		-	P -.-.-.- 21.22.23.+0 eth3	; Pose back channel
eth3 T	21.22.23.* 		*.*.*.* 		-	P 12.23.34.+0:+23:0:r:g:23:+5:+12 -.-.-.- eth4 ;Pose as from 12.23.34.*
.

Note that a valid rule file ends in a line with only a '.' (period) on it. All lines thereafter are ignored, which can be convenient for more extensive documentation associated with the rule file. If the end of file is reached before such a line, the rule set is assumed to be completed at the end of the file. Once you have prepared a valid rule file, you can run the following command to translate it into a lisp expression and detect any errors in your specification:

Once this result looks right, you can load, compile, and run the rules by typing:

Invalid rule files are treated rather poorly and the diagnostics are obscure at best, but on the other hand, the rules should not be that hard to get right since each has the same fields. All fields must be properly capitalized and only spaces may be used to separate fields. Debugging messages in the form of each line read are printed out, so if there is a syntax error, it will apply to the line just printed and include a line number. Syntax errors will also cause the rule to be replaced by a "SYNTAX ERROR" printout that will replace the rule so that any time the rule is missed the error message will be printed. In addit6ion, a generic syntax error will be printed at the start of every packet reception.

Here are a few examples of rules file I have used. The IP addresses and ports have been changed to protect the users:

The net effect is to slow down many Internet worms. When they try to come to these addreses, which have no legitimate services on port 80, their inbound packets are accepted, and they are provided with consistent forged ARPs and ICMP responses, but no responses are made after the TCP 'connection' is made. This tends to run the attacking computers out of resources because they only have so many available outbound ports and to get them stuck on these IP addresses because of the retry mechanisms in TCP that continue trying to complete the uncompletable connection.

You can view the lisp code produced by a rule set by using:

Here is the result of applying a version of router-parse to the rule set above:

The output begins by describing what was loaded to start compilation. It then indicates that the RAWSOCK package is being used to interact with the interface card. It lists the lines of the router file and the shows the program generated by these rules. It starts by setting the packet number PNUM to 0 and then creates a loop that eternally gets a packet, increments PNUM, and executes a conditional COND. Lisp has big numbers so that the PNUM count can never get so large as to cause an overflow (actually - it is limited to the largest number that can be represented in the memory of your computer using 8 bits per byte and as many bytes as your RAM can hold). (FACEMATCH '(101 116 104 48) (SLOT FROM 'SA_DATA)) matches the string 'eth0' to the ethernet data arriving on the interface that got the last packet. (EQUAL (ARPTYPE) :ARP) checks if it is an ARP packet. (LISTCMP (ARPDST) '(10 2 3 (4 5)) checks the ARP destination address against the IP address 10.2.3.4-5. (PROGN (FORWARD '(101 116 104 49)) T)) forwards the result to ethernet 1. The other conditions are handled in a similar manner and finally, 1099 is the length of the source code for the function.

Here's another simple sample in the same vein:

The difference here is that all TCP is Itched. The effect is quite extrordinary. In effect, Garbling in 'Itch' mode means that packets are mirrored with the initial parts of packet content left untouched, while the latter part is garbled. Remote worm code entering this site starts by connecting to port 80, which is basically mirrored untouched. Then, as the work tries to insert its code into the defending systems, the mirror sends the same code back to the attacker, but the garbling effect causes the latter part of the attack code to become randomized. This means that, while the initial part of the break-in code that lets the worm in runs on the attacking computer, the coherent code of the worm that tends to reside near the end of the packet is no longer coherent when it is executed on the attacker's machine. The majority of incoherent byte sequences executed by processors causes programs to fail. The net effect is that the worm enters the attackers computer and crashes it.

Here's an example that shows some of the more complex operations.

Note the importance of using the hash sets in terms of rule (and thus time) savings. Without the hashsets, this would have taken about 2,000 rules - with hash sets it takes only 11 rules. Please feel free to parse it yourself. The resulting function is 7793 bytes long.

Performance Enhancement

Performance of Responder is quite good. We have run traffic at near saturation levels on several 100Mbps Ethernets using a 350Mhz processor with an inexpensive interface card without packet loss. Performance is, however, largely effected by the rules you choose ond the amount of logging used.

The first thing to note is that when using the D and V modes for verbose output and detailing, response times can become quite long. In ping flood experiments we were able to get ping performance to more than a second of delay with all logging turned on and output going to an X11 display. We we3re also running TCPdump on all three Ethernets. When we removed D and V from the options field except on rules were particularly interested in, response time stayed below a milisecond.

Another critical performance enhancer is keeping the number of rules small. With the use of hash functions we have turned rules sets with thousands of rules in to sets with a few rules. The net effect was dramatic performance enhancement similar to the results of logging (but not as stark). We have done quite complex response mechanisms with only 10-20 rules, including gateway routing for select systems, bad computer differentiation and deception, select logging, and translations between three networks.

The third thing to do for enhanced performance is to order rules so that the things that are encountered most often are triggered first. Rule ordering is a complex issue because you are deinfing a finite state machine by the order of your rules. It is the source of many mistakes by less experienced folks and there are some subtle things that can happen with rule reordering. Still, if you can find an ordering that uses earlier rules more often performance will be faster. Also note that by trying to exercise different rules an attacker might be able to tell something about the rule ordering. It is an interesting covert channel that can be largely avoided at the cost of performance - but that discussion must go elsewhere.

The last thing to do is be careful about your lisp code. We have been pretty careful about our parser and as a result, you will see that in many (perhaps most) cases, when a check does not have to be done it is not done. For example, when you use '*' or '=' for a field, in many cases, no check is done for that field at all. If you don't include ports or MAC addresses, no check is generated for them. This makes the program smaller, faster, and more efficient at runtime. You can do the same thing in your lisp code. Avoid inefficient constructs, don't make unnecessary loops, and don't do recursive functions. It sounds almost blasphemous to say that to lisp programmers, but performance is improved when less memory allocaiton is done, and recursion uses lots of memory allocation.

Intrusion Detection

It turns out that in router mode, Responder makes a real nice intrusion detector. By selectively using d, D, v, and V options, you can configure your system so that all non-permitted packets generate output for review. As a first cut - in a relatively quiet network environment, this is a winner. If you are doing deceptions, then any attempt by attackers to use deceptions can be handled by a rule with logging as well. By using comments in a reasonable way, you can even provide hints about what happened to other analysis programs. For example, use WARNING and DANGER in comments an your output listing will provide lots of useful information about intrusion attempts.

But Responder can do a lot better than that through the use of embedded lisp. For example, suppose I wanted to keep counts of every packet from each IP address that triggered select rules, and when a threshold was reached, change the behavior for that IP address. The plan would be to create a hashset for 'questionable' addresses with a value equal to the number of times that IP address triggered an event. When the threshold is reached on an IP address, add it to the 'bad' address list which is treated differently, log the event, and continue on. For lisp programmers, this is a fairly simple matter. It takes perhaps 3-4 lines of lisp code. Here is a simple example:

Handy Selections for Implementations

This section is full of handy things from previous implementations. We will start with an ARP cache and restoration mechanism that is very useful for cases where you want to remember the ARP source addresses from incoming traffic and apply them to outbound traffic later. For example, if you have a gateway and traffic going to one of two interfaces depending on its source address, you need to store the ARP addresses of the destinations on interfaces and restore the proper ARPs in each direction or packets will get lost.

H gateway 1.2.3.4
:(setarphash (SLOT FROM 'SA_DATA) (src) (arpsrc))
; the source ARP address from the ARP packet's request
* A * * C I	; store ARPs in ARP cache for all ARP packets and go on
:(setarphash (SLOT FROM 'SA_DATA) (src) (tomac))
; the destination MAC from the TCP packet resulting from prior ARP replies from eth1
* TUIO * * C I	; store ARPs in ARP cache for all other IP packets and go on
;; OK - a note here - something like this is required if you want to set ARP cache values
;; this particular setup assumes that source ARPs are valid and ignores destination ARPs,
;; but it's a matter of personal choice - and situation - to determine when to trust what.

;..... other stuff not using ARP caches goes here

; all ARPs are sent from the gateway to both sides - this primes the ARP caches for the other interfaces.
eth0 A * * C F eth1	;send eth0 ARP packets to eth1 unaltered
eth0 A * * - F eth2	;also send eth0 ARP packets to eth2 unaltered
; note this generates ARP returns which are collected by the above rules for all Ethernets.

; ARPs are forwarded from eth1 to eth0 - priming the pump and asnwering requests.
eth1 A * * - F eth0	;send eth1 ARP packets to eth0 with destination MAC for gateway
; ARPs from eth2 are dazzled so that responses are ignored and requests appear to have addresses
eth2 A * * - Z G	;Dazzle ARPS on eth2 - G so addresses seem to have unique ARP addresses

; Other packets from eth1 pass through to eth0 unaltered.
eth1 * * * - F eth0	;send eth1 other returns to eth0
; Other packets from eth2 are given the MAC address of the gateway on eth0
eth2 * * * Mm F eth0	;send eth2 other packets to eth0 with destination MAC for gateway and src MAC from eth1
;; Why from eth1?  Because it is the only one that returned ARP information to the gateway - which then uses it's ARP on inbound
;; packets as the destination ARP...

; Finally, we decide which way things go on eth0 and associate ARPs from eth2 if they go that way.
eth0 * 1.2.3.4 * - F eth1	; things from this source go to eth1 and are left alone
eth0 * * * M F eth1		; everywhere else go to eth2 fixing the destination ARP per previous ARP responses (for example)

Programmed mode

In programmed mode you can write your own programs to cause Responder to function as you wish. You will need to know LISP, since Responder is a LISP program. Specifically, the following data structures and functions are provided for your use.

Variable What it is
socket The raw socket used for I/O - provided by the function init
len The length of the last packet in or the next packet out
logging Enables loging
buffer The buffer with the bytes from the packet
from The socket data structure
Function What it does
(init) Iniitializes the socket
(getraw) Gets a raw packet into buffer and sets len to its total size
(sendt socket len) Sends buffer for length len tothe socket specified
(slot from 'SA_DATA) The ethernet associated with the I/O
(IN-PACKAGE "RAWSOCK") The package these all reside in
(configdev S F P N) Configire Socket interFace Promiscuous Noarp raw
(tcpcsum) Set the TCP header checksum for the packet
(ipcsum) Set the IP header checksum for the packet
(icmpcsum) Set the ICMP header checksum for the packet
(udpcsum) Set the UDP header checksum for the packet
(swapmac) Swap source and destination ARP addresses
(swapip) Swap source and destination IP addresses
(cb FR TO CNT) Copy CNT bytes from FR to TO in buffer
(swap A B CNT) Swap CNT bytes starting at buffer[A] with bytes at buffer[B]

Here is a simple example program to forward packets:

(IN-PACKAGE "RAWSOCK")
(init)
(configdev socket "eth0" 1 1 )	; eth0 no arp raw mode on socket
(configdev socket "eth1" 1 1 )	; eth1 no arp raw mode on socket
(configdev socket "eth2" 1 1 )	; eth2 no arp raw mode on socket

(defun forward (toether)
        (loop for i from 0 below (length toether) do (setf (element (slot from 'SA_DATA) i)
                (char-code (aref toether i))))  (sendt socket len))
(forward "eth1")

This will forward all inbound pacets on eth0, eth1, and eth2 to eth1. No headers or checksums need to be altered in this case, so you get off easy. Here's a more complex one:

(IN-PACKAGE "RAWSOCK")
(init)
(configdev socket "eth0" 1 1 )	; eth0 no arp raw mode on socket
(defun arptype () (case (+ (ash (b 12) 8) (b 13))
        (512 :PUP) (2048 :IP) (2054 :ARP) (32821 :RARP) (t ()) ))
(defun proto ()  (case (packtype)   (17 :udp)   (6 :tcp)   (1 :icmp)))
(defun mirror ()
        (case (arptype)
                (:IP    (case (proto)
                                (:TCP   (swapmac) (swapip) (sendt socket len))
                                (:UDP   (swapmac) (swapip) (sendt socket len))
                                (:ICMP  (swapmac) (swapip) (sendt socket len))
                                (t      (swapmac) (swapip) (sendt socket len))
                )       )
                (:ARP   (progn (cb 22 32 6) (swap 28 38 4) (sendt socket len)))
                (t      ())
)       )

(loop (getraw) (mirror))

This example demonstrated how the 'mirror' function is implemented. It swaps the header information and sends the packet back out on the same interface it arrived on. Nothing to it. Note that you would have to call ipcsum just before sendt and, as apropriate, udpcsum, tcpcsum, or icmpcsum before that, except that these particular transforms do not alter the checksum for a packet.

To run your program (called yourprogram in /u/yourdir), do the following from the Unix shell:

Have fun...