이것저것

IDA Pro 다루기 with Lab05-01.dll 본문

전공/악성코드분석

IDA Pro 다루기 with Lab05-01.dll

신쥔 2022. 11. 23. 06:24

블로그는 1일 1포스팅임이 원칙임을 알지만

 

정말 잘 알고있지만

매일매일 글감이 쏟아지고있지만

그렇지만!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

글감을 위해 공부를 더 할 어어 알죠알죠 그럴 시간이 없습니다.

그러니까 뭐랄까...  프로젝트 하면서 만나는 여러 에러들을 해결하는 과정을 공부해서 쓰고싶은데 프로젝트 마감 기한이 얼마 남지않아 일단 고치고 비공개 포스팅으로 고치기 전 후 과정만 다듬어지지 않은 채로 일단 올려두고 예

 

비공개글이 17개가 되었단 얘깁니다.

 

조금만 기다려주세요.. 종강하자마자 진짜 1일 1포스팅하면서 진짜진짜... 

 

가상머신 글은 언제 올리지? 곧...곧 진짜 곧...곧.........................

그럼에도 꾸준하게 올리는 악성코드분석 공부(사실 과제)

 

그럼 오늘도 화이팅! 화이팅!

 

제목을 보면 예상할 수 있듯이 이번 과제는 IDA Pro를 다루는데 초점을 두겠다.

 

IDA Pro
컴퓨터 소프트웨어용 디스어셈블러로 바이너리 코드를 어셈블리어로 변환해주는 프로그램이다.
이때, IDA는 다른 디스어셈블러와 달리 바이너리 어셈블리어 C언어로 까지 재구성이 가능하다.
코드 분석 시 code section 사이의 상호 참조, API 호출 시 매개변수 그리고 여러 다른 정보들을 이용한다.

 

IDA Pro로 Lab05-01.dll을 분석해보면서 사용법을 차근차근 익혀보자

 

0. 아 뭐 눌러야하는데?

현재 IDA Pro를 구동하고 있는 운영체제는 Windows xp

Lab05-01의 확장자는 .dll (Dynamic load library)

 

뭘 설치하네 뭐네 과정을 거치면 이때 주의할 점이 있는데..

analysis now 를 선택하면 알아서 쫙쫙 분석해서 각 함수들을 그래프로 구조화 해서 보여준다. 혼자 분석을 해버리기 때문에 우리는 분석할 게 없다..!

 

아무튼, analysis now를 해제하고 진행하면 아래와 같은 화면을 볼 수 있다.

 

1.DllMain의 주소는 무엇인가?

 

OllyDbg는 main 함수를 찾아 사방팔장 분기점 확인하고 다녔어야했는데 IDA Pro는 자동으로 main함수에서 시작한다.

DLLMain의 주소는 1000D02E  !

 

2. Imports 윈도우를 이용해 gethostbyname을 탐색해보자. 임포트 위치는 어디인가?

 

IDA Pro은 여러가지 윈도우(창)을 띄우는데, 

 

Imports 윈도우를 띄워, Import 되어있는 여러 함수들을 이름순으로 정렬한 다음 GetHostByName 을 찾아보았다.

근데 있을거라고 예상한 자리에 없다

 

왜...? 왜 없는데? 난 그저 이 과제를 빨리 끝내고 자고싶은 대학생1이라고. 내놔! 어딨어!!!!!!!! 

 

당연하다 없을 수 밖에 없다.

나는 GetHostByName 가 함수명일 줄 알았는데 gethostbyname이 함수명이다.

Import 위치는 100163CC !

 

 

그렇다면 gethostbyname은 어떤 함수일까?

쉽게 말하면 접속할려는 host에 대한 정보를 알아보는 함수이다.

// C++
//syntax

typedef struct hostent {
  char  *h_name;
  char  **h_aliases;
  short h_addrtype;
  short h_length;
  char  **h_addr_list;
} HOSTENT, *PHOSTENT, *LPHOSTENT;


// name == domain name
hostent *WSAAPI gethostbyname(const char *name);

