Threat Level: green Handler on Duty: Pedro Bueno

SANS ISC InfoSec Handlers Diary Blog

Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!

Published: 2009-11-18
Last Updated: 2009-11-18 16:55:27 UTC
by Rob VandenBrink (Version: 1)
4 comment(s)

Have you ever thought about your routers.  I mean - *really* thought about them?  They think all day long, processing all of the packets in and out of your company’s WAN or internet connection, and hardly ever complain.  But can you get any useful information out of those packets?

PC's with almost any operating system can be configured with tcpdump or windump (with wireshark or whatever gui you'd care to hang in front of it) to do packet capture an analysis.  But if the traffic you are trying to capture is halfway across the world (or maybe closer but still too far to drive), can you use your router to capture packets in a standard libpcap format?

As you've probably guessed, the answer is YES, or else there’d be no reason to write this article.  Let's go through the steps, from start to finish.

First, ensure that you have syslog set up – your packets are going to show up in the router’s log.  You can execute this packet capture process without syslog by using “show log” to view the local log buffer, but you'll be very limited as to how many packets you can capture per session.

Next, decide what traffic you'd like to capture.  Keep in mind that your captured packets are going to be sent back over the network to your syslog server.  So if you are troubleshooting a congested network, you might be better served using ip accounting or netflow.  To define your traffic, use an access list.  Remember that you're going to end up having to look at these packets, so the more specific you can make this list, the better.  Something like:

ip access-list 111 permit tcp host any eq 80
ip access-list 111 permit tcp any eq 80 host

will capture all web traffic originating from, as well as the return traffic.  However, something like

ip access-list 111 permit tcp any any eq 80

is generally a VERY BAD idea as it will capture all web traffic requests but none of the responses - not only will this only capture half of the conversation, it will likely max out the cpu and network of your router (depending on the router cpu and network of course).  Also be very sure that your list does not encompass your syslog traffic – often adding the line:

ip access-list 111 deny udp any any eq 514

might be a smart thing to add to your list , just to be safe.  It prevents an infinite recursive loop – your first packet will go to syslog, be recaptured as an sent to syslog, and so on ...  This process isn't supposed to capture packets sourced from the router, but if you are troubleshooting problems it's generally because things aren't working the way they should ...

Next, we need to start capturing traffic.  from the exec prompt (privilege level 15), do

debug ip packet 111 dump

This debug command initiates the packet capture of the “interesting traffic” defined in access list 111- it's now time to have your workstation do whatever it is you want to "catch on film" (sorry, I guess I'm dating myself with this reference).  The debug ip packet dump command is included in standard IOS starting in version 12.0.  So if you don’t have this as a command on your router, it’s probably time to consider an update! 

When you've got enough traffic “in the hopper”, disable the debug and remove the access list.

no debug ip packet 111 dump

or :

no debug all

as well as:

config t
no access-list 111

When we go to the log, you'll now see all the packets in hexadecimal and ASCII representation, similar to:

