Tuesday, November 15, 2016

[0day] [PoC] Risky design decisions in Google Chrome and Fedora desktop enable drive-by downloads

Overview
A confluence of two risky design choices, combined with various implementation issues, makes drive-by downloads possible with Google Chrome on Fedora. In total, with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 risky design choices first, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issues are:

  • Chrome will auto download files to a user’s desktop with no confirmation.
  • Fedora’s “tracker” software will auto crawl downloaded files to index cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, including media files.
  • The “gstreamer” framework, as used to handle media in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Fedora desktop, has questionable implementation quality from a security perspective.
  • The “tracker” component responsible for parsing media files does not appear to be sandboxed (e.g. with SELinux).
  • The Fedora default desktop install includes a range of fairly obscure media decoders that confer risk but are not necessary for a thorough desktop experience.

Demonstration and proof of concept
In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 screenshot below, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Chrome browser has visited a (malicious) website and you can see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is a forced download leading to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 side effect of a crash in a process unrelated to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 web browser:

tracker_crash.png

“We’re sorry, it looks like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Tracker Metadata Extractor crashed.” It certainly did, without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user needed to do anything ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r that visit a web page. It is not necessary to click on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 button corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 download.

This is in a default install of Fedora 24, but with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer updates applied (without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, gstreamer doesn’t work correctly). The crashing binary is /usr/libexec/tracker-extract. It has ASLR enabled, which is good. But ps -eZ identifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security context as unconfined_u:unconfined_r:unconfined_t, which appears unsandboxed. The crash manifests as an out-of-bounds write.

The demo file can be downloaded here: vmnc_width_height_int_oflow.avi.

This vulnerability also affects cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default install of Ubuntu 16.04, as long as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “mp3” option was selected during install. (This vulnerability appears to go significantly back into history, at least affecting all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way back to Ubuntu 12.04 and it’s older gstreamer-0.10.) Ubuntu doesn’t seem to index desktop files by default though, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 impact on Ubuntu will be less severe but still nasty via e.g. triggering thumbnailing by opening cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 nautilus file browser in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Downloads directory. Or opening a USB drive. Or e-mailing someone cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit file and have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m open it in a media player.

0day details
(Absent a CVE, you can uniquely identify this as CESA-2016-0002.)
The vmnc decoder renders video for a VMware screen capture format. This format is usually contained within an AVI container. The vmnc decoder in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer code base contains a fairly obvious and simple width * height * depth integer overflow in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 render buffer. From gst-plugins-bad1.0/gst/vmnc/vmncdec.c:

