Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 May 2014 15:28:31 -0500
From:      David Noel <david.i.noel@gmail.com>
To:        FreeBSD Questions Mailing List <freebsd-questions@freebsd.org>
Subject:   MITM attacks against portsnap and freebsd-update
Message-ID:  <CAHAXwYBEtqxpDZJBhRF1=QDi6v97qQvJeYUbDE0kYqEsMbvf_w@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
I shared this with the freebsd-security mailing list last month but
didn't achieve my goal of finding a Bourne-savvy programmer who was
willing to take on this bug. I'm posting it here to address a larger
audience and hopefully find someone who has the time free to come up
with some patches for us.

---

I found a few bugs in portsnap and freebsd-update that I'd like to
bring to the community's attention and hopefully recruit people to
help fix. I mentioned them to Colin (their author) a few years ago and
he agreed that they're issues that need to be addressed, but in the
time since neither he nor I have been able to get around to fixing
them. I'm hoping that someone reading this is able and willing to
pitch in. I've also taken this to secteam@, but no one there's made
any progress on them in the past 6 months so I figured it was time to
approach the broader community. Surely there's a benevolent sh-savvy
hacker out there who has time to take these on. They're pretty simple
fixes -- the functionality that's needed exists in the scripts
already, it just needs to be reused in a few key places.

I also think it would be an appropriate time to discuss retiring portsnap.

Problem Summary

1. Both portsnap and freebsd-update extract fetched data prior to
SHA256 verifying it. The extraction libraries used have a long history
of bugs so it's reasonable to assume there might be more. Both
freebsd-update and portsnap are run as root. Using a vulnerability in
the extraction libraries an attacker who was MITM-capable could
compromise any FreeBSD system running portsnap or freebsd-update.
2. The portsnap mirroring script (pmirror.sh) lacks of any sort of
mechanism to verify the data prior to processing and mirroring it.
Without this, mirrors are open to compromise via methods similar to
those found in the client-side scripts (decompression library
exploitation). It also means an attacker could feed a mirror a corrupt
archive, opening users of that mirror to compromise.
3. Both portsnap and freebsd-update are vulnerable to freeze attacks.
4. The addition of subversion in base makes portsnap redundant.
5. The default implementation of the portsnap build code leaves users
vulnerable to MITM attacks.

Solution Summary

1. A re-working of the snapshot hashing and hash verification process.
2. The addition of hashing and hash verification code to pmirror.sh.
3. The server-side inclusion of date-stamps, and strict client-side
enforcement of expiration policies.
4. Begin phasing out portsnap.
5. Switch the default subversion URL to HTTP Secure.

Details

The functions of concern in portsnap.sh are fetch_snapshot(),
fetch_update(), and fetch_snapshot_verify().
The lines of concern in pmirror.sh are 99-103, 121-125, 138-149, and
153-157 (using revision 257073).
The functions of concern in freebsd-update.sh are fetch_metadata(),
fetch_files_premerge(), and fetch_files().

The changes will need to apply to those sections of code and the
corresponding code in the build scripts.

Retiring Portsnap

Given the inclusion of svnlite in 10 and the amount of effort required
to fix these bugs I think the valid question comes up as to whether we
really need the portsnap system. My position is that it could be
safely retired. Obviously if the conclusion of that discussion is that
we don't need it then these bug fixes would be unnecessary.

The main argument I see for it to be retired is that subversion allows us to
do everything portsnap does and more; it allows us to easily and
securely check out the ports tree. Checking out the repository is a
one line command: `svn co https://... /usr/ports`. Keeping it
up-to-date it is another one-liner: `svn update`. With the inclusion
of svnlite in base, the portsnap code and servers acting as mirrors
seem redundant and a waste of resources.

PR's

I've avoided filing PR's to give myself, Colin, or secteam@ the chance
to fix these bugs first. Since none of us have had the time to do
so and because I'm now sharing these bugs publicly with the list I
figure it would be an appropriate time to file PR's for them.

MITM attacks against freebsd-update:
http://www.freebsd.org/cgi/query-pr.cgi?pr=188429
MITM attacks against portsnap: http://www.freebsd.org/cgi/query-pr.cgi?pr=188428
Freeze attacks against freebsd-update:
http://www.freebsd.org/cgi/query-pr.cgi?pr=188434
Freeze attacks against portsnap:
http://www.freebsd.org/cgi/query-pr.cgi?pr=188430
MITM attacks against portsnap mirrors (pmirror.sh):
http://www.freebsd.org/cgi/query-pr.cgi?pr=188432
Retiring portsnap: http://www.freebsd.org/cgi/query-pr.cgi?pr=188433

---

In a later email I pointed out that the portsnap build code pulls the
ports tree from subversion using http vs https. This makes ports trees
fetched via portsnap vulnerable to MITM attacks and potential
corruption as well. A member of the Security Team, Xin Li was kind
enough to look into this and brought to our attention that the actual
portsnap build system is running a somewhat modified version of the
scripts found in Colin's subversion directory
(http://svnweb.freebsd.org/base/user/cperciva/). The changes applied
to those scripts tell the build system to fetch all files from svn via
spiped, in theory securing them from MITM attacks. I have not
personally reviewed the spiped code so I am not certain whether
transport via spiped truly secures the data transfer.

There remains the question of whether the portsnap mirror scripts were
modified similarly in production.

Regardless, anyone using the build and mirror scripts found on svn is
vulnerable to attack, so privately run portsnap mirrors using those
scripts should be treated accordingly.

---

The good news is that these are relatively simple fixes. Colin's code
is clean, efficient, and aside from these small oversights very well
written. Another thing that makes this an easy fix is that the
functionality that's needed exists elsewhere in the code, so there are
plenty of good examples to work from. It's virtually a copy/paste job,
but not quite that simple.

If no one here is able to pick these up it's not the end of the world
-- I'll get around to them eventually. But for now I'm poor and
unemployed, so every free moment of productive time I have is going
towards projects that contribute towards taking care of my life's
basic necessities.

-David



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAHAXwYBEtqxpDZJBhRF1=QDi6v97qQvJeYUbDE0kYqEsMbvf_w>