악성코드 분석

DoS 공격분석 (feat. IDA)

JNU 2023. 1. 14. 00:46
반응형

 

 

 

 

이번 시간에는 악의적인 행위를 하는 악성코드를 분석해보려고 해

저번 시간까지 써보지 않았던 IDA라는 disassembly tool을 이용해서 

해당 code를 깊게 분석해 보고 ollydbg를 통해서 함수의 흐름도 같이 알아보도록 할게

자, 바로 가보자고~

 

 

먼저 간단한 string 분석을 해보니까 MalService, 악성 URL, IE와 버전 등의 값이 존재하는 것을 볼 수 있어

internet 접속을 통해서 어떠한 악성 program을 진행시키는 것 같은데

string 분석만으로 다 알기 어려우니 IDA를 통해서 code의 흐름을 좀 더 정확하게 파악해 볼게

string 분석을 좀 더 해보면 어느정도 감이 잡힐 수 있겠지만 오늘은 바로 IDA 분석을 통해서 code의 흐름을 파악해볼게

먼저 함수의 시작 지점인 main으로 가보자~

 

 

 

IDA로 main함수의 시작점을 확인해 보니까 StartServiceCtrlDispatcherA라는 API 함수와

subroutine_401040을 호출하는 것을 볼 수 있어

subroutine을 실행하기 전에 먼저 API를 호출한다는 것을 보고 바로 API와 IDA를 통해 분석을 해본 결과...!

 

 

 

 

 

 

StartServiceCtrlDispatcherA 함수가 보이지?

이 함수는 프로세스의 main 스레드를  서비스 제어 관리자(SCM)로 연결하는 서비스에 의해 사용되는 함수야

SCM은 윈도우 service process와 시작과 정지 및 상호작용 하는 특별한 시스템 프로세스인데

간단하게 이야기하자면 service database를 관리하는 system program이라고 할 수 있어

SCM은 services.msc 명령으로 내역들을 확인할 수 있어!

 

 

 

현재 이 함수가 앞으로 어떻게 작용할지 더 알아봐야겠지만 실행하려는 servie의 이름이 MalService인 것을 알 수 있고

해당 service process를 subroutine 401040을 통해서 실행시킨다는 것도 알게 됐어!

그렇다면 subroutine 401040에는 어떤 함수들이 들어있는지 확인해 봐야겠지?

 

 

 

subroutine이 시작되자마자 API들을 왕창 불러오고 있어... (왜 이렇게 많은 거야..!)

일단 중요한 API들을 확인해 보면

OpenMutexA

ExitProcess

CreateMutexA

OpenSCManagerA

 

각각의 API들에 대한 정의와 parameter들을 정리해 볼게

 

 

 

1. OpenMutexA: 기존에 존재하는 뮤텍스 열기

뮤텍스 = 동시 프로그래밍에서 공유 불가능한 자원의 동시 사용을 피하기 위해 사용하는 알고리즘
즉, 동시에  program을 실행시키지 않도록 하는 알고리즘

- dwDesiredAccess: 뮤텍스 개체에 대한 access 권한 
- bInheritHandle: 값이 true 즉, 1일 경우 해당 process에서 만든 process가 handle을 상속한다.
                            1이 아닌 0이므로  process는 handle을 상속하지 않는다.
- IpName: 뮤텍스의 이름 = HGL345

현재 뮤텍스가 존재하지 않아 상속될 수 없고 다음 API를 보면 새롭게 뮤텍스를 생성하는 것을 볼 수 있어

 

 

 

해당 함수가 call이 되고 밑에 test eax, eax 가 실행되는 것 보이지?

즉,  이미 실행되고 있을 경우에는  jz 401064를 통해서 해당 프로세스를 종료하게 돼 (ExitProcess)

하지만, 실행되지 않았더라면 다음 분기로 넘어가서 createmutexa를 실행하게 되지!

그러면 어떻게 뮤텍스를 생성하는지 자연스럽게 넘어가 보자~

 

 

 

2. CreateMutexA: 새로운 뮤텍스 생성하기

- lpMutexAttributes: 해당 값이 0이므로 뮤텍스의 기본 보안 설명자를 가져온다. (default로 설정된다는 뜻)

- bInitialOwner: 해당 값이 true이고 호출자가 뮤텍스를 만든 경우 호출 스레드는 뮤텍스 개체의 초기 소유권을 갖는다.

                         하지만, 0 이기 때문에 호출 스레드는 뮤텍스의 소유권을 얻지 못한다.

- lpName = HGL345

 

 

 

3. OpenSCMangagerA: 지정된 컴퓨터의 서비스 제어관리자에 대한 연결을 설정하고 database를 연다.

- lpMachineName: 대상 컴퓨터의 이름 = null

- lpDatabaseName: 서비스 제어 관리자 database 이름 = null

- dwDesiredAccess: 서비스 제어 관리자에 대한 access 권한 =3

 

 

 

이후에 맨 아래의 CreateServiceA를 호출하기 위해

OpenSCMManagerA, GetCurrentProcess, GetModuleFileNameA API를 순차적으로 호출

- OpenSCMManagerA : 프로그램이 서비스를 추가하거나 수정할 수 있는 서비스 제어 관리자 핸들 반환

                                      기존에 남아있는 것이 없으니 서비스를 추가하겠지?