static int
vmnc_handle_wmvi_rectangle (GstVMncDec * dec, struct RfbRectangle *rect,
   const guint8 * data, int len, gboolean decode)
{
 bpp = data[0];
 dec->format.bytes_per_pixel = bpp / 8;
 dec->format.width = rect->width;
 dec->format.height = rect->height;
 dec->imagedata = g_malloc (dec->format.width * dec->format.height *
     dec->format.bytes_per_pixel);

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above code, rect->width and rect->height are attacker controlled 16-bit unsigned values taken straight from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input file. bpp is also taken from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input file, and is validated to be one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 typical depth values 8, 16, 32.

To create cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC, an existing sample file was located from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 excellent MPlayerHQ test set: test.avi. This is a vmnc-inside-avi sample file. All that is changed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 width and height values at file offset 0x201c are changed to 65535 and 32769, respectively. The base image is a 16bpp image, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 calculation on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overflow line is 65535 * 32769 * 2. In signed 32-bit integer math, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is 65534. That’s a reasonable sized buffer but subsequent decoding believes that it has a huge 65535 x 32769 canvas to render into. Heap based buffer overflow results.

Exploitability
Yes.
To be a bit more specific, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are a couple of challenges which would make this exploit tricky: firstly, this is 64-bit modern Linux (and in particular, Fedora), where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ASLR is generally pretty good. Secondly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker does not have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 luxury of attacking this vulnerability from a scripting environment. This is key, and makes things much harder, because pointers cannot be readily calculated based on information leaks, decisions cannot be made based on measurements of corruption side effects, etc.

However, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 flipside, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are a lot of ways in which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker has a lot of control and assistance to exploit this, even without script to help. Let’s enumerate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, we might find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range of possibilities surprising:

  • Precise control over heap chunk size that is overflowed. By fiddling with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 width, height and bpp values that factor into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 integer overflow, we can choose a wide range of different chunk sizes to later go off cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of. This means we can corrupt a lot of different areas of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap depending on what works best.
  • Surprisingly stable heap layout. The vmnc decoding kicks off on a relatively fresh thread, which typically has a relatively fresh glibc per-thread malloc arena. Heap grooming may only be minimally required, if at all.
  • Possibility for 3 byte partial pointer overwrites. Because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overflow is kicking off inside a glibc thread area, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 alignment of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 arena is typically to 16MB or so. This means you can potentially do up to a 3 byte partial pointer overwrite reliably. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 world of partial pointer overwrites, this is a luxury.
  • Excellent heap grooming opportunities inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vmnc decode loop. Inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main decode loop, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are lots of opportunities to allocate and free memory, with great control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sizes. This occurs in vmnc_handle_wmvi_rectangle(), which can reallocate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existing decode buffer, and vmnc_handle_wmvd_rectangle(), which allocates and frees cursor buffers. This level of control will allow good heap grooming, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 possibility of attacking heap metadata, if no ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r good opportunities present cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves.
  • A copy primitive as one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rendering modes. This is super big. vmnc_handle_copy_rectangle() is a rendering mode that will take pixels from one area of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image and copy cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r area of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image. Since our integer overflow leads to a small image buffer but a huge image canvas size, you can see that this will enable us to read some out-of-bounds content and write that out-of-bounds. This solves one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardest problems we might face, which is to syncá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365size valid pointers in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of good ASLR. We can read an existing valid pointer that is out-of-bounds, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n copy it somewhere else, also out-of-bounds.

To back up a couple of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above points, we can briefly look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC crashing in gdb. We’ll run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 totem media player on both Ubuntu 16.04 and Fedora 24:

gdb totem
r vmnc_width_height_int_oflow.avi
[SEGV]
(gdb) bt
#0  __memcpy_avx_unaligned ()
(gdb) i r
...
rsi            0x7fffbb5e0015 140736336887829
rdi            0x7fffa40237fe 140735944996862
...

The last three bytes of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rdi register at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 crash are reasonably consistent across both Ubuntu and Fedora, at 0x0237fe. This is just off cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of a glibc thread arena, which ends at 0x022000. This illustrates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fairly clean heap state, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 16MB+ alignment of thread arenas.

It’s clear that writing this exploit would be a lot of fun. I’ll put it on my TODO list, but I’d love to see someone else pick it up.

Google Chrome’s culpability
Let’s be clear: Google Chrome is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most secure of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 common general purpose browsers out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re. It has had more effort and money put into sandboxing, code quality, mitigations, fuzzing and community security involvement than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r browsers. This is all backed by a large, strong security team -- cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 largest monetary investment of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 major browser vendors, which speaks volumes.

However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default download behavior is one where you can point to e.g. Firefox’s solution as demonstrably superior: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user has to accept any random attacker supplied bytes before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are dumped to disk in a well known and indexable location, with an attacker supplied filename and extension.

This could be a default behavior to re-align with ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r browsers, to avoid known security headaches, and probably some as-yet-undiscovered ones too.

Absent action from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Chrome developers, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is fortunately a setting that can be used in environments where security is a concern: chrome://settings -> Show advanced settings -> Downloads -> Ask where to save each file before downloading.

Fedora’s culpability
You can clearly see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 appeal of parsing and indexing all files that appear on disk. It enables desktop functionality that some users will consider userful. Certainly, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r non-Linux operating systems do some of this too. But, this cannot be done carelessly. The lack of a robust sandbox for automatically parsing media formats seems like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 largest gap Fedora has.

This is a problem that lends itself nearly ideally to sandboxing: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 inputs and outputs and clear, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rights needed to transform cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 inputs into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 outputs are minimal. The input is just a memory chunk of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 media file to be indexed. The output is a few metadata strings, perhaps some fixed format thumbnail canvases, etc. And cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rights needed to do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transform are probably minimal: no writable filesystem access, no network access, no ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r process access, etc.

There’s also cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 concern that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 media attack surfaces are a little out of hand. The default desktop install offers a range of fringe decoders that provide risk, for little benefit. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of Fedora 24, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 faulty plug-in is pulled in via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default package gstreamer1-plugins-bad-free. From cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer documentation: “cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se plug-ins are Bad with a capital B”. I’m not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first to notice this possible disconnect. From Ted Unangst’s post: “I do not want something called gstreamer-plugins-bad to be connected to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 internet”. For some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most dodgy decoders, we probably shouldn’t even be providing a nice automatic UI to offer to install cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, because users will just click “yes”.

We can note that one quick way to break cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 link between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two risky designs is to remove cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user/Downloads folder from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 list of indexed paths. This can be achieved via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tracker-preferences tool, see below.

Disabling or removing tracker is non-trivial. This thing is like a virus! There’s some good information here: How do I disable tracker? To distill it:

  • There’s a non-default-install tool, tracker-preferences, that appears to offer cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to disable indexing, or configure which paths are indexed.
  • Or you may prefer to just eviscerate tracker from your install. A lot of things depend on it, but rpm -e tracker --nodeps does not appear to blow things up too badly.
  • Beware that even after removing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tracker package, a log out and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n in still left cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 daemons running for me. Perhaps do a reboot to be safe.

Bonus 0day
(Absent a CVE, you can uniquely identify this as CESA-2016-0003.)
The render canvas, as allocated in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code snippet quoted way above, is not black filled or ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rwise initialized. The call to g_malloc() is just a thin wrapper around malloc(), which does not initialize any returned heap area. Therefore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s an easy information leak in thumbnailing a simple 1 frame vmnc movie that does not draw to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocated render canvas at all. This could be a problem for anyone using gstreamer in a server environment to provide thumbnailing services.

Closing notes
Did I mention that ffmpeg has a vmnc decoder too and it appears more robust than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer one?


This was too easy. It should not be possible to find a serious memory corruption vulnerability in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default Linux desktop attack surface with just a few minutes of looking. Although it’s hard to say it, this is not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kind of situation that occurs with a latest Windows 10 default install. Is it possible that Linux desktop security has rotted?

Monday, November 14, 2016

[0day] [exploit] Compromising a Linux desktop using... 6502 processor opcodes on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NES?!

Overview
A vulnerability and a separate logic error exist in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer 0.10.x player for NSF music files. Combined, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y allow for very reliable exploitation and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bypass of 64-bit ASLR, DEP, etc. The reliability is provided by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of a turing complete “scripting” inside a music player. NSF files are music files from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Nintendo Entertainment System. Curious? Read on...

Demonstration, and affected distributions
Here is a screenshot of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit triggering. Somewhat alarmingly, it does so without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user opening cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit file -- cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y only have to navigate to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 folder containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file. More on that below.

xcalc_from_downloads_folder.png

You can download cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file: exploit_ubuntu_12.04.5_xcalc.nsf. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 image above, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file has been renamed to “time_bomb.mp3”. We’ll cover why below.

As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 filename suggests, this exploit works against Ubuntu 12.04.5. This is an old but still supported distribution. Specifically, for reproducibility, it works against _exactly_ Ubuntu 12.04.5, without furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r updates. If you take all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 updates, you’ll get a new glibc, which changes some code offsets and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit will crash. The crash is of course deterministic and it would be possible to code cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit to cater for arbitrary glibc binaries; this is left as an exercise for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reader.

The vulnerability is in libgstnsf.so, an audio decoder present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer-0.10 distribution. Ubuntu 12.04 uses gstreamer-0.10 for all its audio handling needs. Ubuntu 14.04 is apparently affected because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default install includes gstreamer-0.10, but most media handling applications use gstreamer-1.0 which is also installed. The exact circumstances under which Ubuntu 14.04 uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerable gstreamer-0.10 are not clear. The Ubuntu 16.04 default install has only gstreamer-1.0, which is not affected by this vulnerability.

This exploit works against what I would consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “default” install. During Ubuntu install, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s a question along cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lines of “hey, do you want mp3s to work?” and of course cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct answer is “yes”. Various extra packages are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n installed including gstreamer0.10-plugins-bad. This package includes libgstnsf.so.

Wait, what, an 0day, with an exploit and all?
Yes, an 0day.
As a learning experiment, most of my bug disclosures going forward are going to be 0day. I’ve got a lot of experience participating in so-called “co-ordinated disclosure”, where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving vendor takes as long as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y wish to fix a vulnerability. (I once waited over a year(!) for Apple to fix a Safari vulnerability.) I’ve got significantly less experience with “full disclosure”, where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public receives details of a risk at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same time as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vendor. To be clear, I’m fairly certain that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct balance is a compromise somewhere between “full disclosure” and “co-ordinated disclosure”. The Project Zero 90-day deadlines appear to achieve this compromise nicely and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s a lot of data backing up cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 policy.

Don’t worry, this particular 0day is very minor, only affecting very old Linux distributions; see above. This 0day is more about fun than impact. Future 0days may be more widespread ;-)

