Improved static Enigma Virtual Box unpacker

kao

Last few weeks have been really hectic. I moved to a new apartment, so lots of time was spent on packing, unpacking, cleaning, and other non-computer related chores. Finally it's done, I got a great new place to live and I'm happy. πŸ™‚

To relax and get back into shape, I spent an evening with one of my old projects - Enigma Virtual Box unpacker. I fixed few little bugs and added support for x64 executables.

EnigmaVB unpacker

Get it here: Please get latest version from this post

When software is good enough

kao

Microsoft, Google and Apple make software for everybody. Millions of users run this software every day. It must be stable and user friendly, so that Aunt Judy and Average Farmer Joe can use it. If it crashes, clueless user can't do much about it - and that's bad. That's why these companies spend thousands of hours in testing and improving usablility.

On the other hand, reversers make tools. A specialized software for solving small and nasty problems, like hiding debugger, defeating specific protection or bypassing some authorization check. Tools are made by a reverser for a reverser, so there are completely different expectations for them. Nobody expects that today's DNGuard unpacker will work with next year's DNGuard binaries, or that DRM authors won't change their encryption mechanisms.

That's why reversers make tools that are just "good enough".

Olly, Confuser and de4dot

Funny thing happens when reversing tools suddenly become extremely popular. Newbies start using them, ordinary users start using them - and the expectations change. Suddenly the author is overwhelmed with extremely helpful "bug reports" like "cannot unpack latest reactor" or "obfuscation fails for my application". It's annoying, wastes reverser's time and is not helpful in any way. Therefore I totally understand 0xd4d's reaction:

There's no support. Don't email me if you can't use it or if it fails to deobfuscate a file obfuscated with an updated obfuscator.

Instead, try to update de4dot yourself. It's a lot easier than you think. If you can't, search the Internet and you should find a couple of forums where you can ask your question.

TitanHide is good enough

Earlier this month I made few posts about bugs in TitanHide. Are these real bugs? Yes. Is it important to fix them? Not really. Let's face it - there are literally dozens of ways to detect TitanHide. But until commercial protectors start doing that, nobody cares.

TitanHide works and does its job well - that's all that matters. πŸ™‚

The two bugs I mentioned earlier

First bug was a confusion about CONTEXT_DEBUG_REGISTERS flags. You see, CONTEXT_DEBUG_REGISTERS is defined as

#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7

which is quite unexpected. πŸ™‚ So, the code

OriginalContextFlags = Context->ContextFlags;
Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
...
NTSTATUS ret = Undocumented::NtSetContextThread(ThreadHandle, Context);

was accidentally removing CONTEXT_i386 flag from ContextFlags. Such call to should fail, I'm pretty sure it did fail in some cases in my VMWare, but in real world it works just fine.

Second bug is in checking if CONTEXT structure is writeable when calling SetThreadContext. Why should it be - SetThreadContext is only reading from it.. So, this pseudo-code lets you defeat TitanHide hardware breakpoint protection with ease:

CONTEXT cont = VirtualAlloc(0, sizeof(CONTEXT), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
cont.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread, &cont);
cont.Dr0 = 0x00401000;
cont.Dr7 = 0x000f0101;
VirtualProtect(&cont, sizeof(CONTEXT), PAGE_READONLY, &dummy);
SetThreadContext(hThread, &cont);

Again, it's a small bug, nobody is abusing it yet, so there is no real reason to fix it.

String decryption with de4dot

kao

Introduction

de4dot is a wonderful tool for deobfuscating known and unknown .NET protections. Dealing with known and supported protections is easy - drag&drop executable on de4dot and it will create deobfuscated assembly. Removing unknown protections is a little bit harder and requires supplying correct command-line parameters to de4dot.

In this article I'll show how de4dot can be used to deobfuscate strings in almost any .NET assembly, some undocumented features of de4dot, and a few bugs in de4dot too. πŸ™‚

Basics of string encryption/decryption

To show how string encryption works, let's start with a simple C# program.

Hint - you don't have to copy-paste all the code, sample files are available in the archive at the bottom of the post.

using System;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, world!");
            Console.Write("Please enter password: ");
            string pass = Console.ReadLine();
            if (pass == "secret")
            {
               Console.WriteLine("Password accepted");
            }
            else
            {
               Console.WriteLine("Bad password");
            }
            Console.ReadKey();
        }
    }
}

As you can see, all the strings are in the clear view and it's obvious that correct password is "secret". No protection whatsoever.

To slow down reversing efforts, obfuscators offer to encrypt user strings. They locate all strings in assembly, encode them somehow, and replace access to string with call to obfuscator code. To keep the code simple, I'll just encode all strings using Base64 - however, the same approach would work for almost any string encryption method (xor, Rijndael, or anything else).

