2009
12.29
blah

As we said in the blog dedicated to our latest TitanEngine release we are continuously working on expanding our SDK to support as much programming languages as possible. That is why the next major version update for TitanEngine will feature a support for LUA scripting language. This is it from ReversingLabs for this year. Enjoy the holidays!

VN:F [1.9.3_1094]
Rating: +3 (from 3 votes)
  • Share/Bookmark
2009
12.28

Lockpicking tELock

Today's blog post brings TitanEngine to the test and its a good way to end this years series of our blog posts dedicated to unpacking. The reason why TitanEngine is put to the test is because tELock is a protector riddled with protection tricks. That is why some modifications were needed so that we can debug files protected with this protection without getting detected by its anti-debugging tricks. Furthermore because of the specific packing method used our PE file validation routine needed some tweaks too. These small inconveniences resulted in today's publishing of two tools named: PEValidate and LogException. Those two tools are used to test the engine's performance with file execution and validation.

PEValidate is used to validate any PE32/PE32+ file. It evaluates the plausibility of file execution and provides detail error description about every found problem. This tool is a wrapper around TitanEngine function IsPE32FileValidEx and its used as a test for it.

LogException is used to track all exceptions that occur while debugging any PE32 file. It does execute the file fully so run it in the safe environment for suspicious samples. This tool also demonstrates the usage of TitanEngine debugging features and it is used as a test for detection from debugging tricks. What this tool showed us is that tELock uses debug registers to decode data and to place hardware breakpoints it itself handles. That made us redo the part of engine that handles hardware breakpoints for TitanEngine 2.0.3. This way plugins such as AntiDRx for OllyDBG are not needed for our engine.

Writing a blog that describes in detail how tELock works isn't an easy task because files protected with it are riddled with protection tricks, polymorphic decryption loops and exceptions specifically targeting possible errors in debuggers. Simply put tELock is roller coaster made of fun. For the purpose of this blog we are using a sample packed by tELock 0.99 with all protection options turned on.

After the first jump instruction in the sample we land on the start of the protector's section. Executing several obfuscations leads us to first poly decryptor code. Right here:

  MOV ECX,1DC9
  MOV EAX,ECX
  ADD ESI,36
DecryptionLoop:
  LEA EAX,DWORD PTR DS:[ECX+EAX*4+67]
  CALL DummyLabel
DummyLabel:
  XOR BYTE PTR DS:[ESI],AL
  INC ESI
  POP EDX
  DEC ECX
  JG DecryptionLoop

After the first encrypted layer has been decrypted we continue tracing until the first exception:

  SUB ECX,ECX
  PUSH DWORD PTR FS:[ECX]
  MOV DWORD PTR FS:[ECX],ESP
  INC BYTE PTR DS:[ECX]

Which is in this case an access violation. Just after we return from its handler execution next decryption awaits us here:

  MOV EDX,DWORD PTR SS:[ESP]
  POP EAX
  SUB EDX,004128BF
  MOV EAX,729017A8
  MOV EDI,EAX
  SUB EDI,724EEF46
  STC
  ADD EDI,EDX
  MOV EAX,72901D20
  MOV ECX,EAX
  SUB ECX,72901D12
  DEC EAX
  MOV EBX,72900C26
DecryptionLoop:
  XOR DWORD PTR DS:[EDI],EBX
  ADD EBX,72900C76
  XOR EAX,ESI
  CLC
  MOV EAX,4
  ADD EDI,EAX
  SBB EAX,72BFB05C
  SUB EAX,72BFB131
  SUB ECX,1
  STC
  OR EAX,ESI
  PUSH ECX
  MOV ECX,ECX
  JECXZ ExitDecryption
  POP ECX
  JMP DecryptionLoop

And this is immediately followed by the next decryption loop:

DecryptionLoop:
  OR CX,CX
  JNZ OverDummy
  INT 20
