• About Me
  • Blog
  • Home

Eric Hokanson

~ E's little space in cyberspace

Eric Hokanson

Monthly Archives: January 2014

ESET Challenge Part 4

26 Sunday Jan 2014

Posted by Eric Hokanson in Cyber Security Research, Malware RE

≈ 2 Comments

Tags

ESET ChallengeME 2013, ESET CrakMe 2013 Challenge, Malware Analysis, Malware Reverse Engineering

My continuing adventures in the ESET 2013 CrackMe Challenge

Last time, we discovered that the crack_me_2.zip binary contains two BMP resources, and one of those resources were extracted and dropped into one of my temporary directories.  This “BMP” was actually an executable:

crack_me_2_dotnet_eastereggUpon double-clicking it displays a cute little photo.  We also learned that the executable to the left was not just any executable but a .NET executable and an obfuscated one at that.

crack_me_2_dotnet_decompiled

The strings all appear to be encrypted with some sort of byte array scheme. Classes and functions are all labeled with only the letters A through F in upper and lowercase.

However, even though this executable is obfuscated, we did see an indication that this rabbit bitmap is actually a pipe-server.  The pipe server that our crack_me_2 binary was searching for.  Upon first running the crack_me_2, we didn’t have a pipe-server running so the function returned a -1.  Crack_me_2 then proceeded to create the .tmp

crack_me_2_named_pipefile that resulted in the “Easter Egg” pipe-server .NET file.  Below is the disassembled code confirming our named pipe “Vincent_Vega” server:

easter_egg_pip_server

And the code that creates the pipe:

ester_egg_pipe2

To disassemble a .NET file you may use ILSpy or .NET Reflector.  I used both.  Started with ILSpy to statically study the Easter Egg and Reflector for debugging (dynamic analysis).

Upon re-starting crack_me_2 with this Easter Egg pipe server running, I set a break point on CreateFileW and instead of EAX = -1, EAX = 0x2C so we got a handle to our named pipe.  Now that a pipe server is running, the program skips all the instructions to create its .tmp Easter Egg file and jumps to here:

hamberger_messgae

We see another base 64 encoded string:

base64_royale_with_cheese

With the pipe-server running, the pipe sends the message “Le Big Mac”, and then compares that with our “Royale with Cheese”:

hamburger_message2

In the above screen shot, on the right, you can see the current state of the registers.  EAX contains the string “Le Big Mac”, while ESI holds “Royale with Cheese”.  These two registers are compared.  If they were equal, the Hamburger message box would appear with the message: “Hamburgers.  The cornerstone of any nutritious breakfast.”   The Pulp Fiction theme continues as the hamburger message is another quote delivered by Jules (Played by Samuel L. Jackson) in the film’s diner scene.  Since the messages do not match, no dialog box will be displayed.  However, we can hack the code, change our “Royale with Cheese” to “Le Big Mac” if we wanted to display the message.

Either way, hamburger message or no, when we continue to single-step, the program now takes us to:

loading_malcho_dll

Another set of base64 encoded strings.  They translate to:

base64_malcho_dll

base64_malcho_dll_function

So crack_me_2 is going to attempt to load a MALCHO.DLL that exports a base64 encoded function that gets a password.

It looks as though, once MALCHO.DLL is loaded, crack_me_2 will extract a password from the Easter Egg pipe server.  This password will then be used to in the following:

gets_decrypts_resource_133

The function call at 0x404A71 is going to extract the second BMP resource in crack_me_2’s resource section. The parameter of 0x85 = 133 in base 10 and we see thanks to PE Explorer that the 133 is the second BMP’s resource ID.

crack_me_2_resources_BMPs

All that is missing is the first parameter — the password that this so-called MALCHO.DLL is supposed to retrieve for us.  But where is this dll?  I have to admit that this stymied me for a few days.  I searched up and down the code looking for this MALCHO.DLL.  I even tried googling for it.  No hits for the dll, but there were links to reports that contained the name, Juraj Malcho, head of — you guessed it — ESET’s Virus Laboratory.  Could he be the author???  I was wondering about the dll’s name because I did not see any reference to a Malcho in Pulp Fiction.

After a couple of days searching to no avail, I decided to ask the Reverse Engineering Malware Research group on linkedIn (my thanks to Mr. Mahmoudnia) for some hints.  It turns out that there is no MALCHO.DLL; I have to make my own MALCHO.DLL.  They key is in the .NET Easter Egg binary.

To help me better understand this .NET Easter Egg, I used a tool called DeReactor to deobfuscate this .NET file.

After setting up the named pipe-server, most of the action appears to be here:

deobfuscated_dynamic_routine

deobfuscated_dynamic_routine_part2

The deobfuscated file calls it method_8() in Class_06; its called Method A of Class D in the obfuscated file.  This took me a while to figure out what was going on here.  It turns out that this Easter Egg .Net creates threads that dynamically — and it is one of three routines that does this (the whole chunk of code is below; feel free to scroll past all that).

protected void A([In] List<byte> obj0)
{
Encoding.ASCII.GetString(obj0.ToArray(), 1, obj0.Count - 1);
}

protected void B()
{
string str1 = string.Format(.d(), (object) null, (object) null);
string str2 = string.Format(.E(), (object) null, (object) null);
string str3;
lock (D.A)
str3 = !this.a ? str2 : str1;
this.A.A(str3);
}

private void b()
{
this.A.Add((object) new G((object) OpCodes.Ldc_I4, (object) (this.A & (int) byte.MaxValue), (object) .e()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4, (object) (this.a & (int) byte.MaxValue), (object) .F()));
this.A.Add((object) new G((object) OpCodes.Xor, (object) null, (object) .f()));
}

private void A([In] object obj0)
{
try
{
Thread thread = obj0 as Thread;
if (thread == null)
{
thread = new Thread(new ParameterizedThreadStart(this.A));
thread.IsBackground = true;
thread.Start((object) Thread.CurrentThread);
this.a = this.A(MethodBase.GetCurrentMethod());
this.a.Set();
Thread.Sleep(500);
}
while (!this.A)
{
if (Debugger.IsAttached || Debugger.IsLogging())
this.a();
if (!thread.IsAlive)
this.a();
Thread.Sleep(1000);
}
lock (D.B)
{
if (--this.B != 0)
return;
this.B.WaitOne();
this.A.A.WaitOne();
this.A.Set();
}
}
catch (Exception ex)
{
}
}

