Pull to refresh

Декодирование ipsec в Linux

Reading time 3 min
Views 16K
Иногда возникает необходимость снять дамп трафика внутри ipsec тоннеля. Я расскажу как это сделать в случае ipsec, поднятом на Linux сервере с PSK аутентификацией при помощи wireshark.



Для успешного декодирования трафика необходимо начать снимать дамп сразу после поднятия ipsec.
Для захвата трафика используем tcpdump, например так:

# tcpdump -i any -s 0 -w ipsec.pcap esp


Затем поднимаем ipsec:

# /etc/init.d/ipsec start


Так как ipsec настроен с использованием PSK (pre shared key) аутентификации, то для успешного декодирования необходимо узнать сессионный ключ. Это можно сделать с помощью команды setkey.
Данная команда, в случае debian, входит в пакет ipsec-tools. Запускать нужно с правами root.

# setkey -D
10.1.1.1  10.2.2.2
	esp mode=tunnel spi=2548102798(0x97e0f68e) reqid=16389(0x00004005)
	E: aes-cbc  2a787e41 bbdc2f94 9ced721c 7fcf934e
	A: hmac-sha1  6af6847a 477bea9f 5c9a8d13 7ea9a5b5 9a318d29
	seq=0x00000000 replay=32 flags=0x00000000 state=mature 
	created: Oct 16 10:37:52 2012	current: Oct 16 11:04:26 2012
	diff: 1594(s)	hard: 0(s)	soft: 0(s)
	last:                     	hard: 0(s)	soft: 0(s)
	current: 0(bytes)	hard: 0(bytes)	soft: 0(bytes)
	allocated: 0	hard: 0	soft: 0
	sadb_seq=1 pid=9195 refcnt=0


Нам потребуется:
1) ip-адреса
2) spi — security parameter index
3) строка «E:» (алгоритм шифрования и сессионный ключ), для данного примера алгоритм шифрования aes-cbc, и 128-битный AES ключ «2a787e41 bbdc2f94 9ced721c 7fcf934e»
4) строка «A:» (алгоритм аутентификации и его ключ), для данного примера это hmac-sha1 и ключ «6af6847a 477bea9f 5c9a8d13 7ea9a5b5 9a318d29»

Т.к. у нас используется AES-CBC, то именно поэтому (из-за приставки -CBC) потребуется весь трафик с момента поднятия ipsec тоннеля (CBC — cipher block chaining). Возможно, с другими алгоритмами не потребуется иметь весь трафик, этого я не знаю, но думаю, что скорее всего будет требоваться весь трафик с момента поднятия ipsec туннеля.

Для декодирования и просмотра используем wireshark (1.8.2, можно и более раннюю версию, но там будет немного иначе).

Данные параметры нужно вбить в wireshark. Нужно открыть окно настроек «Edit->Preferences», там выбрать «Protocols->ESP», где установить галочки «Attempt to detect/decode NULL encrypted ESP payloads», «Attempt to detect/decode encrypted ESP payloads» и «Attempt to Check ESP Authentication».



Затем нажать кнопку «Edit» («Edit» -> «Создать») и вбить ip-адреса, spi и ключи полученные с помощью setkey:



После сохранения введенных изменений, мы должны получить декодированный трафик:



Для облегчения настройки wireshark я написал небольшую утилиту на perl, которая запускает setkey -D и форматирует вывод в формат настроек wireshark:

#!/usr/bin/perl -w

%ealg = (
	'aes-cbc' => 'AES-CBC [RFC3602]',
	'3des-cbc' => 'TripleDES-CBC [RFC2451]',
	'aes-ctr' => 'AES-CTR [RFC3686]',
	'todo' => 'DES-CBC [RFC2405]',
	'todo' => 'CAST5-CBC [RFC2144]',
	'blowfish-cbc' => 'BLOWFISH-CBC [RFC2451]',
	'twofish-cbc' => 'TWOFISH-CBC'
);
%aalg = (
	'hmac-sha1' => 'HMAC-SHA-1-96 [RFC2404]',
	'hmac-sha256' => 'HMAC-SHA-256-96 [draft-ietf-ipsec-ciph-sha-256-00]',
	'todo' => 'HMAC-SHA-256-128 [RFC4868]',
	'todo' => 'HMAC-MD5-96 [RFC2403]',
	'todo' => 'MAC-RIPEMD-160-96 [RFC2857]',
	'todo' => 'ANY 96 bit authentication [no checking]',
	'todo' => 'ANY 128 bit authentication [no checking]',
	'todo' => 'ANY 192 bit authentication [no checking]',
	'todo' => 'ANY 256 bit authentication [no checking]'
);

open KEYS, "setkey -D |";
while (defined($l = <KEYS>)) {
	if ($l =~ /^\d/) {
		($ip_src, $ip_dst) = (split(/\s+/, $l))[0,1];
	} elsif ($l =~ /^\s+esp mode=.*? spi=\d+\((0x.*?)\)/) {
		$spi = $1;
	} elsif ($l =~ /^\s+E: ([^\s]+)\s+(.*)$/) {
		($ealg, $ekey) = ($1, $2);

		$ealg = ($ealg{$ealg} or die "Unknown encr alg: '$ealg'");
		$ekey =~ s/\s+//g;
	} elsif ($l =~ /^\s+A: ([^\s]+)\s+(.*)$/) {
		($aalg, $akey) = ($1, $2);
		$aalg = ($aalg{$aalg} or die "Unknown auth alg: '$aalg'");
		$akey =~ s/\s+//g;

		print qq#"IPv4","$ip_src","$ip_dst","$spi",$ealg,"0x$ekey","$aalg","0x$akey"\n#;
		($ip_src, $ip_dst, $spi, $ealg, $ekey, $aalg, $akey) = ();
	}
}
close KEYS


Результат нужно записать в файл ~/.wireshark/esp_sa. После чего перезапустить wireshark.

Если скрипт у вас не заработает, и выдаст ошибку «Unknown encr alg» или «Unknown auth alg», нужно будет вбить в скрипт в хеш-таблицы %ealg или %aalg соответствие этого алгоритма в утилите setkey и соответствующего значения для wireshark. Мной тестировалось только с aes-cbc и hmac-sha1.

Дополнительная информация (немного устаревшая) на сайте wireshark.
Tags:
Hubs:
+13
Comments 6
Comments Comments 6

Articles