OverDummy:
  ROL BYTE PTR DS:[EBX+ECX],5
  ADD BYTE PTR DS:[EBX+ECX],CL
  XOR BYTE PTR DS:[EBX+ECX],0F1
  INC BYTE PTR DS:[EBX+ECX]
  DEC ECX
  JG DecryptionLoop

From this execution pattern we see two things. One, tELock decrypts internal data with multiple polymorphic decryption loops followed by exceptions and two this blog would be too long to list them all. Therefore we will only focus on two important parts: imports and entry point. To find the import filling part we reset our sample and set a breakpoint on the RET instruction of GetModuleHandleA API. First time that breakpoint hits tELock is just locating EnumWindows API to try to locate debugger windows. But the second time that breakpoint hits its going to take us exactly where we want to be. Here:

  PUSH EAX ;Get DLL base
  CALL NEAR DWORD PTR SS:[EBP+4036D1]
  TEST EAX,EAX
  JNZ DLLFound
...
DLLFound:
  PUSHAD ;Check if that DLL can be redirected
L001:
  XOR ECX,ECX
  SUB DH,DH
L003:
  MOV DL,BYTE PTR DS:[EBX]
  TEST DL,40
  JE L007
  AND DL,5F
L007:
  OR DL,DL ;Check ASCII "GDI32.DLLUSER32.DLLSHELL32.DLLKERNEL32.DLL"
  JE L021
  INC EBX
  INC DH
  INC ECX
  CMP DL,BYTE PTR DS:[EAX+ECX-1]
  JE L003
  CMP DL,BYTE PTR DS:[EAX+ECX+8]
  JE L003
  CMP DL,BYTE PTR DS:[EAX+ECX+12]
  JE L003
  CMP DL,BYTE PTR DS:[EAX+ECX+1D]
  JE L003
  JMP L001
L021:
  OR DH,DH
  MOV DWORD PTR SS:[ESP+1C],EDX
  POPAD
...
  AND EBX,7FFFFFFF ;Get API address
  PUSH EBX
  PUSH DWORD PTR SS:[EBP+40374B]
  CALL NEAR DWORD PTR SS:[EBP+401C6E]
  INC EAX
  DEC EAX
...
  PUSHAD ;Check whether to write a redirection
  AND DWORD PTR DS:[EDI],0
  MOV EAX,DWORD PTR SS:[EBP+403853]
  INC EAX
  JE WriteAPIPointer ;Patch to always jump!
WriteAPIPointer:
  POPAD
  XOR DWORD PTR DS:[EDI],EAX
  POP EAX
  DEC EAX
  JE NextAPIPointe

Quite a long piece of code which does the following:

  • Get the base of loaded DLL with GetModuleHandleA or load new DLL with LoadLibraryA
  • Check the name of current DLL in the import table to see if that DLL can be redirected
  • Allocate memory for redirection of APIs inside kernel32, user32, gdi32 and shell32 dlls
  • Check whether to redirect the API (if yes then redirect, if no the write normal pointer)
  • Process next API and next DLL

From this we can easily collect all the data we need to fix the import table. Only one jump needs to be patched to prevent tELock from ever redirecting APIs. This patch isn't necessary for our unpacker but can be used as a work around tELock's redirection. Due to the fact that everything inside the packers import table is encrypted with layers of polymorphic encryption data gathering with dynamic unpacking is much easier then static option.

After the import table has been filled tELock will execute a couple of exceptions more before it jumps to the entry point. Last polymorphic decryption loop which decrypts the entry point jump is here:

  XOR DWORD PTR DS:[EDI],EDX
  DEC EBX
  SBB EAX,EDI
  ADD EDX,726C7434
  CMP EAX,-7C
...
  CWDE
  POPAD
  ADD EAX,ESP
  RET

After POPAD and RET instructions execute you will land here:

  MOV EBX,DWORD PTR SS:[EBP+403783]
