Saturday, 5 December 2009
Juletip 5: Vi bygger pakker
« Juletip 4: IPv4 gråzoner og magiske konstanter | Main | Juletip 6: Vi bygger IPv6 pakker med PCS »Pakker er der nok af på vores IP netværk og de fleste kommer (forhåbentlig) fra applikationer som vi bruger. Andre igen kommer fra kernen, som svar på problemer. Enhelt tredie kategori er pakker vi selv bygger og det kan man gøre med mange værktøjer, eksempelvis:
- libnet
- Scapy
- Packet Construction Set
Det første er et C bibliotek som har været tilgængeligt i mange år. Hvis man kaster sig over libnet vil man måske i første omgang mene det er lidt gammeldags, men i forhold til at skrive C programmer der direkte bygger pakkerne var det et stort fremskridt. Idag er der mange af vores programmer og hackerprogrammer der benytter libnet, så der er en stor sandsynlighed for at I har libnet installeret allerede.
Hvis man programmerer i C er det naturligt at vælge libnet og man kan læse mere på hjemmesiden http://libnet.sourceforge.net/ og det lader til at den oprindelige URL jeg ellers har brugt http://www.packetfactory.net er død :-(
Går man tilbage til eksempelvis dsniff pakken er det en af de pakker som benytter libnet og det er alt jeg ville sige om libnet idag, ligeså er scapy heller ikke på programmet idag, men måske en anden dag :-)
Idag skal det altså handle om Packet Construction Set, PCS
Packet Construction Set PCS
Jeg formoder I selv kan hente det på hjemmesiden og udpakke det.
PCS Install
Når man således har hentet og udpakket det skal man installere det, men først skulle jeg lige smide et ekstra bibliotek ind, som hedder Cython: C-Extensions for Python. Det gjorde jeg nemt på min Mac med Macports og jeg anbefaler at man så vidt muligt bruger pakkesystemerne - men ofte er små værktøjer som PCS ikke med.
Bemærk også at PCS bruger python26, dvs Python version 2.6 - så jeg måtte også lige installere python26
På min Mac var det altså kun at udføre følgende:
hlk@bigfoot:scripts$ sudo port install py26-cython ---> Computing dependencies for py26-cython ---> Fetching python26 ---> Attempting to fetch Python-2.6.4.tar.bz2 from http://arn.se.distfiles.macports.org/python26 ---> Verifying checksum(s) for python26 ---> Extracting python26 ---> Applying patches to python26 ---> Configuring python26 ---> Building python26 ---> Staging python26 into destroot ---> Installing python26 @2.6.4_0+darwin ---> Activating python26 @2.6.4_0+darwin To fully complete your installation and make python 2.6 the default, please run sudo port install python_select sudo python_select python26 ---> Cleaning python26 ---> Fetching py26-cython ---> Attempting to fetch Cython-0.11.3.tar.gz from http://arn.se.distfiles.macports.org/python ---> Verifying checksum(s) for py26-cython ---> Extracting py26-cython ---> Configuring py26-cython ---> Building py26-cython ---> Staging py26-cython into destroot ---> Installing py26-cython @0.11.3_0 ---> Activating py26-cython @0.11.3_0 ---> Cleaning py26-cython hlk@bigfoot:scripts$ sudo port install python_select ---> Computing dependencies for python_select ---> Cleaning python_select hlk@bigfoot:scripts$ sudo python_select python26 Selecting version "python26" for python
og hvis du oplever problemer senere så kan det være du mangler andre dependencies. Næste skridt var at læse PCS filerne README og INSTALL:
Installation Instructions for Packet Construction Set (PCS) PCS follows the normal Python conventions for building and installing and there is very little, if any, magic. To install the library and the associated packet classes into your system do: > python setup.py config > python setup.py install To test your installation do: > cd tests/ > python *.py Some tests fail if you do not have enough privileges to work with the Berkeley Packet Filter. If you wish to run those tests run them using sudo. To build the documentation you will need pdflatex and a BSD version of make(1) installed. Go into the docs directory and build the documentation: > cd docs/ > bsdmake all you will see PDF versions of the docs.
Det lyder jo fint, så hvad sker der - husk selv sudo under install delen:
hlk@bigfoot:pcs-0.6$ python -V
Python 2.6.4
hlk@bigfoot:pcs-0.6$ python setup.py config
running config
found {'libraries': ['pcap'], 'library_dirs': ['/usr/lib'], 'include_dirs': ['/usr/include/pcap']}
Aha, det lader til at PCS bruger libpcap packet capture, det giver mening - endnu et af vores standardbiblioteker, som forøvrigt stammer fra tcpdump :-)
hlk@bigfoot:pcs-0.6$ sudo python setup.py install running install running build running build_py creating build/lib.macosx-10.4-i386-2.6 creating build/lib.macosx-10.4-i386-2.6/pcs copying pcs/__init__.py -> build/lib.macosx-10.4-i386-2.6/pcs creating build/lib.macosx-10.4-i386-2.6/pcs/packets copying pcs/packets/__init__.py -> build/lib.macosx-10.4-i386-2.6/pcs/packets copying pcs/packets/arp.py -> build/lib.macosx-10.4-i386-2.6/pcs/packets ... byte-compiling /usr/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pcs/packets/udpv6.py to udpv6.pyc byte-compiling /usr/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pcs/packets/vlan.py to vlan.pyc running install_egg_info Writing /usr/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pcs-0.6-py2.6.egg-info
Færdig, PCS er installeret
Running PCS
Super, vi har installeret PCS - lad os så komme igang. Det naturlige er at se på nogle af eksempelprogrammerne under pcs-0.6/scripts og jeg har klippet icmpv4test.py op og molestreret det således:
#!/usr/bin/env python
# Copyright (c) 2006, Neville-Neil Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# Neither the name of Neville-Neil Consulting nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# File: $Id: icmpv4test.py,v 1.8 2006/09/05 07:30:56 gnn Exp $
#
# Author: George V. Neville-Neil
#
# Description: This module performs a self test on the IPv4 packet.
# That is to say it first encodes a packet, then decodes it and makes
# sure that the data matches.
import sys
if "-l" in sys.argv:
sys.path.insert(0, "../") # Look locally first
sys.argv.remove("-l") # Needed because unittest has issues
from pcs.packets.ethernet import ethernet
from pcs.packets.ipv4 import *
from pcs.packets.icmpv4 import *
from pcs import *
class hlktest():
def test_icmpv4_ping(self):
import os
uname = os.uname()[0]
if uname == "FreeBSD":
devname = "edsc0"
elif uname == "Linux":
devname = "lo"
elif uname == "Darwin":
print "Found Darwin"
devname = "en1"
else:
print "unknown host os %s" % uname
return
e = ethernet()
e.type = 0x0800
e.src = "\x00\x00\x00\x00\x00\x00"
e.dst = "\xff\xff\xff\xff\xff\xff"
e.type = 0x0800
print e
ip = ipv4()
ip.version = 4
ip.hlen = 5
ip.tos = 0
ip.length = 28
ip.id = 1234
ip.flags = 0
ip.offset = 0
ip.ttl = 64
ip.protocol = IPPROTO_ICMP
ip.src = inet_atol("10.0.42.95")
ip.dst = inet_atol("10.0.42.44")
print ip
icmp = icmpv4()
icmp.type = 8
icmp.code = 0
icmp.cksum = 0
print icmp
echo = icmpv4echo()
echo.id = 37123
echo.sequence = 0
print echo
ip.len = len(ip.bytes) + len(icmp.bytes) + len(echo.bytes)
packet = Chain([e, ip, icmp, echo])
packet.calc_checksums()
packet.encode()
output = PcapConnector(devname)
n_out = output.write(packet.bytes, 42)
hlk = hlktest()
hlk.test_icmpv4_ping()
og sorry, hvis I prøver at copy paste det, python er ret pernitten med indrykning så det er bedre at downloade det :-) Men under alle omstændigheder så burde det være tydeligt hvad der sker og det er yderst letlæseligt. Når man kører programmet får man følgende output, mig der har tilføjet lidt print for at vise hvad der sker:
hlk@bigfoot:hlk$ sudo python icmpv4test.py Found Darwin Ethernet dst: ff:ff:ff:ff:ff:ff src: 0:0:0:0:0:0 type: 0x800 IPv4 version 4 hlen 5 tos 0 length 28 id 1234 flags 0 offset 0 ttl 64 protocol 1 checksum 0 src 10.0.42.95 dst 10.0.42.44 options [] ICMPv4 Echo Request type 8 code 0 checksum 0 ICMPv4 Echo id 37123 sequence 0
og en tcpdump der kører samtidig viser:
hlk@bigfoot:hlk$ sudo tcpdump -ni en1 icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on en1, link-type EN10MB (Ethernet), capture size 65535 bytes 16:08:02.872460 IP 10.0.42.95 > 10.0.42.44: ICMP echo request, id 37123, seq 0, length 8 16:12:09.288684 IP 10.0.42.95 > 10.0.42.44: ICMP echo request, id 37123, seq 0, length 8
Øv, der kommer jo ikke noget svar?! Men det er jo helt naturligt, se på Ethernet pakken, dst og src - ahhhh. Hvordan er det lige med Ethernet, ja normalt bruger vi ARP - men vores program har hardcodet ff:ff:ff:ff:ff:ff og 0:0:0:0:0:0, hmmm det må vi gøre noget ved. Først henter vi MAC adresserne med arp og ifconfig:
hlk@bigfoot:hlk$ arp -an ? (10.0.42.1) at 0:0:24:c8:b2:4c on en1 ifscope [ethernet] ? (10.0.42.44) at 0:40:63:c9:f3:11 on en1 ifscope [ethernet] hlk@bigfoot:hlk$ ifconfig en1 en1: flags=8963mtu 1500 inet6 fe80::223:6cff:fe9a:f52c%en1 prefixlen 64 scopeid 0x5 inet 10.0.42.95 netmask 0xffffff00 broadcast 10.0.42.255 inet6 2001:16d8:dd0f:cf0f:223:6cff:fe9a:f52c prefixlen 64 autoconf ether 00:23:6c:9a:f5:2c media: autoselect status: active supported media: autoselect
og retter programmet:
e.src = "\x00\x23\x6c\x9a\xf5\x2c" e.dst = "\x00\x40\x63\xc9\xf3\x11"
og vupti :-)
16:15:37.114776 IP 10.0.42.95 > 10.0.42.44: ICMP echo request, id 37123, seq 0, length 8 16:15:37.117927 IP 10.0.42.44 > 10.0.42.95: ICMP echo reply, id 37123, seq 0, length 8
Så det er altså relativt nemt med PCS at bygge pakkerne - men man overtager en del af arbejdet selv :-) Det var alt for idag.
Posted by at CET 14:12 05/12/2009 in Toolbox entries
[Trackback URL for this entry]