private int A([In] MethodBase obj0)
{
byte[] ilAsByteArray = obj0.GetMethodBody().GetILAsByteArray();
int num1 = 0;
foreach (byte num2 in ilAsByteArray)
num1 += (int) num2;
return num1;
}

protected void C()
{
this.A.Add((object) new G((object) OpCodes.Ldarg_1, (object) null, (object) .G()));
this.A.Add((object) new G((object) OpCodes.Ldloc_0, (object) null, (object) .g()));
this.A.Add((object) new G((object) OpCodes.Ldloc_2, (object) null, (object) .H()));
this.A.Add((object) new G((object) OpCodes.Ldarg_0, (object) null, (object) .h()));
this.A.Add((object) new G((object) OpCodes.Nop, (object) null, (object) .I()));
this.A.Add((object) new G((object) OpCodes.Ldloc_2, (object) null, (object) .i()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_1, (object) null, (object) .J()));
this.A.Add((object) new G((object) OpCodes.Add, (object) null, (object) .j()));
this.A.Add((object) new G((object) OpCodes.Stloc_2, (object) null, (object) .K()));
this.A.Add((object) new G((object) OpCodes.Ldlen, (object) null, (object) .k()));
this.A.Add((object) new G((object) OpCodes.Conv_I4, (object) null, (object) .L()));
this.A.Add((object) new G((object) OpCodes.Nop, (object) null, (object) .l()));
this.A.Add((object) new G((object) OpCodes.Ldarg_0, (object) null, (object) .M()));
this.A.Add((object) new G((object) OpCodes.Ldloc_2, (object) null, (object) .m()));
this.A.Add((object) new G((object) OpCodes.Ldelem_U1, (object) null, (object) .N()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_0, (object) null, (object) .n()));
this.A.Add((object) new G((object) OpCodes.Stloc_3, (object) null, (object) .O()));
this.A.Add((object) new G((object) OpCodes.Ldloc_1, (object) null, (object) .o()));
this.A.Add((object) new G((object) OpCodes.Ldloc_0, (object) null, (object) .P()));
this.A.Add((object) new G((object) OpCodes.Sub, (object) null, (object) .p()));
this.A.Add((object) new G((object) OpCodes.Add, (object) null, (object) .Q()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_0, (object) null, (object) .q()));
this.A.Add((object) new G((object) OpCodes.Stloc_0, (object) null, (object) .R()));
this.A.Add((object) new G((object) OpCodes.Stloc_0, (object) null, (object) .r()));
this.A.Add((object) new G((object) OpCodes.Ldloc_0, (object) null, (object) .S()));
this.A.Add((object) new G((object) OpCodes.Ldarg_1, (object) null, (object) .s()));
this.A.Add((object) new G((object) OpCodes.Ldlen, (object) null, (object) .T()));
this.A.Add((object) new G((object) OpCodes.Conv_I4, (object) null, (object) .t()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_1, (object) null, (object) .U()));
this.A.Add((object) new G((object) OpCodes.Sub, (object) null, (object) .u()));
this.A.Add((object) new G((object) OpCodes.Ceq, (object) null, (object) .V()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_0, (object) null, (object) .v()));
this.A.Add((object) new G((object) OpCodes.Ceq, (object) null, (object) .W()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_1, (object) null, (object) .w()));
this.A.Add((object) new G((object) OpCodes.Stloc_3, (object) null, (object) .X()));
this.A.Add((object) new G((object) OpCodes.Stloc_S, (object) 4, (object) .x()));
this.A.Add((object) new G((object) OpCodes.Ldloc_S, (object) 4, (object) .Y()));
this.A.Add((object) new G((object) OpCodes.Clt, (object) null, (object) .y()));
this.A.Add((object) new G((object) OpCodes.Stloc_S, (object) 4, (object) .Z()));
this.A.Add((object) new G((object) OpCodes.Ldloc_S, (object) 4, (object) .z()));
this.A.Add((object) new G((object) OpCodes.Ldelem_U1, (object) null, (object) .aA()));
this.A.Add((object) new G((object) OpCodes.Ceq, (object) null, (object) .aa()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_0, (object) null, (object) .aB()));
this.A.Add((object) new G((object) OpCodes.Ceq, (object) null, (object) .ab()));
this.A.Add((object) new G((object) OpCodes.Nop, (object) null, (object) .aC()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_0, (object) null, (object) .ac()));
this.A.Add((object) new G((object) OpCodes.Stloc_0, (object) null, (object) .aD()));
this.A.Add((object) new G((object) OpCodes.Stloc_1, (object) null, (object) .ad()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_0, (object) null, (object) .aE()));
this.A.Add((object) new G((object) OpCodes.Stloc_2, (object) null, (object) .ae()));
this.A.Add((object) new G((object) OpCodes.Stloc_S, (object) 4, (object) .aF()));
this.A.Add((object) new G((object) OpCodes.Nop, (object) null, (object) .af()));
this.A.Add((object) new G((object) OpCodes.Ldloc_S, (object) 4, (object) .aG()));
this.A.Add((object) new G((object) OpCodes.Nop, (object) null, (object) .ag()));
this.b();
this.A.Add((object) new G((object) OpCodes.Ldloc_0, (object) null, (object) .aH()));
this.A.Add((object) new G((object) OpCodes.Ldc_I4_1, (object) null, (object) .ah()));
}

