14 Oct

About FLARE 2017

This was the 3rd time I played Flare-On reverse-engineering contest. And I must say, this year was much nicer than the last. Challenges were more balanced, didn't require insane arcane knowledge and rick-rolling was kept to a reasonable minimum.

As for me - I wasted too much time and effort in challenge #7 and stopped competing at that point. Later I spent few hours every weekend just to finish the entire contest on time.

Mandatory bragging screen:

I'm not planning make full-featured writeups, so here's just an overview of this year's challenges.

#1 - login.html

ROT13, what else?
Time spent: 20 seconds

#2 - IgniteMe.exe

It's XOR. For some reason I kept messing up my answer. I guess I wasn't really awake yet. bigsmile
Time spent: 30 minutes

#3 - greek_to_me.exe

Bruteforce the correct byte value which will decode valid x86 code which will get you the flag. Simples.
Time spent: 15 minutes

#4 - notepad.exe

The worst challenge in the contest. To decrypt the flag, one must get data from last years challenge files. Self-centered ego masturbation, anyone?
Time spent: 2.5 hours

#5 - pewpewboat.exe

Linux challenge in form of a Battleship game with hardcoded levels. Simple to patch to reveal all ships and equally simple to write a C# decryptor that will decrypt all levels.
Time spent: 2.5 hours

#6 - payload.dll

You get a DLL and then mess with it's exports. Reminded me very much of last year's challenge #4.
Time spent: 2 hours

#7 - zsud.exe

It's a single-player dungeon. You get a native executable that functions also as .NET CLR host and as a web server. It loads a .NET DLL which in turn decrypts PowerShell code. PowerShell code then functions as a web client, sends the player's moves to server, server validates it and sends the result back.

I followed the wrong path and got stuck. I got to the powershell code all too quickly and neglected to look at the process itself. If I had done that, I would have noticed hooked API functions and would not have wasted too much time trying to bruteforce my way through..
Time spent: way too much

#8 - flair.apk

Mandatory Android challenge. It looked like there could be some anti-debug checks but JEB worked just fine. I solved each stage be reimplementing the check in C# and then breaking it.
Time spent: few hours

#9 - remorse.ino.hex

Arduino challenge, that's a first! smile I had to learn AVR assembly, find out how to debug stuff in Atmel Studio 7 and it was a walk in the park from there.

Note to self - IDA's support for Atmega is crap. Atmel Studio kicks ass.
Time spent: few hours

#10 - shell.php

PHP challenge. Boring. It all boils down to obtaining the correct XOR key by making intelligent guesses on how the valid PHP code looks like. Repeat 4 times for extra boredom.
Time spent: few hours

#11 - covfefe.exe

It's a VM. It has one instruction. It self-modifies the code. Very nice! bigsmile I solved it by making dynamic disassembler/emulator in C#. Just after solving it, I learned about OISC and subleq in particular..
Time spent: 6-8 hours in total?

#12 - [missing]

This was probably my favorite CTF challenge ever. You get a PCAP and a malware binary. You must decode custom protocol malware uses to communicate with the bad guys and extract all the data from packets. Throw in some dynamic plugins for encryption, compression and commands and you get a whole lot of fun stuff to analyze. Awesome! bigsmile
Time spent: ~18 hours in total?

04 Oct

October update to Molebox unpacker

Thanks to my reader Max I have fixed another bug in the Molebox unpacker.

  • Removed memory leak that caused "out of memory" error when unpacking very large files (1.5GB+)

The usual request

I hope you find this unpacker useful. But if it doesn't work for you, please send me an error report with all the details you can and I'll try to fix it. Have fun!

Download link: https://www.mediafire.com/?pd555sk18yj3wl3
Alternative link: https://mega.nz/#!thYFDCCB!EO5-BQRr_idpJKXm6c_82YrcIEadpXCB7M_tC4cZ7nA

05 Sep

MSDN is sometimes wrong

While reversing a certain executable, I needed to figure out what data it sends over SSL/TLS. It's not using standard WinHttp functions but custom Schannel/SSPI implementation that's similar to CURL.

One of the steps in the process is to obtain SecurityFunctionTable using code like this:

And then you can use the obtained SECURITY_FUNCTION_TABLE to call different SSPI functions.

