Discussion:
[Ipsec-tools-devel] [Ipsec-tools-core] Potential Vulnerability Discovered in IPsec-Tools
Robert Foggia
2016-10-13 16:43:56 UTC
Permalink
Hello,

Please find attached a patched for an issue discovered in ipsec-tools affecting raccoon 0.8.2 and prior. Details about Remote un-authenticated denial of service finding is below:

Finding 1: Remote un-authenticated denial of service
Credit: Trustwave

The ipsec-tools racoon daemon contains a remotely exploitable computational complexity attack when parsing and storing isakmp fragments. The implementation permits a remote attacker to exhaust computational resources on the remote endpoint by repeatedly sending isakmp fragment packets in a particular order such that the worst-case computational complexity is realized in the algorithm utilized to determine if reassembly of the fragments can take place.

The algorithm in question is a simple quadratic linked list walk and is in O(n(n+1)) hence O(n^2) for ’n’ fragments received. Since the implementation fails to identify repeated fragment indices, a remote attacker can repeatedly specify the same index. Worst-case complexity is realized if fragments are sent in reverse order, for instance:

253, 252 ... 3, 2, 1, 255 (last fragment)

The absence of fragment index 254 is not an error as this ensures fragment reassembly is not possible.


After review, please provide feedback on the next steps to get this issue patched. Thanks!


Best regards,

Robert F.
Security Researcher, Intelligence Team, SpiderLabs

Trustwave | SMART SECURITY ON DEMAND
www.trustwave.com <http://www.trustwave.com/>


On Wed, 27 Jul 2016 16:09:04 +0000
In the interest of responsible disclosure, we are notifying you about
potential vulnerability we have discovered in IPSec-Tools. This
vulnerability allows the ability for a remote unauthenticated
attacker to perform a denial of service attack. Based on our
disclosure policy, we will release an advisory detailing these
finding(s) after 30 days if we do not receive a reply. Because of the
sensitive nature of this issue, we are unable to include the advisory
in this email. However, we'd be happy to send the full advisory to
you. Please let me know if you prefer for us to send it encrypted
with your PGP key, send it using our secure email system, or simply
using conventional email.
It seems no one is actively maintaining the upstream distribution any
more. However, there is active community using it on ipsec-tools-devel
mailing list. I suggest you post there first the patch if one exists,
or other details.

Thanks,
Timo


________________________________

This transmission may contain information that is privileged, confidential, and/or exempt from disclosure under applicable law. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein (including any reliance thereon) is strictly prohibited. If you received this transmission in error, please immediately contact the sender and destroy the material in its entirety, whether in electronic or hard copy format.
Reinoud Koornstra
2016-10-15 09:55:21 UTC
Permalink
Hi Robert,

Thanks for the patch and discovering this. Adding Rainer to this thread as
he'll know quickly if this patch is good or needs a small adjustment.
Thanks,

Reinoud.
Post by Robert Foggia
Hello,
Please find attached a patched for an issue discovered in ipsec-tools
affecting raccoon 0.8.2 and prior. Details about Remote un-authenticated
Finding 1: Remote un-authenticated denial of service
Credit: Trustwave
The ipsec-tools racoon daemon contains a remotely exploitable
computational complexity attack when parsing and storing isakmp fragments.
The implementation permits a remote attacker to exhaust computational
resources on the remote endpoint by repeatedly sending isakmp fragment
packets in a particular order such that the worst-case computational
complexity is realized in the algorithm utilized to determine if reassembly
of the fragments can take place.
The algorithm in question is a simple quadratic linked list walk and is in
O(n(n+1)) hence O(n^2) for ’n’ fragments received. Since the implementation
fails to identify repeated fragment indices, a remote attacker can
repeatedly specify the same index. Worst-case complexity is realized if
253, 252 ... 3, 2, 1, 255 (last fragment)
The absence of fragment index 254 is not an error as this ensures fragment
reassembly is not possible.
After review, please provide feedback on the next steps to get this issue patched. Thanks!
Best regards,
Robert F.
Security Researcher, Intelligence Team, SpiderLabs
Trustwave | SMART SECURITY ON DEMAND
www.trustwave.com <http://www.trustwave.com/>
On Wed, 27 Jul 2016 16:09:04 +0000
In the interest of responsible disclosure, we are notifying you about
potential vulnerability we have discovered in IPSec-Tools. This
vulnerability allows the ability for a remote unauthenticated
attacker to perform a denial of service attack. Based on our
disclosure policy, we will release an advisory detailing these
finding(s) after 30 days if we do not receive a reply. Because of the
sensitive nature of this issue, we are unable to include the advisory
in this email. However, we'd be happy to send the full advisory to
you. Please let me know if you prefer for us to send it encrypted
with your PGP key, send it using our secure email system, or simply
using conventional email.
It seems no one is actively maintaining the upstream distribution any
more. However, there is active community using it on ipsec-tools-devel
mailing list. I suggest you post there first the patch if one exists,
or other details.
Thanks,
Timo
________________________________
This transmission may contain information that is privileged,
confidential, and/or exempt from disclosure under applicable law. If you
are not the intended recipient, you are hereby notified that any
disclosure, copying, distribution, or use of the information contained
herein (including any reliance thereon) is strictly prohibited. If you
received this transmission in error, please immediately contact the sender
and destroy the material in its entirety, whether in electronic or hard
copy format.
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Ipsec-tools-devel mailing list
https://lists.sourceforge.net/lists/listinfo/ipsec-tools-devel
Rainer Weikusat
2016-10-18 16:33:56 UTC
Permalink
Post by Reinoud Koornstra
Thanks for the patch and discovering this. Adding Rainer to this thread as
he'll know quickly if this patch is good or needs a small adjustment.
Thanks,
The underlying problem is really that racoon just puts all fragments it
receives on a list without checking for duplicate fragment indices. This
means an unauthenticated attacker can just keep sending a fragment with
the same index and the list will keep growing until the machine runs out
of memory. It's also possible to make the daemon additionally consume a
lot of CPU time by triggering 'did we receive all fragements' scans
after each fragment was received. The algorithm used for detecting this
is roughly:


