Monday, October 20, 2008

Some Python bugs

A little late on this report, but here are some Python runtime bugs I found back in May 2007:

Nothing too interesting. It continues to illustrate that modules backed by native code are a great way to break out of a VM. Also, image manipulation code remains a hot spot for integer overflows.

The pickle bug is worth talking about. It has been known for trusted applications to unpickle untrusted data. Of course, any such application invites arbitrary Python code execution unless the pickled buffer is very carefully sanitized; Python pickle buffers can carry Python executable payloads. Assuming an application avoids this more egregious security bug, this is a nasty subtlety. Along with the string concatenation bug, it's a way an attacker could directly attack a trusted application written in an allegedly memory-safe language.

Whilst testing out the pickle bug, I was seeing a very interesting glibc interaction:

*** glibc detected *** ./python: munmap_chunk(): invalid pointer: 0x0819e9a8
Segmentation fault

Unfortunately, my laptop with the magic glibc / gcc versions to reproduce this died horribly and I can't even remember what it was running. Anyway, these messages suggest that the glibc memory error handler is trusting the heap rather than "getting the hell out" by using write(stderr, ...) and kill(getpid(), SIGABRT). This can sometimes turn an unexploitable condition into an exploitable one. If you're interested in looking into this, let me know and I can try and help with the test environment.

1 comment:

jnf said...

I have to admit I was really happy to see people both from Google and Apple kinda run with the concept, which was more of what I wanted to do honestly.

On a side note, I believe (going from memory) the error messages printed out by malloc.c et al on failure use constant strings and stack memory for the most part-- it goes into __libc_message() which is pretty involved and I won't say is safe because I've never followed it back down, but from what I recall there were a lot of alloca() calls and such, so in theory, assuming that is consistent, theres no usage of heap memory during fatal errors.