1# SPDX-License-Identifier: GPL-2.0-only 2# This file is part of Scapy 3# See https://scapy.net/ for more information 4# Copyright (C) Gabriel Potter 5 6""" 7Very partial RPC definitions for the following interfaces: 8- wkssvc (v1.0): 6BFFD098-A112-3610-9833-46C3F87E345A 9""" 10 11from enum import IntEnum 12import uuid 13 14from scapy.fields import StrFixedLenField 15from scapy.layers.dcerpc import ( 16 register_dcerpc_interface, 17 DceRpcOp, 18 NDRConfPacketListField, 19 NDRConfVarStrLenFieldUtf16, 20 NDRConfVarStrNullFieldUtf16, 21 NDRFullPointerField, 22 NDRInt3264EnumField, 23 NDRIntField, 24 NDRPacket, 25 NDRPacketField, 26 NDRShortField, 27 NDRUnionField, 28) 29 30 31class LPWKSTA_INFO_100(NDRPacket): 32 ALIGNMENT = (4, 8) 33 fields_desc = [ 34 NDRIntField("wki100_platform_id", 0), 35 NDRFullPointerField( 36 NDRConfVarStrNullFieldUtf16("wki100_computername", ""), deferred=True 37 ), 38 NDRFullPointerField( 39 NDRConfVarStrNullFieldUtf16("wki100_langroup", ""), deferred=True 40 ), 41 NDRIntField("wki100_ver_major", 0), 42 NDRIntField("wki100_ver_minor", 0), 43 ] 44 45 46class NetrWkstaGetInfo_Request(NDRPacket): 47 fields_desc = [ 48 NDRFullPointerField(NDRConfVarStrNullFieldUtf16("ServerName", "")), 49 NDRIntField("Level", 0), 50 ] 51 52 53class NetrWkstaGetInfo_Response(NDRPacket): 54 fields_desc = [ 55 NDRUnionField( 56 [ 57 ( 58 NDRFullPointerField( 59 NDRPacketField( 60 "WkstaInfo", LPWKSTA_INFO_100(), LPWKSTA_INFO_100 61 ) 62 ), 63 ( 64 (lambda pkt: getattr(pkt, "Level", None) == 100), 65 (lambda _, val: val.tag == 100), 66 ), 67 ), 68 ], 69 StrFixedLenField("WkstaInfo", "", length=0), 70 align=(4, 8), 71 switch_fmt=("L", "L"), 72 ), 73 NDRIntField("status", 0), 74 ] 75 76 77class NET_COMPUTER_NAME_TYPE(IntEnum): 78 NetPrimaryComputerName = 0 79 NetAlternateComputerNames = 1 80 NetAllComputerNames = 2 81 NetComputerNameTypeMax = 3 82 83 84class PUNICODE_STRING(NDRPacket): 85 ALIGNMENT = (4, 8) 86 fields_desc = [ 87 NDRShortField("Length", None, size_of="Buffer", adjust=lambda _, x: (x * 2)), 88 NDRShortField( 89 "MaximumLength", None, size_of="Buffer", adjust=lambda _, x: (x * 2) 90 ), 91 NDRFullPointerField( 92 NDRConfVarStrLenFieldUtf16( 93 "Buffer", "", length_from=lambda pkt: (pkt.Length // 2) 94 ), 95 deferred=True, 96 ), 97 ] 98 99 100class PNET_COMPUTER_NAME_ARRAY(NDRPacket): 101 ALIGNMENT = (4, 8) 102 fields_desc = [ 103 NDRIntField("EntryCount", None, size_of="ComputerNames"), 104 NDRFullPointerField( 105 NDRConfPacketListField( 106 "ComputerNames", 107 [PUNICODE_STRING()], 108 PUNICODE_STRING, 109 count_from=lambda pkt: pkt.EntryCount, 110 ), 111 deferred=True, 112 ), 113 ] 114 115 116class NetrEnumerateComputerNames_Request(NDRPacket): 117 fields_desc = [ 118 NDRFullPointerField(NDRConfVarStrNullFieldUtf16("ServerName", "")), 119 NDRInt3264EnumField("NameType", 0, NET_COMPUTER_NAME_TYPE), 120 NDRIntField("Reserved", 0), 121 ] 122 123 124class NetrEnumerateComputerNames_Response(NDRPacket): 125 fields_desc = [ 126 NDRFullPointerField( 127 NDRPacketField( 128 "ComputerNames", PNET_COMPUTER_NAME_ARRAY(), PNET_COMPUTER_NAME_ARRAY 129 ) 130 ), 131 NDRIntField("status", 0), 132 ] 133 134 135WKSSVC_OPNUMS = { 136 0: DceRpcOp(NetrWkstaGetInfo_Request, NetrWkstaGetInfo_Response), 137 30: DceRpcOp( 138 NetrEnumerateComputerNames_Request, NetrEnumerateComputerNames_Response 139 ), 140} 141register_dcerpc_interface( 142 name="wkssvc", 143 uuid=uuid.UUID("6BFFD098-A112-3610-9833-46C3F87E345A"), 144 version="1.0", 145 opnums=WKSSVC_OPNUMS, 146) 147