OpenBSD.org
. 2007-02-20: First notification sent by Core.
. 2007-02-20: Acknowledgement of first notification received from the
OpenBSD team.
. 2007-02-21: Core sends draft advisory and proof of concept code that
demonstrates remote kernel panic.
. 2007-02-26: OpenBSD team develops a fix and commits it to the HEAD
branch of source tree.
. 2007-02-26: OpenBSD team communicates that the issue is specific to
OpenBSD. OpenBSD no longer uses the term "vulnerability" when
referring to bugs that lead to a remote denial of service attack,
as opposed to bugs that lead to remote control of vulnerable systems
to avoid oversimplifying ("pablumfication") the use of the term.
. 2007-02-26: Core email sent to OpenBSD team explaining that Core
considers a remote denial of service a security issue and therefore
does use the term "vulnerability" to refer to it and that although
remote code execution could not be proved in this specific case,
the possibility should not be discarded. Core requests details about
the bug and if possible an analysis of why the OpenBSD team may or
may not consider the bug exploitable for remote code execution.
. 2007-02-28: OpenBSD team indicates that the bug results in corruption
of mbuf chains and that only IPv6 code uses that mbuf code, there is
no user data in the mbuf header fields that become corrupted and it
would be surprising to be able to run arbitrary code using a bug so
deep in the mbuf code. The bug simply leads to corruption of the mbuf
chain.
. 2007-03-05: Core develops proof of concept code that demonstrates
remote code execution in the kernel context by exploiting the mbuf
overflow.
. 2007-03-05: OpenBSD team notified of PoC availability.
. 2007-03-07: OpenBSD team commits fix to OpenBSD 4.0 and 3.9 source
tree branches and releases a "reliability fix" notice on the project's
website.
. 2007-03-08: Core sends final draft advisory to OpenBSD requesting
comments and official vendor fix/patch information.
. 2007-03-09: OpenBSD team changes notice on the project's website to
"security fix" and indicates that Core's advisory should reflect the
requirement of IPv6 connectivity for a successful attack from outside
of the local network.
. 2007-03-12: Advisory updates with fix and workaround information and
with IPv6 connectivity comments from OpenBSD team. The "vendors
contacted" section of the advisory is adjusted to reflect more
accurately the nature of the communications with the OpenBSD team
regarding this issue.
. 2007-03-12: Workaround recommendations revisited. It is not yet
conclusive that the "scrub in inet6" directive will prevent
exploitation. It effectively stops the bug from triggering according
to Core's tests but OpenBSD's source code inspection does not provide
a clear understanding of why that happens. It could just be that the
attack traffic is malformed in some other way that is not meaningful
for exploiting the vulnerability (an error in the exploit code rather
than an effective workaround?). The "scrub" workaround recommendation
is removed from the advisory as precaution.
. 2007-03-13: Core releases this advisory.

Release Mode: FORCED RELEASE

*Vulnerability Description*

The OpenBSD kernel contains a memory corruption vulnerability in the
code that handles IPv6 packets. Exploitation of this vulnerability can
result in:

1) Remote execution of arbitrary code at the kernel level on the
vulnerable systems (complete system compromise), or;

2) Remote denial of service attacks against vulnerable systems (system
crash due to a kernel panic)

The issue can be triggered by sending a specially crafted IPv6
fragmented packet.

OpenBSD systems using default installations are vulnerable because the
default pre-compiled kernel binary (GENERIC) has IPv6 enabled and
OpenBSD's firewall does not filter inbound IPv6 packets in its default
configuration.

However, in order to exploit a vulnerable system an attacker needs to
be able to inject fragmented IPv6 packets on the target system's local
network. This requires direct physical/logical access to the target's
local network -in which case the attacking system does not need to have
a working IPv6 stack- or the ability to route or tunnel IPv6 packets to
the target from a remote network.

All other releases that implement the IPv6 protocol stack may be
vulnerable.

*Solution/Vendor Information/Workaround*

The OpenBSD team has released a "security fix" to correct the mbuf
problem, it is available as a source code patch for OpenBSD 4.0
and 3.9 here:

ftp://ftp.openbsd.org/pub/OpenBSD/patches/4.0/common/010_m_dup1.patch

The patch can also be applied to previous versions of OpenBSD.

OpenBSD-current, 4.1, 4.0 and 3.9 have the fix incorporated in their
source code tree and kernel binaries for those versions and the
upcoming version 4.1 include the fix.

