08 Jun 2015

Analyzing malicious LNK file

Last week I noticed a month-old post from F-Secure titled "Janicab Hides Behind Undocumented LNK Functionality" in my RSS Reader. I had starred it but never had time to read and analyze it thoroughly. Post title and their statement caught my attention:

But the most interesting part is the use of an undocumented method for hiding the command line argument string from Windows Explorer.

What is this undocumented functionality you're talking about? Tell me more! Unfortunately, they didn't provide any technical details just some screenshots.

I'm gonna fix that (and have some fun in process) smile

Initial findings and available tools (are crap)

Armed with information from FSecure's post, I started Googling. In a few minutes I found VirusTotal scan and a couple of searches later the LNK file itself. Now what?

I'm not a LNK file expert and I don't have magic tools for analyzing them. So, I did what everyone else would - Googled again. There are 3 tools that can be found easily:

All of these tools showed the same information as VirusTotal scan - absolutely nothing useful. See for yourself in screenshots:
lnk_template_original

Marked in blue is the final structure of LNK file, as per 010Editor Template. COMMAND_LINE_ARGUMENTS are empty. And it looks like malware authors somehow managed to put the real command-line "/c copy *.jpg.lnk..." outside the defined structures, right? How's that possible?

So, I got an official Shell Link (.LNK) Binary File Format specification by Microsoft and started reading.

Fixing 010Editor template

LNK file consists of sequence of structures of variable size. There's always size of the structure, followed by data. Right after it there's a next size and next data. Size, data, size, data.. It's very easy to process, just look at the size, read the appropriate number of bytes, process them. Repeat until done. How hard is that?

Yet, Mr. Stevens (proudly calling himself Microsoft MVP Consumer Security, CISSP, GSSP-C, MCSD .NET, MCSE/Security, MCITP Windows Server 2008, RHCT, CCNP Security, OSWP) managed to mess up his template.

lol

His implementation of LinkInfo structure looks like this:

He just reads all the fields one after another and expects that the length of all the fields will be equal to the size of structure (LinkInfoSize). Sure, it might work on "normal" LNK files but we're dealing with malware and intentionally modified files here. wink

After fixing that and few more bugs in the template, I was able to see the proper structure of this LNK file:
lnk_template_fixed_overview
Command-line passed to cmd.exe is exactly where it should be, so why is Windows Explorer having problems with it?

Modifications in LNK file

Well, let's look at the file in more details.

lnk_template_lots_of_zeros_1
Looks like someone took a hex editor and just filled with zeroes every possible field in most of ItemID structures.

lnk_template_lots_of_zeros_2
Same in LinkInfo, lots of zeroes.

lnk_template_lots_of_zeros_3
And in EnvironmentDataBlock too..

lnk_template_lots_of_zeros_4
Hmm, this is interesting, 0xA0000000 is not a defined ExtraData structure ID according to MS spec.

Well, there are lots of changes but which one(-s) are causing the Explorer cockup F-Secure is mentioning? There are two ways to find it - debugging Windows Explorer shell, or making a test LNK file and filling it with zeroes until Explorer breaks. First one would be fun, but second one will be definitely faster. wink

After few attempts, I found the culprit: it's the modified EnvironmentDataBlock.

So, now you know. Adding empty EnvironmentDataBlock to any shortcut and setting ShellLinkHeader.LinkFlags.HasExpString = 1 will cause Windows Explorer to hide your command-line (but not exe name) from the user. twisted

Command line magic and steganography

I wanted to finish my analysis but some things were still bugging me.
lnk_template_extra_data
What are these data after the end-of-file marker? And why is this LNK file 500+KB in size?

The answer is simple - it's using steganography to hide malicious VBScript inside.

