What is Packet Purgatory?
Download packet purgatory here!
Welcome to the wonderful world of Packet Purgatory, where the packets
you send are exactly what you want them to be, but you can still use your
favorite web browser!
Packet Purgatory grew out of stegtunnel, which originally swiped code
from lsrtunnel. In both cases, the underlying problem was how to
generate fundamentally odd or altered packets, but still be able to
use unmodified clients, and to do so portably?
Portability requirments disqualified kernel modules. The first iteration
used the concept of a proxy IP address. This is an unassigned IP address
on the local subnet. Packet Purgatory will arp for this IP address,
and packets sent to this IP adress are absorbed by packet purgatory and
sent to the appropriate routine.
This enables our userspace program to completely handle the IP conversation,
as no kernel state about packets sent to these IP addresses will be kept.
Each packet purgatory connection is actually composed of two separate
connections, one between the local host and the proxy IP, and another
between the proxy IP and the remote host.
This prevents the kernel from injecting spurious RST packets into our
modified connections, and prevents ACK storms as well.
This was the only mode available in early lsrtunnel and stegtunnel
iterations. When Packet Purgatory was broken out, it obtained a new
mode. In the new mode, the route table is modified and a built-in
firewall is added to keep the kernel unaware of the packet tampering.
Packet purgatory is given a set of IP addresses that it is to intercept
messages to/from. It will update the firewall to block all inbound packets
from those addresses, but will sniff for packets from those addresses.
That way, inbound packets will be ignored by the kernel, but absorbed
by Packet Purgatory. It will also update the route for those addresses
to point out the loopback interface, and sniff on the loopback for outbound
packets to absorb.
The second technique was semi-swiped from Fragroute, by Dug Song, which
mangles the outbound traffic, but doesn't capture the input. The idea
was swiped, but not the code, as I needed/wanted multi-IP/multi-interface
support.
How Do I use Packet Purgatory?
Read the man page! For the seriously lazy, though, a quick how-to:
Packet purgatory based programs are centered around their packet
handling routines. The user linking to libpacketp must specify
inbound and outbound handlers which will be called on each packet, along
with a pointer to some structure which can be used to share state.
(If no state is needed, a NULL pointer may be passed).
There are two required calls to use libpacketp. They are:
struct packetp_ctx *packetp_init(), which returns a pointer to
the context which stores settings and internal handles.
int packetp_start(struct packetp_ctx *context, packet_handler inbound,
packet_handler outbound, void *user_state), which
actually begins the packet purgatory process, and will not return during
normal operation.
The inbound and outbound functions are what you have to write. Actually,
you can pass NULL pointers as the handlers, but then the program won't do
anything other than pass the packets through userland.
By default, packet purgatory will use a firewall and route table mangling
type of packet capture, and do so to all IP addresses. If you want
to restrict the target IP addresses to affect, or change the type of
capture back to the proxy IP method (which is the safest method, as you're
not poking at your route table), you need to use such calls as
packetp_set_target() or packetp_set_type(), and for the details on how
those work I really am going to go make you read the man page.
Part 1: Packet Purgatory Quick Start
Part 2: Part 2: Using a Proxy IP to Capture Packets