...
  MOV ECX,39E
  REP STOS BYTE PTR ES:[EDI]  ;Zero out packer code
  LEA EDI,DWORD PTR SS:[EBP+4015DC]
  MOV ECX,1BFF
  REP STOS BYTE PTR ES:[EDI]  ;Zero out packer code
  STOS WORD PTR ES:[EDI]
  LEA EDI,DWORD PTR SS:[EBP+4015DC]
  TEST ESI,ESI
  JNZ L011
  MOV DWORD PTR DS:[EDI],C340C033
  JMP L016
L011:
  MOV BYTE PTR DS:[EDI],0E9  ;Write OEP JUMP
  INC EDI
  SUB EBX,EDI
  SUB EBX,4
  MOV DWORD PTR DS:[EDI],EBX ;Write OEP JUMP
L016:
  LEA EDI,DWORD PTR SS:[EBP+4031DB]
  MOV ECX,2C
  REP STOS BYTE PTR ES:[EDI]
  STOS WORD PTR ES:[EDI]
  JMP L022
  INT 20
L022:
  POPAD
  CALL L024
L024:
  POP EDX
  SUB EDX,0E
  PUSH EDI
  PUSH ECX
  XOR EAX,EAX
  LEA EDI,DWORD PTR DS:[EDX]
  MOV ECX,20
  REP STOS BYTE PTR ES:[EDI]
  STOS WORD PTR ES:[EDI]
  POP ECX
  POP EDI
  RET   ;JUMP TO OEP

This code erases the protector memory and creates a new jump at the start of the tELock section which leads to the entry point. Purpose of that jump is to provide a redirection to entry point when tELock is used to protect DLL files. However we couldn't make tELock protect any DLL file successfully which is why our unpacker only supports executable files.

If you only want to unpack tELock protected file you can see how it is done in our video tutorial which shows ImportStudio usage:

blah

Writing an unpacker for tELock should be a nice exercise for any reverser. As always unpacker, source code and the samples are included with the blog. Until next week...

TitanEngine

ReversingLabs Corporation

RL!deTELock
(package contains unpacker binary, source and samples used)

VN:F [1.9.3_1094]
Rating: +4 (from 4 votes)
  • Share/Bookmark
2009
12.21

With the latest TitanEngine release, we introduced new functions which enable decompression of content packed with aPLib and LZMA. Today we will use those functions to make a static decompressor for AHPack. But before we do that we must answer a simple question: "What is the difference between regular static unpackers and static decompressors?"

Simply put, regular static unpackers are only used to unpack "simple" crypters which don't compress data in order to decrease the encrypted file size. In contrast, in the case where some data is compressed, unpacking must decompress that data, therefore we call such unpackers static decompressors. Static decompression can be used to unpack  both PE packers and installer formats since similar unpacking logic is used for both.

The Unpacker we are making today will be a static decompressor, since AHPack uses aPLib compression to decrease the file size. Furthermore we are "killing two birds with one stone" since both AHPack and !EPPack are based on the same source code base and can be unpacked the same way. If you open any of the provided samples in OllyDBG you'll see the packed file entry point:

  PUSHAD
  PUSH 00407054		;String: kernel32.dll
  MOV EAX,[KERNEL32.GetModuleHandleA]
  CALL NEAR DWORD PTR DS:[EAX]
  PUSH 004070B3		;String: GlobalAlloc
  PUSH EAX
  MOV EAX,[KERNEL32.GetProcAddress]
  CALL NEAR DWORD PTR DS:[EAX]
  PUSH 3000		;Virtual size of first section
  PUSH 40
  CALL NEAR EAX
  MOV DWORD PTR DS:[4070CA],EAX
  MOV EDI,EAX
  MOV ESI,00401000 	;Virtual offset of first section
  PUSHAD		;aPLib decompression
  CLD
  MOV DL,80
  XOR EBX,EBX
  MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
...
  POPAD			;aPLib decompression end
  MOV ECX,2FFC		;copy decompressed data to first section
L002:
  MOV EBX,DWORD PTR DS:[EAX+ECX]
  MOV DWORD PTR DS:[ECX+401000],EBX
  LOOPD L002
 

