Copy Fail: an exploit for all Linux distributions since 2017
Posted by alexeyr@reddit | programming | View on Reddit | 94 comments
Posted by alexeyr@reddit | programming | View on Reddit | 94 comments
catch_dot_dot_dot@reddit
It's an ad for their AI product but it's also a legit bug. It has been patched in the latest kernel but they have a point that basically no distros use a patched kernel.
HighRelevancy@reddit
All published security vulnerability write-ups are advertising for something, even if it's just an individual building their portfolio.
Ythio@reddit
Well they found a way to get root on all versions since 4.14 they can their moment of spotlight, and even fail their advertising with a vibe coded website (that version of RHEL doesn't even exist), frankly I don't care. The problem is real and we want flaws to be found and patched
HighRelevancy@reddit
They've corrected the RHEL version number typo.
gimpwiz@reddit
All comments everywhere are advertising for something, even if it's just an individual wanting to have their ego stroked via upvotes on reddit. ;)
HighRelevancy@reddit
Aren't you very clever and smart and witty for that one.
You missed my point though. These write-ups take a lot of effort. Writing, editing, corporate approval processes, etc. It's substantially different to a comment.
HasFiveVowels@reddit
Guys, can we drop this "it’s just an ad for their AI" stuff? Like… I can’t imagine a way that they could have reported this without Reddit going "this is just an ad for AI slop!". It’s honestly just tedious at this point. AI exists. Not every story that involves it is an ad.
catch_dot_dot_dot@reddit
There is literally an ad for Xint Code at the bottom and it's mentioned a few times. They're not hiding it.
Inoffensive_Account@reddit
Debian fixed Trixie, just update.
wannaliveonmars@reddit
Nice and simple.
Swipecat@reddit
I've risked testing it on Ubuntu 24.04 LTS with its latest kernel update (6.8.0-110), and yes it works, straight to root.
jl2352@reddit
Awesome! Good to know next time I ssh into a box. \s
Nice_Ad8308@reddit
yea helps a lot.. much easier then typing `sudo -i`
frymaster@reddit
I've also tested it on SLES 15, RHEL 8 and RHEL 9
Nice_Ad8308@reddit
Hotest Ubuntu Server, 24.04 LTS is still not patched indeed
cpt-derp@reddit
In fact root is already achieved by line 7 in the PoC on a Pixel 9's Debian VM, which is arm64, and line 9 just inserts its own compressed amd64 su binary.
The-Bite_of_87@reddit
Not a problem for rolling release distro then
DualWieldMage@reddit
Why is the PoC obfuscated? Sure as heck i'm not running it to validate a patch if i can't even understand what it's doing first. Posing as a security bug(might be real, can't verify) is a good way to get unsuspecting users to run a random script on their machine, ticks the urgency and fear targets of a typical scam.
HighRelevancy@reddit
There's a chunk of binary shit in there but it's just a zlib compressed bigger chunk of binary shit. The purpose of the PoC is to insert patched binary code into a system, it's gonna have some binary shit in it. That's not obfuscation, that's just what it is.
Otherwise it's just minified so they can be like "wow look it's only 732 bytes". It's not really obfuscation any more than picking slightly shitty variable names is.
Neither of these are obfuscation.
Plus the write-up has enough detail that you could write your own PoC to at least replace the file header with a shell script that echoes LOLFUCK instead. It's not a terribly complex bug to exploit.
aanzeijar@reddit
import os as galias takes 5 byte and is then used 4 times later to save 4 byte. And you could simply alias bytes.hexfrom too.Whoever wrote this can't even golf properly. Can't take these people seriously.
HighRelevancy@reddit
I didn't say it was done well
frymaster@reddit
and later they alias
splicein order to use it exactly oncevalarauca14@reddit
Claude, Obfuscate this code. Make no mistakes.
iluvatar@reddit
Yes, it's obfuscation. They could have supplied the source to compile the binary. They could have written the script in a way that was obvious (and commented it so readers could see what it was intended to do). They chose not to. That's obfuscation.
HighRelevancy@reddit
There is a GitHub repo with the un-minified script and quite probably the build tool chain. I would expect any security people capable of building such a thing to also be capable of sticking the binary blob in a disassembler. Built code isn't obfuscation, you just haven't learned his to read it.
Yes, I'm aware that sounds like a slippery slope into "there's no such thing as obfuscation, you just lack the skill". It isn't. Machine code is the plaintext of that layer. If you work in that domain, there's absolutely no mysteries here.
Swipecat@reddit
It's a 64-bit ELF executable. See:
https://github.com/theori-io/copy-fail-CVE-2026-31431/issues/54#issuecomment-4351460190
case-o-nuts@reddit
BAHAHA, the assholes forgot to tell the distros that they'd need to ship a fix.
https://www.openwall.com/lists/oss-security/2026/04/30/10
DontBuyAwards@reddit
Not defending the reporters with their AI-generated website full of inaccuracies, but IMO upstream's processes are also to blame here. It would be reasonable to think that if you report a major security issue to a project that "takes security very seriously", they would make sure their users are aware of the fix when it's released. But the kernel places this responsibility on the reporter. Since 2024 they do assign CVEs, but this is a separate process that happens after the fact, and they have a policy of assigning a CVE "to any bugfix that they identify" which results in a lot of noise. Their solution to this is that distros should ship every release of the LTS series they're using, but most stable distros don't do so (this also requires the fix to be backported to those trees, which in this case didn't even happen until today). A more complete timeline of what happened is something like this:
lachlanhunt@reddit
I hada sense of relief when I a good thing my Synology NAS is still running a kernel version from 2013.
happyscrappy@reddit
The PoC fails on ARM (Raspberry Pi). This is presumably just because of the payload in the PoC, not the logic behind the exploit not working.
Pharisaeus@reddit
Their poc is literally patching su binary with a shellcode, so it's only going to work on architecture they wrote this for, unless someone puts effort into making a polyglot shellcode there.
happyscrappy@reddit
You can always call /usr/bin/cc. They just did it this way to be more flashy.
Pharisaeus@reddit
They did it this way to have payload with zero dependencies. They could have included their original assembly payload, but then they would have to assemble it, calling some external library or utility.
Only the most braindead ones ;) Especially in the LLM era, where you could just ask clanker to spit out shellcodes for different architectures.
happyscrappy@reddit
Yeah. That's what I said by being more flashy. It looks at first glance like it's pure python. It's flashy.
No. That'd be pretty ridiculous. I don't mean assembly. If you want to be cross platform you use C. They can put any program they want within reason in there. It could just be a C main, not assembly.
Pharisaeus@reddit
"Tell me you've never written an exploit without telling me". They're not overwriting the whole
suelf file, they are only patching a piece of the.textsegment with different machine code. Doing that via C would be tricky and painful - you'd have to compile it and then extract a piece of the machine code from that compiled binary, making sure you don't mess up offsets, and that the compiler didn't do some fancy optimizations that would break it (like making some unexpected jumps). It's waaaay easier to make a simple shellcode which invokes exec syscall with some/bin/shas argument. In fact I'm not even sure how you would invoke syscall fromCwithoutasmsection and without calling exec function (which you obviously can't do because you don't know the address). Your idea would only work if you overwritten the wholesubinary with a new elf file, but I'm not sure if that's even possible with the primitive they have, because it can't be used it to overwrite beginning of the file for example.happyscrappy@reddit
I didn't say anything about this.
Looks to me like they are starting at the start:
https://github.com/theori-io/copy-fail-CVE-2026-31431/issues/54#issuecomment-4351460190
You do have to look into patch_chunk but it appears that all it does is add 4. That is, this stuff is being written directly after the magic cookie at the start. Or possibly that 4 is an artifact of the cryptography socket they are using. I don't know.
It's not at all painful. I compile stand-alone code using C compilers for embedded systems all the time. Yes, it's a bit tricky. But this whole thing is tricky, isn't it?
Some of these options to cc might be enlightening. Or maybe not, this isn't quite all you need to do:
for compiling: -nostdinc -ffreestanding -static -fno-PIC
for linking, all those plus: -nostartfiles
There's more to it than this, you may need to get the results out of the ELF into just the binary code representation. That would require post-link processing. Again, not sexy to do so. Also, you'd still be ELF-only unless you start adding even more smarts about how to pick parts out of other compiled binaries. Luckily linux uses ELF (everywhere I think) in all the timeframe mentioned.
I didn't say anything about easy or difficult. Why, after talking about assembling are you now wanting to complain about difficulty?
I am.
UNIX is a bootstrappable system. Without writing special assembly to retarget. That requires the system be able to be constructed from C code (and a proper compiler).
Wrong. You don't know how to do this so you think it can't be done. Interesting. What happens if we apply the fact that 99% of us didn't know how to do this exploit in the first place? Does it then become impossible?
I don't think that would accomplish their goals. You don't get real uid 0 that way, only euid 0. Sure, there are ways to leverage that including one obvious one. But it's more stuff they have to put into their script, it wouldn't look as flashy or be as small.
I do expect that there is a potential limitation of one page they can write over. 4K or 16K depending on the architecture. Not because it's not possible to write over more, but because as is mentioned in the writeup the dirty flag is not set on the pages which are overwritten. So if those pages are paged out and back in they will be back to their old contents. So keeping the changes within one page really minimizes the chances of failure.
Not that I ever said they should write over all of /bin/sh. I never mentioned anything large.
I think given you don't know this stuff and I apparently do says maybe your choice of "tell me you've never written an exploit" was ill considered. Would you like to try this again with both of us not assuming we're the only one on here who knows what they are doing?
Pharisaeus@reddit
And on every compiler you get exactly the same binary? No. So you'd still have to parse the ELF file to find the
.textand then to find your "patch" to carve out. Not impossible, but significantly more complex than writing a handful of asm instructions.Because again: the whole reason they did this, was to avoid having a complex code with lots o dependencies. What they have in the PoC is very short piece of code that has no dependencies outside of standard python. What you're talking about is adding a C compiler to the mix and parsing an ELF file. The whole point was to make the PoC simple and straightforward, not to make a fully weaponized multi-arch exploitation toolkit. You've completely missed the point.
I was talking about assembling, simply because it would be slightly more "readable" for an average person if they had the assembly source for the shellcode instead of raw compiled shellcode (there were already people here complaining it's "obfuscated" because they don't understand what they're looking at), but that would add one more dependency to the PoC. I guess they could have posted 2 versions of the PoC, the "minimized one", and the "verbose one".
This only works if you statically compile the binary, so the definition of this function that invokes a syscall is included, and this means you have even bigger patch to apply. So instead of some 30-byte shellcode (seriously, you can make x64 exec /bin/sh shellcode in literally 10 asm instructions) you now have to transplant chunks of statically compiled libc. This reminds me of https://github.com/enterprisequalitycoding/fizzbuzzenterpriseedition Would it work? Probably. Does it make sense? No.
I can't, because you clearly have no idea what you're talking about. Have you ever written a memory corruption exploit? We both know you didn't, so this discussion is pointless. Go to https://pwn.college/ or https://pwnable.tw/ or https://pwnable.kr/ come back in 6 months and then we can have a discussion.
wndrbr3d@reddit
Uptime isn’t the flex it once was (if it ever was)
commandersaki@reddit
Turns out I have 122 days uptime and I'm unaffected since I upgraded my kernel many times during that period which wiped away the current running kernel's module directory so the module(s) that are affected cannot even load.
Ckarles@reddit
Not everything is inside Modules, the distros choose what is and what is not.
You're free to build it yourself and choose though, what goes into modules and what not, so up to anyone to maintain that if they wish so.
Salander27@reddit
While that is technically true most distros build almost everything they can as modules. There's almost no downside to doing so and it reduces memory usage by not having to load unused code. The only real exceptions are things that you need during init that may cause problems in certain fail cases (such as the fat32 driver used to mount the boot/efi partition).
frymaster@reddit
on RHEL, the vulnerable code is complied-in, rather than as a module, so that doesn't help (and neither do any mitigations around denying loading modules)
whatThePleb@reddit
Livepatching exists.
JeSuisAnhil@reddit
Doesn't
kexecreset the uptime counter?morphemass@reddit
Pretty severe since it impacts K8s too; this is the sort of day where I'm glad to not be responsible for dealing with the fallout of corporately mandated poor security practices. Beer in the sun instead.
Nyefan@reddit
It doesn't affect containers unless you're doing something exceedingly odd. The user needs to already be a sudoer for this to work, and every container I've ever seen in production either is running as root or running as an unprivileged user, so even if you managed to get shell access, you would either already be root or unable to use the exploit.
DaRadioman@reddit
Actually read the CVE man. It allows malicious code to hitchhike on privileged container invocations. So for example the malicious container can poison executable pages needed by kube-proxy, who then invokes it as a low level user.
Yes it impacts k8s, and no it doesn't require anyone to do anything too stupid.
Nyefan@reddit
I did. And I tested it in a sandbox cluster yesterday to figure out exactly which container and user privileges were required to escalate to the node. If you're running containers with non-root, non-sudoer users, it doesn't work (at least not on alpine, distroless, or ubuntu containers, which should cover most everyone). If you're running root containers, you could already nsenter into the host without this vulnerability. Ergo, no change from the status quo.
DaRadioman@reddit
Kube-proxy runs with elevated access. It doesn't matter what your user containers are running as.
Nyefan@reddit
And if you can get terminal access to kube-proxy, you can already elevate to the host, without this CVE. What new escalation path do you think this opens up in a normal cluster?
DaRadioman@reddit
It gives you that RCE.
It allows an unprivileged container an escalation path to do RCE as a privileged user. That's what I am saying. No terminal access, just an unprivileged container.
frymaster@reddit
they absolutely do not, I've tested the PoC code on many different operating systems.
That being said, I've not tried it from inside the container, so it's possible some of the other constraints that containers typically have prevent it from working
n0k0@reddit
This exploit works on wsl in windows, btw.
wannaliveonmars@reddit
So from what I understand from this video - https://www.youtube.com/watch?v=wQ914geKOcw, this works by doing cache poisoning on
su, right? So it loads thesetuidbinary in cache, opens a socket to it, does some splicing and pipes, and then uses some kernel crypto function that writes 4 bytes at a time.Then once su is executed, the kernel sees it's cached, but the cache has been "patched" (while the file on disk is not changed actually).
So is the bug that splicing tricks the kernel crypto function to treat read-only memory as read-write? Also, what is the fix?
CatWeekends@reddit
If I'm the only user on my servers, is there any reason to care about this?
slaymaker1907@reddit
It’s something that makes other exploits worse since code execution privileges elevate to root execution privileges.
FortuneIIIPick@reddit
It's local so the user would have to be someone you know already with a local non-privileged account.
ked913@reddit
Given how many exploits are being discovered with Claude and LLMs. I wonder what happens to the old and stable argument at this point.
You run something slightly old I suspect by EoY your version will be Swiss cheese with vulnerabilities.
Are all these issues and problems going to be backported and tested sufficiently?
nnomae@reddit
There are tens of thousands of CVEs every year even without LLMs. Even if LLMs were to double that figure it makes little practical difference. The AI companies are just taking advantage of the fact that most people have no idea how common vulnerabilities are, coupled with a press that will obligingly hype up anything AI to try and make AI seem scary.
ApertureNext@reddit
I think you underestimate how many vulnerabilities will be found by AI now that it can take a whole chunk of a codebase in context for its bug hunt.
nnomae@reddit
No I don't, going off Anthropic's Mythos report it cost them about $20k a bug to find them and the vast vast majority of them were not severe and in that case, as in this one, it required expert human supervision and guidance. The reality is it's not worth spending that amount to find bugs. It would be close to an order of magnitude cheaper on a cost to bug ratio to just hire humans to find the bugs and, unlike the humans, the AI models are getting more expensive.
Any company, for decades, could have found far more bugs by spending far less on human experts, but they don't because the reality is bugs aren't all that valuable, exploiting them will land you in prison, and, with the exception of nation state actors who already have more than enough talent to find whatever exploits they need, no one is going to spend that amount per bug.
Even if it gets down to $2k a bug, a 10x reduction in cost, and there were no other costs (remember Anthropic just quoted the token cost, not the cost of the experts they hired to use the AI), then very few companies would bother to spend it and even if they were going to spend the money there are way better things you could do with lets say $200k than blowing it on finding a random assortment of bugs, most of which will be minor.
Any competent developer could advertise a service where they find a bug in your software for $500 a pop and no one would hire them. Go to any open source repo and look at the issues list, you'll find hundreds of unfixed bugs sitting there, fully publicly disclosed because nobody has bothered to fix them yet.
Read this article, an experienced researcher came up with a novel approach for finding bugs and used AI as a tool to find instances of his novel weakness in large amounts of code. Without the human this bug never gets found, without the AI it just takes the researcher a bit longer which makes no difference because compared to the years of knowledge and experience and understanding it took to come up with the approach the few extra days spent finding it is a rounding error.
happyscrappy@reddit
Stable versions aren't as much as issue. Stable versions aren't unchanging, they just aren't using all the newest stuff. Stable versions should be patched with security fixes throughout their time of support.
Old versions are definitely boned.
There is a question as to if there is enough capability (manpower or LLM) to patch all the stable versions so many times and get them tested and out there. Let alone the updates actually being installed. But that last problem applies to "latest" versions too. They don't work if you don't install them.
sellyme@reddit
Not much.
Your point is certainly cogent right now as detection technology is rapidly improving, but any given piece of software has a finite number of bugs, so if they're being found at rapid pace you're eventually going to either find and patch them all, or (more likely) reach a stagnation of the detection technology such that the remaining really complex ones are no longer rapidly found.
In either case, version stability returns.
ApokatastasisPanton@reddit
This is assuming that:
in complex systems, patching non-trivial bugs is very likely to introduce new, possibly worse, bugs
ked913@reddit
Oh am not arguing the system is broken in a normal time. Just arguing that for this brief point in time a Pandora box of LLM scanning feels like running windows 98 in windows 7 era.
prone-to-drift@reddit
Time for strict firewalls and package management policies to keep foreign code out in the first place. You cannot exploit my linix box if you cannot reach it. Gotcha!
andrerav@reddit
So I guess exploits gets a shiny website now? Because reasons, surely.
ZuriPL@reddit
What, a person who found the exploit can't make a website?
andrerav@reddit
Of course they can. But the way it's done here has this weird instagram reality vibe to it.
"732 bytes. No race. Local root on every distro"
That reads like the tagline in an advertisement. It's dumb.
ourobor0s_@reddit
yeah it's all AI written. the number of long dashes in the first two paragraphs was enough to tip me off
ZuriPL@reddit
I mean, I'm pretty sure the website is vibecoded, or at the very least the content was AI-generated. So in that regard I agree, it looks bad.
But on the other hand, your comment sounded like you had an issue specifically with someone making a website for an exploit, not how this website specifically looked.
jykke@reddit
On every distro he tested, 6.19.12 in Fedora has the fix. But it sounds more scary to lie and say "every distro" instead of "many distros".
reddraggone9@reddit
That's just responsible disclosure. This wasn't published until the patch was out.
New-Anybody-6206@reddit
From a public service perspective I think it holds more weight that the issue is so bad it has its own website.
happyscrappy@reddit
It's been for a long time now, over a decade. It's been this way pretty much since heartbleed (2012/2014).
Marketing names and websites for exploits are de rigeur. Yeah, it's kind of dumb.
FuckOnion@reddit
This is the age of democratized programming. Claude probably whipped this up in 5 minutes, complete with the nonsensical copy.
headykruger@reddit
This one rides to the level of a bag named exploit. It gets a website
RenlyHoekster@reddit
This does not affect any RHEL 6, 7, 8, 9 systems. It only affects RHEL 10. See the Red Hat security listing. So it is false to state this CVE "affects all linux distributions since 2017".
Red-River-Sun-1089@reddit
I use Ububtu and according to their website their latest LTS release Ubuntu 26.04 is not susceptible to this vulnerability. https://ubuntu.com/security/CVE-2026-31431
So I upgraded to 26.04 manually today and verified it. Its correct. Running the Python exploit on 26.04 simply prompts for the sudo password and doesn't automatically log in as root.
iluvatar@reddit
Soooo... an obfuscated script that claims to give root access? I'm not going to be running that any time soon. I tried deobfuscating it, but ran out of patience and I just can't be bothered.
Pharisaeus@reddit
There is nothing obfuscated there, it's just a polyglot shellcode.
Crihexe@reddit
I was a bit concerned about the fate of my ctf platform with RCE challenges, so I had fun making this super size-(sl)optimized Linux x86_64 no-libc ELF build of the original Python PoC for research/reproduction purposes after (hopefully) having patched it.
Current size: 756 bytes on GCC 13.3.0 / Ubuntu 24.04.
Repo: https://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431
Crihexe@reddit
actually 745 rn!
RationalDialog@reddit
And who added the offending change(s)? Would be interesting to know. all that persons commits should undergo further scrutiny now...state actors something something.
saviourman@reddit
For every 1 vulnerability introduced by a malicious state actor there are 100 which are simply mistakes
SharkBaitDLS@reddit
The detailed blog post on it explains how it was introduced. It was a combination of 3 independent changes, each reasonable and logical optimizations in isolation, that ended up combining to produce the bug. Doesn’t look like malice.
Worth_Trust_3825@reddit
It was an optimization made back in 2017.
Snowpire@reddit
No fucking way.... I looked at the repo and it's just 10 lines of code...... Looks like Anthropic weren't kidding about Claude Code.
lamp-town-guy@reddit
It doesn't look like a frog.
Snowpire@reddit
It does on both my desktop and mobile. What operating system are you using? Can you explain what you see on screen?
lamp-town-guy@reddit
iOS app. It was completely garbled for some reason. Or I don't have enough imagination.
Jaded-Asparagus-2260@reddit
Have an upvote for your ASCII frog.
Snowpire@reddit
Thank you! I appreciate your support!
alexeyr@reddit (OP)
r/linux discussion: Copy Fail is a trivially exploitable logic bug in Linux, reachable on all major distros released in the last 9 years. A small, portable python script gets root on all platforms.