protected void c()
{
this.A = new DynamicMethod(.aI(), typeof (bool), new Type[2]
{
typeof (byte[]),
typeof (byte[])
}, typeof (D).Module);
ILGenerator ilGenerator = this.A.GetILGenerator();
ilGenerator.DeclareLocal(typeof (int), true);
ilGenerator.DeclareLocal(typeof (int), true);
ilGenerator.DeclareLocal(typeof (int), true);
ilGenerator.DeclareLocal(typeof (bool), true);
ilGenerator.DeclareLocal(typeof (bool), true);
Label label1 = ilGenerator.DefineLabel();
Label label2 = ilGenerator.DefineLabel();
Label label3 = ilGenerator.DefineLabel();
Label label4 = ilGenerator.DefineLabel();
Label label5 = ilGenerator.DefineLabel();
Label label6 = ilGenerator.DefineLabel();
this.A.Add((object) new G((object) OpCodes.Brtrue_S, (object) label2, (object) .ai()));
this.A.Add((object) new G((object) OpCodes.Br_S, (object) label1, (object) .aJ()));
this.A.Add((object) new G((object) label6, (object) null, (object) .aj()));
this.A.Add((object) new G((object) OpCodes.Brtrue_S, (object) label3, (object) .aK()));
this.A.Add((object) new G((object) OpCodes.Br_S, (object) label4, (object) .ak()));
this.A.Add((object) new G((object) label3, (object) null, (object) .aL()));
this.A.Add((object) new G((object) OpCodes.Br_S, (object) label5, (object) .al()));
this.A.Add((object) new G((object) label2, (object) null, (object) .aM()));
this.A.Add((object) new G((object) label5, (object) null, (object) .am()));
this.A.Add((object) new G((object) label1, (object) null, (object) .aN()));
this.A.Add((object) new G((object) OpCodes.Brtrue_S, (object) label6, (object) .an()));
this.A.Add((object) new G((object) OpCodes.Br_S, (object) label4, (object) .aO()));
this.A.Add((object) new G((object) label4, (object) null, (object) .ao()));
this.A.Add((object) new G((object) OpCodes.Ldloc_3, (object) null, (object) .aP()));
this.A.Add((object) new G((object) OpCodes.Xor, (object) null, (object) .ap()));
this.A.Add((object) new G((object) OpCodes.Ret, (object) null, (object) .aQ()));
this.A.Sort();
foreach (G g in this.A)
{
if (g.A is OpCode)
{
if (g.a != null)
{
if (g.a is byte)
ilGenerator.Emit((OpCode) g.A, (byte) g.a);
else if (g.a is int)
{
ilGenerator.Emit((OpCode) g.A, (int) g.a);
}
else
{
if (!(g.a is Label))
throw new Exception(.aq());
ilGenerator.Emit((OpCode) g.A, (Label) g.a);
}
}
else
ilGenerator.Emit((OpCode) g.A);
}
else if (g.A is Label)
ilGenerator.MarkLabel((Label) g.A);
}
this.A = (D.e<bool, byte[], byte[]>) this.A.CreateDelegate(typeof (D.e<bool, byte[], byte[]>));
}

To make analyzing this Easter Egg a challenge, these methods are generating MSIL opcodes on the fly and in a “randomish” order.  Note the this.A.Sort() after all those this.A.Add(…) statements.  To better understand what is going on, we will need to run it in Reflector’s Visual Studio debugger plugin.  But first we will have to deal with:

dotNet_anti_debugging

Its checking if we are running the Easter Egg program in a debugger or if we are running any logging tools, if so the program basically does nothing.  So I used Reflector to edit out that snippet, “re-compile” it and set a break point after the this.A.Sort() routine.  Then I dumped out the IL (Intermediate Language) evaluation stack and here is what I got (I put in the comments):

L_000000000: Nop
L_000000010: Ldc.I4.0
L_000000020: Stloc.0
L_000000030: Ldc.I4,88 	//Load value 88 
L_000000031: Ldc.I4,254 //Load value 254 
L_000000032: Xor  	// Xor: 88 xor 254 = 166
L_000000080: Stloc.1	// store the value 166
L_000000090: Ldc.I4.0
L_0000000A0: Stloc.2
L_0000000B0: br.s label
L_0000000CF: label6
L_0000000D0: Nop
L_0000000E0: Ldarg.0	//Load the byte[] array
L_0000000F0: Ldloc.2 	//Load local2 
L_000000100: Ldelem.U1	//Take one byte from byte[] array with index at 
			//local2
L_000000110: Ldloc.1 	//
L_000000120: Ldloc.0
L_000000130: Sub	//local1 - local2
L_000000140: xor	//(local1 - local2) Xor byte[]
L_000000150: Ldarg.1
L_000000160: Ldloc.0
L_000000170: Ldelem.U1
L_000000180: Ceq
L_0000001A0: Ldc.I4.0
L_0000001B0: Ceq
L_0000001D0: Stloc.S,4
L_0000001F0: Ldloc.S,4
L_000000210: brtrue.s label2
L_000000230: Nop
L_000000240: ldloc.0
L_000000250: ldc.i4.1
L_000000260: Add
L_000000270: Stloc.0
L_000000280: Ldloc.0
L_000000290: Ldarg.1
L_0000002A0: Ldlen
L_0000002B0: Conv.I4
L_0000002C0: Ldc.I4.1
L_0000002D0: Sub
L_0000002E0: Ceq
L_000000300: Ldc.I4.0
L_000000310: Ceq
L_000000330: Stloc.S,4
L_000000350: Ldloc.S,4
L_000000370: brtrue.s label3
L_000000390: Ldc_I4.1
L_0000003A0: Stloc.3
L_0000003B0: Br.s label4
L_0000003CF: label3
L_0000003D0: Nop
L_0000003E0: br.s label5
L_0000003FF: label2
L_000000400: Ldc_I4.0
L_000000410: Stloc.0
L_000000420: Nop
L_000000430: Ldloc.2
L_000000440: Ldc_I4.1
L_000000450: Add
L_000000460: Stloc.2
L_000000470: Ldloc.2
L_000000480: Ldarg.0
L_000000490: Ldlen
L_0000004A0: Conv.I4
L_00000041F: label5
L_00000046F: label
L_0000004B0: Clt
L_0000004D0: Stloc_S,4
L_0000004F0: Ldloc_S,4
L_000000510: brtrue.s label6
L_000000530: Ldc_I4_0
L_000000540: Stloc_3
L_000000550: br.s label4
L_00000056F: label4
L_000000570: ldloc.3
L_000000580: Ret