New code looks like this:

using System;
using System.Text;

namespace Demo
{
    static class Obfuscator
    {
       static string[] hiddenStrings = {
         "SGVsbG8sIHdvcmxkIQ==",
         "UGxlYXNlIGVudGVyIHBhc3N3b3JkOiA=",
         "c2VjcmV0",
         "UGFzc3dvcmQgYWNjZXB0ZWQ=",
         "QmFkIHBhc3N3b3Jk"
       };

       public static string DecryptString(int index)
       {
          return Encoding.UTF8.GetString(Convert.FromBase64String(hiddenStrings[index]));
       }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Obfuscator.DecryptString(0));
            Console.Write(Obfuscator.DecryptString(1));
            string pass = Console.ReadLine();
            if (pass == Obfuscator.DecryptString(2))
            {
               Console.WriteLine(Obfuscator.DecryptString(3));
            }
            else
            {
               Console.WriteLine(Obfuscator.DecryptString(4));
            }
            Console.ReadKey();
        }
    }
}

No more obvious strings! πŸ™‚ Let's see how we can decrypt them using de4dot..

de4dot and basic string decryption

If you check de4dot help, you'll see that you need to supply 2 command line options for a string decryption to work. First, you need to choose a string decrypter type using --strtyp option: static, delegate, emulate. Then you need to tell de4dot which is string decrypter method using --strtok option.

Let's find which method is responsible for string decryption. Good decompiler can show method tokens, for example, SAE shows it as a tooltip, when you hover over the method:SAE method token

So, for our very basic protection we could run de4dot with commandline:

de4dot hello-2.exe --strtyp delegate --strtok 0x06000001

and the result will look like this:
decompiled cleaned file
So far, so good!

Advanced string decryption

But what happens if obfuscator uses more than one string decryptor? Let's change the code a little bit:

using System;
using System.Text;

namespace Demo
{
    static class Obfuscator
    {
       static string[] hiddenStrings = {
         "SGVsbG8sIHdvcmxkIQ==",
         "UGxlYXNlIGVudGVyIHBhc3N3b3JkOiA=",
         "c2VjcmV0",
         "UGFzc3dvcmQgYWNjZXB0ZWQ=",
         "QmFkIHBhc3N3b3Jk"
       };

       public static string DecryptStringA(int key)
       {
          return Encoding.UTF8.GetString(Convert.FromBase64String(hiddenStrings[key ^ 0x666]));
       }

       public static string DecryptStringB(int key)
       {
          return Encoding.UTF8.GetString(Convert.FromBase64String(hiddenStrings[key + 0xDEAD]));
       }

       public static string DecryptStringC(int key)
       {
          return Encoding.UTF8.GetString(Convert.FromBase64String(hiddenStrings[key - 0xC0DE]));
       }

    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Obfuscator.DecryptStringC(0xC0DE));
            Console.Write(Obfuscator.DecryptStringA(0x667));
            string pass = Console.ReadLine();
            if (pass == Obfuscator.DecryptStringB(-57003))
            {
               Console.WriteLine(Obfuscator.DecryptStringA(0x665));
            }
            else
            {
               Console.WriteLine(Obfuscator.DecryptStringC(0xC0E2));
            }
            Console.ReadKey();
        }
    }
}

Now there are 3 methods that decrypt strings, and each of them is slightly different. Of course you could run de4dot 3 times, but it's just a pain-in-the-butt.

de4dot help doesn't tell you this, but it is possible to to specify more than one string decryption method:

de4dot hello-3.exe --strtyp delegate --strtok 0x06000001 --strtok 0x06000002 --strtok 0x06000003

This is a little bit awkward, but works.

But what to do if there are hundreds of methods - specifying each of them by token is time-consuming and command-line might get too long.

de4dot has solution for that too. Hidden in the middle of help file, is this little gem:

--strtok METHOD String decrypter method token or [type::][name][(args,...)]

It turns out that you can tell de4dot the name of obfuscator class/methods responsible for string decryption and it will resolve tokens automatically. πŸ™‚

So, the following command-lines will work:

  •  
    de4dot hello-2.exe --strtyp delegate --strtok "Demo.Obfuscator::DecryptString"

    This tells de4dot that string decryptor is method with full name Demo.Obfuscator::DecryptString.

  •  
    de4dot hello-3.exe --strtyp delegate --strtok "Demo.Obfuscator::"

    This tells de4dot to check all methods in class Demo.Obfuscator and pick the ones which look like string decryptors.

  •  
    de4dot hello-3.exe --strtyp delegate --strtok "Demo.Obfuscator::(System.Int32)"

    This tells de4dot which class to look at and what kind of parameters string decryption method has.

  •  
    de4dot hello-3.exe --strtyp delegate --strtok "::DecryptStringA"

    This tells de4dot to look at all classes for a method called DecryptStringA and use that as string decryptor.

If you want to know more about possible options and the combinations, I suggest that you look at de4dot source code, file de4dot.code\ObfuscatedFile.cs, lines 454-511.

You said something about bugs?

Ok, ok, there are few issues here.. It still works 99% of the time, so no complaining!

First bug is in the checking of string decryptor parameters. When I said that --strtok "Demo.Obfuscator::(System.Int32)" will select only methods that take Int32 as a parameter, I lied. πŸ™‚

Look at the source:

for (int i = 0; i < argsStrings.Length; i++) {
   if (argsStrings[i] != sig.Params[i].FullName)
      continue;
}

The continue instruction here does nothing, it just goes on to check next parameter. I guess 0xd4d wanted to stop evaluating this method and go to next one, but got it wrong.

Second bug is in selecting string decryptors - you cannot select a method which takes no parameters. Sample code showing this type of protection is in hello-4.cs (see below).

Look again at the source:

if (argsStrings == null) {
    if (sig.Params.Count == 0)
        continue;
else {
    if (argsStrings.Length != sig.Params.Count)
        continue;
}

If you don't supply hints about parameters, then methods with 0 parameters will be ignored because of 2nd if. If you do supply hints - then no method with 0 parameters can pass the 3rd if.

Fixing these 2 bugs is left as an exercise to the reader.

Conclusion

In this article explained how to use de4dot to decrypt strings in any .NET assembly, including some lesser known options. Hope this helps you next time you encounter .NET protection that's not directly supported by de4dot. πŸ™‚

All sample files and their source code: https://www.mediafire.com/?2kwnf7d7vre4uv8

Why you should not worry about HARES

kao

Last week Wired published an article about HARES - Hardened Anti-Reverse Engineering System. The article is really great example of what happens when some idiot starts to write about things he has no clue about.

I wanted to write a full-length post about that, but Errata Security beat me to it. So, please enjoy this great writeup instead. πŸ™‚ Thank you, guys!

So, can HARES be used in malware?

Wired article states that:

[HARES] could also mean the start of a new era of well-armored criminal or espionage malware that resists any attempt to determine its purpose, figure out who wrote it, or develop protections against it.

First, HARES requires a hypervisor. If the attacker had ability install hypervisor on your system, you were screwed anyway. This also means that 99.999% of today's malware won't be able to take advantage of HARES.

Second, modern antimalware solutions do not need to analyze code. They can analyze behavior of the process, monitor network connections, registry changes, file system changes - and that's enough for a successful detection. HARES doesn't interfere with that.

You can go to sleep peacefully tonight, the world is still spinning and no magical malware is going to appear overnight.

Further reading

HARES FAQ
PDF: MoRE Shadow Walker: TLB-splitting on Modern x86
Youtube video: Virtualization: MoRE Shadow Walker The Progression of TLB Splitting on x86
PAGEEXEC and TLB Splitting

Rapidshare is closing. And nothing of value was lost.

kao

As reported by Neowin, Rapidshare customers today are greeted with the message:
rapidshare_closing_notice

Which makes me wonder - was anyone still using Rapidshare? Really?

From my experience, their service was really crappy for last 3 years. Files were quickly deleted "due to inactivity" and free download speeds reminded me good old times with 56kbps modem.

Alexa's Traffic Rank seems to agree:
Rapidshare popularity graph

R.I.P. Rapidshare. All hail Mediafire, MEGA or Oboom.

Freeware scam artists. And some real morons.

kao

If you spend any time playing with malware, or just downloading software, you've probably seen those kinds of scams.

Take some free software, wrap it in Nullsoft Installer, add a few toolbar and "system optimizer" softwares to the bundle, make the installation dialog as confusing as possible and get commissions for each install.

It usually looks something like this:
uniblue

The reason why it works - people are stupid. They just click "Next", "Next", "Next", "Finish" and think it's gonna be alright. Sorry grandma - you just made somebody a few bucks richer!

These types of installers are usually detected as Adware or PUAs (Potentially Unwanted Programs) by most antivirus companies. The criteria for detection are really simple - if your installation dialog is designed to confuse Average Farmer Joe, you should be detected. You may not hide "Decline" button, you may not try to blend it into background, it must be clearly visible and accessible.

And now look at Elementary OS

Having said that, just look at the new and improved download page for ElementaryOS - freeware, open-source operating system:
elementaryos_download_dialog
Can you see the free download button? Neither can I. Because it's not there!

You have to explicitly click on "$ Custom", enter "0" there, and then click "Download".

Huh? Come again, please?

Apparently, someone at Elementary OS thinks it's a great feature:

We’ve opted to present users with some easy one-button choices. Right now we have ambitious $10, $25, and $50 buttons along with a β€œCustom” button that lets you type anythingβ€”including $0.
...
We didn’t exclude a $0 button to deceive you; we believe our software really is worth something.

You, sir, are a fucking moron.

I need adblocker for my.. TV!

kao

I really, truly, absolutely hate ads on webpages. Any device I have has some sort of adblocking solution installed. As it turns out, some marketing "geniuses" are going to take these annoyances to the next level. Let's see how..

Ads on your Smart TV.

Oh, this is real! πŸ™‚

As reported by CNET, GigaOM and several other news websites, Samsung SmartTVs suddenly started interrupting your TV experience and showing ads.

Every movie I play, 20-30 minutes in it plays the Pepsi ad, no audio but crisp clear ad. It has happened on 6 movies today,.

Pepsi, of all things!

Luckily, the problem was limited to Australia, and is already "resolved". πŸ™‚ But don't you worry, they will try again for sure!

Just a reminder, same Samsung SmartTVs did similar stunt a year ago.
samsung

Back then, it was possible to get rid of ads by opting-out of some obscure Yahoo crap:

To opt-out of Yahoo Broadcast Interactivity, Exit Smart Hub first, press Menu on your Samsung Remote and scroll to Smart Hub > Terms & Policy > Yahoo Privacy Policy. Scroll to β€œI disagree with the Yahoo Privacy Notice.” and you can toggle the option on to opt-out.

And Panasonic did the same thing 2 years ago..
panasonic
In that case, you could opt out of it by going to Menu > Setup > Display customization > Viera Connect Banner > Off.

Ads when making phone call

As reported by The Register, some companies would like you to listen to advertisements when you are making a phone call. And you can even "express product interest by pressing an action key"!

Right. While you're at it, don't forget add 10$/month fee for ad-free calling.

Luckily for us, this "product" hasn't been deployed on any mobile network so far. At least, not on the networks I know.

Conclusion

Welcome to the new world! You're paying us good money, but we'll still try make more money off of you..

Writing good drivers is really hard, part 2

kao

Mr. eXoDia was very quick in fixing the bug I described few days ago.. That's a great work! πŸ™‚

This is part of his new code:

...
if (IsHidden)
{
	Log("[TITANHIDE] NtSetContextThread by %d\n", pid);
	__try
	{
		ProbeForWrite(&Context->ContextFlags, sizeof(ULONG), 1);
		OriginalContextFlags = Context->ContextFlags;
		Context->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS;
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		return Undocumented::NtSetContextThread(ThreadHandle, Context);
	}
}
NTSTATUS ret = Undocumented::NtSetContextThread(ThreadHandle, Context);
...

There are 2 bugs hiding in this short snippet, can you spot them?

Hints

Bug #1 is old and breaks the functionality of SetContextThread. It's much easier to spot it in disassembly than in source code.
Bug #2 makes it easy to bypass TitanHide. It was introduced in this commit.

Let the analysis begin! I'm waiting for your comments.. πŸ™‚

.NET exception “The remote certificate is invalid”

kao

For one project I needed to make a simple tool that fetches file from webserver via HTTPS connection. Sounds easy, right?

There are plenty of ways of doing things, but to keep it simple, lets ignore error handling, timeouts, authorization and other features:

HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create({url_here});
HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
... process response ...

It should work, right?

And yes, it works most of the time. For example, it fetches page from https://google.com/ without any problems.

But for some sites it mysteriously crashes with exception:

Error: System.Net.WebException: The underlying connection was closed: 
Could not establish trust relationship for the SSL/TLS secure channel. ---> 
System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

Cause of the error

It turns out that sites that are using self-signed, expired and otherwise bad certificates will cause this exception. How nice from .NET devs - they're trying to protect me! Well, no, because I still need to download that information!

Solution

I found lots of solutions of the web - and quite a few of them failed. Some of them are .NET 4.5 only, some of them are overly complicated class consisting of 20+ lines. I need something simple, that works everywhere from .NET 2.0 up and is actually readable!

This one works for me: put this line before doing any HTTPS requests:

ServicePointManager.ServerCertificateValidationCallback += delegate {return true;};

It effectively suppresses all certificate validation errors. Problem solved!

Example site for testing your code: https://www.pcwebshop.co.uk/

Excuse the mess

kao

My host (bplaced) seems to be having issues with the server where this page is being hosted. I opened a ticket, but their support is taking its sweet time to respond. πŸ™ So, if you're seeing 30+ second page load times, I really apologize for that.

Also, I'm still learning how to use WordPress in the most efficient way. So, if RSS feeds get broken or some other f*ckup happens - I apologize for that too. And please let me know if you're experiencing any issues with the site.