Skip to content

Commit 1bf7584

Browse files
committed
Adds support for resolving multiple hosts
1 parent bf5bc65 commit 1bf7584

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

python/meterpreter/ext_server_stdapi.py

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,9 @@ class RTMSG(ctypes.Structure):
581581

582582
TLV_TYPE_SHUTDOWN_HOW = TLV_META_TYPE_UINT | 1530
583583

584+
# Resolve hosts/host
585+
TLV_TYPE_RESOLVE_HOST_ENTRY = TLV_META_TYPE_GROUP | 1550
586+
584587
##
585588
# Railgun
586589
##
@@ -1074,10 +1077,27 @@ def netlink_request(req_type, req_data):
10741077
sock.close()
10751078
return responses
10761079

1080+
# def resolve_host(hostname, family):
1081+
# address_info = getaddrinfo(hostname, family=family, socktype=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP)
1082+
# address = address_info[0]['sockaddr'][0]
1083+
# addresses = []
1084+
# for addr in address_info:
1085+
# addresses.append(addr['sockaddr'][0])
1086+
#
1087+
# all_addresses = ", ".join(addresses)
1088+
# return {'family': family, 'address': address, 'packed_address': inet_pton(family, address), 'all_addresses': all_addresses }
1089+
1090+
# TODO: Let's update this to return an array of hosts
10771091
def resolve_host(hostname, family):
10781092
address_info = getaddrinfo(hostname, family=family, socktype=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP)
1079-
address = address_info[0]['sockaddr'][0]
1080-
return {'family': family, 'address': address, 'packed_address': inet_pton(family, address)}
1093+
addresses = []
1094+
for addr in address_info:
1095+
binary_address = inet_pton(family, addr['sockaddr'][0])
1096+
addresses.append(binary_address)
1097+
1098+
return [{ 'family': family, 'address': addresses }]
1099+
# return [{ 'family': family, 'address': addresses }, { 'family': family, 'address': inet_pton(family, '127.0.0.2') }]
1100+
10811101

10821102
def tlv_pack_local_addrinfo(sock):
10831103
local_host, local_port = sock.getsockname()[:2]
@@ -2633,6 +2653,7 @@ def stdapi_net_config_get_proxy(request, response):
26332653

26342654
@register_function
26352655
def stdapi_net_resolve_host(request, response):
2656+
# TODO: Ticket suggests updating to AF_UNSPEC. not sure if that needs to be here or in Framework's resolve_host method
26362657
hostname = packet_get_tlv(request, TLV_TYPE_HOST_NAME)['value']
26372658
family = packet_get_tlv(request, TLV_TYPE_ADDR_TYPE)['value']
26382659
if family == WIN_AF_INET:
@@ -2641,9 +2662,20 @@ def stdapi_net_resolve_host(request, response):
26412662
family = socket.AF_INET6
26422663
else:
26432664
raise Exception('invalid family')
2665+
# resolve_host will now return an array of objects, we'll loop over the objects and put it into a group. Each group will contain the IP and addr type. - DONE
2666+
# TODO: Assuming I should be calling both familys here and not relying on the family that is pulled out
26442667
result = resolve_host(hostname, family)
2645-
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
2646-
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])
2668+
2669+
# TODO: Update this to now use the pattern of using groups of IP/ADDRTYPE - DONE
2670+
for resolved_host in result:
2671+
host_tlv = bytes()
2672+
for ip in resolved_host['address']:
2673+
host_tlv += tlv_pack(TLV_TYPE_IP, ip)
2674+
host_tlv += tlv_pack(TLV_TYPE_ADDR_TYPE, family)
2675+
2676+
2677+
response += tlv_pack(TLV_TYPE_RESOLVE_HOST_ENTRY, host_tlv)
2678+
26472679
return ERROR_SUCCESS, response
26482680

26492681
@register_function
@@ -2661,8 +2693,14 @@ def stdapi_net_resolve_hosts(request, response):
26612693
result = resolve_host(hostname, family)
26622694
except socket.error:
26632695
result = {'family':family, 'packed_address':''}
2664-
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
2665-
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])
2696+
for resolved_host in result:
2697+
host_tlv = bytes()
2698+
for ip in resolved_host['address']:
2699+
host_tlv += tlv_pack(TLV_TYPE_IP, ip)
2700+
host_tlv += tlv_pack(TLV_TYPE_ADDR_TYPE, family)
2701+
2702+
# TLV_TYPE RESOLVE_HOST_ENTRY
2703+
response += tlv_pack(TLV_TYPE_RESOLVE_HOST_ENTRY, host_tlv)
26662704
return ERROR_SUCCESS, response
26672705

26682706
@register_function

python/meterpreter/tests/test_ext_server_stdapi.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,24 @@ def test_stdapi_sys_config_getsid(self):
320320
).get("value")
321321
self.assertRegex(sid, "S-1-5-.*")
322322

323+
class ExtStdNetResolveTest(ExtServerStdApiTest):
324+
def stdapi_net_resolve_hosts(self):
325+
# Full request from msfconsole
326+
request = b'\x00\x00\x00\x0c\x00\x02\x00\x01\x00\x00\x04\x00\x00\x00\x00)\x00\x01\x00\x0264769531726942037539492283558475\x00\x00\x00\x00\x13\x00\x01\x05xrapid7.com\x00\x00\x00\x00\x0c\x00\x02\x05\xa4\x00\x00\x00\x02'
327+
response = bytes()
328+
_result_code, result_tlvs = self.assertMethodErrorSuccess(
329+
"stdapi_net_resolve_hosts", request, response
330+
)
331+
332+
print(response)
333+
334+
# TODO: Assert
335+
# user_name = self.meterpreter_context["packet_get_tlv"](
336+
# result_tlvs, self.ext_server_stdapi["TLV_TYPE_USER_NAME"]
337+
# ).get("value")
338+
#
339+
#self.assert(response, bytes('......'))
340+
323341

324342
if __name__ == "__main__":
325343
unittest.main()

0 commit comments

Comments
 (0)