It looks like this is part of a decryption routine.  In C, it would look something like:

for(int i = 0; i < byteArray.length; i++)
{
    byteArray[i] = (byteArray[i] ^ (166 - i));
}

And what is the byte array? If we examine the original obfuscated start of our routine, we see that there is one byteArray passed in as an argument:

byte_array_screen_shot

and the only byte[] member in Class D contains:

byte_array_contents

which if you run in our psuedo decryption algorithm above, transforms those numbers in the byte array to the ASCII codes that produces the string:

/ download/bmV4dF9maWxl/cGEkJHdk.txt

That looks like a URL. Now this is starting to make sense! In the following:

enumerating_windows_screenshot

My guess is that the above chunk enumerates searching for Internet Explorer and sends the decrypted URL.  If we append our decrypted URL to ESET’s URL:

http://www.joineset.com/download/bmV4dF9maWxl/cGEkJHdk.txt

then click on the link, the site contains:

Jules:You read the bible, Ringo?

So this must be the password that our MALCHO.DLL must retrieve for us to use as the decryption key to the second BMP resource. So now its off to Visual Studio to create a simple MALCHO.DLL:

malcho_dll_code

It simply returns the password as a string.  Also I changed the function name since the base64 encoded name had an equals sign in it.  At first I used the base64 name but the compiler freaked out.  I forgot that you can’t use an ‘=’ in variable names or function names.  The ‘=’ sign is an assignment operator and it confuses the compiler.  So after we load our MALCHO.DLL, we can simply change the function name to getPassord in OllyDbg before we allow the program to call GetProcAddress:

loading_malcho_dll

changing_malcho_function_name

And it loaded!

getPassword_worked

Continuing to step through the program:

gets_decrypts_resource_133

crack_me_2 has now extracted and decrypt the resource 133 BMP and is going to drop it as 2B0.tmp.  I let the Olly run the program to completion and grabbed our new file.  I tried changing the extension to .exe to run it but that did not work.  I tried loading it in PE Explorer but it told me that 2B0 was not a legitimate PE file so I loaded 2B0 into HexWorkshop:

2B0_tmp_is_a_java_class_file

I recognized the magic bytes: CAFEBABE.  This is a java class file.  A java class file called Bible.  And you can see the print statement strings containing the most famous quote in the movie Pulp Fiction:

all_easter_eggs_found

So it seems that we have found all the Easter eggs.  Is that all there is?  I don’t know for sure.  There are still parts of the crack_me_2 code that I have not examined in complete detail.  I did see calls to some registry querying and other registry functions.  Additionally, I found some other anti-debugging checks later in the code, and some of the code doesn’t disassemble correctly; Olly thinks its a bunch of character bytes.  If there is nothing more than why would someone go to all the bother of calling Windows registry functions, add and occlude more code if not to have it do something.  I speak from experience that programmers are generally lazy.  I don’t mean that as a derogatory remark.  Programmers purposely do not add any functionality to a program that will never be used.  Suffice it to say, there may be more to this saga.  After all, I have not tried to put any other Pulp Fiction quotes other than “I did it!” in the second textbox of the starting dialog box.  We could attempt to try all possible Pulp Fiction quotes but there are a lot of them and I could spend the rest of my natural life trying them all.  And since I am lazy I am not going to do that.

Whenever I have some spare time, I will continue to poke around.  If I find anything new, I will post those results here.

Oh God Please Don’t Let it Be the Columbia Mall…

26 Sunday Jan 2014

Posted by Eric Hokanson in Current Events, Random Stuff

≈ Leave a comment

Tags

Columbia Mall, Maryland mall, The Mall in Columbia

… were the first words out of my mouth when the USA Today notification flashed upon my iPhone screen alerting me to a “shooting at a Maryland mall.”  I used to frequent the Mall in Columbia when I lived in the area.  I still have many friends that live nearby and I hoped none of them got caught up in the melee.  All are ok as far as I know.

I occasionally still visit while on travel for work.  I sometimes swing by the Columbia mall to get my Teavana fix.  Until recently Albuquerque didn’t have a store.  There is a deli in the food court that makes the best potato salad and hand-made sandwiches; there is also a good sushi restaurant across from the mall that I still frequent (the name of it escapes me at the moment).

I remember one December Monday morning.  I woke up at 0430 to get ready to go to work.  I looked out the window and it was snowing fiercely.  Really coming down.  An inch had already stuck to the ground so I called the hotline to see if I had to report for duty; nope.  Non-essentials did not have to report (it is one of the few times a person is glad to be called a non-essential employee).  After sleeping in, at 10:00 the sun came out and melted all evidence that there even was a snow storm.  With a sudden free day, I decided to take advantage of it and finish my Christmas shopping at the Columbia mall.  I was not the only one with that idea; I bumped into my supervisor — and later — several co-workers.  The day turned into a beautiful sunny mid-morning and we felt as if we were playing “hooky.”

As you can see, I have a lot of fond memories of my time at the Columbia mall.  Not once did the thought or feeling ever occur to me, that some one could be packing and decide to whip it out causing chaos and harm.  The only annoyance I ever encountered was having to dodge the rows of cell phone and cell phone accessory kiosks.  Being hounded to show my phone, my service plan, promising they could give me a better contract, or giving me “a special 10% discount” if I showed my employers special access badge.  That is the only horror anyone should have to endure at any mall.  Well, the cell phone kiosk thing, and dodging packs of hyper-texting pre-teen girls who apparently just discovered makeup and decided to apply all of it in one application.

Gallery

Make Your Own Motivational/Demotivational Posters.

20 Monday Jan 2014

Posted by Eric Hokanson in Random Stuff

≈ Leave a comment

Tags

Big Huge Labs, Demotivational Posters, motivational posters

This gallery contains 9 photos.

I discovered a new way to fritter my time away.  Making fake motivational posters.  Here are a few of my …

Continue reading →

ESET Challenge Part 3

18 Saturday Jan 2014

Posted by Eric Hokanson in Malware RE

≈ 2 Comments

Tags

ESET CrakMe 2013 Challenge, Malware Reverse Engineering