Sure, InitSecurityInterface and the SECURITY_FUNCTION_TABLE structure are described on MSDN (just the start of structure is shown for brevity):

So, I added the corresponding structure definition to IDA and tried to analyze the calls. It made no sense whatsoever.

What's happening here?

After some head scratching, I searched WDK for SECURITY_FUNCTION_TABLE definition. And here it is:

I wonder where the Reserved1 field has gone... wink

Fix the structure definition in IDA and magically all the calls make perfect sense:

Morale of the story - MSDN is great for quick reference but having a full Windows SDK/WDK installed is priceless.

Morale #2 - always carefully check IDA standard structures. Apparently, IDA doesn't have SECURITY_FUNCTION_TABLE defined - but it does have proper definition for SecurityFunctionTable.

22 Aug

Yet another update to Molebox unpacker

Thanks to my readers I have fixed few more bugs in the Molebox unpacker.

  • Better support for non-ASCII symbols in filenames
  • Very large (4GB+) files will now unpack correctly
  • Unpacker will extract embedded files packed with old versions of Molebox (like version 2.0570)

The usual request

I hope you find this unpacker useful. But if it doesn't work for you, please send me an error report with all the details you can and I'll try to fix it. Have fun!

Download link: removed. See October update to Molebox unpacker for an updated version

19 Aug

Use of syscall and sysenter in VMProtect 3.1

Few days ago Xjun briefly mentioned a new feature of VMProtect 3.1 - it uses direct syscalls to check if software is running under debugger. I decided to take a quick look myself and figure out how exactly it works.