Philosophical 0day question
Is it still an 0day if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 patch is released alongside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 0day? Here’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 patch for Ubuntu 12.04:
sudo rm /usr/lib/x86_64-linux-gnu/gstreamer-0.10/libgstnsf.so

While at first glance, this “patch” would appear to remove functionality, it does not. Your wonderful NSF files will still play. WTF? Would you believe that Ubuntu 12 and 14 ship not one but two different code bases for playing NSF files? That’s a lot of code for a very fringe format. The second NSF player is based on libgme and does not appear to have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerabilities of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first.

The attack surface
This exploit abuses a vulnerability in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer-0.10 plug-in for playing NSF music files. These music files are not like most ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r music files that your desktop can play. Typical music files are based on compressed samples and are decoded with a bunch of math. NSF music files, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hands, are played by actually emulating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NES CPU and sound hardware in real time. Is that cool or what? The gstreamer plug-in creates a virtual 6502 CPU hardware environment and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n plays cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 music by running a bit of 6502 code for a little while and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resulting values in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtualized sound hardware registers and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n rendering some sound samples based on that.

If you’re curious to play a real NSF file, feel free to download cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file: cv2.nsf. It’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 music from Castlevania 2, and you can find similar examples with a simple Google search for a term such as “nsf music files”. If your Linux desktop has support for NSF, you should be able to play it with something like: totem cv2.nsf. (Don’t be surprised if your distribution kindly offers to automagically install a suitable plug-in if one is missing.) It’s just 17264 bytes, which is tiny! Far too small to contain much in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way of samples, but large enough to contain some a small program which sequences requests for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 basic NES hardware to make some simple noises.

