Services

Presenter Notes

What

What services are

Installing Services

How Malware uses services

Finding hidden services

Presenter Notes

Services

Non-interactive background processes.

Commonly run with higher privileges than the user

What runs as services?

  • Anti-virus
  • Event-logging
  • Print spooler
  • Firewall
  • DHCP Client
  • Application updaters
  • Network monitoring

Presenter Notes

Service Architecture

Installed services located in HKLM/SYSTEM/CurrentControlSet/Services

services

Presenter Notes

Subkeys

Each service has a subkey with various values that describe how and when the service starts.

Also shows if the service is for a process, DLL or kernel driver.

dhcp

Presenter Notes

Components

components

Presenter Notes

Installing Services

Manually with sc.exe

Batch Scripts

  • Malware commonly drops and executes batch scripts
  • Creates disk artifacts

Windows API

  • CreateService and StartService.
  • SC.exe is front end to API
  • CreateService adds a subkey to the registry and StartService leaves logs

Windows Management Instrumentation (WMI)

Presenter Notes

Sc.exe

How to install service with sc?

@echo off
set SERVICENAME="Malware"
set BINPATH="c:\bin\malware.dll"

sc create "%SERVICENAME" binPath= "%SystemRoot%\system32\svchost.exe" -k "%SERVICENAME" type= share start= auto

reg add "HKLM\System\CurrentCOntrolSet\Services\%SERVICENAME\Parameters" /v ServiceDll /t REG_EXPAND_SZ /d "%BINPATH%" /f

sc start %SERVICENAME%



Presenter Notes

WinAPI


SC_HANDLE WINAPI CreateService(
  _In_       SC_HANDLE hSCManager,
  _In_       LPCTSTR lpServiceName,
  _In_opt_   LPCTSTR lpDisplayName,
  _In_       DWORD dwDesiredAccess,
  _In_       DWORD dwServiceType,
  _In_       DWORD dwStartType,
  _In_       DWORD dwErrorControl,
  _In_opt_   LPCTSTR lpBinaryPathName,
  _In_opt_   LPCTSTR lpLoadOrderGroup,
  _Out_opt_  LPDWORD lpdwTagId,
  _In_opt_   LPCTSTR lpDependencies,
  _In_opt_   LPCTSTR lpServiceStartName,
  _In_opt_   LPCTSTR lpPassword
);


BOOL WINAPI StartService(
  _In_      SC_HANDLE hService,
  _In_      DWORD dwNumServiceArgs,
  _In_opt_  LPCTSTR *lpServiceArgVectors
);

Presenter Notes

Start Types

| Name                 | Hex  |
|----------------------|------|
| SERVICE_AUTO_START   | 0x02 |
| SERVICE_BOOT_START   | 0x00 |
| SERVICE_DEMAND_START | 0x03 |
| SERVICE_DISABLED     | 0x04 |
| SERVICE_SYSTEM_START | 0x01 |

Presenter Notes

Service Types

| Name                        | Hex  |
|-----------------------------|------|
| SERVICE_ADAPTER             | 0x04 |
| SERVICE_FILE_SYSTEM_DRIVER  | 0x02 |
| SERVICE_KERNEL_DRIVER       | 0x01 |
| SERVICE_RECOGNIZER_DRIVER   | 0x08 |
| SERVICE_WIN32_OWN_PROCESS   | 0x10 |
| SERVICE_WIN32_SHARE_PROCESS | 0x20 |

Presenter Notes

Installing Services with Stealth

Create required registry keys

Call NdrClientCall

  • Interface for StartService

Call NtLoadDriver

  • Loads Kernel drver service

Both methods AVOID event logs!

After service starts, just delete registry keys!

Presenter Notes

Stopping Services

Some malware will stop services

  • net stop
  • ControlService from WinAPI
  • TerminateProcess from WinAPI

Look at stopped and running services!

Wscsvr = Windows Security Center Wuauserv = Windows Auto Update WinDefend = Windows Defender WerSvc = Windows Error Reporting

Presenter Notes

Services on a Live System

Services MMC snap-in

servicesMMC

Presenter Notes

Services on a Live System

PowerShell cmdlet Get-Service

PS C:\Users\topher> Get-Service

