Day 6 of C# Advent - Coding for an encrypted service

Welcome to the 6th day of the C# Advent! Let's encrypt some malware.

That sounds horrible, but in security testing, sometimes you have to use the tools of the bad guy to make sure you aren't likely to be susceptible to any attacks. There are many such tools, but a new one - one that takes instructions from an HTTP web server - was developed by Dave Kennedy of TrustedSec. Called TrevorC2, it is a Python Command and Control server with a variety of clients.  The attacker would install the client on the target workstation, and have a server delivering commands.  In this case, it is over HTTP.  And one of the clients is in C#.  And encrypted in AES.

Wait, what?  AES?  Really?  

Yes, really.  Companies look for certain strings that are common in command and control servers moving across their networks.  So, the attackers encrypt things! How do we find it then?  Well, that's not our problem at the moment - we just need to figure out how to replicate what the bad guys are doing.  So, that's the task for this day of the C# Advent - implement AES in C# that will talk nice to a Python command an control server over HTTP.  

Fortunately, most of it I have written.  The communication bits in C# are pretty straightforward, but the encryption piece is not at all.  When I started, I wanted to use System.Security.Cryptography.Aes, but guess what?  It ain't that easy.  The Python client encryption method looks like this:

    def encrypt(self, raw):
        raw = self._pad(AESCipher.str_to_bytes(raw))
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw)).decode('utf-8')

 

My initial take was something like this for an encrypt method:

        static string Encrypt(string target)
        {
            byte[] result = null;
            try
            {
                if (target == null || target.Length <= 0)
                    throw new ArgumentNullException("plainText");

                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = Cipher;
                    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                    using (MemoryStream msEncrypt = new MemoryStream())
                    {
                        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                        {
                            using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                            {
                                swEncrypt.Write(target);
                            }
                            result = msEncrypt.ToArray();
                        }
                    }
                }
            }
            catch(Exception e)
            {
                Console.Write(e.Message);
            }
            return Encoding.ASCII.GetString(result);
        }

That didn't work.  So, I did what any good senior developer would do.  I buckled down, focused, and looked for a library written by someone smarter than me. Fortunately, Adam Caudill is out there with libsodium.net, a C# implementation of the well known NaCl library. There's the solution I needed.

Libsodium.net is a living breathing example of how complicated encryption can be.  NaCl is a very well known implementation of the main encryption protocols ... in C.  Yeah, C.  You can use it in other languages but C is what NaCl is for.

The chem majors among us will recognize that NaCl is table salt.  Thus, Sodium.  Libsodium is a higher level library for C++ and ilk, and then Adam's implementation uses the .NET native libraries to perform the same tasks.  It's a reasonable legacy, and you should consider it if you have to write encryption code, as, well, I do right now.

Anyway, the interface is SUPER easy to use.  The SecretBox holds everything you need, including the abilityto generate the nonce required for the AES encryption, and to do the actual work.

So, my NEW method, after adding libsodium.net, looks like this:

        static string Encrypt(string target)
        {
            try
            {
                var nonce = SecretBox.GenerateNonce();
                var result = SecretBox.Create(target, nonce, Cipher);
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
            }
            return Encoding.ASCII.GetString(result);
        }

Tune back in next week, after I get my Trevor server up and running, and we'll get everything configured and working. (Remember, play with malware on a network that is not your employer's network!) 

 

Comments (2) -

Patrick Kursawe
12/6/2017 11:11:54 AM #

Sodium is an alkaline metal, not table salt. Table salt is sodium chloride (https://en.wikipedia.org/wiki/Sodium_chloride).
So it's just someone too lazy to write the full name.
Looks really easy to use, though - for people like me who are lazy.

Bill Sempf
12/6/2017 1:31:54 PM #

The original library is NaCl, which is table salt. That's what I was trying to get across.  And yes, I like me some lazy.

Add comment

Bill Sempf

Husband. Father. Pentester. Secure software composer. Brewer. Lockpicker. Ninja. Insurrectionist. Lumberjack. All words that have been used to describe me recently. I help people write more secure software.

PageList

profile for Bill Sempf on Stack Exchange, a network of free, community-driven Q&A sites

MonthList