Memory locking behavior issues

This is nothing new, and it’s strictly what the POSIX specification warns about mlock() & munlock(). As you may already know, mlock() locks memory to prevent it from being swapped to disk (for example, if you require cryptographic secrets such as encryption keys to be memory resident during system stress, preventing resilience on disk and other media). munlock() does exactly the opposite: it unlocks memory.

The problem is that both functions don’t necessarily work in the same manner across different implementations. The address parameter to both might be required to be page-aligned (rounded up to the size of a memory page, for example 4096 bytes in x86).

What happens if we supply a non-page aligned memory address? If the implementation rounds up by default, we will be either locking a whole page or unlocking it, if we use mlock() or munlock() respectively. That means all the memory contents within the same page will be affected. This might not be an issue during locking, but when you are unlocking, it’s a different situation… we might expose data that was supposed to remain locked and compromise other secrets.

Continue reading →

Security decisions from the past: to cache or not to cache

We haven’t been abducted, yet. While working on an interesting research project, we found something about Apple’s Kernel Authorization framework that might be a bit odd. From their documentation:

When writing a vnode scope listener, be aware that not every file system operation will trigger an authorization request. For example, if an actor successfully requests KAUTH_VNODE_SEARCH on a directory, the system may cache that result and grant future requests without invoking your listener for each one.

Albeit we haven’t verified this any further, it’s at very least interesting. Does that mean that a security decision might be cached and applied again under potentially circumstances? Huh. It’s true that a vnode scope listener can be one hell of a performance black-hole, but race conditions due to cached decisions is worse than slowing down file system operations, especially if the module overrides other policies.

QA Hell: Quicktime again!

Even if time for keeping this blog updated is becoming rather scarce, we couldn’t resist publishing a note about Quicktime again. It was on the news some time ago, due to another simple, classical stack buffer overflow flaw. It was related with RTSP interfaces again.

Our exploit pack already provides a reliable exploit against this and other recent flaws, and there’s no real exploit for this flaw publicly available (in terms of quality and reliability). It’s quite possible that so-called drive-by malware installation kits are making use of this flaw to infect unsuspecting users.

We expected Apple to perform some due diligence with Quicktime’s QA, since the last real 1990 style flaws have been all related to RTSP functionality, but looks like they are still missing some guidance. Hopefully it won’t take long for them to realize that something like SDL could significantly improve their product security.

Our last public (Apple Mac OS X) exploit of the year: mount_smbfs

We are happy to announce the availability of a 100% reliable exploit against CVE-2007-3876, the mount_smbfs argument stack-based buffer overflow. Using the shared_region_map_file_np() system call, we map a file containing shellcode at a fixed location, with write, read and execute permissions (VM_PROT_EXECUTE|VM_PROT_READ|VM_PROT_WRITE). This technique was first documented publicly in a Phrack article by nemo, and has been partially restricted in Leopard.
On an unpatched Mac OS X 10.4 installation (only without the update fixing this problem) it will allow any user to gain root privileges.

$ ./mount_smbfs_root
Mac OS X 10.4.10, 10.4.11 mount_smbfs Local Root exploit
Copyright (c) 2007-2008 Subreption LLC. All rights reserved.
Mapping shellcode from file via shared_region_map_file_np()...
Shellcode mapped: mapping starts at 0x9ffff000, shellcode at 9fffff71
Payload size: 1064 (1040 padding bytes), Return address: 0x9fffff71
mount_smbfs: workgroup name 'AAAA...'
malcomx:/Users/nonpriv root# id
uid=0(root) gid=501(nonpriv) groups=501(nonpriv), 81(appserveradm), 79(appserverusr), 80(admin)
malcomx:/Users/nonpriv root# exit
exit

It is available at our corporate public repository, as well as the Milw0rm website.

Starting January 2008, our focus will be set on the development and polishing of a commercial exploit code and penetration-testing toolset, comprising several reliable exploits and tools to aid security professionals in penetration-tests, IDS and HIPS developers, as well as serving as an educational resource on exploit techniques, IDS evasion and general information security for the Mac OS X, Solaris, Linux and Microsoft Windows platforms, from a strictly technical perspective.

