Show Notes

75 - Defcon Quals, Dead μops, BadAllocs, Wordpress XXE

Potentially a new named vulnerability class/set of vulns. Its integer overflows in the size calculations, specifically within the allocator code. I think that definitely makes them bugs, but we don’t really need a new name. In-fact “bad alloc” I think hides and makes it more difficult to talk about rather than just saying its bad calculations inside the allocator.

The gist of it is various allocators (largely in real-time OS and other constrained environments) might do a calculation to decide on how much memory to alloc. Think of something like calloc doing a multiplication of number of elements * size of each element, then not checking for an integer overflow. It is definitely a bug leading to an overflow but calling it “bad alloc” instead of talking about the vuln class itself I think is just obscuring the issue.

A new micro-arch, side-channel attack. This one is interesting because first it impacts both Intel and AMD and existing Spectre mitigations don’t apply.

Specifically its a timing side-channel in the micro-op cache. So what is the micro-op cache, basically every “macro-op” or the instructions you’d write in assembly get decoded into micro-operations. So each cycle the processor fetches some bytes, decodes them into their micro-op instructions. This is an expensive process so there is a micro-op cache that can be checked before doing the expensive decoding process.

Since its a cache, you’ve got the potential for a side-channel based on how quickly something is decoded, and because its in the actual instruction decoding pipeline, before instructions are actually executed something like LFENCE which controls and prevents speculation at the execution level happens too late in the process.

The paper itself goes into details about the replacement strategy within this cache and their own displacement attack against it to determine which micro-ops were recent executed, but the basic idea is that you can leak whether or not a secret dependent jump or branch was taken.

Intel does not appear to share the micro-op cache across hyperthreads but certain AMD processors do.

Brave when configuring its File Provider exposes all files form its public and private directory. This means an app could trigger a download a Brave’s cookie database by making a request to the content:// url for it and have it downloaded into the Downloads folder where any app could read it.

The author turns this into a remote vuln by taking advantage of the permission structure that allows a content:// file to load other content:// files. So an attacker generated page first triggers a download of their own malicious file, and then upon interaction triggers that file to be opened via its content:// url. That newly download page once opened can then use javascript to download other files like the cookie file and send it to the attacker.

Two stage attack to fully takeover a facebook account.

First stage leaks a read-only access token and is centered on a couple open-redirects in First is that when you access any page that requires a login, it will set a redirect_url cookie, then redirect you to /auth for the user to actually login. This cookie is also used by /facebook/auth which is where Facebook’s oauth flow would redirect back to.

There was also a more general open-redirect on the custom pages feature where a /hash/ would be used to redirect. THis hash could be crafted to redirect to an attacker page.

So the chain of the first attack is to trigger the redirect_url to be set to the attackers /CUSTOM_PAGE/e/x/x/HASH/ page. Then make a request to’s oauth endpoint with /facebook/auth as the redirect url (which is the proper target) and response_type=token. Once the victim logs in with facebook they’ll be redirected to /facebook/auth which redirects to the attackers /hash/ page, which redirects them to the attacker with the token in the url.

Stage two is upgrading this token. For this the author takes advantage of a “device login” feature which is meant to things like TVs which don’t have an easy input UI. Instead of entering your credentials you get prompted with a one-time code to enter. The page requests necessary to start this process are protected by CSRF tokens. Fortunately the previously obtained token can be used to read the CSRF token out of the graphql database. So they can fake the flow and obtain a full login.

This one is just a silly issue. On PHP versions under 8 libxml_disable_entity_loader(true) is called to disable external entities. This function is deprecated in PHP8 because remote entities are disabled by default. The problem is that when calling simplexml_load_string, a flag is passed in LIBXML_NOENT which means no entities should remain in the output so it will resolve and replace them. This mean it will turn on external entities.

Composer will query Packagist to obtain metadata about the package to download. This includes where to fetch the code from (both source and pre-build archives). Rather than implementing various version console software Composer calls out to the respective program. It does escape the URL to prevent any command injection vulnerabilities but it does not ensure the url is actually a url. Opening up these calls to argument injection. They found that hg (Mercurial) could be leveraged for code execution.