Let's look at the commands passed to cmd.exe, I'll just prettify them a bit. To do it properly, you need to know about command prompt escape characters, like "^" (at first I didn't and FSecure got it wrong in their blogpost, too! wink ). These are the actual commands:

First few lines are copying our LNK file to TEMP folder. Remember, FSecure analysis says that LNK file was originally called fotomama.jpg.lnk. wink
dir command is printing full filename of our evil file into another file named "o".
echo lines are generating file .bat.
And finally .bat is executed.

So, what is being written into .bat?

First 2 lines just copy our evil file to z9. I really don't know why file copy is done via environment variables, maybe it's some sort of anti-antivirus trick to hide the malware origin.
findstr treats z9 as text file and copies all "lines" of text that contain "#@~" into a file 1.vbe. If you Google a bit, you'll learn that encrypted VBScript files have extension .vbe, consist of one long string and start with magic bytes "#@~^"".
Then a script gets executed, LNK file deleted and stupid user ends up being pwned. smile

Now, the bytes after end-of-file marker in LNK file start to make sense. 0x0A is new-line that's necessary for findstr, and then comes encrypted VBScript. Nice example of steganography, lots of black command-prompt scripting magic, I really like it! wink

Decoding VBE file and analyzing it - that's a matter of another blog post. Yes, it's really on my todo list.

Fixed LNK Template

I spent few more evenings working on the LNK template. It was just bugging me, to have something so useful, yet so terribly broken. So, I'm happy to present a fully reworked version that should be much more stable and able to deal with malicious LNK files in much better fashion.

Download link: https://www.mediafire.com/?zvrlmjy9v9m3ed3

Final thoughts

This was a fun evening project. I learned a lot about 010Editor Binary Templates, learned something new about LNK files and got a refresher course in CMD scripting and steganography. Writing this post took much much more time than the actual research, though.

If you want to have some fun too, you can use my 010Editor Template to edit your LNK files. Or make a simple tool in C#. Or create a LNK obfuscation service webpage in PHP. Possibilities are endless! smile

Obviously I won't give out link to an actual malware (if Google is your friend, you can find it anyway) but here's a demo LNK file I put together just for fun: http://www.mediafire.com/?gmphyn0mkmmyuag

It's harmless, trust me! bigsmile

Useful links

FSecure post that started my adventure
Original LNK Template
Official LNK specification by Microsoft
Overview of LNK file data that are useful for computer forensics

27 May 2015

Static Enigma Virtual Box unpacker, part 2

Here comes a new version. smile This time I added support for unpacking external packages. "External packages" are data files that can be loaded by Enigma Virtual Box and can contain both embedded files and registry entries.

I also made my unpacker 100% Unicode-aware - there should not be any more problems with non-english filenames. But I had to switch to Delphi 2009 compiler to do this, so there might be some unexpected bugs lurking around.

And, of course, lots of internal bugs had to be fixed. My code is not perfect, you know! wink

EnigmaVB Unpacker v0.30

Download link: Please get latest version from this post

P.S. Thanks to Manofwar for giving me few example files for development & testing!

19 May 2015

Static linking of Bassmod in Delphi

BASS and BASSMOD are very well known freeware libraries for playing XM, IT, WAV and many more sound file formats. They are widely used in keygens and other apps. However, authors only distribute them in a DLL form, there is no LIB file or any other option for linking them statically.

Last week someone resurrected an old thread at Tuts4You and asked how to convert DLL to LIB and link it statically with Delphi. I gave poster the standard answer but he was still running in all sorts of issues. So, can it be done?

Then answer is - yes. But it's not easy.

Note - This article is written for good old Delphi 6/7/2007. Since Delphi XE2 the process should be easier as the linker was improved to use COFF OBJ files directly. However, I don't have those new Delphi versions, so I can't test the claims.

Steps to be taken

I'll make a list of all necessary steps first and then I'll discuss them in details.

  1. Unpack the DLL properly
  2. Convert DLL to LIB
  3. Extract OBJ files from LIB
  4. Convert COFF OBJ files to OMF OBJ files
  5. Make those OMF files usable by Delphi
  6. Write a wrapper unit that works around Delphi limitations

Unpack the DLL properly

First step sounds easy, right? It isn't.

The LIB provided in Tuts4you thread is badly unpacked. Sure, it can work when compiled with MASM. It can be made work with Delphi, but you'll need to hex-edit compiled EXE file first. The reason for this is extremely primitive Delphi compiler/linker. You have no control over PE section names or attributes. It relies on specific section names and always makes code section read-only. But the LIB from tuts4you uses one segment for both code and data and it must have read-write-execute characteristics. Ooops.

So, we need to unpack DLL ourselves using all the standard steps. PE packer is a very simple one, so you can easily find OEP, dump the file, load DLL at different imagebase, find the OEP and make a 2nd dump, use 2 dumps to fix the relocations using Relox and finally restore Import Table using Scylla or ImpRec. Nothing new here.

Once you've unpacked the DLL, you will have to detect section boundaries and create new PE section table. When you're at OEP of bass.dll, check the memory map in some process exploring tool. You'll see the sections and their characteristics nicely:
BASS memory map in PETools

Now use any PE editor to create appropriate PE section headers:
Section headers in CFF
To make Delphi happy, code section should be named _TEXT and data section should be named _DATA. All the sections you don't need in final OBJ file, should be named ".reloc", ".edata" or similar - Dll2lib will remove them automatically.

Convert DLL to LIB

Well, this step is easy. Use DLL2LIB (google "DLL.To.Lib.v1.42.Full.Retail-DLL2Lib" or get trial version from official site), leave all the default settings and press "Start convert".

Dll2lib

Extract OBJ files from LIB

For next few steps you'll need objconv.exe by Agner Fog. It's better to download the latest version, as earlier versions didn't support extracting LIB files.

It's a simple command objconv.exe -lx bass.lib

Convert COFF OBJ files to OMF OBJ files

That's also simple. Just run objconv.exe -fomf bass.obj bass-omf.obj

Make those OMF files usable by Delphi

Delphi imposes quite a few limitations to OBJ file format. Some of them are documented, some of them aren't. So, it's better to rely on special tools made for this purpose, like omf2d.exe by EliCZ.

I'm sure that objconv.exe can do the same, but I'm too lazy to try to figure the right command line parameters. So, just run omd2f.exe bassmod-omf.obj bassmod-omf-d.obj

Note - omd2d.exe will mess up some decorated names from msvcrt.dll, like "??2@YAPAXI@Z". That's not a problem, we'll fix that in the wrapper unit.

Write a wrapper unit that works around Delphi limitations

This is also tough. And again the problems are caused by the primitive Delphi compiler/linker.

Delphi doesn't support direct API calls, all API calls will go through the thunk table. When you try to reference any external API from Delphi code, in reality you'll get address of the thunk code.

For the same reason in Delphi you can't access exported global variables from another DLL.

Unfortunately BASS/BASSMOD uses both direct API calls and global variables from msvcrt.dll. Little bit of clever hacking is required to work around that - you'll have to load msvcrt and other DLLs from unit initialization code and use GetProcAddress to get the required addresses.

So, the implementation part of the unit will look like this:

In addition to that we need to call the original DllMain function to make sure that BASS is initialized properly:

As a final touch, in the finalization part of unit we'll have to call DllMain again to make sure all resources are freed properly.

Putting it all together

I already outlined all the steps needed. Anyone with proper skills should be able to replicate them and make his/her own BASS unit.

For those who are lazy - here is the package with Delphi units+obj files + all the intermediate files + compiled projects from BASS/BASSMOD examples to show that it really works.

Have fun!

Useful links

Unpacking DLLs #1: Tutorial by Mr. eXodia
Unpacking DLLs #2: How to use Relox in few simple steps
Omf2d: https://www.mediafire.com/?hsksyjwnwlaw3zb

11 May 2015

Improving Meltdown

More than 2 years ago I released Meltdown. It's a proof-of-concept tool that showed several security issues in Faronics DeepFreeze products. Faronics are infamous for their attempts to hide the issues, so I was really curious how it will work out.

Bugs in my code

First, a few bugs in my code surfaced. None of them were in the core components dealing with DeepFreeze, I had that part tested thoroughly. But I overlooked issues with UAC, possibility that Windows are not installed on drive C:\, empty passwords and other edge cases.

All in all, it was a good learning experience.

Requests for source code

The very first version of Meltdown came with a full source code and explanation of the vulnerabilities in Faronics products. Once I started fixing bugs, I released only the updated binary. Yet quite a few people kept asking for the updated source.

To be honest, I have no idea why. So far, I haven't seen a single tool that would be based on my source code, not even a straightforward rip with a changed name and copyrights. Weird..

Bug reports

People reported bugs. Big bugs, small bugs, non-bugs and everything in between.

Most bug reports came from arabic-speaking guys. Some of them even didn't bother to use Google Translate and wrote in their native language. No, I really don't speak Arabic, German, French or Indonesian.

Also, most bug reports came without any actionable information whatsoever. Just "It doesn't work". Well, that's not helpful at all! I really want to help you, but you must tell me more than that. In later versions, I added information to main window about detected OS, 32/64bits, detected DF version, etc, etc. And then I can just ask for a screenshot, it contains most of the info I need to replicate the issue.

It was a good learning experience again. I learned how to make my tools more user-proof.

Faronics response

For a year, there was none.

Then in June 2014 they released DeepFreeze Enterprise 8.11 where the issue was fixed. At least the changelog says so:

7936 Resolved a security issue that could result in the user accessing Deep Freeze without authorization.

Yeah, right.. In reality they just added yet-another-layer of xor-encryption and removed useful data from frzstate2k.exe. But the same data are still present in dfserv.exe.

Wow, that's what I call "resolving a security issue"! smile

In September 2014 they released DeepFreeze Standard 8.10 where the other vulnerability was fixed. However, there was no mention of anything like that in the changelog. From a quick glance, it looks like they finally got their code right and aren't sending xor-encrypted password from driver to usermode anymore.

What now?

I'm presenting you an updated version of Meltdown.

Meltdown v1.5
It shows that vulnerabilities in Enterprise version are still present, just slightly more obfuscated. But security through obscurity does not work!

The glaring vulnerability in Standard version is fixed, and 8.x Standard versions seem to be safe. Funny, isn't it - you'd expect a corporate product to provide better security than home-edition, yet this is not the case.. smile

Download link for Meltdown v1.5: http://www.mediafire.com/?0wc0vv1kauhwxbb

23 Mar 2015

.NET, ScyllaHide and HEAP_CREATE_ENABLE_EXECUTE

While doing some research on ILProtector, I loaded my test executable in Olly. To much of my surprise, it refused to run and all I could see in Olly log, was this:

Something smells fishy! wink

I disabled all non-standard plugins, and I was still getting the exception. It was only after I removed the remaining 2 plugins (ScyllaHide and ODBGScript) that my test application launched. Few more restarts and I was sure that ScyllaHide is the one causing the trouble.

OK, I've found a bug in ScyllaHide. But where is it? Which option is causing it? And how can I fix it?

Unfortunately, there is no easy way. Just go through one option after another, until you trigger the bug. 10 minutes and 100 rude words later I was sure that "HeapFlags" is the culprit.

A side note from Captain Obvious

If you're seeing access violation in Olly and want to know where it's happening, make sure you uncheck Ignore Memory access violation in Debugging Options:
olly debugging options
and then run your target:
crash on jit stub
Here we can see that there is a real code at this address - small stub calling mscorwks.dll and that the call comes from ILProtector's protect32.dll.

It immediately gives you plenty of useful information about what's happening. Unfortunately I debugged one instance of Olly from another instance of Olly - got the same results but it took me much longer.

Meet HEAP_CREATE_ENABLE_EXECUTE

It turns out that .NET Runtime Execution Engine (mscoreei.dll) loves to put executable code on heap:

but ScyllaHide prefers to mark all heaps as non-executable:

and these 2 options kinda conflict with each other. smile

Workaround & fix

This small bug can be used to detect ScyllaHide, as it's enabled by default in all configurations, and tooltip explicitly suggests to leave it as-is:

Very important option, a lot of protectors check for this value.

Here is a suggested patch:

If you don't want to recompile the entire Scylla, here's the binary patch for the official ScyllaHideOlly1.dll from ScyllaHide_v1.3fix_Olly1.rar package:

As a simple workaround, you could uncheck "HeapFlags" in ScyllaHide when debugging .NET applications. However, I would really suggest to fix ScyllaHide instead.

Have fun and keep it safe!

05 Mar 2015

Improved static Enigma Virtual Box unpacker

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. smile

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

31 Jan 2015

Improved CFF Explorer

CFF Explorer is another invaluable tool for .NET reversers. Unfortunately it is closed-source and is not actively maintained anymore.

One of the most annoying problems is that it cannot correctly process .NET metadata in some assemblies protected by ConfuserEx (and few other protectors).
CFF shows garbage
As you can see, Module data make no sense and Methods also look weird.

Cause of the problem

The problem is caused by obscure and undocumented field in Metadata Table Stream. DNLib is one of the very few tools/libraries that properly supports it:

This extraData field is causing us troubles.. Oh, well, it's time to fix it! smile

Solution

Since CFF Explorer is closed-source, I had to reverse-engineer parts of it. Then I created a small code cave and added extra code that checks flag value and skips over extraData field, if necessary. If you're interested how exactly it was done, check address 004689CC and added code at 00589800.

CFF works fine
Much better, isn't it?

Download link for patched EXE: Please get latest version from this post

29 Jan 2015

Improved dotNET Tracer

dotNET Tracer is a great tool created by my friend Kurapica. It provides information really useful for analyzing different .NET protections, like which modules are being loaded, which functions are being JIT-compiled, and so on.
DotNET Tracer main window

Unfortunately, it is missing some features and has some small bugs. For example, DisguiserNET.Sample.GUI unpackme by li0nsar3c00l (another friend of mine!) detects dotNET tracer and refuses to run:

Disguiser detects dotNET Tracer

Cause of the problem

It's actually quite simple. dotNET Tracer is using .NET CLR Profiling APIs to gather the information. To do that, it needs to set several environment variables, as you can see in the Form_Main.cs:

After profiling dll (system.dll) is initialized, it resets first 2 environment variables, but forgot to reset the 3rd one. Disguiser detects presence of that variable and crashes. Oops.

Solution

After spending some time on both tracer and the unpackme, I'm happy to present a fixed version of dotNET Tracer. So far I have improved:

  1. Created workaround for li0n's anti-profiler trick;
  2. Added logging of "Module load finished" events. This prints imagebase for loaded DLLs and thus makes dumping resources from memory easier;
  3. When you close dotNET Tracer, traced process will be killed automatically.

Disguiser runningjust fine
Now I can spend more time on the unpackme.. smile

Download link for binaries: http://www.mediafire.com/?8zfaukefx39i32n
I respect Kurapica's wishes and therefore source code will not be made available.