This first part of the packer code quite clearly shows what the packer does. First it allocates a temporary memory buffer to store decompressed data, then decompresses the content of the first section to it. After the content is decompressed it is written to its original location, which, in this case, is first section's memory. The packer only compresses the first section since all compilers create PE files with a code section as the first file section. Resources, imports, relocations and TLS data isn't compressed, it is just realigned to new physical location after the size of first section decreases. In order to decompress the file we must do the following:

  • Decompress the content of the first section
  • Move the content of all other sections (including overlay) by the size needed to write decompressed content
  • Write decompressed data to first section and correct its physical size
  • Fix section data pointers to correctly point to the new section location for the remaining sections

After this we have to fix imports, correct the entry point address, and optionally delete the last section. We have already said the imports are not compressed, but that doesn't mean that this packer doesn't process imports. This code here does exactly that:

  MOV EDX,00400000
  MOV ESI,445C ;Address of first IID
  ADD ESI,EDX
  MOV EAX,DWORD PTR DS:[ESI+C]
  TEST EAX,EAX
  JE 00407277
  ADD EAX,EDX
  MOV EBX,EAX
  PUSH EAX
  MOV EAX,[KERNEL32.GetModuleHandleA]
  CALL NEAR DWORD PTR DS:[EAX]
...
  AND EBX,0FFFFFFF
  PUSH EBX
  PUSH DWORD PTR DS:[4070CE]
  MOV EAX,[KERNEL32.GetProcAddress]
  CALL NEAR DWORD PTR DS:[EAX]
  MOV DWORD PTR DS:[EDI],EAX
  ADD DWORD PTR DS:[4070D2],4
  JMP SHORT 00407218
  ADD ESI,14
  MOV EDX,00400000
  JMP 004071E5
 

You can see that it's very simple code that just goes through the normal import table and fills its content. The data we need from here is address of the first IID, which will be used to find out the size of the import table or the number of IIDs present in the import table. Keep in mind that last IID will be empty, since that is the way import table is described in PECOFF. Since this table is valid we can use these two values to fix it. Simply by setting ImportTableAddress and ImportTableSize values in the PE header, we fix the import table in the unpacked file. Last thing we need to do is read the address of the entry point which can be found here:

  PUSH EDX
  CALL NEAR EAX
  POPAD
  MOV EAX,004012C0 ;Address of entry point
...
  PUSH ECX
  RET
 

Writing an unpacker for AHPack  is fairly complex, since there are a few details to worry about. It provides an interesting challenge for any reverser and it shows the potential of TitanEngine's new static unpacking function. As always unpacker, source code and the samples are included with the blog. Until next week...

TitanEngine

ReversingLabs Corporation

RL!deAHPack
(package contains unpacker binary, source and samples used)

VN:F [1.9.3_1094]
Rating: 0 (from 2 votes)
  • Share/Bookmark
2009
12.16
blah

There was a lot of response and quality feedback about our latest TitanEngine release. One of the questions we got is "How to use the engine and its plugins?". That is why we made this video which shows a quick example on how to compile the UPX sample and use our Nexus plugin in order to unpack samples which can't be run on the system because one or more of their dependencies is missing. Sounds cool?

VN:F [1.9.3_1094]
Rating: +3 (from 3 votes)
  • Share/Bookmark
2009
12.14

TE202

TitanEngine just got its new major update we labeled as TitanEngine 2.0.2. Even though the version incrementation is small the number of changes and the pure size of the code is vast. That is why we dedicate today's blog for listing all additions and changes done to the engine.

Unicode support

Possibly the biggest overall change done to the engine is accommodation of all existing functions to support unicode file names and paths. To preserve compatibility with all previous versions we have retained all function definitions and just added new functions to work with unicode input parameters. Such functions can be easily recognized by the appendix “W” which they have. For specific function definitions please refer to the documentation and SDK header files.

Linux support

