Squashed commit of the following:

commit 8b4750d0dcbac0686f9403acdf5cab50c918212f
Author: James Lee <egypt@metasploit.com>
Date:   Tue Mar 13 13:14:43 2012 -0600

    Add bins for listing all addresses

    [Fixes #6476]

commit 213dd92ebc9b706a45725e6515c7939d2edace0e
Author: James Lee <egypt@metasploit.com>
Date:   Tue Mar 13 02:08:34 2012 -0600

    Accept multiple addresses and netmasks

    [See #6476]

commit 2e8bd3c3ecfb319bf9456485d2420bb5829b60cc
Author: James Lee <egypt@metasploit.com>
Date:   Tue Mar 13 01:55:57 2012 -0600

    Make inspecting meterpreter packets a little less painful

    Not sure why I originally thought there was no way to access extensions'
    constants before.  A simple `require` makes it all happy.

commit da367907cf579bd3aefaffbc84d2f96a41b85f00
Author: James Lee <egypt@metasploit.com>
Date:   Sun Mar 11 22:08:44 2012 -0600

    Fix up Linux after changes for Windows

commit ec9f04378b0155f69df95d4a94e62d33ce61977c
Author: James Lee <egypt@metasploit.com>
Date:   Sun Mar 11 21:56:11 2012 -0600

    Grab IPv6 addresses on Windows when possible

    Tries to GetProcAddress of GetAdaptersAddresses and falls back to the
    old GetIpAddrTable() function when it isn't available. This should work
    on XPSP1 and newer, albeit without netmasks on versions before Vista.
    Still trying to figure that one out.

commit 1052ebdcf86114fbc03d1a37ab5d4c6a78e82daa
Author: James Lee <egypt@metasploit.com>
Date:   Tue Mar 6 15:34:09 2012 -0700

    Wrap Windows-specifc headers in ifdef

commit f23f20587b3117c38a77e7e5a93d542411e9504f
Author: James Lee <egypt@metasploit.com>
Date:   Tue Mar 6 14:36:34 2012 -0700

    Handle multiple addrs on one iface on the ruby side

commit d7207d075ac6462875d9da531cf20c175629a416
Author: James Lee <egypt@metasploit.com>
Date:   Mon Mar 5 21:57:39 2012 -0700

    Adds IPv6 addrs to win32 get_interfaces response

commit 11ae7e8a45bd56d25841ea8724377e0fb6789d72
Author: James Lee <egypt@metasploit.com>
Date:   Mon Mar 5 09:07:28 2012 -0700

    Don't distinguish between 4 and 6.

    The client can figure it out from the length.

commit 2c7490bdf3e4079f30857ee323d2ce23ab1bd9a5
Author: James Lee <egypt@metasploit.com>
Date:   Sun Mar 4 04:25:26 2012 -0700

    Append to the list instead of assigning to it

    All addresses are being sent to the client now.  Just need a way to
    parse them out correctly on the other side and meterpreter will be able
    to list all addresses on all interfaces on Linux.  Next step is to
    allocate the proper number of TLVs to avoid good ol' stack smashes on
    systems with lots of addresses and then make sure we clean all the
    memory leaks.

    [See #6476]

commit 73bba037ad968b922341c02459017afcc8407a76
Author: James Lee <egypt@metasploit.com>
Date:   Sun Mar 4 03:12:28 2012 -0700

    Lay the groundwork for returning all addresses

    This commit only sends the last interface in the list, but it is looping
    through all of them as evidenced by the log, just need to make sure
    we're not overwriting as we go.

    [See #6476]
unstable
James Lee 2012-03-13 13:19:18 -06:00
parent 81248f35c4
commit dd9ac8a6c0
14 changed files with 464 additions and 232 deletions

Binary file not shown.

BIN
data/meterpreter/msflinker_linux_x86.bin Executable file → Normal file

Binary file not shown.

View File

@ -37,16 +37,26 @@ typedef struct ___u128 {
__u32 a4;
}__u128;
struct iface_address {
int family;
union {
__u32 addr;
__u128 addr6;
} ip;
union {
__u32 netmask;
__u128 netmask6;
} nm;
};
struct iface_entry {
unsigned char name[IFNAMSIZ+1];
__u32 addr;
__u32 netmask;
unsigned char hwaddr[6];
__u128 addr6;
__u128 netmask6;
uint32_t mtu;
uint32_t index;
unsigned char flags[FLAGS_LEN+1];
int addr_count;
struct iface_address *addr_list;
};
struct ifaces_list {

View File

@ -1528,4 +1528,4 @@ DWORD packet_receive_via_http(Remote *remote, Packet **packet)
return 0;
}
#endif
#endif

View File

@ -1,15 +1,15 @@
#include "precomp.h"
/*
* Returns zero or more local interfaces to the requestor
*/
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
#ifdef _WIN32
#include <ws2ipdef.h>
#endif
#ifdef _WIN32
DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
{
Packet *response = packet_create_response(packet);
DWORD result = ERROR_SUCCESS;
DWORD entryCount;
#ifdef _WIN32
Tlv entries[6];
PMIB_IPADDRTABLE table = NULL;
DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
@ -35,26 +35,24 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
}
// Enumerate the entries
for (index = 0;
index < table->dwNumEntries;
index++)
for (index = 0; index < table->dwNumEntries; index++)
{
entryCount = 0;
interface_index_bigendian = htonl(table->table[index].dwIndex);
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_INTERFACE_INDEX;
entries[entryCount].buffer = (PUCHAR)&interface_index_bigendian;
entries[entryCount].header.type = TLV_TYPE_INTERFACE_INDEX;
entries[entryCount].buffer = (PUCHAR)&interface_index_bigendian;
entryCount++;
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_IP;
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwAddr;
entries[entryCount].header.type = TLV_TYPE_IP;
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwAddr;
entryCount++;
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_NETMASK;
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwMask;
entries[entryCount].header.type = TLV_TYPE_NETMASK;
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwMask;
entryCount++;
iface.dwIndex = table->table[index].dwIndex;
@ -63,28 +61,28 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
if (GetIfEntry(&iface) == NO_ERROR)
{
entries[entryCount].header.length = iface.dwPhysAddrLen;
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
entries[entryCount].buffer = (PUCHAR)iface.bPhysAddr;
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
entries[entryCount].buffer = (PUCHAR)iface.bPhysAddr;
entryCount++;
mtu_bigendian = htonl(iface.dwMtu);
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_INTERFACE_MTU;
entries[entryCount].buffer = (PUCHAR)&mtu_bigendian;
entries[entryCount].header.type = TLV_TYPE_INTERFACE_MTU;
entries[entryCount].buffer = (PUCHAR)&mtu_bigendian;
entryCount++;
if (iface.bDescr)
{
entries[entryCount].header.length = iface.dwDescrLen + 1;
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
entries[entryCount].buffer = (PUCHAR)iface.bDescr;
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
entries[entryCount].buffer = (PUCHAR)iface.bDescr;
entryCount++;
}
}
// Add the interface group
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
entries, entryCount);
entries, entryCount);
}
} while (0);
@ -92,64 +90,249 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
if (table)
free(table);
return result;
}
DWORD get_interfaces_windows(Remote *remote, Packet *response) {
DWORD result = ERROR_SUCCESS;
DWORD entryCount;
// Most of the time we'll need:
// index, name (description), MAC addr, mtu, flags, IP addr, netmask, maybe scope id
// In some cases, the interface will have multiple addresses, so we'll realloc
// this when necessary, but this will cover the common case.
DWORD allocd_entries = 10;
Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 10);
DWORD mtu_bigendian;
DWORD interface_index_bigendian;
ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_DNS_SERVER;
LPSOCKADDR sockaddr;
ULONG family = AF_UNSPEC;
IP_ADAPTER_ADDRESSES *pAdapters = NULL;
IP_ADAPTER_ADDRESSES *pCurr = NULL;
ULONG outBufLen = 0;
DWORD (WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);
// Use the larger version so we're guaranteed to have a large enough struct
IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr;
do
{
gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
);
if (!gaa) {
result = get_interfaces_windows_mib(remote, response);
// --- DEBUG ---
packet_add_tlv_uint(response, TLV_TYPE_EXIT_CODE, 666);
// --- END DEBUG ---
break;
}
gaa(family, flags, NULL, pAdapters, &outBufLen);
if (!(pAdapters = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen)))
{
result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
if (gaa(family, flags, NULL, pAdapters, &outBufLen))
{
result = GetLastError();
break;
}
// Enumerate the entries
for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
{
entryCount = 0;
interface_index_bigendian = htonl(pCurr->IfIndex);
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_INTERFACE_INDEX;
entries[entryCount].buffer = (PUCHAR)&interface_index_bigendian;
entryCount++;
entries[entryCount].header.length = pCurr->PhysicalAddressLength;
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
entries[entryCount].buffer = (PUCHAR)pCurr->PhysicalAddress;
entryCount++;
entries[entryCount].header.length = wcslen(pCurr->Description)*2 + 1;
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
entries[entryCount].buffer = (PUCHAR)pCurr->Description;
entryCount++;
mtu_bigendian = htonl(pCurr->Mtu);
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_INTERFACE_MTU;
entries[entryCount].buffer = (PUCHAR)&mtu_bigendian;
entryCount++;
for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
{
// This loop can add up to three Tlv's - one for address, one for scope_id, one for netmask.
// Go ahead and allocate enough room for all of them.
if (allocd_entries < entryCount+3) {
entries = realloc(entries, sizeof(Tlv) * (entryCount+3));
allocd_entries += 3;
}
sockaddr = pAddr->Address.lpSockaddr;
if (sockaddr->sa_family == AF_INET) {
entries[entryCount].header.length = 4;
entries[entryCount].header.type = TLV_TYPE_IP;
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
if (pCurr->Length > 68) {
// --- DEBUG ---
packet_add_tlv_uint(response, TLV_TYPE_EXIT_CODE, 1337);
// --- END DEBUG ---
entryCount++;
entries[entryCount].header.length = 4;
entries[entryCount].header.type = TLV_TYPE_NETMASK;
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
}
} else {
entries[entryCount].header.length = 16;
entries[entryCount].header.type = TLV_TYPE_IP;
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
entryCount++;
entries[entryCount].header.length = sizeof(DWORD);
entries[entryCount].header.type = TLV_TYPE_IP6_SCOPE;
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id);
if (pCurr->Length > 68) {
entryCount++;
entries[entryCount].header.length = 16;
entries[entryCount].header.type = TLV_TYPE_NETMASK;
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
}
}
entryCount++;
}
// Add the interface group
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
entries, entryCount);
}
} while (0);
if (entries)
free(entries);
return result;
}
#else
int get_interfaces_linux(Remote *remote, Packet *response) {
struct ifaces_list *ifaces = NULL;
int i;
int if_error;
int result;
uint32_t interface_index_bigendian, mtu_bigendian;
Tlv entries[9];
// wild guess, should probably malloc
Tlv entries[39];
if_error = netlink_get_interfaces(&ifaces);
dprintf("Grabbing interfaces");
result = netlink_get_interfaces(&ifaces);
dprintf("Got 'em");
if (if_error) {
result = if_error;
} else {
if (!result) {
for (i = 0; i < ifaces->entries; i++) {
int tlv_cnt = 0;
int j = 0;
dprintf("Building TLV for iface %d", i);
entries[0].header.length = strlen(ifaces->ifaces[i].name)+1;
entries[0].header.type = TLV_TYPE_MAC_NAME;
entries[0].buffer = (PUCHAR)ifaces->ifaces[i].name;
entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].name)+1;
entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].name;
tlv_cnt++;
entries[1].header.length = 6;
entries[1].header.type = TLV_TYPE_MAC_ADDR;
entries[1].buffer = (PUCHAR)ifaces->ifaces[i].hwaddr;
entries[tlv_cnt].header.length = 6;
entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].hwaddr;
tlv_cnt++;
entries[2].header.length = sizeof(__u32);
entries[2].header.type = TLV_TYPE_IP;
entries[2].buffer = (PUCHAR)&ifaces->ifaces[i].addr;
for (j = 0; j < ifaces->ifaces[i].addr_count; j++) {
if (ifaces->ifaces[i].addr_list[j].family == AF_INET) {
dprintf("ip addr for %s", ifaces->ifaces[i].name);
entries[tlv_cnt].header.length = sizeof(__u32);
entries[tlv_cnt].header.type = TLV_TYPE_IP;
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr;
tlv_cnt++;
entries[3].header.length = sizeof(__u32);
entries[3].header.type = TLV_TYPE_NETMASK;
entries[3].buffer = (PUCHAR)&ifaces->ifaces[i].netmask;
//dprintf("netmask for %s", ifaces->ifaces[i].name);
entries[tlv_cnt].header.length = sizeof(__u32);
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask;
tlv_cnt++;
} else {
dprintf("-- ip six addr for %s", ifaces->ifaces[i].name);
entries[tlv_cnt].header.length = sizeof(__u128);
entries[tlv_cnt].header.type = TLV_TYPE_IP;
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr6;
tlv_cnt++;
entries[4].header.length = sizeof(__u128);
entries[4].header.type = TLV_TYPE_IP6;
entries[4].buffer = (PUCHAR)&ifaces->ifaces[i].addr6;
entries[5].header.length = sizeof(__u128);
entries[5].header.type = TLV_TYPE_NETMASK6;
entries[5].buffer = (PUCHAR)&ifaces->ifaces[i].netmask6;
//dprintf("netmask6 for %s", ifaces->ifaces[i].name);
entries[tlv_cnt].header.length = sizeof(__u128);
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask6;
tlv_cnt++;
}
}
mtu_bigendian = htonl(ifaces->ifaces[i].mtu);
entries[6].header.length = sizeof(uint32_t);
entries[6].header.type = TLV_TYPE_INTERFACE_MTU;
entries[6].buffer = (PUCHAR)&mtu_bigendian;
entries[tlv_cnt].header.length = sizeof(uint32_t);
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
tlv_cnt++;
entries[7].header.length = strlen(ifaces->ifaces[i].flags)+1;
entries[7].header.type = TLV_TYPE_INTERFACE_FLAGS;
entries[7].buffer = (PUCHAR)ifaces->ifaces[i].flags;
entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].flags)+1;
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_FLAGS;
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].flags;
tlv_cnt++;
interface_index_bigendian = htonl(ifaces->ifaces[i].index);
entries[8].header.length = sizeof(uint32_t);
entries[8].header.type = TLV_TYPE_INTERFACE_INDEX;
entries[8].buffer = (PUCHAR)&interface_index_bigendian;
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, 9);
entries[tlv_cnt].header.length = sizeof(uint32_t);
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
tlv_cnt++;
dprintf("Adding TLV to group");
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, tlv_cnt);
dprintf("done Adding TLV to group");
}
}
if (ifaces)
free(ifaces);
return result;
}
#endif
/*
* Returns zero or more local interfaces to the requestor
*/
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD result = ERROR_SUCCESS;
#ifdef _WIN32
result = get_interfaces_windows(remote, response);
#else
result = get_interfaces_linux(remote, response);
#endif
// Transmit the response if valid
@ -159,5 +342,3 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
}

