2010
01.27

The time has proven itself irrelevant once more with ReversingLabs celebrating its first birthday after seven long years of existence. Today is a very special day for us here at the ReversingLabs because today we turn one, officially. That means that just a year ago roller-coaster we call ReversingLabs Corporation stared its journey racing us to future. So far it has been a hell of a ride with the best twist and turns yet to happen, we promise you that. This year, even though its January, looks extremely promising with interesting works already done and releases pending, so keep an eye out open for us since you never know where we might show up.

Our thanks goes to everyone who supported us during all those years, we promise to keep surprising you with our projects on (more) regular basics.

VN:F [1.9.13_1145]
Rating: +5 (from 5 votes)
Share
2010
01.18

If it ain't broke, don't fix it. But what if it is? What if the file you are trying to unpack with your unpacker is broken, then what? Do you just chuck it marking it as crapware or do you try to fix it? This raises many many question in file handling. Its foolish to assume that every file your unpacker receives is a valid portable executable. So, how does TitanEngine cope with this?

As you may know TitanEngine has two built in functions to identify and fix damaged PE32/PE32+ files. Those two functions are: IsPE32FileValidExW and FixBrokenPE32FileExW in their UNICODE implementation. If you remember, not too long ago we published a PE validation tool built around our validation function which is available here. Today we pay attention on how to use these two functions.

Ideally before initializing the dynamic unpacking process you would validate the file you are unpacking to see if it will actually execute on the system. Windows loader can also show error messages about the broken file but since we are building our own application which might batch files its best to handle these cases statically before the application runs. And TitanEngine's validation function works in just such a way. It statically inspects the file making sure that it is valid or providing as much information about the errors found as possible. If we take a look at the FILE_STATUS_INFO structure we see all aspects of PE file being inspected.

typedef struct{
	BYTE OveralEvaluation;
	bool EvaluationTerminatedByException;
	bool FileIs64Bit;
	bool FileIsDLL;
	bool FileIsConsole;
	bool MissingDependencies;
	bool MissingDeclaredAPIs;
	BYTE SignatureMZ;
	BYTE SignaturePE;
	BYTE EntryPoint;
	BYTE ImageBase;
	BYTE SizeOfImage;
	BYTE FileAlignment;
	BYTE SectionAlignment;
	BYTE ExportTable;
	BYTE RelocationTable;
	BYTE ImportTable;
	BYTE ImportTableSection;
	BYTE ImportTableData;
	BYTE IATTable;
	BYTE TLSTable;
	BYTE LoadConfigTable;
	BYTE BoundImportTable;
	BYTE COMHeaderTable;
	BYTE ResourceTable;
	BYTE ResourceData;
	BYTE SectionTable;
}FILE_STATUS_INFO, *PFILE_STATUS_INFO;

Most important field for file validation purposes is the OveralEvaluation field which can have the following values:

  • UE_RESULT_FILE_OK
  • UE_RESULT_FILE_INVALID_FORMAT
  • UE_RESULT_FILE_INVALID_AND_NON_FIXABLE
  • UE_RESULT_FILE_INVALID_BUT_FIXABLE

No matter if the file is fixable or not the rest of the structure will be filled with information about defects found in the file. File is considered invalid and non fixable if the file OveralEvaluation says so, but that doesn't mean that the file will execute. If there are missing dependencies in the file it might not execute but that can be easily fixed by installing the Nexus plugin. If however OveralEvaluation claims that file can be fixed we can call FixBrokenPE32FileExW function to try to repair the file. While file is being repairedĀ  following structure will be filled:

typedef struct{
	BYTE OveralEvaluation;
	bool FixingTerminatedByException;
	bool FileFixPerformed;
	bool StrippedRelocation;
	bool DontFixRelocations;
	DWORD OriginalRelocationTableAddress;
	DWORD OriginalRelocationTableSize;
	bool StrippedExports;
	bool DontFixExports;
	DWORD OriginalExportTableAddress;
	DWORD OriginalExportTableSize;
	bool StrippedResources;
	bool DontFixResources;
	DWORD OriginalResourceTableAddress;
	DWORD OriginalResourceTableSize;
	bool StrippedTLS;
	bool DontFixTLS;
	DWORD OriginalTLSTableAddress;
	DWORD OriginalTLSTableSize;
	bool StrippedLoadConfig;
	bool DontFixLoadConfig;
	DWORD OriginalLoadConfigTableAddress;
	DWORD OriginalLoadConfigTableSize;
	bool StrippedBoundImports;
	bool DontFixBoundImports;
	DWORD OriginalBoundImportTableAddress;
	DWORD OriginalBoundImportTableSize;
	bool StrippedIAT;
	bool DontFixIAT;
	DWORD OriginalImportAddressTableAddress;
	DWORD OriginalImportAddressTableSize;
	bool StrippedCOM;
	bool DontFixCOM;
	DWORD OriginalCOMTableAddress;
	DWORD OriginalCOMTableSize;
}FILE_FIX_INFO, *PFILE_FIX_INFO;

