Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for resolving multiple host ips #681

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 38 additions & 17 deletions php/meterpreter/ext_server_stdapi.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@

define("TLV_TYPE_SHUTDOWN_HOW", TLV_META_TYPE_UINT | 1530);

# Resolve hosts/host
define("TLV_TYPE_RESOLVE_HOST_ENTRY", TLV_META_TYPE_GROUP | 1550);

##
# Sys
##
Expand Down Expand Up @@ -440,10 +443,10 @@ function add_stat_buf($path) {
$st_buf .= pack_p($st['atime']);
$st_buf .= pack_p($st['mtime']);
$st_buf .= pack_p($st['ctime']);

$st_buf .= pack("V", $st['blksize']);
$st_buf .= pack("V", $st['blocks']);

return create_tlv(TLV_TYPE_STAT_BUF, $st_buf);
}
return false;
Expand Down Expand Up @@ -480,16 +483,21 @@ function resolve_host($hostname, $family) {
return NULL;
}

$result = array("family" => $family);
$record = $dns[0];
if ($record["type"] == "A") {
$result["address"] = $record["ip"];
}
if ($record["type"] == "AAAA") {
$result["address"] = $record["ipv6"];
$addresses = [];

foreach ($dns as $record) {
if ($record["type"] == "A") {
$addr = $record["ip"];
}
if ($record["type"] == "AAAA") {
$addr = $record["ipv6"];
}

$binary_address = inet_pton($addr);
array_push($addresses, $binary_address);
}
$result["packed_address"] = inet_pton($result["address"]);
return $result;

return ['family' => $family, 'addresses' => $addresses];
}
}

Expand Down Expand Up @@ -1271,9 +1279,9 @@ function stdapi_registry_set_value($req, &$pkt) {
function stdapi_net_resolve_host($req, &$pkt) {
my_print("doing stdapi_net_resolve_host");
$hostname_tlv = packet_get_tlv($req, TLV_TYPE_HOST_NAME);
$hostname = $hostname['value'];
$hostname = $hostname_tlv['value'];
cgranleese-r7 marked this conversation as resolved.
Show resolved Hide resolved
$family_tlv = packet_get_tlv($req, TLV_TYPE_ADDR_TYPE);
$family = $family['value'];
$family = $family_tlv['value'];

if ($family != WIN_AF_INET && $family != WIN_AF_INET6) {
my_print('invalid family, must be AF_INET or AF_INET6');
Expand All @@ -1282,11 +1290,18 @@ function stdapi_net_resolve_host($req, &$pkt) {

$ret = ERROR_FAILURE;
$result = resolve_host($hostname, $family);

if ($result != NULL) {
$ret = ERROR_SUCCESS;
packet_add_tlv($pkt, create_tlv(TLV_TYPE_IP, $result['packed_address']));
cgranleese-r7 marked this conversation as resolved.
Show resolved Hide resolved
packet_add_tlv($pkt, create_tlv(TLV_TYPE_ADDR_TYPE, $result['family']));
$host_tlv = "";
foreach($result['addresses'] as $ip){
packet_add_tlv($host_tlv, create_tlv(TLV_TYPE_IP, $ip));
packet_add_tlv($host_tlv, create_tlv(TLV_TYPE_ADDR_TYPE, $family));
}

packet_add_tlv($pkt, create_tlv(TLV_TYPE_RESOLVE_HOST_ENTRY, $host_tlv));
}

return $ret;
}
}
Expand All @@ -1311,10 +1326,16 @@ function stdapi_net_resolve_hosts($req, &$pkt) {
packet_add_tlv($pkt, create_tlv(TLV_TYPE_IP, ''));
packet_add_tlv($pkt, create_tlv(TLV_TYPE_ADDR_TYPE, $family));
} else {
packet_add_tlv($pkt, create_tlv(TLV_TYPE_IP, $result['packed_address']));
packet_add_tlv($pkt, create_tlv(TLV_TYPE_ADDR_TYPE, $result['family']));
$host_tlv = "";
foreach($result['addresses'] as $ip){
packet_add_tlv($host_tlv, create_tlv(TLV_TYPE_IP, $ip));
packet_add_tlv($host_tlv, create_tlv(TLV_TYPE_ADDR_TYPE, $family));
}

packet_add_tlv($pkt, create_tlv(TLV_TYPE_RESOLVE_HOST_ENTRY, $host_tlv));
}
}

return ERROR_SUCCESS;
}
}
Expand Down
31 changes: 25 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 @@ -1076,8 +1079,12 @@ def netlink_request(req_type, req_data):

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, 'addresses': addresses }

def tlv_pack_local_addrinfo(sock):
local_host, local_port = sock.getsockname()[:2]
Expand Down Expand Up @@ -2641,9 +2648,16 @@ def stdapi_net_resolve_host(request, response):
family = socket.AF_INET6
else:
raise Exception('invalid family')

result = resolve_host(hostname, family)
response += tlv_pack(TLV_TYPE_IP, result['packed_address'])
response += tlv_pack(TLV_TYPE_ADDR_TYPE, result['family'])

host_tlv = bytes()
for ip in result['addresses']:
host_tlv += tlv_pack(TLV_TYPE_IP, ip)
cgranleese-r7 marked this conversation as resolved.
Show resolved Hide resolved
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 +2675,13 @@ 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'])

host_tlv = bytes()
for ip in result['addresses']:
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 Down
102 changes: 102 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,108 @@ def test_stdapi_sys_config_getsid(self):
).get("value")
self.assertRegex(sid, "S-1-5-.*")

class ExtStdNetResolveTest(ExtServerStdApiTest):
def test_stdapi_net_resolve_host(self):
cgranleese-r7 marked this conversation as resolved.
Show resolved Hide resolved
MSF_AF_INET = 2

request = bytes()
request += self.meterpreter_context["tlv_pack"](
self.meterpreter_context["TLV_TYPE_COMMAND_ID"],
self.meterpreter_context['cmd_string_to_id']('stdapi_net_resolve_host')
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_REQUEST_ID"],
"18252822037434405542596288798302"
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_HOST_NAME"],
"rapid7.com"
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_ADDR_TYPE"],
MSF_AF_INET
)

response = bytes()
_result_code, result_tlvs = self.assertMethodErrorSuccess(
"stdapi_net_resolve_hosts", request, response
)

resolve_host_entries = self.meterpreter_context["packet_get_tlv"](
result_tlvs, self.ext_server_stdapi["TLV_TYPE_RESOLVE_HOST_ENTRY"]
).get("value")

resolved_host_ips = self.meterpreter_context["packet_enum_tlvs"](
resolve_host_entries, self.ext_server_stdapi["TLV_TYPE_IP"]
)

resolved_host_families = self.meterpreter_context["packet_enum_tlvs"](
resolve_host_entries, self.ext_server_stdapi["TLV_TYPE_ADDR_TYPE"]
)

for ip in resolved_host_ips:
resolved_ip = socket.inet_ntop(socket.AF_INET, ip['value'])
self.assertTrue(isinstance(socket.inet_aton(resolved_ip), bytes))

for family in resolved_host_families:
self.assertEqual(family['value'], MSF_AF_INET)

def test_stdapi_net_resolve_hosts(self):
MSF_AF_INET = 2

request = bytes()
request += self.meterpreter_context["tlv_pack"](
self.meterpreter_context["TLV_TYPE_COMMAND_ID"],
self.meterpreter_context['cmd_string_to_id']('stdapi_net_resolve_hosts')
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_REQUEST_ID"],
"11047287278261284282680986949856"
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_ADDR_TYPE"],
MSF_AF_INET
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_HOST_NAME"],
"rapid7.com"
)

request += self.meterpreter_context["tlv_pack"](
self.ext_server_stdapi["TLV_TYPE_HOST_NAME"],
"google.com"
)

response = bytes()
_result_code, result_tlvs = self.assertMethodErrorSuccess(
"stdapi_net_resolve_hosts", request, response
)

resolved_host_entry_list = self.meterpreter_context["packet_enum_tlvs"](
result_tlvs, self.ext_server_stdapi["TLV_TYPE_RESOLVE_HOST_ENTRY"]
)

for resolved_host_entry in resolved_host_entry_list:
resolved_host_ips = self.meterpreter_context["packet_enum_tlvs"](
resolved_host_entry['value'], self.ext_server_stdapi["TLV_TYPE_IP"]
)

resolved_host_families = self.meterpreter_context["packet_enum_tlvs"](
resolved_host_entry['value'], self.ext_server_stdapi["TLV_TYPE_ADDR_TYPE"]
)

for ip in resolved_host_ips:
resolved_ip = socket.inet_ntop(socket.AF_INET, ip['value'])
self.assertTrue(isinstance(socket.inet_aton(resolved_ip), bytes))

for family in resolved_host_families:
self.assertEqual(family['value'], MSF_AF_INET)

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