- GetCurrentProcess : 현재 프로세스의 핸들 반환 

- GetModuleFileNameA : 첫째 인자가 0인 경우, 현재 동작중인 실행 파일이나 로드된 DLL의 전체 경로명 반환

                                        실행한 파일이름이 들어감

 

 

이제 마지막으로 대망의  CreateServiceA  함수!

해당 함수는 hexray로 어떻게 이뤄져 있는지 같이 보자고~

C언어로 보니까 훨씬 더 잘 보이지?

 

 

CreateServiceA: service 개체를 만들고 지정된 SCM DB에 추가! (service 만들고 database에 저장한다는 뜻)

해당 API 함수는 어떻게 이뤄져있는지 확인해 보자

 



- hscmanager: 서비스 제어 관리자 DB에 대한 handle
- IpServiceName: 설치할 service의 이름 최대 256자
- IpDisplayName: service를 식별하기 위해 사용자 int program에서 사용할 표시 이름 
                            (service, displayname = Malservice)

- dwDesiredAccess: service에 대한 access.
access 권한 부여하기 전에 system은 호출 process의 access token을 확인한다.

SC_MANAGER_CREATE_SERVICE (0x0002) CreateService 함수를 호출하여 서비스 개체를 만들고
데이터베이스에 추가하는 데 필요


- dwServiceType: service 유형

0x10 --> 자체 process에서 실행되는 service


- dwStartType: service 시작 option
0x02 --> system 시작 중에 SCM이 자동으로 시작한 service

 

- dwErrorControl: service가 시작되지 않는 오류의 심각도 및 조치
0x00 --> 시작 program은 오류를 무시하고 시작 작업을 계속진행

 

 

해당 service는 위의 parameter 대로 이름은 Malservice이고

system 시작 중에 SCM이 자동으로 실행시키는 service라는 것을 알 수 있어

 

여기까지 함수의 흐름을 정리해보자면...

 

1. dispatch 함수를 통해서 SCM에 스레드가 접근할 수 있도록 한다.
2. 이 때 service의 이름을 Malservice로 설정하고 
3.  Malservice를 system 실행과 동시에 자동으로 실행하도록 설정한다.

 

service 자체를 생성하여 지속적으로 system 안에서 실행되도록 하는 것을 알 수 있겠지?

 

 

 

 

CreateServiceA 함수를 실행한 이후에 시간과 날짜에 대한 정보를 수집하는 것을 볼 수 있어

먼저 SystemTimeToFileTime 함수를 통해서 system 시간을  file 시간 형식으로 바꾸게 되는데

hexray로  좀 더 자세하게 살펴볼게

 

 

systemtime에서 year, week, hour, second를 불러오는 것을 볼 수 있는데

이 중에서 year에 대한 값을 2100으로 설정하는 것을 볼 수 있어

즉, 해당 연도에 대한 값을 2100년으로 지정하고 나머지는 default이므로 1월 1일로 날짜를 지정하고

해당 날짜까지 대기를 하도록 하는 프로그램을 만드는 것이라고 유추해 볼 수 있겠지?

 

CreateWaitableTimerA: 대기 가능한 타이머 개체를 만들거나 open을 한다.

SetWaitableTimer: 지정된 대기 가능 타이머를 활성화합니다.

WaitForSingleObject: 지정된 개체가 신호 상태가 되거나 시간제한 간격이 경과할 때까지 기다립니다.

                                   현재 0 xFFFFFFFF 만큼 시간제한을 두고 있다.

CreateThread: 스레드를 새롭게 생성하거나 연다.

Sleep: program 실행을 일정 시간 동안 멈춘다.

 

 

정리하자면 SetWaitableTimer 함수를 통해 일정 시간동안 program 실행에 있어 대기시간을 걸어놓고

총 20개의 스레드를 생성하게 되는데, 생성과정을 보면 Startaddress라는 함수를 호출하게 돼

이때 실행시키는 주소가 무엇인가 하고 봤더니......

 

 

 

Startaddress 함수는 CreateThread의 IpStartAddress 인자값에서 실행하고 있는데 

IpStartAddress 인자의 역할은 스레드의 시작 주소를 나타내

즉, http://www.malwareanalysisbook.com이라는 주소로 URL을 시작주소로 설정하는 것을 볼 수 있어

그렇게 20개의 스레드를 다 생성하여 while문을 탈출하면 sleep 함수로 넘어가는데...

 

 

 

오랜 시간 동안 잠들어버리게 되는 프로그램인 것을 알 수 있어 ㅜㅜ......

여기까지 우리가 분석한 것을 정리하면 다음과 같이 악성코드를 분석해 볼 수 있어!

 

 

 

해당 프로그램의 목적은 특정 시간대에 수행되는 DDoS 공격이고 

2100년 1월 1일까지 공격이 진행되고 http://www.malwareanalysisbook.com으로

분산 서비스 공격을 실행하는 것을 볼 수 있어

그리고 해당 프로그램은 종료되지 않고 2100년 1월 1일까지 20개의 스레드를 동작시켜 무한루프를 진행하게 돼

여기까지가 오늘 분석한 악성 code의 내용이야!

오늘도 여기까지~

 

 

 

 

 

반응형