This structure is input/output one. It can be used to set options to what will be fixed in and what will be left as it is. This is totally optional and this structure can be left zeroed before calling the file fixing function. Field OveralEvaluation can have the same values like in the FILE_STATUS_INFO structure and its used the same way. Additionally the value of variable FileFixPerformed indicates if the the file has been fixed. However not all field can be fixed, some can only be temporarily stripped. These fields are saved in the FILE_FIX_INFO structure and must be restored once the file has been dumped to disk. Most commonly this refers to resources which can be corrupted on disk but valid once the file has been decompressed in memory. Currently there isn't a function to automatically restore these fields so it must be done by the unpacker code. This will change for next major release.

To make this blog a little more then just a documentation clarification we have modified our existing UPX unpacker sample to support basic file fixing. Sample which is included in the package has damaged SizeOfImage field and incorrect code section attributes. This is fixed by the unpacked and saved in a new file which is then used for unpacking. As always binary, source code and the samples are included with the blog. Until next week...

TitanEngine

ReversingLabs Corporation

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

VN:F [1.9.13_1145]
Rating: +3 (from 3 votes)
Share
2010
01.11
http://www.youtube.com/watch?v=J0Uli-Di3_c

Recently we have seen an increase of malware attacks targeting multimedia formats. One of the formats targeted recently was PDF, a popular document format. Latest and still un-patched exploit targeting this format CVE-2009-4324 is particularly dangerous because it allows download of malicious content and its execution on the affected system or if it is unsuccessful denial of service attack. Statical analysis of the exploit showed how it operates and it described to bug inside out but we couldn't helped but wonder... Could we have prevented such an attack on the live system? Can we prevent future attacks that work similarly?

Having those questions in mind and the phrase "Swiss army knife for reverse engineering" used to describe our TitanEngine we decided to create a small project that could help us prevent these attacks. That project is called TitanGuard and it is a simple sandbox built around TitanEngine that prevents download of malicious content and its execution. Once installed this program monitors the application actions and queries user for response on suspicious behavior. This way CVE-2009-4324 and all future attacks targeting PDF file format and its most popular viewer can be prevented. Furthermore this kind of tool enables safe run-time analysis regardless of the exploit used since we can always block the file execution and study downloaded files. Until next time...

VN:F [1.9.13_1145]
Rating: +7 (from 7 votes)
Share
2010
01.04

Not too long ago we dedicated a blog post to removing executable password protections. In that post we said that we will eventually return to this topic to deal with much harder opponent. Well today is that day. This time we take a look at executable password protection named PEPasswordEncryptor

As we have seen in our previous blog on this subject tools that provide this kind of protection are very often coded with major design flaws which enable us with quick and painless ways to work around the password protection. However today's password protection option doesn't have such flaws. And that is why we need to find an optimal way to quickly and accurately recover the password. Can it be done in this case?

Quick analysis of the protected file shows us these interesting pieces of code:

  PUSH ECX
  PUSH ECX
  PUSH 40
  PUSH 0D
  PUSH DWORD PTR SS:[EBP+20]
  CALL NEAR DWORD PTR DS:[EDI+402923]
  POP ESI
  CALL L025        ;Calculate the hash for input string
  CMP EAX,F492C2C1 ;Correct password hash
  MOV EAX,0
  JNZ L015
...
L025:              ;Slow hashing algorithm
  XOR EAX,EAX      ;Hash initialization
  PUSH ECX
  PUSH ESI         ;ESI holds the password pointer
  PUSH EDX
  XOR EDX,EDX      ;Reason why it executes 0xFFFF times
  DEC ESI          ;for every letter
L031:
  INC ESI
  XOR AH,BYTE PTR DS:[ESI]
L033:
  XOR AL,DL
  ADD EAX,434F4445 ;Constant
  MOV CL,AL
  ROR EAX,CL
  XOR EAX,55AA5A5A ;Constant
  DEC DX
  JNZ L033
  CMP BYTE PTR DS:[ESI],0
  JNZ L031
  POP EDX
  POP ESI
  POP ECX
  RET

Now just by looking at this piece of code we see that the author of the program thought of many things when it comes to protected file's security. Why? Algorithm in charge of hashing the string is really slow because it executes 0xFFFF times for every letter of the password. If it wasn't for this bruteforcingĀ  this algorithm would be nice and quick. But before we go for that extreme we should always check for possible shortcuts that can enable us to skip the password necessity.