In order to actually exploit this vulnerability, or a vulnerability like it, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are various plausible and different avenues:

  • Send exploit via e-mail attachment. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim downloads and opens cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are compromised. Note -- for this to work, you likely need to rename exploit.nsf to exploit.mp3. Most Linux desktops don’t know what to do with an NSF file, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y’ll happily stuff any sequence of bytes in an MP3 file through a media player. Most gstreamer based media players will ignore a file’s suffix and use file format auto detection to load cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most appropriate decoder.
  • Partial drive-by download. By abusing Google Chrome’s somewhat risky file download UX, it’s possible to dump files to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim’s Downloads folder when a booby trapped web page is visited. When cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Downloads folder is later viewed in a file manager such as nautilus, an attempt is made to auto thumbnail files with known suffixes (so again, call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NSF exploit something.mp3). The exploit works against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 thumbnailer.
  • Full drive-by download. Again, abusing Google Chrome download UX, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s a path to a possible full drive-by download. This will be explored in a separate blog post.
  • USB drive based attack. Again, opening a USB drive opens up cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 thumbnailing attack described above.

6502 and NES ROM loading and paging crash course
The 6502 CPU is legendary, appearing in a diverse range of also legendary systems such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Nintendo Entertainment System, Commodore 64, BBC Micro, etc. It is 8-bit, but with 16-bit addressing, giving a 64kB address space. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NES application, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 upper 32kB of address space (0x8000 - 0xffff) is reserved for ROM, i.e. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read-only data on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cartridge you have stuffed in.

Here lies an interesting problem: what if you want to make a game larger than 32kB? Perhaps you have a game of 16 levels, each level having 16kB of unique graphics and music. No way that’s going to fit into 32kB. To solve this problem, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 concept of “banks” and “bank switching”. A bank is simply an aligned 4kB contiguous area of ROM, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are 8 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m packed between 6502 addresses 0x8000 - 0xfffff. Each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se banks can be mapped to a contiguous, aligned 4kB region inside a cartridge ROM that is potentially much larger than 32kB. At runtime, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 NES program can write to a special magic memory location (0x5ff8 - 0x5fff) that contains hardware registers that control what portion of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM is mapped to which bank.
Example: if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 CPU writes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value 10 to 0x5ff9, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 memory locations 0x9000 - 0x9fff will be backed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bytes at index (10 * 4096) into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cartridge ROM.