3.gethostbyname 함수를 호출하는 CALL  명령어는 몇 개인가?

 

IDA View-A 창으로 가서 gethostbyname 이 import 되고 있는 위치로 가서 x 를 누르면 

xrefs(External Reference)를 실행할 수 있다.

gethostbyname 함수를 호출하는 CALL  명령어는 총 7개임을 알 수 있다.

 

4.0x10001757에 위치한 gethostbyname 호출을 보면 어떤 DNS 요청이 이뤄지는지 알 수 있는가?

 

DNS, Domain Name System
사람이 읽을 수 있는 도메인 이름(예: www.c-2022YH.space)을 머신이 읽을 수 있는 IP 주소로 변환하는 것

 

....????? 내가 모르는 DNS 정의가 있나?

어떤 도메인을 IP 주소로 변환할려고 하는건지 물어보는건가?

 

일단, 10001757로 이동했다.

아까 getbyhostname가 어떤 함수인지 정리하면서 getbyhostname는 domain name을 매개변수로 받는걸 알게됐었다.

어떤 도메인을 받아오는질 알아야하는데...

 

어셈블리어를 기억을 더듬어 해석해보면

EAX = 10019040(주소, 가 가르키고 있는 값) + 0Dh

 

10019040 위치로 이동해보면 10019040은 1001914와 연결되어있다.

해당 위치로 이동해서 화면을 자세히 보니

 

This is ~ 뭔가 문장이 보인다.

음 그러니까, 10001757에 위치한 gethostbyname는 pics.praticalmalwareanalysis.com을 매개변수로 받는다.

 

이상하다 지금 새벽 4신데 과제가 안끝난다.

나 잘 수 있을까?

 

 

5.0x10001656에 있는 서브루틴에서 IDA Pro는 지역 변수 몇 개를 인지하고 있는가?

 

10001656으로 이동하자

...? 그 어떤 지역변수도 인지하고 있지 않다...

뭘 놓친게 있나? sub routine이 대체 뭘 말하는거지? 내가 알고있는 그 sub routine 일텐데

 

*sub routine == 함수

 

0개

 

6.0x10001656에 있는 서브루틴에서 IDA Pro는 파라미터 몇 개를 인지하고 있는가?

아무...아무것도 없는데요......

 

0개

 

 

 

이 거짓말쟁이 사기꾼들 뭐가 존재한다는거야!

 

7.Strings 윈도우를 이용해 디스어셈블리 내의 문자열 \cmd.exe /c 를 찾아보자. 어디에 있는가?

 

string을 정렬해서 하나씩 뒤져가면서 찾았다

10095B34에 존재한다.

 

8.\cmd.exe /c를 참조하는 코드 영역에서 무슨 일이 발생하는가?

 

해당 주소로 이동을 하면 

나에게 막 master라고 부르면서 ! 막 어!

 

졸린가보다. 

 

다른 전공과목에서 xdoor, 즉 backdoor에 대해 배운 적이 있다.

backdoor는 권한을 몰래 탈취하여 평문 접근, 인증 등을 행하는 방법을 말한다.

 

그렇다면 이 Lab05-01.dll은 권한을 탈취하여 pics.praticalmalwareanalysis.com에 접근하는 악성코드일려나

 

아직 확신하기에는 부족한 점이 많아 보인다. 주석으로 DATA XREF : .text:1001010D0 라고 쓰여있었기 cmd.exe를 실행하는 곳으로 이동해보자

 

 

가장 눈에 띄는 게 GetSystemDirectoryA 함수

GetSystemDirectoryA
system directory의 경로를 검색하는 함수
system directory에는 동적 연결 라이브러리 및 드라이버와 같은 시스템 파일이 포함되어있다.
//C++
//LPSTR lpBuffer 경로를 수신할 버퍼에 대한 포인터 
//UINT  uSize 버퍼의 최대 크기
UINT GetSystemDirectoryA([out] LPSTR lpBuffer, [in]  UINT  uSize);

 

따라서 GetSystemDirectoryA를 이용해 cmd를 강제로 실행시킬려는 것으로 보인다.

 

 