My continuing saga tackling the ESET 2013 challenge

In part one and part two, we unpacked and coaxed the ESET CrackMe 1 puzzle into revealing its hidden messages, which led us to a second puzzle called crack_me_2.zip.

crack_me_2.zip is an actual executable because you can see the ‘MZ’ header in a hex editor.  If we examine the sample using the strings command:

crack_me_2_strings

We can see it is packed.  Claims to be UPX but is it?  According to PEiD, it claims “Nothing Found” but there is some overlay.

crack_me_2_peid

Using PEiD’s extra information plug-in, we can examine the EP and the Entropy of the code section.  Entropy is pretty high, indicating that this sample is packed with something.  It turns out, that you can use the same unpacking technique that we did in part one.  However, I needed to use LordPE to rebuild the unpacked and repaired crack_me_2 sample to get it to run.  When the unpacking process was done and we run our unpacked sample we get:

crack_me_diagog_greyedtextbox

Note that the text boxes for Stage 1 and Stage 2 are greyed out.  I can not enter any text in them, nor can I click on any of the “check” buttons.  The only thing I can click on is the red X button in the upper right hand corner of the CrackMe dialog box.

This perplexed me for a while.  I wasn’t sure if I unpacked this sample correctly so I executed the packed crack_me_2.zip and got the same dialog box as above with the inactive text boxes and check buttons.  Perhaps examining the code in OllyDbg will yeild insights into how I might activate the text boxes:

crack_me_2_first_dialog_box_clue

I couldn’t find any sign of how to activate the text boxes but I did find clues as to what to put in the text boxes.  In the above screen shot, you will observe that we should enter the text: “Pigs are filthy animals”.  When we hit the check button, it compares our entry with String2 and if they match, it activates the next text box.

crack_me_2_second_dialogbox_clue

As you can see above, the second text box clue is obsured.  That ASCII string “SSBkaWQgaXQh” looks like a base64 encoding.  We can test this by entering that string in a tool called base64 encoder/decoder (my version is older so it looks different than the one at the link):

crack_me_2_second_textbox_clue

Lucky guess.  I wasn’t sure it was base64 because this encoding did not have the tell tale ‘==’ at the end of the string.  We know what to enter in the text boxes but I still haven’t found any clues as to how to enable these text boxes.

I was still stumped after a few hours.  I decided to try the crack_me_2 sample on my old Windows XP laptop and you know something?  It worked!  The first text box was enabled and I could enter text.  Next I tried the sample on a Windows 7 machine and that, too worked.   Stage 1’s text box was enabled.  I suddenly realized that the difference between those machines and my analysis machine, was that my analysis platform was running inside VMWare.  This sample wouldn’t be VM aware would it and try some anti-VM tricks?  So I found this white paper from SANS on Thwarting VM analysis.  Then I set to searching for OP Codes in Olly that looked for a VM presence.

For example, I thought I would start with a simple anti-VM trick outlined in that SANS paper:

MOV EAX,564D5868 <--"VMXh"
MOV EBX,0
MOV ECX,0A
MOV EDX,5658 <-- "VX"
IN EAX,DX <-- Check for VMWare
CMP EBX,564D5868

I used Olly’s search trying the first MOV instruction.  No hits.  Then I tried the second instruction.  No hits.  It wasn’t until the last instruction, the CMP instruction that I got a hit:

crack_me_2_anti_vm1

By the way, the hexidecimal 0x564D5868 in ASCII is: “VMXh”.  You can see the CMP instruction but not the others.  But you do notice the CHARs VX and VMXh just above the CMP instruction.  It appears that this sample has some anti-disassemble techniques that fool Olly’s ability, in selected parts of the code, to distinguish between data bytes and actual OP codes.  To be sure and avoid the anti-debugging tricks, I activated the Advanced Olly plug in to hide itself from these anti-debugging techniques.

We can highlight these so called data bytes and then right-click, select Analyze, and then Remove Analysis from Selection:

crack_me_2_anti_vm2

By removing Olly’s analysis, the code is revealed and it looks just like one of the tricks mentioned in the SANS white paper.  If we highlight the top instruction and hit F4 (Run to here), then single step past the MOV EAX, 564D5868, we can simply change EAX to something else — like 0.  When we do that:

crack_me_textboxes_work_on_vm

It works!  Well almost.  After entering the correct text we get a “Nope you didn’t” notice.  If you click the OK button, the program just sits there until you hit the red X button and terminate the program.  Argh!  All that work… well, that is the life of a malware analyst.  We will often go after something interesting only to discover that it may lead us astray.  We are going to have to search the code and look for something else of interest.

When you first load crack_me_2 into Olly, it stops at this starting point:

crack_me_2_named_pipe

This program calls CreateFileW and looks for a named pipe called Vincent_Vega.  Since there is no pipe server by that name running, CreateFileW will return a -1.  So I set a break point on CreateFileW and hit F9 to run the program.  When the execution stopped at CreateFileW, I noticed in the stack trace something about a 990.tmp file.crack_me_2_create_990_tmp_file

Looks like this thing will create a .tmp file in my Local Settings\Temp directory.  By the way, each run of crack_me_2 will create a different named .tmp file.  Usually, the names are simple like 2C.tmp, 4C.tmp, etc.  Upon this running, it is calling mine 990.tmp:

crack_me_2_going_to_create_990_tmp_file

This program is going to create a 990.tmp file.  Earlier in the code, I noticed some function calls for getting resources.  If we examine crack_me_2 in PExplorer:

crack_me_2_resources_BMPs

We can see that crack_me_2 has two bitmap resources.  What do you bet that these resources are something MORE than bitmap files?

crack_me_2_going_to_create_990_tmp_file

At 0x404983, we see this function is going to take the resource bitmap ID 0x83 = 131 in decimal, and decrypt it with the key: “T2ggbWFuLEkgc2hvdCBNYXJ2aW4gaW4gdGhlIGZhY2U=”
That looks like base64 encoding:crack_me_2_decryption_key_for_990_tmp

