AdaptixC2 ๊ตฌ์ฑ ์ถ์ถ ๋ฐ TTPs
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
AdaptixC2๋ Windows x86/x64 beacons(EXE/DLL/service EXE/raw shellcode) ๋ฐ BOF๋ฅผ ์ง์ํ๋ ๋ชจ๋์์ ์คํ์์ค postโexploitation/C2 ํ๋ ์์ํฌ์ ๋๋ค. ์ด ํ์ด์ง๋ ๋ค์์ ๋ฌธ์ํํฉ๋๋ค:
- RC4โpacked configuration์ด ์ด๋ป๊ฒ ํฌํจ๋์ด ์๋์ง์ beacon์์ ์ด๋ฅผ ์ถ์ถํ๋ ๋ฐฉ๋ฒ
- HTTP/SMB/TCP ๋ฆฌ์ค๋์ ๋ํ ๋คํธ์ํฌ/ํ๋กํ ์งํ
- ์ค์ ์ฌ๋ก์์ ๊ด์ฐฐ๋ ์ผ๋ฐ์ ์ธ loader ๋ฐ persistence TTPs์ ๊ด๋ จ Windows technique ํ์ด์ง๋ก์ ๋งํฌ
Beacon ํ๋กํ ๋ฐ ํ๋
AdaptixC2๋ ์ธ ๊ฐ์ง ์ฃผ์ beacon ํ์ ์ ์ง์ํฉ๋๋ค:
- BEACON_HTTP: ์๋ฒ/ํฌํธ/SSL, method, URI, headers, userโagent ๋ฐ custom parameter name์ ์ค์ ํ ์ ์๋ web C2
- BEACON_SMB: namedโpipe ๊ธฐ๋ฐ์ peerโtoโpeer C2 (intranet)
- BEACON_TCP: ์ง์ ์์ผ ๋ฐฉ์, ์ ํ์ ์ผ๋ก ํ๋กํ ์ฝ ์์์ ๋๋ ํํ๊ธฐ ์ํ ์ ํ ๋ง์ปค(prepended marker) ํฌํจ ๊ฐ๋ฅ
HTTP beacon ๊ตฌ์ฑ(๋ณตํธํ ํ)์์ ๊ด์ฐฐ๋๋ ์ผ๋ฐ์ ์ธ ํ๋กํ ํ๋:
- agent_type (u32)
- use_ssl (bool)
- servers_count (u32), servers (array of strings), ports (array of u32)
- http_method, uri, parameter, user_agent, http_headers (lengthโprefixed strings)
- ans_pre_size (u32), ans_size (u32) โ ์๋ต ํฌ๊ธฐ ํ์ฑ์ ์ฌ์ฉ
- kill_date (u32), working_time (u32)
- sleep_delay (u32), jitter_delay (u32)
- listener_type (u32)
- download_chunk_size (u32)
์์ ๊ธฐ๋ณธ HTTP ํ๋กํ (beacon ๋น๋์์):
{
"agent_type": 3192652105,
"use_ssl": true,
"servers_count": 1,
"servers": ["172.16.196.1"],
"ports": [4443],
"http_method": "POST",
"uri": "/uri.php",
"parameter": "X-Beacon-Id",
"user_agent": "Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20121202 Firefox/20.0",
"http_headers": "\r\n",
"ans_pre_size": 26,
"ans_size": 47,
"kill_date": 0,
"working_time": 0,
"sleep_delay": 2,
"jitter_delay": 0,
"listener_type": 0,
"download_chunk_size": 102400
}
๊ด์ฐฐ๋ ์ ์ฑ HTTP ํ๋กํ(์ค์ ๊ณต๊ฒฉ):
{
"agent_type": 3192652105,
"use_ssl": true,
"servers_count": 1,
"servers": ["tech-system[.]online"],
"ports": [443],
"http_method": "POST",
"uri": "/endpoint/api",
"parameter": "X-App-Id",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36",
"http_headers": "\r\n",
"ans_pre_size": 26,
"ans_size": 47,
"kill_date": 0,
"working_time": 0,
"sleep_delay": 4,
"jitter_delay": 0,
"listener_type": 0,
"download_chunk_size": 102400
}
์ํธํ๋ ๊ตฌ์ฑ ํจํน ๋ฐ ๋ก๋ ๊ฒฝ๋ก
์ด์์๊ฐ builder์์ Create๋ฅผ ํด๋ฆญํ๋ฉด, AdaptixC2๋ ์ํธํ๋ ํ๋กํ์ผ์ beacon์ tail blob์ผ๋ก ์๋ฒ ๋ํฉ๋๋ค. ํ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- 4 ๋ฐ์ดํธ: ๊ตฌ์ฑ ํฌ๊ธฐ (uint32, littleโendian)
- N ๋ฐ์ดํธ: RC4โ์ํธํ๋ ๊ตฌ์ฑ ๋ฐ์ดํฐ
- 16 ๋ฐ์ดํธ: RC4 ํค
beacon loader๋ ๋์์ 16โbyte ํค๋ฅผ ๋ณต์ฌํ๊ณ Nโbyte ๋ธ๋ก์ ์ ์๋ฆฌ์์ RC4๋ก ๋ณตํธํํฉ๋๋ค:
ULONG profileSize = packer->Unpack32();
this->encrypt_key = (PBYTE) MemAllocLocal(16);
memcpy(this->encrypt_key, packer->data() + 4 + profileSize, 16);
DecryptRC4(packer->data()+4, profileSize, this->encrypt_key, 16);
์ค๋ฌด์ ์์ฌ์ :
- ์ ์ฒด ๊ตฌ์กฐ๋ ์ข ์ข PE .rdata ์น์ ๋ด๋ถ์ ์์นํฉ๋๋ค.
- ์ถ์ถ์ ๊ฒฐ์ ์ ์ ๋๋ค: size๋ฅผ ์ฝ๊ณ , ํด๋น ํฌ๊ธฐ์ ciphertext๋ฅผ ์ฝ๊ณ , ๋ฐ๋ก ๋ค์์ ์์นํ 16โbyte ํค๋ฅผ ์ฝ์ ๋ค์, RC4โdecryptํฉ๋๋ค.
๊ตฌ์ฑ ์ถ์ถ ์ํฌํ๋ก์ฐ (๋ฐฉ์ด์)
beacon logic์ ๋ชจ๋ฐฉํ๋ extractor๋ฅผ ์์ฑํ์ธ์:
- PE ๋ด๋ถ์์ blob์ ์ฐพ์ต๋๋ค (์ผ๋ฐ์ ์ผ๋ก .rdata). ์ค์ฉ์ ์ธ ๋ฐฉ๋ฒ์ .rdata๋ฅผ ์ค์บํ์ฌ ํฉ๋ฆฌ์ ์ธ [size|ciphertext|16โbyte key] ๋ ์ด์์์ ์ฐพ๊ณ RC4๋ฅผ ์๋ํ๋ ๊ฒ์ ๋๋ค.
- ์ฒ์ 4๋ฐ์ดํธ๋ฅผ ์ฝ์ต๋๋ค โ size (uint32 LE).
- ๋ค์ N=size ๋ฐ์ดํธ๋ฅผ ์ฝ์ต๋๋ค โ ciphertext.
- ๋ง์ง๋ง 16๋ฐ์ดํธ๋ฅผ ์ฝ์ต๋๋ค โ RC4 key.
- ciphertext๋ฅผ RC4โdecryptํ ๋ค, ํ๋ฌธ ํ๋กํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ํ์ฑํฉ๋๋ค:
- ์์ ์ธ๊ธํ ๊ฒ์ฒ๋ผ u32/boolean scalars
- ๊ธธ์ด ์ ๋ํ ๋ฌธ์์ด (u32 length ๋ค์์ ๋ฐ์ดํธ; ๋์ NUL์ด ์์ ์ ์์)
- ๋ฐฐ์ด: servers_count ๋ค์์ ๊ทธ ์๋งํผ์ [string, u32 port] ์์ด ์ต๋๋ค
์ฌ์ ์ถ์ถ๋ blob์์ ๋์ํ๋ ์ต์ํ์ Python proofโofโconcept(standalone, ์ธ๋ถ ์ข ์ ์์):
import struct
from typing import List, Tuple
def rc4(key: bytes, data: bytes) -> bytes:
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) & 0xFF
S[i], S[j] = S[j], S[i]
i = j = 0
out = bytearray()
for b in data:
i = (i + 1) & 0xFF
j = (j + S[i]) & 0xFF
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) & 0xFF]
out.append(b ^ K)
return bytes(out)
class P:
def __init__(self, buf: bytes):
self.b = buf; self.o = 0
def u32(self) -> int:
v = struct.unpack_from('<I', self.b, self.o)[0]; self.o += 4; return v
def u8(self) -> int:
v = self.b[self.o]; self.o += 1; return v
def s(self) -> str:
L = self.u32(); s = self.b[self.o:self.o+L]; self.o += L
return s[:-1].decode('utf-8','replace') if L and s[-1] == 0 else s.decode('utf-8','replace')
def parse_http_cfg(plain: bytes) -> dict:
p = P(plain)
cfg = {}
cfg['agent_type'] = p.u32()
cfg['use_ssl'] = bool(p.u8())
n = p.u32()
cfg['servers'] = []
cfg['ports'] = []
for _ in range(n):
cfg['servers'].append(p.s())
cfg['ports'].append(p.u32())
cfg['http_method'] = p.s()
cfg['uri'] = p.s()
cfg['parameter'] = p.s()
cfg['user_agent'] = p.s()
cfg['http_headers'] = p.s()
cfg['ans_pre_size'] = p.u32()
cfg['ans_size'] = p.u32() + cfg['ans_pre_size']
cfg['kill_date'] = p.u32()
cfg['working_time'] = p.u32()
cfg['sleep_delay'] = p.u32()
cfg['jitter_delay'] = p.u32()
cfg['listener_type'] = 0
cfg['download_chunk_size'] = 0x19000
return cfg
# Usage (when you have [size|ciphertext|key] bytes):
# blob = open('blob.bin','rb').read()
# size = struct.unpack_from('<I', blob, 0)[0]
# ct = blob[4:4+size]
# key = blob[4+size:4+size+16]
# pt = rc4(key, ct)
# cfg = parse_http_cfg(pt)
ํ:
- ์๋ํํ ๋, PE parser๋ฅผ ์ฌ์ฉํด .rdata๋ฅผ ์ฝ๊ณ ์ฌ๋ผ์ด๋ฉ ์๋์ฐ๋ฅผ ์ ์ฉํ์ธ์: ๊ฐ ์คํ์ o์ ๋ํด size = u32(.rdata[o:o+4]), ct = .rdata[o+4:o+4+size], candidate key = next 16 bytes; RC4โdecryptํ๊ณ ๋ฌธ์์ด ํ๋๊ฐ UTFโ8๋ก ๋์ฝ๋ฉ๋๋์ง์ ๊ธธ์ด๊ฐ ํ๋นํ์ง ํ์ธํฉ๋๋ค.
- ๋์ผํ lengthโprefixed ๊ท์ฝ์ ๋ฐ๋ผ SMB/TCP ํ๋กํ์ผ์ ํ์ฑํ์ธ์.
๋คํธ์ํฌ ์ง๋ฌธํ ๋ฐ ํํ
HTTP
- ์ผ๋ฐ์ : ์ด์์ ์ ํ URIs๋ก POST(์: /uri.php, /endpoint/api)
- beacon ID์ ์ฌ์ฉ๋๋ ์ปค์คํ ํค๋ ํ๋ผ๋ฏธํฐ(์: XโBeaconโId, XโAppโId)
- Firefox 20 ๋๋ ๋น์์ Chrome ๋น๋๋ฅผ ํ๋ด๋ด๋ Userโagents
- sleep_delay/jitter_delay๋ฅผ ํตํด ๋ณด์ด๋ ํด๋ง ์ฃผ๊ธฐ
SMB/TCP
- ์น egress๊ฐ ์ ํ๋ ์ธํธ๋ผ๋ท C2๋ฅผ ์ํ SMB namedโpipe ๋ฆฌ์ค๋
- TCP beacons๋ ํ๋กํ ์ฝ ์์์ ์ํํ๊ธฐ ์ํด ํธ๋ํฝ ์์ ๋ช ๋ฐ์ดํธ๋ฅผ ๋ถ์ผ ์ ์์
์ธ์๋ํธ์์ ๊ด์ฐฐ๋ Loader ๋ฐ persistence TTPs
๋ฉ๋ชจ๋ฆฌ ๋ด PowerShell ๋ก๋
- Base64/XOR ํ์ด๋ก๋ ๋ค์ด๋ก๋ (InvokeโRestMethod / WebClient)
- unmanaged memory ํ ๋น, shellcode ๋ณต์ฌ, VirtualProtect๋ก ๋ณดํธ๋ฅผ 0x40 (PAGE_EXECUTE_READWRITE)์ผ๋ก ๋ณ๊ฒฝ
- .NET ๋์ ํธ์ถ๋ก ์คํ: Marshal.GetDelegateForFunctionPointer + delegate.Invoke()
๋ฉ๋ชจ๋ฆฌ ๋ด ์คํ ๋ฐ AMSI/ETW ๊ด๋ จ ๊ณ ๋ ค์ฌํญ์ ๋ค์ ํ์ด์ง๋ฅผ ํ์ธํ์ธ์:
๊ด์ฐฐ๋ ์ง์์ฑ ๋ฉ์ปค๋์ฆ
- ๋ก๊ทธ์จ ์ ๋ก๋๋ฅผ ์ฌ์คํํ๊ธฐ ์ํ Startup ํด๋์ ๋ฐ๋ก๊ฐ๊ธฐ(.lnk)
- Registry Run ํค(HKCU/HKLM โฆ\CurrentVersion\Run), ์ข ์ข โUpdaterโ์ฒ๋ผ ๋ฌดํดํ๊ฒ ๋ค๋ฆฌ๋ ์ด๋ฆ์ผ๋ก loader.ps1์ ์์
- ์ทจ์ฝํ ํ๋ก์ธ์ค๋ฅผ ๋์์ผ๋ก %APPDATA%\Microsoft\Windows\Templates ์๋์ msimg32.dll์ ๋ฌ์ ๋ฐ์ํ๋ DLL searchโorder hijack
๊ธฐ์ ์ฌ์ธต ๋ถ์ ๋ฐ ์ ๊ฒ:
Privilege Escalation with Autoruns
ํํ ์์ด๋์ด
- PowerShell์์ ๋ฐ์ํ๋ RWโRX ์ ํ: powershell.exe ๋ด๋ถ์์ VirtualProtect๋ฅผ ํตํด PAGE_EXECUTE_READWRITE
- ๋์ ํธ์ถ ํจํด (GetDelegateForFunctionPointer)
- ์ฌ์ฉ์ ๋๋ ๊ณต์ฉ Startup ํด๋์ Startup .lnk
- ์์ฌ์ค๋ฌ์ด Run ํค(์: โUpdaterโ) ๋ฐ update.ps1/loader.ps1 ๊ฐ์ ๋ก๋ ์ด๋ฆ
- msimg32.dll์ ํฌํจํ๋ %APPDATA%\Microsoft\Windows\Templates ์๋์ ์ฌ์ฉ์ ์ฐ๊ธฐ ๊ฐ๋ฅํ DLL ๊ฒฝ๋ก
OpSec ํ๋์ ๋ํ ๋ ธํธ
- KillDate: ์์ด์ ํธ๊ฐ ์ค์ค๋ก ๋ง๋ฃ๋๋ ์์ ์ดํ์ ํ์์คํฌํ
- WorkingTime: ์์ด์ ํธ๊ฐ ๋น์ฆ๋์ค ํ๋์ ์์ด๋๋ก ํ์ฑํ๋์ด์ผ ํ๋ ์๊ฐ๋
์ด ํ๋๋ค์ ํด๋ฌ์คํฐ๋ง์ ์ฌ์ฉํ๊ฑฐ๋ ๊ด์ฐฐ๋ ์กฐ์ฉํ ๊ธฐ๊ฐ์ ์ค๋ช ํ๋ ๋ฐ ํ์ฉํ ์ ์์ต๋๋ค.
YARA ๋ฐ ์ ์ ๋จ์
Unit 42๋ beacons(C/C++ ๋ฐ Go)์ฉ ๊ธฐ๋ณธ YARA์ loader APIโhashing ์์๋ฅผ ๊ณต๊ฐํ์ต๋๋ค. PE .rdata ๋ ๊ทผ์ฒ์์ [size|ciphertext|16โbyteโkey] ๋ ์ด์์๊ณผ ๊ธฐ๋ณธ HTTP ํ๋กํ์ผ ๋ฌธ์์ด์ ์ฐพ๋ ๋ฃฐ๋ก ๋ณด์ํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
References
- AdaptixC2: A New Open-Source Framework Leveraged in Real-World Attacks (Unit 42)
- AdaptixC2 GitHub
- Adaptix Framework Docs
- Marshal.GetDelegateForFunctionPointer โ Microsoft Docs
- VirtualProtect โ Microsoft Docs
- Memory protection constants โ Microsoft Docs
- Invoke-RestMethod โ PowerShell
- MITRE ATT&CK T1547.001 โ Registry Run Keys/Startup Folder
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