The vulnerabilit(ies)
1: Lack of checking ROM size when mapping into 6502 memory and bank switching
(Absent a CVE, you can uniquely identify this as CESA-2016-0001.)
There is a near total lack of bounds checking on proposed ROM mappings. This applies to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial ROM load, as well as subsequent ROM bank switching. All of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 handling for ROM mapping is in gst-plugins-bad/gst/nsf.c, including:

nsf_bankswitch (uint32 address, uint8 value)
{
 ...
 cpu_page = address & 0x0F;
 roffset = -(cur_nsf->load_addr & 0x0FFF) + ((int) value << 12);
 offset = cur_nsf->data + roffset;
 ...
 cur_nsf->cpu->mem_page[cpu_page] = offset;
 …

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above code snippet, cur_nsf->data points to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual ROM data content of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input music file. The format of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file is pretty simple: a 128 byte header (starting with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 4 character sequence “NESM”) and anything following is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM. So, for example, if you had a 200 byte input file, that would be 128 bytes of header and 72 bytes of ROM. The entire ROM is kept in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host emulator heap via a single malloc(). As can be seen, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer named offset is taken as an arbitrary offset into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM heap memory with no checking against any kind of length!

Let’s make this problem concrete: even in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simplest ROM load case of our 200 byte file, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual ROM load address will be 0x8000 and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 loading code will call nsf_bankswitch() for addresses 0x5ff8 - 0x5fff, with ascending bank indexes 0 - 7. This will result in 6502 virtual address 0x8000 being backed by nsf-> data + 0, 0x9000 backed by nsf->data + 4096, … all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way to 0xf000 backed by nsf->data + (7 * 4096). So even in this very simple example case, reading linearly in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 emulator from 0x8000 to 0xffff will result in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read of 72 bytes of real ROM data followed by 32696 bytes of out of bounds heap data!

But this is just an out of bounds read, because virtual addresses 0x8000 - 0xffff are read only in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 emulator. An OOB read is not particularly serious in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 context of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 emulator. It could be used as a useful tool to bypass ASLR, but any sensitive data read in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host heap can only be used to play sound. The emulator doesn’t have any advanced functionality such as e.g. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to egress heap data via network connections. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most serious case, if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 emulator were running as part of an internet server for music conversion, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker could render parts of OOB heap content as sound waves in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output file, to try and steal interesting data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server’s heap.

However, a second logic quirk of this particular emulator makes things more serious:

2: Ability to load or bank switch ROM to writable memory locations
(Probably not an actual vulnerability per se; no identified assigned.)
Ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r NES music players I’ve looked at do not permit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 loading or bank switching of ROM data at addresses below 0x8000. But this particular player does, eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r via a ROM load address in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file header that is below 0x8000, or via writes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bank registers 0x5ff6 or 0x5ff7 (ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r emulators do not even have bank registers as low as 0x5ff6 or 0x5ff7):

static nes6502_memwrite default_writehandler[] = {
 {0x0800, 0x1FFF, write_mirrored_ram},
 {0x4000, 0x4017, apu_write},
 {0x5FF6, 0x5FFF, nsf_bankswitch},
 {(uint32) - 1, (uint32) - 1, NULL}
};

Writing e.g. 0x00 to 0x5ff6 will result in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first 4096 bytes of ROM being mapped read and write at 6502 virtual address 0x6000. In our 200 byte file example, this means that a subsequent write of 0x41 to virutal address 0x6048 will result in 0x41 being written out of bounds relative to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host emulator heap.

As can be appreciated, we now have a lot of read and write control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host emulator heap and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more experienced exploit writers will realize that successful exploitation is already all but assured.

The exploit: overview
Here is an image of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit file inside okteta, a hex editor:

nsf_exploit_okteta.png

This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 full exploit and as you can see, it’s pleasingly compact at 416 bytes. The image has been decorated with three colored lines that show cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 different pieces of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit file:

  • Blue, for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 128 byte header. Much of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header is irrelevant and in fact, clever exploit techniques could conceivably compress some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 payload into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header. It would be a beautiful challenge to take this exploit and try and do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same in as few bytes as possible :) In terms of significant fields in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header:
    • 0x8000 (little endian, as are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 subsequent values) at offset 8. This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual ROM load address.
    • 0x8070 at offset 10. The virtual address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial 6502 routine that is called once.
    • 0x80a0 at offset 12. The virtual address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 per-frame 6502 routine.
    • 0x41a1 at offset 110. The frame timing. Needs to be left alone to ensure cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sound engine works.
  • Orange, for metadata, at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM image directly after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 header. This metadata is loaded at virtual address 0x8000 and is available and used in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 program. The metadata includes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 string “xcalc”, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eventual payload, a constant to search for in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap to make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit reliable, and a table of reads, additions and writes to perform on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main heap in order to progress cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit.
  • Green, for real 6502 opcodes -- yay! The exploit proceeds via a program written entirely in 6502 assembly. The music playing emulator will emulate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se opcodes, but break out of virtual 6502 address space into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host emulator main heap on account of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability details outlined above.

