|Home » News » Roundups » The Rise and Fall of GRC
Curse of the Malicious Hackers
17 January 2006 17:17 UTC
Never attribute to malice that which can get Steve Gibson confused.
Only Steve Gibson could waste ten minutes of airtime explaining the difference between 'hacker' and 'cracker'. Only the Steve Gibson home security hobbyists would want him to discuss it.
Actually that's not true: Steve Gibson's hometown buddy (Gayburn CO) Leo Laporte could do it too.
In their latest AOL-sponsored 'podcast' Steve 'Ahab' Gibson and Leo Laporte did just that - and then segued (almost as if they'd planned it) into:
The Discovery of the Year
Steve Gibson had namely been very interested in the recent Windows WMF flaw. And he'd taken the available source code for the fix and begun building his own fix - without copying from the previous program of course - and come upon a startling discovery.
The WMF flaw was not a flaw but an intentional back door.
It's all about a standard GDI call. 'SetAbortProc'. Steverino discovered that the WMF exploit using this GDI call didn't work as he expected (a claim that rang very true). Instead, it relied on input of a 'flawed' value to the GDI replay records in the WMF file.
By setting the length of a GDI record to one byte - an impossible value - Gibson could get his WMF file to
execute arbitrary code.
Gibson told his good buddy Leo that the exploit didn't work if the record length were set to any other value. It had to be set to one byte.
The forlorn tech writer couldn't figure out why metafiles would want to set an abort procedure in the first place. It must be real legacy code, opined Gibson.
Back in the days old IBM were worried that their multitudinous hardware platforms were making customers confused. Each had a different interface. They started a project to unify all possible interfaces. The result was what they called 'System Applications Architecture/Common User Access' or 'SAA/CUA' for short or even just 'CUA'. At the bottom of CUA were seven principles of correct GUI design. The first and foremost of these was called the 'User in Control Principle'.
In a nutshell the 'User in Control Principle' principle stated:
'The user must always be in control - or at least think he is.'
Thus the use of the 'wait' cursor - an hourglass, a watch with the second hand moving, a spinning beach ball.
But the 'User in Control Principle' also stated that the wait cursor was only acceptable for shorter delays of two to three seconds. When delays would be greater than that, the user must be given
an 'abort' dialog.
The abort dialog would typically have a
And the user, by clicking on this button (or hitting the space bar or Enter) could
abort the procedure.
A typical use for this mechanism was for printouts. Printouts should be done asynchronously as they rely on networking. Typically a program will send the print job to the 'spooler' where it will wait in queue. There are so many opportunities for delay here that the user cannot be expected to do nothing while the job completes - and a wait cursor which might be interminable (with printer error) is not acceptable either. Thus the 'abort' dialog.
Setting up a print job on Windows is not more difficult than doing anything else on that platform. Once the document is realised for the printing device (Windows is not true WYSIWYG and dimensions, fonts, etc have to be recalculated) the job is ready to be sent, and the client application must send the exported address of the abort procedure.
While the print job is pending, and until the print job has completed, user interaction with the abort dialog on screen will be fed into the client application's message queue. This is the purpose of setting the abort procedure.
It is important that the procedure which will accept user input be exported so Windows can see it. Exported procedures are visible to the operating system. They're listed in a special section in the executable's headers. When the client sets the abort procedure, and if the procedure is exported, the linker picks up the relative address of the procedure and inserts this address in the headers. From this point onward the system will be able to call the procedure back in the event of user interaction while the print job is completing.
The abort procedure is set by calling the GDI API 'SetAbortProc'. This call takes two arguments: the 'device context' for the job and the address of the abort procedure. Once the client application has set up the printing device context, it uses this identifier plus the name of its own abort procedure to call SetAbortProc. Once the print job begins the operating system will route user input and other related messages to this procedure.
If the user clicks the 'cancel' button, the operating system will send this information to the abort procedure. The client application's code will then process the message, and in the event it's a request to abort the print job, issue the appropriate command to the spooler so the print job is aborted.
Easy as pie.
SetAbortProc is part of the Windows GDI - the graphical device interface. Any client application wishing to set a print job will use it. And as it's part of the GDI, it can also be recorded in a metafile.
Metafiles in this context are merely a 'playback' mechanism for ordinary GDI calls used by programs to draw things on screen (or to a printer). Most any function that's in the GDI can be recorded in a metafile. SetAbortProc can be recorded in a metafile.
The WMF flaw was exploitable because malicious hackers set the abort procedure address to point to their own highly malicious code inside the metafile itself. Normally this shouldn't work, as Windows is supposed to see that only code in specially marked areas of memory is allowed to execute.
But that's only in theory - which in the world of Windows, as everyone knows, is a far cry from reality.
This is also why only 'hardware' data execution prevention (DEP) could reliably stop the WMF exploit. DEP means that memory marked as data (and not code) cannot be executed. (Microsoft's software implementation of DEP namely screws up. Toss the potato.)
SetAbortProc has been around since time immemorial. It's been part of the 16-bit Windows API. It evolved into the 32-bit platform created by the Tribe. It's necessary and it's even OK from a security standpoint.
What was not good was allowing any section of memory to be regarded as executable code. And recognising metafile records with calls to SetAbortProc in metafiles destined only for the computer screen.
For it's the possible delay that's determinant - or how would it look with a 'cancel' dialog on screen for every desktop icon every time a Windows user wanted to refresh the desktop?
Earlier versions of Windows correctly disregarded calls to set the abort procedure in device contexts other than for printing; later versions slipped up - and thus the exploit.
Microsoft's chief of security Stephen Toulouse responded to Steve Gibson's latest attempt to 'stir the pot' and in so doing showed he understands Windows code as the erstwhile charlatan never will. (He doesn't mention Ahab's name - that would understandably be beneath him.)
It was not an intentional back door, said Toulouse, and it was not fixed in earlier versions of Windows because those versions simply dropped the call and disregarded the callback address. And, the flaw has been fixed.
Toulouse also pointed out that Gibson's 'research' [sick] was in itself flawed (a claim that rang very true). By adding the evil malicious code only at the end of his metafile, Gibson was getting erroneous test results, said Toulouse.
Gibson and Open Source
The portent of Steve Gibson's self-induced discovery is leading him, or so he says, to provisionally reevaluate the benefits of open source. A staunch opponent of open source (or anything non-Windows as that's the only platform he has a fighting chance to understand) Gibson says things like the evil malicious WMF back door could not have been perpetrated on a platform open to public inspection.
Once again Gibson shows why true security experts such as Fyodor hold him in such scorn: father of Unix Ken Thompson had a back door in the source code to the Unix C compiler and the RMS Linux distro Debian recently found something similar.
The next time there's a cry of malicious hackers planting evil insidious back doors in anyone's code, look to the source. If the source is wont to make the claim in
huge centred Sesame Street HTML layout and graphics
Then perhaps it's best ignored.
[Yes there is another level to this mystery, that of exactly how and when WMF records are recognised and the significance of the picture/fax viewer DLL. But let's keep things simple: Steve might be reading. Ed.]