for (i = 1; i <= last_frag_index; ++i)
/* walk complete list to look for fragment with index i */

The proposed patch addresses this partially by checking that no
duplicate fragments are received and by keeping the fragment list sorted
(insertion sort) so that the scan for 'all fragments received' becomes
linear. But there's another quadratic scan in the reassembly function and
for at most 255 fragments, the complexity doesn't matter that much.

As bandaid, I suggest to leave the scan algorithm alone and just reject
duplicated and/or obviously nonsensical fragment numbers.

It's possible to do a O(1) implementation here (I'm using a partial O(1)
implementation in the commercial fork I'm maintaining) and I'm planning
to replace this with a complete one. I'll ask for permission to publish
it once it's done.

Getting in touch with NetBSD might also a good idea as they are (AFAIK)
maintaining there own fork as part of the NetBSD tree.

NB: A known issue with this (and also the other patch) is that the
daemon will accept fragments whose index is larger than that of the one
marked as last fragment. But this should be harmless.

---
diff -rNu ipsec-tools-0.8.0/src/racoon/isakmp_frag.c patched/src/racoon/isakmp_frag.c
--- ipsec-tools-0.8.0/src/racoon/isakmp_frag.c 2009-04-22 12:24:20.000000000 +0100
+++ patched/src/racoon/isakmp_frag.c 2016-10-18 17:28:57.289513357 +0100
@@ -231,14 +231,31 @@
if (iph1->frag_chain == NULL) {
iph1->frag_chain = item;
} else {
- struct isakmp_frag_item *current;
+ struct isakmp_frag_item *current, *next;

- current = iph1->frag_chain;
- while (current->frag_next) {
- if (current->frag_last)
- last_frag = item->frag_num;
- current = current->frag_next;
- }
+ next = iph1->frag_chain;
+ do {
+ current = next;
+ if (current->frag_num == item->frag_num) {
+ plog(LLV_DEBUG, LOCATION, NULL, "duplicate fragment %d\n",
+ item->frag_num);
+
+ free(item);
+ return 0;
+ }
+
+ if (current->last_frag) {
+ if (item->last_frag) {
+ plog(LLV_WARNING, LOCATION, NULL, "multiple last fragments received\n");
+
+ free(item);
+ return -1;
+ }
+
+ last_frag = current->frag_num;
+ }
+ } while ((next = next->next));
+
current->frag_next = item;
}
Rainer Weikusat
2016-10-18 20:45:38 UTC
Permalink
Rainer Weikusat <***@mobileactivedefense.com> writes:

[...]
Post by Rainer Weikusat
+ current = next;
+ if (current->frag_num == item->frag_num) {
+ plog(LLV_DEBUG, LOCATION, NULL, "duplicate fragment %d\n",
+ item->frag_num);
+
+ free(item);
+ return 0;
+ }
This leaks memory in both early exits as the data is in a dynamically
allocated buffer[*].

[*] It also calls free instead of racoon_free. This doesn't really
matter because the only difference is that the code could be compiled
with the Boehm-GC and I doubt anyone uses that (plain malloc is also
used in other places).

