Wireshark-users: [Wireshark-users] Decrypting ESP on Snow Leopard
Date: Tue, 15 Mar 2011 09:42:22 -0700
Basic problem: I had a bit of trouble (putting it mildly) getting
wireshark to decrypt ESP traffic via Cisco VPN on my mac running Snow
Leopard.  In case anyone else has similar woes, perhaps this will help
them out.  I just joined this list to put this note out, as my searches
were fruitless in helping me with my own situation.  If there's a how2
anywhere I couldn't find it, feel free to point it out and perhaps the
engines will suck it in.

Situation: MacBookPro5,3 (as returned by system info) with 2.66 GHz Intel
Core 2 Duo chip.  Using physical ethernet and/or builtin wireless along
with WireShark 1.4.1 + gcrypt (I rebuilt wireshark from source to put
in gcrypt; there was some of the usual pain and suffering working with
open source there, but with the aid of hard liquor I've blotted that
out of my mind, and in the end it worked.)  I did most of the work a
half-dozen months ago, so pray forgive any lapses of memory or reason.

Reader's digest version:

0) Read http://wiki.wireshark.org/ESP_Preferences

1) Build or get wireshark with gcrypt support

2) Use apple's built-in.  Cisco VPN software is bad.  Bad dog.
   Fire up VPN connection.

3) Use "racoonctl show-sa esp" to show keys.  Racoons to the rescue!
   Optionally use my perl program below to parse.

4) Enter keys and information into WireShark, in

5) Start capture.

6) Don't complain to me if it doesn't work.

BTW, the keys will change from time to time, so you'll have to
racoon it again to get the new ones... why the WireShark folks 
can't put this into WS or write a utility to do this automatically
as they change... (hint hint!)

Longer discourse follows.

I tried initially to get it working by following:


I'm sure someone skilled in the arts would have no difficulty at all
setting it all up, but I'm not skilled in the arts, and it seemed 
to leave out some important details.  Of course after I got it working
and read it again it all seemed much clearer, but such is hindsight.

My first efforts were done using Cisco's own VPN software.  I was unable
to get that to work at all (let's just say that debugging this kind
of this is nearly a ludicrous venture; blind trial and error seemed my
only aid); I seem to recall reading somewhere that they don't play fair,
but it was only out of desperation that I tried the Mac built-in VPN
(parenthetical note: not only did I finally get it to work, but it
is much more stable.)  I realize that for some this isn't an option
(corporate mandates or w/e), but c'est la vie.

On the Mac there is a program - racoon - that reveals all.  According
to the man page (alas, seemingly written in the same style as the
aforementioned wiki) is the "IKE (ISAKMP/Oakley) key management daemon".
The important thing here is that this can display the encryption keys you
need.  I can't even find the page that revealed how to dump keys anymore,
but eventually I discovered that (run as root, shell/command line):

	# racoonctl show-sa esp

Dumps all the information I needed.  Painfully WireShark doesn't take
the output (heaven forbid there are spaces or missing 0x, etc.), so I
wrote a little perl script (below) to parse it for me and spit out what
works for me, at least.  The output looks like:

	SA #1:			IPv4|||*
	Encryption Key #1:	0x58e398b83c63a7b6074141b6cd336997
	Authentication Key #1:	0x1cea80b798bb566b3fcf3f34aabaacf36fa5237a
	SA #2:			IPv4|||*
	Encryption Key #2:	0x362c64e1a4a12951b12513261f414ae2
	Authentication Key #2:	0x91ccc9267c2be2e51893d0b75926114a8bd729ba

This corresponds to the language used in WireShark.  Go to the
Edit->Preferences area, then to the Protocols section (on the
left-hand-side) and scroll down to ESP.  Click it and you enter the
stuff above.  Well, the above stuff probably won't work for you, you'll
have to run the program yourself.  Just in case, I have "Attempt to
detect/decode NULL encrypted ESP payloads" unchecked, and "Attempt to
detect/decode encrypted ESP payloads" as well as "Attempt to Check ESP
Authentication" checked.  The encryption used in my setup is AES-CBC &
HMAC-SHA-1-96 (both pulldowns in this options area.)

