143 lines
4.2 KiB
ReStructuredText
143 lines
4.2 KiB
ReStructuredText
|
=============================
|
||
|
Testing TCP/IP Network Stacks
|
||
|
=============================
|
||
|
|
||
|
When working on the network stack there is a need to test and verify the changes
|
||
|
made. While problems may be discovered by chance, it is hard to reproduce such
|
||
|
situations. The following sections show some methods to stress the target or
|
||
|
generate some specific traffic.
|
||
|
|
||
|
In the examples the target has the IP address 192.168.2.135
|
||
|
|
||
|
SYN Flood Attack
|
||
|
================
|
||
|
|
||
|
Flood the target with SYN packets to exhaust its resources.
|
||
|
It's a good way to test the network driver's buffer management.
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
sudo hping3 --flood -S -p 80 192.168.2.135
|
||
|
|
||
|
Building Packets with Scapy
|
||
|
===========================
|
||
|
|
||
|
A wonderful network testing tool is the Scapy lib.
|
||
|
It enables you to build pretty much any packet constellation you need for testing.
|
||
|
|
||
|
You have to add an iptables rule to prevent outgoing RST packets from the OS's
|
||
|
networking stack which does nothing know about our test connection.
|
||
|
|
||
|
To disable outgoing RST packets:
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 192.168.2.135 -j DROP
|
||
|
|
||
|
For removing the rule:
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
sudo iptables -D OUTPUT -p tcp --tcp-flags RST RST -d 192.168.2.135 -j DROP
|
||
|
|
||
|
**Testing Re-transmission behavior**
|
||
|
|
||
|
When sending a 3-way handshake only, the target should time out and reset the
|
||
|
connection.
|
||
|
|
||
|
The following Python Scapy script starts a HTTP request without further responding.
|
||
|
The stack should start re-transmit the packets and finally time out.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
#!/usr/bin/env python
|
||
|
|
||
|
import logging
|
||
|
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
|
||
|
from scapy.all import *
|
||
|
|
||
|
get = 'GET / HTTP/1.1\r\n\r\n'
|
||
|
|
||
|
ip = IP(dst="192.168.2.135")
|
||
|
port = RandNum(1024, 65535)
|
||
|
|
||
|
# Create SYN packet
|
||
|
SYN = ip/TCP(sport=port, dport=80, flags="S", seq=42)
|
||
|
|
||
|
# Send SYN and receive SYN,ACK
|
||
|
SYNACK = sr1(SYN)
|
||
|
|
||
|
# Create ACK with GET request
|
||
|
ACK = ip/TCP(sport=SYNACK.dport, dport=80, flags="A", seq=SYNACK.ack, ack=SYNACK.seq + 1)
|
||
|
|
||
|
# SEND our ACK
|
||
|
send(ACK)
|
||
|
|
||
|
reply, err = sr(ip/TCP(sport=SYNACK.dport, dport=80, flags="A", seq=SYNACK.ack, ack=SYNACK.seq + 1) / get)
|
||
|
|
||
|
Simulating Packet Loss
|
||
|
======================
|
||
|
|
||
|
With simulating packet loss one can test the re-transmission behavior of the
|
||
|
target stack.
|
||
|
|
||
|
To start packet loss:
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
# for randomly dropping 10% of incoming packets:
|
||
|
sudo iptables -A INPUT -m statistic --mode random --probability 0.1 -j DROP
|
||
|
|
||
|
# and for dropping 10% of outgoing packets:
|
||
|
sudo iptables -A OUTPUT -m statistic --mode random --probability 0.1 -j DROP
|
||
|
|
||
|
To remove the rules:
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
# for the incoming packets:
|
||
|
sudo iptables -D INPUT -m statistic --mode random --probability 0.1 -j DROP
|
||
|
|
||
|
# and for the outgoing packets
|
||
|
sudo iptables -D OUTPUT -m statistic --mode random --probability 0.1 -j DROP
|
||
|
|
||
|
Fuzz-Testing
|
||
|
============
|
||
|
|
||
|
For fuzz testing network applications the excellent
|
||
|
`SPIKE <https://www.immunitysec.com/resources-freesoftware.shtml>`_ tool can be
|
||
|
used. To make it compile under Ubuntu 14.04 LTS you have to add
|
||
|
``-fno-stack-protector`` to CFLAGS.
|
||
|
|
||
|
SPIKE complained about missing SSL libs. I simply linked the existing to the needed
|
||
|
filenames::
|
||
|
|
||
|
/lib/i386-linux-gnu$ sudo ln -s ./libssl.so.1.0.0 ./libssl.so.0
|
||
|
/lib/i386-linux-gnu$ sudo ln -s ./libcrypto.so.1.0.0 ./libcrypto.so.0
|
||
|
|
||
|
Maybe those lib versions aren't the expected by SPIKE but if you don't use SSL
|
||
|
it works fine.
|
||
|
|
||
|
SPIKE provides a proxy server to record requests to your web application. Based
|
||
|
on these requests a application specific fuzz test can be generated.
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
~/SPIKE/src$ mkdir requests && cd requests
|
||
|
# Record requests to the target at 192.168.2.135 on port 80
|
||
|
~/SPIKE/src/requests$ ../webmitm -t 192.168.2.135 -p 80
|
||
|
|
||
|
Now use your web applicaiton through localhost to record some requests. Then you
|
||
|
can generate your application specific fuzz test from the recorded requests.
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
~/SPIKE/src$ ./makewebfuzz.pl ./requests/http_request-1.0 > myfuzz.c
|
||
|
~/SPIKE/src$ gcc ./myfuzz.c -I../include -o myfuzz -L. -ldlrpc -ldl
|
||
|
|
||
|
Now you can fuzz your target:
|
||
|
|
||
|
.. code-block:: bash
|
||
|
|
||
|
~/SPIKE/src$ LD_LIBRARY_PATH=. ./myfuzz 192.168.2.135 80
|