015515: Jun 29 08:35:52.777 EST: IP: tableid=0, s= (Vlan1), d= (FastEthernet0), routed via FIB
015516: Jun 29 08:35:52.781 EST: IP: s= (Vlan1), d= (FastEthernet0), g=, len 48, forward
05199CC0:                       0017 0E0CB761            ....7a
05199CD0: 0018DE5A 6FAA0800 45000030 91694000  ..^Zo*..E..0.i@.
05199CE0: 7F0649B7 63F2A0A7 41ADDA60 73E40050  ..I7cr 'A-Z`sd.P
05199CF0: 81254296 00000000 7002FC00 2F4F0000  .%B.....p.|./O..
05199D00: 020404EC 01010402                    ...l....
015517: Jun 29 08:35:53.133 EST: IP: tableid=0, s= (Vlan1), d= (FastEthernet0), routed via FIB
015518: Jun 29 08:35:53.133 EST: IP: s= (Vlan1), d= (FastEthernet0), g=, len 48, forward
05199E00:                       0017 0E0CB761            ....7a
05199E10: 0018DE5A 6FAA0800 45000030 917E4000  ..^Zo*..E..0.~@.
05199E20: 7F06EDCD 63F2A0A7 4A7D2D65 73E50050  ..mMcr 'J}-ese.P
05199E30: CE7AE47A 00000000 7002FC00 E43F0000  Nzdz....p.|.d?..
05199E40: 020404EC 01010402                    ...l....
015519: Jun 29 08:35:53.201 EST: IP: tableid=0, s= (Vlan1), d= (FastEthernet0), routed via FIB
015520: Jun 29 08:35:53.201 EST: IP: s= (Vlan1), d= (FastEthernet0), g=, len 48, forward
0531AC20:                       0017 0E0CB761            ....7a
0531AC30: 0018DE5A 6FAA0800 45000030 91924000  ..^Zo*..E..0..@.
0531AC40: 7F06498E 63F2A0A7 41ADDA60 73E60050 'A-Z`sf.P
0531AC50: CF69CD4F 00000000 7002FC00 564F0000  OiMO....p.|.VO..
0531AC60: 020404EC 01010402                    ...l....
015521: Jun 29 08:35:55.205 EST: IP: tableid=0, s= (Vlan1), d= (FastEthernet0), routed via FIB
015522: Jun 29 08:35:55.205 EST: IP: s= (Vlan1), d= (FastEthernet0), g=, len 48, forward
0531AAE0:                       0017 0E0CB761            ....7a
0531AAF0: 0018DE5A 6FAA0800 45000030 92104000  ..^Zo*..E..0..@.
0531AB00: 7F06F531 63F2A0A7 42232DC9 73E70050  ..u1cr 'B#-Isg.P
0531AB10: 88101C35 00000000 7002FC00 FAE30000  ...5....p.|.zc..
0531AB20: 020404EC 01010402                    ...l....
015512: Jun 29 08:37:22.206 EST: %SEC-6-IPACCESSLOGP: list 101 denied tcp ->, 1 packet
015513: Jun 29 08:37:39.279 EST: %SEC-6-IPACCESSLOGP: list 101 denied tcp ->, 2 packets

In many cases, you can work with the packets in hex, and this output will be sufficient – I guess this all depends on your “geek factor”.  However, if you need to interpret these packets with a decoder or in a GUI, you'll need to get them into PCAP format.  This is a two stage process.  First, we'll need to get them to PCAP's ascii representation, which looks like this:

# Packet  1
00000000 00 17 0E 0C B7 61 00 18 DE 5A 6F AA 08 00 45 00 #
00000010 00 30 91 69 40 00 7F 06 49 B7 63 F2 A0 A7 41 AD #
00000020 DA 60 73 E4 00 50 81 25 42 96 00 00 00 00 70 02 #
00000030 FC 00 2F 4F 00 00 02 04 04 EC 01 01 04 02 #
# Packet  2
00000000 00 17 0E 0C B7 61 00 18 DE 5A 6F AA 08 00 45 00 #
00000010 00 30 91 7E 40 00 7F 06 ED CD 63 F2 A0 A7 4A 7D #
00000020 2D 65 73 E5 00 50 CE 7A E4 7A 00 00 00 00 70 02 #
00000030 FC 00 E4 3F 00 00 02 04 04 EC 01 01 04 02 #
# Packet  3
00000000 00 17 0E 0C B7 61 00 18 DE 5A 6F AA 08 00 45 00 #
00000010 00 30 91 92 40 00 7F 06 49 8E 63 F2 A0 A7 41 AD #
00000020 DA 60 73 E6 00 50 CF 69 CD 4F 00 00 00 00 70 02 #
00000030 FC 00 56 4F 00 00 02 04 04 EC 01 01 04 02 #
# Packet  4
00000000 00 17 0E 0C B7 61 00 18 DE 5A 6F AA 08 00 45 00 #
00000010 00 30 92 10 40 00 7F 06 F5 31 63 F2 A0 A7 42 23 #
00000020 2D C9 73 E7 00 50 88 10 1C 35 00 00 00 00 70 02 #
00000030 FC 00 FA E3 00 00 02 04 04 EC 01 01 04 02 #

