1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-18 07:11:12 +02:00
OJ 4ffe127f04
Begin removing the delay-load dependency
The 'common' library has been removed. The only project that actually
used it was metsrv, so the code that metsrv required from common is now
directly compiled in as part of that project.

The common folder now contains files that are importanta cross all of
the projects, with a primary focus on the new "API" style function. What
this means is that MetSrv has an API that it exposes through a function
pointer that is passed to the extension when it's initialised. This
pointer references a structure with all the API functions wired in. This
means that:

* Extensions don't need to know anything about metsrv at compile time.
* The delay loading code can be removed, which was one of the last
  instances of "metsrv.dll" as a string.
* Metsrv.dll no longer exports any functions.

More to come.
2020-04-22 13:06:40 +10:00

240 lines
7.2 KiB
C
Executable File

#include "precomp.h"
#include "common_metapi.h"
#include <iptypes.h>
#include <ws2ipdef.h>
DWORD get_interfaces_mib(Remote *remote, Packet *response)
{
DWORD tableSize = sizeof(MIB_IPADDRROW);
DWORD index;
MIB_IFROW iface;
PMIB_IPADDRTABLE table = (PMIB_IPADDRTABLE)malloc(sizeof(PMIB_IPADDRTABLE));
if (table == NULL)
{
return ERROR_OUTOFMEMORY;
}
// attempt with an insufficient buffer size
DWORD result = GetIpAddrTable(table, &tableSize, TRUE);
if (result == ERROR_INSUFFICIENT_BUFFER)
{
table = (PMIB_IPADDRTABLE)realloc(table, tableSize);
if (table == NULL)
{
return ERROR_OUTOFMEMORY;
}
if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR)
{
free(table);
return GetLastError();
}
}
// it might have worked with a single row!
else if (result != NO_ERROR)
{
free(table);
return GetLastError();
}
// Enumerate the entries
for (index = 0; index < table->dwNumEntries; index++)
{
Packet* group = met_api->packet.create_group();
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, table->table[index].dwIndex);
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&table->table[index].dwAddr, sizeof(DWORD));
met_api->packet.add_tlv_raw(group, TLV_TYPE_NETMASK, (PUCHAR)&table->table[index].dwMask, sizeof(DWORD));
iface.dwIndex = table->table[index].dwIndex;
// If interface information can get gotten, use it.
if (GetIfEntry(&iface) == NO_ERROR)
{
met_api->packet.add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)iface.bPhysAddr, iface.dwPhysAddrLen);
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, iface.dwMtu);
if (iface.bDescr)
{
met_api->packet.add_tlv_string(group, TLV_TYPE_MAC_NAME, iface.bDescr);
}
}
// Add the interface group
met_api->packet.add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
}
free(table);
return ERROR_SUCCESS;
}
DWORD get_interfaces(Remote *remote, Packet *response)
{
DWORD result = ERROR_SUCCESS;
ULONG flags = GAA_FLAG_INCLUDE_PREFIX
| GAA_FLAG_SKIP_DNS_SERVER
| GAA_FLAG_SKIP_MULTICAST
| GAA_FLAG_SKIP_ANYCAST;
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 newer version so we're guaranteed to have a large enough struct.
// Unfortunately, using these probably means it won't compile on older
// versions of Visual Studio. =(
IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr = NULL;
IP_ADAPTER_UNICAST_ADDRESS_LH *pPref = NULL;
// IP_ADAPTER_PREFIX is only defined if NTDDI_VERSION > NTDDI_WINXP
// Since we request older versions of things, we have to be explicit
// when using newer structs.
IP_ADAPTER_PREFIX_XP *pPrefix = NULL;
// We can't rely on the `Length` parameter of the IP_ADAPTER_PREFIX_XP struct
// to tell us if we're on Vista or not because it always comes out at 48 bytes
// so we have to check the version manually.
OSVERSIONINFOEX v;
gaa = (DWORD(WINAPI *)(DWORD, DWORD, void*, void*, void*))GetProcAddress(
GetModuleHandle("iphlpapi"), "GetAdaptersAddresses");
if (!gaa)
{
dprintf("[INTERFACE] No 'GetAdaptersAddresses'. Falling back on get_interfaces_mib");
return get_interfaces_mib(remote, response);
}
gaa(family, flags, NULL, pAdapters, &outBufLen);
if (!(pAdapters = malloc(outBufLen)))
{
return ERROR_NOT_ENOUGH_MEMORY;
}
if (gaa(family, flags, NULL, pAdapters, &outBufLen))
{
result = GetLastError();
goto out;
}
dprintf("[INTERFACE] pAdapters->Length = %d", pAdapters->Length);
// According to http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058(v=vs.85).aspx
// the PIP_ADAPTER_PREFIX doesn't exist prior to XP SP1. We check for this via the `Length`
// value, which is 72 in XP without an SP, but 144 in later versions.
if (pAdapters->Length <= 72)
{
dprintf("[INTERFACE] PIP_ADAPTER_PREFIX is missing");
result = get_interfaces_mib(remote, response);
goto out;
}
// we'll need to know the version later on
memset(&v, 0, sizeof(v));
v.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((LPOSVERSIONINFO)&v);
// Enumerate the entries
for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
{
// Save the first prefix for later in case we don't have an OnLinkPrefixLength
pPrefix = pCurr->FirstPrefix;
Packet* group = met_api->packet.create_group();
dprintf("[INTERFACE] Adding index: %u", pCurr->IfIndex);
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, pCurr->IfIndex);
dprintf("[INTERFACE] Adding MAC");
met_api->packet.add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)pCurr->PhysicalAddress, pCurr->PhysicalAddressLength);
dprintf("[INTERFACE] Adding Description");
met_api->packet.add_tlv_wstring(group, TLV_TYPE_MAC_NAME, pCurr->Description);
dprintf("[INTERFACE] Adding MTU: %u", pCurr->Mtu);
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, pCurr->Mtu);
for (pAddr = (IP_ADAPTER_UNICAST_ADDRESS_LH*)pCurr->FirstUnicastAddress;
pAddr; pAddr = pAddr->Next)
{
sockaddr = pAddr->Address.lpSockaddr;
if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family)
{
// Skip interfaces that aren't IP
continue;
}
DWORD prefix = 0;
if (v.dwMajorVersion >= 6) {
// Then this is Vista+ and the OnLinkPrefixLength member
// will be populated
dprintf("[INTERFACES] >= Vista, using prefix: %x", pAddr->OnLinkPrefixLength);
prefix = htonl(pAddr->OnLinkPrefixLength);
}
else if (pPrefix)
{
dprintf("[INTERFACES] < Vista, using prefix: %x", pPrefix->PrefixLength);
prefix = htonl(pPrefix->PrefixLength);
}
else
{
dprintf("[INTERFACES] < Vista, no prefix");
prefix = 0;
}
if (prefix)
{
dprintf("[INTERFACE] Adding Prefix: %x", prefix);
// the UINT value is already byte-swapped, so we add it as a raw instead of
// swizzling the bytes twice.
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP_PREFIX, (PUCHAR)&prefix, sizeof(prefix));
}
if (sockaddr->sa_family == AF_INET)
{
dprintf("[INTERFACE] Adding IPv4 Address: %x", ((struct sockaddr_in *)sockaddr)->sin_addr);
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr), 4);
}
else
{
dprintf("[INTERFACE] Adding IPv6 Address");
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr), 16);
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP6_SCOPE, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id), sizeof(DWORD));
}
}
// Add the interface group
met_api->packet.add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
}
out:
free(pAdapters);
return result;
}
/*
* Returns zero or more local interfaces to the requestor
*/
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
{
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
result = get_interfaces(remote, response);
// Transmit the response if valid
met_api->packet.transmit_response(result, remote, response);
return result;
}