DCE/RPC と NDR
RPC はクライアントからリモートの関数を呼び出す仕組みです。Impacket の MSRPC 実装は、接続先の特定、メッセージの交換、引数の符号化をそれぞれ 別の層で扱います。C706 と [MS-RPCE] の 接続指向実装で、transport、runtime、NDR、各 interface が分かれています。
| モジュール | 責務 |
|---|---|
transport.py | string binding → TCP / SMB pipe / HTTP / UDP / local |
rpcrt.py | PDU、bind / alter context、AUTH3、SIGN/SEAL |
rpch.py | RPC over HTTP v1/v2 |
ndr.py | NDR / NDR64 の pack |
epm.py | Endpoint Mapper |
dcomrt.py + dcom/ | DCOM OXID / OBJREF、WMI |
関連コマンド: rpcdump、rpcmap、 services、atexec、 wmiexec、samrdump
String binding と transport
Section titled “String binding と transport”[uuid@]proto:address[endpoint,opt=val]DCERPCTransportFactory() の分岐:
| proto | クラス | 典型 |
|---|---|---|
ncacn_np | SMBTransport | ncacn_np:host[\pipe\svcctl] |
ncacn_ip_tcp | TCPTransport | 既定 135。動的ポートは EPM で引く |
ncacn_http | HTTPTransport | 直結 593、または RpcProxy=host:443 |
ncadg_ip_udp | UDPTransport | 接続レス。DCERPC_v4 |
ncalocal | LOCALTransport | \\\\.\\PIPE\\...。LPC (ncalrpc) ではない |
SMBTransport は既存 SMBConnection を再利用できます。複数 interface を
同じセッションで開くときはこれを使います。
RPC over HTTP
Section titled “RPC over HTTP”rpch.py は [MS-RPCH] です。
- 直結: ポート 593、バナー
ncacn_http/1.0(RPC_OVER_HTTP_v1) - Proxy: option
RpcProxy=host:80|443→/rpc/rpcproxy.dll?RemoteName:RemotePort。IN チャネル (RPC_IN_DATA) と OUT チャネル (RPC_OUT_DATA) を対で張り、RTS (CONN_A1/B1/A3/C2) でトンネルを確立します - Exchange は 6001–6004 (OXCRPC / OXABREF / OXNSPI) をよく使います
set_credentials() は auth level を自動で CONNECT まで上げます。
DRSUAPI や一部 DCOM が要求する PKT_PRIVACY は呼び出し側が明示します。
資格情報は transport に置き、DCERPC_v5.set_credentials() が bind 時に
拾います。SMB transport では同じ SMBConnection を再利用できます。
PDU と bind
Section titled “PDU と bind”主要 type (rpcrt.py):
| 値 | 名前 |
|---|---|
| 0x00 / 0x02 | REQUEST / RESPONSE |
| 0x03 | FAULT |
| 0x0B / 0x0C / 0x0D | BIND / BINDACK / BINDNAK |
| 0x0E / 0x0F | ALTERCTX / ALTERCTX_R |
| 0x10 | AUTH3 (NTLM Type3) |
| 0x14 | RTS (RPC over HTTP) |
DCERPC_v5.bind(iface_uuid) は abstract syntax (interface UUID+version) と
transfer syntax を CtxItem に載せます。
| Transfer syntax | UUID |
|---|---|
| NDR 2.0 | 8a885d04-1ceb-11c9-9fe8-08002b104860 |
| NDR64 1.0 | 71710533-beba-4937-8319-b5dbef9ccc36 |
bogus_binds はダミー context を先に足します (一部ホストの指紋回避)。
bind が拒否されると rpc_cont_def_result / rpc_status_codes 付きの
DCERPCException になります。
EPM (epm.py) UUID は
E1AF8308-5D1F-11C9-91A4-08002B14A0FA v3.0、既定 binding は
ncacn_ip_tcp:host[135] です。
| helper | 役割 |
|---|---|
hept_lookup | 全 tower + annotation。rpcdump |
hept_map | 指定 interface の string binding を 1 つ返す。DRSUAPI/GKDI の動的ポート |
PrintStringBinding | floor を文字列へ |
tower は interface UUID、transfer syntax、protocol、pipe/port、host の
floor 列です。rpcmap は指定 binding 上で mgmt (hinq_if_ids) または
UUID/opnum 探索をします。
共有型は dtypes.py ([MS-DTYP]:
DWORD、WSTR、RPC_SID、GUID、SECURITY_DESCRIPTOR)。
NULL は NDRPOINTERNULL のシングルトンです。
DCERPC.request(req) は req と同じモジュールの
{ClassName}Response を探し、末尾 4 byte が 0 でなければ
そのモジュールの DCERPCSessionError を投げます。
set_auth_type / set_auth_level:
| auth_type | 値 | 実装 |
|---|---|---|
RPC_C_AUTHN_NONE | 0x00 | 無し |
RPC_C_AUTHN_GSS_NEGOTIATE | 0x09 | Kerberos (getKerberosType1) |
RPC_C_AUTHN_WINNT | 0x0A | NTLMSSP (既定) |
RPC_C_AUTHN_NETLOGON | 0x44 | Secure Channel (nrpc.getSSPType1) |
| auth_level | 値 | 意味 |
|---|---|---|
NONE | 1 | 認証無し |
CONNECT | 2 | bind 時だけ (set_credentials の既定) |
CALL | 3 | コール単位 |
PKT | 4 | パケット単位 |
PKT_INTEGRITY | 5 | 署名 |
PKT_PRIVACY | 6 | 署名 + 暗号化 |
NTLM の bind は Type1 を BIND に載せ、BINDACK の Type2 を見て AUTH3 で
Type3 を送ります。PKT_INTEGRITY / PKT_PRIVACY では以後の REQUEST に
SEC_TRAILER と署名/暗号が付きます。Kerberos は SPNEGO AP-REQ/AP-REP
(DCE_STYLE) です。
SMB3 上では RPC 署名鍵に SMBConnection.getSessionKey() の
ApplicationKey を使います。NTLM exported key そのものではありません。
NDR は Structure に似た宣言型ですが、C706 の alignment
規則を持ちます。プリミティブの前に 最小のパディングが入ります。
| クラス | 用途 |
|---|---|
NDRSMALL / NDRSHORT / NDRLONG / NDRHYPER と符号無し版 | スカラ |
NDRBOOLEAN / NDRCHAR / NDRFLOAT | その他プリミティブ |
NDRENUM | 列挙 |
NDRSTRUCT | 構造体 |
NDRUNION | 判別 union |
NDRUniFixedArray / NDRUniConformantArray / NDRUniVaryingArray / NDRUniConformantVaryingArray | 配列 |
NDRVaryingString / NDRConformantVaryingString | 文字列 |
NDRPOINTER / NDRPOINTERNULL | 参照ポインタ。referent は後置 |
NDRCALL | request / response のトップレベル |
isNDR64=True で commonHdr64 / structure64 / align64 に切り替わります。
ポインタは 4 byte から 8 byte になります。
interface モジュールのパターン:
MSRPC_UUID_* = uuidtup_to_bin((uuid, version))- 型を
NDRSTRUCT/NDRPOINTERで宣言 - 各 op を
NDRCALLサブクラスにし、helperhXxxYyy(dce, ...)を置く
新しい op を足すときは IDL の alignment と conformant 配列の
MaximumCount / Offset / ActualCount を守ってください。手で
Structure を組むとパディングがずれます。
実装されている主な interface
Section titled “実装されている主な interface”named pipe は代表値です。ホストによっては EPM 経由の TCP だけ、 または別名 pipe のことがあります。
| モジュール | UUID (抜粋) | 代表 pipe / ポート | 用途 |
|---|---|---|---|
epm | E1AF8308-...A0FA v3 | TCP 135 | endpoint 解決 |
mgmt | afa8bd80-... | 任意 | interface inquiry (rpcmap) |
samr | 12345778-...89AC v1 | samr | アカウント列挙・作成・password |
lsat / lsad | 12345778-...89AB v0 | lsarpc | SID lookup、policy、secret |
nrpc | 12345678-...CFFB v1 | netlogon | Secure Channel、challenge/authenticate |
scmr | 367ABB81-... v2 | svcctl | サービス作成/開始/停止。RCreateWowService(opnum 60)と ROpenSCManager2(opnum 64)も含む |
tsch | 86D35949-... v1 | TaskScheduler | XML タスク (atexec) |
atsvc / sasec | 1FF70682-... | atsvc | 古い AT job、タスクアカウント |
srvs | 4B324FC8-...E188 v3 | srvsvc | 共有・セッション |
fsrvp | A8E0653C-...2292 v1 | FssagentRpc | ファイルサーバ remote VSS(MS-FSRVP) |
wkst | 6BFFD098-...345A v1 | wkssvc | ワークステーション / join |
rrp | 338CD001-... v1 | winreg | Remote Registry。boot key のクラス名もここ |
drsuapi | E3514235-...DCD2 v4 | TCP (EPM) | DRSGetNCChanges。通常 PKT_PRIVACY |
bkrp | 3dde7c30-...db40 v1 | — | DPAPI domain backup key |
gkdi | B9785960-...2085 v1 | TCP (EPM) | LAPS v2 / DPAPI-NG の GkdiGetKey |
dcomrt + dcom/wmi | OXID / IWbem* | TCP 135 + 動的 | WMI / MMC / ShellWindows。OXID ping スレッドあり |
nspi | F5CC5A18-...8426 v56 | HTTP 6004 も | Exchange address book |
oxabref | 1544F5E0-...BD09 | HTTP 6001 付近 | RfrGetNewDSA |
icpr | 91ae6020-...91be | cert | 証明書要求 (AD CS relay) |
tsts | 複数 | LSM_API_service 等 | セッション操作 (tstool) |
rprn / par | 12345678-...89AB 等 | spoolss | 印刷スプーラ |
even / even6 | 82273FDC-... / F6BEAFF7-... | eventlog | イベントログ |
mimilib | 17FC11E9-...6244 | — | mimikatz RPC (Microsoft interface ではない) |
dhcpm / raa / iphlp / dssp | 各仕様 | — | DHCP、Authz、マシンロール |
DCOM は通常の bind に加え、OXID resolver、OBJREF、IRemUnknown の
参照カウントがあります。wmiexec は Win32_Process.Create、
dcomexec は ShellWindows / ShellBrowserWindow / MMC20.Application、
wmipersist は permanent event subscription です。途中失敗時の
RemRelease / object 解放が契約です。
典型クライアント手順
Section titled “典型クライアント手順”rpctransport = transport.DCERPCTransportFactory(r'ncacn_np:host[\pipe\svcctl]')rpctransport.set_credentials(user, password, domain, lmhash, nthash)dce = rpctransport.get_dce_rpc()dce.connect()dce.bind(scmr.MSRPC_UUID_SCMR)# scmr.hROpenSCManagerW(dce, ...)dce.disconnect()Kerberos なら transport に set_kerberos(True, kdcHost) を付けます。
変更時の確認
Section titled “変更時の確認”- interface UUID / version / opnum を変えると相手は FAULT を返す
- NDR64 切替はポインタ幅と配列ヘッダの両方に効く
- 新しい auth_type は bind、AUTH3、以降 PDU の SIGN/SEAL の 3 箇所が必要
- 関連テスト:
tests/dcerpc/、tests/misc/test_dcerpc_v5_ndr.py

