Skip to content

Commit

Permalink
netstat and arp commands in win32/posix meterpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
mephos authored and egypt committed Aug 28, 2012
1 parent 363c091 commit c1ca9fe
Show file tree
Hide file tree
Showing 13 changed files with 2,017 additions and 641 deletions.
57 changes: 51 additions & 6 deletions external/source/meterpreter/source/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>

typedef DWORD __u32;
typedef struct ___u128 {
__u32 a1;
__u32 a2;
__u32 a3;
__u32 a4;
}__u128;
#endif
#include "openssl/ssl.h"
#ifdef _UNIX
Expand Down Expand Up @@ -70,16 +78,16 @@ struct ipv4_route_entry {
__u32 dest;
__u32 netmask;
__u32 nexthop;
unsigned char interface[IFNAMSIZ+1];
__u32 metric;
unsigned char interface[IFNAMSIZ+1];
__u32 metric;
};

struct ipv6_route_entry {
__u128 dest6;
__u128 netmask6;
__u128 nexthop6;
unsigned char interface[IFNAMSIZ+1];
__u32 metric;
unsigned char interface[IFNAMSIZ+1];
__u32 metric;
};

struct ipv4_routing_table {
Expand All @@ -93,10 +101,23 @@ struct ipv6_routing_table {
};

struct routing_table {
struct ipv4_routing_table ** table_ipv4;
struct ipv6_routing_table ** table_ipv6;
struct ipv4_routing_table ** table_ipv4;
struct ipv6_routing_table ** table_ipv6;
};

struct arp_entry {
__u32 ipaddr;
unsigned char hwaddr[6];
unsigned char name[IFNAMSIZ+1];
};

struct arp_table {
int entries;
struct arp_entry table[0];
};



int netlink_get_routing_table(struct ipv4_routing_table **table_ipv4, struct ipv6_routing_table **table_ipv6);
int netlink_get_interfaces(struct ifaces_list **iface_list);

Expand All @@ -108,6 +129,30 @@ void real_dprintf(char *filename, int line, const char *function, char *format,

#endif

struct connection_entry {
char type; // AF_INET / AF_INET6
union {
__u32 addr;
__u128 addr6;
} local_addr;
union {
__u32 addr;
__u128 addr6;
} remote_addr;
__u32 local_port;
__u32 remote_port;
unsigned char protocol[5]; // tcp/tcp6/udp/udp6
unsigned char state[15]; // established, syn_sent..
__u32 uid;
__u32 inode;
unsigned char program_name[30]; // pid/program_name or "-"
};

struct connection_table {
int entries;
int max_entries;
struct connection_entry table[0];
};

#include "linkage.h"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#include "precomp.h"

#ifdef _WIN32

DWORD windows_get_arp_table(Remote *remote, Packet *response)
{
PMIB_IPNETTABLE pIpNetTable = NULL;
DWORD result = ERROR_SUCCESS;
DWORD dwSize = 0;
DWORD dwRetVal;
DWORD i;
char interface_index[10];

do {
dwRetVal = GetIpNetTable(NULL, &dwSize, 0);

/* Get the size required by GetIpNetTable() */
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
pIpNetTable = (MIB_IPNETTABLE *) malloc (dwSize);
}

else if ((dwRetVal != NO_ERROR) && (dwRetVal != ERROR_NO_DATA)) {
result = ERROR_NOT_SUPPORTED;
break;
}

if (pIpNetTable == NULL) {
result = GetLastError();
break;
}

if ((dwRetVal = GetIpNetTable(pIpNetTable, &dwSize, 0)) == NO_ERROR) {
dprintf("[ARP] found %d arp entries", pIpNetTable->dwNumEntries);
for (i = 0 ; i < pIpNetTable->dwNumEntries ; i++) {
// send only dynamic or static entry
if ((pIpNetTable->table[i].dwType == MIB_IPNET_TYPE_DYNAMIC) ||
(pIpNetTable->table[i].dwType == MIB_IPNET_TYPE_STATIC)) {
Tlv arp[3];
// can't send interface name as it can be _big_, so send index instead
sprintf_s(interface_index, sizeof(interface_index), "%d", pIpNetTable->table[i].dwIndex);

arp[0].header.type = TLV_TYPE_IP;
arp[0].header.length = sizeof(DWORD);
arp[0].buffer = (PUCHAR)&pIpNetTable->table[i].dwAddr;

arp[1].header.type = TLV_TYPE_MAC_ADDR;
arp[1].header.length = 6;
arp[1].buffer = (PUCHAR)pIpNetTable->table[i].bPhysAddr;

arp[2].header.type = TLV_TYPE_MAC_NAME;
arp[2].header.length = strlen(interface_index) + 1;
arp[2].buffer = (PUCHAR)interface_index;

packet_add_tlv_group(response, TLV_TYPE_ARP_ENTRY, arp, 3);
}
}
free(pIpNetTable);
}
else { // GetIpNetTable failed
result = GetLastError();
break;
}
} while (0);

return result;
}
#else

DWORD linux_proc_get_arp_table(struct arp_table ** table_arp)
{
unsigned char buffer_ip[40], buffer_mac[40], buffer_int[40];
char * end_ptr;
DWORD result = ERROR_SUCCESS;
FILE * fd;
__u32 newsize, i;
long b;
struct arp_table * table_tmp;
struct in_addr ip_addr;

fd = fopen("/proc/net/arp", "r");
if (fd == NULL) {
result = GetLastError();
return result;
}

*table_arp = calloc(sizeof(struct arp_table), 1);

/*
* read first line that we don't need
* IP address HW type Flags HW address Mask Device
*/
while (!feof(fd) && fgetc(fd) != '\n');
while (!feof(fd) && (fscanf(fd, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %30s", buffer_ip, buffer_mac, buffer_int) == 3)) {

// allocate size for new entry
newsize = sizeof(struct arp_table);
newsize += ((*table_arp)->entries + 1) * sizeof(struct arp_entry);
table_tmp = realloc(*table_arp, newsize);
if (table_tmp == NULL)
return ENOMEM;

memset(&table_tmp->table[table_tmp->entries], 0, sizeof(struct arp_entry));

// ip address
inet_pton(AF_INET, buffer_ip, &ip_addr);
table_tmp->table[table_tmp->entries].ipaddr = ip_addr.s_addr;

// mac address
for(i = 0; i < 6 ; i++) {
b = strtol(&buffer_mac[3*i], 0, 16);
table_tmp->table[table_tmp->entries].hwaddr[i] = (unsigned char)b;
}

// interface name
strncpy(table_tmp->table[table_tmp->entries].name, buffer_int, IFNAMSIZ);

table_tmp->entries++;
*table_arp = table_tmp;

}

fclose(fd);
return result;
}

DWORD linux_get_arp_table(Remote *remote, Packet *response)
{
struct arp_table *table_arp = NULL;
DWORD result;
DWORD index;


dprintf("getting arp table through /proc/net/arp");
result = linux_proc_get_arp_table(&table_arp);
dprintf("result = %d, table_arp = 0x%p , entries : %d", result, table_arp, table_arp->entries);

for(index = 0; index < table_arp->entries; index++) {
Tlv arp[3];

arp[0].header.type = TLV_TYPE_IP;
arp[0].header.length = sizeof(__u32);
arp[0].buffer = (PUCHAR)&table_arp->table[index].ipaddr;

arp[1].header.type = TLV_TYPE_MAC_ADDR;
arp[1].header.length = 6;
arp[1].buffer = (PUCHAR)(table_arp->table[index].hwaddr);

arp[2].header.type = TLV_TYPE_MAC_NAME;
arp[2].header.length = strlen(table_arp->table[index].name) + 1;
arp[2].buffer = (PUCHAR)(table_arp->table[index].name);

packet_add_tlv_group(response, TLV_TYPE_ARP_ENTRY, arp, 3);
}
dprintf("sent %d arp entries", table_arp->entries);

if (table_arp)
free(table_arp);

return result;
}

#endif

/*
* Returns zero or more arp entries to the requestor from the arp cache
*/
DWORD request_net_config_get_arp_table(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD result;

#ifdef _WIN32
result = windows_get_arp_table(remote, response);
#else
result = linux_get_arp_table(remote, response);
#endif

packet_transmit_response(result, remote, response);

return ERROR_SUCCESS;
}

Loading

0 comments on commit c1ca9fe

Please sign in to comment.