Status   Name               DisplayName
------   ----               -----------
Running  AeLookupSvc        Application Experience
Stopped  ALG                Application Layer Gateway Service
Stopped  AppIDSvc           Application Identity
Running  Appinfo            Application Information
Stopped  aspnet_state       ASP.NET State Service
Running  AudioEndpointBu... Windows Audio Endpoint Builder
Running  AudioSrv           Windows Audio
Stopped  AxInstSV           ActiveX Installer (AxInstSV)
Stopped  BDESVC             BitLocker Drive Encryption Service
Running  BFE                Base Filtering Engine
Running  BITS               Background Intelligent Transfer Ser...
Stopped  Browser            Computer Browser
Stopped  bthserv            Bluetooth Support Service
Stopped  CertPropSvc        Certificate Propagation
Stopped  clr_optimizatio... Microsoft .NET Framework NGEN v2.0....
Stopped  clr_optimizatio... Microsoft .NET Framework NGEN v2.0....
Stopped  clr_optimizatio... Microsoft .NET Framework NGEN v4.0....
Stopped  clr_optimizatio... Microsoft .NET Framework NGEN v4.0....
Stopped  COMSysApp          COM+ System Application
Running  CryptSvc           Cryptographic Services
Running  DcomLaunch         DCOM Server Process Launcher
Stopped  defragsvc          Disk Defragmenter
Running  Dhcp               DHCP Client
Running  Dnscache           DNS Client
Stopped  dot3svc            Wired AutoConfig
Running  DPS                Diagnostic Policy Service
Running  EapHost            Extensible Authentication Protocol

Presenter Notes

Services on a Live System

Sc.exe and Query

