NetBalancer: should you trust it?

kao

Last few months people kept bashing antivirus and security software in general. Like on Twitter or their personal pages. Sure, Twitter is full of opinionated idiots who just love to complain about everything that doesn't match their point of view. On a few occasions they are right and even I have written about some of the issues with antiviruses before.

But!

But you'd be f*king stupid to delete your antivirus just because it has some bugs. Doorlocks get picked by criminals every day and people still use them. Professional lockpickers do exist - it's their job to break lock's security mechanism and get you back in the house when you lose your keys. Tavis Ormandy is a professional lockpicker - only he works in the digital world. It's his job to break digital security mechanisms and help vendors to fix the issues.

Having said that, not all software is created equal. Sometimes new and dangerous features get added to an otherwise great software. These features look good on paper but they can really ruin someone's day. Today, I'll demonstrate one such feature.

Introducing SeriousBit NetBalancer

NetBalancer is a Windows application for local network traffic control and monitoring. It shows you the network traffic on your computer and helps you to set limits, priorities and rules for that traffic. Some sort of a firewall - but better. It can prioritize your traffic, schedule it for specific times, do statistics, make graphs and charts and what not. And it looks really good!

Predefined Priorities

NetBalancer's Predefined Priorities is a feature that looks great on paper.

For those of you who are not sure what priorities are best for your PC we decided in NetBalancer 8.5 to add some predefined priorities.
These priorities include the most used programs and processes, currently about 1700 total (and counting), and are set to match the needs of most users

It could be used for virtually everything:

  • giving high priority to VoIP applications and games
  • making sure background processes (eg. software updaters) don't interrupt your Youtube experience
  • and even blocking malware

The possibilities are endless. In fact, virtually all of the antivirus products use similar databases to preconfigure their firewalls. It makes total sense after all!

However, the devil is in the details. All such databases must be maintained. New version of Skype comes out, you need to update database. League of Legends releases new update, you must update the database. And you must do it very fast, so that your users don't suffer from misbehaved firewall. It's a lot of work.

Since NetBalancer is made by a small company called SeriousBit SRL, I was naturally curious how they manage to do that. 🙂

Inside Predefined Priorities

First, I needed to obtain the complete database of the priorities. You could try to find something in C:\ProgramData\SeriousBit\NetBalancer\ but it would be more interesting to find and download correct files for the official servers, right? 🙂 After a quick string search, I learned that priorities can be downloaded from https://netbalancer.com/api/internal/predefinedpriorities. It's a huge JSON file but isn't encrypted or signed in any way.

That's a serious red flag right there. Security companies vigorously protect their databases - it's their know-how, their crown jewels. And they use digital signatures to make sure that the databases aren't tampered with. After all, which developer wants to see his product in news like "MalwareBytes: multiple security issues"? 🙂

OK, in this case JSON file is downloaded over HTTPS, therefore it's slightly harder to intercept traffic and modify it. So, let's ignore this issue for a moment and look at the JSON data instead.

In a minute or two, I was in the full "WTF?" mode.

Here's an excerpt from the JSON, prettified for easier viewing:

{
    "$type": "Events.PredefinedPriority, Events",
    "ExeNameCrc": 1772190657,
    "Priority": {
      "$type": "Events.AppPriorityInfo, Events",
      "AdapterId": -1521929413,
      "ExecutablePath": "driver.okaya.g200l.rar",
      "DownloadPriority": "High",
      "UploadPriority": "Normal",
      "DownloadLimit": 30000,
      "UploadLimit": 30000,
      "DownloadDelay": 0,
      "UploadDelay": 0,
      "DownloadDelayJitter": 0,
      "UploadDelayJitter": 0,
      "DownloadDropRate": 0.0,
      "UploadDropRate": 0.0,
      "PerConnectionLimits": false
    }
  },