Some meme worthy vulnerabilities like unauthenticated root ADB access, don’t worry its not enabled by default. But the request to enable it doesn’t require authentication.

On :7777 luci_server is running, it has a custom binary protocol but there is a GETPASS command that doesn’t require authentication and can be used to retrieve the password.

The same service has various READ_ commands that can be used to read device config values without authentication. Including things like wifi pass.

Gatekeeper would misclassify certain types of applications allowing them to run without any restriction. Specifically you can cause a confusion in the policy engine regarding whether the app is bundled or not. You can trick it into thinking it’s not a bundled app when it is, which leads to it being misclassified and sets the allowed flag on the script.

Once allowed it can download a binary to /tmp to execute.

/proc/<pid>/syscall fills in a struct syscall_info using an architecture specific implementation. The structure has a u64[6] for argument registers to be put into. On a 32bit implementation(ARM and x86) this is cast down to a u32 and written to. Leaving only 24 of the 48bytes initialized. When the data is printed a %llx format specifier is used which prints 8bytes; leaking some kernel data.

Two vulnerabilities, both in ConnMann a root service for managing network connections, a stack-based overflow and a stack leak. First was a stack-based overflow in uncompressing DNS records. First it would copy the uncompressed resource record, type, class and a null byte to a tmp buffer. Increment the pointers, then copy the fixed portion (10bytes) and increment the pointers. The problem was that while it would do a bounds check on the variable size content, it wouldn’t bounds check the fixed size copy. Leading to a linear overflow.

There was also another more subtle bug in how it would calculate the pointer increments. Namely the strncpy would be called with the remaining buffer size for maxlen, but the pointer increment would just be the strlen without regard for the buffer size. Allowing an attacker to increment over the canary and not overwrite it. Which I thought was a cool trick, not really widely applicable but still a fun trick.

The second issue was a stack leak, in a central listener for DHCP packets the packet buffer is allocated on the stack but not zeroed. SO if you end a packet with an option code but no option data it’ll read an uninitialized stack area. They were conveniently able to read both stack addresses to know where the stack was and return addresses from library function calls to know where libraries were located. Where there was some randomization, the spacing between libraries was not randomized.

Base issue is that when handling a file upload (two locations do this) the buffer is allocated based on Content-Length, but the memcpy is based on the actual payload length. Creating a heap overflow.

Exploitation is where things get a bit more interesting. They do a fd (forward) pointer overwrite on fastbin. Idea being you overwrite that pointer so that when you free, first it’ll give you the corrupted block, and then it’ll set that fd pointer as the head of the fastbin, and give you that as a next block.

However this won’t work in the original location because it always does a free before the alloc taking over the head of the fastbin. The second location for it, /genierestore.cgi could work except it triggers a malloc(0x1000) beforehand which triggers a malloc_consolidate which properly frees all the fastbins. So they first do a targeted overwrite of the heaps max_fast value.

This happens because the malloc_state structure has the max_fast value immediately preceding the fastbin array. When assigning a new block into the fastbin it’ll call fastbin_index(size) to get the index to the fastbin to write to. If you corrupt the size though it’ll return -1, writing to fastbins[-1] which happens to be max_fast.

Once overwritten they can use the genierestore.cgi page and target the fastbin fd pointer, overwrite it and get a chunk pointing to the GOT entry for system.

Two vulnerabilities and a good deal of background. Vulns happen in the UEFI Request hypercalls. Passes a struct with pieces of the request (op to perform, data pointers, sizes). First vuln is a host-kernel heap overflow as the “name” size is trusted but copied into a fixed sized buffer.

Second vuln, is a TOCTOU. The datasize is written to shared memory and then validated before returning. On a Write request (SetVariaible) the VMM validates this size, on a Read request its delegated to the user-side, if the user-side returns status=0 then the data size is fetched (double fetch) again and used to copy data to the guest. Race this between one thread doing a large write, and QueryVariableInfo which does a 24byte read. Racing for Query to do a big return.