View File

@ -355,26 +355,6 @@
TLV_META_TYPE_GROUP, \
TLV_TYPE_EXTENSION_STDAPI, \
1423)
#define TLV_TYPE_SUBNET6 \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_RAW, \
TLV_TYPE_EXTENSION_STDAPI, \
1424)
#define TLV_TYPE_NETMASK6 \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_RAW, \
TLV_TYPE_EXTENSION_STDAPI, \
1425)
#define TLV_TYPE_GATEWAY6 \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_RAW, \
TLV_TYPE_EXTENSION_STDAPI, \
1426)
#define TLV_TYPE_NETWORK_ROUTE6 \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_GROUP, \
TLV_TYPE_EXTENSION_STDAPI, \
1427)
#define TLV_TYPE_IP \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_RAW, \
@ -395,9 +375,9 @@
TLV_META_TYPE_GROUP, \
TLV_TYPE_EXTENSION_STDAPI, \
1433)
#define TLV_TYPE_IP6 \
#define TLV_TYPE_IP6_SCOPE \
MAKE_CUSTOM_TLV( \
TLV_META_TYPE_RAW, \
TLV_META_TYPE_RAW, \
TLV_TYPE_EXTENSION_STDAPI, \
1434)

View File

@ -158,8 +158,8 @@ int netlink_parse(int fd, int seq, netlink_cb_t callback, void *data)
}
for(nh = (struct nlmsghdr *)(buf); NLMSG_OK(nh, len); nh = (struct nlmsghdr *) NLMSG_NEXT(nh, len)) {
dprintf("buf = %p, nh = %p", buf, nh);
dprintf("nh->nlmsg_type = %d", nh->nlmsg_type);
//dprintf("buf = %p, nh = %p", buf, nh);
//dprintf("nh->nlmsg_type = %d", nh->nlmsg_type);
if(nh->nlmsg_type == NLMSG_DONE) {
end = 1;
@ -168,12 +168,12 @@ int netlink_parse(int fd, int seq, netlink_cb_t callback, void *data)
if(nh->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *me = (struct nlmsgerr *) NLMSG_DATA (nh);
dprintf("in NLMSG_ERROR handling.. me = %p");
dprintf("me->error = %d", me->error);
//dprintf("in NLMSG_ERROR handling.. me = %p", me);
//dprintf("me->error = %d", me->error);
if(me->error) {
dprintf("so, we have: nlmsg_len: %d, nlmsg_type: %d, nlmsg_flags: %d, nlmsg_seq: %d, nlmsg_pid: %d",
me->msg.nlmsg_len, me->msg.nlmsg_type, me->msg.nlmsg_flags,
me->msg.nlmsg_seq, me->msg.nlmsg_pid);
//dprintf("so, we have: nlmsg_len: %d, nlmsg_type: %d, nlmsg_flags: %d, nlmsg_seq: %d, nlmsg_pid: %d",
// me->msg.nlmsg_len, me->msg.nlmsg_type, me->msg.nlmsg_flags,
// me->msg.nlmsg_seq, me->msg.nlmsg_pid);
if(me->msg.nlmsg_seq == seq) {
dprintf("Hum. kernel doesn't like our message :~(");
@ -188,7 +188,7 @@ int netlink_parse(int fd, int seq, netlink_cb_t callback, void *data)
//
dprintf("[%s] dispatching into callback", __FUNCTION__);
dprintf("dispatching into callback");
status = callback(nh, data);
@ -262,7 +262,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
dprintf("Adjusted rm at +4");
}
dprintf("rtm_family : 0x%x , rtm_dst_len : 0x%x, rtm_src_len : 0x%x",rm->rtm_family, rm->rtm_dst_len, rm->rtm_src_len);
//dprintf("rtm_family : 0x%x , rtm_dst_len : 0x%x, rtm_src_len : 0x%x",rm->rtm_family, rm->rtm_dst_len, rm->rtm_src_len);
// print directly connected routes
if(rm->rtm_type != RTN_UNICAST && rm->rtm_type != RTN_LOCAL) {
dprintf("got %d instead of RTN_UNICAST (%d) or RTN_LOCAL (%d)", rm->rtm_type, RTN_UNICAST,RTN_LOCAL);
@ -289,7 +289,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
else
is_ipv6 = 1;
dprintf("nh->nlmsg_len: %d, NLMSG_LENGTH(sizeof(..)): %d, is_ipv6 : %d", nh->nlmsg_len, NLMSG_LENGTH(sizeof(struct rtmsg)),is_ipv6);
//dprintf("nh->nlmsg_len: %d, NLMSG_LENGTH(sizeof(..)): %d, is_ipv6 : %d", nh->nlmsg_len, NLMSG_LENGTH(sizeof(struct rtmsg)),is_ipv6);
len = nh->nlmsg_len - NLMSG_LENGTH (sizeof(struct rtmsg));
if(len <= 0) {
@ -297,12 +297,12 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
return 0;
}
dprintf("RTA_DST=%d, RTA_SRC=%d, RTA_GATEWAY=%d, RTA_PREFSRC=%d, RTA_OIF=%d, RTA_PRIORITY=%d", RTA_DST, RTA_SRC, RTA_GATEWAY, RTA_PREFSRC,RTA_OIF, RTA_PRIORITY);
//dprintf("RTA_DST=%d, RTA_SRC=%d, RTA_GATEWAY=%d, RTA_PREFSRC=%d, RTA_OIF=%d, RTA_PRIORITY=%d", RTA_DST, RTA_SRC, RTA_GATEWAY, RTA_PREFSRC,RTA_OIF, RTA_PRIORITY);
dprintf("rtm_table : %d, RT_TABLE_UNSPEC=%d, RT_TABLE_DEFAULT =%d, RT_TABLE_MAIN=%d,RT_TABLE_LOCAL=%d", rm->rtm_table,RT_TABLE_UNSPEC, RT_TABLE_DEFAULT , RT_TABLE_MAIN, RT_TABLE_LOCAL);
//dprintf("rtm_table : %d, RT_TABLE_UNSPEC=%d, RT_TABLE_DEFAULT =%d, RT_TABLE_MAIN=%d,RT_TABLE_LOCAL=%d", rm->rtm_table,RT_TABLE_UNSPEC, RT_TABLE_DEFAULT , RT_TABLE_MAIN, RT_TABLE_LOCAL);
dprintf("rtm_type : %d, RTN_UNICAST=%d, RTN_LOCAL=%d", rm->rtm_type,RTN_UNICAST, RTN_LOCAL);
//dprintf("rtm_type : %d, RTN_UNICAST=%d, RTN_LOCAL=%d", rm->rtm_type,RTN_UNICAST, RTN_LOCAL);
// okay, so.
//
@ -310,11 +310,11 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
{
if (is_ipv6) {
what6 = (unsigned char *) RTA_DATA(ra);
dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x %08x %08x %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *(__u32 *)what6, *(__u32 *)(what6+4), *(__u32 *)(what6+8), *(__u32 *)(what6+12));
//dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x %08x %08x %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *(__u32 *)what6, *(__u32 *)(what6+4), *(__u32 *)(what6+8), *(__u32 *)(what6+12));
}
else {
what = (__u32 *) RTA_DATA(ra);
dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *what);
//dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *what);
}
switch(ra->rta_type) {
@ -341,7 +341,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
}
}
dprintf("and while you're here, rtm_dst_len = %d", rm->rtm_dst_len);
//dprintf("and while you're here, rtm_dst_len = %d", rm->rtm_dst_len);
if (is_ipv6) {
// if netmask is FFFFFFFF FFFFFFFF 00000000 00000000 (/64), netmask6.a1 and netmask6.a2 == 0xffffffff, and nestmask6.a3 and .a4 == 0
@ -387,11 +387,11 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
strncpy(re6->interface, int_name, IFNAMSIZ);
re6->metric = metric;
dprintf("re6->dest6 = %08x %08x %08x %08x, re6->netmask6 = %08x %08x %08x %08x, re6->nexthop6 = %08x %08x %08x %08x, interface = %s, metric = %d",
re6->dest6.a1,re6->dest6.a2,re6->dest6.a3,re6->dest6.a4,
re6->netmask6.a1,re6->netmask6.a2,re6->netmask6.a3,re6->netmask6.a4,
re6->nexthop6.a1,re6->nexthop6.a2,re6->nexthop6.a3,re6->nexthop6.a4,
re6->interface,re6->metric);
//dprintf("re6->dest6 = %08x %08x %08x %08x, re6->netmask6 = %08x %08x %08x %08x, re6->nexthop6 = %08x %08x %08x %08x, interface = %s, metric = %d",
// re6->dest6.a1,re6->dest6.a2,re6->dest6.a3,re6->dest6.a4,
// re6->netmask6.a1,re6->netmask6.a2,re6->netmask6.a3,re6->netmask6.a4,
// re6->nexthop6.a1,re6->nexthop6.a2,re6->nexthop6.a3,re6->nexthop6.a4,
// re6->interface,re6->metric);
tmp6->entries++;
*table_v6 = tmp6;
@ -414,7 +414,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
strncpy(re->interface, int_name, IFNAMSIZ);
re->metric = metric;
dprintf("re->dest = %08x, re->netmask = %08x, re->nexthop = %08x, interface = %s, metric = %d", re->dest, re->netmask, re->nexthop,re->interface,re->metric);
//dprintf("re->dest = %08x, re->netmask = %08x, re->nexthop = %08x, interface = %s, metric = %d", re->dest, re->netmask, re->nexthop,re->interface,re->metric);
tmp->entries++;
*table_v4 = tmp;
@ -531,7 +531,7 @@ int netlink_parse_interface_link(struct nlmsghdr *nh, void *data)
iface = (unsigned char *)iface + 4;
dprintf("Adjusted iface at +4");
}
dprintf("ifi_family : 0x%x , ifi_type : 0x%x, ifi_index : 0x%x",iface->ifi_family, iface->ifi_type, iface->ifi_index);
//dprintf("ifi_family : 0x%x , ifi_type : 0x%x, ifi_index : 0x%x",iface->ifi_family, iface->ifi_type, iface->ifi_index);
len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*iface));
memset(&iface_tmp, 0, sizeof(iface_tmp));
@ -642,8 +642,7 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
{
struct ifaces_list ** iface_list = ( struct ifaces_list **) data;
struct iface_entry * iff;
struct iface_entry * iff_tmp;
struct ifaces_list *tmp;
struct ifaces_list * iface_list_tmp;
struct iface_entry iface_tmp;
struct ifaddrmsg *iaddr;
@ -652,6 +651,11 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
uint32_t newsize;
unsigned char is_ipv6;
struct iface_address *addr_tmp;
// strictly for debugging
char addr_str[64];
iaddr = NLMSG_DATA(nh);
// stumbled upon an old system with 4 bytes padding between nlmsghdr and ifaddrmsg, try to detect it
if (!likely_ifaddrmsg(iaddr)) {
@ -659,7 +663,6 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
dprintf("Adjusted iaddr at +4");
}
dprintf("ifa_family : 0x%x , ifa_prefixlen : 0x%x, ifa_flags : 0x%x, ifa_scope : 0x%x",iaddr->ifa_family, iaddr->ifa_prefixlen, iaddr->ifa_flags, iaddr->ifa_scope);
len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*iaddr));
if (iaddr->ifa_family == AF_INET6)
@ -667,127 +670,111 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
else if (iaddr->ifa_family == AF_INET)
is_ipv6 = 0;
else {
dprintf("Got iaddr->ifa_family : %d which is unknown (iaddr->ifa_index : %d)", iaddr->ifa_family, iaddr->ifa_index);
//dprintf("Got iaddr->ifa_family : %d which is unknown (iaddr->ifa_index : %d)", iaddr->ifa_family, iaddr->ifa_index);
return 0;
}
memset(&iface_tmp, 0, sizeof(iface_tmp));
iface_tmp.index = iaddr->ifa_index;
dprintf("-------------------------------------");
for (attribute = IFA_RTA(iaddr); RTA_OK(attribute, len); attribute = RTA_NEXT(attribute, len))
{
dprintf("Start of loop, attribute->rta_type = %d", attribute->rta_type);
switch(attribute->rta_type)
{
case IFA_ADDRESS:
// Make room for a new address
iface_tmp.addr_count++;
iface_tmp.addr_list = realloc(iface_tmp.addr_list, sizeof(struct iface_address) * iface_tmp.addr_count);
addr_tmp = &iface_tmp.addr_list[iface_tmp.addr_count-1];
if (is_ipv6)
memcpy(&iface_tmp.addr6, (unsigned char *) RTA_DATA(attribute), sizeof(__u128));
else
iface_tmp.addr = *(__u32 *) RTA_DATA(attribute);
{
addr_tmp->family = AF_INET6;
memcpy(&addr_tmp->ip.addr6, (unsigned char *) RTA_DATA(attribute), sizeof(__u128));
} else {
addr_tmp->family = AF_INET;
addr_tmp->ip.addr = *(__u32 *) RTA_DATA(attribute);
}
address_calculate_netmask(addr_tmp, iaddr->ifa_prefixlen);
inet_ntop(addr_tmp->family, &addr_tmp->ip, addr_str, sizeof(addr_str));
dprintf("Interface: %s", addr_str);
inet_ntop(addr_tmp->family, &addr_tmp->nm, addr_str, sizeof(addr_str));
dprintf("Netmask: %s", addr_str);
break;
case IFA_LABEL:
strncpy(iface_tmp.name, (unsigned char *) RTA_DATA(attribute), IFNAMSIZ);
dprintf("Copied name %s", iface_tmp.name);
break;
default:
break;
}
dprintf("-------------------------------------");
}
dprintf("and while you're here, iaddr->ifa_prefixlen = %d", iaddr->ifa_prefixlen);
if (is_ipv6) {
// if netmask is FFFFFFFF FFFFFFFF 00000000 00000000 (/64), netmask6.a1 and netmask6.a2 == 0xffffffff, and nestmask6.a3 and .a4 == 0
// netmask6 is set to 0 at the beginning of the function, no need to reset the values to 0 if it is needed
// XXX really ugly, but works
if (iaddr->ifa_prefixlen >= 96) {
iface_tmp.netmask6.a4 = (1 << (iaddr->ifa_prefixlen-96))-1;
iface_tmp.netmask6.a1 = iface_tmp.netmask6.a2 = iface_tmp.netmask6.a3 = 0xffffffff;
}
else if (iaddr->ifa_prefixlen >= 64) {
iface_tmp.netmask6.a3 = (1 << (iaddr->ifa_prefixlen-64))-1;
iface_tmp.netmask6.a1 = iface_tmp.netmask6.a2 = 0xffffffff;
}
else if (iaddr->ifa_prefixlen >= 32) {
iface_tmp.netmask6.a2 = (1 << (iaddr->ifa_prefixlen-32))-1;
iface_tmp.netmask6.a1 = 0xffffffff;
}
else
iface_tmp.netmask6.a1 = (1 << iaddr->ifa_prefixlen)-1;
}
else {
if (iaddr->ifa_prefixlen == 32)
iface_tmp.netmask = 0xffffffff;
else
iface_tmp.netmask = ((1 << iaddr->ifa_prefixlen) - 1);
}
dprintf("Exited loop");
/*
* try to find the iface by index and name
* an IP alias (eth0:0 for instance) will have the same index but not the same name/label
* no alias when getting IPv6 address, so just search using the index
* An IP alias (eth0:0 for instance) will have the same index but not the
* same name/label. There are no aliases when getting IPv6 address, so
* just search using the index.
*/
if (is_ipv6) {
iff = find_iface_by_index(*iface_list, iaddr->ifa_index);
iff = find_iface_by_index(*iface_list, iface_tmp.index);
if (iff == NULL) {
dprintf("Cannot find iface with index %d", iaddr->ifa_index);
dprintf("Cannot find iface with index %d", iface_tmp.index);
return 0;
}
}
else
iff = find_iface_by_index_and_name(*iface_list, iaddr->ifa_index, iface_tmp.name);
iff = find_iface_by_index_and_name(*iface_list, iface_tmp.index, iface_tmp.name);
if (iff == NULL) {
dprintf("[%s] %s an alias?", __FUNCTION__, iface_tmp.name);
// didn't find this name, probably an alias such as eth0:0
iff = find_iface_by_index(*iface_list, iaddr->ifa_index);
/* Now we're dealing with an IPv4 alias such as eth0:0. With a regular
* interface, the mac address, mtu, flags, etc. would already have been
* initialized when we did the RTM_GETLINK request. Since an alias
* doesn't count as a physical interface, that didn't happen, so copy
* all of the parent interface's info to this one.
*/
dprintf("%s an alias?", iface_tmp.name);
iff = find_iface_by_index(*iface_list, iface_tmp.index);
if (iff == NULL) {
dprintf("Cannot find iface with index %d", iaddr->ifa_index);
dprintf("Cannot find iface with index %d", iface_tmp.index);
return 0;
}
// found it, copy the data to save it
// old MAC addr and MTU
memcpy(iface_tmp.hwaddr, iff->hwaddr, 6);
iface_tmp.mtu = iff->mtu;
iface_tmp.index = iff->index;
memcpy(&iface_tmp.addr6, &iff->addr6, sizeof(__u128));
memcpy(&iface_tmp.netmask6, &iff->netmask6, sizeof(__u128));
strncpy(iface_tmp.flags, iff->flags, FLAGS_LEN);
// allocate new one
// expand the list to accomodate the new one
newsize = sizeof(struct ifaces_list);
newsize += ((*iface_list)->entries + 1) * sizeof(struct iface_entry);
iface_list_tmp = realloc(*iface_list, newsize);
tmp = realloc(*iface_list, newsize);
if(tmp == NULL) {
if(iface_list_tmp == NULL) {
return ENOMEM;
}
iff = &(tmp->ifaces[tmp->entries]);
iff = &(iface_list_tmp->ifaces[iface_list_tmp->entries]);
memset(iff, 0, sizeof(struct iface_entry));
// copy back saved data in new iface_entry
memcpy(iff->hwaddr, iface_tmp.hwaddr, 6);
iff->mtu = iface_tmp.mtu;
iff->index = iface_tmp.index;
memcpy(&iff->addr6, &iface_tmp.addr6, sizeof(__u128));
memcpy(&iff->netmask6, &iface_tmp.netmask6, sizeof(__u128));
strncpy(iff->flags, iface_tmp.flags, FLAGS_LEN);
// copy new name
strncpy(iff->name, iface_tmp.name, IFNAMSIZ);
tmp->entries++;
*iface_list = tmp;
}
//now, iff points to a iface_entry, just copy add/addr6 and netmask/netmask6
if (is_ipv6) {
memcpy(&iff->addr6, &iface_tmp.addr6, sizeof(__u128));
memcpy(&iff->netmask6, &iface_tmp.netmask6, sizeof(__u128));
}
else {
iff->addr = iface_tmp.addr;
iff->netmask = iface_tmp.netmask;
iface_list_tmp->entries++;
*iface_list = iface_list_tmp;
}
dprintf("iff->index = %d, iff->name = %s, iff->addr = %08x, iff->netmask = %08x, iff->addr6 = %08x %08x %08x %08x, iff->netmask6 = %08x %08x %08x %08x",
iff->index, iff->name, iff->addr, iff->netmask,
iff->addr6.a1,iff->addr6.a2,iff->addr6.a3,iff->addr6.a4, iff->netmask6.a1,iff->netmask6.a2,iff->netmask6.a3,iff->netmask6.a4);
inet_ntop(addr_tmp->family, &addr_tmp->ip, addr_str, sizeof(addr_str));
dprintf("Appending: %s", addr_str);
iface_entry_append_address(iff, &iface_tmp.addr_list[0]);
dprintf("iff->addr_count = %d; iface_tmp.addr_count = %d", iff->addr_count, iface_tmp.addr_count);
return 0;
}
@ -836,7 +823,7 @@ int netlink_get_interfaces(struct ifaces_list **iface_list)
return ERROR_NOT_SUPPORTED;
}
// for each interface created before, will get the IPv4 / IPv6 addr
status = netlink_parse(fd, seq, netlink_parse_interface_address, iface_list);
status = netlink_parse(fd, seq, netlink_parse_interface_address, iface_list);
close(fd);
if(status != 0) {
if (*iface_list)
@ -848,3 +835,42 @@ int netlink_get_interfaces(struct ifaces_list **iface_list)
return status;
}
void address_calculate_netmask(struct iface_address *address, int ifa_prefixlen) {
if (address->family == AF_INET6) {
// if netmask is FFFFFFFF FFFFFFFF 00000000 00000000 (/64), netmask6.a1 and netmask6.a2 == 0xffffffff, and nestmask6.a3 and .a4 == 0
// netmask6 is set to 0 at the beginning of the function, no need to reset the values to 0 if it is needed
// XXX really ugly, but works
if (ifa_prefixlen >= 96) {
address->nm.netmask6.a4 = (1 << (ifa_prefixlen-96))-1;
address->nm.netmask6.a1 = address->nm.netmask6.a2 = address->nm.netmask6.a3 = 0xffffffff;
}
else if (ifa_prefixlen >= 64) {
address->nm.netmask6.a3 = (1 << (ifa_prefixlen-64))-1;
address->nm.netmask6.a1 = address->nm.netmask6.a2 = 0xffffffff;
}
else if (ifa_prefixlen >= 32) {
address->nm.netmask6.a2 = (1 << (ifa_prefixlen-32))-1;
address->nm.netmask6.a1 = 0xffffffff;
}
else
address->nm.netmask6.a1 = (1 << ifa_prefixlen)-1;
}
else {
if (ifa_prefixlen == 32)
address->nm.netmask = 0xffffffff;
else
address->nm.netmask = ((1 << ifa_prefixlen) - 1);
}
}
void iface_entry_append_address(struct iface_entry *iface, struct iface_address *address) {
iface->addr_count++;
iface->addr_list = realloc(iface->addr_list, sizeof(struct iface_address) * iface->addr_count);
dprintf("Realloc'd %p", iface->addr_list);
memcpy(&iface->addr_list[iface->addr_count-1], address, sizeof(struct iface_address));
}

View File

@ -312,18 +312,18 @@ class Meterpreter < Rex::Post::Meterpreter::Client
# Try to match our visible IP to a real interface
# TODO: Deal with IPv6 addresses
found = ifaces.find {|i| i.ip == shost }
found = !!(ifaces.find {|i| i.addrs.find {|a| p a; a == shost } })
nhost = nil
hobj = nil
if Rex::Socket.is_ipv4?(shost) and not found
# Try to find an interface with a default route
default_routes = routes.select{ |r| r.subnet == "0.0.0.0" }
default_routes = routes.select{ |r| r.subnet == "0.0.0.0" || r.subnet == "::" }
default_routes.each do |r|
ifaces.each do |i|
cidr = Rex::Socket.net2bitmask( i.netmask ) rescue "/32"
rang = Rex::Socket::RangeWalker.new( "#{i.ip}/#{cidr}" ) rescue nil
bits = Rex::Socket.net2bitmask( i.netmask ) rescue 32
rang = Rex::Socket::RangeWalker.new( "#{i.ip}/#{bits}" ) rescue nil
if rang and rang.include?( r.gateway )
nhost = i.ip
break

View File

@ -58,16 +58,27 @@ class Config
response = client.send_request(request)
response.each(TLV_TYPE_NETWORK_INTERFACE) { |iface|
addrs = []
netmasks = []
while (a = iface.get_tlv_value(TLV_TYPE_IP, addrs.length))
# Netmasks aren't tightly associated with addresses, they're
# just thrown all together in the interface TLV ordered to
# match up. This could be done better by creating another
# GroupTlv type for addresses containing an address, a netmask,
# and possibly a scope.
n = iface.get_tlv_value(TLV_TYPE_NETMASK, addrs.length)
addrs << Rex::Socket.addr_ntoa(a)
netmasks << Rex::Socket.addr_ntoa(n) if n
end
ifaces << Interface.new(
iface.get_tlv_value(TLV_TYPE_INTERFACE_INDEX),
iface.get_tlv_value(TLV_TYPE_IP),
iface.get_tlv_value(TLV_TYPE_NETMASK),
iface.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
iface.get_tlv_value(TLV_TYPE_MAC_NAME),
iface.get_tlv_value(TLV_TYPE_IP6),
iface.get_tlv_value(TLV_TYPE_NETMASK6),
iface.get_tlv_value(TLV_TYPE_INTERFACE_MTU),
iface.get_tlv_value(TLV_TYPE_INTERFACE_FLAGS))
:index => iface.get_tlv_value(TLV_TYPE_INTERFACE_INDEX),
:mac_addr => iface.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
:mac_name => iface.get_tlv_value(TLV_TYPE_MAC_NAME),
:mtu => iface.get_tlv_value(TLV_TYPE_INTERFACE_MTU),
:flags => iface.get_tlv_value(TLV_TYPE_INTERFACE_FLAGS),
:addrs => addrs,
:netmasks => netmasks
)
}
return ifaces