And yes it is!  By the way, I am starting to detect a theme here.  The named pipe is “Vincent Vega” a character played by John Travolta in the film “Pulp Fiction“.  The phrase we put in the Stage 1 text box: “Pigs are filthy animals” is a quote from one of the scenes when Vince asked Jules (played by Samuel L Jackson) if he wanted some bacon.  The key to decrypt our 990.tmp file is another quote from the movie.

If we continue to let this run and let it drop the 990.tmp file, then open it in a hex editor we see that it is supposedly an executable (has an MZ header).  Next, I renamed 990.tmp to 990.exe and double click on it, I discovered that it is a .NET executable because I was told to install .NET Framework 4 in order to run it.  Once that was done:

crack_me_2_dotnet_easteregg

How cute.  Ok, maybe it was a bitmap resource.  However, the picture of a bunny rabbit and a little Easter egg icon in the upper left corner suggests its time to go on an Easter egg hunt.  This .NET file may do more than just display a cute picture.  There is just one small challenge ahead for me: I am pretty weak with reversing .NET executable files in that I have, until today, zero experience.  I am going to have to do some research.

But first, I tried disassembling the Easter egg in IDA Pro and it can handle .NET files, however, it looked gibberish.  No strings to examine and weird function names.  Soon, I discovered that there are open source .NET decompilers like ILSpy.

crack_me_2_dotnet_decompiled

I am not sure how to make heads or tails of the above.  Class names of a, A, b, B, c, etc.  Variable names were not much help either.  However, just by happen chance, I decompiled the class a() and the result is in the left panel above.  This looks like something that sets up a pipe server named Vincent Vega.  My guess is that if we run this .NET Easter egg, it creates the named pipe that our crack_me_2 file was looking for.  The next step, then, is to run this Easter egg and re-run crack_me_2 to see what messages may be passed through this pipe.  I will also need to analyze this Easter egg .NET file further for clues as to where to take my analysis.  I am unsure yet so I have some studying to do.  The challenge continues…

ESET Challenge Part 2

10 Friday Jan 2014

Posted by Eric Hokanson in Malware RE

≈ 4 Comments

Tags

ESET ChallengeME 2013, Malware Analysis, Malware Reverse Engineering, Reverse Engineering, Reverse Engineering Puzzles

In part one of the ESET CrackMe 2013 challenge, we:

  • Did some initial triaging and string analysis in order to try and deduce what the sample may do.
  • We discovered that it was packed using a UPX packer.
  • We unpacked the sample by hand using OllyDbg and ImportRec.
  • Then analyzed the strings of our unpacked sample to see if we could now determine this samples potential capabilities.

Today, we are going to test our theory by actually running and debugging the EsteCrackMe3013 sample.  Remember from part one, we did observe some indications of anti-debugging in our string analysis, so it is likely that we will have to try to circumvent those.

First, let’s load our unpacked CrackMe sample into IDA Pro and let it take us to the starting point of the program.  A little ways down you can see a series of MOV instructions.  This is a long block of move instructions, starting at 0x404679 and ending at 0x407A63:

Screen Shot 1

These look like ASCII characters and if we highlight each character in IDA and hit the ‘r’ key, it will reveal the actual character:

Screen Shot 2

This looks like it might be the message we see printed to the console that we see when we first run the program:

crackme_firs_run

I see an asterisk, some characters, and lots and lots of spaces.  I could be hitting the ‘r’ key all day, and it appears that these characters are being loaded “randomly” into random locations.  Perhaps they are scrambling the start up message to make static analysis harder.  If we set a break point in IDA after all these MOV instructions, then highlight on of the move instructions, right click and jump in a new hex window, we can see:

Screen Shot 3

Screen Shot 4

And that is exactly what all those MOV instructions are doing.  Moving the “scrambled” start up message into memory.  It also explains why we were seeing lots of spaces.

At the end of the MOV instructions, if scroll down, we see calls to SetConsoleCursorPositon, SetConsoleTitle, and WriteConsole.  This is the part of the code that retrieves the start up message lines from memory and prints them to the screen.  Once we scroll past the routines that print the start message to the console, that is where things start getting interesting:

Screen Shot 5

After writing the start up message to the console, the program immediately calls a subroutine located at 0x402998.  This routine checks if we hit the ‘Enter’ key to continue.  Once we hit the enter key, the program calls the subroutine on the next line.  At first, I thought this was a TLS callback because I saw evidence of TlsIndex, and calls to TlsGetValue.  There appears to be a place for a callback function.  However, after hitting CTL-E in IDA, the only starting point I saw was the program’s starting point.  I did not see evidence of a TlsCallbackEntry point.  I did not spend too much time investigating this subroutine, but, whether a callback is called or not, it appears that the program makes calls to non-returnable functions.  These functions eventually cause the program to wend its way to a FreeLibrary call and then eventually to an ExitProcess call.  My guess is, that during the normal flow of the program, we call this routine and eventually terminate the program.  This subroutine, however, does not prevent us from stepping over this function during a debug session.  But if we do, notice that the program loads some value from location 0x40810C, and then calls OutPutDebugString.  What do you bet, EAX contains that ‘s%s%s%s%s%s%s…” string sequence we saw in our string analysis in part one?

Screen Shot 6

Sure enough, that is exactly what EAX contains.  So, if we step over subroutine sub_40256C, and get to location 0x407BD92, then the program knows it must be in a debugger.  It attempts to leverage an old OllyDbg vulnerability that will crash Olly.  We can change EAX to 0 to get past that issue, or use a newer version of Olly, or IDA’s debugger.

After surviving our first anti-debugging trick, we now see that there are calls to LoadLibrary, but we don’t know the library’s name because it is disguised at offset dword_407F18:

Screen Shot 7

I suspect, the authors are trying to hide the name of the library loaded.  If we highlight, and hit the ‘a’ key, IDA will resolve the above array of numbers to an ASCII string:

Screen Shot 8

We do this to all the obfuscated library names, and we can begin to see clearly what is being loaded:

Screen Shot 2014-01-10 at 11.56.24 AM

