[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: not getting compromised while applying apt-get upgrade for CVE-2016-1252

First things first:
If you really want to pull packages by hand you need to pull libapt-pkg
as the faulty code is in the apt library (aka it effects aptitude,
synaptics, …). Updating apt only isn't changing anything…

Second: The DSA unfortunately didn't mention apt-ftparchive – if you
don't trust the source of the .dsc files it reads that might be the
better place to exploit this CVE…
so lets get into details:

On Fri, Dec 16, 2016 at 10:32:00PM +0000, Patrick Schleizer wrote:
> Julian Andres Klode:
> > (2) look at the InRelease file and see if it contains crap
> >     after you updated (if it looks OK, it's secure - you need
> >     fairly long lines to be able to break this)
> Thank you for that hint, Julian!
> Can you please elaborate on this? (I am asking for Qubes and Whonix
> (derivatives of Debian) build security purposes. [1])
> Could you please provide information on how long safe / unsafe lines are
> or how to detect them?

The exploit uses the fact that apt performs the splitting of a clear-
signed file multiple times, one time for verification and later again to
actual work with the "verified" data.¹ So you need to trick apt with the
same file to "see" sometimes the good and sometimes the bad stuff. How
do you do that?

The splitting code uses the function getline(3) and basically does the
same as the example code provided in the manpage – lets copy for

| while ((read = getline(&line, &len, stream)) != -1) {
|    printf("Retrieved line of length %zu :\n", read);
|    printf("%s", line);

This loop runs as long as there are lines in the file (stream) until no
line is left and getline returns -1 – expect that this isn't the only
case it can return -1. The manpage mentions bad arguments – we know what
we are doing, so that isn't the case aka we are fine. Are we?

No, getline can also fail if it can't allocate enough memory to hold the
complete current line (aka: The example code has the same 'exploit',
just that the action it performs isn't security relevant).  So, all you
have to do as an attacker is put the target machine under enormous
memory pressure at the right moment so that the allocation fails and the
code incorrectly assumes end-of-file, so that your bad content at the
beginning of the file is treated as data instead of ignored as "garbage"
if apt had seen the later lines (with the signed data it had seen just
moments earlier while verifying).

The provided exploit used a 1.3 GB big InRelease file for that, which
works with some confidence on a sufficiently memory-starved i386 system
if you can live with the fact that this works only 1/4 of the time as
the rest of the time it will fail (or not) at the wrong moment resulting
in errors from apt. More recent (>= 1.1) apt versions bail if
a (In)Release file is larger than 10 MB which is further complicating
things. A good attacker therefore likely needs a way to put the machine
in a memory-starved state on demand – like DoS the webserver running on
the same box at the right moment. Timing and luck is really important.

> [some comments I had read elsewhere and just want to comment on here]

I am not trying to downplay the problem as such: I made a bubu (as it
was me who wrote that faulty code), it is a serious exploit and you
should upgrade BUT we had far worse things in the past, so don't get too
excited: The world hasn't ended yet.

In all honesty that CVE makes me a bit happy and proud as it means that
someone cared enough about some code I wrote to look at it searching for
a way to exploit it and THIS is the best they came up with. You never
get a note of "I looked, but couldn't find anything" and the default is
"nobody looked or cared" so in some twisted and strange way it is nice…

It is nicer than what can be deduced from many reactions from self-
called experts at least as some comments proof that they haven't
understood the CVE nor looked at all at the fix, which is a bit strange
as it means people seem to care, but don't look anyhow… dangerous
combination and not very encouraging.

> Ideally could you please provide some sanity check command that could be
> used to detect malicious InRelease files such as 'find /var/lib/apt
> -name '*InRelease*' -size +2M' or so?

That is likely all it takes.

You should also be able to look at the first line of the file and see
"-----BEGIN PGP SIGNED MESSAGE-----" there (without quotes). If that
isn't the case it must not be a problem, but it is with 99% confidence.
(I am working on some changes to make apt warn if that isn't the case,
but I kinda expect some strange repository somewhere to violate this.
Note that gpg does the same ignoring apt does here – but its usecase is
different with clearsigned mails and such where unsigned parts are

In terms of stable (which seems to be what you are asking about) there
is a trivial 99,9% shortcut: stable has no InRelease file for technical
reasons ATM, so something is fishy if you get one (aka apt should
display Ign lines).²

If you are sufficiently paranoid ensure that you have a reasonable
amount of free memory, apt isn't downloading giant InRelease files, look
at them (its the type of stuff you know is wrong without even knowing
how a legit file should look) and run update a few times in a row
(delete /var/lib/apt/lists in between) take note if one of these calls

> - debootstrap can only bootstrap from one source such as
> 'http://ftp.de.debian.org/debian' - which still contains vulnerable apt.
> (Correct me if I am wrong, I would hope to be wrong on that one.)

It will be included there with the next point-release same as all other
updates. unstable has it already and I asked for hinting it to testing
earlier. The mirror network can take 'ages' to update, so you can't
really depend on it – stable sources do not even have Valid-Until, so
a MITM can replay an old archive state to you "forever" anyhow meaning
that you need to always check your bootstrap and this one is hardly
a big additional hurdle… [or you have a "trusted" (local) mirror] –
you do perform checks, don't you?

btw: debootstrap happens without apt being involved as you can bootstrap
from basically any system – getting apt to run on any system while not
entirely impossible is considerably harder and it expects a reasonable
systemstate to work with which a bootstrapping system is not… in
exchange you don't get support for more advanced stuff like Valid-Until
(if it were available). Pick your poison I guess.

Best regards

David Kalnischkies

¹ Its complicated as many different code parts are interacting here, so
simply storing the split-result wasn't as easy as it sounds. The acquire
system rewrite we performed the last few years should make that possible
now. I wanted to look into that anyhow, just have to find the time as it
is still not as easy as it sounds. Just likely "possible".

² to verify InRelease files apt splits the file internally into
a Release and a Release.gpg file and verifies those. You can do the
opposite as well to craft an InRelease file – I doubt any mirror is
doing this (because: hard), so that leaves you with evil people only…

Attachment: signature.asc
Description: PGP signature

Reply to: