MoleBox goes out of business

kao

Molebox as it used to be

A bit of history

MoleBox 2 was released in year 2003 and it was one of the first file virtualization solutions in the market. It bundled executable with the DLL and data files into a single EXE file. At that time that was something new and innovative.

They had quite a success and released another product (MoleBox Ultra, later renamed to MoleBox Virtualization Solution) in year 2009. Apparently it was very hard to fight in the increasingly more competitive market of application virtualization solutions and the last version of MoleBox Virtualization Solution was released in 2013.

Game over

In February 2016 domain molebox.com was sold for $1526. Yesterday their web server started serving generic WordPress page with dating-related spam. And that is just sad. πŸ™
MoleBox dating advice

Release of static unpacker

However, both editions of MoleBox are still very popular with private game server owners, as they allow to bundle patched EXE files together with their custom data files. It's not a bullet-proof security but stops newbies from stealing their valuable data.

Since the MoleBox company is officially out of business now, I have no more reasons to keep my static Molebox unpacker private. It supports most versions of MoleBox 2.x including the external box files.

Have fun guys!

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

P.S. This post was made just because I noticed changes in MoleBox web, I wasn't planning to release the unpacker today. So, please keep in mind this code was written in year 2009 and has had only one small fix applied in 2015. It's likely that you'll encounter some bugs and quirks - please send me the problematic file and I'll fix the bug. πŸ™‚

P.P.S. I have static unpacker for MoleBox Virtualization Solution as well. But it doesn't have a nice UI yet, so it will be released on a later day.

About .NET, googling and lazy programmers.

kao

Delphi fail. .NET win.

Recently, several people sent me bug reports where my EnigmaVB unpacker failed to extract files. In all cases, the problem was caused by really large files, like 3.5GB in size. So, what's causing the problem?

EnigmaVB unpacker is a 32bit application written in Delphi. And Delphi streams are retarded. They look like they've been written in 1990s and were never updated. TMemoryStream uses a continuous memory range, so it can never support anything larger than 2GB. TFileStream internally uses longint, so it doesn't properly support files larger than 2GB. WTF?

So, I have two choices. I can either make a custom stream class in Delphi, or I can pick another framework and rewrite my tool to use that.

I'm not a programmer, I'm a reverser. I don't want to spend my time developing custom stream classes. I'd very much rather use this time breaking some code. So, say hello to .NET framework - my next version of EnigmaVB unpacker will be made in C#.. πŸ™‚

Am I a programmer or a googler?

While researching all the Delphi limitations and possible workarounds, I ran into this great article by Scott Hanselman. Reading both the post and the comments made me think a lot.

Does using Google to solve your programming tasks makes you less of a programmer? I don't think so.

In fact, I'm just lazy. Most people are. Why should I spend 30 minutes remembering basic algorithms for converting string to hex, if Google query can solve it in 10 seconds? Why reinvent the wheel and write CRC calculation from scratch? I'll just open StackOverflow and have a solution that's already tried and tested. It doesn't mean I can't do those boring tasks - I just don't want to.

How about you? Would you be able to write some tools without using Google and StackOverflow?

Updated Meltdown and EnigmaVB Unpacker

kao

About Error Messages

Users can't read.

Or maybe they don't want to read. I don't know.

But one thing I know for sure - you must make your tools foolproof. If your tool is showing an error message, make sure even your grandma could understand it. Otherwise you'll be getting lots and lots of invalid bug reports.

For example, this is the error message my EnigmaVB unpacker used to show (as reported by ho3ein at Tuts4You):
enigmavb_error_message

It seemed to be very clear to me. First, tool tells user all the versions of Enigma Virtual Box it supports. Then tool explains that it expects to see a PE section with a name ".enigma2" but it found section with a name ".rsrc" instead. To me it's absolutely clear what happened: this file is not protected with Enigma Virtual Box (or it's hacked).