Since we already know that password hash must be 0xF492C2C1 lets see if the memory content decryption has a weakness.

  PUSHAD
  MOV EDI,EAX
  MOV ESI,EDX
  MOV EAX,48415348 ;Hash initialization
  XOR AL,BYTE PTR DS:[ESI]
  CALL GetPasswordHash
  MOV EBX,EAX
  XOR AH,BYTE PTR DS:[ESI]
  CALL GetPasswordHash
  SHR ECX,2
  MOV EDX,ECX
L011:              ;Decrypt first section
  XOR DWORD PTR DS:[EDI],EAX
  MOV CL,AL
  ADD EDI,4
  ROL EBX,CL
  XOR EAX,EBX      ;Keys for decryption: EAX and EBX
  MOV CL,BH
  ROR EAX,CL
  ADD EBX,EAX
  DEC EDX
  JNZ L011
  POPAD
  RET

Here is what happens here. Just before the program decrypts the first section it initializes two 32bit decryption keys. Both keys are initialized from the password string, more accurately the keys are password hashes. Second key is calculated fist. This key which is stored in EBX register is a direct product of password hash for algorithm initialize value 0x48415348. However this value isn't a constant, it is modified by XORing with the fist letter of the password. That is why the already calculatedĀ  password hash we have 0xF492C2C1 isn't enough to break this algorithm. Fist key is calculated last and its value is stored in EAX register. Hashing algorithm for this key calculation is a direct result of first key stored in EBX XORed with the fist letter of the password. Only by having the state of both keys for decryption beginning we can correctly decrypt the file. However we put it the password seems like a must for decryption. We are going to return to shortcuts a bit later, lets discuss the bruteforce option first.

Building a bruteforcer for this algorithm is quite easy. We just need to go through the all possible combinations that a password can take in order to recover the 'lost' password. However that proves to be a much harder task then it sounds. Building the bruteforcer isn't a problem but the time its needed for recovering a simple password which is only 4 characters in length is very long. Take a look at this program log to see a basic log which shows the "slowness" of this algorithm. It seems that author of the program saw bruteforce as a potential risk and made it slow on purpose. But this isn't the only problem. Our bruteforce test shows that passwords collide meaning the multiple passwords have the same hash. Any of these passwords will unlock the program but it won't be decrypted correctly and therefore it will crash. Here is how the bruteforce program log looks like:

Correct password for this sample is: "ap0x" but to recover it bruteforcer needed approximately 4 minutes. And as you can see in log file time needed to go through every four character password combination (a..z + A..Z + 0..9) is more then 2 hours. And even that isn't a guarantee because you have check every password since the protection doesn't have an additional validation to check if the code decrypted correctly. Since that is way too slow for any practical use on longer passwords we return to finding the algorithm weakness.

But is there a weakness? If we look at the decryption algorithm we see that both EAX and EBX keys are needed for decryption to work correctly. However only one key, EAX, is used to decrypt data by XORing the file memory content. Therefore recovering the password would be easy if we knew the first four bytes unencrypted. Which we don't... Could it help if we need the unencrypted value of any random sequence of bytes in the file? It might but that would mean that we would also need one more information for that location, the value of ECX register because it is used to modify successive decryption keys. Is there just such a sequence of bytes? Sure, at the end of file whose sections are aligned to PE.FileAlignment (and its a must for this protection) we have at least 12 bytes which are zeroes. Last four bytes in that case are equal to EAX decryption key at that time, which leaves EBX and CL as unknowns. Four bytes before that we have the same story. In order to recover EAX, EBX and CL we must do the following:

  • Reverse the decryption algorithm so it decrypts the memory backwards
  • Bruteforce that decryption to recover EAX, EBX and CL values
  • Make sure that those key values are correct since algorithm does collide
  • Decrypt the file backwards using the correct keys

Since keys are 32bit and we already know the value of one of those at one point we can bruteforce keys between 0x00000000 and 0xFFFFFFFF in order to get the missing EBX and CL values. That is much faster then trying to bruteforce the infinity of possible passwords. Reversed algorithm can be seen in the source code under the function named PEPDecryptFile.

http://www.youtube.com/watch?v=jJG-9l-Urmc

Writing a bruteforcer for PEPasswordEncryptor is a nice reversing exercise especially when algorithm shortcut inspection is involved. As always binary, source code and the samples are included with the blog. Until next week...

PEBrute
(package contains unpacker binary, source and samples used)

VN:F [1.9.13_1145]
Rating: +9 (from 9 votes)
Share
2010
01.01
http://www.youtube.com/watch?v=TcKiRr_ItyQ

In our previous blog we have shown a short video that demonstrates the usage of new LUA SDK. Since then we decided that console unpackers are very boring to we included a new function in the TitanEngine which enables creation of a simple unpacker GUI that makes your script unpackers a little bit more user friendly. With this youtube video we welcome you to 2010. ReversingLabs will be back on Monday with more reverse engineering stories just for you. Catch us next time....

VN:F [1.9.13_1145]
Rating: +7 (from 7 votes)
Share