4 ms·
1) IFUNC is hardly the only way to run code before main. 2) The alternative they present is arguably less secure because the function pointer will remain writa
by wahern 5mo ago
1) IFUNC is hardly the only way to run code before main.
2) The alternative they present is arguably less secure because the function pointer will remain writable for the life of the process, whereas with IFUNC the GOT will eventually be made immutable (or can be... not sure if that's the default behavior). In general function pointers aren't great for security unless you explicitly make the memory backing the pointer(s) unwritable, which at least is easier to do for a global table than it is for things like C++ vtables (because there's the extra indirection through data pointers involved to get to the table).
- ajross 5mo agoYeah, this blog is misguided. As a higher level criticism: it's confusing[1] the technical details with the payload with the exploit chain that deployed it. The interesting thing is obviously not that you can get code to run at high privilege level by modifying a system component. I mean, duh, as it were. The interesting thing is that the attackers (almost) got downstream Linux distros to suck down and deploy that malicious component for them. And that's not down to an oddball glibc feature, it happened because they got some human beings to trust a malicious actor. GNU glibc can't patch that! [1] Incorrectly, as you point out.
- ordu 5mo ago> The alternative they present is arguably less secure because the function pointer will remain writable for the life of the process The article mentions this, and also points to mprotect which you can use to protect the pointer. Why people jump to criticize without reading first? BTW, you can ask an LLM to check your critique, before posting, if you don't want to read the text.
- IAmLiterallyAB 5mo agoYes but at best their "solution" is equally secure, not any better.
- kstrauser 5mo agoWould xz still have been able to alter opensshd without IFUNC?
- rwmj 5mo agoYes, liblzma could have used multiple routes to take over sshd. Once you're running inside the process it's game over. The exact details, like how they used ifunc and an audit hook, are very interesting, but ultimately not that important.
- robertdfrench 5mo agoI've updated the post and am offering $500 if you can pull this attack off without ifunc.
- rwmj 5mo ago$500 isn't worth my time and I don't trust you'd pay up. But for anyone who wants to attempt to get him to pay up, here are three simple approaches: (A1) In a POSIX constructor function in liblzma, set an alarm(2) for a few seconds later (once sshd has fully loaded). (A2) In the alarm callback locate the original function that was patched using dlfcn, and mmap a page of modified code over the top that calls the exploit. Or: (B1) POSIX constructor function, call clone(2) to start a background thread. (B2) In the background thread, sleep for a little, then patch the code as in A2 above. Or: (C1) POSIX constructor function that completely replaces the sshd process with a workalike that contains the exploit. In A & B, for OSes (not Linux) that deny mmap, you'll need to find a struct or stack frame used by the function and work out how to adjust the data it uses or find a function pointer and exploit that.
- robertdfrench 5mo agoYou may well be right about this! What I genuinely don't understand then, is why Jia Tan relied on ifunc rather than POSIX constructors. Seems like that would have been easier and more widely applicable, right?
- dwattttt 5mo ago> The alternative they present is arguably less secure because the function pointer will remain writable for the life of the process They also suggest an alternative to storing the function pointer, store the bit flags that decide which function to call. That restricts the call targets to only the legitimate ones intended.