But you won't believe how many times this gets reported as a bug.

There was a similar problem with Meltdown. It clearly stated which versions of DeepFreeze it supports. Then it printed the detected DeepFreeze version. However, the error message didn't explicitly say "This version of DeepFreeze is not supported", it said "DeviceIoControl failed." It makes perfect sense from developer's point of view, but apparently is very confusing for users.

So, here are improved versions of my tools, fixing the error messages and some other stuff..

Improved EnigmaVB Unpacker

First of all, I fixed the error message. I also added detection and tested compatibility with the latest EnigmaVB v7.40. Hopefully, this will make users happier and less confused. πŸ™‚
EnigmaVBUnpacker_v034

Improved Meltdown

Meltdown 1.7 fixes confusing error message with DeepFreeze Standard v8.x. Thanks to Alexander for reporting it.

I also took a closer look at DeepFreeze Enterprise versions and found a way to make Meltdown more user friendly. If DeepFreeze Enterprise v7.20+ is detected, Meltdown will get OTP Token automatically and immediately generate correct password.

meltdown17

Download links

Enigma Virtual Box Unpacker: Please get latest version from this post
Meltdown v1.7: https://www.mediafire.com/?b0bamd3t2d6bbkq

How to lose 20% of your readers in one day

kao

I was reading "How WIRED Is Going to Handle Ad Blocking" article and didn't know if I should laugh or cry. Here are some excerpts:

On an average day, more than 20 percent of the traffic to WIRED.com comes from a reader who is blocking our ads. We know that you come to our site primarily to read our content

Translation: we know that more than 20% of our users hate our irrelevant ads covering half the page. Fucking freeloaders, we can't make a penny out of them!

We know that there are many reasons for running an ad blocker, from simply wanting a faster, cleaner browsing experience to concerns about security and tracking software.

Translation: we know that ads can be obnoxious and sometimes distribute malware. Hell, big companies like Forbes distributed malware twice last year. We don't care, as long as we get paid.

So, in the coming weeks, we will restrict access to articles on WIRED.com if you are using an ad blocker. There will be two easy options to access that content.

Translation: WIRED just gave a middle finger to 20% of its users. What a great idea!


EDIT: lots of companies seem to be reacting to WIRED's move in one way or another. For comparison, here's the comment by Stack Overflow advertising managers. Now, that's an attitude that actually makes sense!

Is your password ‘123456’? Mine too!

kao

Last few days everyone is writing about passwords. How the most popular password last year was '123456', how it's all bad and that we all are idiots.

Let me tell you something - that's bullshit.

There are 2 types of resources: few important ones (my internet bank, company login, some RE forums, my blog, etc.) and the ones I don't really care about (2shared, codeproject and everyone else with mandatory registration).

For the important resources I have strong passwords. Unique ones with 8+ characters, mixed case letters, numbers and special symbols. You know the drill.

For everything else I'm using a throwaway email like Mailinator and password '123456'. Why? Because I don't give a crap. You want to crack my Codeproject login to download few files? Please do so. Hijack my Kickass Torrent account and post childish comment or two? Please. Use my account to download something from 2shared? Yeah, why not! I don't care! πŸ™‚

So, next time someone runs around screaming about use of insecure passwords, ask yourself - where does this password list come from and who is this person making these statements? Maybe he just wants to sell you something?

Use a password manager such as {software_name} to organize and protect passwords, generate random passwords, and automatically log into websites

Right, let's make more FUD in effort to sell your software. Genius!

Stay cool, stay safe!

Local Privilege Escalation Bug in Faronics Deep Freeze

kao

While preparing update for Meltdown, I encountered a textbook error in Faronics Deep Freeze Enterprise v8.31. So, here goes..

Running With Unnecessary Privileges

frzstate2k.exe is application responsible for displaying Deep Freeze Workstation Configuration dialog. To do that, it sits in the system tray and communicates with DeepFreeze driver.