C:\Users\topher>sc query
DISPLAY_NAME: Power
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (NOT_STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

SERVICE_NAME: ProfSvc
DISPLAY_NAME: User Profile Service
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

Presenter Notes

Services in Memory

Event Logs

Registry Keys

Services for invalid states

Unlinked Service Records

Hijacked Services

Presenter Notes

SCM in Memory

SCM maintains a linked-list of installed services

Magic = Serv or serH

Undocumented

>>> dt("_SERVICE_HEADER")
 '_SERVICE_HEADER' (None bytes)
0x0   : Tag                            ['array', 4, ['unsigned char']]
0xc   : ServiceRecord                  ['pointer', ['_SERVICE_RECORD']]



>>> dt("_SERVICE_RECORD")
 '_SERVICE_RECORD' (None bytes)
0x0   : ServiceList                    ['_SERVICE_LIST_ENTRY']
0x8   : ServiceName                    ['pointer', ['String', {'length': 512, 'encoding': 'utf16'}]]
0xc   : DisplayName                    ['pointer', ['String', {'length': 512, 'encoding': 'utf16'}]]
0x10  : Order                          ['unsigned int']
0x18  : Tag                            ['array', 4, ['unsigned char']]
0x24  : DriverName                     ['pointer', ['String', {'length': 256, 'encoding': 'utf16'}]]
0x24  : ServiceProcess                 ['pointer', ['_SERVICE_PROCESS']]
0x28  : Type                           ['Flags', {'bitmap': {'SERVICE_KERNEL_DRIVER': 0, 'SERVICE_WIN32_OWN_PROCESS': 4, 'SERVICE_WIN32_SHARE_PROCESS': 5, 'SERVICE_INTERACTIVE_PROCESS': 8, 'SERVICE_FILE_SYSTEM_DRIVER': 1}}]
0x2c  : State                          ['Enumeration', {'target': 'long', 'choices': {1: 'SERVICE_STOPPED', 2: 'SERVICE_START_PENDING', 3: 'SERVICE_STOP_PENDING', 4: 'SERVICE_RUNNING', 5: 'SERVICE_CONTINUE_PENDING', 6: 'SERVICE_PAUSE_PENDING', 7: 'SERVICE_PAUSED'}}]
0x44  : Start                          ['Enumeration', {'target': 'long', 'choices': {0: 'SERVICE_BOOT_START', 1: 'SERVICE_SYSTEM_START', 2: 'SERVICE_AUTO_START', 3: 'SERVICE_DEMAND_START', 4: 'SERVICE_DISABLED'}}]

>>> dt("_SERVICE_PROCESS")
 '_SERVICE_PROCESS' (None bytes)
0x8   : BinaryPath                     ['pointer', ['String', {'length': 256, 'encoding': 'utf16'}]]
0xc   : ProcessId                      ['unsigned int']

Presenter Notes

Position in the list of ServiceList (only a prevois pointer) indicates start time. typically alphabetically

Win7 has only a

0x0 : prevEntry ['_SERVICE_LIST_ENTRY']

SvcScan

Pool tag scan for Windows services

[root&windows]#volatility -f Lab2.vmem --profile=WinXPSP2x86 svcscan
Volatility Foundation Volatility Framework 2.4
Offset: 0x671e90
Order: 1
Start: SERVICE_DISABLED
Process ID: -
Service Name: Abiosdsk
Display Name: Abiosdsk
Service Type: SERVICE_KERNEL_DRIVER
Service State: SERVICE_STOPPED
Binary Path: -

Offset: 0x671fb0
Order: 3
Start: SERVICE_BOOT_START
Process ID: -
Service Name: ACPI
Display Name: Microsoft ACPI Driver
Service Type: SERVICE_KERNEL_DRIVER
Service State: SERVICE_RUNNING
Binary Path: \Driver\ACPI

Presenter Notes

Recently Created

Registry keys are updated with a last write timestamp when service is created or modified

Scan all timestamps and view latest ones

>>> import volatility.plugins.registry.registryapi as registryapi
>>> regapi = registryapi.RegistryApi(self._config)
>>> key = "ControlSet001\Services"
>>> subkeys = regapi.reg_get_all_subkeys("system", key)
>>> services = dict((s.Name, int(s.LastWriteTime)) for s in subkeys)
>>> times = sorted(set(services.values()), reverse=True)
>>> top_three = times[0:3]
>>> for time in top_three:
...   for name, ts in services.items():
...     if ts == time:
...       print time, name
...
1428376879 driver
1428206878 pmem
1428106135 DMusic
1428106135 swmidi
1428106135 drmkaud
1428106135 kmixer
1428106135 aec

Presenter Notes

Cross reference with svcscan

If you find keys, are they in svcscan?

Malware can hide from SCM

Check if service is running

  1. Find driver name from registry
  2. Scan drivers with modules

Presenter Notes

[root&windows]#volatility -f Lab2.vmem --profile=WinXPSP2x86 printkey -K 'ControlSet001\Services\kmixer'
Volatility Foundation Volatility Framework 2.4
Legend: (S) = Stable   (V) = Volatile

----------------------------
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\system
Key name: kmixer (S)
Last updated: 2015-04-04 00:08:55 UTC+0000

Subkeys:
  (S) Security
  (V) Enum

Values:
REG_DWORD     Type            : (S) 1
REG_DWORD     Start           : (S) 3
REG_DWORD     ErrorControl    : (S) 1
REG_EXPAND_SZ ImagePath       : (S) system32\drivers\kmixer.sys
REG_SZ        DisplayName     : (S) Microsoft Kernel Wave Audio Mixer

[root&windows]#volatility -f Lab2.vmem --profile=WinXPSP2x86 modules | grep kmixer.sys
Volatility Foundation Volatility Framework 2.4
0x81ee42a0 kmixer.sys           0xb1564000    0x2b000 \SystemRoot\system32\drivers\kmixer.sys

Presenter Notes

Hijacked Services

Attackers can change path in registry of a service to point to malware .exe, .dll, etc.

Can also overwrite existing DLL or binary

Mandiant APT1 Report shows a lot of 61938 malware hijacks and installs services

APT1 Samples

Presenter Notes

Detecting Hijacked Paths

Use svcscan and look for ServiceDll and Binary Paths

Compare them with paths from an uninfected system

Pull hypothesized malicious binary out of capture and analyze

[root&windows]#volatility -f Lab2.vmem --profile=WinXPSP2x86 svcscan -v | egrep '(ServiceDll|Binary Path)'
Volatility Foundation Volatility Framework 2.4
ServiceDll: %SystemRoot%\system32\alrsvc.dll
Binary Path: C:\WINDOWS\System32\alg.exe
ServiceDll: %SystemRoot%\System32\appmgmts.dll
Binary Path: C:\WINDOWS\System32\svchost.exe -k netsvcs
ServiceDll: %SystemRoot%\System32\audiosrv.dll
Binary Path: \Driver\audstub
Binary Path: \Driver\Beep
ServiceDll: C:\WINDOWS\system32\qmgr.dll
ServiceDll: %SystemRoot%\System32\browser.dll

Presenter Notes

Get a Baseline of Service DLLs

import pywintypes, win32api, win32con

def main():

  w32 = win32con

  read_flags = (w32.KEY_READ |
    w32.KEY_ENUMERATE_SUB_KEYS | 
    w32.KEY_QUERY_VALUE)

  hkey = win32api.RegOpenKeyEx(w32.HKEY_LOCAL_MACHINE, 
    "System\\ControlSet001\\Services", 
    0, 
    read_flags)

  keys = [data[0] for data in win32api.RegEnumKeyEx(hkey)]

  for name in keys:

    try:

      subkey = win32api.RegOpenKeyEx(
        hkey,
        "%s\\Parameters" % name,
        0,
        read_flags)

      value = win32api.RegQueryValueEx(
        subkey,
        "ServiceDll")

    except pywintypes.error:
      continue

    path = win32api.ExpandEnvironmentStrings(value[0])
    name = name.lower()
    path = path.lower()

    if path.find("c:\windows") != -1: 
      path = path.replace("c:\windows", "%SYSTEMROOT%")
      print "%s" % (path)

if __name__ == "__main__":
  main()

Presenter Notes

And use them

c:\Python27>python.exe Scripts\serviceDll.py
%SYSTEMROOT%\system32\aelupsvc.dll
%SYSTEMROOT%\system32\appidsvc.dll
%SYSTEMROOT%\system32\appinfo.dll
[SNIP]


[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 svcscan -v | grep ServiceDll 
ServiceDll: %SystemRoot%\system32\wdi.dll
ServiceDll: %SystemRoot%\system32\wdi.dll
ServiceDll: %SystemRoot%\System32\WcsPlugInService.dll
ServiceDll: %SystemRoot%\System32\wcncsvc.dll
ServiceDll: %SystemRoot%\System32\wbiosrvc.dll
ServiceDll: %systemroot%\system32\w32time.dll
ServiceDll: %SystemRoot%\system32\wpdbusenum.dll
ServiceDll: %SystemRoot%\System32\wpcsvc.dll
ServiceDll: %SystemRoot%\System32\wlansvc.dll
ServiceDll: %SystemRoot%\system32\WsmSvc.dll
ServiceDll: %SystemRoot%\System32\wscsvc.dll
ServiceDll: %SystemRoot%\System32\wwansvc.dll
ServiceDll: %SystemRoot%\System32\WUDFSvc.dll
ServiceDll: %systemroot%\system32\wuaueng.dll

Presenter Notes

Detecting Hijacked disk Binaries

Malware can just overwrite a binary on disk

Hard to detect

Hashing from Volatility and on disk does not work

Look at artifacts of DLL

Dump DLLs and compare them to ones of disk

Presenter Notes

Dump All Dlls from Services

  1. Svcscan to list all ServiceDlls
  2. Dump files that matched above output
  3. Run each file through virus scanner or analyze
  4. ???
  5. Profit


[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 svcscan -v | grep ServiceDll > serviceDlls
[root&windows]#sed 's/ServiceDll: %SystemRoot%\\System32\\//gI' serviceDlls > serviceDllSed

[root&windows]#cat serviceDllSed | while read dll; do volatility -f Win7.bin --profile=Win7SP0x86 dlldump -r $dl^C-D serviceDllDump/; done

Presenter Notes

VirusTotal

Run each file through virus scanner or analyze

VirusTotal is a free service that analyzes suspicious files and URLs and facilitates the quick detection of viruses, worms, trojans, and all kinds of malware.

Use the VirusTotal API to scan all the DLLs that were dumped

VirusTotal Public API keys are free

Presenter Notes

API

I used https://github.com/Gawen/virustotal as main module

import virustotal
import os
from os import path

indir = '/root/amf/windows/serviceDllDump/'

virus = virustotal.VirusTotal('API_KEY_HERE')

fileNames = filter(path.isfile, os.listdir(indir))

for f in fileNames:
  print(f)
  report = virus.scan(f)
  report.join()
  assert report.done == True
  print "Report"
  print "- Resource's UID:",report.id
  print "- Scan's UID:", report.scan_id
  print "- Permalink:" ,report.permalink
  print "- Resource's MD5:", report.md5
  print "- Resource's status:", report.status
  print "- Antivirus' total:", report.total
  print "- Antivirus's positives:", report.positives

Presenter Notes

Results

Note: Permalink lets you see VirusTotal results from web

module.352.3dc5b420.71330000.dll
Report
- Resource's UID: 8b641606bef10135ba8ef342a99f41dde8be69af53dd039ba3834fe0c8c36010-1428875468
- Scan's UID: 8b641606bef10135ba8ef342a99f41dde8be69af53dd039ba3834fe0c8c36010-1428875468
- Permalink: https://www.virustotal.com/file/8b641606bef10135ba8ef342a99f41dde8be69af53dd039ba3834fe0c8c36010/analysis/1428875468/
- Resource's MD5: a58b2a03fe4edbebd43c12a4564ce9ae
- Resource's status: Scan finished, information embedded
- Antivirus' total: 56
- Antivirus's positives: 0

Virus sandboxes are not end all be all, but there are a good start!

Takes a minute or two per DLL... run then go to lunch! :)

Presenter Notes

EOF

Presenter Notes