LTMEAT

Literally The Meatiest Exploit of All Time

Hello sysadmins! My Reddit account is bigminecraftgamer 💀 love you guys

Dedicated to ULTRABLUE, a fellow Mercury Workshop member who I wish I'd gotten to know more.

This writeup was published on May 2nd, 2023, noon UTC.

The night I found LTBEEF, 231 days ago, I was hyped. I shared it, went to sleep, and woke up to dozens of pings. Disable an admin extension so easily? It was unheard of. It spread across the internet, got sysadmins in a scramble, and took an absurdly long time to get patched. Everything a good exploit should do.

I thought LTBEEF was as easy as it got. I thought Chrome had gotten too secure to have any more simple exploits. I was wrong.

I want to keep reading Just give me the new exploit

Introduction

LTBEEF truly disabled extensions. Unsurprisingly, it's really hard to fully disable an extension when you aren't supposed to be able to. Admin-installed extensions can only be disabled by other admin-installed extensions or components that use the chrome.management API. The Chrome Web Store had this permission and was treated like a normal webpage, which was the weakest link that LTBEEF took advantage of. There was also a variation for Inspect Element users which involved directly running code on a long-forgotten component extension. So truly disabling extensions is really hard.

In fact, LTMEAT (the new exploit I found) doesn't fully disable extensions.

Well, what else can you do? one may ask. If the extension isn't disabled, that means it's running, right?

To answer that question, we have to get into Chrome's process management, extension runtime, internal debug URLs, and more. Let's get started.

Hanging and killing (kid-friendly material, trust me)

JavaScript is cool. The web runs on JavaScript, in case you weren't aware. That means, of course, that Chrome does too. The people working over at Google HQ (yuck, California) and other web browser devs have to worry about limiting JavaScript. For example, what do you do when a website uses too much of it?

Well, browsers like Chrome don't want to lag out the entire browser and definitely not its user's whole computer, so they give each tab a certain amount of memory. When it's working at full blast, the browser will hang the site. This means that the page will become unresponsive as it waits for the JavaScript to finish. You can try this yourself by running an infinite loop on any page:

for(;;)1

Chrome also limits tabs in terms of actual memory used. Once JavaScript starts using more memory than Chrome can afford, the tab will be killed. It's not loading, there's no chance of it being responsive again--it's just dead. This kind of behavior can also be triggered by a crash, which is self-explanatory and has a similar effect. You can see this for yourself by running code to create an Array with 4,294,967,295 elements in it, as seen below. Talk about overkill! (pun intended)

[...Array(2**32-1)]

To recap, hanging is when a tab freezes and becomes unresponsive because it's actively running intense JavaScript. Killing is when a tab is crashed because the browser decides that it's using far too much memory.

Diseases and handshakes

Time for a thinking activity (that sounds Orwellian, lol). Imagine every tab on your computer as a person. These people (tabs) are all at a party or some other public gathering.

Normally, tabs are completely seperated. But when a tab opens a tab with its same domain, those two tabs share memory. We can imagine this by imagining two people at the party shaking hands. When one of them gets sick, the other also gets sick. When one gets electrocuted, the other also gets electrocuted, and so on. You can simulate this by running the following code on a page...

open(location.href)

...then using the hang or kill codes (scroll up) on either page. When it crashes or freezes, the other tab will be taken with it. This is because they're shaking hands, or in technical terms, because they are using the same memory process in Chrome.

So why does any of this matter? you may wonder. Why do I need to know so much about how Chrome freezes its tabs?

Finally, it's time to get to the point of the exploit.

The deadly group hug

This exploit stops extensions (including admin-enforced ones such as web filters) from working until a Chromebook is restarted. But to understand how, we need to talk about a little quirk in the tab party situation.

Chrome Extensions are made of a group of files. So what? Chrome sees these files as tabs, and it runs of them in the same process, sharing memory. This can be imagined as a group hug. When one person is electrocuted, they all are. When one tab crashes, the whole extension crashes.

Ah, exclaims the average Joe. I get the point. You're going to kill one of the extension tabs. Then the extension will go away. I'm so smart!

Come on, Google isn't that stupid. When an admin extension crashes, it recovers within three seconds or so. There's no good way to automate crashing it, and it just lags your computer insanely hard when you try. Plus, we want a semi-permanent exploit.

Oh, he says. Then we just hang it. I see it now! You hang one, and the rest of the files don't run any scripts.

Yeah, that's 100% correct. When you hang an extension page, the whole extension stops functioning. But there is an issue. Web filter extensions like GoGuardian and Securly work by using the chrome.webRequest API, where they add listeners to every request you send.

This means that your browser waits for those extensions to respond before it loads any website. Since the extensions are hanging, they can't respond. And you can't load any websites.

While trying to fix this issue, I accidentally stumbled upon a way to basically stop the extension's entire runtime until a restart.

Before I get into this, I'd like to re-state my absolute astonishment that Chrome still has bugs like this in 2023, and that nobody else has noticed them. This should have been discovered and patched in 2018 or 2019 at the latest.

Chrome error in your favor! Collect $200.

Three Chrome "features" put together make this exploit insanely convenient.

