The next article is an invitee spider web log post service from an external researcher (i.e. the writer is non a  or Google researcher). 
  This post service is nearly a Chrome OS exploit I reported to Chrome VRP inwards September. The  folks were overnice to allow me practice a invitee post service nearly it, thence hither goes. The written report includes a detailed writeup, thence this post service volition have got less detail.
 1 byte overflow inwards a DNS library
 In Apr I flora a TCP port listening on localhost inwards Chrome OS. It was an HTTP proxy built into shill, the Chrome OS network manager. The proxy has at nowadays been removed equally component of a fix, but its source tin withal last seen from an one-time revision: shill/http_proxy.cc. The code is uncomplicated together with doesn’t seem to comprise whatever obvious exploitable bugs, although it is real liberal inwards what it accepts equally incoming HTTP. It calls into the c-ares library for resolving DNS. There was a possible 1 byte overflow inwards c-ares piece edifice the DNS packet. Here is the vulnerable code, stripped heavily from its original to brand the põrnikas to a greater extent than visible:
  It parses dot-separated labels together with writes them into a buffer allocated yesteryear malloc(). Each label is prefixed yesteryear a length byte together with separating dots are omitted. The buffer length calculation is essentially merely a strlen(). Influenza A virus subtype H5N1 dot that follows a label accounts for the length byte. The in conclusion label may or may non terminate amongst a dot. If it doesn’t, together with then the buffer length is incremented inwards the initiative of all dark box to occupation organization human relationship for the length byte of the in conclusion label.
  Dots may last escaped though together with an escaped dot is component of a label instead of beingness a separator. If the in conclusion label ends amongst “\.”, an escaped dot, together with then the initiative of all dark box wrongly concludes that the length byte of the in conclusion label has already been accounted for. The buffer remains brusk yesteryear 1 byte together with the to the lowest degree pregnant byte of dnsclass overflows. The value of dnsclass is most ordinarily a constant 1.
 Exploit from JavaScript?
 Shill runs equally root. Influenza A virus subtype H5N1 straight exploit from JavaScript would accomplish inwards a unmarried stair what mightiness otherwise select three: renderer code execution -> browser code execution -> privesc to root. This agency less function together with fewer points of failure. It’s convenient that shill together with chrome are separate processes, thence if the exploit fails together with crashes shill, it doesn’t convey downward chrome together with shill is restarted automatically. The straight exploit turned out to last possible, but amongst difficulties.
  There doesn’t seem to last an obvious way to larn chrome to identify “\.” at the terminate of a Host header using HTTP. So instead the exploit uses the TURN protocol amongst WebRTC. It encodes what looks similar HTTP into the username land of TURN. TURN is a binary protocol together with it tin solely last used because HTTP parsing yesteryear the proxy is lax.
  Also, shill is listening on a random port. The exploit uses TURN again, to scan the localhost ports. It measures connexion fourth dimension to decide if a port was open. The scan besides runs into a surprising deportment explained nicely inwards here. If the source together with destination TCP ports of a localhost connexion endeavor occur to match, together with then the essence connects the socket to itself. Anything sent on a socket is received on the same socket. This causes faux positives, thence the scan must retry until a unmarried port remains.
  A to a greater extent than hard number is that in that location aren’t whatever decent retentivity preparation primitives. The proxy allocates the headers into a vector of strings. It applies minimal processing to the Via together with Host headers, forwards the headers to some other server together with frees the them. It accepts a unmarried customer at a time. The number of headers is express to <= 0x7f, header size is <= 0x800 bytes together with TURN package is <= 0x8000 bytes. The crude oil conception is to practice rooming over half-dozen connections or stages. The occupation is that unlike stages ask to reliably identify allocations at the same location. This is hard because the retentivity layout changes betwixt connections inwards ways that are hard to predict. The solution is to create what I telephone retrieve a persistent size 0x820 byte hole.
 820 hole
 First, it should last mentioned that shill uses dlmalloc, which is a best-fit allocator. malloc() uses the smallest gratis chunk that tin fit the request. free() coalesces whatever neighboring gratis chunks.
  Let’s expect at the pic of preparation at phase 1. This creates a persistent hole of 0x820 bytes:
  Red agency that the chunk is inwards role chunk together with light-green agency free. Cyan is the large overstep chunk of dlmalloc. The number on each chunk is the chunk size inwards hex. 0x is omitted. In the residual of this post, I’ll e'er refer to chunk sizes inwards hex, omitting 0x. Also, I’ll frequently refer to chunk sizes equally nouns, which is a brusk way of referring to the chunk amongst such size. I’ll omit the actual preparation primitives used for these allocations, but for those interested, the Host together with Via header processing inwards here is used.
  So the initiative of all pic shows how the 820 hole is created. Four chunks of size 410 are allocated from the overstep chunk inwards [0-3]. In [5,6], the initiative of all 410 is freed together with replaced amongst the backing allotment of the vector of headers. Even though the headers themselves are freed afterward phase 1 connexion closes, the backing allotment of the vector is persistent across connections. The 4th 410 is besides freed together with the buffer for incoming server information is placed into it. It is besides persistent across stages. Then the connexion closes, the 2 410 headers inwards the center are freed together with consolidated into 820.
  Why is this 820 hole useful? It is persistent because the previous together with next 410 are non freed betwixt stages. Each phase tin at nowadays start amongst the steps:
 - allocate the 820
