13 Security Lab

Windows 서비스 바이너리 디버깅하려면? 본문

Computer Security/Analysis

Windows 서비스 바이너리 디버깅하려면?

Maj0r Tom 2021. 2. 22. 14:52

윈도우즈 서비스 프로그램 디버깅하는 방법에 대해서 요약한다.

Windows 서비스 프로그램은 Windows 실행파일은 맞지만 실행되는 방식이 exe, dll과는 조금 다르다.

서비스 바이너리를 디버깅 할 때 어떻게 다른지 알아보고, 디버깅하는지 요약해본다.

 

Windows 서비스 ?

리눅스의 데몬과 그 개념이 유사하며, 백그라운드로 실행되는 프로세스이다.

지속적으로 백그라운드에서 실행시킬 프로그램을 윈도우즈 세션으로 실행시킬 수 있다.
서비스는 컴퓨터가 부팅될 때 자동으로 실행되고, 잠시 멈추거나 재시작 할수있다. 또 유저 인터페이스에는 나타나지 않는다. 

보통 서비스들은 svchost.exe를 통하여 DLL로 메모리에 로드되어 실행된다.

EXE 형태로 독립적인 프로세스로 동작하는 서비스와, 다른 DLL서비스와 함께 하나의 프로세스 svchost.exe 에서 동작하는 형태가 있다.

Service 동작 원리

Windows 내에서 서비스가 동작하기까지의 순서를 간략하게 표현한다.

SCM과 서비스의 관계는 파이프 통신으로 이루어진다. SCM이 생성한 파이프 이름을 서비스에서 열고 서로 통신하게 된다. 
서비스는 SCM으로부터 자신의 서비스 이름을 얻고 자신의 서비스를 열 수 있는지 검사한다. 

열 수 있다면 CreateThread로 자신의 서비스 메인을 실행한다. 이때부터 서비스 메인이 실행된다. 
SvcMain은 개념적으로 StartServiceCtrlDispatcher 가 리턴됨과 동시에 SCM에서 호출되지만, 실제로는 StartServiceCtrlDispatcher 함수에서 CreateThread 를 통해 SvcMain을 호출하게 된다.

Windows Internals 'service'

 

 



Service Control Manager

Service Control Manager (SCM) 는 WindowsNT 시스템 내 특별한 프로세스 중에 하나이고, 윈도우즈 서비스와 통신 상호작용하면서 서비스를 start, stop, restart 등 제어한다. 실행파일은 %SystemRoot%\System32\services.exe 경로에 존재한다.

서비스 프로세스는 Windows API를 통해 SCM과 상호적으로 통신하며, 같은 API가 서비스 관리도구 MMC(services.msc)  와 커맨드라인 서비스 유틸리티 sc.exe 에서도 사용한다. 당연하지만 services.exe 를 끄거나 삭제하면 블루스크린이 뜬다.

 

Service Controller

service controller(sc.exe), mmc(services.msc) 같은 서비스 관리도구

example) sc create [Service Name] binpath=[Service File Path]

SC(Service Controller) 내부적으로 OpenSCManager, OpenService, StartService가 호출된다.

 

Windows 서비스 디버깅 방법

방법1 - 서비스 실행 시 디버거 실행 되도록 레지스트리 설정

IEFO(Image File Execution Options) + WinDbg Network(Remote) Debug
디버거 붙여서 원격디버깅

Image File Execution Options (IFEO) 는 프로세스를 시작할 때 자동으로 디버깅을 설정하는 데 주로 사용된다. 
서비스 실행파일 이름으로 된 서브키를 만든다. 그리고 Value 값으로 "Debugger" Data 값에 디버거로 붙일 프로그램의 full path 를 넣어준다.

IFEO레지스트리 경로
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options

원격 디버깅을 해야하는 이유는 디버거가 Session 0 (서비스 세션)에서 실행되기 때문에 디버거의 UI가 보이지 않게 되기 때문이다. (Desktop은 session 1 이고, 매핑 된 데스크톱이 없기 때문에 사용자 화면에서 보이지 않음)

 

방법2 - 서비스 DLL 디버거로 강제분석

SCM부터 디버깅? EIP 강제 세팅해서 분석

1. Set on EP, execution halt by (0xEB 0xFE) (JMP REL8 -2, opcodes: 0xEB 0xFE)

RVA 39E1 -> DATA : 0xEB 0xFE

 

2 EAT ServiceMain에 무한루프점프(0xEB 0xFE) 세팅

RVA 1E20 -> DATA : 0xEB 0xFE

 

3 Ollydbg에 직접 로드

ServiceMain() 위치로 EIP를 설정 후 디버깅 시작

 

원래 서비스에서는 SCM에 의해 실행되므로해당 API를 실행하게 되면정상적인 서비스 실행이 되지 않아 Terminate된다

아래 위치(RegisterServiceCtrlHandlerExA())에서 함수 Call 부분 다음으로 EIP를 수정하여 API를 넘어가도록 수정한다.

 

이 후, 디버깅을 진행한다.

 

방법3 - 서비스 정상 실행시 제어권 가져오기

서비스 설치후 서비스 바이너리 EP코드에 무한루프 설치 -> 서비스 실행 디버그 attach ep복구 ep코드 부터 분석

Dll의 EP가 아닌 ServiceMain 부분에 IP hijacking 필요하다.

 

 

서비스 등록 및 재실행

1) 서비스 정상적인 등록절차

Win10 (Win7 이상)
(EXE) sc create "MyService" binPath="C:\Users\Desktop\MyTestService.exe" start=auto DisplayName="Windows Test Service" error=ignore

(DLL)
sc create "MyService" binPath="C:\windows\system32\svchost.exe -k [ServiceName]" start=auto DisplayName="Windows Test Service" error=ignore

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[servicename]\Description
Key: [ServiceMain] Data: "THis is Test Service Desc"

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[servicename]\Parameters
Key: ServiceDll Data: [ServiceDllPath] // REG_EXPAND_SZ
Key: "ServiceMain" Data: "ServiceMain" // REG_S

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost
Key: [ServiceName] Data: [ServiceName]    // (REG_MULTI_SZ)

*x86 서비스
x64 OS에서 x86 서비스 DLL 은 아래 레지스트리 경로에 써져야 한다.
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Svchost\[ServiceName]

 

WinXP 이전 A ancient OS

instsrv 서비스이름 서비스경로

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\servicename

ImagePath 를 ~\system32\svchost.exe -k [ServiceKeyword]

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[ServiceName]\parameters

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Svchost

[ServiceKeyword] Key -> ServiceName

 



2)    등록된 서비스의 위치 확인 및 서비스(servicesmsc)의 해당 서비스 중지


3)    서비스의 HEX값을 0xEB 0xFE로 수정하여 실행상태로 루프를 돌도록 수정

4)    서비스 재 실행 후 Attach

디버깅을 위한 타임아웃 설정 변경 

충분히 길게 변경한다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Name: ServicesPipeTimeout
Type: REG_DWORD
Data: The number of milliseconds that you want to give the services to start in.



 

▶ Introduction to Windows Service Applications

Comments