URLMON and WININET libraries, functions for checking for Internet connections, and to download a file from some location.  We also see strings for IsDebuggerPresent and scrolling down a little further we also calls to GetTickCount, and checks to the file segment fs:18h.  These are all known techniques for checking to see if the program is in a debugger.  If it is, the program can simply terminate the process leaving us high and dry.

Screen Shot 2014-01-10 at 12.00.39 PM

We will need to deal with these anti-debugging techniques.  Before we start debugging, lets continue our static analysis and scroll down to find some other interesting things such as:

Screen Shot 2014-01-10 at 12.05.07 PM

I am not sure what that is.  Junk code?  The hexidecimal digits look like ASCII symbols.  If we highlight and press the ‘r’ key:

Screen Shot 2014-01-10 at 12.10.16 PM

Interesting!  A key of some sort?  Scrolling further down, there are more checks for debugging and calls to GetTickCount, and jumps to ExitProcess if a debugger is detected.  But eventually, we arrive to a series of code blocks that call WriteConsole.  What other messages are there?  Our next goal is to start the debugger, and when ever we come to a check for a debugger, change the jump value in the control flags to avoid ending the process.  Lets see if we can get to these WriteConsole calls and see what these messages are.

After a couple of attempts, I finally get to the first WriteConsole call and we see the message:

Screen Shot 2014-01-10 at 12.44.42 PM

Continuing, stepping through to the next WriteConsole call, we get our second message:

Screen Shot 2014-01-10 at 12.48.02 PM

We continue stepping through to the third call to WriteConsole, and our third hidden message is revealed:

Screen Shot 2014-01-10 at 12.52.21 PM

Looks like there is a second leg to our quest!  Ok.  We got pretty far today.  It may be a good idea to re-run this program in our debugger, just like we did above, but this time run procmon and fakenet to see if this program did anything else behind the scenes such as write to the registry, and download any files.

This was a lot of fun and I learned some new tricks in IDA Pro that will be useful in my new position as a malware analyst and researcher.  The next step is to visit the site, and get the second part of the challenge, and repeat the process.  But that we will have to do another day.

New Year Same Old Run-A-Round

09 Thursday Jan 2014

Posted by Eric Hokanson in Holidaze

≈ Leave a comment

Tags

Exercise, Gym Membership, New Year, Resolutions, Running, Treadmill

crowded-gym

New Years resolution season means long lines for treadmills at my fitness club.  While waiting, I realized that I was not the only one who broke last year’s New Years resolution, got fat, and made a new New Years resolution to go back to the gym.

Sometimes the circle of life IS a treadmill.

ESET 2013 Challenge

08 Wednesday Jan 2014

Posted by Eric Hokanson in Malware RE, Uncategorized

≈ 3 Comments

Tags

ESET ChallengeME 2013, Malware Analysis, Malware Reverse Engineering

UPDATE 20160114:  The links to the ESET ChallengeMe 2013 sample are now outdated.  I have attached the samples to this post and you can get them here: Crackmes.  Password: eset.  Enjoy!

E

==============================

I was introduced to ESET’s ChallengeMe 2013 by Yashar Mahmoudnia, a member of the Reverse Engineering Malware Research group on LinkedIn.   You can download the challenge here. Before reading the solution, I wanted to try my hand at the challenge and brush up on my skills.  Then I can compare my results to see how I did.   I am half-way through the challenge and here is what I have learned so far.

Step one:  Triage analysis

When you first run the program you get:

crackme_firs_run

When you hit enter it quits.   Next, I ran the sample through a strings program:

crackme_strings

Not very many human readable strings.  Looks like a bunch of garbage.  This is an indication of packing or encryption.  I used a tool called PEiD to try to identify the packer.  At first under normal scan, PEiD said it found nothing. So I tried the deepscan:

crackme_peid

Packed with UPX.

step two: unpacking

We could try the program upx -d to unpack, however, I am going to unpack it by hand.  I am going to use OllyDbg to load the program, step (F7) past the PUSHAD (you may want to make sure you have the anti-debug plugins installed to hide the debugger in case the sample uses anti-debugging techniques) instruction and then set a hardware breakpoint on the ESP register on access.   Then run the program (F9) and when the breakpoint is hit, you should be close to the POPAD instruction.  Close by should be the programs Original Entry Point (OEP):

crackme_unpack_OEP

We just paused after the POPAD and a few lines down we see a really far, unconditional jump from our present location at 0x4122E6 to 0x40463C.  That is our OEP.  Set the cursor to that JMP instruction and hit F4 to run to position.  Then hit F7 to make the jump to the OEP and voila — this looks like source code:

crackme_unpacked

Leave the program paused here for now.  This won’t run as is.  We have to first rebuild the imports with ImportRec.   We will need the Relative Virtual Address (RVA): in our OEP address of 0x40463C that is the 463C part.  Next, we need the RVA of the import table.  In Olly, scroll down until you see something that looks like:

crackme_import_table

The table starts at address 0x40C074 and if you keep scrolling down to the end of the table, you will find that it ends at 0x40C150.  The RVA of the table is C074 and if we subtract that from the C150 we get the size of the table: 0xDC (220 bytes).  This is all the information we will need to use ImportRec.

Attach to the running process with ImportRec, the right click the big middle, white box and go to “Advanced Commands”, then “Select Code Sections”, and accept the defaults.  Now press the full dump button to dump the process from memory.  Click “Ok” to close the dialog boxes.

In ImportRec’s “IAT Infos needed” section type the 463C in the OEP box, C074 in the RVA box, and DC in the size box.  Click on the “IAT Autosearch” button.  If we did this right, it should find something:

crackme_importrec1

Click OK, then click Get Imports.  The big middle white box should have no errors.  Next click on the Fix Dump button and click on the dump file that ImportRec created for us earlier.  ImportRec will create a esetcrackme2013_dump_.exe file.  You should be able to run that file and it should work just like the original packed sample, displaying the same start up message, and exiting when you hit the enter key.

Now we should be able to examine the binary’s strings to get a first impression of what this program might do:

crackme_unpacked_strings