For reasons I really can't understand, this simple UI component is executed under SYSTEM account. To make matters worse, it doesn't even drop unnecessary privileges. All these are textbook errors and Microsoft has spent last 10+ years trying to educate programmers and eliminate these kinds of bugs.

Here's the great presentation from Black Hat 2006 about this subject (slides 7-15): Security Engineering in Windows Vista

Abusing Common Dialogs

Microsoft Windows provide APIs for creating nice standard dialogs like "Open File.." and "Save As.." These dialogs are heavily integrated with Windows shell and offer much more than just file selection - within the dialog box you can do almost anything you can do using Windows Explorer. Like executing other applications..

Due to that, these dialogs are often used to break out of Terminal Server environment or to elevate local user privileges. Here is a quite good tutorial covering the basics: Breaking out of applications.

These attacks are also very old. Here's nice presentation from year 2008: Hacking Internet Kiosk’s

Putting it all together

Here's how any user can get SYSTEM privileges in 5 easy steps:

  1. user is logged on using low-privilege account,eg. belongs to "users" group;
  2. 1-user-privs

  3. user gains access to workstations DeepFreeze administration interface (eg. using password generated by Meltdown);
  4. 2-deepfreeze-ui

    ​

  5. user presses "Activate Now" -> "Activate Offline" -> "Next" -> and presses either of the 2 buttons that open "Save As" or "Open" dialogs;
  6. 3-create-activation
    ​

  7. since FrzState2k.exe is running under SYSTEM account, these dialogs give access to anything SYSTEM account has access to.
  8. user navigates to C:\Windows\System32\ , right-clicks cmd.exe, and chooses Open.
  9. 4-select-cmd
    ​

  10. cmd.exe is executed under SYSTEM account.
  11. 5-game-over

  12. game over.

Mitigating factors?

This attack was verified against 30-day evaluation version of Deep Freeze Enterprise. It is possible that after the workstation is activated, the "Activate Now" button is disabled and there's not an easy way to access it. This would (accidentally) limit attacks only to workstations that haven't been activated yet.

Conclusion

It's hard to write anything here without using inappropriate language. Faronics positions itself as a security company, yet their products contain textbook errors like these. Make your own conclusions.

Updated Faronics DeepFreeze and Meltdown

kao

tl;dr - DeepFreeze is still buggy and one-time passwords can be easily generated. Download link: https://www.mediafire.com/?mtpaf3quaifwm3u

What was changed in DeepFreeze version 8.31?

Well, two things.

First, they made an attempt to stop Meltdown from generating correct One Time Passwords (OTP). While doing so, they added a new vulnerability - similar to the one that Meltdown used to obtain password for Deep Freeze Standard version 7.x and older.
Second, they added a licensing mechanism that requires each workstation to be activated. While doing so, they created a new local privilege escalation vulnerability.

What is this new (old) vulnerability?

The problem is in data exchange between driver and the UI component. It's done using DeviceIoControl calls and data are encrypted using changing XOR key. However, the overall communication protocol is badly designed.

So, let's start with the Deep Freeze Standard versions 5.x to 7.x. Communication between UI (frzstate2k.exe) and the driver goes like this:
DFS 7.x
Obviously, it's easy to extract password from the information provided by driver. That's what Meltdown originally did.

Faronics fixed that in Deep Freeze Standard v8.10:
DFS 8.x
Makes total sense, right? I looked at the communication protocol and concluded that the issue is fixed. End of story.

Deep Freeze Enterprise is a different story:
DFE 7.x
This communication makes sense. But all the information necessary to generate OTP was present in dfserv.exe and other executables. So, Meltdown didn't even have to communicate with the driver.

But in the latest version (v8.31) the information to generate OTP is not present in dfserv.exe or other executables. However, Faronics added a new feature to the driver:
DFE 8.31
Where have I seen this design before? πŸ™‚ So, I updated Meltdown to obtain information necessary for OTP generation from DeepFreeze driver. Easy as pie.

