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:

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=8963 mtu 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 hlk at CET 14:12 05/12/2009 in Toolbox entries

 

[Trackback URL for this entry]

Your comment:

(not displayed)
 
 
 

Live Comment Preview:

 
« september »
mationtofr
  12345
6789101112
13141516171819
20212223242526
27282930