본문 바로가기
일반IT/IT보안

[실습] 악성코드의 심장을 찾아라! 🫀 암호화·네트워크 함수 위치 특정 및 코드 정밀 분석

by gasbugs 2025. 12. 14.

안녕하세요, 끈기 있는 보안 연구원 여러분! 🕵️‍♂️

지난 시간, 우리는 메타데이터(IAT, 문자열)를 통해 악성코드가 "무슨 도구"를 챙겼는지 확인했습니다. "음, 암호화 도구(CryptEncrypt)와 통신 도구(InternetOpen)를 챙겼군. 랜섬웨어 같아!"

하지만 이것만으로는 부족합니다. 범인이 칼을 샀다고 해서 무조건 범죄를 저지른 건 아니죠. "언제, 어디서, 어떻게 그 칼을 휘둘렀는지" 현장을 덮쳐야 합니다.

오늘은 리버스 엔지니어링 도구(Ghidra 또는 IDA)를 사용하여, 악성 행위가 실제로 일어나는 코드의 심장부(Core Logic)를 찾아내고 분석하는 실습을 진행하겠습니다.

이 기술을 익히면 수만 줄의 코드 속에서 헤매지 않고, 단 3번의 클릭으로 핵심 로직으로 이동할 수 있습니다! 🚀


1. 🧭 나침반 준비: 상호 참조(Cross-Reference)의 마법

수만 줄의 어셈블리 코드 중에서 암호화 함수가 어디 숨어있는지 눈으로 찾으려면 밤을 새워도 모자랍니다. 이때 사용하는 치트키가 바로 상호 참조(X-Ref, Cross-Reference)입니다.

💡 상호 참조란? "이 함수(API)를 누가 호출했어?"라고 묻는 기능입니다. 책 뒤에 있는 '색인(Index)'과 똑같습니다. 단어를 찾으면 그 단어가 쓰인 페이지 번호를 알려주는 것과 같죠.


2. [실습 1] 암호화 로직(Ransomware Core) 위치 특정 🔐

랜섬웨어의 본질은 '파일 암호화'입니다. 이 현장을 잡아봅시다.

🛠️ 도구: Ghidra (무료) 또는 IDA Pro 📂 타겟 API: CryptEncrypt (또는 WriteFile)

👣 Step-by-Step 추적

  1. Symbol Tree(심볼 트리) 열기: Ghidra 우측의 Symbol Tree 창에서 Imports 폴더를 엽니다.
  2. API 검색: ADVAPI32.DLL 안에 있는 CryptEncrypt를 찾습니다.
  3. X-Ref 확인:
    • CryptEncrypt 함수 이름 위에서 우클릭 -> Show References to (또는 단축키 Ctrl+Shift+F)를 누릅니다.
  4. 현장 급습 (Jump): 목록에 뜬 주소(예: FUN_00401000)를 더블 클릭합니다.

🎯 도착! 화면이 이동한 그곳이 바로 파일을 암호화하는 루프(Loop)가 돌아가는 현장입니다. 주변을 보면 XOR 연산을 하거나, 파일 내용을 버퍼에 담는 코드가 보일 겁니다.


3. [실습 2] 네트워크 연결(C2 Communication) 위치 특정 🌐

해커에게 정보를 빼돌리거나 키를 받아오는 통신 구간을 찾아봅시다.

📂 타겟 API: InternetOpenUrl, HttpSendRequest, socket, connect

👣 Step-by-Step 추적

  1. 문자열(Strings)로 찾기: 이번엔 API 말고 문자열로 찾아봅시다.
    • 상단 메뉴 Search -> Strings 클릭.
    • http, https 또는 의심스러운 IP 주소를 검색합니다.
  2. X-Ref 확인:
  3. 현장 급습: 해당 문자열을 사용하는 함수로 이동합니다.

🎯 도착! 이곳을 분석하면 "어떤 데이터를, 어떤 방식(GET/POST)으로, 어디로 보내는지" 정확히 알 수 있습니다.


4. 🧠 [심화] AI와 함께하는 코드 영역 분석

함수 위치를 찾았는데, 막상 코드를 보니 외계어(uVar1, param_2...) 투성이죠? 이곳이 바로 지난 시간에 배운 AI의 능력을 200% 활용할 지점입니다.

📝 디컴파일 코드 분석 프롬프트

Ghidra의 Decompile 창에 있는 C 코드를 복사해서 AI에게 이렇게 물어보세요.

[요청] 아래 C 코드는 CryptEncrypt API를 호출하는 함수입니다. 리버스 엔지니어링 도구로 추출하여 변수명이 엉망입니다.

  1. 이 함수의 작동 원리를 단계별로 설명해 주세요.
  2. 변수 local_14, param_1 등이 실제로는 어떤 역할(파일 핸들, 버퍼, 키 등)을 하는지 추론해 주세요.
  3. 이 코드를 이해하기 쉬운 Python 의사 코드(Pseudocode)로 변환해 주세요.

[코드] (Ghidra에서 복사한 코드 붙여넣기)

AI는 문맥을 읽고 "local_14는 파일 핸들이고, 루프를 돌며 1024바이트씩 읽어서 암호화하고 있네요!"라고 명쾌하게 해석해 줍니다.


5. ⚠️ 분석 시 주의할 점 (함정 피하기)

  1. 동적 로딩 (Dynamic Loading):
    • 똑똑한 악성코드는 Imports 목록에 API를 숨깁니다.
    • 대신 LoadLibrary와 GetProcAddress를 써서 실행 중에 API를 불러옵니다.
    • 만약 Imports에 찾는 API가 없다면, GetProcAddress를 추적해야 합니다.
  2. 래퍼 함수 (Wrapper Function):
    • 악성코드 제작자가 MyEncrypt라는 함수를 만들고 그 안에서 CryptEncrypt를 부르는 경우가 많습니다.
    • X-Ref를 따라갔는데 코드가 너무 짧다면, 그 함수를 호출하는 상위 함수(Caller)로 한 단계 더 올라가야 전체 그림이 보입니다.

🎉 마치며: 숲을 보고 나무를 베자!

오늘 우리는 드넓은 코드의 숲에서 '악성 행위'라는 나무가 어디 심어져 있는지 정확히 찾아내는 법을 배웠습니다.

  • 상호 참조(X-Ref)는 지도(Map)입니다.
  • 디컴파일러(Ghidra)는 번역기입니다.
  • AI는 가이드입니다.

이 세 가지를 조합하면, 아무리 복잡한 악성코드라도 그 핵심 로직을 낱낱이 파헤칠 수 있습니다.

이제 여러분은 "이 파일 악성이에요"를 넘어, "이 파일 내부 0x401000 주소에 있는 함수가 AES-256으로 파일을 암호화합니다"라고 말할 수 있는 전문가가 되었습니다.

다음 시간에는 지금까지의 모든 분석 내용을 종합하여 "실무형 악성코드 분석 보고서"를 작성하는 대망의 피날레를 장식해 보겠습니다. 기대해 주세요! 👋