9.같은 영역 0x100101C8에서 dword_1008E5C4는 경로를 지정하는 전역 변수로 보인다. 악성코드는 어떻 dword_1008E5C4를 설정하는가? (힌트 : dword_1008E5C4의 상호 참조를 이용하라)

총 두군데서 참조하는 것을 볼 수 있는데 (마지막 한 군데는 그 자리 그대로) 모두 다 가보기..엔 너무 졸립기도 하고

솔직히 cmp(compare)는 값을 비교해서 분기점이 있을거 같은데

 

질문이 설정하는 방법에 대해 물었기때문에 값의 변화를 주는 mov를 우선으로 확인해보기로 했다.

 

loc_10003695라는 함수를 실행시키고 그 결과값을 eax 저장, eax는 그걸 dword_1008E5C4에 저장

dword_1008E5C4값으로 loc_100036C3라는 함수를 실행시키는데 영향을 주는 것 같다.

 

loc_10003695 함수의 위치로 이동하면 아래 사진과 같은 모습을 볼 수 있는데

박스 친 부분만 좀 눈여겨 보면 될거 같다. (어차피 첫 3줄은 함수 프롤로그로 보인다)

 

GetVersionExA
//C++
//운영 체제 정보를 수신 하는 데이터 구조를 매개변수로 가짐
NOT_BUILD_WINDOWS_DEPRECATE BOOL GetVersionExA([in, out] LPOSVERSIONINFOA lpVersionInformation);

 

음.

아무튼, 운영체제의 정보를 알아와서 EAX에 저장 후

기존에 EAX와 값이 동일한지 XOR 연산을 한 뒤

2와 EBP - 84 의 위치 값과 비교해서

setz al을 함으로써 dword_1008E5C4값을 설정해주는거 같은데

 

당최 그럼 EAX는 왜 대입/계산해준건지...?

 

 

10.0x1000FF58에서 서브루틴으로 수백 라인은 문자열을 비교하기 위한 일련의 memcmp 비교다. Robotwork와 문자열 비교가 성공적으로 이뤄지면 무슨 일이 일어나는가? (memcmp가 0을 반환)

 

우선, 문자열 비교라는 말이 있기때문에, Robotwork 문자열의 위치부터 찾아보자.

 

근데 이 위치까지 왔는데 문제에서 언급한 memcmp는 보이지도 않아서 한참 헤맸다.

 

loc_10014F58이 memcmp이다.

memcmp는 3개의 매개변수를 입력받는데

첫번째 매개변수(문자열 A)와 두번째 매개변수(문자열 B)를 size_t만큼만 비교한 후 int 형 데이터를 반환한다.

 

그 결과(문자열이 동일한지 안한지)에 따라

두 문자열이 다르면 10010468 같으면 100052A2로 이동하게 된다.

 

*memcmp 함수 자체가 문자열이 모두 일치하면 0을 반환하고 그렇지 않으면 0이 아닌 값을 반환한다.

*test 어셈블리어는 AND 연산자 같으면 true(=1) 반환

*jnz 어셈블리어는 0이 아니면 jump

입력된 문자열이 모두 동일하다고 가정했을 때 다음 위치에 도달하는 것을 발견할 수 있다.

레지스트리의 키를 열고 닫는 모습을 볼 수 있다.

 

레지스트리 키를 연 후 에는 loc_1005309로 이동할 것이라고 예측할 수 있는데

loc_1005309 위치로 가면

레지스트리 값을 가져와서 문자열을 정수로 변환한 후 출력하고..

이후에 호출되는 함수들도 크게 신경쓰이는 부분들이 없다.

여기서 네트워크적인 뭔가가 벌어질 거라고 생각했는데 아닌가보다.

 

11.PSLIST 익스포트는 무슨 역할을 하는가?

export 는 함수, 객체 등을 보낼 때 쓰는 사용하는 명령어다.

즉, PSLIST가 무엇을 보내는지 알아야한다.

 

PSLIST는 아래와 같이 구성되어있다. (함수인거 같다)