As we mentioned in our blog earlier TitanEngine can now be run on any Linux platform under WINE. This change ensures maximum safe environment for live malware analysis for those reverse engineers that make Linux their platform of choice.

Plugin extensions

With this update we introduced the possibility of extending TitanEngine core functionality by writing plugins for it. We have included four samples with our TitanEngine PDK. Most interesting one is called Nexus which hooks internal TitanEngine functions and automatically enables unpacking of all samples which can't be run on the system because one or more DLL's they import is missing on the system. Other plugins show data and ASM extraction with an interesting example called lynxImpRec which shows how to import and export IAT data from and to ImpRec tree files.

MASM32 SDK

Header files that come with the engine now include an SDK for MASM. It is our intent to provide header files for as much programming languages as possible so that you can use TitanEngine in any way that you desire. Each new TitanEngine major release such as this one will include support for at least one more programming language. Until we run out of languages to support.

New functions

Not counting the new functions added for unicode compatibility TitanEngine has been increased by 43 new functions. We extended functionality of Relocater, Resourcer, Threader, Static and Engine modules and added two new ones called Extension and Hooks. Most important changes to the existing modules are the ones done to the Static module. These new functions enable compressed content decompression (supporting: aplib and lzma), new types of memory decryption and copying, file and memory hashing. Regarding new modules the most interesting one in the module called Hooks. This module is used to insert hooks (supports: API and IAT hooking) in its loading process. We were aware of the fact that sometimes you won't need the whole TitanEngine functionality for your project and that is why we have created TitaniumHooks which only consists of the Hooks module.

Samples

On its original release date TitanEngine came with only two samples, unpackers for UPX and BeroExePacker. Today with the release of version 2.0.2 we ship TitanEngine with 28 code samples listed in following categories: Plugins, Tools, Unpackers and Hooks. Samples are sorted by programming languages they are written in. We try to equally grow sample code base for all programming languages TitanEngine SDK supports but the most dominant one is still C/C++.

Bug fixes

Any release without this is unimaginable. In this release we fixed all bugs that we are aware of. Thank you for all your reports, you keep TitanEngine with as little bugs as possible.

TitanEngine 2.0.2 in numbers

  • 385 functions
  • 25,000 lines of code
  • 28 usage samples
  • 4 supported programming languages
  • 365 pages of documentation
  • 1 download waiting to happen...

RL

VN:F [1.9.3_1094]
Rating: +5 (from 7 votes)
  • Share/Bookmark
2009
12.07

With the next TitanEngine release just around the corner we decided to do a light an interesting analysis of a simple executable password protection. Today's focus is on LCCrypto a simple example which will show us the general security and vulnerabilities of such and similar tools.

Now it theory only one password should be able to unlock such protected application and allow its execution without any possibility of removing the protection without the correct password. Well that's the theory behind such tools but they themselves have a weakness too because there still must be a way for the application to check the validity of the inputted password. So regardless of the protection executable password protection solution must do one of the following:

  • Compare passwords or password hashes to determine whether or not to execute the file
  • Use the inputted password for code decryption and verify the decrypted content by hashing

So, not a lot of options to choose from. First model would be the least secure since no content is encrypted and the second most secure requiring password bruteforce to be removed. Lets see what we are dealing with in LCCrypto's case. Entry point of the protected file looks like this:

  MOV EAX,DWORD PTR SS:[ESP] ;Pointer to ExitProcess API
  AND EAX,FFFF0000
L002:
  CMP DWORD PTR DS:[EAX],905A4D
  JE L006
  SUB EAX,1000
  JMP L002
L006:
  PUSH EBP

Very simple way to get the kernel base most commonly used in malware which could flag this sample as malicious by some anti-virus vendors. Following this we have:

  MOV EBP,EAX
  ADD EAX,DWORD PTR DS:[EAX+3C]
  MOV EDI,DWORD PTR DS:[EAX+78]
  ADD EDI,EBP
  MOV ESI,DWORD PTR DS:[EDI+20]
  ADD ESI,EBP
  XOR EDX,EDX
