# 맬웨어 분석 {{#include ../../banners/hacktricks-training.md}} ## 포렌식 치트시트 [https://www.jaiminton.com/cheatsheet/DFIR/#](https://www.jaiminton.com/cheatsheet/DFIR/) ## 온라인 서비스 - [VirusTotal](https://www.virustotal.com/gui/home/upload) - [HybridAnalysis](https://www.hybrid-analysis.com) - [Koodous](https://koodous.com) - [Intezer](https://analyze.intezer.com) - [Any.Run](https://any.run/) ## 오프라인 안티바이러스 및 탐지 도구 ### Yara #### 설치 ```bash sudo apt-get install -y yara ``` #### 규칙 준비 이 스크립트를 사용하여 github에서 모든 yara malware rules을 다운로드하고 병합하세요: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ _**rules**_ 디렉토리를 생성하고 실행하세요. 그러면 모든 yara rules for malware가 포함된 _**malware_rules.yar**_ 파일이 생성됩니다. ```bash wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py mkdir rules python malware_yara_rules.py ``` #### 스캔 ```bash yara -w malware_rules.yar image #Scan 1 file yara -w malware_rules.yar folder #Scan the whole folder ``` #### YaraGen: malware 검사 및 yara rules 생성 바이너리에서 yara rules를 생성하기 위해 [**YaraGen**](https://github.com/Neo23x0/yarGen) 도구를 사용할 수 있습니다. 다음 튜토리얼을 참조하세요: [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/) ```bash python3 yarGen.py --update python3.exe yarGen.py --excludegood -m ../../mals/ ``` ### ClamAV #### 설치 ``` sudo apt-get install -y clamav ``` #### 스캔 ```bash sudo freshclam #Update rules clamscan filepath #Scan 1 file clamscan folderpath #Scan the whole folder ``` ### [Capa](https://github.com/mandiant/capa) **Capa**는 실행 파일(PE, ELF, .NET)에서 잠재적으로 악의적인 **기능**을 탐지합니다. 따라서 Att\&ck 전술이나 다음과 같은 의심스러운 기능들을 찾아냅니다: - check for OutputDebugString error - run as a service - create process 설치는 [**Github repo**](https://github.com/mandiant/capa)에서 받으세요. ### IOCs IOC는 Indicator Of Compromise의 약자입니다. IOC는 일부 잠재적으로 원치 않는 소프트웨어나 확인된 **malware**를 식별하는 **조건들의 집합**입니다. Blue Teams는 이러한 정의를 사용해 자신들의 **시스템**과 **네트워크**에서 이러한 종류의 악성 파일을 **검색합니다**.\ 이 정의들을 공유하는 것은 매우 유용합니다. 한 컴퓨터에서 malware가 식별되어 해당 malware에 대한 IOC가 생성되면, 다른 Blue Teams가 이를 사용해 malware를 더 빠르게 식별할 수 있기 때문입니다. IOC를 생성하거나 수정하는 도구는 [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\ 또한 [**Redline**](https://www.fireeye.com/services/freeware/redline.html)과 같은 도구를 사용해 **장치에서 정의된 IOCs를 검색**할 수 있습니다. ### Loki [**Loki**](https://github.com/Neo23x0/Loki) 는 Simple Indicators of Compromise를 위한 스캐너입니다.\ 탐지는 네 가지 탐지 방법에 기반합니다: ``` 1. File Name IOC Regex match on full file path/name 2. Yara Rule Check Yara signature matches on file data and process memory 3. Hash Check Compares known malicious hashes (MD5, SHA1, SHA256) with scanned files 4. C2 Back Connect Check Compares process connection endpoints with C2 IOCs (new since version v.10) ``` ### Linux Malware Detect [**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/)는 GNU GPLv2 license 하에 배포되는 Linux용 malware scanner로, 공유 호스팅 환경에서 직면하는 위협을 중심으로 설계되었습니다. 네트워크 에지 intrusion detection systems로부터의 위협 데이터를 이용해 공격에 실제로 사용되는 malware를 추출하고 탐지용 signatures를 생성합니다. 또한 위협 데이터는 LMD checkout feature를 통한 사용자 제출과 malware community resources에서도 파생됩니다. ### rkhunter Tools like [**rkhunter**](http://rkhunter.sourceforge.net) can be used to check the filesystem for possible **rootkits** and malware. ```bash sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress] ``` ### FLOSS [**FLOSS**](https://github.com/mandiant/flare-floss)는 실행 파일 내의 난독화된 문자열을 다양한 기법으로 찾아내려고 시도하는 도구입니다. ### PEpper [PEpper ](https://github.com/Th3Hurrican3/PEpper)는 실행 파일 내부의 몇 가지 기본 항목(binary data, entropy, URLs and IPs, some yara rules)을 검사합니다. ### PEstudio [PEstudio](https://www.winitor.com/download)는 Windows 실행 파일의 imports, exports, headers 등의 정보를 얻을 수 있게 해주는 도구이며, 또한 virus total을 확인하고 잠재적인 Att\&ck 기법을 찾아냅니다. ### Detect It Easy(DiE) [**DiE**](https://github.com/horsicq/Detect-It-Easy/)는 파일이 **암호화된**지 여부를 감지하고 **packers**도 찾아내는 도구입니다. ### NeoPI [**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)은 다양한 **통계적 방법**을 사용하여 텍스트/스크립트 파일 내의 **난독화된** 및 **암호화된** 콘텐츠를 탐지하는 Python 스크립트입니다. NeoPI의 의도된 목적은 숨겨진 **web shell 코드**의 **탐지**를 돕는 것입니다. ### **php-malware-finder** [**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder)는 **난독화된**/**의심스러운 코드**와 malwares/webshells에서 자주 사용되는 **PHP** 함수들을 사용하는 파일들을 탐지하는 데 최선을 다합니다. ### Apple Binary Signatures 어떤 **malware sample**을 확인할 때는 바이너리의 **서명을 확인**해야 합니다. 서명한 **developer**가 이미 **malware**와 **관련되어** 있을 수 있기 때문입니다. ```bash #Get signer codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier" #Check if the app’s contents have been modified codesign --verify --verbose /Applications/Safari.app #Check if the signature is valid spctl --assess --verbose /Applications/Safari.app ``` ## 탐지 기법 ### File Stacking If you know that some folder containing the **files** of a web server was **last updated on some date**. **Check** the **date** all the **files** in the **web server were created and modified** and if any date is **suspicious**, check that file. ### Baselines If the **files** of a folder **shouldn't have been modified**, you can calculate the **hash** of the **original files** of the folder and **compare** them with the **current** ones. Anything modified will be **suspicious**. ### Statistical Analysis When the information is saved in **logs** you can **check statistics like how many times each file of a web server was accessed as a web shell might be one of the most**. --- ### Android in-app native telemetry (no root) Android에서는 다른 JNI 라이브러리들이 초기화되기 전에 작은 로거 라이브러리를 프리로딩하여 대상 앱 프로세스 내부의 native code를 계측할 수 있습니다. 이렇게 하면 시스템 전역 훅이나 root 없이도 native 동작을 조기에 관찰할 수 있습니다. 널리 쓰이는 접근법은 SoTap입니다: 적절한 ABI에 맞는 libsotap.so를 APK에 넣고 초기에 System.loadLibrary("sotap") 호출을 삽입(예: static initializer 또는 Application.onCreate)한 뒤, internal/external 경로나 Logcat을 통해 로그를 수집합니다. See the Android native reversing page for setup details and log paths: {{#ref}} ../../mobile-pentesting/android-app-pentesting/reversing-native-libraries.md {{#endref}} --- ## Deobfuscating Dynamic Control-Flow (JMP/CALL RAX Dispatchers) Modern malware families heavily abuse Control-Flow Graph (CFG) obfuscation: instead of a direct jump/call they compute the destination at run-time and execute a `jmp rax` or `call rax`. A small *dispatcher* (typically nine instructions) sets the final target depending on the CPU `ZF`/`CF` flags, completely breaking static CFG recovery. The technique – showcased by the SLOW#TEMPEST loader – can be defeated with a three-step workflow that only relies on IDAPython and the Unicorn CPU emulator. ### 1. Locate every indirect jump / call ```python import idautils, idc for ea in idautils.FunctionItems(idc.here()): mnem = idc.print_insn_mnem(ea) if mnem in ("jmp", "call") and idc.print_operand(ea, 0) == "rax": print(f"[+] Dispatcher found @ {ea:X}") ``` ### 2. dispatcher byte-code 추출 ```python import idc def get_dispatcher_start(jmp_ea, count=9): s = jmp_ea for _ in range(count): s = idc.prev_head(s, 0) return s start = get_dispatcher_start(jmp_ea) size = jmp_ea + idc.get_item_size(jmp_ea) - start code = idc.get_bytes(start, size) open(f"{start:X}.bin", "wb").write(code) ``` ### 3. Unicorn으로 두 번 에뮬레이트하기 ```python from unicorn import * from unicorn.x86_const import * import struct def run(code, zf=0, cf=0): BASE = 0x1000 mu = Uc(UC_ARCH_X86, UC_MODE_64) mu.mem_map(BASE, 0x1000) mu.mem_write(BASE, code) mu.reg_write(UC_X86_REG_RFLAGS, (zf << 6) | cf) mu.reg_write(UC_X86_REG_RAX, 0) mu.emu_start(BASE, BASE+len(code)) return mu.reg_read(UC_X86_REG_RAX) ``` `run(code,0,0)` 및 `run(code,1,1)`을 실행하여 *false* 및 *true* 분기 타겟을 얻습니다. ### 4. 직접적인 jump / call 복원 ```python import struct, ida_bytes def patch_direct(ea, target, is_call=False): op = 0xE8 if is_call else 0xE9 # CALL rel32 or JMP rel32 disp = target - (ea + 5) & 0xFFFFFFFF ida_bytes.patch_bytes(ea, bytes([op]) + struct.pack('