SMB / NetBIOS
Impacket の SMB は「パケットを組み立てるライブラリ」と「セッション実装」の
両方です。CLI のほとんどは SMBConnection だけを使い、dialect 差は内側に
閉じます。
| モジュール | 役割 |
|---|---|
nmb.py | NetBIOS 名前解決とセッションフレーミング |
smb.py | SMB1 (NT LM 0.12)、\xffSMB |
smb3.py + smb3structs.py | SMB2 および SMB3、\xfeSMB / 暗号時 \xfdSMB |
smbconnection.py | dialect 透過のクライアント facade |
smbserver.py | 検証用サーバ (SMBSERVER / SimpleSMBServer) |
関連コマンド: smbclient、smbserver、DumpNTLMInfo、psexec、ntlmrelayx
flowchart TB
App["SMBConnection / DCERPC SMBTransport"] --> NMB["NetBIOSTCPSession"]
NMB --> TCP["TCP 445 または 139"]
App --> Neg["NEGOTIATE"]
Neg -->|magic FE| SMB23["smb3.SMB3"]
Neg -->|magic FF| SMB1["smb.SMB"]
SMB23 --> Auth["SESSION_SETUP NTLM または Kerberos"]
SMB1 --> Auth
Auth --> Tree["TREE_CONNECT"]
Tree --> File["create / read / write"]
Tree --> Pipe["IPC$ named pipe / FSCTL_PIPE_*"]
445 でも NetBIOS session message (type 0x00) で包みます。139 だけ
SESSION REQUEST (0x81) が先行し、*SMBSERVER は NBSTAT で実名を取ります。
ポート定数: SMB_SESSION_PORT=445、NETBIOS_SESSION_PORT=139、
NETBIOS_NS_PORT=137。
ネゴシエーション
Section titled “ネゴシエーション”SMBConnection.negotiateSession() は preferred dialect が無いとき、
SMB1 SMB_COM_NEGOTIATE に次を載せます。
NT LM 0.12 / SMB 2.002 / SMB 2.???139 では SMB 2.??? を省略します。応答先頭が \xfe なら SMB2/3、
それ以外は SMB1 に固定します。
smb3.SMB3.negotiateSession() は [MS-SMB2] の Connection 状態を持ちます。
- 提示 dialect: 指定が無ければ
0x0202/0x0210/0x0300/0x0302/0x0311 - 3.1.1 がある場合: Preauth Integrity (SHA-512) と Encryption (AES-128-GCM、AES-128-CCM) の negotiate context
- サーバが
SIGNING_REQUIRED、または dialect が 3.1.1 ならRequireSigning - dialect ≥ 3.0 でパケットクラスを
SMB3Packetへ切替 (Statusが request ではChannelSequenceになる)
3.1.1 では AES-128-GCM を優先し、AES-128-CCM も提示します。 3.0 / 3.0.2 は暗号方式のネゴシエーションがなく、AES-128-CCM を使います。 圧縮は扱いません。
どちらも SPNEGO の中に NTLM または Kerberos AP-REQ を載せます。
| 経路 | 入口 | 要点 |
|---|---|---|
| NTLM | login() | Type1 → Type2 → Type3。exportedSessionKey が署名・暗号の起点 |
| Kerberos | kerberosLogin() | cifs/<ServerName> の TGS。KDC_ERR_ETYPE_NOSUPP では NT hash に落として再試行 |
| SMB1 旧式 | login_standard() | extended security が無いときの DES(challenge, LM/NT hash) |
SMB1 の extended login 中は一時的に Unicode を落とします。
ntlmFallback は SMB1 だけで、NativeLanMan が Windows 2000 / Samba のときに
NTLMv1 へ下がります。
signSMB():
SecurityFeatures = LE64(seq)MD5(SigningSessionKey || SigningChallengeResponse || packet)[:8]seq += 2NTLMv2 の exported key では challenge-response 部分は空です。
SMB2 / SMB3
Section titled “SMB2 / SMB3”| dialect | 署名 |
|---|---|
| 2.0.2 / 2.1 | HMAC-SHA256(SessionKey, packet)[:16] |
| 3.x | AES_CMAC(SigningKey, packet) (crypto.AES_CMAC) |
3.x の鍵導出は crypto.KDF_CounterMode (HMAC-SHA256、128 bit) です。
| 鍵 | 3.0 / 3.0.2 | 3.1.1 |
|---|---|---|
| SigningKey | Label SMB2AESCMAC\0, Context SmbSign\0 | Label SMBSigningKey\0, Context = PreauthHash |
| ApplicationKey | SMB2APP\0 / SmbRpc\0 | SMBAppKey\0 / PreauthHash |
| EncryptionKey (C2S) | SMB2AESCCM\0 / ServerIn \0 | SMBC2SCipherKey\0 |
| DecryptionKey (S2C) | SMB2AESCCM\0 / ServerOut\0 | SMBS2CCipherKey\0 |
dialect ≥ 3.0 かつサーバが GLOBAL_CAP_ENCRYPTION を出し、guest/anonymous
でなければ、クライアント側で SMB2_SESSION_FLAG_ENCRYPT_DATA を強制します。
暗号化 PDU は \xfdSMB の SMB2_TRANSFORM_HEADER と、
ネゴシエーションで選んだ AES-128-GCM または AES-128-CCM です。
RPC over SMB3 は getSessionKey() が返す ApplicationKey を使います。
生の NTLM session key ではありません。
ツリー接続と named pipe
Section titled “ツリー接続と named pipe”connectTree() は \\host\SHARE を作り、TreeID を保持します。
DCERPC の典型経路は次です。
connectTree('IPC$')- 必要なら
waitNamedPipe(SMB1 TRANS_WAIT_NMPIPEまたはFSCTL_PIPE_WAIT) create/nt_create_andxで\pipe\<name>を開くtransactNamedPipe(TRANS_TRANSACT_NMPIPE=0x26) またはFSCTL_PIPE_TRANSCEIVE=0x0011C017
共有一覧 listShares() は SMB1 LANMAN ではなく、同じセッション上の
srvsvc RPC(NetrShareEnum info level 1)です。listSharesWithPrivs() は
info level 502 で共有の privilege 欄を返し、管理者権限が必要です。
SMB3 クライアントの list_shared は未実装です。
サーバ実装の範囲
Section titled “サーバ実装の範囲”SimpleSMBServer / SMBSERVER:
- SMB1 は
NT LM 0.12。extended security では NTLMSSP を提示 - SMB2/3 応答 dialect は 2.0.2、2.1、3.1.1。3.1.1 では preauth hash と AES-128-GCM / AES-128-CCM の暗号化に対応
- 資格情報ストアが空なら SMB1 標準セキュリティは成功扱いになる経路がある
registerNamedPipeで in-process DCERPC (srvsvc/wkssvc) を載せられる- hook (
hookSmbCommand/hookSmb2Command) は karmaSMB などが使う
SMB 3.0 / 3.0.2 とマルチチャネルなど、実装範囲外の機能は個別に確認してください。
実装上の制約
Section titled “実装上の制約”- Oplock break とマルチチャネル bind は未実装。compound request の一部は処理するが、全パターンの対応を前提にしない
- transform 復号では GCM / CCM の認証 tag を検証する
- クライアントの暗号化 nonce は AES-CCM で 11 文字、AES-GCM で 12 文字の
ASCII 文字列を
random.choiceで作り、CSPRNG を使っていない negoexは SMB login に繋がっていない
変更時の確認
Section titled “変更時の確認”- dialect 分岐を
SMBConnectionの外へ漏らさない - 署名シーケンス、preauth hash、Tree ごとの EncryptData を壊さない
- 新しい create option / info class は SMB1 と SMB2 の両方の定数を確認する
- 関連テスト:
tests/SMB_RPC/