Local privilege escalation

It's so good, it deserves a separate blog post.

What do you think about Faronics?

I get this question a lot lately. People who see Meltdown ask that. IT managers who bought DeepFreeze ask that. And even some reverser friends have asked me that. But I'd rather not say anything and let the facts speak for themselves.

  • 2013-Mar-06 - Meltdown is published.
  • 2014-Mar-31 - Faronics closes the vulnerability in DeepFreeze Standard v8.10. No mention of any security issues in the changelog. No security bulletins published. This vulnerability had existed since very early versions of DeepFreeze and it suddenly got fixed. To me, it indicates that Faronics was aware of Meltdown at this moment of time.
  • 2014-Jun-24 - Changes in DeepFreeze Enterprise v8.11 break existing versions of Meltdown. Release notes say "Resolved a security issue that could result in the user accessing Deep Freeze without authorization." No security bulletins published.
  • 2015-May-11 - User reported that Meltdown wasn't working anymore. It took me few hours to add that new round of "extra secure" xor encryption.
  • 2015-Dec-31 - Changes in DeepFreeze Enterprise 8.31 break existing versions of Meltdown. Changelog says "Secured One-Time Password functionality from potential vulnerability." No security bulletins published. They introduce 2 new vulnerabilities in this version.
  • 2016-Jan-12 - Meltdown is updated with another round of xor encryption and 2 new calls to DeviceIoControl API.

You can compare Faronics' behavior and response time to other software companies and make your own conclusions.

Download link for Meltdown 1.6: https://www.mediafire.com/?mtpaf3quaifwm3u

Since you asked.. How to obtain value of a field using WinDbg?

kao

My friends occasionally ask me tricky questions - about PE file format, about .NET internals, usage of dnlib or WinDbg and what not. Even if I'm not an expert in some areas, I usually can figure out stuff pretty fast.

So, here's a question that li0nsar3c00l asked me few days ago:

How to get the value of a static field using WinDbg?

To put the question in context - he is trying to debug a .NET assembly which is obfuscated and all names are unprintable. When all names look like "□", it's quite hard to find out which is which - and I doubt you can use those names when setting breakpoints.. So, we need to figure out a way that avoids using object names.

I will assume that you have very basic knowledge of using WinDbg with .NET applications. If you don't, I suggest that you start by reading introductory tutorials, for example, Getting started with Windbg - part I and part II. You could also check WinDbg tutorial by netmatze. Or just go through the entire amazing collection of .NET Debugging Demos by Tess Ferrandez.

Quick answer

You can use !mx command to locate the class and field you need. Then you can use !mdt -e command to display values you need.

But if you have no idea how those commands work, please continue reading..

Long answer

Dealing with static classes and static fields is easier. After the corresponding .cctor is executed, you can get the values you need. But for non-static classes and fields you need to stop debugger at a place where an instance of the object is already created and values initialized.