View File

@ -27,16 +27,14 @@ class Interface
# Returns a logical interface and initializes it to the supplied
# parameters.
#
def initialize(index, ip, netmask, mac_addr, mac_name, ip6=nil, netmask6=nil, mtu=nil, flags=nil)
self.index = index || -1
self.ip = (ip ? IPAddr.ntop(ip) : nil)
self.netmask = (netmask ? IPAddr.ntop(netmask) : nil)
self.mac_addr = mac_addr
self.mac_name = mac_name
self.ip6 = (ip6 ? IPAddr.new_ntoh(ip6).to_s : nil)
self.netmask6 = (netmask6 ? IPAddr.new_ntoh(netmask6).to_s : nil)
self.mtu = mtu
self.flags = flags
def initialize(opts={})
self.index = opts[:index] || -1
self.mac_addr = opts[:mac_addr]
self.mac_name = opts[:mac_name]
self.mtu = opts[:mtu]
self.flags = opts[:flags]
self.addrs = opts[:addrs]
self.netmasks = opts[:netmasks]
end
#
@ -54,11 +52,22 @@ class Interface
macocts[3], macocts[4], macocts[5])],
["MTU" , mtu ],
["Flags" , flags ],
["IPv4 Address" , ((ip and ip != "0.0.0.0") ? ip : nil) ],
["IPv4 Netmask" , netmask ],
["IPv6 Address" , ((ip6 and ip6 != "::") ? ip6 : nil) ],
["IPv6 Netmask" , ((netmask6 and netmask6 != "::") ? netmask6 : nil) ],
]
# If all went as planned, addrs and netmasks will have the same number
# of elements and be properly ordered such that they match up
# correctly.
addr_masks = addrs.zip(netmasks)
addr_masks.select { |a| Rex::Socket.is_ipv4?(a[0]) }.each { |a|
info << [ "IPv4 Address", a[0] ]
info << [ "IPv4 Netmask", a[1] ]
}
addr_masks.select { |a| Rex::Socket.is_ipv6?(a[0]) }.each { |a|
info << [ "IPv6 Address", a[0] ]
info << [ "IPv6 Netmask", a[1] ]
}
pad = info.map{|i| i[0] }.max_by{|k|k.length}.length
ret = sprintf(
@ -76,17 +85,20 @@ class Interface
end
#
# The indedx of the interface.
# The first address associated with this Interface
#
def ip
addrs.first
end
#
# The index of the interface.
#
attr_accessor :index
#
# The IP address bound to the interface.
# An Array of IP addresses bound to the Interface.
#
attr_accessor :ip
#
# The subnet mask associated with the interface.
#
attr_accessor :netmask
attr_accessor :addrs
#
# The physical (MAC) address of the NIC.
#
@ -96,10 +108,6 @@ class Interface
#
attr_accessor :mac_name
#
# The IPv6 address bound to the interface.
#
attr_accessor :ip6
#
# The subnet mask associated with the IPv6 interface.
#
attr_accessor :netmask6
@ -111,6 +119,7 @@ class Interface
# The flags associated with the interface.
#
attr_accessor :flags
attr_accessor :netmasks
end
end; end; end; end; end; end

View File

@ -51,17 +51,12 @@ TLV_TYPE_SUBNET = TLV_META_TYPE_RAW | 1420
TLV_TYPE_NETMASK = TLV_META_TYPE_RAW | 1421
TLV_TYPE_GATEWAY = TLV_META_TYPE_RAW | 1422
TLV_TYPE_NETWORK_ROUTE = TLV_META_TYPE_GROUP | 1423
TLV_TYPE_SUBNET6 = TLV_META_TYPE_RAW | 1424
TLV_TYPE_NETMASK6 = TLV_META_TYPE_RAW | 1425
TLV_TYPE_GATEWAY6 = TLV_META_TYPE_RAW | 1426
TLV_TYPE_NETWORK_ROUTE6 = TLV_META_TYPE_GROUP | 1427
TLV_TYPE_IP = TLV_META_TYPE_RAW | 1430
TLV_TYPE_MAC_ADDRESS = TLV_META_TYPE_RAW | 1431
TLV_TYPE_MAC_NAME = TLV_META_TYPE_STRING | 1432
TLV_TYPE_NETWORK_INTERFACE = TLV_META_TYPE_GROUP | 1433
TLV_TYPE_IP6 = TLV_META_TYPE_RAW | 1434
TLV_TYPE_IP6_SCOPE = TLV_META_TYPE_RAW | 1434
TLV_TYPE_SUBNET_STRING = TLV_META_TYPE_STRING | 1440
TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441

View File

@ -1,5 +1,7 @@
#!/usr/bin/env ruby
require 'rex/post/meterpreter/extensions/stdapi/tlv'
module Rex
module Post
module Meterpreter
@ -129,13 +131,14 @@ class Tlv
def inspect
utype = type ^ TLV_META_TYPE_COMPRESSED
group = false
meta = case (utype & TLV_META_MASK)
when TLV_META_TYPE_STRING; "STRING"
when TLV_META_TYPE_UINT; "INT"
when TLV_META_TYPE_RAW; "RAW"
when TLV_META_TYPE_BOOL; "BOOL"
when TLV_META_TYPE_QWORD; "QWORD"
when TLV_META_TYPE_GROUP; "GROUP"
when TLV_META_TYPE_GROUP; group=true; "GROUP"
when TLV_META_TYPE_COMPLEX; "COMPLEX"
else; 'unknown-meta-type'
end
@ -175,16 +178,33 @@ class Tlv
when TLV_TYPE_MIGRATE_PAYLOAD; "MIGRATE-PAYLOAD"
when TLV_TYPE_MIGRATE_ARCH; "MIGRATE-ARCH"
# Extension classes don't exist yet, so can't use their constants
# here.
#when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask'
when Extensions::Stdapi::TLV_TYPE_MAC_ADDRESS; 'mac-address'
when Extensions::Stdapi::TLV_TYPE_MAC_NAME; 'interface-name'
when Extensions::Stdapi::TLV_TYPE_IP6_SCOPE; 'address-scope'
when Extensions::Stdapi::TLV_TYPE_INTERFACE_MTU; 'interface-mtu'
when Extensions::Stdapi::TLV_TYPE_INTERFACE_FLAGS; 'interface-flags'
when Extensions::Stdapi::TLV_TYPE_INTERFACE_INDEX; 'interface-index'
else; "unknown-#{type}"
end
val = value.inspect
if val.length > 50
val = val[0,50] + ' ..."'
end
"#<#{self.class} type=#{stype} #{self.class.to_s =~ /Packet/ ? "tlvs=#{@tlvs.inspect}" : "meta=#{meta} value=#{val}"} >"
group ||= (self.class.to_s =~ /Packet/)
if group
tlvs_inspect = "tlvs=[\n"
@tlvs.each { |t|
tlvs_inspect << " #{t.inspect}\n"
}
tlvs_inspect << "]"
else
tlvs_inspect = "meta=#{meta} value=#{val}"
end
"#<#{self.class} type=#{stype} #{tlvs_inspect}>"
end
##