L007:
  MOV EAX,DWORD PTR DS:[ESI]
  ADD EAX,EBP
  CMP DWORD PTR DS:[EAX],50746547
  JNZ L025
  CMP DWORD PTR DS:[EAX+4],41636F72
  JNZ L025
  CMP DWORD PTR DS:[EAX+8],65726464
  JNZ L025
  CMP WORD PTR DS:[EAX+C],7373
  JNZ L025
  MOV EAX,DWORD PTR DS:[EDI+24]
  ADD EAX,EBP
  MOVZX EBX,WORD PTR DS:[EAX+EDX*2]
  MOV EAX,DWORD PTR DS:[EDI+1C]
  ADD EAX,EBP
  MOV EAX,DWORD PTR DS:[EAX+EBX*4]
  ADD EAX,EBP
  MOV DWORD PTR DS:[407408],EAX
L025:
  ADD ESI,4
  INC EDX
  CMP EDX,DWORD PTR DS:[EDI+18]
  JNZ L007

Another code which is used to locate GetProcAddress API pointer. This is crucial since that API and already located kernel base are all that this protection needs to locate all other needed APIs to create password input dialog and process it. Code that creates the window and its elements is located just after the code locates all needed APIs. Code that is of interest is here:

  PUSH DWORD PTR DS:[407004]
  CALL NEAR DWORD PTR DS:[407410] ;FreeLibrary
  PUSH DWORD PTR DS:[407000]
  CALL NEAR DWORD PTR DS:[407410] ;FreeLibrary
  CMP BYTE PTR DS:[407881],0
  JE L008
  MOV EAX,004012C0 ;OriginalEntryPoint
  JMP NEAR EAX
L008:
  PUSH 0
  CALL NEAR DWORD PTR DS:[407414] ;ExitProcess

This is what happens when the window message processing loop just above this exits, and that will happen when the created window associated with that message processing loop terminates by window closing. Which means that if the byte at address 0x00407881 isn't set to zero LCCrypto will pass the code execution to original entry point which in this case isn't encrypted at all. Patching this compare in memory and closing the window would do the trick. Removing the protection completely would be as easy as setting the entry point address in the PE header to 0x000012C0. Normally our work would be done here, but lets dig in just a little bit more.

  PUSH 10
  PUSH 0040776E
  PUSH 64
  PUSH DWORD PTR SS:[EBP+8]
  CALL NEAR DWORD PTR DS:[407460] ;GetDlgItemTextA
  CALL 00407FF9 ;Calculate CRC32
  LEA EBX,DWORD PTR DS:[40776E]
  CALL 00408021 ;Update CRC32
  CMP DWORD PTR DS:[40775E],EAX ;Compare password CRC32
; DS:[0040775E]=0E1A88EF
  SETE BYTE PTR DS:[407881] ;Set the correct password switch

This code bit here processes the inputted password. As we can see from the code above inputted password is hashed with CRC32 and that value is compared with the value 0x0E1A88EF, and that means that hash for the password must be 0x0E1A88EF for protection to pass the control to original code. Now, leaving alone the fact that we can patch the file, think about what we can do to legitimately start the application. Bruteforce the hash? What about make a string that has the same one?

CRC32 algorithm collides which means that we can create such a string. Without going into coding a program that can do that we use a PeID plugin called CRC32 made by Gelios on a simple text file containing only the string "pwd". After the file's CRC32 has been set to 0x0E1A88EF our string "pwd" becomes "pwd€va" which is a string with the CRC32 hash we need. Entering such string into program will fool it into thinking that is the original password making LCCrypto execute the file normally.

We didn't do any coding today because it wasn't necessary. However we did investigate the security of one executable password protection and saw all the flaws its has. Next time we return to this topic we will do some coding in order to make a bruteforce engine that will recover the password used to protect the file. Until next time...

LCCrypto
Download protected sample

VN:F [1.9.3_1094]
Rating: +1 (from 1 vote)
  • Share/Bookmark