So, we'll take a scenic route from the very beginning till the end. Here's a demo app you can test your skills with: https://www.mediafire.com/?wavmalk6sqhdcy6

  1. Load sos and sosex extensions. I'm using this one-liner for .NET 4.0 - you can use separate commands, if you prefer.
  2. 0:000> sxe ld:clrjit;g;.loadby sos clr;.load F:\Sosex\sosex.dll
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll - 
    (1810.15ac): Unknown exception - code 04242420 (first chance)
    ModLoad: 62620000 6268e000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
    
  3. Examine domain, find module
  4. 0:000> !DumpDomain
    {boring stuff here}
    
    Assembly:           007894c8 [F:\ConsoleApplication1.exe]
    ClassLoader:        00789590
    SecurityDescriptor: 00788ca8
      Module Name
    00192e94    F:\ConsoleApplication1.exe
  5. Find the type you want
  6. 0:000> !DumpModule -mt 00192e94
    Name:       F:\ConsoleApplication1.exe
    Attributes: PEFile 
    Assembly:   007894c8
    LoaderHeap:              00000000
    TypeDefToMethodTableMap: 00190038
    TypeRefToMethodTableMap: 00190050
    MethodDefToDescMap:      001900bc
    FieldDefToDescMap:       001900d0
    MemberRefToDescMap:      001900e4
    FileReferencesMap:       00190140
    AssemblyReferencesMap:   00190144
    MetaData start address:  013120d8 (2160 bytes)
    
    Types defined in this module
    
          MT  TypeDef Name
    ------------------------------------------------------------------------------
    001937e0 0x02000003 ConsoleApplication1.Program
    
    Types referenced in this module
    
          MT    TypeRef Name
    ------------------------------------------------------------------------------
    62a8b064 0x02000001 System.Object
  7. Find the method you need
  8. 0:000> !DumpMT -md 001937e0 
    EEClass:         001912d0
    Module:          00192e94
    Name:            ConsoleApplication1.Program
    mdToken:         02000003
    File:            F:\ConsoleApplication1.exe
    BaseSize:        0xc
    ComponentSize:   0x0
    Slots in VTable: 6
    Number of IFaces in IFaceMap: 0
    --------------------------------------
    MethodDesc Table
       Entry MethodDe    JIT Name
    629949d0 62696728 PreJIT System.Object.ToString()
    62988800 62696730 PreJIT System.Object.Equals(System.Object)
    629883d0 62696750 PreJIT System.Object.GetHashCode()
    62981760 62696764 PreJIT System.Object.Finalize()
    0019c015 001937d8   NONE ConsoleApplication1.Program..ctor()
    0019c011 001937cc   NONE ConsoleApplication1.Program.Main(System.String[])
  9. Put breakpoint on the method and run
  10. 0:000> !bpmd -md 001937cc
    MethodDesc = 001937cc
    Adding pending breakpoints...
    0:000> g
    (1810.15ac): CLR notification exception - code e0444143 (first chance)
    JITTED ConsoleApplication1!ConsoleApplication1.Program.Main(System.String[])
    Setting breakpoint: bp 003F00B9 [ConsoleApplication1.Program.Main(System.String[])]
    Breakpoint: JIT notification received for method ConsoleApplication1.Program.Main(System.String[]) in AppDomain 00735ca8.
    Breakpoint 0 hit
    eax=003f00b0 ebx=0033f54c ecx=02722330 edx=00000000 esi=00000000 edi=0033f4c0
    eip=003f00b9 esp=0033f490 ebp=0033f4a8 iopl=0         nv up ei pl nz na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    003f00b9 b968381900      mov     ecx,193868h
  11. Disassemble code, locate place where the interesting object will be already initialized.
  12. You need to put a breakpoint after the object is created and initialized.

    0:000> !U eip
    Normal JIT generated code
    ConsoleApplication1.Program.Main(System.String[])
    Begin 003f00b0, size 8a
    *** WARNING: Unable to verify checksum for ConsoleApplication1.exe
    
    003f00b0 55              push    ebp
    003f00b1 8bec            mov     ebp,esp
    003f00b3 57              push    edi
    003f00b4 56              push    esi
    003f00b5 53              push    ebx
    003f00b6 83ec0c          sub     esp,0Ch
    >>> 003f00b9 b968381900      mov     ecx,193868h (MT: ConsoleApplication1.Bla)
    003f00be e83d20d9ff      call    00182100 (JitHelp: CORINFO_HELP_NEWSFAST)
    003f00c3 8bf8            mov     edi,eax
    003f00c5 8bcf            mov     ecx,edi
    003f00c7 ff15a8381900    call    dword ptr ds:[1938A8h] (ConsoleApplication1.Bla..ctor(), mdToken: 06000001)
    003f00cd b940bfa862      mov     ecx,offset mscorlib_ni+0x3fbf40 (62a8bf40) (MT: System.Byte)
    
    {boring stuff here}

    Unfortunately !U doesn't show IL code. So, let's use !mu output to confirm our findings:

    0:000> !mu
    *** WARNING: Unable to verify checksum for ConsoleApplication1.exe
        IL_0000: newobj ConsoleApplication1.Bla::.ctor()
        IL_0005: stloc.0  (bla)
            >>> 003f00b9 b968381900      mov     ecx,193868h
            003f00be e83d20d9ff      call    00182100
            003f00c3 8bf8            mov     edi,eax
            003f00c5 8bcf            mov     ecx,edi
            003f00c7 ff15a8381900    call    dword ptr ds:[1938A8h]
        IL_0006: ldstr "{0:X} {1:X}"
        IL_000b: ldsfld ConsoleApplication1.Bla::key1
        IL_0010: ldc.i4.1 
        IL_0011: ldelem.u1 
        IL_0012: box System.Byte
        IL_0017: ldloc.0  (bla)
        IL_0018: ldfld ConsoleApplication1.Bla::key2
        IL_001d: ldc.i4.2 
        IL_001e: ldelem.u1 
        IL_001f: box System.Byte
        IL_0024: call System.Console::WriteLine
        IL_0029: call System.Console::ReadKey
        IL_002e: pop 
            *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\d12f4fda3d1bfabf888342e96983e9a7\mscorlib.ni.dll
    *** ERROR: Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\d12f4fda3d1bfabf888342e96983e9a7\mscorlib.ni.dll
    003f00cd b940bfa862      mov     ecx,offset mscorlib_ni+0x3fbf40 (62a8bf40)
    
    {boring stuff here}

    Command !mu doesn't show call targets but interleaves IL code with x86 code. Combining both outputs we know that we should get to address 003f00cd.

  13. Execute code to the place where data are already initialized
  14. 0:000> g 003f00cd 
    eax=ea1dad0b ebx=0033f54c ecx=027223a4 edx=00009c88 esi=00000000 edi=02722398
    eip=003f00cd esp=0033f490 ebp=0033f4a8 iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    003f00cd b940bfa862      mov     ecx,offset mscorlib_ni+0x3fbf40 (62a8bf40)
  15. Use command !mx
  16. This command is little known but it's bloody awesome!

    Usage: !sosex.mx <Filter String>

    Displays any matching type, method or field for <Filter String>, where <Filter String> is a string in module!metadataname format. If module! is not specified, all modules are searched for the specified metadata. Searched info includes types, methods and fields.

    In order to search globals, do not precede the field or method filter with a ".". To enumerate all globals for a given module filter, use "globals" as the type filter. eg: "globals" "*!globals" "mymod!globals", etc...

    So, let's ask to show us all objects from our test application:

    0:000> !mx ConsoleApplication1!*
    AppDomain 63d78180 (Shared Domain)
    ---------------------------------------------------------
    
    AppDomain 00735ca8 (ConsoleApplication1.exe)
    ---------------------------------------------------------
    module: ConsoleApplication1
      class: ConsoleApplication1.Bla
        .ctor()
        static .cctor()
        static key1 {fieldtype: byte[]}
        key2 {fieldtype: byte[]} 
      class: ConsoleApplication1.Program
        static Main(string[])
        .ctor()
      class: {C5635AC4-C624-4BB2-B53A-AC963D1790A5}
        static $$method0x6000004-1 {fieldtype: __StaticArrayInitTypeSize=3} 
        static $$method0x6000001-1 {fieldtype: int} 
  17. Get the address of class
  18. Class Bla contains static field key1 which we're interested in. Click on Bla hyperlink. You actually don't care about the output, just the address of class.

    0:000> !dumpmt 00193868
    {lots of boring stuff}
  19. Use !mdt command to get address of the field
  20. 0:000> !mdt -e 00193868
    ConsoleApplication1.Bla
        [s]key1: byte[]
            AppDomain 'ConsoleApplication1.exe' (00735ca8): 02722340[System.Byte[]]
        key2: byte[]
  21. Use provided hyperlinks to access data
  22. Clicking on "02722340" and then on "Expand" will get you the good stuff. Or you can enter "!mdt" command manually:

    0:000> !mdt 02722340
    02722340 (System.Byte[], Elements: 3)  expand
    0:000> !mdt -e:1 02722340
    02722340 (System.Byte[], Elements: 3)  expand
    [0] 0x12
    [1] 0x23
    [2] 0x34

    Congratulations, this is the value of static field. Task #1 done! πŸ™‚

  23. Locate instance of the class
  24. Remember, we put a breakpoint just after the class initialization. You can either use your x86 knowledge and check the proper register values, or just display managed stack objects:

    0:000> !dso
    OS Thread Id: 0x15ac (0)
    ESP/REG  Object   Name
    ecx      027223a4 System.Byte[]
    edi      02722398 ConsoleApplication1.Bla
    0033F498 02722330 System.Object[]    (System.String[])
    0033F520 02722330 System.Object[]    (System.String[])
    0033F67C 02722330 System.Object[]    (System.String[])
    0033F6B4 02722330 System.Object[]    (System.String[])
  25. Use !mdt command to get the stuff just like before
  26. 0:000> !mdt 02722398 
    02722398 (ConsoleApplication1.Bla)
        key2:027223a4 (System.Byte[], Elements: 4)  expand
    0:000> !mdt -e:1 027223a4
    027223a4 (System.Byte[], Elements: 4)  expand
    [0] 0x0b
    [1] 0xad
    [2] 0x1d
    [3] 0xea

    Congrats, this is value of non-static field. Task #2 done!