---
diff -rNu ipsec-tools-0.8.0/src/racoon/isakmp_frag.c patched/src/racoon/isakmp_frag.c
--- ipsec-tools-0.8.0/src/racoon/isakmp_frag.c 2009-04-22 12:24:20.000000000 +0100
+++ patched/src/racoon/isakmp_frag.c 2016-10-18 21:37:12.033038458 +0100
@@ -231,14 +231,35 @@
if (iph1->frag_chain == NULL) {
iph1->frag_chain = item;
} else {
- struct isakmp_frag_item *current;
+ struct isakmp_frag_item *current, *next;

- current = iph1->frag_chain;
- while (current->frag_next) {
- if (current->frag_last)
- last_frag = item->frag_num;
- current = current->frag_next;
- }
+ next = iph1->frag_chain;
+ do {
+ current = next;
+ if (current->frag_num == item->frag_num) {
+ plog(LLV_DEBUG, LOCATION, NULL, "duplicate fragment %d\n",
+ item->frag_num);
+
+ racoon_free(item);
+ vfree(buf);
+
+ return 0;
+ }
+
+ if (current->last_frag) {
+ if (item->last_frag) {
+ plog(LLV_WARNING, LOCATION, NULL, "multiple last fragments received\n");
+
+ racoon_free(item);
+ vfree(buf);
+
+ return -1;
+ }
+
+ last_frag = current->frag_num;
+ }
+ } while ((next = next->next));
+
current->frag_next = item;
}
Robert Foggia
2016-11-07 18:56:44 UTC
Permalink
Hi Rainer,

Thanks for the feedback. Just checking if there are any news on this. Thanks!


Best regards,

Robert Foggia
Security Researcher, Intelligence Team, SpiderLabs
t: +1 312.873.7696

Trustwave | SMART SECURITY ON DEMAND
www.trustwave.com <http://www.trustwave.com/>
Post by Rainer Weikusat
Post by Reinoud Koornstra
Thanks for the patch and discovering this. Adding Rainer to this thread as
he'll know quickly if this patch is good or needs a small adjustment.
Thanks,
The underlying problem is really that racoon just puts all fragments it
receives on a list without checking for duplicate fragment indices. This
means an unauthenticated attacker can just keep sending a fragment with
the same index and the list will keep growing until the machine runs out
of memory. It's also possible to make the daemon additionally consume a
lot of CPU time by triggering 'did we receive all fragements' scans
after each fragment was received. The algorithm used for detecting this
for (i = 1; i <= last_frag_index; ++i)
/* walk complete list to look for fragment with index i */
The proposed patch addresses this partially by checking that no
duplicate fragments are received and by keeping the fragment list sorted
(insertion sort) so that the scan for 'all fragments received' becomes
linear. But there's another quadratic scan in the reassembly function and
for at most 255 fragments, the complexity doesn't matter that much.
As bandaid, I suggest to leave the scan algorithm alone and just reject
duplicated and/or obviously nonsensical fragment numbers.
It's possible to do a O(1) implementation here (I'm using a partial O(1)
implementation in the commercial fork I'm maintaining) and I'm planning
to replace this with a complete one. I'll ask for permission to publish
it once it's done.
Getting in touch with NetBSD might also a good idea as they are (AFAIK)
maintaining there own fork as part of the NetBSD tree.
NB: A known issue with this (and also the other patch) is that the
daemon will accept fragments whose index is larger than that of the one
marked as last fragment. But this should be harmless.
---
diff -rNu ipsec-tools-0.8.0/src/racoon/isakmp_frag.c patched/src/racoon/isakmp_frag.c
--- ipsec-tools-0.8.0/src/racoon/isakmp_frag.c 2009-04-22 12:24:20.000000000 +0100
+++ patched/src/racoon/isakmp_frag.c 2016-10-18 17:28:57.289513357 +0100
@@ -231,14 +231,31 @@
if (iph1->frag_chain == NULL) {
iph1->frag_chain = item;
} else {
- struct isakmp_frag_item *current;
+ struct isakmp_frag_item *current, *next;
- current = iph1->frag_chain;
- while (current->frag_next) {
- if (current->frag_last)
- last_frag = item->frag_num;
- current = current->frag_next;
- }
+ next = iph1->frag_chain;
+ do {
+ current = next;
+ if (current->frag_num == item->frag_num) {
+ plog(LLV_DEBUG, LOCATION, NULL, "duplicate fragment %d\n",
+ item->frag_num);
+
+ free(item);
+ return 0;
+ }
+
+ if (current->last_frag) {
+ if (item->last_frag) {
+ plog(LLV_WARNING, LOCATION, NULL, "multiple last fragments received\n");
+
+ free(item);
+ return -1;
+ }
+
+ last_frag = current->frag_num;
+ }
+ } while ((next = next->next));
+
current->frag_next = item;
}
________________________________

This transmission may contain information that is privileged, confidential, and/or exempt from disclosure under applicable law. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein (including any reliance thereon) is strictly prohibited. If you received this transmission in error, please immediately contact the sender and destroy the material in its entirety, whether in electronic or hard copy format.
Loading...