The exploit: details
So how does cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit work to reliably pop a calculator in so few bytes? The exploit is 416 bytes: 128 bytes of header and 288 bytes of ROM which are mapped at virtual 6502 address 0x8000. The ROM consists of a bunch of metadata followed by some 6502 opcodes.

In order to explore 6502 and “compile” 6502 assembly, this web page is a nice resource: Easy 6502. The page also makes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 claim “6502 is fun!” -- I concur. The reasonably commented 6502 assembly source for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 opcodes in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit is here: asm_final_main.asm. With a couple of tiny extra routines: asm_final_init.asm, asm_final_adder.asm.

The exploit proceeds as follows:
1: Locate important metadata object of type nes6502_context in main heap
Because of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability noted above, any read from 0x8120 - 0xffff will read out of bounds in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host heap, so we can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore read out of bounds until we locate bytes in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host heap that we believe correspond to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 nes6502_context object, which is defined like this:

typedef struct
{
  uint8 * mem_page[NES6502_NUMBANKS];  /* memory page pointers */
  ...
  nes6502_memread *read_handler;
  nes6502_memwrite *write_handler;
  int dma_cycles;
  uint32 pc_reg;
  uint8 a_reg, p_reg, x_reg, y_reg, s_reg;
  uint8 int_pending;
} nes6502_context;

Why are we keen to locate this particular object? For two reasons. Firstly, it controls how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 virtual memory accesses map to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host heap. By taking control of this mapping, we’ll get read and write access anywhere in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual memory of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host process. Secondly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object contains pointers into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS section. Locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS is important later in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit.

We identify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object in memory via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 byte sequence 00 00 00 00 00 50 00 00 00 00 00 00 ff 00 00 00 (which you can find in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit file at ROM offset 0), on a 16-byte alignment, which corresponds to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial values in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fields from dma_cycles to s_reg. (Due to a bug, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se initial values are never synced with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real current register values, so we can search for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m reliably.)

2: Remap cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 virtual read write address 0x6000 to point to nes6502_context::mem_page[6]
It would be remiss of me not to cite some beautiful 6502, so here’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code that writes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 magic hardware register to map 0x6000 to out of bounds ROM:
; Some fairly simple calculations and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n memory bank remapping.
; Match address is stored at 0x02, e.g.: 0x91b0
; Subtract 0x60 from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 match address.
; This indexes earlier into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real heap metadata object.
; It indexes to a real pointer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 backing heap for 6502 0x6xxx RAM.
; Subtract 0x8000 to get offset from ROM base.
LDA $02
SEC
SBC #$60
STA $02
LDA $03
SBC #$80
STA $03
; Now, 0x02 contains e.g. 0x1160
; Shift cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most significant byte to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM bank id.
; Each bank is 0x1000 in size.
LSR
LSR
LSR
LSR
; In this case, our bank id is 1.
; Write 1 to magic hardware register 0x5ff6.
; Causes 0x6xxx RAM to map to 0x1000 into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM.
; Which will be out of bounds relative to main host heap :-)
; Note that 0x6xxx is writable whereas 0x8xxx+ is not, so we need this.
; Offset e.g. 0x160 into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 0x6xxx space is a main heap pointer.
; This main heap pointer can be read/written from 6502 at e.g. 0x6160.
STA $5ff6
If you’re not familiar with 6502, hopefully you got an idea of some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simple elegance of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 opcodes. Perhaps you also noted some headaches:
  • There’s no instruction to bitshift by a variable amount. Hence, 4 LSR’s in a row (logical shift right) to effectively do what is >> 4 in C.
  • This really is an 8-bit processor, no 16-bit registers, so a simple 16-bit calculation has to be broken into two halves with careful management of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 carry flag! (SBC is SuBtract with Carry.)

