hping wiki

Differences for page Getting started with hping3

Current version compared with version Fri Jun 04 08:36:55 GMT 2004

...
- ===Getting Started With hping3===
- 
  This document is a quick introduction to [hping3]. [hping3] is mostly command line compatible with [hping2]
  so the command line interface is not documented in this document. Instead this is an introduction to the
- hping Tcl scripting capabilities, and how to use they interactively and as real programmers.
+ hping Tcl scripting capabilities, and how to use them interactively and in standalone scripts.
  
- {Work in progress... will be done in some hour I hope}+ 
+ {Important Note:} to get the best of hping3 you should learn some basic Tcl programming. To make the
+ task more simple I'm writing a book about Tcl programming, the first nine chapters (all you need
+ to start with Tcl IMHO) are *online for free* here: [link http://www.invece.org/tclwise/].  
+ 
+ ===First steps===
+ 
+ 
+ First of all you need a working [hping3] installation. Go to the [download] page, and download the latest
+ hping3 tar.gz available. Install it, and log in as the *root* user (you need this to send and receive raw packets).
+ 
+ 
+ To enter the hping3 interactive shell, just type:
+ 
+  # hping3
+ 
+ without any argument. If hping was compiled with Tcl scripting capabilities you should see a prompt.
+ The prompt will accept any [Tcl] command, it's actually a [Tcl] shell, what's special about it
+ is that there is a new command called *hping*, and support for big numbers using commands like
+ *+*, *-*, and so on.
+ 
+ 
+ As first try, you can type a simple command and see the result:
+ 
+  hping3.0.0-alpha-1> hping resolve www.google.com
+  66.102.9.104
+ 
+ 
+ The *hping* command should be called with a subcommand as a first argument (*resolve* in the example)
+ and additional arguments according to the particular subcommand.
+ The [hping resolve] command is used to convert a hostname to an [IP address].
+ 
+ 
+ Ok, that's the basic usage. Now we can start to try more advanced commands (you can find
+ a complete list of commands in the [hping3 API] page). For example the [hping send] command
+ can send [TCP/IP] packets that you can easily describe as strings:
+ 
+ 
+  hping3.0.0-alpha-1> hping send {ip(daddr=192.168.1.8)+icmp(type=8,code=0)}
+ 
+ 
+ This command means "send an ICMP echo request packet to 192.168.1.8". Many details of
+ the packet can be omitted. For example we didn't specify our source address (that will
+ default to the real source address of the sender, the one of the outgoing interface),
+ nor the IP or ICMP checksum. hping will compute them for us.
+ 
+ 
+ Let's check what tcpdump running at 192.168.1.8 detected:
+ 
+  tcpdump: listening on eth0
+  19:09:16.556695 192.168.1.6 > 192.168.1.8: icmp: echo request [ttl 0]
+  19:09:16.556803 192.168.1.8 > 192.168.1.6: icmp: echo reply
+ 
+ 
+ Our ICMP packet reached the destination, that kindly replied with an ICMP echo reply
+ packet.
+ 
+ It's better to recall for a second the previous command, to analyze it better:
+ 
+ hping3.0.0-alpha-1> {hping send \{ip(daddr=192.168.1.8)+icmp(type=8,code=0)\}}
+ 
+ As you can see, there are \{ and \} surrounding the packet description. This is required by
+ [Tcl] in order to quote the string so that special characters will not be interpreted.
+ Quoting with \{\} in Tcl is just like to quote with "" in most other languages, with the
+ difference that no escapes are recognized inside \{\} quoting.
+ 
+ The second thing to note is the format we used to describe the packet. That's called
+ [APD], and was introduced with hping3 itself. The [APD] syntax is trivial, and there
+ is a simple way to figure how to generate a given packet, because hping3 use this
+ format to send packets, but also to receive packets as we will see in a moment.
+ 
+ ===Tcl inside===
+ 
+ Before to show how it's possible to receive packets, I want to stress the fact that we are
+ inside a [Tcl] interpreter, so we can use any of the Tcl abilities in hping scripts.
+ 
+ 
+ The following hping script will send the same ICMP packet we already sent to
+ 192.168.1.8, but using different TTL values, from 5 to 10.
+ 
+  foreach i [list 5 6 7 8 9 10] {
+      hping send "ip(daddr=192.168.1.8,ttl=$i)+icmp(type=8,code=0)"
+  }
+ 
+ With scripts longer then one line it can be a good idea to write the script with a
+ text editor, and then run it using hping:
+ 
+  # hping exec foo.htcl
+ - Cut&paste it into the hping interactive shell also works well.
+ 
+ Note that because this example uses a variable *i* to increment the ttl value on every iteration 
+ of the *foreach*, we used "" rather than \{\} quoting so that *$i* would be expanded to the value of *i*.
+ 
+ 
+ I think it's clear now that in order to make a good use of [hping3] you need to learn the Tcl
+ language. The good news are that [Tcl] is a very powerful language, but it's very easy
+ to learn, and if you learn [Tcl] you will enjoy it in many different tasks related or
+ not to hping. The best site about [Tcl] is the [link http://wiki.tcl.tk Tcler's Wiki].
+ 
+ ===Packet reception===
+ 
+ Another very important subcommand of hping is [hping recv], that is used to
+ capture packets from the specified interface. The simplest usage is the following:
+ 
+ 
+  hping3.0.0-alpha-1> hping recv eth0
+  ip(ihl=0x5,ver=0x4,tos=0x00,totlen=52,id=42833,fragoff=0,mf=0,df=1,rf=0,ttl=54,proto=6,cksum=0xd53a,saddr=192.106.224.132,daddr=192.168.1.6)+\
+  tcp(sport=6667,dport=52466,seq=2163829654,ack=3105171942,x2=0x0,off=8,flags=a,win=2848,cksum=0x99bd,urp=0)+\
+  tcp.nop()+tcp.nop()+tcp.timestamp(val=181365875,ecr=104872758)
+ 
+ 
+ 
+ `Because the received packet description is too long I added newlines quoted with \\, but actually hping will read the packet as a unique string.`
+ 
+ 
+ [hping recv] returns a Tcl list, where every element is a packet (but by default
+ it will be just one-element list).
+ 
+ 
+ At every call, {hping recv eth0} will return the packet(s) in queue. If there is no packet to receive
+ the command will block until one is available.
+ 
+ 
+ If you don't want [hping recv] to block forever, you can specify an additional
+ argument. One more argument will tell hping the max number of packets to return in
+ a single call. To learn the details please check the [hping recv] page in this wiki.
+ 
+ 
+ Note that the command always returns a Tcl list of packets, even when just one packet
+ is returned. So if you want to use the returned packets you need to use Tcl list
+ commands (as we will see in a moment). Another thing to note is that
+ the packets are received in [APD] format, so it's possible to get a packet,
+ possibly manipulate it, and resend the packet using [hping send].
+ 
+ 
+ The following is an example script using [hping recv].
+ 
+  while 1 {
+      set p [lindex [hping recv eth0] 0]
+      puts "[hping getfield ip saddr $p] -> [hping getfield ip ttl $p]"
+  }
+ 
+ 
+ The first line is just a *while* loop that will repeat the script provided as second argument forever.
+ The second line, {set p \[lindex \[hping recv eth0\] 0\]} gets the next packet, the *lindex* command
+ is used to extract the packet from the Tcl list (and the 0 argument tells lindex to get the first packet).
+ 
+ 
+ The second line of code, {puts "..."}, print on the screen the source IP address and the TTL value of the
+ packet. To extract fiels from packets there is the command [hping getfield] (see the specific page for
+ more information as usually).
+ 
+ 
+ If you execute this script, you'll get an output similar to the following:
+ 
+ 
+  # ./hping3 exec /tmp/test.tcl
+  192.168.1.6 -> 128
+  192.168.1.20 -> 128
+ 
+ the script will dump the packets until you press ctrl+C.
+ 
+ 
+ ===A more complex example===
+ 
+ 
+ The following is a more real-world example, an hping script used to analyze the Initial Sequence Number
+ of a TCP/IP stack implementation. This example uses [Tk] in order to be able to display a spectrogram
+ of the ISN increments in graphic. Note that the script is quite "rude" in order to make it
+ as simple as possible (otherwise it will hardly be good in order to learn hping3 by examples).
+ 
+ 
+ Before to show the actual code, I want to show an example output for Linux and Windows.
+ 
+ That's Linux:
+ 
+ [img http://www.hping.org/hping3/linux.jpg]
+ 
+ 
+ While that's what I get with Windows 2000:
+ 
+ [img http://www.hping.org/hping3/win.jpg]
+ 
+ 
+ `To appreaciate the real difference about the two OSes note the scale indication in the pictures.`
+ 
+ 
+ Note that the script sends SYN packets to the target host always using the same IP address,
+ so it does only check how random the increment is in a particular situation. But if your
+ TCP/IP stack will show a bad spectrogram in this context, there is already something of
+ bad (think about dialups, or DSL lines with dynamic IP, I can connect, sample a given host,
+ reconnect with a different IP and try to do IP spoofing with the previous one).
+ 
+ 
+ Finally that's the hping3 script to do the actual analysis:
+ 
+ 
+  # isn-spectrogram.htcl -- show the ISN increments "spectrogram".
+  # Copyright(C) 2003 Salvatore Sanfilippo.
+  #
+  # All rights reserved.
+  #
+  # Here the idea is very simple, in operating systems implemeting
+  # ISN as random increments, it is useless to analyze the whole
+  # sequence number, because the random part is just the increment.
+  # Morover, some weaknes isn't about correlation between previous
+  # and successive increments, but just about increments don't show
+  # a good distribution. So the idea is to display a spectrogram
+  # of the increments distribution instead of the more complex to read
+  # 3D attractors (See [1]). This way is possible to see at least some of
+  # the common vulnerabilties you can discover with 3D attractors,
+  # but it is much simpler to guess how hard is to exploit the system
+  # just from the picture.
+  #
+  # [1] http://razor.bindview.com/publish/papers/tcpseq.html
+  #
+  # Please if you make this script better write me back the
+  # changes. (antirez@invece.org).
+  #
+  # The script requires Tk to run.
+  
+  package require Tk
+  source hpingstdlib.htcl
+  
+  if {$argc != 3} {
+      puts stderr "Usage: isn-spectrogram <host> <scale> <open-tcp-port>"
+      puts stderr "Example: isn-spectrogram www.example.com 100000 80"
+      exit
+  }
+  
+  set bgcolor {#000000}
+  wm title . {hping3 -- attractors}
+  set w .main
+  frame $w
+  pack $w -side top
+  . config -background $bgcolor
+  $w config -background $bgcolor
+  
+  # canvas
+  set xres 800
+  set yres 800
+  canvas $w.can -width $xres -height $yres
+  $w.can config -background $bgcolor
+  pack $w.can -fill both -expand true
+  
+  # globals
+  foreach {hostname div dport} $argv break
+  set sport 1
+  #set dport 80
+  set target [hping resolve $hostname]
+  set targetif [outifname $target]
+  set myip [hping outifa $target]
+  set isnqueue {}
+  set relative_attractor 1
+  set lastisn 0
+  #set div 10000000
+  
+  hping setfilter $targetif "tcp and src host $target"
+  
+  
+  $w.can create rectangle 40 450 139 450 -fill white -width 0
+  $w.can create text 90 470 -fill white -text [expr $div*100]
+  
+  proc sendsyn {} {
+      global sport dport myip target
+      append syn "ip(saddr=$myip,daddr=$target,ttl=255)+"
+      append syn "tcp(sport=$sport,dport=$dport,flags=s)"
+      hping send $syn
+      incr sport
+      after 1 sendsyn
+  }
+  
+  proc recvsynack {} {
+      global lastisn relative_attractor
+  
+      set packets [hping recv eth0 0 0]
+      foreach p $packets {
+  	if {![hping hasfield tcp flags $p]} continue
+  	set isn [hping getfield tcp seq $p]
+  	if {$relative_attractor} {
+  		set tisn [expr abs($isn-$lastisn)]
+  		set lastisn $isn
+  		set isn $tisn
+  	}
+  	#puts "ISN: $isn"
+  	displaypoint $isn
+      }
+      after 10 recvsynack
+  }
+  
+  proc displaypoint isn {
+      global w xres yres pastcol div
+  
+      set isn [expr $isn/$div]
+      set y 300
+      set x $isn
+      puts "$x $y"
+      if {[haskey pastcol $x.$y]} {
+  	set graylevel [incr pastcol($x.$y) 10]
+      } else {
+  	set pastcol($x.$y) 0
+  	set graylevel 0
+      }
+      if {$graylevel >= 256*3} {
+  	set graylevel [expr (256*3)-1]
+      }
+      if {$graylevel <= 255} {
+  	set b $graylevel
+ 
+  	set g 0
+  	set r 0
+      } elseif {$graylevel <= 511} {
+  	set b 0
+  	set g [expr $graylevel - 256]
+  	set r 255
+      } elseif {$graylevel <= 767} {
+  	set b 255
+  	set g 255
+  	set r [expr $graylevel - 512]
+      }
+      set color [format "#%02X%02X%02X" $r $g $b]
+      $w.can create rectangle $x $y [expr $x+1] [expr $y+100] -fill $color -width 0
+  }
+  
+  after 1 sendsyn
+  after 1 recvsynack
+  
+  vwait forever
+  
+  # vim: filetype=tcl softtabstop=4
+ 
+ 
+ If you know some basic Tcl/Tk you will find it very simple to read I hope.
+ Note that if you want to run this code you require a little hping standard
+ library, but both this program and the lib itself are under the */lib* directory
+ of the hping3 distribution, so don't bother to retype it from this page.
+ 
+ That's how to use the script against a Linux box.
+ 
+  cd /your/path/hping3/lib
+  ../hping3 exec isn-spectrogram.htcl <target-host> 100000 25
+ 
+ Note that '25' is an open port, you need to specify an open TCP port for the target system.
+ 100000 is instead the scale, if you see that the graph is bigger than the screen use
+ a bigger scale value, if you see it concentrating in the left of the screen and very dense,
+ use a lower one. auto-scaling is trivial but not implemented in that script.
+ 
+ {Work in progress... I hope to refine this tutorial at some point}

The following is the old page content