FEATURE ONE: There is a small gap between when an extension starts loading and its pages start initializing. So, in theory, if you managed to restart an extension and instantly hang it, none of its pages would load, meaning none of its listeners would load. Then Chrome wouldn't try to communicate with it and you could actually browse with web filter extensions disabled.

FEATURE TWO: An extension's background page (_generated_background_page.html) ties everything together and is loaded first. If you hang an extension page before the background page has loaded, all the other parts of the extension won't be able to load either.

And in fact, this means you can even close the tab you messed with (at the top), since the background tab stays frozen and keeps the whole extension broken.

For Manifest V3 extensions, though, you'll want to keep the tampered page open. But MV3 is extremely rare in managed environments because nobody cares about what Google thinks anymore (W).

That's great! But how do I hang an extension? I don't have Inspect Element allowed on my Chromebook.

"FEATURE" THREE: There are literally built-in ways to hang and kill any page. No joke.

chrome://kill and chrome://hang can be entered into the URL bar of any website. Chrome literally does not care whether you're running them on managed extensions. Either they neglected it or assumed that it wouldn't cause any damage. I literally do not know what the software engineers are doing at their headquarters.

ChromeOS has supported enterprise enrollment for six years, and stuff like this is still being found.

Anyway, exploit time! Aren't you glad you read all that extra stuff I had to say?

The meaty stuff (instructions)

Alternate Method #1 (easier)

The method linked above involves less spamming. It doesn't work for all extensions, but it should work for your filter. However, it's also easier to block. The original instructions are shown below.

STEP ONE: Find a page belonging to the extension you want to disable. You'll need your extension's 32-character ID to continue. If you're trying to bypass stuff, try finding it in a filter extension ID list. For further help, check the help section.

Once you have the ID, you'll be guaranteed to get to a working chrome-extension:// page by visiting the manifest file: (with your extension's ID substituted in, of course)

chrome-extension://extension_id_here_please/manifest.json

Some extensions' pages are much easier to access directly (like their options or block pages). All that's important is that you open a page belonging to the extension you want to disable.

STEP TWO: Bookmark the extension page (bookmark A) if you wish. Then, bookmark chrome://kill (B) and chrome://hang (C).

STEP THREE: While on the extension page (A), click the chrome://kill bookmark (B). The page should crash. You should already have the next step prepared.

STEP FOUR: Instantly start spamming chrome://hang (bookmark C) and quickly reload the page while spamming using the refresh key on your keyboard (or less ideally, ctrl+R). You should have reloaded within one or two seconds of killing the page.

A timeline of the exploit can be seen below:

If you are unable to visit the extension page (bookmark A) after trying the exploit, then LTMEAT worked! Please read the help section if you had an issue (for example, if no sites seem to load). You can restore extensions by signing out and back into your Chromebook.

Note that the steps above are by no means the only way to perform the exploit. I'll add the first alternate set of instructions on May 11th for people affected by patches.

Send me money

"Help me! I'm an idiot!"

Turns out that I had far too much faith in society when making this page. Some of you skids out there are really, really stupid and also can't read. So here are the answers to some commonly asked questions.

How do I get an extension ID?

Okay, fair. Extension IDs are leaked in a couple of places. Generally, the best way to get them is to go to extension settings and copy the URL query value as shown in the video below:

If you're actually competent in dealing with JSON, you can easily find IDs in chrome://extensions-internals too, as well as another similar URL.

It says blocked by client?

That's the message you get when you try to visit an a page belonging to an extension that doesn't exist. The error message (ERR_BLOCKED_BY_CLIENT) is extremely misleading. Nobody blocked it--you just need to find the right extension ID (see above).

If you got this because you tried to visit the extension_id_here_please example URL, you should be extremely ashamed of yourself. Please change and grow as a person.

I don't have a bookmarks bar!!!!

First, try running ctrl+shift+B. If that doesn't work, go to chrome://settings and turn on the "home button" feature, then set it to chrome://hang. A home icon should show up to the right of your refresh icon in the top left. Use that instead of bookmark C.

If that doesn't work, try the first alternate method. It should work for most web filters, but I can't guarantee that it can disable every extension. I'll try to add more alternate methods soon.

I disabled an extension but now I can't load websites!

If you actually just read the writeup, you'd know that this would happen if the extension's background page loaded and its listeners were already initialized before you used chrome://hang.

Anyway, no listeners means you were too slow. Either you waited more than three seconds between bookmark B and reloading the page, or you weren't spamming bookmark C fast enough. The most reliable fix for this is to just restart your computer and try again. Try to match the pace of the gif below: (note the reload)

Note how the name of the extension doesn't show in the URL bar after the start, because I didn't let the extension (and thus its listeners) load between bookmarks B and C. Again, the timeline is a good visualization of this.

The bookmarks don't do anything when I click them!

Might be admin-blocked. Either be smart enough to figure out another way, or check this site daily to see if new alternate instructions have been posted.

I disabled the extension, why is some stuff still blocked?

I have bad news for you... not all filters are Chrome Extensions. And again, make sure the extension pages (like bookmark A) are frozen before you assume that your skiddy self successfully did the exploit.

Need more help? Go annoy the people in Titanium Network.

Contact me

Bypassi#7037

contact@bypassi.com

I'm happy to answer questions, whether you're a sysadmin, student, or Chrome dev.