Once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct ROM bank is mapped writable, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s a furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r normalization calculation which actually adds cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bank offset to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 raw host heap pointer nes6502_context::mem_page[6]. This is a very precise memory corruption and it takes effect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next frame. It ensures that 0x6000 points exactly to nes6502_context::mem_page[6] for all possible bank offsets that we might have located it at.

3: Start a series of read / add / write sequences, in a one-per-frame loop
With a normalized 6502 virtual address 0x6000 that points exactly to nes6502_context::mem_page[6], we’re in good shape to start reading and writing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 full host heap (and stack / BSS / whatever pointers we can find and follow or calculate!) with perfect accuracy, using 6502 opcodes. If we modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mem_page array, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 effect is not visible to 6502 memory accesses until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next frame, so we simply do one memory modification per frame.
The table used to drive cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read / add / write loop is located at ROM offset 0x20 and each entry is 8 bytes, e.g. cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first one:
50 60 08 60 60 6f ff ff
This means, read 8 bytes from virtual address 0x6050, add (sign extended, effectively a subtraction) 0xffff6f60 to that 8 byte value, and write it back to virtual address 0x6008.

4: Calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 libgstnsf.so BSS
We’re in luck: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of nes6502_context::read_handler, which now is readily available at virtual address 0x6050, is at a fixed value from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS because it points to an object in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS. We calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS and write it to virtual address 0x6008, which is nes6502_context::mem_page[7]. In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, we just mapped a readable and writable view of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS at virtual address 0x7000 in our little 6502 CPU.

5: Edit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memset() GOT entry
At offset 0xf8 into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GOT exists cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memset() function pointer. This is a pointer into glibc. It is now mapped at virtual address 0x70f8. Do you know what else is in glibc, at a fixed relative offset? system(). By adding a fixed value to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memset() GOT entry, we ensure future calls to memset() will in fact call system().

6: Map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual nes6502_context::read_handler object at 0x7000
Here’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read_handler definition; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read_handler pointer points to an array of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se:

typedef struct
{
  uint32 min_range, max_range;
  uint8 (*read_func)(uint32 address);
} nes6502_memread;

And here are some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entries that fill this array:

static nes6502_memread default_readhandler[] = {
 {0x0800, 0x1FFF, read_mirrored_ram},
 {0x4000, 0x4017, apu_read},
 {(uint32) - 1, (uint32) - 1, NULL}
};

As you can see, this object contains function pointers. Useful. Also useful are that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se function pointers are called in normal operation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 6502 memory accesses, when accesses to certain virtual addresses are made.

7: Change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apu_read() function pointer
By accessing virtual address 0x7018, we’re now (thanks to step 6 above) accessing index 0x18 into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read_handler BSS object. The apu_read() function pointer, called for reads of 0x4000 - 0x4017, is stored cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re. We add a little bit to this pointer (0x1d0) in order to in fact change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function pointer to apu_reset(). The reason will become apparent shortly!

8: Calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of BSS variable apu, again using a fixed relative offset from nes6502_context::read_handler
apu is defined thusly:

/* pointer to active APU */
static apu_t *apu;

We write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 calculated address such that virtual address 0x7000 points to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of apu.

9: Copy cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apu pointer into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory bank mappings so we can dereference into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apu object at virtual address 0x7000
Just chasing a level of pointer indirection here, because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BSS value is just a pointer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual object which is on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap.

10: Write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 string “xcalc” into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apu object
The apu object is quite large:

