Identifying Rust's collect::<Vec<_>>() memory leak footgun
This is the story of how I identified the bug. (TLDR: collect::<Vec<_>>() will sometimes reuse allocations, resulting in Vecs with large excess capacity, even when the length is exactly known in advance, so you need to call shrink_to_fit if you want to free the extra memory.)
Ordinarily, that wouldn’t have been a problem, since the into_iter().map().collect() line used to pack them into (u32, u32)s would allocate a new vector with only the exact amount of space required. However, thanks to the allocation reuse optimization added in Rust 1.76, the new vec shared the backing store of the input vec, and hence had a capacity of 16560, meaning it was using 132480 bytes of memory to store only 16 bytes of data.
npm search RCE? - Escape Sequence Injection
In a previous post I went over a vulnerability I discovered in iTerm2 that allowed code execution in the shell by leveraging the output of a command. Today, We’ll focus on the other side of that interaction, the application running underneath the terminal.
Running the “Reflections on Trusting Trust” Compiler
In October 1983, 40 years ago this week, Ken Thompson chose supply chain security as the topic for his Turing award lecture, although the specific term wasn’t used back then. (The field of computer science was still young and small enough that the ACM conference where Ken spoke was the “Annual Conference on Computers.”) Ken’s lecture was later published in Communications of the ACM under the title “Reflections on Trusting Trust.” It is a classic paper, and a short one (3 pages); if you haven’t read it yet, you should. This post will still be here when you get back.
In the lecture, Ken explains in three steps how to modify a C compiler binary to insert a backdoor when compiling the “login” program, leaving no trace in the source code. In this post, we will run the backdoored compiler using Ken’s actual code. But first, a brief summary of the important parts of the lecture.
Investigating why Steam started picking a random font
And you know what’s special about 2040? It’s after 2038.
"[31m"?! ANSI Terminal security in 2023 and finding 10 CVEs
This paper reflects work done in late 2022 and 2023 to audit for vulnerabilities in terminal emulators, with a focus on open source software. The results of this work were 10 CVEs against terminal emulators that could result in Remote Code Execution (RCE), in addition various other bugs and hardening opportunities were found. The exact context and severity of these vulnerabilities varied, but some form of code execution was found to be possible on several common terminal emulators across the main client platforms of today.
WebGPU Security Technical Report
In this document we outline how WebGPU works through the mind of an attacker, our vulnerability research methodologies, and our thought processes in some of the more difficult research areas. There are many interesting portions of Chrome graphics that we omitted from review to keep scope manageable. While our primary focus was WebGPU, we did explore a few attack surfaces shared by other graphics features. We will interleave background information on WebGPU with descriptions of the important bugs we found. We hope this report will give the security community a deeper understanding of the shape of vulnerabilities we may come to expect with the addition of WebGPU, along with a lens into the vulnerabilities we might encounter in the future.
Add extra stuff to a "standard" encoding? Sure, why not.
Hold on. protobufs do not work that way! They don’t have their own framing. That’s why recordio was invented, and countless other ways to bundle them up so you know what type they are, how long they are, and all of that other stuff. The actual binary encoding of the protobuf itself is bare bones! So what’s up with this length byte?
CVE-2023-38408: Remote Code Execution in OpenSSH's forwarded ssh-agent
While browsing through ssh-agent’s source code, we noticed that a remote attacker, who has access to the remote server where Alice’s ssh-agent is forwarded to, can load (dlopen()) and immediately unload (dlclose()) any shared library in /usr/lib on Alice’s workstation (via her forwarded ssh-agent, if it is compiled with ENABLE_PKCS11, which is the default).
Surprisingly, by chaining four common side effects of shared libraries from official distribution packages, we were able to transform this very limited primitive (the dlopen() and dlclose() of shared libraries from /usr/lib) into a reliable, one-shot remote code execution in ssh-agent (despite ASLR, PIE, and NX). Our best proofs of concept so far exploit default installations of Ubuntu Desktop plus three extra packages from Ubuntu’s “universe” repository. We believe that even better results can be achieved (i.e., some operating systems might be exploitable in their default installation):
Culture eats policy
There’s a convenient punching bag for many of these failures: outdated government technology, and outdated approaches to tech by the bureaucracy. But try to fix that through policy change and you’ll find it’s turtles all the way down. The levers leaders use to fix tech are the same ones they use to steer the economy, improve government-funded healthcare, manage immigration, and even strengthen our national defense. We increase budgets, cut budgets, make new rules, and hold hearings, but the tools we use to fix our tools aren’t working either.
The people on this project knew quite well that using this ESB was a terrible idea. They’d have been relieved to just throw it out, plug in the simple protocol, and move on. But they couldn’t. It was a requirement in their contract. The contracting officers had required it because a policy document called the Air Force Enterprise Architecture had required it. The Air Force Enterprise Architecture required it because the Department of Defense Enterprise Architecture required it. And the DoD Enterprise Architecture required it because the Federal Enterprise Architecture, written by the Chief Information Officers Council, convened by the White House at the request of Congress, had required it. Was it really possible that this project was delayed indefinitely, racking up cost overruns in the billions, because Congress has ordered the executive branch to specify something as small and technical as an ESB?
Jack beat them all, winning the contest and demonstrating not only his enormous skills in securing critical national security systems, but an incredible enthusiasm for serving his country. He was a dream candidate, and the Defense Digital Service (DDS), the team that had sponsored the Hack the Pentagon contest, encouraged Jack to apply for a job. But the resume Jack submitted described his experience developing “mobile applications in IonicJS, mobile applications using Angular, and APIs using Node.js, MongoDB, npm, Express gulp, and Babel”. This would have given a technical manager a good sense of the range of his skills, but no one technical reviewed his resume. DoD’s hiring protocols, like those of most agencies, required that it be reviewed by an HR staffer with a background in government hiring rules, not technology. The staffer saw what looked like a grab bag of gobbledygook and tried to match it to the job description, which required “experience that demonstrated accomplishment of computer-project assignments that required a wide range of knowledge of computer requirements and techniques pertinent to the position to be filled.” The fact that he’d just beat out 600 other security researchers meant nothing. His resume was deemed “not minimally qualified” and didn’t make the first cut.
acme.sh runs arbitrary commands from a remote server
Now it became immediately obvious to my why HiCA only supports acme.sh. They are not conforming to ACME at all! (Bugs the heck outa me that they’re using the official ACME logo on their site even though they don’t implement the ACME standard.)
Instead, HiCA is stealthily crafting curl commands and piping the output to bash. acme.sh is (being tricked into?) running arbitrary code from a remote server.
Memoirs from the old web: The KEYGEN element
The purpose of the <keygen/> element was to allow a web browser to generate a private/public keypair upon submitting a form, in a way that allowed a web browser to be enrolled in a new client certificate.
The Most Dangerous Codec in the World: Finding and Exploiting Vulnerabilities in H.264 Decoders
Modern video encoding standards such as H.264 are a marvel of hidden complexity. But with hidden complexity comes hidden security risk. Decoding video in practice means interacting with dedicated hardware accelerators and the proprietary, privileged software components used to drive them. The video decoder ecosystem is obscure, opaque, diverse, highly privileged, largely untested, and highly exposed—a dangerous combination.
We introduce and evaluate H26FORGE, domain-specific infrastructure for analyzing, generating, and manipulating syntactically correct but semantically spec-non-compliant video files. Using H26FORGE, we uncover insecurity in depth across the video decoder ecosystem, including kernel memory corruption bugs in iOS, memory corruption bugs in Firefox and VLC for Windows, and video accelerator and application processor kernel memory bugs in multiple Android devices.
The Quest for Netflix on Asahi Linux
Thus begins the “do not violate the DMCA challenge 2023”. The goal of this challenge is to figure out how to watch Netflix on Asahi Linux without bypassing or otherwise breaking DRM. You may notice that this article is significantly longer than my 280-character publication on doing the latter, from 2019.
We’re on the home stretch now, right? Right??? Not quite, there is one last showstopper for Asahi users, and it’s a big one: Asahi Linux is built to use 16K page sizes. The Widevine blobs available to us only support 4K pages.
An instruction oddity in the ppc64 (PowerPC 64-bit) architecture
As Raymond Chen notes, ‘or rd, ra, ra’ has the effect of ‘move ra to rd’. Moving a register to itself is a NOP, but several Power versions (the Go code’s comment says Power8, 9, and 10) overload this particular version of a NOP (and some others) to signal that the priority of your hardware thread should be changed by the CPU; in the specific case of ‘or r1, r1, r1’ it drops you to low priority. That leaves us with the mystery of why such an instruction would be used by a compiler, instead of the official NOP (per Raymond Chen, this is ‘or r0, r0, 0’).
As covered in the specific ppc64 diff in the change that introduced this issue, Go wanted to artificially mark a particular runtime function this way (see CL 425396 and Go issue #54332 for more). To do this it needed to touch the stack pointer in a harmless way, which would trigger the toolchain’s weirdness detector. On ppc64, the stack pointer is in r1. So the obvious and natural thing to do is to move r1 to itself, which encodes as ‘or r1, r1, r1’, and which then triggers this special architectural behavior of lowering the priority of that hardware thread. Oops.
The curious tale of a fake Carrier.app
Six privilege escalation exploits are bundled with this app. Five are well-known, publicly available N-day exploits for older iOS versions. The sixth is not like those others at all. This blog post is the story of the last exploit and the month-long journey to understand it.
Porting Zelda Classic to the Web
I spent the last two months (roughly ~150 hours) porting Zelda Classic to run in a web browser.
I hope my efforts result in Zelda Classic reaching a larger audience. It’s been challenging work, far outside my comfort zone of web development, and I’ve learned a lot about WebAssembly, CMake and multithreading. Along the way, I discovered bugs across multiple projects and did due diligence in fixing (or just reporting) them when I could, and even proposed a change to the HTML spec.
Weird how there’s bugs everywhere one looks.
A Tale Of A Trailing Dot
Trailing dots on host names in URLs is the gift that keeps on giving. Let me take you through a dwindling story of how the dot is handled differently in different places through the stack of an Internet client. The evil trailing dot.
What goes into an X resource and its name
Most people who deal with X resources, me included, generally deal with them at a relatively superficial level. At this level, you can say that X resources are a text based key/value database, with the name (key) of every resource being a composite name that specifies both its program and some program specific name (although there are conventions for the name portion). But if you start to look at the actual names for X resources, things start looking a little more odd.
Into the rabbit hole.
One of the problems with X resources is that they’re arcane and hard to manage.
An unexpected Redis sandbox escape affecting only Debian, Ubuntu, and other derivatives
This post describes how I broke the Redis sandbox, but only for Debian and Debian-derived Linux distributions. Upstream Redis is not affected. That makes it a Debian vulnerability, not a Redis one. The culprit, if you will, is dynamic linking, but there will be more on that later.
The perils of the “real” client IP
The state of getting the “real client IP” using X-Forwarded-For and other HTTP headers is terrible. It’s done incorrectly, inconsistently, and the result is used inappropriately. This leads to security vulnerabilities in a variety of projects, and will certainly lead to more in the future.