...
{
    "$type": "Events.PredefinedPriority, Events",
    "ExeNameCrc": 3944917558,
    "Priority": {
      "$type": "Events.AppPriorityInfo, Events",
      "AdapterId": 2089926557,
      "ExecutablePath": "msi1f5.tmp",
      "DownloadPriority": "High",
      "UploadPriority": "Normal",
      "DownloadLimit": 30000,
      "UploadLimit": 30000,
      "DownloadDelay": 0,
      "UploadDelay": 0,
      "DownloadDelayJitter": 0,
      "UploadDelayJitter": 0,
      "DownloadDropRate": 0.0,
      "UploadDropRate": 0.0,
      "PerConnectionLimits": false
    }
  },

Setting high priority for RAR and TMP files.. More than 2000 entries like that? WTF?

How about this?

{
    "$type": "Events.PredefinedPriority, Events",
    "ExeNameCrc": 4213633860,
    "Priority": {
      "$type": "Events.AppPriorityInfo, Events",
      "AdapterId": -118159810,
      "ExecutablePath": "sexual babe receives screwed - xnxx.com.flv",
      "DownloadPriority": "High",
      "UploadPriority": "Normal",
      "DownloadLimit": 30000,
      "UploadLimit": 30000,
      "DownloadDelay": 0,
      "UploadDelay": 0,
      "DownloadDelayJitter": 0,
      "UploadDelayJitter": 0,
      "DownloadDropRate": 0.0,
      "UploadDropRate": 0.0,
      "PerConnectionLimits": false
    }
  },

Yes, I want to download my porn with a high priority, thank you very much!

But how on earth that got through the QA process? Is there any QA process in SeriousBit SRL? I highly doubt that..

Unsolicited user data gathering