A simple way to do this is take your log file and run it through a AWK script "i2p.awk" that I've written to "fix" the file format, then run THAT file through text2pcap.exe (which comes as part of the wireshark distro).  There are lots of perl scripts out there to do this exact thing, but I thought that AWK might be a lighter-weight, portable way of getting this same job done with less fuss.  Plus I wanted to write something neat in AWK.

if (match($0 , /[0-9A-F](8):/ ) == 0)  {

Select lines that hold packet info (line starts 8 hex digits followed by a colon)

hex = hex substr ( $0 , 10, 36) Select lines that hold packet info (line starts 8 hex digits followed by a colon)
} else {  
if (length(hex) > 0) { If it’s not a packet, and we have hex data in the buffer, it’s time to “fix the data”
 ++packet Increment the packet number
printf "%s %in%08x ", "# Packet " ,packet, 0 Print “Packet #” info, plus a Carriage Return, plus the first hex offset (0)
gsub(/[ t]/,"" ,hex) Remove all spaces from the hex info
while ( i < length(hex) ) { Loop through the hex info, byte by byte (awk starts with a byte offset of 1)
  printf "%s%s" , substr (hex , i , 2 ), " " Print each byte, with a trailing space
  mod = (i+1)%32 Are we at the end of a line?
  if (mod == 0 ) { printf "#n%08X ", (i+1)/2 } If so, print the “#” at the end of the  line, then the byte offset of the next line (note we’re correcting for the 1 byte offset that awk uses)
i += 2 Increment the character count by 2
printf "#" Print the last trailing “#”
hex = "" Clear the packet hex string


So, if your syslog file is syslog.out, you might run this as:

C:>type syslog.out | awk -f i2p.awk > test1.out

C:> text2pcap test1.out  ioscap.pcap
Input from: Standard input
Output to: ioscap.pcap
Wrote packet of 16 bytes at 0
Wrote packet of 32 bytes at 16
Read 2 potential packets, wrote 2 packets

Now we have a file we can open in wireshark (or anything else that can read a PCAP file).

So as you can see, we’re able to use a standard router as a remote collector for any standard packet sniffer program that can read a PCAP file.  Just keep in mind that you are both changing the config of that router (with the access list), and enabling a debug, which can impact both CPU and Network utilization.  So be sure to get permission – in many IT shops, this will take the form of a Change Control Request.

After we’ve gone through this process, some of you are probably asking – “Rob, why would I want to go through this just to capture a few packets?”  My answer to this might be “Perhaps there are no PC’s at the remote location”, or “Maybe you’re not allowed to install a packet capture program on any of the remote PC’s”, or “the switch at the remote location might not support a SPAN port”.    But the best answer is “Why *wouldn’t* you want to do this at least once just for fun – isn’t this the neatest thing ever?”

This process might seem to be a bit complex, but once you have the awk code up and running, the mechanics of actually collecting and processing the packets is pretty streamlined and goes very quickly.   If you find any cases where the code might need improvement, please shoot me a note and I'll try to address it.  If you use this code to solve an interesting problem, please share your experience - there's a "Comment" button at the bottom of this entry.  Have fun, with this, I hope you find it useful! 


Note: If you are running linux, AWK is generally included as part of even the most basic distro installations.  If you are a Windows user, you can get AWK from the Windows 2003 Subsystem for Unix Applications (SUA), or you can download GNUutils ( ), which will give you a number of *nix utilities as native EXE files, or install cygwin to get native linux support.

4 comment(s)
Diary Archives