파이썬스터디

PE 파일 생성 및 YARA 패턴 작성 실습

0v0k 2025. 3. 26. 21:51

YARA

악성코드 탐지 및 파일 분석을 위한 패턴 매칭 도구

규칙을 만들어서 파일이 정상인지 악성인지 구별하는 프로그램

파일 또는 메모리 내 특정 패턴을 기반으로 탐지 가능

특정 문자열이 포함된 경우를 탐지하거나, 파일에서 특정한 바이너리 코드가 존재하는지 확인 가능

 

rule smaple //룰 이름
{
	meta: //설명
       author = ""
       type = ""
       filetype = ""
       version = ""
       date = ""
       description = ""
      
    strings:
    	&str = "" //텍스트 스트링 형태
        &hex = {} //hex 스트링 형태
        $re = // //정규표현식 형태
        
    condition:
    	all of them //모든 스트링에 적용
}

meta : 주석

strings : 텍스트 스트링, hex 스트링, 정규 표현식 형태로 작성

               텍스트 스트링 : "" 사이에 작성, 대소문자 구분

                hex 스트링  : {} 사이에 작성, {3 10 F2 A3 A?}처럼 사용 가능

                정규표현식 : // 사이에 작성

condition : stirngs 에서 사용된 식별자를 이용해 condition 구문 작성, Boolean값으로만 결과 나타난다

                   all of them : 모든 스트링에 적용

                   any of them : 스트링 중 최소 하나 적용

                   all of ($a) : &a로 시작되는 모든 스트링에 적용

                   any of (&a, &b, &c)* : &a, &b, &c 중 최소 하나 적용

PE(Portable Executable) 파일 

윈도우 실행파일, 윈도우 OS에서 사용되는 실행파일 형식을 의미 

exe, scr 등이 있음 

Linux나 Unix에는 PE파일과 비슷한 형식으로 ELF (Executable and Linkable Format)파일 존재

출처 : https://rninche01.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%8B%A4%ED%96%89%ED%8C%8C%EC%9D%BC-%EA%B5%AC%EC%A1%B0PE%ED%8C%8C%EC%9D%BC

PE 구조

- 다양한 정보들이 PE Header에 구조체 형식으로 저장

- 파일에서는 offset, 메모리에서는 VA로 위치를 표현 

   offset : 파일의 첫 바이트부터 거리

   VA : 프로세스 가상 메모리의 절대 주소

 

PE 기본구조 파일 생성 및 YARA 기본 패턴 생성 실습 

https://github.com/virustotal/yara/releases/ 에서  yara 다운로드

yara64 --help 명령어를 통해 설치 확인 가능

 

YARA 룰셋 테스트를 위한 PE 파일 생성 

: 생성형 AI(Claude, Chat GPT) 이용 

 

[ 입력 프롬프트 ]

PE 기본 구조 파일 생성 및 YARA 기본 패턴 생성하는 실습을 하려고 해. 
다음 요구사항에 맞는 PE 파일을 생성하는 파이썬 코드를 작성해줘.

1. 3개의 섹션을 가지고 있어.

2. 생성된 파일 크기가 5KB보다 작아야 해.

3. 의심스러운 API를 사용해줘

4. 난독화된 문자열 패턴을 포함해줘. 

아래의 문자열을 Base64로 인코딩해줘. 

"http://malicious.example.com/payload",
"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
"cmd.exe /c powershell -enc {}"

5. 실행 압축된 코드 섹션을 추가해줘. XOR로 인코딩된 가짜 쉘코드를 포함해서 코드 난독화를 시켜줘.

6. Anti-VM 체크 코드 섹션을 추가해줘. 악성코드 분석 방해를 위한 가상머신 탐지를 위한 Dummy 어셈블리 코드를 포함해줘. 

 

[ 결과 ]

더보기
import struct
import base64

# XOR 인코딩 함수 (간단한 난독화)
def xor_encode(data, key=0x55):
    return bytes([b ^ key for b in data])

# 악성 문자열을 Base64로 인코딩
malicious_strings = [
    "http://malicious.example.com/payload",
    "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
    "cmd.exe /c powershell -enc {}"
]
encoded_strings = [base64.b64encode(s.encode()).decode() for s in malicious_strings]

# DOS 헤더: "MZ" 시그니처와 e_lfanew (PE 헤더 위치) 설정
dos_header = b'MZ' + b'\x00' * 58 + struct.pack('<I', 0x80)  # e_lfanew = 0x80

# PE 시그니처 및 HEADER
pe_signature = b'PE\x00\x00'
file_header = struct.pack('<HHIIIHH', 0x014c, 3, 0, 0, 0, 224, 0x103)  # **섹션 3개 설정**

# Optional Header
optional_header = b'\x00' * 96

# PE 섹션 테이블 추가 (.text, .data, .rsrc)
section1 = b'.text\x00\x00\x00' + b'\x00' * 32
section2 = b'.data\x00\x00\x00' + b'\x00' * 32
section3 = b'.rsrc\x00\x00\x00' + b'\x00' * 32  # **3개의 섹션만 유지**