loc_100036C3이라는 함수를 호출하기에 함수 위치로 이동했더니 9번에서 본 loc_10003695와 굉장히 흡사해보이는 형태의 함수였다.

운영체제에 대한 정보를 어딘가로 넘기고 있음을 알 수 있다.

 

12.그래프 모드를 이용해 sub_10004E79 상호 참조 그래프를 그려보자. 이 함수에 진입하기 위해 호출하는 API 함수는 무엇인가? 해당 API 함수에만 기반을 두고 이 함수를 어떤 이름으로 변경하겠는가?

 

????????????????????????????????

무슨 말인지 하나도 이해 못했다. 이름을 왜 변경해줘야하지..?

 

이일단, loc_10004E79 를 호출하는 위치를 찾아보면

loc_10010420을 호출하는 위치는 10010414

 

이런식으로 꼬리에 꼬리를 물어 함수를 호출하고 있기 때문에, 최초 진입지점을 찾아보면

 

loc_10010357이라는 함수라는 것을 알 수 있다.

 

그래프 모드로 진입을 하면

그저 당황스러운 결과만이 날 기다리고 있다. 왜 이렇게..왜..........왜 ........?

 

아무튼 그래프 모드..에서는 모르겠지만

이런 형태로 이어져있음을 짐작할 수 있다.

 

 

13.DllMain이 직접 호출하는 윈도우 API 함수는 몇 개인가? 두 번째 깊이 (depth of 2)에서 몇 개인가?

 

1번 문제의 정답으로 dllmain의 위치는 1000D02E 라는 것을 알고있다.

해당 위치로 가서 그래프 모드로 진입하면

그래프 모드 진입 위치

dllmain이 직접 호출하고 있는 api(함수)는 strncpy _strnicmp CreateThread 총 3개임을 알 수 있다.

두번째 깊이에서는 strlen 을 호출하고 있다.

 

 

.. 문자열 길이를 알아내는 함수는 왜!?

 

14.0x10001358에서 Sleep 호출이 존재한다 (sleep까지 수 밀리초 값을 파라미터로 갖는 API 함수) 코드 후반부를 보면 이 코드가 수행되려면 프로그램이 얼마동안 sleep 하는가?

 

대체 어디에 sleep 호출이 존재하지?

1001358 주소도 잘 이동했고, sleep 함수가 없는데? 

 

 

 

15.0x10001701에서 소켓을 호출한다. 세 가지 파라미터는 무엇인가?

??????????? socket 함수도 없는다.

이쯤되면 문제가 날 골탕먹이는게 분명하다.

 

그래서.. import 윈도우 창으로 들어와서 socket이 호출되고 있는 위치로 이동했다

socket을 참조하고 있는 곳은 총 7군데

모든 위치를 가보면

 

 

모든 위치에서 6, 1, 2를 매개변수로 받고있다.

 

 

6, 1, 2 가 무슨 의민데?

Socket function
특정 전송 서비스 공급자에 바인딩된 소켓을 만드는 함수
//C++

SOCKET WSAAPI socket([in] int af, [in] int type, [in] int protocol);


//af == 2
//AF_INET
//인터넷 프로토콜 버전 4(IPv4) 주소 패밀리.

//type == 1
//SOCK_STREAM
//OOB 데이터 전송 메커니즘과 함께 순차적이고 신뢰할 수 있는 양방향 연결 기반 바이트 스트림을 제공
//인터넷 주소 계열(AF_INET 또는 AF_INET6)에 TCP(Transmission Control Protocol)를 사용

//protocol == 6
//전송 제어 프로토콜(TCP)
//IPPROTO_TCP
//af 매개변수가 AF_INET 또는 AF_INET6 이고 유형 매개변수가 SOCK_STREAM 일 때 가능한 값

즉, TCP 로 STREAM 형태의 socket을 주고받는데, 그때 사용하는 IP주소의 버전은 4라는 것을 알 수 있다.

 

16. 소켓과 IDA Pro에서 명명한 심볼 상수 기능을 이용해 이 파라미터를 좀 더 유용하게 할 수 있겠는가? 변경 후 파라미터는 무엇인가?

 