All those entries made me think - how is it possible that NetBalancer's database contains such crap information? Most obvious answer was - it's submitted by users. To verify the guess, I took a sneak peek inside SeriousBit.NetBalancer.Core.dll. And there it was:

  public static void smethod_1(bool bool_0)
  {
    try
    {
      ...
      using (WebClient webClient = new WebClient())
      {
        NameValueCollection expr_77 = new NameValueCollection();
        expr_77["priorities"] = gparam_.smethod_0(true);
        NameValueCollection data = expr_77;
        bytes = webClient.UploadValues("https://netbalancer.com/api/internal/predefinedpriorities", "POST", data);
      }
    catch (Exception arg_126_0)
    {
      GClass48.smethod_11(arg_126_0, "LoadFromWww", "C:\\wrk\\seriousbit\\netb\\deskapp\\src\\SeriousBit.NetBalancer.Core\\Priorities\\PredefinedPrioritiesTable.cs", 91);
      if (bool_0)
      {
        throw;
      }
    }
    finally
    {
      GClass51.smethod_1("LastPredefinedPrioritiesLoaded", DateTime.Now);
    }
  }

The call is coming from here:

        if (GClass51.smethod_0("PredefinedPrioritiesEnabled", false, true) && GClass51.smethod_0("LoadPredefinedPrioritiesAutomatically", true, true) && GClass51.smethod_0("LastPredefinedPrioritiesLoaded", DateTime.MinValue, true) < DateTime.Now.AddDays(-7.0))
        {
          GClass30.smethod_1(false);
        }

There you have it - if you have enabled "Predefined Priorities", NetBalancer will also silently upload all your priorities to their servers.

Want to wreak some havoc with unsuspecting users of NetBalancer? Post your own JSON file that blocks all traffic for all the browsers - apparently NetBalancer doesn't validate user submissions and will happily distribute them to other users. 😀

Abusing existing database

I was also wondering what is the meaning of ExeNameCrc field. 🙂 Turns out that NetBalancer uses CRC32 of filename as a key in the dictionary that manages process priorities To make matters easier, they also supply you with a proper filename in ExecutablePath field. So, if you want to make sure your malware has unlimited traffic and high download priority, just name it swarm.exe:

{
    "$type": "Events.PredefinedPriority, Events",
    "ExeNameCrc": 1475648703,
    "Priority": {
      "$type": "Events.AppPriorityInfo, Events",
      "AdapterId": 1630508967,
      "ExecutablePath": "swarm.exe",
      "DownloadPriority": "High",
      "UploadPriority": "High",
      "DownloadLimit": 0,
      "UploadLimit": 0,
      "DownloadDelay": 0,
      "UploadDelay": 0,
      "DownloadDelayJitter": 0,
      "UploadDelayJitter": 0,
      "DownloadDropRate": 0.0,
      "UploadDropRate": 0.0,
      "PerConnectionLimits": false
    }
  },

Indeed, CRC32("swarm.exe") = 1475648703, as you can verify in some online CRC32 calculator..

A quick test confirms that too:

Conclusion

Trust is a delicate subject. On the one hand, all the Cloud and Connected things make your life much easier. On the other hand, you must choose wisely who you trust and what data he/she can access. I doubt that SeriousBit intentionally created such buggy and dangerous feature in NetBalancer. But that doesn't mean I would ever want it to be running on my machine!

Have fun and stay safe!

Updated Molebox unpacker

kao

During last year, the most common complaint on this blog was "your Molebox unpacker cannot unpack this crazy big EXE of MMORPG game X, Y or Z."

Sounds like an easy problem to fix, right? Well, that's not true - but I finally did it!

TL;DR:

In the rest of the post I'll describe the obstacles I had to overcome while solving this seemingly simple problem.

Delphi TMemoryStream limitation

First, unpacker is written using classic (non-.NET) Delphi and compiled as x86 executable. And standard Delphi streams are retarded. TMemoryStream uses GetMem - which ends up somewhere in Delphi memory manager and VirtualAlloc. That doesn't work well with 800+MB files.

I ended up with implementing custom stream backed by temporary file (CreateFile with FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE).

Pointer magic

Since the original unpacker was using TMemoryStream, the whole file was loaded in memory as a continuous memory block and I could easily read/write each byte of file using pointers. Something like this:

function Decode_Stage2(p: pdword; size: dword; key: dword): dword;
var
   d: dword;
begin
   result := 0;
   d := 0;
   while d < size do begin
      key := key * $19660D + $3C6EF35F;
      p^ := p^ xor key;
      inc(p);
      inc(d, 4);
   end;
end;

...

Decode_Stage2(pointer(dword(f.fImage.Memory) + f.RVAToOffset(startAddress - f.NtHeader.OptionalHeader.ImageBase)), endAddress - startAddress, decryptionKey);

Guess what? Files don't work that way.. 🙁 I had to do a full and complete rewrite of all those methods.

Zlib conflicts

Original unpacker was compiled with Delphi 3. Delphi 3 didn't have Zlib library, so you had to supply your own Zlib implementation. But it won't compile with new versions of Delphi, giving error message

Unit Graphutil was compiled with a different version of zlib.TZDecompressionStream.

The solution was to get rid of my Zlib implementation and rewrite all methods that deal with decompression.

ANSI strings

In Delphi 3 all strings were ANSI. Starting from Delphi 20072009, strings are Unicode. Since Molebox internally uses ANSI, it required changing quite a few structure definitions and rewriting several string manipulation routines. It's a lot of fun (and source of the most obscure bugs), trust me!

Conclusion

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

Moving to a new host

kao

Last week MaxXor suggested that I should add HTTPS support to my blog. My existing free host (bplaced) doesn't offer HTTPS, so I decided to finally switch to paid hosting. After thinking a bit, reading customer references, I chose Active24 - and so far the experience has been overwhelmingly positive.

  • Webhost was set up within minutes, including self-signed HTTPS certificate;
  • As soon as you update your DNS entries, Let's Encrypt certificate is issued automatically. You don't need to do anything yourself!
  • Unlimited disk space;
  • Unlimited traffic;
  • Unlimited cron jobs;
  • And everything "just works™";

For now HTTPS is optional (try https://lifeinhex.com/), I'll start enforcing HTTPS in a few days after fixing all the mixed-content warnings. 🙂

Have fun and stay safe (and let me know if you notice any issues)!