Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# SECUREAUTH LABS. Copyright 2020 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under a slightly modified version 

4# of the Apache Software License. See the accompanying LICENSE file 

5# for more information. 

6# 

7# Authors: 

8# Arseniy Sharoglazov <mohemiv@gmail.com> / Positive Technologies (https://www.ptsecurity.com/) 

9# 

10# Description: 

11# Implementation of iphlpsvc.dll MSRPC calls (Service that offers IPv6 connectivity over an IPv4 network) 

12 

13from socket import inet_aton 

14 

15from impacket import uuid 

16from impacket import hresult_errors 

17from impacket.uuid import uuidtup_to_bin 

18from impacket.dcerpc.v5.dtypes import BYTE, ULONG, WSTR, GUID, NULL 

19from impacket.dcerpc.v5.ndr import NDRCALL, NDRUniConformantArray 

20from impacket.dcerpc.v5.rpcrt import DCERPCException 

21 

22MSRPC_UUID_IPHLP_IP_TRANSITION = uuidtup_to_bin(('552d076a-cb29-4e44-8b6a-d15e59e2c0af', '1.0')) 

23 

24# RPC_IF_ALLOW_LOCAL_ONLY 

25MSRPC_UUID_IPHLP_TEREDO = uuidtup_to_bin(('ecbdb051-f208-46b9-8c8b-648d9d3f3944', '1.0')) 

26MSRPC_UUID_IPHLP_TEREDO_CONSUMER = uuidtup_to_bin(('1fff8faa-ec23-4e3f-a8ce-4b2f8707e636', '1.0')) 

27 

28class DCERPCSessionError(DCERPCException): 

29 def __init__(self, error_string=None, error_code=None, packet=None): 

30 DCERPCException.__init__(self, error_string, error_code, packet) 

31 

32 def __str__( self ): 

33 key = self.error_code 

34 if key in hresult_errors.ERROR_MESSAGES: 

35 error_msg_short = hresult_errors.ERROR_MESSAGES[key][0] 

36 error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1] 

37 return 'IPHLP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 

38 else: 

39 return 'IPHLP SessionError: unknown error code: 0x%x' % self.error_code 

40 

41################################################################################ 

42# CONSTANTS 

43################################################################################ 

44 

45# Notification types 

46NOTIFICATION_ISATAP_CONFIGURATION_CHANGE = 0 

47NOTIFICATION_PROCESS6TO4_CONFIGURATION_CHANGE = 1 

48NOTIFICATION_TEREDO_CONFIGURATION_CHANGE = 2 

49NOTIFICATION_IP_TLS_CONFIGURATION_CHANGE = 3 

50NOTIFICATION_PORT_CONFIGURATION_CHANGE = 4 

51NOTIFICATION_DNS64_CONFIGURATION_CHANGE = 5 

52NOTIFICATION_DA_SITE_MGR_LOCAL_CONFIGURATION_CHANGE_EX = 6 

53 

54################################################################################ 

55# STRUCTURES 

56################################################################################ 

57 

58class BYTE_ARRAY(NDRUniConformantArray): 

59 item = 'c' 

60 

61################################################################################ 

62# RPC CALLS 

63################################################################################ 

64 

65# Opnum 0 

66class IpTransitionProtocolApplyConfigChanges(NDRCALL): 

67 opnum = 0 

68 structure = ( 

69 ('NotificationNum', BYTE), 

70 ) 

71 

72class IpTransitionProtocolApplyConfigChangesResponse(NDRCALL): 

73 structure = ( 

74 ('ErrorCode', ULONG), 

75 ) 

76 

77# Opnum 1 

78class IpTransitionProtocolApplyConfigChangesEx(NDRCALL): 

79 opnum = 1 

80 structure = ( 

81 ('NotificationNum', BYTE), 

82 ('DataLength', ULONG), 

83 ('Data', BYTE_ARRAY), 

84 ) 

85 

86class IpTransitionProtocolApplyConfigChangesExResponse(NDRCALL): 

87 structure = ( 

88 ('ErrorCode', ULONG), 

89 ) 

90 

91# Opnum 2 

92class IpTransitionCreatev6Inv4Tunnel(NDRCALL): 

93 opnum = 2 

94 structure = ( 

95 ('LocalAddress', "4s=''"), 

96 ('RemoteAddress', "4s=''"), 

97 ('InterfaceName', WSTR), 

98 ) 

99 

100class IpTransitionCreatev6Inv4TunnelResponse(NDRCALL): 

101 structure = ( 

102 ('ErrorCode', ULONG), 

103 ) 

104 

105# Opnum 3 

106class IpTransitionDeletev6Inv4Tunnel(NDRCALL): 

107 opnum = 3 

108 structure = ( 

109 ('TunnelGuid', GUID), 

110 ) 

111 

112class IpTransitionDeletev6Inv4TunnelResponse(NDRCALL): 

113 structure = ( 

114 ('ErrorCode', ULONG), 

115 ) 

116 

117################################################################################ 

118# OPNUMs and their corresponding structures 

119################################################################################ 

120 

121OPNUMS = { 

122 0 : (IpTransitionProtocolApplyConfigChanges, IpTransitionProtocolApplyConfigChangesResponse), 

123 1 : (IpTransitionProtocolApplyConfigChangesEx, IpTransitionProtocolApplyConfigChangesExResponse), 

124 2 : (IpTransitionCreatev6Inv4Tunnel, IpTransitionCreatev6Inv4TunnelResponse), 

125 3 : (IpTransitionDeletev6Inv4Tunnel, IpTransitionDeletev6Inv4TunnelResponse) 

126} 

127 

128################################################################################ 

129# HELPER FUNCTIONS 

130################################################################################ 

131def checkNullString(string): 

132 if string == NULL: 

133 return string 

134 

135 if string[-1:] != '\x00': 

136 return string + '\x00' 

137 else: 

138 return string 

139 

140# For all notifications except EX 

141def hIpTransitionProtocolApplyConfigChanges(dce, notification_num): 

142 request = IpTransitionProtocolApplyConfigChanges() 

143 request['NotificationNum'] = notification_num 

144 

145 return dce.request(request) 

146 

147# Only for NOTIFICATION_DA_SITE_MGR_LOCAL_CONFIGURATION_CHANGE_EX 

148# No admin required 

149def hIpTransitionProtocolApplyConfigChangesEx(dce, notification_num, notification_data): 

150 request = IpTransitionProtocolApplyConfigChangesEx() 

151 request['NotificationNum'] = notification_num 

152 request['DataLength'] = len(notification_data) 

153 request['Data'] = notification_data 

154 

155 return dce.request(request) 

156 

157# Same as netsh interface ipv6 add v6v4tunnel "Test Tunnel" 192.168.0.1 10.0.0.5 

158def hIpTransitionCreatev6Inv4Tunnel(dce, local_address, remote_address, interface_name): 

159 request = IpTransitionCreatev6Inv4Tunnel() 

160 request['LocalAddress'] = inet_aton(local_address) 

161 request['RemoteAddress'] = inet_aton(remote_address) 

162 

163 request['InterfaceName'] = checkNullString(interface_name) 

164 request.fields['InterfaceName'].fields['MaximumCount'] = 256 

165 

166 return dce.request(request) 

167 

168def hIpTransitionDeletev6Inv4Tunnel(dce, tunnel_guid): 

169 request = IpTransitionDeletev6Inv4Tunnel() 

170 request['TunnelGuid'] = uuid.string_to_bin(tunnel_guid) 

171 

172 return dce.request(request)