ksmbd ๊ณต๊ฒฉ ํ๋ฉด & SMB2/SMB3 ํ๋กํ ์ฝ ํผ์ง (syzkaller)
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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๊ฐ์
์ด ํ์ด์ง๋ syzkaller๋ฅผ ์ฌ์ฉํด Linux ์ธ์ปค๋ SMB ์๋ฒ(ksmbd)๋ฅผ ์คํํ๊ณ ํผ์งํ๊ธฐ ์ํ ์ค์ฉ ๊ธฐ๋ฒ๋ค์ ์ถ์ํํฉ๋๋ค. ๊ตฌ์ฑ์ผ๋ก ํ๋กํ ์ฝ ๊ณต๊ฒฉ ํ๋ฉด์ ํ์ฅํ๊ณ , SMB2 ์ฐ์ฐ์ ์ฒด์ด๋ํ ์ ์๋ ์ํ ์ ์ง ํ๋์ค(stateful harness)๋ฅผ ๊ตฌ์ถํ๋ฉฐ, ๋ฌธ๋ฒ์ ๋ง๋ PDU๋ฅผ ์์ฑํ๊ณ , ์ฝํ๊ฒ ์ปค๋ฒ๋๋ ์ฝ๋ ๊ฒฝ๋ก๋ก ๋ณํ์ ํธํฅ์ํค๋ฉฐ, focus_areas์ ANYBLOB ๊ฐ์ syzkaller ๊ธฐ๋ฅ์ ํ์ฉํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์๋ณธ ์ฐ๊ตฌ๋ ํน์ CVE๋ค์ ์ด๊ฑฐํ์ง๋ง, ์ฌ๊ธฐ์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ๋ก ๊ณผ ์์ ์ ํ๊ฒฝ์ ๋ง๊ฒ ์ ์ฉํ ์ ์๋ ๊ตฌ์ฒด์ ์ธ ์ค๋ํซ์ ๊ฐ์กฐํฉ๋๋ค.
๋์ ๋ฒ์: SMB2/SMB3 over TCP. Kerberos์ RDMA๋ ํ๋์ค ๋จ์ํ๋ฅผ ์ํด ์๋์ ์ผ๋ก ๋ฒ์์์ ์ ์ธํฉ๋๋ค.
๊ตฌ์ฑ์ผ๋ก ksmbd ๊ณต๊ฒฉ ํ๋ฉด ํ์ฅ
๊ธฐ๋ณธ์ ์ธ ksmbd ์ค์ ์ ์๋ฒ์ ๋ง์ ๋ถ๋ถ์ ํ ์คํธํ์ง ๋ชปํ ์ฑ๋ก ๋ก๋๋ค. ๋ค์ ๊ธฐ๋ฅ๋ค์ ํ์ฑํํ์ฌ ์ถ๊ฐ ํ์/ํธ๋ค๋ฌ๋ฅผ ํต๊ณผ์ํค๊ณ ๋ ๊น์ ์ฝ๋ ๊ฒฝ๋ก์ ๋๋ฌํ์ธ์:
- Global-level
- Durable handles
- Server multi-channel
- SMB2 leases
- Per-share-level
- Oplocks (๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋จ)
- VFS objects
์ด๋ค์ ํ์ฑํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ชจ๋์์ ์คํ์ด ์ฆ๊ฐํฉ๋๋ค:
- smb2pdu.c (๋ช ๋ น ํ์ฑ/๋์คํจ์น)
- ndr.c (NDR ์ธ์ฝ๋/๋์ฝ๋)
- oplock.c (oplock ์์ฒญ/์ค๋จ)
- smbacl.c (ACL ํ์ฑ/๊ฐ์ )
- vfs.c (VFS ์ฐ์ฐ)
- vfs_cache.c (์กฐํ ์บ์)
์ฐธ๊ณ
- ์ ํํ ์ต์ ์ ๋ฐฐํฌํ์ ksmbd ์ฌ์ฉ์ ๊ณต๊ฐ(ksmbd-tools)์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. /etc/ksmbd/ksmbd.conf ๋ฐ ๊ฐ share ์น์ ์ ๊ฒํ ํ์ฌ durable handles, leases, oplocks ๋ฐ VFS objects๋ฅผ ํ์ฑํํ์ธ์.
- Multi-channel๊ณผ durable handles๋ ์ํ ๋จธ์ ๊ณผ ์๋ช ์ ์ํฅ์ ์ฃผ๋ฉฐ, ๋์์ฑ ํ์์ UAF/refcount/OOB ๋ฒ๊ทธ๋ฅผ ์์ฃผ ๋๋ฌ๋ ๋๋ค.
ํผ์ง์ ์ํ ์ธ์ฆ ๋ฐ ์๋ ์ ํ ์กฐ์
SMB3๋ ์ ํจํ ์ธ์ ์ด ํ์ํฉ๋๋ค. ํ๋์ค์ Kerberos๋ฅผ ๊ตฌํํ๋ฉด ๋ณต์ก์ฑ์ด ์ฆ๊ฐํ๋ฏ๋ก ํผ์ง์๋ NTLM/guest๋ฅผ ๊ถ์ฅํฉ๋๋ค:
- guest ์ ๊ทผ์ ํ์ฉํ๊ณ map to guest = bad user๋ก ์ค์ ํด ์๋ ค์ง์ง ์์ ์ฌ์ฉ์๊ฐ GUEST๋ก ํด๋ฐฑ๋๋๋ก ํฉ๋๋ค.
- NTLMv2๋ฅผ ํ์ฉํฉ๋๋ค(๋นํ์ฑํ๋ ๊ฒฝ์ฐ ์ ์ฑ ์ ํจ์น). ์ด๋ ํธ๋์ ฐ์ดํฌ๋ฅผ ๋จ์ํ๊ฒ ์ ์งํ๋ฉด์ SMB3 ์ฝ๋ ๊ฒฝ๋ก๋ฅผ ์คํํ๊ฒ ํฉ๋๋ค.
- ์คํ ์ค์๋ ์๊ฒฉํ credit ๊ฒ์ฌ(credit checks)๋ฅผ ํจ์นํด ์ ๊ฑฐํ์ธ์ (ํ๋๋ ์ดํ CVE-2024-50285๋ก ๋์ ์์ ํฌ๋ ๋ง ๋ถ์ฌ๊ฐ ๋ ์๊ฒฉํด์ก์ต๋๋ค). ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ ์ ํ์ด ํผ์ฆ๋ ์ํ์ค๋ฅผ ๋๋ฌด ์ผ์ฐ ๊ฑฐ๋ถํ ์ ์์ต๋๋ค.
- ์ต๋ ์ฐ๊ฒฐ ์๋ฅผ ์ฆ๊ฐ์์ผ(์: 65536) ๊ณ ์ฒ๋ฆฌ๋ ํผ์ง ์ค ์กฐ๊ธฐ ๊ฑฐ๋ถ๋ฅผ ํผํ์ธ์.
์ฃผ์: ์ด๋ฌํ ์ํ๋ ํผ์ง์ ์ฉ์ดํ๊ฒ ํ๊ธฐ ์ํ ๊ฒ๋ฟ์ ๋๋ค. ์ด์ ํ๊ฒฝ์ ์ด ์ค์ ์ ๋ฐฐํฌํ์ง ๋ง์ธ์.
์ํ ์ ์ง ํ๋์ค: ๋ฆฌ์์ค ์ถ์ถ ๋ฐ ์์ฒญ ์ฒด์ด๋
SMB๋ ์ํ๋ฅผ ๊ฐ์ง๋๋ค: ๋ง์ ์์ฒญ์ด ์ด์ ์๋ต์์ ๋ฐํ๋ ์๋ณ์(SessionId, TreeID, FileID ์ ๋ฑ)์ ์์กดํฉ๋๋ค. ํ๋์ค๋ ์๋ต์ ํ์ฑํ๊ณ ๋์ผํ ํ๋ก๊ทธ๋จ ๋ด์์ ID๋ฅผ ์ฌ์ฌ์ฉํ์ฌ ๊น์ ํธ๋ค๋ฌ์ ๋๋ฌํด์ผ ํฉ๋๋ค(์: smb2_create โ smb2_ioctl โ smb2_close).
์์ ์ค๋ํซ: ์๋ต ๋ฒํผ( +4B NetBIOS PDU ๊ธธ์ด ์๋ต)๋ฅผ ์ฒ๋ฆฌํ๊ณ ID๋ฅผ ์บ์ํ๋ ๋ฐฉ๋ฒ:
// process response. does not contain +4B PDU length
void process_buffer(int msg_no, const char *buffer, size_t received) {
uint16_t cmd_rsp = u16((const uint8_t *)(buffer + CMD_OFFSET));
switch (cmd_rsp) {
case SMB2_TREE_CONNECT:
if (received >= TREE_ID_OFFSET + sizeof(uint32_t))
tree_id = u32((const uint8_t *)(buffer + TREE_ID_OFFSET));
break;
case SMB2_SESS_SETUP:
// first session setup response carries session_id
if (msg_no == 0x01 && received >= SESSION_ID_OFFSET + sizeof(uint64_t))
session_id = u64((const uint8_t *)(buffer + SESSION_ID_OFFSET));
break;
case SMB2_CREATE:
if (received >= CREATE_VFID_OFFSET + sizeof(uint64_t)) {
persistent_file_id = u64((const uint8_t *)(buffer + CREATE_PFID_OFFSET));
volatile_file_id = u64((const uint8_t *)(buffer + CREATE_VFID_OFFSET));
}
break;
default:
break;
}
}
ํ
- ์ธ์ฆ/์ํ๋ฅผ ๊ณต์ ํ๋ fuzzer ํ๋ก์ธ์ค ํ๋๋ฅผ ์ ์งํ์ธ์: ksmbdโs global/session tables์์ ๋ ๋์ ์์ ์ฑ๊ณผ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ป์ต๋๋ค. syzkaller๋ ops๋ฅผ async๋ก ํ์ํด ๋ด๋ถ์ ์ผ๋ก ์ฌ์คํํ๋ฉด์ ์ฌ์ ํ ๋์์ฑ์ ์ฃผ์ ํฉ๋๋ค.
- Syzkaller์ experimental reset_acc_state๋ global state๋ฅผ ๋ฆฌ์ ํ ์ ์์ง๋ง ์ฌ๊ฐํ ์ฑ๋ฅ ์ ํ๋ฅผ ์ด๋ํ ์ ์์ต๋๋ค. ์์ ์ฑ์ ์ฐ์ ํ๊ณ fuzzing์ ์ง์คํ์ธ์.
๋ฌธ๋ฒ ๊ธฐ๋ฐ SMB2 ์์ฑ (์ ํจํ PDUs)
Microsoft Open Specifications์ SMB2 ๊ตฌ์กฐ๋ฅผ fuzzer grammar๋ก ๋ณํํ์ฌ generator๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ์ ํจํ PDUs๋ฅผ ์์ฑํ๋๋ก ํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด dispatchers์ IOCTL handlers์ ์ฒด๊ณ์ ์ผ๋ก ๋๋ฌํฉ๋๋ค.
์์ (SMB2 IOCTL request):
smb2_ioctl_req {
Header_Prefix SMB2Header_Prefix
Command const[0xb, int16]
Header_Suffix SMB2Header_Suffix
StructureSize const[57, int16]
Reserved const[0, int16]
CtlCode union_control_codes
PersistentFileId const[0x4, int64]
VolatileFileId const[0x0, int64]
InputOffset offsetof[Input, int32]
InputCount bytesize[Input, int32]
MaxInputResponse const[65536, int32]
OutputOffset offsetof[Output, int32]
OutputCount len[Output, int32]
MaxOutputResponse const[65536, int32]
Flags int32[0:1]
Reserved2 const[0, int32]
Input array[int8]
Output array[int8]
} [packed]
์ด ๋ฐฉ์์ ๊ตฌ์กฐ์ฒด ํฌ๊ธฐ/์คํ์ ์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฐ์ ํ๋ฉฐ ๋ธ๋ผ์ธ๋ ๋ฎคํ ์ด์ ์ ๋นํด ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๊ทน์ ์ผ๋ก ํฅ์์ํต๋๋ค.
Directed Fuzzing With focus_areas
syzkallerโs ์คํ์ focus_areas๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ์ปค๋ฒ๋ฆฌ์ง๊ฐ ์ฝํ ํน์ ํจ์/ํ์ผ์ ๊ฐ์ค์น๋ฅผ ๋ํ์ธ์. ์์ JSON:
{
"focus_areas": [
{"filter": {"functions": ["smb_check_perm_dacl"]}, "weight": 20.0},
{"filter": {"files": ["^fs/smb/server/"]}, "weight": 2.0},
{"weight": 1.0}
]
}
์ด๊ฒ์ smbacl.c์ arithmetic/overflow ๊ฒฝ๋ก๋ฅผ ํ๊นํ๋ ์ ํจํ ACLs๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ณผ๋ํ dacloffset์ ๊ฐ์ง ์ ์์ ์ธ Security Descriptor๋ integer-overflow๋ฅผ ์ฌํํฉ๋๋ค.
์ฌํ๊ธฐ ๋น๋ (๊ฐ๋จํ Python):
def build_sd():
import struct
sd = bytearray(0x14)
sd[0x00] = 0x00; sd[0x01] = 0x00
struct.pack_into('<H', sd, 0x02, 0x0001)
struct.pack_into('<I', sd, 0x04, 0x78)
struct.pack_into('<I', sd, 0x08, 0x00)
struct.pack_into('<I', sd, 0x0C, 0x10000)
struct.pack_into('<I', sd, 0x10, 0xFFFFFFFF) # dacloffset
while len(sd) < 0x78:
sd += b'A'
sd += b"\x01\x01\x00\x00\x00\x00\x00\x00" # minimal DACL
sd += b"\xCC" * 64
return bytes(sd)
ANYBLOB๋ก ์ปค๋ฒ๋ฆฌ์ง ์ ์ฒด ๋ํ
syzkallerโs anyTypes (ANYBLOB/ANYRES)๋ ๋ณต์กํ ๊ตฌ์กฐ๋ฅผ ์ผ๋ฐ์ ์ผ๋ก mutateํ๋ blob์ผ๋ก ์ถ์ํ ์ ์๊ฒ ํด์ค๋ค. ๊ณต๊ฐ SMB pcaps์์ ์๋ก์ด corpus๋ฅผ seedํ๊ณ payload๋ฅผ syzkaller ํ๋ก๊ทธ๋จ์ผ๋ก ๋ณํํ์ฌ ๋น์ ์ pseudo-syscall(์: syz_ksmbd_send_req)์ ํธ์ถํ๋ผ:
# Extract SMB payloads to JSON
# tshark -r smb2_dac_sample.pcap -Y "smb || smb2" -T json -e tcp.payload > packets.json
import json, os
os.makedirs("corpus", exist_ok=True)
with open("packets.json") as f:
data = json.load(f)
# adjust indexing to your tshark JSON structure
packets = [e["_source"]["layers"]["tcp.payload"] for e in data]
for i, pkt in enumerate(packets):
pdu = pkt[0]
pdu_size = len(pdu) // 2 # hex string length โ bytes
with open(f"corpus/packet_{i:03d}.txt", "w") as f:
f.write(
f"syz_ksmbd_send_req(&(&(0x7f0000000340))=ANY=[@ANYBLOB=\"{pdu}\"], {hex(pdu_size)}, 0x0, 0x0)"
)
์ด๊ฒ์ ํ์์ ๋น ๋ฅด๊ฒ ์์์ํค๋ฉฐ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ช ํผ์ผํธ ๋์ด์ฌ๋ฆฌ๋ ๋์์ ์ฆ์ UAFs(์: ksmbd_sessions_deregister)๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
Sanitizers: Beyond KASAN
- KASAN์ ํ ๋ฒ๊ทธ(UAF/OOB)๋ฅผ ํ์งํ๋ ์ฃผ์ ์๋จ์ผ๋ก ๋จ์ ์์ต๋๋ค.
- KCSAN์ ์ด ๋์์์ ์ข ์ข ์คํ์ ๋ด๊ฑฐ๋ ์ฌ๊ฐ๋๊ฐ ๋ฎ์ ๋ฐ์ดํฐ ๋ ์ด์ค๋ฅผ ๋ณด๊ณ ํฉ๋๋ค.
- UBSAN/KUBSAN์ ๋ฐฐ์ด ์ธ๋ฑ์ค ์๋ฏธ๋ก ๋๋ฌธ์ KASAN์ด ๋์น๋ ์ ์ธ๋ ๊ฒฝ๊ณ ์ค๋ฅ๋ฅผ ์ก์ ์ ์์ต๋๋ค. ์:
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
struct smb_sid {
__u8 revision; __u8 num_subauth; __u8 authority[NUM_AUTHS];
__le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */
} __attribute__((packed));
num_subauth = 0์ผ๋ก ์ค์ ํ๋ฉด ๊ตฌ์กฐ์ฒด ๋ด๋ถ์์ sub_auth[-1]์ ๋ํ OOB read๊ฐ ๋ฐ์ํ๋ฉฐ, UBSAN์ declared-bounds ๊ฒ์ฌ์ ์ํด ํฌ์ฐฉ๋ฉ๋๋ค.
์ฒ๋ฆฌ๋ ๋ฐ ๋ณ๋ ฌ์ฑ ์ฃผ์์ฌํญ
- ๋จ์ผ fuzzer ํ๋ก์ธ์ค (shared auth/state)๋ ksmbd์ ๋ํด ํจ์ฌ ๋ ์์ ์ ์ธ ๊ฒฝํฅ์ด ์์ผ๋ฉฐ, syzkaller์ ๋ด๋ถ async executor ๋๋ถ์ ์ฌ์ ํ races/UAFs๋ฅผ ๋๋ฌ๋ ๋๋ค.
- ์ฌ๋ฌ VM์ ์ฌ์ฉํ๋ฉด ์ ๋ฐ์ ์ผ๋ก ์ด๋น ์๋ฐฑ ๊ฑด์ SMB ๋ช ๋ น์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ํจ์ ์์ค์ ์ปค๋ฒ๋ฆฌ์ง๋ fs/smb/server์ ์ฝ 60% ๋ฐ smb2pdu.c์ ์ฝ 70% ์ ๋ ๋ฌ์ฑํ ์ ์์ผ๋, ์ํ ์ ์ด(state-transition) ์ปค๋ฒ๋ฆฌ์ง๋ ์ด๋ฌํ ์งํ๋ก๋ ๊ณผ์ํ๊ฐ๋ฉ๋๋ค.
์ค๋ฌด ์ฒดํฌ๋ฆฌ์คํธ
- ksmbd์์ durable handles, leases, multi-channel, oplocks ๋ฐ VFS objects๋ฅผ ํ์ฑํํ์ธ์.
- guest ๋ฐ map-to-guest๋ฅผ ํ์ฉํ๊ณ NTLMv2๋ฅผ ์์ฉํ์ธ์. fuzzer ์์ ์ฑ์ ์ํด credit limits๋ฅผ ์ ๊ฑฐํ๊ณ max connections๋ฅผ ๋๋ฆฌ์ธ์.
- SessionId/TreeID/FileIDs๋ฅผ ์บ์ํ๊ณ create โ ioctl โ close๋ฅผ ์ฐ์ํ๋ stateful harness๋ฅผ ๊ตฌ์ถํ์ธ์.
- ๊ตฌ์กฐ์ ์ ํจ์ฑ์ ์ ์งํ๊ธฐ ์ํด SMB2 PDUs์ ๋ํ grammar๋ฅผ ์ฌ์ฉํ์ธ์.
- ์ฝํ๊ฒ ์ปค๋ฒ๋ ํจ์์ ๊ฐ์ค์น๋ฅผ ๋๊ธฐ ์ํด focus_areas๋ฅผ ์ฌ์ฉํ์ธ์ (์: smbacl.c์ smb_check_perm_dacl ๊ฒฝ๋ก).
- ์ ์ฒด๊ธฐ๋ฅผ ๊นจ๊ธฐ ์ํด ์ค์ pcaps์ ANYBLOB๋ก ์๋๋ฅผ ์์ฑํ๊ณ , ์ฌ์ฌ์ฉ์ ์ํด syz-db๋ก ์๋๋ค์ ํจํนํ์ธ์.
- KASAN + UBSAN๋ก ์คํํ์ธ์; UBSAN์ declared-bounds ๋ณด๊ณ ์๋ ์ ์คํ ๋ถ์ํ์ธ์.
์ฐธ๊ณ ์๋ฃ
- Doyensec โ ksmbd Fuzzing (Part 2): https://blog.doyensec.com/2025/09/02/ksmbd-2.html
- syzkaller: https://github.com/google/syzkaller
- ANYBLOB/anyTypes (commit 9fe8aa4): https://github.com/google/syzkaller/commit/9fe8aa4
- Async executor change (commit fd8caa5): https://github.com/google/syzkaller/commit/fd8caa5
- syz-db: https://github.com/google/syzkaller/tree/master/tools/syz-db
- KASAN: https://docs.kernel.org/dev-tools/kasan.html
- UBSAN/KUBSAN: https://docs.kernel.org/dev-tools/ubsan.html
- KCSAN: https://docs.kernel.org/dev-tools/kcsan.html
- Microsoft Open Specifications (SMB): https://learn.microsoft.com/openspecs/
- Wireshark Sample Captures: https://wiki.wireshark.org/SampleCaptures
- ๋ฐฐ๊ฒฝ ์ฝ๊ธฐ: pwning.tech โTickling ksmbd: fuzzing SMB in the Linux kernelโ; Dongliang Muโs syzkaller notes
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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