- eat all gratis holes upwards to the overstep chunk yesteryear doing tons of minor allocations
- free the 820
 Let’s say a phase together with then allocates a minor chunk of 100. dlmalloc uses the smallest gratis chunk, which is the 820, because smaller ones were allocated. Now let’s say the phase finishes together with the 100 is freed. Next phase tin role the same algorithm to identify a 100 at the same location. This capability allows merely plenty preparation inwards phase 2 together with 3 to larn from 1 byte overwrite to overlapping chunks.
  But things could larn wrong. There mightiness last some other 820 hole yesteryear jeopardy together with unlike stages mightiness allocate a unlike 820. Or it could occur that the tons of minor allocations neglect to consume all holes, because the sum of retentivity allocated per connexion is limited. So the exploit attempts to larn rid of most of the gratis chunks before phase 1 yesteryear combining unlike techniques. An interesting 1 maybe is that it intentionally crashes shill. The procedure is restarted automatically together with starts amongst a build clean heap layout. It besides uses 2 techniques to allocate lots of memory—more than what’s allowed yesteryear the limits mentioned above. I won’t larn into details hither though.
 Overlapping chunks
 Stage 2 triggers the retentivity corruption together with phase 3 creates overlapping chunks:
  First, a 1e0 chunk is allocated inwards [10-12] yesteryear allocating 640, together with then 1e0 together with and then freeing 640. Then the inquiry buffer of ares is allocated into the 110 slot at [13]. This leaves a gratis 530 inwards the middle. Now is a proficient fourth dimension to select a closer expect at the dlmalloc chunk header declared here:
  This header is kept inwards front end of each chunk. The 3 to the lowest degree pregnant bits of the size land are used equally flags. Most importantly, lsb = 1 indicates that the previous chunk is inwards use. So looking at [13], the 530 chunk has size = 531 together with 1e0 chunk has prev_size = 530. The prev_size land is solely used when the previous chunk is free. Otherwise the previous chunk spans the prev_size field. This agency that the size land of 530 instantly follows the inquiry buffer inwards 110. The unmarried byte that overflows the inquiry buffer overwrites the to the lowest degree pregnant byte of the size land of 530: 0x31 -> 0x01. So the iii flags are non affected. But chunk size is corrupted from 530 to 500 equally tin last seen from [14].
  What’s interesting is that 1e0 doesn’t know anything nearly this corruption together with its prev_size remains 530. Now, [15-17] divide the gratis 500 into gratis 2e0 together with in-use 220. But dlmalloc is already confused at this point. When it tries to update the prev_size of the chunk next 220, it’s off yesteryear thirty bytes from 1e0. And 1e0 keeps on believing that prev_size = 530. It besides believes that the previous chunk is gratis fifty-fifty though 220 is in-use. So at nowadays inwards [18], 1e0 is freed. It tries to coalesce amongst a previous 530 chunk. There is a 2e0, where in that location used to last 530. dlmalloc is fine amongst that together with creates a large 710 chunk that overlaps the 220.
  These form of overlapping chunks are relatively slowly to exploit. They’re proficient both for breaking ASLR together with getting RCE. This technique for going from a unmarried byte overflow to overlapping chunks is non new. Chris Evans demonstrated it this  post. I’m non surely if anyone has demonstrated earlier.
  What’s non shown inwards the pic for simplicity is that [14-15] is the boundary betwixt phase 2 together with 3. The retentivity corruption of phase 2 occurs inwards DNS code afterward Via together with Host headers are processed, thence no farther preparation is possible. Stage 3 continues amongst preparation to larn overlapping chunks. But the 110 inquiry buffer is genuinely freed afterward phase 2. Stage 3 needs to reallocate a 110 chunk at the same location. The method described to a higher identify is used.
 ASLR
 Stage 4 breaks ASLR. It initiative of all turns the overlapping 220 into a to a greater extent than convenient 810 chunk:
  So it allocates the 820, which overwrites the header of 220 together with changes the size to 810. It’s interesting to banking concern complaint that the fd together with bk pointers inwards the header of 220 are besides overwritten. The exploit can’t afford to corrupt pointers at this dot because it hasn’t broken ASLR. But fd together with bk are solely used when the chunk is free—they are used for a doubly linked freelist. [21] frees the overwritten chunk together with dlmalloc finds it to last of size 810.
  Next, 2 gratis 2a0 chunks are crafted into the 810:
  So 2a0 is allocated, 2d0 is allocated together with 2a0 is freed. Now, the late mentioned fd together with bk pointers are leaked to interruption ASLR. The 2 2a0 chunks have got the same size together with are placed into the same freelist. With additional preparation at the initiative of all of phase 4, the exploit tin last surely that the 2 chunks are the solely ones inwards this freelist. Well, in that location is besides a 3rd chemical ingredient linked in—the freelist caput allocated statically from libc. So looking at the initiative of all 2a0, its fd together with bk dot to the other 2a0 together with into libc. Also, the initiative of all 2a0 overlaps amongst 820, which contains an HTTP header that is forwarded to an attacker-controlled HTTP proxy. So that leaks 2 pointers that the proxy server forwards to JavaScript. The 2 pointers are used to calculate the address of 820 together with the base of operations address of libc.
 To root
 ASLR defeated, stages v together with half-dozen larn code execution:
  The crude oil stance is to overwrite a BindState which holds callback information—a business office pointer together with arguments. The business office pointer is overwritten to dot to system() inwards libc, the base of operations address of which is known. And the initiative of all declaration is overwritten to dot to a musical rhythm out command string crafted into the 820 slot, the address of which is besides known. BindState chunk size is 40, thence now, 810 is resized to 40. First, [25] frees 2d0, which consolidates to 810. For the 810 chunk to last placed into the size xl freelist, it is removed from its electrical current freelist yesteryear allocating it inwards [27]. 810 size is overwritten to xl yesteryear freeing 820 inwards [26] together with reallocating it amongst novel information inwards [28]. [29] frees the resized xl together with [30] allocates a BindState into it. BindState at nowadays conveniently overlaps amongst 820. [31-32] reallocates 820 to corrupt the BindState to launch system(). The especial callback used triggers inwards thirty seconds together with system() runs a musical rhythm out command equally root.
 Persistence bug
 It may audio surprising, but an assailant that has gained root on Chrome OS volition lose the privileges afterward reboot. Chrome OS has verified boot. Bootloader inwards read-only retentivity verifies the kernel, which inwards plough verifies the hash of each disk block that it needs during runtime. This applies to the organization partitioning which contains all the executable binaries, libraries together with scripts. So an assailant can’t merely laid upwards a script to run at boot. But in that location is besides a stateful partitioning that tin last modified. It is intended for variable materials similar logs, configuration files together with caches.
  The way this exploit achieves persistence across reboots volition audio familiar to anyone who’s read nearly this exploit yesteryear geohot. Both role symlinks, dump_vpd_log together with modprobe. The dump_vpd_log script itself was fixed to non follow symlinks, but hither is a snippet from /etc/init/ui-collect-machine-info.conf:
  /var is a stateful partitioning thence UI_MACHINE_INFO_FILE tin last turned into an arbitrary symlink. dump_vpd_log --full --stdout writes /mnt/stateful_partition/unencrypted/cache/vpd/full-v2.txt to stdout. This tin last used to create an arbitrary file amongst arbitrary contents during boot. geohot used dump_vpd_log to write a command into /proc/sys/kernel/modprobe at kick thence a next modprobe would execute the command. But in that location are some extra problems when trying to reuse this approach.
  The initiative of all number is that /var/run is a symlink to /run, which is a tmpfs together with non persistent. The exploit makes /var/run persistent yesteryear relinking it to /var/real_run. Some parts of Chrome OS larn confused yesteryear that together with it is dealt amongst yesteryear using to a greater extent than symlinks. I’ll skip the details here.
 modprobe.d config file
 So at nowadays it’s possible to write into arbitrary files during boot. Another number is that writing into /proc/sys/kernel/modprobe amongst dump_vpd_log won’t function inwards this case, because the next udevadm writes into the same file together with its output can’t last controlled. The in conclusion write() syscall is what counts when writing into /proc/sys/kernel/modprobe. So instead, the exploit creates /run/modprobe.d, which is is a configuration file for modprobe. Parsing of modprobe.d is lax. Any trace starting amongst "install modulename command..." specifies a command to execute when that module is loaded. Any lines that neglect to parse are ignored.
 Late modprobe
 The terminal occupation is that ui-collect-machine-info.conf runs belatedly during boot, when all modprobing is complete. The created configuration file is non of much use. So the terminal fox is to honour a way to trigger modprobe belatedly during boot. The exploit creates a device file amongst mknod, which has a major number 173. 173 is unknown to the kernel, which agency that when something accesses the device file, together with then the essence volition endeavor to modprobe a handler module named char-major-173-0. Then it is sufficient to plough some ordinarily accessed file into a symlink to the device file together with each access to the file volition modprobe. The exploit uses /var/lib/metrics/uma-event.
  There is yet 1 to a greater extent than issue. Stateful partitions are mounted amongst the nodev flag, which blocks access to device files. So the device has to last moved to /dev during startup. This code inwards /etc/init/cryptohomed.conf is used for that:
  The device is created equally /mnt/stateful_partition/home/.shadow/attestation.epb together with /mnt/stateful_partition/unencrypted/preserve/attestation.epb is turned into a symlink to /dev/net. This moves the device to /dev/net. /dev/net is used instead of /dev because cryptohomed changes the possessor of the target attestation.epb. This would alter the possessor of the whole /dev directory together with drive chrome to crash.
  So that completes the Rube Goldberg machine of symlinks. dump_vpd_log creates /run/modprobe.d configuration file amongst a command to launch equally root. cryptohomed moves a device file to /dev/net. Any generated metric accesses the uma-event symlink to the device, which launches modprobe, which launches a command from modprobe.d.
 Patches
 By now, the issues have got been fixed pretty thoroughly. c-ares was patched inwards Chrome OS together with upstream. The HTTP proxy was removed from shill. TURN implementation was hardened to block JavaScript from sending an arbitrary username to a localhost TCP port. And the symlink issues were fixed here, here, here together with here.
Komentar
Posting Komentar