Remix.run Logo
simonw 8 hours ago

> In the hardest task I challenged GPT-5.2 it to figure out how to write a specified string to a specified path on disk, while the following protections were enabled: address space layout randomisation, non-executable memory, full RELRO, fine-grained CFI on the QuickJS binary, hardware-enforced shadow-stack, a seccomp sandbox to prevent shell execution, and a build of QuickJS where I had stripped all functionality in it for accessing the operating system and file system. To write a file you need to chain multiple function calls, but the shadow-stack prevents ROP and the sandbox prevents simply spawning a shell process to solve the problem. GPT-5.2 came up with a clever solution involving chaining 7 function calls through glibc’s exit handler mechanism.

Yikes.

cookiengineer 6 hours ago | parent | next [-]

> glibc's exit handler

> Yikes.

Yep.

arthurcolle 5 hours ago | parent [-]

Life, uh, finds a way

rvz 6 hours ago | parent | prev [-]

Tells you all you need to know around how extremely weak a C executable like QuickJS is for LLMs to exploit. (If you as an infosec researcher prompt them correctly to find and exploit vulnerabilities).

> Leak a libc Pointer via Use-After-Free. The exploit uses the vulnerability to leak a pointer to libc.

I doubt Rust would save you here unless the binary has very limited calls to libc, but would be much harder for a UaF to happen in Rust code.

pizlonator an hour ago | parent | next [-]

Yeah Fil-C to the rescue

(I’m not trying to be facetious or troll or whatever. Stuff like this is what motivated me to do it.)

cookiengineer 6 hours ago | parent | prev | next [-]

The reason I value Go so much is because you have a fat dependency free binary that's just a bunch of syscalls when you use CGO_ENABLED=0.

Combine that with a minimal docker container and you don't even need a shell or anything but the kernel in those images.

akoboldfrying 6 hours ago | parent [-]

Why would statically linking a library reduce the number of vulnerabilities in it?

AFAICT, static linking just means the set of vulnerabilities you get landed with won't change over time.

cookiengineer 5 hours ago | parent [-]

> Why would statically linking a library reduce the number of vulnerabilities in it?

I use pure go implementations only, and that implies that there's no statically linked C ABI in my binaries. That's what disabling CGO means.

akoboldfrying 4 hours ago | parent [-]

What I mean is: There will be bugs* in that pure Go implementation, and static linking means you're baking them in forever. Why is this preferable to dynamic linking?

* It's likely that C implementations will have bugs related to dynamic memory allocation that are absent from the Go implementation, because Go is GCed while C is not. But it would be very surprising if there were no bugs at all in the Go implementation.

tptacek 4 hours ago | parent [-]

They're prioritizing memory corruption vulnerabilities, is the point of going to extremes to ensure there's no compiled C in their binaries.

cookiengineer 24 minutes ago | parent | next [-]

It would be nice if there was something similar to the ebpf verifier, but for static C, so that loop mistakes, out of boundary mistakes and avoidable satisfiability problems are caught right in the compile step.

The reason I'm so avoidant to using C libraries at all cost is that the ecosystem doesn't prioritize maintenance or other forms of code quality in its distribution. If you have to go to great lengths of having e.g. header only libraries, then what's the point of using C99/C++ at all? Back when conan came out I had hopes for it, but meanwhile I gave up on the ecosystem.

Don't get me wrong, Rust is great for its use cases, too. I just chose the mutex hell as a personal preference over the wrapping hell.

underdeserver 30 minutes ago | parent | prev [-]

You can have memory corruption in pure Go code, too.

tptacek 27 minutes ago | parent | next [-]

Uh huh. That's where all the Go memory corruption vulnerabilities come from!

cookiengineer 23 minutes ago | parent | prev [-]

Nobody claimed otherwise. You're interacting with a kernel that invented its own programming language based on macros, after all, instead of relying on a compiler for that.

What could go wrong with this, right?

/s

tptacek 5 hours ago | parent | prev | next [-]

"C executables" are most of the frontier of exploit development, which is why this is a meaningful model problem.

0xDEAFBEAD an hour ago | parent [-]

Can we fight fire with fire, and use LLMs to rewrite all the C in Rust?

0xbadcafebee 5 minutes ago | parent [-]

[delayed]

vsgherzi an hour ago | parent | prev | next [-]

Wouldn’t the idea be to not have the uaf to begin with? I’d argue it saves you very much by making the uaf way harder to write. Forcing unsafe and such.

an hour ago | parent | prev [-]
[deleted]