At this point you'll either chortle at my naivete, curse me for reading
all this and still not getting it to work, or see unencrypted packets.
Good luck!  If you have problems... I'm sure others can help you out ;)


----- cut here... or maybe better still, down a line... ------


# typical racoonctl out
# racoonctl show-sa esp
# 	esp mode=tunnel spi=1392725529(0x53034e19) reqid=0(0x00000000)
# 	E: aes-cbc  9ee021f3 a7f2c598 393b3c5d c991b631
# 	A: hmac-sha1  8740366d 046cb0d2 f9e7da5e 3901cc6b a5340133
# 	seq=0x00001502 replay=4 flags=0x00000006 state=mature 
# 	created: Nov 24 11:08:53 2010	current: Nov 24 11:17:33 2010
# 	diff: 520(s)	hard: 3600(s)	soft: 2880(s)
# 	last: Nov 24 11:17:30 2010	hard: 0(s)	soft: 0(s)
# 	current: 1269712(bytes)	hard: 0(bytes)	soft: 0(bytes)
# 	allocated: 5378	hard: 0	soft: 0
# 	sadb_seq=1 pid=3313 refcnt=2
# 	esp mode=tunnel spi=82142164(0x04e563d4) reqid=0(0x00000000)
# 	E: aes-cbc  87ffc878 d0c069d1 2d333315 7ab05359
# 	A: hmac-sha1  ea717256 a1404607 91d3bf3f 62d0ffd7 2ea12023
# 	seq=0x00001a79 replay=4 flags=0x00000006 state=mature 
# 	created: Nov 24 11:08:53 2010	current: Nov 24 11:17:33 2010
# 	diff: 520(s)	hard: 3600(s)	soft: 2880(s)
# 	last: Nov 24 11:17:30 2010	hard: 0(s)	soft: 0(s)
# 	current: 7325681(bytes)	hard: 0(bytes)	soft: 0(bytes)
# 	allocated: 6777	hard: 0	soft: 0
# 	sadb_seq=0 pid=3313 refcnt=2

# must be SUID, have root running this, or some permission voodoo

open(RACOON, "racoonctl show-sa esp|") || die "can't execute racoonctl successfully\n";

$sa = 1;

while (<RACOON>) {


	# look for a line starting with an IP addr... yes, I know there are
	# better regexps... but racoon seems to only have one line starting with...
	if (/^[0-9]/) {
		($ip1, $ip2) = split(/\s+/, $_);
		# print the SA #1 line for wireshark
		print "SA #$sa:\t\t\tIPv4|$ip1|$ip2|*\n";
	if (/^\s*E: aes-cbc/) {
		if (!$aes_1) {
			# print "AES-1:\t0x";
			print "Encryption Key #1:\t0x";
			($x, $x, $x, $one, $two, $three, $four) = split(/\s+/, $_);
			$aes_1 = "$one$two$three$four";
			# print "AES-1: $aes_1\n";
			print "$aes_1\n";
		else {
			# print "AES-2:\t0x";
			print "Encryption Key #2:\t0x";
			($x, $x, $x, $one, $two, $three, $four) = split(/\s+/, $_);
			$aes_2 = "$one$two$three$four";
			# print "AES-2: $aes_2\n";
			print "$aes_2\n";

	if (/^\s*A: hmac-sha1/) {
		if (!$hmac_1) {
			# print "HMAC-1:\t0x";
			print "Authentication Key #1:\t0x";
			($x, $x, $x, $one, $two, $three, $four, $five) = split(/\s+/, $_);
			$hmac_1 = "$one$two$three$four$five";
			# print "HMAC-1: $hmac_1\n";
			print "$hmac_1\n";
		else {
			# print "HMAC-2:\t0x";
			print "Authentication Key #2:\t0x";
			($x, $x, $x, $one, $two, $three, $four, $five) = split(/\s+/, $_);
			$hmac_2 = "$one$two$three$four$five";
			# print "HMAC-2: $hmac_2\n";
			print "$hmac_2\n";