This concludes our journey. Hopefully you learned something new today!

Why do antiviruses suck, part 2

kao

In part 1, I tried to explain reasons behind some of the decisions anti-malware companies make when designing their products. In this part I'll touch some other side-effects of those decisions and what they mean for power-users.

This site has been blocked

In general, I need a very basic antivirus protection - when I make a mistake during my reversing session or web browsing, it should stop malware from:

  • becoming persistent on my computer;
  • sending any data to its C&C server

I'm not retarded and can read and think for myself - therefore I don't want "anti-phishing protection", "parental control", "safe banking", "vulnerability scan" or any other features aimed for persons who shouldn't be using Internet in the first place.

So, I always configure my antivirus to have just very basic on-access scan and firewall enabled, and all other components switched off. You can imagine my surprise when in last 2 days I have been greeted with these messages on 2 separate sites:
page blocked
WTF guys, I have switched off every component I could - why are you still active?! And why are you bugging me with this nonsense?

Make it more user-friendly

I'm very sure that the answer is very simple: somebody in the UI/UX department decided that Bitdefender UI needs to be simplified. So, they took the UI that actually made sense, and fucked it up.

Here's how settings looked like in year 2013 (image (c) Softpedia):
bitdefender 2013 settings

And here's how it looks in the Bitdefender 2016:
bitdefender 2016 settings
Antispam and Firewall have been moved to their corresponding module, but "Antimalware Filter" has disappeared altogether. After all, who would ever want to disable it, right?