I see some Windows Registry key strings HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, and HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess.  This sample may set these keys to persist between power cycles.  There are strings to URLMON.DLL functions that check an Internet connection and to download a file.  I see an URL to http://www.eicar.org, so this thing may be trying to download an eicar.com file.  Also note the long string sequence highlighted in the string snapshot above.  That looks like the string sequence used to leverage an old OllyDbg vulnerability.  I see other possible anti-debugging strings such as GetTickCount, and IsDeguggerPresent.

Upon first impression, it looks like this program might be some sort of downloader or dropper, but the only way to know for sure is to attempt to debug it.  See if we can coax the thing to continue even after we hit the enter key in order to observe what its true intent is.  I will write up those results and post them in a few days.

EDIT TO ADD 20140109: Yashar posted his teammate’s write up of the solution.

EDIT TO CORRECT 20140109: Corrected the spelling of Yashar’s name.

Like Time Travel? Then Meet Me Last Friday!

05 Sunday Jan 2014

Posted by Eric Hokanson in Research

≈ Leave a comment

Tags

Research, Social Media, Time Travel, Time Travelers Exist

As a researcher myself, I am always on the lookout for interesting stuff.  Here’s one I found while reading my Pulse app this morning: If Time Travelers Exist, They’re Lying Low on Social Media.  I have seen cybersecurity, and data analytics research regarding social media, but this is the first one I have seen for time travel.

If I understand this article correctly, researchers from Michigan Technological University scoured the popular social media networks for evidence of time travel and those who have done the traveling, but have not had any luck.

Well of course time travel exists!  Allow me to demonstrate it — and at significant savings to the tax payer.  Ready?  I ask you to pause for just one second.  Ok.  It is now one second later.  Congratulations — you have just traveled one second into the future!

Want to travel further?  Then wait a minute, an hour, 24 hours.  By this time tomorrow you will have traveled a whole day into the future.  It is a one-way trip so please use you time wisely.

A Malware Analyst’s Bookshelf

02 Thursday Jan 2014

Posted by Eric Hokanson in Computer Security, Cyber Security Research, Malware RE

≈ 2 Comments

Tags

Gary McGraw, Greg Hoglund, Malware, Malware Analysis, Malware Analysis Sources, Microsoft Windows, OllyDbg, Reverse Engineering, Static program analysis

I am often asked by those wishing to pursue a career as a malware analysit, what references are useful in learning, or the continued learning of the art and craft of malware analysis?  Here is a list of resources that I find useful:

1.  The Art of Computer Virus Research and Defense by Peter Szor (TAOCVRD).  This is the book that introduced me to malware research.  It could use some updating, but sadly, the author recently passed away.  On the other hand, with the popularity of Android malware, what is old is new again.  Many Android malware samples are doing what the old Windows malware used to do in the early days.

TAOCVRD covers different malware types, and the armoring, self-protection strategies they employ, the common detection techniques, and the last chapter is a useful guide in setting up your own malware analysis lab.  Again, a bit outdated because many of the tools we use today were not widely available back when this book was originally published.  However, many of the analysis techniques are still relevant today.

2.  Practical Malware Analysis by Michael Sikorski and Andrew Honig (PMA).  An introductory tour of malware analysis and reverse engineering techniques.  The hands-on labs reinforce the skills covered in each chapter.  Each lab has a set of  “malware” like samples (download from the book’s website).  Introductory chapters cover x86 assembly and the common instructions you will encounter, as well as how to use common tools, such as OllyDbg, and IDA Pro.

3.  One of the most powerful tool for static analysis, that I mentioned in (2), is IDA Pro.  But it has a steep learning curve.  The IDA Pro Book by Chris Eagle is about the only practical users guide available.  Whenever I need to learn something new in IDA, or how to write a plugin, I consult this book.

4.  Exploiting Software: How to Break Code by Greg Hoglund and Gary McGraw.  This book shows the common software programming errors and exploitation patterns.  Usually, I will start looking for these patterns in the malware samples I am analyzing to help guide my investigations; knowing these patterns can reveal what the malware may be targeting.

5.  Reversing: Secrets of Reverse Engineering by Eldad Eilam.  This too is a little outdated, but it is the best introduction into the art of RE that I have found so far.  It covers the common tools used, the basics of assembly and x86 architecture, basic Windows internals, and even has a chapter on reversing malware.

This list is by no means exhaustive.  I am sure I am overlooking other good sources and would be happy to hear what other analysts routinely consult.  I am always looking to expand my library.

related articles
  • How To Get Started with Malware Analysis.
  • An Overview of Becoming a Malware Analyst.

It May be a New Year but the Laws of Physics Have Not Changed

01 Wednesday Jan 2014

Posted by Eric Hokanson in Holidaze

≈ 8 Comments

Tags

Bowl games, New years, Newton's laws of motion, Resolutions

Happy new year!

Yes, I made some resolutions to be more active and exercise.

However, I am having trouble escaping the gravitational pull of my couch and all the bowl games on TV.

Curse you Newton’s First Law!

 

Subscribe

  • Entries (RSS)
  • Comments (RSS)

Archives

  • May 2016
  • May 2015
  • April 2015
  • March 2015
  • September 2014
  • August 2014
  • June 2014
  • May 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013

Categories

  • Alan Turing
  • Algorithms
  • Apollo 17
  • C Programming
  • Christmas
  • Computer Programming
  • Computer Science
  • Computer Security
  • Current Events
  • Cyber Security Research
  • Education
  • Freedom of choice
  • Freewill
  • Hacking
  • Holidaze
  • Learning
  • Malware RE
  • Math
  • NASA
  • Pen-testing
  • Philosophy
  • Pi Day
  • procrastination
  • Programming
  • Python
  • Quine programs
  • Quotes
  • Random Stuff
  • Research
  • Reverse Engineering
  • Shopping
  • Smithsonian National Air and Space Museum
  • Software Development
  • Star Wars
  • Success
  • Uncategorized

Meta

  • Register
  • Log in

Blog at WordPress.com.

  • Follow Following
    • Eric Hokanson
    • Join 44 other followers
    • Already have a WordPress.com account? Log in now.
    • Eric Hokanson
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Report this content
    • View site in Reader
    • Manage subscriptions
    • Collapse this bar
 

Loading Comments...