I'll give you 2 targets for the research:

  • oppo_flash_tool.exe (https://mega.nz/#!ZgJzjQxR!cNEHMwM-jKnLVgPXf4OUupyk1DNt69FYB2rEfY-5AlA) - it was given as an example by Xjun;
  • asshurt.dll (https://mediafire.com/?3xyc0ugc2hxervn) - some sort of a cheat for Roblox. I don't care about the cheat itself, it just happened to have the syscall feature enabled. And it uses different syscalls than Oppo.

In addition to that, I'll provide a very simple demo executable which replicates part of the VMProtect protection, so that you don't waste time looking at obfuscated code.

As a debugger in 32-bit OS you can use anything you like. On 64-bit OS you will really need to use WinDbg - as far as I know, it's the only debugger that can handle those tricks..

32bit OS

Let's start by debugging oppo_flash_tool.exe. First, we need to get past the usual tricks like IsDebuggerPresent and CheckRemoteDebuggerPresent. If you're reading this, I'm sure you know how to do that.

Few moments later we'll arrive here:

Remember this conditional jump. It's taken on 32bit OSes and not taken on 64-bit OS.

Let's look at 32bit OS version first. Now VMProtect prepares to call sysenter.

Since the code is obfuscated, here comes a cleaned-up version. Please note that in other applications, different registers can be used.

64-bit OS

Here it is getting interesting! smile You cannot use sysenter instruction from 32-bit code in 64-bit Windows. But, as ReWolf described few years ago, one can mix x86 code with x64 code in the same process. And that's exactly what VMProtect 3.1 is doing.

Let's go back to that conditional jump and see what happens in 64-bit OS. The jump will not be taken:

Far call?! Last time I saw that was in 16-bit Windows era..

As explained in ReWolf's article:

Summing things up, for every process (x86 & x64) running on 64-bits Windows there are allocated two code segments:

  • cs = 0x23 -> x86 mode
  • cs = 0x33 -> x64 mode

So, as soon as you execute that call, you'll switch to a 64-bit world. WinDbg happily recognizes that, all other debuggers just go astray..

x64 code does pretty much the same thing as x86 code - sets up a stack frame, sets up registers and then executes syscall instruction. Cleaned-up and shortened version follows:

You'll notice that x64 version is slightly more complex due to the way parameters are passed (registers vs. stack). It also includes a special treatment for 8 special edge cases - it will modify syscall parameters to adjust buffers and pointer sizes to satisfy requirements for 64-bit code.

NOTE - to keep code simple, I only showed the part which deals with NtQueryInformationProcess but other cases are similar.

As you can see, return back from x64 to the x86 world is a simple retf instruction. x86 code continues right where it left off:

Instruction at address 0x00ddaeba is the same for both x86 and x64 OS-es and VM continues as usual.

Different protection modes and syscalls

I provided you with 2 real-world test executables. Oppo seems to be simpler and use just 3 syscalls:

  • NtQueryInformationProcess with ProcessDebugObjectHandle class
  • NtSetInformationThread with ThreadHideFromDebugger class
  • NtProtectVirtualMemory to set protection attributes for each section in original executable

Asshurt doesn't have antidebug trick with NtQueryInformationProcess but it uses additional syscalls for some purposes:

  • NtOpenFile
  • NtCreateSection
  • NtMapViewOfSection
  • NtQueryVirtualMemory
  • NtUnmapViewOfSection
  • NtClose

Suggested workaround

Since VMProtect is using undocumented Windows features, it somehow needs to ensure that the protection will work on each and every Windows version. That's VMProtect's biggest strength and also the biggest weakness.

Windows' syscall numbers change in each version and also between major builds. Use the wrong syscall number and you're guaranteed to receive unexpected results. So, VMProtect developers had to hardcode a table with Windows build numbers and corresponding syscall id's in the executable.

You can see the syscall numbers in the j00ru's page (slightly out of date) or in tinysec's windows kernel syscall table

To obtain Windows build number, VMProtect uses information from PEB (Process Environment Block). The method is already described in The MASM Forum, so I'll just reproduce the (ugly) code from their page:

VMProtect checks only the build number and picks the corresponding syscall number. However, if the build number is not in the internal database, it will not use direct syscall and fall back to standard protection. Bingo, problem solved - no need for ugly hacks like Xjun's SharpOD plugin!

Hint: VMProtect 3.1 doesn't support Windows 10 Creators Update (build number 15063).

Demo time

As promised, here is a download link for the test application: https://mediafire.com/?niqqbs0fqcq8n23
Note: it should support most common builds of Windows XP/7/8.1/10. Windows 2003/Vista and other rare systems are not supported!

If it shows "OK" message, you've hidden your debugger well. If it shows "Debugger detected", you have a problem. smile

Have fun!
kao.

EDIT: Updated download link for Oppo. Mediafire's antivirus tends to have plenty of False Positives..

20 Jul

Fix Backspace in Google Chrome

I've written about my fight with Google Chrome updates and broken features in the past. This time let's talk about the brain-dead decision to disable Backspace.

This was their rationale for the change:

We have UseCounters showing that 0.04% of page views navigate back via the backspace button and 0.005% of page views are after a form interaction. The latter are often cases where the user loses data. Years of user complaints have been enough that we think it's the right choice to change this given the degree of pain users feel by losing their data and because every platform
has another keyboard combination that navigates back.

So, just because 50 persons out of each 1'000'000 are f*king idiots, all the others have to suffer? Makes no sense to me.

To prove my point, let's look at the simple Google search: "Google Chrome backspace". It gives 238'000+ results. First few results are: "Backspace to go Back - Chrome Web Store", "Go Back With Backspace - Chrome Web Store", "Back to Backspace - Chrome Web Store", "How to restore the backspace key as a keyboard shortcut to go back in ...", "So where's the Chrome flag to RE-ENABLE BACKSPACE going back a...".

Apparently, I'm not the only one who is hurt by this change.

Hidden BackspaceGoesBack feature

When the change was first introduced in Google Chrome, developers also created a hidden feature that you could set and make Backspace work as it used to. To use it, you just need to launch chrome.exe with a command-line like this:

But in commit 0fe1505a this feature was removed as well.

If you enter the commit number in Chromium Find Releases tool, you'll see that in went out in public in v61.0.3116.0. Another check in Chrome Channel Releases tool will tell you that as of this moment the change is already out for both Canary and Dev channels, and will hit Beta and Stable channels in next months:

So, let's fix this issue for good! And by "fixing it" I don't mean some stupid JavaScript-based Chrome extension (which doesn't work when JavaScript is disabled and in hundreds of other cases..), I mean a proper fix in the code.

Patching Google Chrome again

If you've read my previous post, you know the drill. Set the symbol path, load chrome.dll in IDA, get yourself some coffee and wait. Wait a lot. And after 20-30 minutes you'll be able to start working.

This is the commit that's causing our headaches: commit 0fe1505a and the corresponding place in disassembly of Chrome 58:

What a mess!

Luckily for us, compiler decided to emit nice switch table in version v61.0.3153.2:

To make Backspace work as intended, we can simply overwrite 2 entries in jump table.

Mission accomplished! smile

In the next part of this blog series, I'll show you how to make this patch more user friendly and a few ways how to automate the patching (so that you can receive automatic Google Chrome updates, if you wish).

Till next time!
kao.

02 Jun

Enigma’s EP_CryptDecryptBuffer internals

For one of my private projects, I needed to decrypt some data. Original executable uses Enigma's EP_CryptDecryptBuffer function but I needed to implement the same thing using .NET. Much to my surprise, there was no information about what encryption algorithm is used by Enigma or how it works internally. So, I started by compiling Enigma's sample project CryptBuffer and debugging the executable.

TL;DR - IDEA cipher in CBC mode, password = MD5(user_password), IV for CBC comes from IDEA.Encrypt(8-zeroes, password).

Research

After protecting my executable with Enigma, few assembly lines

got changed into something horrible that looked like an Enigma's VM:

I didn't feel like spending my time on analyzing that. Much easier solution was to put hardware breakpoints on my data and password and wait for them to trigger. In a few seconds I landed into code that looked like MD5 (notice the constants!):

and few hits later I landed into code that I didn't recognize at first:

Delphi compiler had helpfully included RTTI information telling me that this second piece of code belongs to a class called TIdeaCipher. Now I had all the information I needed, I just had to put it all together. smile

Implementing decryption in C#

There aren't many IDEA implementations in C#. In fact, there are 2: by BouncyCastle and by LexBritvin. Since I'm not a big fan of huge and complex libraries like BouncyCastle, so I took the simplest possible code: from Github and modified it a bit.

First, we need change password generation algorithm to use MD5 to generate real password:

Second, we need to add support for CBC mode. It requires both calculating correct IV value and pre/post-processing each block we're encrypting or decrypting.

Calculating IV is quite simple:

Processing each block is slightly harder but not a rocket science either. As explained in image borrowed from Wikipedia:
.

Before decrypting the data block, we need to store the encrypted values as IV for the next block. After decrypting the block, we need to XOR each byte of data with a corresponding byte of IV. Unfortunately, during encryption the data flow is different, so the simple crypt function has to be replaced with 2 functions: encrypt and decrypt.

Few more cosmetic changes and that's it! We got clean and nice implementation of EP_CryptDecryptBuffer in pure C#. smile
Download link: https://bitbucket.org/kao/ep_cryptdecryptbuffer/

Have fun!

P.S. My implementation only supports cases where data length is divisible by 8, adding support for other lengths is left as an exercise for the reader.

12 May

VMProtect and dbghelp.dll bug in export processing

If your Olly is crashing when loading executable protected by VMProtect, you most likely have outdated dbghelp.dll somewhere on your path. Grab the latest version from Microsoft and put it in the Olly folder.

Well, that might be enough to work around the issue that I had - but I still wanted to know what's causing the crash.

Cause of the problem

If you try to debug Olly with another Olly, you'll see the Access Violation happening somewhere in dbghelp.dll:

Check register values in Olly:

For some reason, value in EDX is garbage and therefore access violation happens.

Call stack doesn't tell us much:

And same piece of code in IDA doesn't help much either:

So, it's debugging time! Set breakpoint to start of LoadExportSymbols, then set hardware breakpoint on write to address [ebp+ptrAllocatedMemory].

First hit is initialization of variable with 0:

Second hit stores the address of allocated memory:

And third time is a charm:

Good folks at Microsoft have left us with a nice buffer overflow. exportFunctionName is defined as byte array of size 2048 bytes. Any exported function name longer than that will cause stack overflow and (possibly) subsequent crash.

010Editor with PETemplate confirms that the export name is indeed very long (3100 chars):

From what I can tell, it's a similar (but not the same) bug to what was described by j00ru at http://j00ru.vexillium.org/?p=405 (see "PE Image Fuzzing (environment + process)")

Stay safe!

P.S Here's an example file, if you want to test your Olly: https://forum.tuts4you.com/topic/38963-vmprotect-professional-v-309-custom-protection/
P.P.S. CFF Explorer, HIEW and IDA do not show us any exports in this example file - but that's a matter of another story..