Posted by oger 5 hours ago
I ask because I’ve been dabbling in rooting various closed devices at home. I’m finding AI fantastic at finding vulnerabilities statically (from firmware upgrade binaries), but when you then ask it to use it to get root or code execution it just goes in circles.
In the end it usually ends up there’s no exploit it can find, because it can’t actually influence the affected memory in a useful way. This is especially so if that memory is in the heap. On the stack it’s a lot more predictable (especially with OOB writes).
How do you know which pointer (as I say, especially if it’s in the heap)? And I know it can go wrong - but how do you do more than just crash the kernel?
In OOB writes in a stack variable it’s completely clear to me. For other situations I’d love to find real and clearly explained exploits of past UAF or OOB vulnerabilities.
The simplest thing you could try to do is allocate several more of the same type of object and hope one of them lands at the same memory address. For example if you can UAF a web app's user session and keep it open for a long time period (not true in the TCP bug), you might try to wait until an admin happens to log in with their session at the same address, then use their admin session.
Or you can allocate a lot of something else objects and hope a certain field overlaps, like a function pointer if you can write to it. Like suppose you can get some kind of authentication callback pointer to overlap where your packet sequence number was, maybe you can send a certain number of packets to make it point to the return instruction and skip the authentication.
For example, I remember an exploit workshop around reuse of passwd entries. The vulnerable would validate a passwd entry for a non-root user, use it a bit, and later on free and zero it out for security purposes... except it then looked at the passwd entry again in some conditions. Suddenly, the uid was non-zero at first, and zero later on, so later decisions assumed the user was root.
In a more concurrent situation, a possible vulnerability was a shared cache of these passwd entries. It wouldn't zero them out anymore, but you could create a race condition of starting requests as user A, and then hammering requests as user B, so you'd end up mixing up the permission contexts of these users. Because the passwd entry that had been released back to the pool was overwritten, and then re-read with the value from another context.
The necessary line of thinking tends to be very different from thinking about program code regularly.
At a high level, though: once you've gotten a new object allocated where the old one was, you now have two different views of the same bit of memory. You use valid operations on one view to put the other one into a corrupted state. For example: in a unixlike kernel, maybe one view has a field containing a function pointer (for method dispatch, essentially). You read that field using the other view, use it to deduce something about the target's memory layout, write a new value to the pointer, then use the field via the first view to cause execution to jump to a location you control.
the model spins because it cant test its own guesses. what fixed it for me was emulating the actual device. qemu with the vendor rootfs, real binaries running, and then every claim becomes checkable: did the daemon actually parse my input, which uid is it under, what does its own log say. once it can check things it stops guessing, getting qemu to actually boot the thing was its own little hell though, took more tries than i want to admit.
the other thing i learned the hard way: most static findings die on reachability, not on exploit primitives. so i run them in the emulator first and kill the unreachable ones cheap, before spending any time on heap work
on heap vs stack, i think that intuition is desktop shaped. device userland usually has weak or no mitigations, heap uafs are way more tractable there than youd expect
Good ideas on the QEMU. I guess you’d have to patch the binary if it’s expecting particular hardware etc?
Not sure what you mean by “desktop shaped”?
Can you give a concrete example of UAF on heap? I’m learning a bit on how this is done, and eventually recognised the LLM is doing something called heap spray. But that seemed to rely on hoping some object you wrote just happened to get interpreted by some process. And that was the “no, wait, pointer f isn’t y” loops.
This is wild. I'm a firmware nerd, not a backend nerd, what percentage of TCP/IP servers are 'multipath'?
Also, since IPv6 isn't affected, wouldn't it be funny if this is what it took to get everyone to switch.
no idea, but at least Tailscale and Caddy were opening MPTCP sockets on servers I checked.
Every Ubuntu version in the last decade is currently vulnerable.
https://ubuntu.com/security/CVE-2026-98432
Patches not yet available. That makes this a big deal.
This article says that this isn’t app level but is level and can be exploited before requests reach apps.
I was talking about the Anthropic blog post, only Go/Caddy enable multipath TCP listeners by default.
Why it's urgent: the bug sits in code every Linux server runs when it accepts an IPv4 TCP connection, before any application sees the connection.
It reads like it was LLM generated though so who knows. There is at least a simple mitigation for Golang apps if that is the only concern.
Anthropic only exploited multipath TCP, but the bug is deeper and also affects TCP connections, but it looks like this path is harder to exploit, and it's unclear if anybody managed to.
# CONFIG_MPTCP is not set
actual link: https://nvd.nist.gov/vuln/detail/cve-2026-98432
https://www.reddit.com/r/openwrt/comments/1xka85h/is_the_ope...
They say 25.12-SNAPSHOT has it fixed
If you have services open on the IPv4 net however, close them immediately as a precaution.
Multipath TCP is a neat trick that allows a single TCP connection (TCP = Transport Control Protocol, a stateless protocol for long running connections) to use multiple physical interfaces. You could do something similar before MTCP using bonding, but this was annoying to set up and usually required application level code to efficiently use the bonded connection. MTCP makes this much simpler from an application level point of view and it can use widely diverse underlying transport layers at the same time (for instance, WiFi, Cellular and wired connections).
It's an extension to TCP that, similar to QUIC, allows you to use multiple address/port pairs to transmit data over a single logical stream. Both client/initiator and server/listener have to opt into the extension. This might need to be enabled explicitly by the application[1], which Go apparently does for you, or judging from other posts may be enabled by default systemwide, depending on your platform.
AFAIU, a major user of MPTCP is Apple and the iPhone, and the ubiquity of iPhone clients motivated implementation in and deployment on Linux servers.
[1] https://docs.kernel.org/networking/mptcp.html#sockets-api