Wem die Möglichkeiten von Tools wie
nmap,
p0f,
tcpdump,
AirSnort,
hping oder (sogar)
dsniff nicht weit genug gehen, wird an
Scapy seine helle Freude finden.
Der Vorteil an all diesen (extrem mächtigen) Produkten ist dabei gleichzeitig oft ihr Nachteil: jedes für sich allein genommen ist auf ein sehr spezielles Aufgabengebiet zuschnitten, bietet aber weniger (bis keine) Möglichkeiten, etwas zu tun, das der Programmierer nicht vorgesehen hat. Im Gegensatz dazu umschreibt die
Scapy-Webseite das Programm als "
powerful interactive packet manipulation program"...und besser kann man es kaum sagen.
Das in
Python geschriebene Tool hat im direkten Vergleich zunächst eine (z.T. erheblich) steilere Lernkurve, bietet dafür aber eine Flexibilität, die ihresgleichen sucht.
Potentielle Anwendungsgebiete sind nicht nur Sniffing, Portscanning und Fingerprinting; Scapy ist darüber hinaus in der Lage, nahezu beliebige Pakete zu konstruieren (und miteinander zu kombinieren), womit es sich auch gut für "Netzwerktests" eignet. Passend dazu werden direkt einige Möglichkeiten geboten, die einem Pentester das Leben erleichtern: die Auswahl erstreckt sich von einem DNS-Server über ARP-Spoofing bis hin zu einem
airpwn-Klon.
Für den User stellt sich Scapy in seiner einfachsten Form als Python-Interpreter dar, über den die gesamte Bedienung erfolgt. Ein gewisses Grundlagenwissen zu Python hilft hierbei zum Teil schon ganz extrem weiter.
Kleines Beispiel gefällig? Schauen wir uns doch einfach einmal an, mit welchen (grundlegenden) Hilfsmitteln uns Scapy unterstützen kann:
chris@thinkpad:~$ scapy
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump()
INFO: Can't open ethertypes file
Welcome to Scapy (1.0.1.1beta)
>>> lsc()
sr : Send and receive packets at layer 3
sr1 : Send packets at layer 3 and return only the first answer
srp : Send and receive packets at layer 2
srp1 : Send and receive packets at layer 2 and return only the first answer
srloop : Send a packet at layer 3 in loop and print the answer each time
srploop : Send a packet at layer 2 in loop and print the answer each time
sniff : Sniff packets
p0f : Passive OS fingerprinting: which OS emitted this TCP SYN ?
arpcachepoison : Poison target's cache with (your MAC,victim's IP) couple
send : Send packets at layer 3
sendp : Send packets at layer 2
traceroute : Instant TCP traceroute
arping : Send ARP who-has requests to determine which hosts are up
ls : List available layers, or infos on a given layer
lsc : List user commands
queso : Queso OS fingerprinting
nmap_fp : nmap fingerprinting
report_ports : portscan a target and output a LaTeX table
dyndns_add : Send a DNS add message to a nameserver for "name" to have a new "rdata"
dyndns_del : Send a DNS delete message to a nameserver for "name"
is_promisc : Try to guess if target is in Promisc mode. The target is provided by its ip.
Weitere, grundlegende Funktionen sind z.B. Net(), IP(), ICMP(), TCP() und Ether(), die dazu dienen, die zu konstzruierenden Pakete zu "beschreiben", indem den einzelnen Layern Werte zugewiesen werden. Natürlich müssen nicht sämtliche Paramater gesetzt sein, das Meiste ist mit sinnigen Standardwerten versehen. Ein einfacher Ersatz für "
ping" könnte in Scapy z.B. wie folgt aussehen:
>>> sr( [IP(dst="192.168.100.1")/ICMP()]*4 )
Begin emission:
................................................................................**...*.Finished to send 4 packets.
Received 88 packets, got 4 answers, remaining 0 packets
(Results: UDP:0 TCP:0 ICMP:4 Other:0, Unanswered: UDP:0 TCP:0 ICMP:0 Other:0)
Wer möchte, schaut sich auch noch den ICMP-Payload mit an:
>>> sr1( IP(dst="192.168.100.1")/ICMP() )
Begin emission:
.....................Finished to send 1 packets.
................
Received 451 packets, got 1 answers, remaining 0 packets
IP version=4L ihl=5L tos=0x0 len=28 id=60986 flags= frag=0L ttl=64 proto=ICMP chksum=0x2d94 src=192.168.100.1 dst=192.168.100.2 options='' |ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |Padding load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Darüber hinaus ist es mit einfach (Python-) Mitteln möglich, Scapy innerhalb von eigenen Programmen zu nutzen, beispielsweise um immer wiederkehrende Aufgaben wie das Scannen von Ports automatisieren zu können.
Ein mit Hilfe von Scapy erstellter, einfacher (TCP-) Portscanner könnte z.B. so aussehen:
#!/usr/bin/env python
import sys
from scapy import *
conf.verb=0
if len(sys.argv) != 2:
print "Usage: ./pscan.py <target>"
sys.exit(1)
target=sys.argv[1]
res,unans = sr( IP(dst=target)/TCP(flags="S", sport=RandShort(), dport=(1,1024)) )
res.nsummary( lfilter=lambda (s,r): (r.haslayer(TCP) and (r.getlayer(TCP).flags & 2))
Wie hier unschwer zu erkennen ist, sind selbst hierfür nur einfache Python-Kenntnisse vonnöten. Wer es schafft, einen solchen Portscanner mit ähnlich wenig Code in C zu schreiben, möge sich bitte bei mir melden.
Da das gesamte Thema viel zu komplex ist, um es innerhalb von ein par Zeilen hier mit dem nötigen Tiefgang vorzustellen, verweise ich für alle weiter gehende auf die entsprechende Dokumentation auf Scapys Webseite. Als Einstieg sind dabei besonders
- die "
Demo" und
- die diesjährige
Präsentation des Authors an der
RWTH Aachen
sehr empfehlenswert. Wer sich wirklich einmal mit Scapy befasst (und nicht aufgibt

), hat bald ein extrem mächtiges Werkzeug an der Hand, mit dem sich prinzipiell sämtliche Belange des Netzwerks abdecken lassen. Zusätzlich kann man sich so noch mit einer der angenehmsten Programmiersprachen (
Python) befassen.