typedef struct apu_s
{
  rectangle_t rectangle[2];
  triangle_t triangle;
  noise_t noise;
  dmc_t dmc;
  uint8 enable_reg;

  apudata_t queue[APUQUEUE_SIZE];
  ...

By writing at 0x70f0, we write to offset 0xf0 into this object, which is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 queue buffer field. We write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 string “xcalc” here.

11: Read from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address 0x4000
… and a calculator appears! Black magic? No, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous steps set things up carefully to cause this to happen. Here’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sequence:
  1. 6502 reads from 0x4000.
  2. This is a special memory address that is supposed to call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 apu_read() function pointer to handle cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 access.
  3. Instead, apu_reset() is called because we corrupted cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function pointer earlier.
  4. apu_reset() contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code line: memset (&apu->queue, 0, APUQUEUE_SIZE * sizeof (apudata_t));
  5. But, we corrupted cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memset() GOT entry to point to system(), and we wrote cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 string “xcalc” to apu->queue.
  6. Ergo, system(“xcalc”) is executed, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 calculator appears.

Additional exploitation notes
This exploit works equally well when run in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following binaries:
  • totem
  • rhythmbox (works so well that two calcs are popped ;-)
  • gst-launch-0.10
  • nautilus (may launch a subprocess -- totem-video-thumbnailer?)

This is despite differing heap layouts. The code to scan cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 metadata object of interest, as opposed to relying on a fixed offset, is what provides most of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reliability. The astute reader will note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap scan runs only forwards and only for about 32kB. So what if heap jitter results in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 all important metadata object getting allocated before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM data? This is a definite possibility but does not appear to be a big bocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r in this instance. The NSF decoder runs in a fresh new thread, which in turn generally gets a new heap arena, resulting in decent determinism in heap layout. The metadata object is allocated temporally after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM data, so it will typically get placed after. That said, if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM data is made bigger, it can (deterministically, due to heap holes of deterministic size) end up after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 metadata object.

Our closing note on heap layout is that, if we needed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, we do have opportunities for heap grooming. Aside from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker controlled ROM size, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s also some variable length header strings (song title etc.) that get heap allocated. Finally, we note that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer code for format detection is very non-trivial and may offer furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r opportunities to control heap state.

What lessons can be learned?
While investigating this exploit, a number of hardening ideas came up. Also, a comparison of Ubuntu vs. Fedora -- even when extended to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latest releases -- reveals that Ubuntu is slipping behind Fedora for some exploit mitigations. In no particular order:

  • The attack surface of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux desktop does not appear to be under control, or adequately monitored for regression. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of Ubuntu, adding MP3 support also appears to add support for a huge number of obscure and largely unnecessary audio and video decoders. These contribute little to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desktop experience but greatly to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security risk. The relevant gstreamer extra plug-in packages even identify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 additional decoders as “bad” or “ugly” in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 package name. An effort to furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r split cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 decoders into “useful” ones vs. “obscure / risky” ones is recommended.
  • Initial signs show that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security quality of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gstreamer code is behind cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ffmpeg code. One of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reasons for this is likely to be j00ru’s / Google’s significant effort put into improving ffmpeg security: FFmpeg and a thousand fixes. Still, an important question for discussion is whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r gstreamer’s decoders should be replaced with an ffmpeg based backend.
  • Ubuntu is not nearly as thorough as Fedora in using ASLR on binaries. Comparing Ubuntu 16.04 vs. Fedora 24, we see that Fedora has ASLR on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 binaries for totem, rhythmbox and gst-launch-1.0. Ubuntu only has ASLR on totem.
  • Fedora appears to make good use of RELRO whereas Ubuntu does not. RELRO prevents messing with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function pointers in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GOT.
  • The level of sandboxing is disappointing across both Ubuntu and Fedora. Parsing media files in C has always been a hot spot for security and one mitigation is sandboxing. I don’t see much across Fedora or Ubuntu to use SELinux or AppArmor to meaningfully sandbox totem, rhythmbox, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 thumbnailing processes, etc. by default. There does appear to be interest, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 urgency does not seem to be high. One useful source: AppArmor Confinement. There’s also this Ubuntu bug to sandbox all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 thumbnailers, open since 2011: gnome thumbnailers should have an apparmor profile.
  • Changes in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux glibc heap management code have increased certain aspects of heap layout determinism, particularly for threaded programs. This is a topic for furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r exploration in a different blog post.
  • 6502 really is fun.

Closing notes
There’s a critical reason that decent, reliable exploitation was possible with this bug: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of some form of “scripting” language. In this case, that script happens to be 6502 opcodes. Having an exploit running in script enables important exploitation aspects, such as making decisions based on exploitation environment, and in particular, using code to observe cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 effects of a corruption (such as a memory leak) and make sensible follow-up decisions.

One of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reasons that browsers and browser plug-ins (Flash, Java) are popular exploitation targets is precisely because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are fundamentally scripting environments.

Anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r great example of this phenomena is Windows font parsing and rendering. This has traditionally occurred in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel(!!) and rending modern fonts involves…. yes, running a little language to make rendering decisions. Well, many times, attackers have used that same language to cause Windows kernel corruptions and proceed to full ring 0 compromise by using a script-inside-font to make decisions about reliably proceeding with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit.


So watch out for scripting in unexpected places!