What services are
Installing Services
How Malware uses services
Finding hidden services
Non-interactive background processes.
Commonly run with higher privileges than the user
What runs as services?
Installed services located in HKLM/SYSTEM/CurrentControlSet/Services
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.
Manually with sc.exe
Batch Scripts
Windows API
Windows Management Instrumentation (WMI)
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%
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
);
| Name | Hex |
|----------------------|------|
| SERVICE_AUTO_START | 0x02 |
| SERVICE_BOOT_START | 0x00 |
| SERVICE_DEMAND_START | 0x03 |
| SERVICE_DISABLED | 0x04 |
| SERVICE_SYSTEM_START | 0x01 |
| 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 |
Create required registry keys
Call NdrClientCall
Call NtLoadDriver
Both methods AVOID event logs!
After service starts, just delete registry keys!
Some malware will stop services
Look at stopped and running services!
Wscsvr = Windows Security Center Wuauserv = Windows Auto Update WinDefend = Windows Defender WerSvc = Windows Error Reporting
Services MMC snap-in
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
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
Event Logs
Registry Keys
Services for invalid states
Unlinked Service Records
Hijacked Services
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']
Position in the list of ServiceList (only a prevois pointer) indicates start time. typically alphabetically
Win7 has only a
0x0 : prevEntry ['_SERVICE_LIST_ENTRY']
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
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
If you find keys, are they in svcscan?
Malware can hide from SCM
[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
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
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
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()
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
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
[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
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
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
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! :)
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |