Skip to content

Commit

Permalink
Adds support for resolving multiple hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
cgranleese-r7 committed Oct 18, 2023
1 parent bf5bc65 commit 1bf7584
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
50 changes: 44 additions & 6 deletions python/meterpreter/ext_server_stdapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,9 @@ class RTMSG(ctypes.Structure):

TLV_TYPE_SHUTDOWN_HOW = TLV_META_TYPE_UINT | 1530

# Resolve hosts/host
TLV_TYPE_RESOLVE_HOST_ENTRY = TLV_META_TYPE_GROUP | 1550

##
# Railgun
##
Expand Down Expand Up @@ -1074,10 +1077,27 @@ def netlink_request(req_type, req_data):
sock.close()
return responses

# def resolve_host(hostname, family):
# address_info = getaddrinfo(hostname, family=family, socktype=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP)
# address = address_info[0]['sockaddr'][0]
# addresses = []
# for addr in address_info:
# addresses.append(addr['sockaddr'][0])
#
# all_addresses = ", ".join(addresses)
# return {'family': family, 'address': address, 'packed_address': inet_pton(family, address), 'all_addresses': all_addresses }

# TODO: Let's update this to return an array of hosts
def resolve_host(hostname, family):
address_info = getaddrinfo(hostname, family=family, socktype=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP)
address = address_info[0]['sockaddr'][0]
return {'family': family, 'address': address, 'packed_address': inet_pton(family, address)}
addresses = []
for addr in address_info:
binary_address = inet_pton(family, addr['sockaddr'][0])
addresses.append(binary_address)

return [{ 'family': family, 'address': addresses }]
# return [{ 'family': family, 'address': addresses }, { 'family': family, 'address': inet_pton(family, '127.0.0.2') }]


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

@register_function
def stdapi_net_resolve_host(request, response):
# TODO: Ticket suggests updating to AF_UNSPEC. not sure if that needs to be here or in Framework's resolve_host method
hostname = packet_get_tlv(request, TLV_TYPE_HOST_NAME)['value']
family = packet_get_tlv(request, TLV_TYPE_ADDR_TYPE)['value']
if family == WIN_AF_INET:
Expand All @@ -2641,9 +2662,20 @@ def stdapi_net_resolve_host(request, response):
family = socket.AF_INET6
else:
raise Exception('invalid family')
# 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
# TODO: Assuming I should be calling both familys here and not relying on the family that is pulled out
result = resolve_host(hostname, family)
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])

# TODO: Update this to now use the pattern of using groups of IP/ADDRTYPE - DONE
for resolved_host in result:
host_tlv = bytes()
for ip in resolved_host['address']:
host_tlv += tlv_pack(TLV_TYPE_IP, ip)
host_tlv += tlv_pack(TLV_TYPE_ADDR_TYPE, family)


response += tlv_pack(TLV_TYPE_RESOLVE_HOST_ENTRY, host_tlv)

return ERROR_SUCCESS, response

@register_function
Expand All @@ -2661,8 +2693,14 @@ def stdapi_net_resolve_hosts(request, response):
result = resolve_host(hostname, family)
except socket.error:
result = {'family':family, 'packed_address':''}
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])
for resolved_host in result:
host_tlv = bytes()
for ip in resolved_host['address']:
host_tlv += tlv_pack(TLV_TYPE_IP, ip)
host_tlv += tlv_pack(TLV_TYPE_ADDR_TYPE, family)

# TLV_TYPE RESOLVE_HOST_ENTRY
response += tlv_pack(TLV_TYPE_RESOLVE_HOST_ENTRY, host_tlv)
return ERROR_SUCCESS, response

@register_function
Expand Down
18 changes: 18 additions & 0 deletions python/meterpreter/tests/test_ext_server_stdapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,24 @@ def test_stdapi_sys_config_getsid(self):
).get("value")
self.assertRegex(sid, "S-1-5-.*")

class ExtStdNetResolveTest(ExtServerStdApiTest):
def stdapi_net_resolve_hosts(self):
# Full request from msfconsole
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'
response = bytes()
_result_code, result_tlvs = self.assertMethodErrorSuccess(
"stdapi_net_resolve_hosts", request, response
)

print(response)

# TODO: Assert
# user_name = self.meterpreter_context["packet_get_tlv"](
# result_tlvs, self.ext_server_stdapi["TLV_TYPE_USER_NAME"]
# ).get("value")
#
#self.assert(response, bytes('......'))


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

0 comments on commit 1bf7584

Please sign in to comment.