# XOR로 인코딩된 가짜 쉘코드 (압축된 실행 코드 역할)
fake_shellcode = xor_encode(b"\x90\x90\xCC\xCC\xE8\xFF\xFF\xFF\xFF", key=0x55)

# Anti-VM 탐지 코드 (가짜 어셈블리 코드)
anti_vm_code = b"\x0F\x3F\x07\x0F\x22\xD8\x0F\x22\xD9"

# PE 헤더 조립
pe_header = pe_signature + file_header + optional_header + section1 + section2 + section3

# PE 파일 구성
padding = b'\x00' * (0x80 - len(dos_header))
malicious_pe = dos_header + padding + pe_header

# 추가 데이터 삽입 (의심스러운 API, Base64 난독화 문자열, XOR 인코딩된 코드, Anti-VM 코드)
malicious_pe += b"\x00" * 512  # 빈 공간 패딩
malicious_pe += b"CreateRemoteThread VirtualAlloc"  # 의심스러운 API
malicious_pe += b"\x00" * 16
malicious_pe += b" ".join([s.encode() for s in encoded_strings])  # Base64 난독화된 악성 문자열
malicious_pe += b"\x00" * 16
malicious_pe += fake_shellcode  # XOR 인코딩된 쉘코드
malicious_pe += b"\x00" * 16
malicious_pe += anti_vm_code  # Anti-VM 코드

# 파일 크기가 5KB 미만인지 확인
if len(malicious_pe) >= 5120:
    malicious_pe = malicious_pe[:5119]

# 파일 저장
with open("step2_malicious_pe.exe", "wb") as f:
    f.write(malicious_pe)

print("Malicious PE 파일 생성 완료: step2_malicious_pe.exe, 파일 크기:", len(malicious_pe))

위의 코드를 실행하면 exe파일이 저장된다. 

2KB이므로 5KB이내인 것을 확인할 수 있다.

 

HxD

이진 파일을 읽을 수 있는 무료 에디터 프로그램

https://mh-nexus.de/en/hxd/ 에서 다운로드 

 

exe파일을 불러와서 열면 이진코드와 내용을 확인할 수 있다. 

PE구조 정의

MZ : DOS 실행 파일 서명 

PE파일임을 확인 가능

.text, .data, .rsrc 섹션 확인 가능 

악성 문자열 확인 가능 

- 의심스러운 API 

- Base64로 난독화된 악성문자열

- XOR 인코딩된 가짜 쉘코드

- AntiVM 탐지 코드

 

이를 토대로 YARA 룰셋 제작

.yar 파일! 

import "pe"

rule Detect_Custom_PE_Advanced {
    meta:
        author = "KB"
        description = "PE 파일: .text 섹션 존재, 섹션 수 3(03 00), 파일 크기 5KB 미만, 악성 기능 포함"

    strings:
        // 기본 요구사항 (섹션 이름 및 개수)
        $text_section = ".text"
        $num_sections = { 03 00 }

        // 의심스러운 API 탐지
        $suspicious_api = "CreateRemoteThread VirtualAlloc"

        // Base64 난독화된 악성 문자열 탐지
        $encoded_url = "aHR0cDovL21hbGljaW91cy5leGFtcGxlLmNvbS9wYXlsb2Fk" // "http://malicious.example.com/payload"
        $encoded_reg = "SEtFWV9MT0NBTF9NQUNISU5FXFNvZnR3YXJlXE1pY3Jvc29mdFxXaW5kb3dzXEN1cnJlbnRWZXJzaW9uXFJ1bg==" // 레지스트리 Run 키
        $encoded_cmd = "Y21kLmV4ZSAvYyBwb3dlcnNoZWxsIC1lbmMge30=" // PowerShell 명령 실행

        // XOR 인코딩된 가짜 쉘코드 탐지
        $xor_shellcode = { C5 C5 99 99 BD AA AA AA AA }

        // Anti-VM 탐지 코드
        $anti_vm_code = { 0F 3F 07 0F 22 D8 0F 22 D9 }

    condition:
        // PE 파일인지 확인
        pe.number_of_sections == 3

        // 섹션 이름과 개수 확인
        and $text_section and $num_sections

        // 파일 크기가 5KB 미만인지 확인
        and filesize < 5KB

        // 추가 탐지 조건 (악성 기능 포함 여부)
        and $suspicious_api
        and $encoded_url
        and $encoded_reg
        and $encoded_cmd
        and $xor_shellcode
        and $anti_vm_code
}

 

 

YARA룰셋을 토대로 exe파일을 탐지했을 때 성공적으로 탐지한 것을 확인할 수 있다. 

-섹션 3개, 의심스러운 API 탐지, 난독화된 악성 문자열 탐지, XOR 인코딩된 가짜 쉘코드 탐지, Anti-VM 탐지가 완료되면 

Detect_Custom_PE_Advanced step2_malicious_pe.exe 문구가 뜬다. 

warning: rule "Detect_Custom_PE_Advanced" in step2_detect_pe.yar(11): string "$num_sections" may slow down scanning

이 경고 메시지는 문자열 탐지가 스캔 속도를 느리게 할 수 있음을 알려주는 경고 메시지이다.  

 

이와 같이 악성코드의 특징을 YARA룰로 정의해 탐지할 수 있다.