To make matters worse, here's how the alert looked in Bitdefender 2015 (image (c) PCRisk):
bitdefender2015-website-blocked
See, there was "Settings" button right at the top of alert page and you could disable "Antimalware filter" from there. Well, they "simplified" that option away as well. Geniuses!

But I really want to disable it!

Luckily, you still can. πŸ™‚ All Bitdefender settings are stored in C:\Program Files\Bitdefender\Bitdefender 2016\settings\. However, to be able to modify files, you will need to start your computer in safe mode.

The file you're looking for is cloud.http.xml. Find your user name in it, and you'll see a section like this:

<user name="Administrator">
	<active>true</active>
	<timeout>400</timeout>
	<status value="default">false</status>
	<status value="malware">true</status>
	<status value="phishing">true</status>
	<status value="fraud">true</status>
	<status value="untrusted">true</status>
	<status value="bank">true</status>
	<bank>
		<add>
			<domain value="" option="ask"></domain>
		</add>
	</bank>
</user>

Apparently, there are more few settings which are hidden in the UI. I can only guess the exact meaning of them but - to be honest - I don't care. I just want this bugger to be gone from my machine. So, I changed "active" to "false" and for the good measure disabled each and every component as well. After a reboot, it all works the way I want, and I can access all the sites I want.

Great success! πŸ™‚

