Mac OS X Buffer Overflow Found
MacDork writes "Well, if default settings in Mac OS X made Lance Ulanoff excited, this is really going to make him do the monkey boy dance... SecurityFocus's Bugtraq mailing list just posted a buffer overflow, in the utility for mounting and probing ISO 9660 file systems. No exploits were mentioned. No word on whether 'Max' alerted Apple or anyone outside of the Bugtraq mailing list though." Also, 'Max' made entirely unfounded, sweeping statements about the general quality of Mac OS X from this one little item, but oh well. When you're on top, you make a tempting target.
I have Jag (10.2.8) and was able to do it as a non-admin user.
The command line was just a demonstration of the vulnerability, not exploit code. All it was supposed to do was segfault. The attached gdb output shows that the 'A's overwrote one of the return addresses on the stack frame. That means it might be possible to jump to an arbitrary memory address and execute code, as root I might add.
I have Mac OS X 10.2.8 (Jaguar) and I wasn't able to reproduce the behaviour described in Max's security post. It *does* throw a segmentation fault, but nothing happens afterwards. Neither it writes a core dump file, nor does it give any root privileges. Did someone with an older system try that? I can't find any confirmations that the issue exists. Thanks.
you have to realize that Apple has no experience when it comes to the world of Unix security.
They weren't great, but then who was back in the day.
Next were developing their unix since 1988, and Apple merged with them in 1998. Apple's current CTO is formerly of Next
A/UX, Apple's unix, ran on M68030 Macs in 1989
AIX, IBM's unix, ran on the PPC604 Newtork Servers in 1996
MK/Linux, Apple's Mach/Linux hybrid, ran on PPC Macs in 1996
MacOSX server has been going since 1999.
Well, BeOS doesn't run on any G3/G4/G5. Only original PowerMacs (601/603/603e/604/604e).
OSX only runs on NewWorld G3s and newer, so pretty much BeOS wouldn't be a threat, there. ;)
Linux on the other hand........
...spike
Ewwwwww, coconut...
The error lies in the cd9660.util_main.m file from the isoutil package, specifically, right in the start of the main function:
/* Build our device name (full path), should end up with something like: */
/* /dev/disk1s2 */
if ( (myError = DoVerifyArgs( argc, argv, &mnt_flag )) != 0 )
goto AllDone;
strcpy( &myDeviceName[0], DEVICE_PREFIX );
strcat( &myDeviceName[0], argv[2] );
The strcat function fails with the huge devicename. DoVerifyArgs should check the length of argv[2] to be under 255 characters, but it only checks if it is longer than 2 characters:
/* Make sure device (argv[2]) is something reasonable */
myDeviceLength = strlen( argv[2] );
if ( myDeviceLength < 2 )
{
goto ExitThisRoutine;
}
I'll make a quick fix and test it.
Maybe we deserve this world ?
Get the fix with source code here, just double-click the install.sh script, it will make, copy and setuid the file at the correct location. Somebody please test and review this !
Maybe we deserve this world ?
Apple will just post a fix for it in Jan. if they've been already told about it. They have new OS update coming this week so it could include a fix for this issue as well if it's an easy fix.
The change is in the DoVerifyArgs function, from:
// Added check for lengths of myDeviceName over 255 chars; 16/12/2003 Namu
myDeviceLength = strlen( argv[2] );
if ( myDeviceLength < 2 )
{
goto ExitThisRoutine;
}
to:
myDeviceLength = strlen( argv[2] );
if (( myDeviceLength < 2 ) || (myDeviceLength > 255))
{
goto ExitThisRoutine;
}
The tar.gz archive is just the same as the one from OpenDarwin, except for the fix in the code and the install.sh shell script that makes the utility, installs it under sudo, setuid's it and then cleans.
Maybe we deserve this world ?
Well, Mac machines ARE slightly harder since their instructions are aligned. You need to hit the alignment and the offset.
Is is different from the x86 variable-length world. There are 3 possible alignments.
In this scenario, it doesn't matter though, since it's a non-service.
Slashdot. It's Not For Common Sense
Way to go, Apple. (Actually, this probably dates back to NeXT.)
--
"Open source is good." - Steve Jobs
"Open source is evil." - Microsoft
This type of attack is nothing new, and this vulnerability may be an indication that security isn't being taken seriously.
Or possibly that these developers are delving into a new area where they don't have all the answers yet. I expect that there will be many more security issues found - it's the nature of the game when building something new or something old in a new way. It happens; you fix it and move on.
Or you take the Max alternative - burn your bridges and execute any developer and his/her family and friends as they try to escape.
To celebrate the occasion of my 1000th post, I will post no more forever on Slashdot. Goodbye.
The point is privilege escalation. If there's a hole in one of your services (as there are, from time to time), it won't hurt you too much if, say, an intruder is roaming around as an unprivileged user, such as www or nobody. If they can exploit a setuid binary to give themselves a backdoor, change accounts, basically do anything root can, then that's a hell of a lot worse.
Security comes in layers. I want as many layers as possible.
- Oliver
The right to bear arms is only slightly less stupid than the right to arm bears...
argv[2] gets strcat-ted with DEVICE_PREFIX:
// Added check for lengths of myDeviceName over 255 chars; 16/12/2003 Namu
DEVICE_PREFIX = "/dev/"
strcpy( &myDeviceName[0], DEVICE_PREFIX );
strcat( &myDeviceName[0], argv[2] );
and myDeviceName is declared as a 0..255 array.
So the right check should be:
myDeviceLength > 250
Even worse, there's the following code after the strcpy-strcat couple:
strcpy( &myRawDeviceName[0], RAW_DEVICE_PREFIX );
strcat( &myRawDeviceName[0], argv[2] );
and
RAW_DEVICE_PREFIX = "/dev/r"
myDeviceLenght should not be more than 249 character long.
So the right code should be:
myDeviceLength = strlen( argv[2] );
if (( myDeviceLength < 2 ) || (myDeviceLength > 249))
{
goto ExitThisRoutine;
}
Apple didn't "churn it out." It's derived from OpenStep Workspace Manager as anyone with any relevant knowledge of OS X would know. Hell it even states in it the man page:
"I do know that "MacDork" definitely *is* biased....I wish editors would reject stories that are just blatently biased, or at least reserve the right to re-summarize story submissions."
Why would the Slashdot folks do something so stupid? All of their articles are biased. It's that biasness that gives whiny little wish-I-knew-it-all people such as yourself a place to bitch and moan and make people think you're smart.
Your village called. They want their idiot back. Shoo. Go on now. Shoo.
All he said was that parts of MacOSX (sic) that didn't come from BSD were not very well written.
Because it implies anything written in Mac OS X may be written poorly, while nothing from BSD is. Note that the majority of security fixes lately in Mac OS X, that I recall, were in BSD code (esp. ssh). I'm not criticizing ssh or BSD or anyone, it's just a stupid statement for the guy to make. Fine, it's a bug, no need to attempt to impugn Apple's programmers over it. I've said similar statements about people who criticized the ssh crew's code, or abilities, when a new bug is found.
NUL is '\0' the byte valued 0.
, that tells you where in the string you need to put the address that you want to jump to. The next problem is working out what that address should be. This you can get from the debugger.
C uses '\0' to delimit strings. Therefore a strcat will not go past the first '\0' in the shellcode (or whatever exploit it is you're trying to run).
So, if the code you want to run needs '\0's in it it must build those values on the fly. (e.g. subtract any value from itself and you instantly have a register loaded with 4 zeroes.) If you need opcodes that have 0 somewhere in them, then you need to self-modify, or you need to find a way to write what you want without using such opcodes. Most people go for the former.
That's all there is to being NUL-less. It's easy on x86, but slightly more challenging on fixed-length opcode machines (RISCs and VLIWs). Similarly, avoiding just '\0' is pretty easy - the real skill is from avoiding anything but [a-zA-Z0-9] such that you can pass some input sanitisers. (See posts by Herbert Kleebauer on alt.lang.asm for examples of ascii-only executables (one was called 'beth.com' IIRC, google should find it).)
To calculate the jump, just work out which of the 512 'A's are the 4 that you can see in the debugger stack trace. It's easiest to work this out by not having every character in the overflowing string being the same character. That's why I suggest 'abcdef...'
If you now see the backtrace as containing 0x66676869 then you know it was one of your 'fghi's that you're now looking at. However you don't know which one yet, so try again with a different repeated string with a different length, and 'triangulate'. Or simply use a single probe with a string that doesn't repeat, such as "aaabacad....azbabbbcbd....bzcacbcccd..."
Anyway
Read Aleph One's "smashing the stack for fun and profit" for more info. Once you can do it on one architecture, you'll be equipped to do it pretty much on all of them.
Have fun, but remember to practice safe hex.
YAW.
Your head of state is a corrupt weasel, I hope you're happy.
I seriously doubt that. Ever heard of linux?
...
...to name a few.
Ever heard of...(ahem)...
Adobe Photoshop, After Effects, InDesign, Illustrator, Acrobat, Logic Audio Platinum, Digidesign Protools, Macromedia Flash, Fireworks, Dreamweaver, Freehand, Apple Final Cut Pro, DVD Studio Pro, Shake, QuarkXPress, Microsoft Word, Excel, Powerpoint, Propellerheads Reason, TC Spark, Ableton Live, Corel Painter, Avid Xpress, Symphony, Media Composer
These are programs which people use every day to get work done. They are available on Mac OS X. They are not available on Linux.
Apple used to hold an important niche in the DTP market. Maybe they still do. At least, it's a more important market then commercial desktop unices...
Agreed. Being on top in commercial desktop publishing, graphic design, professional video and audio is much more important than being on top in commercial desktop unices.
concrete5: a cms made for marketing, but strong enough for geeks.
> So... Darwin users/developers. Does this problem affect the open source Darwin?
/ cd9660.util_main.m?rev=1.1.1.6&content-type=text/x -cvsweb-markup&cvsroot=apple">here</a>)
/* Verify our arguments */
/* Build our device name (full path), should end up with something like: */
/* /dev/disk1s2 */
/* Make sure device (argv[2]) is something reasonable */
Well, for one, it made it easier for me to find the issue in the source tree: <a href="http://cvs.opendarwin.org/index.cgi/isoutil
i nt main( int argc, const char *argv[] )
{
const char *myActionPtr;
int myError = FSUR_IO_SUCCESS;
char myRawDeviceName[256];
char myDeviceName[256];
int mnt_flag;
if ( (myError = DoVerifyArgs( argc, argv, &mnt_flag )) != 0 )
goto AllDone;
strcpy( &myDeviceName[0], DEVICE_PREFIX );
strcat( &myDeviceName[0], argv[2] ); <======
Now.. I personally wouldn't have used strcat in this case, strncat is your friend. One also notes DoVerifyArgs(), which does check the length of argv[2]:
myDeviceLength = strlen( argv[2] );
if ( myDeviceLength < 2 )
{
goto ExitThisRoutine;
}
Sigh.. to make sure it's not too short. I've seen worse, but I have also had a CS 202 prof who would fail a student for this kind of thing.
[ Three cheers for the paranoia in slash that made this post nearly impossible ]
2 weeks ? Why wait ? Get the fix for this vulnerability, and another similar one freshly discovered, from here.
Maybe we deserve this world ?