명명한 심볼 상수 기능이 무슨 말인가 했더니

그냥 6, 1, 2로 받고있는걸 사람들이 봤을 때 알기 쉽도록 이름을 지어주라는 것 같다.

 

2(af)는 AF_INET, 1(type)은 SOCK_STREAM, 6은 IPPROTO_TCP로 수정해주었다.

 

 

 

과제는 여기까지다.

 

여기까지 끝났는데 무슨 코든지 전혀 알 수가 없어 그저 당황스러움...........

 

1. socket, strlen, regopenkey, regquery~, getsystemdirectory, gethostbyname 함수들이 쓰였다는 점

2. pics.praticalmalwareanalysis.com 라는 url이 발견된 점

 

두 가지를 통해 유추해보면

이번 악성코드는 내 컴퓨터에서 일어나는 이벤트, 컴퓨터 정보 등을 수집하여 pics.praticalmalwareanalysis.com에 전송하는 게 아닐까싶다.

 

 

 

 

 

 

참고 자료

https://ko.wikipedia.org/wiki/IDA_%ED%94%84%EB%A1%9C

 

IDA 프로 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. IDA(Interactive DisAssembler)는 컴퓨터 소프트웨어 용 디스어셈블러이다. 디스어셈블러는 기계어 코드로부터 어셈블리어 소스 코드를 생성한다. 이것은 다양한 실행

ko.wikipedia.org

https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-gethostbyname

 

gethostbyname function (winsock2.h) - Win32 apps

The gethostbyname function (winsock2.h) function retrieves host information corresponding to a host name from a host database.

learn.microsoft.com

https://learn.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-hostent

 

HOSTENT (winsock.h) - Win32 apps

The HOSTENT (winsock.h) structure is used by functions to store information about a given host, such as host name, IPv4 address, and so forth.

learn.microsoft.com

https://reverseengineering.stackexchange.com/questions/30093/how-to-find-function-calls-in-ida-pro

 

How to find function calls in IDA Pro?

I'm analyzing some *.DLL, I found a function such as sub_10151561 () and I would like to know which other functions call this function. How to do it? Thank you in advance.

reverseengineering.stackexchange.com

https://aws.amazon.com/ko/route53/what-is-dns/

 

DNS란 무엇입니까? – DNS 소개 - AWS

12개월 동안 AWS 프리 티어에 액세스하고 연중무휴 24시간 고객 서비스, 지원 포럼 등을 비롯한 AWS Basic Support의 기능을 사용할 수 있습니다. 현재 Amazon Route 53는 AWS 프리 티어에서 제공되지 않는다

aws.amazon.com

https://ko.wikipedia.org/wiki/%EB%B0%B1%EB%8F%84%EC%96%B4

 

백도어 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 시스템 (또는 암호화 시스템, 알고리즘)의 백도어(영어: backdoor)는 일반적인 인증을 통과, 원격 접속을 보장하고 plaintext에의 접근을 취득하는 등의 행동

ko.wikipedia.org

https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya

 

GetSystemDirectoryA function (sysinfoapi.h) - Win32 apps

Retrieves the path of the system directory. (ANSI)

learn.microsoft.com

https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversion

 

GetVersion function (sysinfoapi.h) - Win32 apps

With the release of Windows 8.1, the behavior of the GetVersion API has changed in the value it will return for the operating system version. The value returned by the GetVersion function now depends on how the application is manifested.

learn.microsoft.com

https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket

 

socket function (winsock2.h) - Win32 apps

The socket function creates a socket that is bound to a specific transport service provider.

learn.microsoft.com

 

'전공 > 악성코드분석' 카테고리의 다른 글

기초동적분석 Lab03-03.exe  (1) 2022.11.15
기초정적분석하기, Lab 01-02.exe  (0) 2022.11.06
오랜만에 쓰는, Lena tutorials 3!  (0) 2022.10.04
IAT 총정리  (0) 2022.10.04
lena tutorials 2, JUMP로 해결하기  (0) 2022.09.27