Keygen templates in Visual Studio

kao

I'm lazy and I hate doing the same tasks over and over again. Making UI for my crackme solutions is one of such tasks. It always goes like this: open Visual Studio, create new Windows Forms project in C#, drop 2 labels, 2 edit boxes and one button on the form. Set label texts to "Name" and "Serial", set button title to "Generate..", set the project icon, etc., etc..

There must be a better way!

..and it's certainly not the way Blue Indian did his keygen template:

To build this template on your own, open the solution in Visual studio, comment out the calls for uFMOD and implement your own logic, after successful build of keygen, close the Visual studio, open the Form_Main.cs file in any text editor and uncomment those two calls to uFMod, save it. Now double click on the build.bat file to built it finally.
...
-To change the ICON and XM tune, edit the mini.res (resource file) with any resource editor like Restorator or any of your choice.

Open this, delete those, compile that, and what? I'm already confused, sorry.

Introducing Visual Studio project templates

I'm sure you know that when you click "New project" in Visual Studio, you're presented with number of choices, like "Windows Forms Application", "Console Application", "Class Library" and so on. All these are project templates that are installed by default.

They provide all the files that are required for a particular project type, include standard assembly references, and set default project properties and compiler options. Hmm, that's exactly what I needed! πŸ™‚

This article at MSDN nicely explains that project template is simply a ZIP file that contains all the necessary files and a special .vstemplate file. This .vstemplate file is an XML file containing metadata Visual Studio needs to display the template in the "New Project" dialog.

Let's try to put it all together.

Making simple keygen template

Making a new template is actually very easy. You take an existing Visual Studio project, replace project-specific strings with template parameters and press File->Export Template.

Here is my keygen for Mr. eXoDia's simple crackme:
keygen_template1
Obviously, template should not contain code for specific crackme. Let's change that to something trivial and mark as FIXME:
keygen_template2
Now I need to remove all references to crackme name. I will replace them with template parameter $safeprojectname$ in all files. After this change, project won't compile anymore, so you need to be extra careful when changing stuff!
keygen_template3
Hardcoding year in the (c) string is not a good idea because I want to use this template in year 2016 as well:
keygen_template4
Now I just need to update AssemblyInfo.cs to make sure each project has correct name, (c) and GUIDs:
keygen_template5
Did it work? Let's see... File->Export Template, follow the wizard and...

It works. Kinda. The created template still has quite a few references to Mr eXodia's crackme, I'll need to modify project and solution files manually. Unzip the template, fix the files in text editor and ZIP them back. And now it works!

Few more cosmetic fixes (like using $projectname$ where possible), using $if$ and $targetframeworkversion$ to target all .NET framework versions, better namespace names and we have a template that's actually useful.

Download here: https://www.mediafire.com/?sx1i5ba1uijjkii

It's not particularly pretty but that's pretty much what I've been using for 2+ years now - and hopefully it can inspire you to do something similar with your own code. πŸ˜‰

Further reading

Reason→Code→Example : Creating Visual Studio project templates
Rebuilding template cache
How to: Manually Create Project Templates
How to: Create Multi-Project Templates