As a work around, users that do not need to process or route IPv6
traffic on their systems can block all inbound IPv6 packets using
OpenBSD's firewall. This can be accomplished by adding the following
line to /etc/pf.conf:

block in quick inet6 all

After adding the desired rules to pf.conf it is necessary to load them
to the running PF using:

pfctl -f /etc/pf.conf

To enable PF use:
pfctl -e -f /etc/pf.conf

To check the status of PF and list all loaded rules use:
pfctl -s rules

Refer to the pf.conf(5) and pfctl(8) manpages for proper configuration
and use of OpenBSD's firewall capabilities.

*Credits*

This vulnerability was found and researched by Alfredo Ortega from
Core Security Technologies. The proof-of-concept code included in the
advisory was developed by Alfredo Ortega with assistance from
Mario Vilas and Gerardo Richarte.

*Technical Description - Exploit/Concept Code*

The vulnerability is due to improper handling of kernel memory buffers
using mbuf structures. The vulnerability is triggered by
OpenBSD-specific code at the mbuf layer and developed to accommodate
the processing of IPv6 protocol packets.

By sending fragmented ICMPv6 packets an attacker can trigger an
overflow of mbuf kernel memory structures resulting either in remote
execution of arbitrary code in kernel mode or a kernel panic and
subsequent system crash (a remote denial of service). Exploitation is
accomplished by either:
1) Gaining control of execution flow by overwriting a function pointer,
or;
2) Performing a mirrored 4 byte arbitrary memory overwrite similar to
a user-space heap overflow.

The overflowed structure is an mbuf, the structure used to store
network packets in kernel memory.

This second structure contains the variable ext_free, a pointer to a
function called when the mbuf is freed. Overwriting a mbuf with a
crafted ICMP v6 packet (or any type of IPv6 packet), an attacker can
control the flow of execution of the OpenBSD Kernel when the m_freem()
function is called on the overflowed packet from any place on the
network stack.

Also, since the mbufs are stored on a linked list, another variant of
the attack is to overwrite the ext_nextref and ext_prevref pointers to
cause a 32 bit write on a controlled area of the kernel memory, like a
user-mode heap overflow exploit.

The following is a simple working proof-of-concept program in Python
that demonstrates remote code execution on vulnerable systems.
It is necessary to set the target's system Ethernet address in the
program to use it.

The PoC executes the shellcode (int 3) and returns. It overwrites the
ext_free() function pointer on the mbuf and forces a m_freem() on the
overflowed packet.

The Impacket library is used to craft and send packets
(http://oss.coresecurity.com/projects/impacket.html or download from
Debian repositories)

Currently, only systems supporting raw sockets and the PF_PACKET family
can run the included proof-of-concept code.

Tested against a system running "OpenBSD 4.0 CURRENT (GENERIC)
Mon Oct 30"

To use the code to test a custom machine you will need to:
1) Adjust the MACADDRESS variable
2) Find the right trampoline value for your system and replace it in
the code. To find a proper trampoline value use the following command:
"objdump -d /bsd | grep esi | grep jmp"
3) Adjust the ICMP checksum

The exploit should stop on an int 3 and pressing "c" in ddb the kernel
will continue normally.

for i in range(100): # fill mbufs
self.sendpacket(firstFragment)
self.sendpacket(validIcmp)
time.sleep(0.01)
for i in range(2): # Number of overflow packets to send. Increase if exploit is not reliable
self.sendpacket(secondFragment)
time.sleep(0.1)
self.sendpacket(firstFragment)
self.sendpacket(validIcmp)
time.sleep(0.1)

CoreLabs, the research center of Core Security Technologies, is charged
with anticipating the future needs and requirements for information
security technologies.

We conduct our research in several important areas of computer security
including system vulnerabilities, cyber attack planning and simulation,
source code auditing, and cryptography. Our results include problem
formalization, identification of vulnerabilities, novel solutions and
prototypes for new technologies.

Based in Boston, MA. and Buenos Aires, Argentina, Core Security
Technologies can be reached at 617-399-6980 or on the Web at
http://www.coresecurity.com.

*DISCLAIMER*

The contents of this advisory are copyright (c) 2007 CORE Security
Technologies and (c) 2007 CoreLabs, and may be distributed freely
provided that no fee is charged for this distribution and proper
credit is given.

*PGP Key*

This advisory has been signed with the PGP key of Core Security
Technologies advisories team, which is available for download at
http://www.coresecurity.com/files/attachments/core_security_advisories.a
sc