We are interested on partnerships with prospective security vendors and especially companies with strong focus on research and a consistent record of developing innovative, technically complex security work. For more information, you can contact us at Our sales email address. We will carefully examine all offers on a case-by-case basis.

Exploits of 1990: mount_smbfs brings it on

Initial development of the mount_smbfs local root exploitWho doesn’t remember those old root setuid binaries with argument parsing stack buffer overflows, the days when sudo had trivially exploitable vulnerabilities and system administrators panicked at the sight of any setuid binary after a some advisory showed up on BUGTRAQ. Apple had its share of bad luck with one of the latest Security Updates for Mac OS X. But it’s 2007, approaching 2008 already, not 1997!

Apparently, a regression was introduced into Tiger via one of the updates (in previous audits we didn’t find this binary to be affected by this vulnerability), and made the mount_smbfs root-setuid binary vulnerable to a trivially exploitable stack-based buffer overflow, which allows (root) privilege escalation for any user on the system.

The condition triggers when an overly long string is passed as parameter to the -W (workgroup name) option. Depending on how many registers you require, the padding size is approximately 1040+16 bytes for x86, to overwrite eip.

One of the requirements to abuse this issue properly is doing a setuid(0) call, in order to make the root privileges effective. There are different possibilities to successfully exploit this issue:

  • Control eax, return to setuid(), with saved eip pointing at system() and argument set to shell of choice (ie. use the SHELL environment variable value).
  • Find a stable or almost stable location for your shellcode on dynamically allocated memory (in this case, heap memory). This might be tricky for this specific issue, since we are calling a command line tool that does very little use of malloc().
    • You might notice some data replication in a MALLOC_LARGE section… it could be in Unicode format.
    • Play with sending large arguments to the command line, any changes?
  • As we explained in previous posts, on PowerPC you don’t need to worry about bypassing NX stack: the stack is executable by default. It can’t be easier.

Apple definitely needs to deploy some sort of Secure Development Lifecycle. Not because it was popularized by Microsoft, not because we want a cheap shot at Apple, but because it simply works. And we don’t agree with some security practices at Microsoft as well (namely the ASLR of Vista; while it’s more solid than Leopard’s, it’s still not enough for many real world scenarios — for in-depth documentation on the ASLR concept, read its PaX project documentation).

Don’t call it SDL. Make it the “Apple Secure Development iLifecycle”. But please, security updates also need to be tested against a regression test suite! We really enjoy using iWorks 2008 but we don’t like vulnerable root-setuid binaries.

Other weaknesses of the Mac OS X firewall

After taking a look over the Mac OS X firewall (which has been criticized by several people already), we’ve detected several weaknesses (which could be considered design flaws, although abusing them is technically feasible and uncomplicated):

Mac OS X firewall allowing connections through different script interpreters

  1. There’s no protection against process-level threats: code injection and subverting processes already trusted by the firewall are completely possible.
    1. There has been research in other platforms about the implications of injecting code in the context of a trusted process to bypass the firewall (see Advanced Windows Firewall Subversion, also Phrack 62: Using Process Infection to Bypass Windows Software Firewalls).
      1. Mac OS X has several interfaces allowing process interaction at low-level.
      2. Ability to load code dynamically is present for all processes in the system.
      3. Apparently, runtime code manipulation wasn’t contemplated by Apple as a potential security issue.
        1. No integrity checks done, signing a binary image is not enough if it can be tampered on memory later!
  2. It works on communication direction basis: inbound, outbound. No way to control what happens in a fine-grained manner.
    1. The Ruby, Python or Perl interpreters bind a socket to listen for connections, and you allow it through the firewall. What’s wrong with that?
      1. Metasploit includes PHP payloads: remote access with the privileges of the user running the interpreter.
      2. Any script will be able to perform network operations within the limits of the firewall configuration: by default, allow incoming connections.
        1. In other words, an attacker will be able to trivially bypass the firewall using a script interpreter like Ruby.

We are working towards developing a proof of concept demonstrating these issues (and other nice tricks) in technical detail; until that happens, stay tuned and enjoy the Christmas holidays :)